New SPARC machine: Leon3
v4 cover New SPARC machine: Leon3
Hello Qemu-devel,
Here is the fourth version of Leon3 emulation patch-set.
Modifications since v3:
- Tracepoints in leon3.c
- Fix compilation error in user mode (target-sparc/op_helper.c)
- Remove unused variable in leon3.
- Minor reformating (style errors from checkpatch.pl)
Please feel free to comment.
Regards,
-------------------------------------------------------------------------------
This patch set introduces a new SPARC V8 machine: Leon3. It's an open-source VHDL System-On-Chip, well known in space industry (more information on
http://www.gaisler.com).
Leon3 is made of multiple components available in the GrLib VHDL library. Three devices are implemented: uart, timers and IRQ manager. You can find code for these peripherals in the grlib_* files.
Modifications have been done to the SPARC cpu emulation code to handle Leon3's specific behavior:
- IRQ management
- Cache control
- Asr17 (implementation-dependent Ancillary State Registers)
- Shutdown
Fabien Chouteau (5):
SPARC: Emulation of GRLIB GPTimer
SPARC: Emulation of GRLIB IRQMP
SPARC: Emulation of GRLIB APB UART
SPARC: Emulation of Leon3
SPARC: Add asr17 register support
Makefile.target | 5 +- hw/grlib.h | 126 +++++++++++++++ hw/grlib_apbuart.c | 187 ++++++++++++++++++++++ hw/grlib_gptimer.c | 395 ++++++++++++++++++++++++++++++++++++++++++++++ hw/grlib_irqmp.c | 376 +++++++++++++++++++++++++++++++++++++++++++ hw/leon3.c | 218 +++++++++++++++++++++++++ target-sparc/cpu.h | 38 +++-- target-sparc/helper.c | 8 +- target-sparc/helper.h | 1 + target-sparc/op_helper.c | 156 ++++++++++++++++++- target-sparc/translate.c | 24 +++- trace-events | 24 +++ 12 files changed, 1536 insertions(+), 22 deletions(-) create mode 100644 hw/grlib.h create mode 100644 hw/grlib_apbuart.c create mode 100644 hw/grlib_gptimer.c create mode 100644 hw/grlib_irqmp.c create mode 100644 hw/leon3.c
PATCH v4 1/5 SPARC: Emulation of GRLIB GPTimer
This device exposes three parameters:
- frequency (uint32) : The system frequency
- irq-line (uint32) : IRQ line number for the first timer
(others use irq-line + 1, irq-line + 2...)
- nr-timers (uint32) : Number of timers
Emulation of GrLib devices is base on the GRLIB IP Core User's Manual:
http://www.gaisler.com/products/grlib/grip.pdf
--- hw/grlib.h | 65 +++++++++ hw/grlib_gptimer.c | 395 ++++++++++++++++++++++++++++++++++++++++++++++++++++ trace-events | 10 ++ 3 files changed, 470 insertions(+), 0 deletions(-)
hw/grlib.h new file +65 -0
@@ -0,0 +1,65 @@ +/* +* QEMU GRLIB Components +* +* Copyright (c) 2010-2011 AdaCore +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + +#ifndef _GRLIB_H_ +#define _GRLIB_H_ + +#include "qdev.h" +#include "sysbus.h" + +/* Emulation of GrLib device is base on the GRLIB IP Core User's Manual: +* http://www.gaisler.com/products/grlib/grip.pdf +*/ + +/* GPTimer */ + +static inline +DeviceState *grlib_gptimer_create (target_phys_addr_t base, +uint32_t nr_timers, +uint32_t freq, +qemu_irq *cpu_irqs, +int base_irq) +{ +DeviceState *dev; +int i; + + dev =qdev_create (NULL ,"grlib,gptimer" ); +qdev_prop_set_uint32 (dev,"nr-timers" , nr_timers); +qdev_prop_set_uint32 (dev,"frequency" , freq); +qdev_prop_set_uint32 (dev,"irq-line" , base_irq); + +if (qdev_init (dev)) { +return NULL ; + } + +sysbus_mmio_map (sysbus_from_qdev (dev),0 , base); + +for (i =0 ; i < nr_timers; i++) { +sysbus_connect_irq (sysbus_from_qdev (dev), i, cpu_irqs[base_irq + i]); + } + +return dev; +} + +#endif /* ! _GRLIB_H_ */
hw/grlib_gptimer.c new file +395 -0
395 lines not on this page · raw message
trace-events +10 -0
@@ -213,3 +213,13 @@ disable qed_aio_write_data(void *s, void *acb, int ret, uint64_t offset, size_t disable qed_aio_write_prefill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64"" disable qed_aio_write_postfill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64"" disable qed_aio_write_main(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu" + +# hw/grlib_gptimer.c +disable grlib_gptimer_enable(int id, uint32_t count) "timer:%d set count 0x%x and run" +disable grlib_gptimer_disabled(int id, uint32_t config) "timer:%d Timer disable config 0x%x" +disable grlib_gptimer_restart(int id, uint32_t reload) "timer:%d reload val: 0x%x" +disable grlib_gptimer_set_scaler(uint32_t scaler, uint32_t freq) "scaler:0x%x freq: 0x%x" +disable grlib_gptimer_hit(int id) "timer:%d HIT" +disable grlib_gptimer_readl(int id, const char *s, uint32_t val) "timer:%d %s 0x%x" +disable grlib_gptimer_writel(int id, const char *s, uint32_t val) "timer:%d %s 0x%x" +disable grlib_gptimer_unknown_register(const char *op, uint64_t val) "%s unknown register 0x%"PRIx64""
Signature · 1 line
1.7.1
PATCH v4 2/5 SPARC: Emulation of GRLIB IRQMP
This device exposes two parameters:
- set_pil_in (ptr) : A function to set the pil_in of the SPARC CPU
- set_pil_in_opaque (ptr) : Opaque argument of the set_pil_in function
Emulation of GrLib devices is base on the GRLIB IP Core User's Manual:
http://www.gaisler.com/products/grlib/grip.pdf
--- hw/grlib.h | 38 ++++++ hw/grlib_irqmp.c | 376 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ trace-events | 6 + 3 files changed, 420 insertions(+), 0 deletions(-)
hw/grlib.h +38 -0
@@ -32,6 +32,44 @@* http://www.gaisler.com/products/grlib/grip.pdf */ +/* IRQMP */ + +typedef void (*set_pil_in_fn ) (void *opaque,uint32_t pil_in); + +void grlib_irqmp_set_irq (void *opaque,int irq,int level); + +void grlib_irqmp_ack (DeviceState *dev,int intno); + +static inline +DeviceState *grlib_irqmp_create (target_phys_addr_t base, +CPUState *env, +qemu_irq **cpu_irqs, +uint32_t nr_irqs, +set_pil_in_fn set_pil_in) +{ +DeviceState *dev; + +assert (cpu_irqs !=NULL ); + + dev =qdev_create (NULL ,"grlib,irqmp" ); +qdev_prop_set_ptr (dev,"set_pil_in" , set_pil_in); +qdev_prop_set_ptr (dev,"set_pil_in_opaque" , env); + +if (qdev_init (dev)) { +return NULL ; + } + + env->irq_manager = dev; + +sysbus_mmio_map (sysbus_from_qdev (dev),0 , base); + + *cpu_irqs =qemu_allocate_irqs (grlib_irqmp_set_irq, + dev, + nr_irqs); + +return dev; +} +/* GPTimer */ static inline
hw/grlib_irqmp.c new file +376 -0
376 lines not on this page · raw message
trace-events +6 -0
@@ -223,3 +223,9 @@ disable grlib_gptimer_hit(int id) "timer:%d HIT" disable grlib_gptimer_readl(int id, const char *s, uint32_t val) "timer:%d %s 0x%x" disable grlib_gptimer_writel(int id, const char *s, uint32_t val) "timer:%d %s 0x%x" disable grlib_gptimer_unknown_register(const char *op, uint64_t val) "%s unknown register 0x%"PRIx64"" + +# hw/grlib_irqmp.c +disable grlib_irqmp_check_irqs(uint32_t pend, uint32_t force, uint32_t mask, uint32_t lvl1, uint32_t lvl2) "pend:0x%04x force:0x%04x mask:0x%04x lvl1:0x%04x lvl0:0x%04x\n" +disable grlib_irqmp_ack(int intno) "interrupt:%d" +disable grlib_irqmp_set_irq(int irq) "Raise CPU IRQ %d" +disable grlib_irqmp_unknown_register(const char *op, uint64_t val) "%s unknown register 0x%"PRIx64""
Signature · 1 line
1.7.1
PATCH v4 3/5 SPARC: Emulation of GRLIB APB UART
This device exposes one parameter:
- chardev (ptr) : Pointer to a qemu character device
Emulation of GrLib devices is base on the GRLIB IP Core User's Manual:
http://www.gaisler.com/products/grlib/grip.pdf
--- hw/grlib.h | 23 +++++++ hw/grlib_apbuart.c | 187 ++++++++++++++++++++++++++++++++++++++++++++++++++++ trace-events | 4 + 3 files changed, 214 insertions(+), 0 deletions(-)
hw/grlib.h +23 -0
@@ -100,4 +100,27 @@ DeviceState *grlib_gptimer_create(target_phys_addr_t base,return dev; } +/* APB UART */ + +static inline +DeviceState *grlib_apbuart_create (target_phys_addr_t base, +CharDriverState *serial, +qemu_irq irq) +{ +DeviceState *dev; + + dev =qdev_create (NULL ,"grlib,apbuart" ); +qdev_prop_set_chr (dev,"chrdev" , serial); + +if (qdev_init (dev)) { +return NULL ; + } + +sysbus_mmio_map (sysbus_from_qdev (dev),0 , base); + +sysbus_connect_irq (sysbus_from_qdev (dev),0 , irq); + +return dev; +} +#endif /* ! _GRLIB_H_ */
hw/grlib_apbuart.c new file +187 -0
187 lines not on this page · raw message
trace-events +4 -0
@@ -229,3 +229,7 @@ disable grlib_irqmp_check_irqs(uint32_t pend, uint32_t force, uint32_t mask, uin disable grlib_irqmp_ack(int intno) "interrupt:%d" disable grlib_irqmp_set_irq(int irq) "Raise CPU IRQ %d" disable grlib_irqmp_unknown_register(const char *op, uint64_t val) "%s unknown register 0x%"PRIx64"" + +# hw/grlib_apbuart.c +disable grlib_apbuart_event(int event) "event:%d" +disable grlib_apbuart_unknown_register(const char *op, uint64_t val) "%s unknown register 0x%"PRIx64""
Signature · 1 line
1.7.1
PATCH v4 4/5 SPARC: Emulation of Leon3
Leon3 is an open-source VHDL System-On-Chip, well known in space industry (more information on http://www.gaisler.com).
Leon3 is made of multiple components available in the GrLib VHDL library. Three devices are implemented: uart, timers and IRQ manager. You can find code for these peripherals in the grlib_* files.
--- Makefile.target | 5 +- hw/leon3.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++ target-sparc/cpu.h | 37 +++++--- target-sparc/helper.c | 7 +- target-sparc/helper.h | 1 + target-sparc/op_helper.c | 156 ++++++++++++++++++++++++++++++++- target-sparc/translate.c | 13 +++- trace-events | 4 + 8 files changed, 419 insertions(+), 22 deletions(-)
Makefile.target +4 -1
@@ -286,7 +286,10 @@ obj-sparc-y += cirrus_vga.o else obj-sparc-y = sun4m.o lance.o tcx.o sun4m_iommu.o slavio_intctl.o obj-sparc-y += slavio_timer.o slavio_misc.o sparc32_dma.o -obj-sparc-y += cs4231.o eccmemctl.o sbi.o sun4c_intctl.o +obj-sparc-y += cs4231.o eccmemctl.o sbi.o sun4c_intctl.o leon3.o + +# GRLIB +obj-sparc-y += grlib_gptimer.o grlib_irqmp.o grlib_apbuart.o endif obj-arm-y = integratorcp.o versatilepb.o arm_pic.o arm_timer.o
hw/leon3.c new file +218 -0
218 lines not on this page · raw message
target-sparc/cpu.h +23 -14
@@ -252,20 +252,21 @@ typedef struct sparc_def_t {uint32_t maxtl; } sparc_def_t; -#define CPU_FEATURE_FLOAT (1 << 0) -#define CPU_FEATURE_FLOAT128 (1 << 1) -#define CPU_FEATURE_SWAP (1 << 2) -#define CPU_FEATURE_MUL (1 << 3) -#define CPU_FEATURE_DIV (1 << 4) -#define CPU_FEATURE_FLUSH (1 << 5) -#define CPU_FEATURE_FSQRT (1 << 6) -#define CPU_FEATURE_FMUL (1 << 7) -#define CPU_FEATURE_VIS1 (1 << 8) -#define CPU_FEATURE_VIS2 (1 << 9) -#define CPU_FEATURE_FSMULD (1 << 10) -#define CPU_FEATURE_HYPV (1 << 11) -#define CPU_FEATURE_CMT (1 << 12) -#define CPU_FEATURE_GL (1 << 13) +#define CPU_FEATURE_FLOAT (1 << 0) +#define CPU_FEATURE_FLOAT128 (1 << 1) +#define CPU_FEATURE_SWAP (1 << 2) +#define CPU_FEATURE_MUL (1 << 3) +#define CPU_FEATURE_DIV (1 << 4) +#define CPU_FEATURE_FLUSH (1 << 5) +#define CPU_FEATURE_FSQRT (1 << 6) +#define CPU_FEATURE_FMUL (1 << 7) +#define CPU_FEATURE_VIS1 (1 << 8) +#define CPU_FEATURE_VIS2 (1 << 9) +#define CPU_FEATURE_FSMULD (1 << 10) +#define CPU_FEATURE_HYPV (1 << 11) +#define CPU_FEATURE_CMT (1 << 12) +#define CPU_FEATURE_GL (1 << 13) +#define CPU_FEATURE_TA0_SHUTDOWN (1 << 14)/* Shutdown on "ta 0x0" */ #ifndef TARGET_SPARC64 #define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \ CPU_FEATURE_MUL | CPU_FEATURE_DIV | \
@@ -437,6 +438,12 @@ typedef struct CPUSPARCState {#define SOFTINT_REG_MASK (SOFTINT_STIMER|SOFTINT_INTRMASK|SOFTINT_TIMER)#endif sparc_def_t *def; + +void *irq_manager; +void (*qemu_irq_ack) (void *irq_manager,int intno); + +/* Leon3 cache control */ +uint32_t cache_control; } CPUSPARCState;#ifndef NO_CPU_IO_DEFS
@@ -469,6 +476,8 @@ int cpu_cwp_inc(CPUState *env1, int cwp);int cpu_cwp_dec (CPUState *env1,int cwp);void cpu_set_cwp (CPUState *env1,int new_cwp); +void leon3_cache_control_int (void ); +/* sun4m.c, sun4u.c */ void cpu_check_irqs (CPUSPARCState *env);
target-sparc/helper.c +4 -3
@@ -770,6 +770,7 @@ void cpu_reset(CPUSPARCState *env) env->pc =0 ; env->npc = env->pc +4 ;#endif + env->cache_control =0 ; }static int cpu_sparc_register (CPUSPARCState *env,const char *cpu_model)
@@ -1274,20 +1275,20 @@ static const sparc_def_t sparc_defs[] = { .mmu_sfsr_mask = 0xffffffff, .mmu_trcr_mask = 0xffffffff, .nwindows = 8, - .features = CPU_DEFAULT_FEATURES, + .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN, }, { .name = "LEON3", .iu_version = 0xf3000000, .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */ .mmu_version = 0xf3000000, - .mmu_bm = 0x00004000, + .mmu_bm = 0x00000000, .mmu_ctpr_mask = 0x007ffff0, .mmu_cxr_mask = 0x0000003f, .mmu_sfsr_mask = 0xffffffff, .mmu_trcr_mask = 0xffffffff, .nwindows = 8, - .features = CPU_DEFAULT_FEATURES, + .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN, }, #endif };
target-sparc/helper.h +1 -0
@@ -85,6 +85,7 @@ DEF_HELPER_0(fcmpeq_fcc2, void) DEF_HELPER_0(fcmpeq_fcc3, void)#endif DEF_HELPER_1(raise_exception, void, int) +DEF_HELPER_0(shutdown, void)#define F_HELPER_0_0 (name) DEF_HELPER_0(f ## name, void)#define F_HELPER_DQ_0_0 (name) \ F_HELPER_0_0(name ## d); \
target-sparc/op_helper.c +154 -2
212 lines not on this page · raw message
target-sparc/translate.c +11 -2
@@ -1997,8 +1997,9 @@ static void disas_sparc_insn(DisasContext * dc) }else tcg_gen_mov_tl (cpu_dst, cpu_src1); } + cond =GET_FIELD (insn,3 ,6 ); -if (cond ==0x8 ) { +if (cond ==0x8 ) {/* Trap Always */ save_state (dc, cpu_cond);if ((dc->def->features &CPU_FEATURE_HYPV ) &&supervisor (dc))
@@ -2007,7 +2008,15 @@ static void disas_sparc_insn(DisasContext * dc)tcg_gen_andi_tl (cpu_dst, cpu_dst,V8_TRAP_MASK );tcg_gen_addi_tl (cpu_dst, cpu_dst,TT_TRAP );tcg_gen_trunc_tl_i32 (cpu_tmp32, cpu_dst); -gen_helper_raise_exception (cpu_tmp32); + +if (rs2 ==0 && + dc->def->features &CPU_FEATURE_TA0_SHUTDOWN ) { + +gen_helper_shutdown (); + + }else { +gen_helper_raise_exception (cpu_tmp32); + } }else if (cond !=0 ) {TCGv r_cond =tcg_temp_new ();int l1;
trace-events +4 -0
@@ -233,3 +233,7 @@ disable grlib_irqmp_unknown_register(const char *op, uint64_t val) "%s unknown r # hw/grlib_apbuart.c disable grlib_apbuart_event(int event) "event:%d" disable grlib_apbuart_unknown_register(const char *op, uint64_t val) "%s unknown register 0x%"PRIx64"" + +# hw/leon3.c +disable leon3_set_irq(int intno) "Set CPU IRQ %d" +disable leon3_reset_irq(int intno) "Reset CPU IRQ %d"
Signature · 1 line
1.7.1
PATCH v4 5/5 SPARC: Add asr17 register support
This register is activated by CPU_FEATURE_ASR17 in the feature field.
--- target-sparc/cpu.h | 1 + target-sparc/helper.c | 3 ++- target-sparc/translate.c | 11 +++++++++++ 3 files changed, 14 insertions(+), 1 deletions(-)
target-sparc/cpu.h +1 -0
@@ -267,6 +267,7 @@ typedef struct sparc_def_t {#define CPU_FEATURE_CMT (1 << 12)#define CPU_FEATURE_GL (1 << 13)#define CPU_FEATURE_TA0_SHUTDOWN (1 << 14)/* Shutdown on "ta 0x0" */ +#define CPU_FEATURE_ASR17 (1 << 15)#ifndef TARGET_SPARC64 #define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \ CPU_FEATURE_MUL | CPU_FEATURE_DIV | \
target-sparc/helper.c +2 -1
@@ -1288,7 +1288,8 @@ static const sparc_def_t sparc_defs[] = { .mmu_sfsr_mask = 0xffffffff, .mmu_trcr_mask = 0xffffffff, .nwindows = 8, - .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN, + .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN | + CPU_FEATURE_ASR17, },#endif };
target-sparc/translate.c +11 -0
@@ -2067,6 +2067,17 @@ static void disas_sparc_insn(DisasContext * dc) case 0x10 ... 0x1f: /* implementation-dependent in theSPARCv8 manual, rdy on the microSPARC II */ +/* Read Asr17 */ +if (rs1 ==0x11 && dc->def->features &CPU_FEATURE_ASR17 ) { +TCGv r_const; + +/* Read Asr17 for a Leon3 monoprocessor */ + r_const =tcg_const_tl ((1 <<8 ) + | (dc->def->nwindows -1 )); +gen_movl_TN_reg (rd, r_const); +tcg_temp_free (r_const); +break ; + }#endif gen_movl_TN_reg (rd, cpu_y);break ;
Signature · 1 line
1.7.1
Blue Swirl
AppliedThanks, applied all.
Quoted 59 lines · Fabien Chouteau
Hello Qemu-devel,
Here is the fourth version of Leon3 emulation patch-set.
Modifications since v3:
- Tracepoints inleon3.c
- Fix compilation error in user mode (target-sparc/op_helper.c)
- Remove unused variable in leon3.
- Minor reformating (style errors from checkpatch.pl)Please feel free to comment.
Regards,
-------------------------------------------------------------------------------
This patch set introduces a new SPARC V8 machine: Leon3. It's an open-source VHDL System-On-Chip, well known in space industry (more information on
http://www.gaisler.com).Leon3 is made of multiple components available in the GrLib VHDL library. Three devices are implemented: uart, timers and IRQ manager. You can find code for these peripherals in the grlib_* files.
Modifications have been done to the SPARC cpu emulation code to handle Leon3's specific behavior:
- IRQ management
- Cache control
- Asr17 (implementation-dependent Ancillary State Registers)
- ShutdownFabien Chouteau (5):
SPARC: Emulation of GRLIB GPTimer
SPARC: Emulation of GRLIB IRQMP
SPARC: Emulation of GRLIB APB UART
SPARC: Emulation of Leon3
SPARC: Add asr17 register supportMakefile.target | 5 +-
hw/grlib.h | 126 +++++++++++++++hw/grlib_apbuart.c| 187 ++++++++++++++++++++++hw/grlib_gptimer.c| 395 ++++++++++++++++++++++++++++++++++++++++++++++hw/grlib_irqmp.c| 376 +++++++++++++++++++++++++++++++++++++++++++hw/leon3.c| 218 +++++++++++++++++++++++++target-sparc/cpu.h| 38 +++--
target-sparc/helper.c | 8 +-
target-sparc/helper.h | 1 +
target-sparc/op_helper.c | 156 ++++++++++++++++++-target-sparc/translate.c| 24 +++-
trace-events | 24 +++12 files changed, 1536 insertions(+), 22 deletions(-)create mode 100644
hw/grlib.h
create mode 100644hw/grlib_apbuart.c
create mode 100644hw/grlib_gptimer.c
create mode 100644hw/grlib_irqmp.c
create mode 100644hw/leon3.c