target-sparc: add niagara OpenSPARC T1 sun4v emulation
v2 cover target-sparc: add niagara OpenSPARC T1 sun4v emulation
This patch series adds a Niagara OpenSPARC T1 sun4v machine.
The most important new feature: it can boot Solaris 10 / sparc64. The machine uses a firmware released by Sun as a part of the OpenSPARC project.
The series are available under:
https://github.com/artyom-tarasenko/qemu/tree/sun4v-v2
The command line for booting Solaris 10 / sparc:
sparc64-softmmu/qemu-system-sparc64 -M niagara -L /path/to/S10image/ -nographic -m 256 -drive if=pflash,readonly=on,file=/path/to/S10image/disk.s10hw2
More info under
http://tyom.blogspot.de/2016/10/qemu-sun4vniagara-target-went-public.html
v1 -> v2:
Rebased on top of current master
Update Niagara target in qemu-doc.texi
v0 -> v1:
Rebased on top of current master
Use lowercase machine name (Mark)
Fixed build on i686
Fixed user-mode build (Richard)
Fixed per review comments from Richard
Added Reviewed-by to the unmodified patches reviewed in the previous round
Artyom Tarasenko (30):
target-sparc: ignore MMU-faults if MMU is disabled in hypervisor mode
target-sparc: store cpu super- and hypervisor flags in TB
target-sparc: use explicit mmu register pointers
target-sparc: add UA2005 TTE bit #defines
target-sparc: add UltraSPARC T1 TLB #defines
target-sparc: on UA2005 don't deliver Interrupt_level_n IRQs in
hypervisor mode
target-sparc: simplify replace_tlb_entry by using TTE_PGSIZE
target-sparc: implement UA2005 scratchpad registers
target-sparc: implement UltraSPARC-T1 Strand status ASR
target-sparc: hypervisor mode takes over nucleus mode
target-sparc: implement UA2005 hypervisor traps
target-sparc: implement UA2005 GL register
target-sparc: implement UA2005 rdhpstate and wrhpstate instructions
target-sparc: fix immediate UA2005 traps
target-sparc: use direct address translation in hyperprivileged mode
target-sparc: allow priveleged ASIs in hyperprivileged mode
target-sparc: ignore writes to UA2005 CPU mondo queue register
target-sparc: replace the last tlb entry when no free entries left
target-sparc: use SparcV9MMU type for sparc64 I/D-MMUs
target-sparc: implement UA2005 TSB Pointers
target-sparc: simplify ultrasparc_tsb_pointer
target-sparc: allow 256M sized pages
target-sparc: implement auto-demapping for UA2005 CPUs
target-sparc: add more registers to dump_mmu
target-sparc: implement UA2005 ASI_MMU (0x21)
target-sparc: store the UA2005 entries in sun4u format
target-sparc: add ST_BLKINIT_ ASIs for UA2005+ CPUs
target-sparc: implement sun4v RTC
target-sparc: move common cpu initialisation routines to sparc64.c
target-sparc: fix up niagara machine
MAINTAINERS | 7 + default-configs/sparc64-softmmu.mak | 2 + hw/sparc64/Makefile.objs | 2 + hw/sparc64/niagara.c | 177 +++++++++++++++++ hw/sparc64/sparc64.c | 378 +++++++++++++++++++++++++++++++++++ hw/sparc64/sun4u.c | 379 +---------------------------------- hw/timer/Makefile.objs | 2 + hw/timer/sun4v-rtc.c | 102 ++++++++++ include/hw/sparc/sparc64.h | 5 + include/hw/timer/sun4v-rtc.h | 1 + linux-user/main.c | 2 +- qemu-doc.texi | 14 +- target/sparc/asi.h | 1 + target/sparc/cpu.c | 13 +- target/sparc/cpu.h | 105 +++++++--- target/sparc/helper.h | 1 + target/sparc/int64_helper.c | 43 +++- target/sparc/ldst_helper.c | 385 ++++++++++++++++++++++++++++-------- target/sparc/machine.c | 4 +- target/sparc/mmu_helper.c | 20 +- target/sparc/translate.c | 64 ++++-- target/sparc/win_helper.c | 46 ++++- 22 files changed, 1225 insertions(+), 528 deletions(-) create mode 100644 hw/sparc64/niagara.c create mode 100644 hw/sparc64/sparc64.c create mode 100644 hw/timer/sun4v-rtc.c create mode 100644 include/hw/sparc/sparc64.h create mode 100644 include/hw/timer/sun4v-rtc.h
Signature · 1 line
1.8.3.1
PATCH v2 1/30 target-sparc: ignore MMU-faults if MMU is disabled in hypervisor mode
while IMMU/DMMU is disabled
- ignore MMU-faults in hypervisorv mode or if CPU doesn't have hypervisor
- signal TT_INSN_REAL_TRANSLATION_MISS/TT_DATA_REAL_TRANSLATION_MISS otherwise
--- target/sparc/cpu.h | 2 ++ target/sparc/ldst_helper.c | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-)
target/sparc/cpu.h +2 -0
@@ -68,6 +68,8 @@#define TT_DATA_ACCESS 0x32#define TT_UNALIGNED 0x34#define TT_PRIV_ACT 0x37 +#define TT_INSN_REAL_TRANSLATION_MISS 0x3e +#define TT_DATA_REAL_TRANSLATION_MISS 0x3f#define TT_EXTINT 0x40#define TT_IVEC 0x60#define TT_TMISS 0x64
target/sparc/ldst_helper.c +13 -2
@@ -1664,14 +1664,25 @@ void sparc_cpu_unassigned_access(CPUState *cs, hwaddr addr, {SPARCCPU *cpu =SPARC_CPU (cs);CPUSPARCState *env = &cpu->env; -int tt = is_exec ?TT_CODE_ACCESS :TT_DATA_ACCESS ;#ifdef DEBUG_UNASSIGNED printf ("Unassigned mem access to " TARGET_FMT_plx" from " TARGET_FMT_lx"\n" , addr, env->pc);#endif -cpu_raise_exception_ra (env, tt,GETPC ()); +if (is_exec) {/* XXX has_hypervisor */ +if (env->lsu & (IMMU_E )) { +cpu_raise_exception_ra (env,TT_CODE_ACCESS ,GETPC ()); + }else if (cpu_has_hypervisor (env) && !(env->hpstate &HS_PRIV )) { +cpu_raise_exception_ra (env,TT_INSN_REAL_TRANSLATION_MISS ,GETPC ()); + } + }else { +if (env->lsu & (DMMU_E )) { +cpu_raise_exception_ra (env,TT_DATA_ACCESS ,GETPC ()); + }else if (cpu_has_hypervisor (env) && !(env->hpstate &HS_PRIV )) { +cpu_raise_exception_ra (env,TT_DATA_REAL_TRANSLATION_MISS ,GETPC ()); + } + } }#endif #endif
Signature · 1 line
1.8.3.1
PATCH v2 2/30 target-sparc: store cpu super- and hypervisor flags in TB
In reply to Artyom Tarasenko--- target/sparc/cpu.h | 17 +++++++++++++++++ target/sparc/translate.c | 24 +++++++++++++++++++----- 2 files changed, 36 insertions(+), 5 deletions(-)
target/sparc/cpu.h +17 -0
@@ -667,6 +667,11 @@ static inline int cpu_supervisor_mode(CPUSPARCState *env1) {return env1->pstate &PS_PRIV ; } +#else +static inline int cpu_supervisor_mode (CPUSPARCState *env1) +{ +return env1->psrs; +}#endif static inline int cpu_mmu_index (CPUSPARCState *env,bool ifetch)
@@ -733,6 +738,8 @@ trap_state* cpu_tsptr(CPUSPARCState* env);#define TB_FLAG_MMU_MASK 7#define TB_FLAG_FPU_ENABLED (1 << 4)#define TB_FLAG_AM_ENABLED (1 << 5) +#define TB_FLAG_SUPER (1 << 6) +#define TB_FLAG_HYPER (1 << 7)#define TB_FLAG_ASI_SHIFT 24 static inline void cpu_get_tb_cpu_state(CPUSPARCState *env, target_ulong *pc,
@@ -742,7 +749,17 @@ static inline void cpu_get_tb_cpu_state(CPUSPARCState *env, target_ulong *pc, *pc = env->pc; *cs_base = env->npc; flags =cpu_mmu_index (env, false); +#ifndef CONFIG_USER_ONLY +if (cpu_supervisor_mode (env)) { + flags |=TB_FLAG_SUPER ; + } +#endif #ifdef TARGET_SPARC64 +#ifndef CONFIG_USER_ONLY +if (cpu_hypervisor_mode (env)) { + flags |=TB_FLAG_HYPER ; + } +#endif if (env->pstate &PS_AM ) { flags |=TB_FLAG_AM_ENABLED ; }
target/sparc/translate.c +19 -5
@@ -72,9 +72,16 @@ typedef struct DisasContext {target_ulong jump_pc[2 ];/* used when JUMP_PC pc value is used */ int is_br;int mem_idx; -int fpu_enabled; -int address_mask_32bit; -int singlestep; +bool fpu_enabled; +bool address_mask_32bit; +bool singlestep; +#ifndef CONFIG_USER_ONLY +bool supervisor; +#ifdef TARGET_SPARC64 +bool hypervisor; +#endif +#endif +uint32_t cc_op;/* current CC operation */ struct TranslationBlock *tb;sparc_def_t *def;
@@ -283,10 +290,11 @@ static void gen_move_Q(DisasContext *dc, unsigned int rd, unsigned int rs)#define hypervisor (dc) 0#endif #else -#define supervisor (dc) (dc->mem_idx >= MMU_KERNEL_IDX)#ifdef TARGET_SPARC64 -#define hypervisor (dc) (dc->mem_idx == MMU_HYPV_IDX) +#define hypervisor (dc) (dc->hypervisor) +#define supervisor (dc) (dc->supervisor | dc->hypervisor)#else +#define supervisor (dc) (dc->supervisor)#endif #endif
@@ -5710,9 +5718,15 @@ void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb) dc->fpu_enabled =tb_fpu_enabled (tb->flags); dc->address_mask_32bit =tb_am_enabled (tb->flags); dc->singlestep = (cs->singlestep_enabled || singlestep); +#ifndef CONFIG_USER_ONLY + dc->supervisor = (tb->flags &TB_FLAG_SUPER ) !=0 ; +#endif #ifdef TARGET_SPARC64 dc->fprs_dirty =0 ; dc->asi = (tb->flags >>TB_FLAG_ASI_SHIFT ) &0xff ; +#ifndef CONFIG_USER_ONLY + dc->hypervisor = (tb->flags &TB_FLAG_HYPER ) !=0 ; +#endif #endif num_insns =0 ;
Signature · 1 line
1.8.3.1
PATCH v2 3/30 target-sparc: use explicit mmu register pointers
In reply to Artyom TarasenkoUse explicit register pointers while accessing D/I-MMU registers. Call cpu_unassigned_access on access to missing registers.
--- target/sparc/cpu.h | 4 +++ target/sparc/ldst_helper.c | 66 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 12 deletions(-)
target/sparc/cpu.h +4 -0
@@ -443,6 +443,8 @@ struct CPUSPARCState {uint64_t sfar;uint64_t tsb;uint64_t tag_access; +uint64_t virtual_watchpoint; +uint64_t physical_watchpoint; } immu; };union {
@@ -455,6 +457,8 @@ struct CPUSPARCState {uint64_t sfar;uint64_t tsb;uint64_t tag_access; +uint64_t virtual_watchpoint; +uint64_t physical_watchpoint; } dmmu; };SparcTLBEntry itlb[64 ];
target/sparc/ldst_helper.c +54 -12
95 lines not on this page · raw message
Signature · 1 line
1.8.3.1
PATCH v2 4/30 target-sparc: add UA2005 TTE bit #defines
In reply to Artyom Tarasenko--- target/sparc/cpu.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
target/sparc/cpu.h +17 -0
@@ -304,19 +304,36 @@ enum {#define TTE_W_OK_BIT (1ULL << 1)#define TTE_GLOBAL_BIT (1ULL << 0) +#define TTE_NFO_BIT_UA2005 (1ULL << 62) +#define TTE_USED_BIT_UA2005 (1ULL << 47) +#define TTE_LOCKED_BIT_UA2005 (1ULL << 61) +#define TTE_SIDEEFFECT_BIT_UA2005 (1ULL << 11) +#define TTE_PRIV_BIT_UA2005 (1ULL << 8) +#define TTE_W_OK_BIT_UA2005 (1ULL << 6) +#define TTE_IS_VALID (tte) ((tte) & TTE_VALID_BIT)#define TTE_IS_NFO (tte) ((tte) & TTE_NFO_BIT)#define TTE_IS_USED (tte) ((tte) & TTE_USED_BIT)#define TTE_IS_LOCKED (tte) ((tte) & TTE_LOCKED_BIT)#define TTE_IS_SIDEEFFECT (tte) ((tte) & TTE_SIDEEFFECT_BIT) +#define TTE_IS_SIDEEFFECT_UA2005 (tte) ((tte) & TTE_SIDEEFFECT_BIT_UA2005)#define TTE_IS_PRIV (tte) ((tte) & TTE_PRIV_BIT)#define TTE_IS_W_OK (tte) ((tte) & TTE_W_OK_BIT) + +#define TTE_IS_NFO_UA2005 (tte) ((tte) & TTE_NFO_BIT_UA2005) +#define TTE_IS_USED_UA2005 (tte) ((tte) & TTE_USED_BIT_UA2005) +#define TTE_IS_LOCKED_UA2005 (tte) ((tte) & TTE_LOCKED_BIT_UA2005) +#define TTE_IS_SIDEEFFECT_UA2005 (tte) ((tte) & TTE_SIDEEFFECT_BIT_UA2005) +#define TTE_IS_PRIV_UA2005 (tte) ((tte) & TTE_PRIV_BIT_UA2005) +#define TTE_IS_W_OK_UA2005 (tte) ((tte) & TTE_W_OK_BIT_UA2005) +#define TTE_IS_GLOBAL (tte) ((tte) & TTE_GLOBAL_BIT)#define TTE_SET_USED (tte) ((tte) |= TTE_USED_BIT)#define TTE_SET_UNUSED (tte) ((tte) &= ~TTE_USED_BIT)#define TTE_PGSIZE (tte) (((tte) >> 61) & 3ULL) +#define TTE_PGSIZE_UA2005 (tte) ((tte) & 7ULL)#define TTE_PA (tte) ((tte) & 0x1ffffffe000ULL)#define SFSR_NF_BIT (1ULL << 24)/* JPS1 NoFault */
Signature · 1 line
1.8.3.1
PATCH v2 6/30 target-sparc: on UA2005 don't deliver Interrupt_level_n IRQs in hypervisor mode
In reply to Artyom TarasenkoAs described in Chapter 5.7.6 of the UltraSPARC Architecture 2005, outstanding disrupting exceptions that are destined for privileged mode can only cause a trap when the virtual processor is in nonprivileged or privileged mode and PSTATE.ie = 1. At all other times, they are held pending.
--- target/sparc/cpu.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
target/sparc/cpu.h +2 -1
@@ -733,8 +733,9 @@ static inline int cpu_interrupts_enabled(CPUSPARCState *env1)if (env1->psret !=0 )return 1 ;#else -if (env1->pstate &PS_IE ) +if ((env1->pstate &PS_IE ) && !cpu_hypervisor_mode (env1)) {return 1 ; + }#endif return 0 ;
Signature · 1 line
1.8.3.1
PATCH v2 7/30 target-sparc: simplify replace_tlb_entry by using TTE_PGSIZE
In reply to Artyom Tarasenko--- target/sparc/ldst_helper.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
target/sparc/ldst_helper.c +2 -3
@@ -127,9 +127,8 @@ static void replace_tlb_entry(SparcTLBEntry *tlb,if (TTE_IS_VALID (tlb->tte)) {CPUState *cs =CPU (sparc_env_get_cpu (env1)); - mask =0xffffffffffffe000ULL ; - mask <<=3 * ((tlb->tte >>61 ) &3 ); - size = ~mask +1 ; + size =8192ULL <<3 *TTE_PGSIZE (tlb->tte); + mask =1ULL + ~size; va = tlb->tag & mask;
Signature · 1 line
1.8.3.1
PATCH v2 5/30 target-sparc: add UltraSPARC T1 TLB #defines
In reply to Artyom Tarasenko--- target/sparc/cpu.h | 4 ++++ 1 file changed, 4 insertions(+)
target/sparc/cpu.h +4 -0
@@ -336,6 +336,10 @@ enum {#define TTE_PGSIZE_UA2005 (tte) ((tte) & 7ULL)#define TTE_PA (tte) ((tte) & 0x1ffffffe000ULL) +/* UltraSPARC T1 specific */ +#define TLB_UST1_IS_REAL_BIT (1ULL << 9)/* Real translation entry */ +#define TLB_UST1_IS_SUN4V_BIT (1ULL << 10)/* sun4u/sun4v TTE format switch */ +#define SFSR_NF_BIT (1ULL << 24)/* JPS1 NoFault */ #define SFSR_TM_BIT (1ULL << 15)/* JPS1 TLB Miss */ #define SFSR_FT_VA_IMMU_BIT (1ULL << 13)/* USIIi VA out of range (IMMU) */
Signature · 1 line
1.8.3.1
PATCH v2 8/30 target-sparc: implement UA2005 scratchpad registers
In reply to Artyom Tarasenko--- target/sparc/asi.h | 1 + target/sparc/cpu.h | 1 + target/sparc/ldst_helper.c | 24 ++++++++++++++++++++++++ 3 files changed, 26 insertions(+)
target/sparc/asi.h +1 -0
@@ -211,6 +211,7 @@#define ASI_AFSR 0x4c/* Async fault status register */ #define ASI_AFAR 0x4d/* Async fault address register */ #define ASI_EC_TAG_DATA 0x4e/* E-cache tag/valid ram diag acc */ +#define ASI_HYP_SCRATCHPAD 0x4f/* (4V) Hypervisor scratchpad */ #define ASI_IMMU 0x50/* Insn-MMU main register space */ #define ASI_IMMU_TSB_8KB_PTR 0x51/* Insn-MMU 8KB TSB pointer reg */ #define ASI_IMMU_TSB_64KB_PTR 0x52/* Insn-MMU 64KB TSB pointer reg */
target/sparc/cpu.h +1 -0
@@ -520,6 +520,7 @@ struct CPUSPARCState {uint32_t gl;// UA2005 /* UA 2005 hyperprivileged registers */ uint64_t hpstate, htstate[MAXTL_MAX ], hintp, htba, hver, hstick_cmpr, ssr; +uint64_t scratch[8 ];CPUTimer *hstick;// UA 2005 /* Interrupt vector registers */ uint64_t ivec_status;
target/sparc/ldst_helper.c +24 -0
@@ -1351,6 +1351,18 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, }break ; } +case ASI_SCRATCHPAD :/* UA2005 privileged scratchpad */ +if (unlikely ((addr >=0x20 ) && (addr <0x30 ))) { +/* Hyperprivileged access only */ +cpu_unassigned_access (cs, addr, false, false,1 , size); + } +/* fall through */ +case ASI_HYP_SCRATCHPAD :/* UA2005 hyperprivileged scratchpad */ + { +unsigned int i = (addr >>3 ) &0x7 ; + ret = env->scratch[i]; +break ; + }case ASI_DCACHE_DATA :/* D-cache data */ case ASI_DCACHE_TAG :/* D-cache tag access */ case ASI_ESTATE_ERROR_EN :/* E-cache error enable */
@@ -1603,6 +1615,18 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,case ASI_INTR_RECEIVE :/* Interrupt data receive */ env->ivec_status = val &0x20 ;return ; +case ASI_SCRATCHPAD :/* UA2005 privileged scratchpad */ +if (unlikely ((addr >=0x20 ) && (addr <0x30 ))) { +/* Hyperprivileged access only */ +cpu_unassigned_access (cs, addr, true, false,1 , size); + } +/* fall through */ +case ASI_HYP_SCRATCHPAD :/* UA2005 hyperprivileged scratchpad */ + { +unsigned int i = (addr >>3 ) &0x7 ; + env->scratch[i] = val; +return ; + }case ASI_DCACHE_DATA :/* D-cache data */ case ASI_DCACHE_TAG :/* D-cache tag access */ case ASI_ESTATE_ERROR_EN :/* E-cache error enable */
Signature · 1 line
1.8.3.1
PATCH v2 9/30 target-sparc: implement UltraSPARC-T1 Strand status ASR
In reply to Artyom Tarasenko--- target/sparc/translate.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
target/sparc/translate.c +11 -0
@@ -3429,6 +3429,17 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)case 0x19 :/* System tick compare */ gen_store_gpr (dc, rd, cpu_stick_cmpr);break ; +case 0x1a :/* UltraSPARC-T1 Strand status */ +/* XXX HYPV check maybe not enough, UA2005 & UA2007 describe +* this ASR as impl. dep +*/ +CHECK_IU_FEATURE (dc,HYPV ); + { +TCGv t =gen_dest_gpr (dc, rd); +tcg_gen_movi_tl (t,1UL ); +gen_store_gpr (dc, rd, t); + } +break ;case 0x10 :/* Performance Control */ case 0x11 :/* Performance Instrumentation Counter */ case 0x12 :/* Dispatch Control */
Signature · 1 line
1.8.3.1
PATCH v2 10/30 target-sparc: hypervisor mode takes over nucleus mode
In reply to Artyom TarasenkoAccordinf to UA2005, 9.3.3 "Address Space Identifiers",
"In hyperprivileged mode, all instruction fetches and loads and stores with implicit ASIs use a physical address, regardless of the value of TL".
--- target/sparc/cpu.h | 4 ++-- target/sparc/translate.c | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-)
target/sparc/cpu.h +2 -2
@@ -716,10 +716,10 @@ static inline int cpu_mmu_index(CPUSPARCState *env, bool ifetch) ? (env->lsu & IMMU_E) == 0 || (env->pstate & PS_RED) != 0 : (env->lsu & DMMU_E) == 0) {return MMU_PHYS_IDX ; - } else if (env->tl > 0) { -return MMU_NUCLEUS_IDX ; } else if (cpu_hypervisor_mode(env)) {return MMU_HYPV_IDX ; + } else if (env->tl > 0) { +return MMU_NUCLEUS_IDX ; } else if (cpu_supervisor_mode(env)) {return MMU_KERNEL_IDX ; } else {
target/sparc/translate.c +5 -1
@@ -2142,7 +2142,11 @@ static DisasASI get_asi(DisasContext *dc, int insn, TCGMemOp memop)case ASI_TWINX_NL :case ASI_NUCLEUS_QUAD_LDD :case ASI_NUCLEUS_QUAD_LDD_L : - mem_idx =MMU_NUCLEUS_IDX ; +if (hypervisor (dc)) { + mem_idx =MMU_HYPV_IDX ; + }else { + mem_idx =MMU_NUCLEUS_IDX ; + }break ;case ASI_AIUP :/* As if user primary */ case ASI_AIUPL :/* As if user primary LE */
Signature · 1 line
1.8.3.1
PATCH v2 11/30 target-sparc: implement UA2005 hypervisor traps
In reply to Artyom Tarasenko--- target/sparc/cpu.h | 1 + target/sparc/int64_helper.c | 37 ++++++++++++++++++++++++++++++++----- target/sparc/win_helper.c | 6 ++++++ 3 files changed, 39 insertions(+), 5 deletions(-)
target/sparc/cpu.h +1 -0
@@ -79,6 +79,7 @@#define TT_FILL 0xc0#define TT_WOTHER (1 << 5)#define TT_TRAP 0x100 +#define TT_HTRAP 0x180#endif #define PSR_NEG_SHIFT 23
target/sparc/int64_helper.c +32 -5
@@ -78,8 +78,10 @@ void sparc_cpu_do_interrupt(CPUState *cs)static int count;const char *name; -if (intno <0 || intno >=0x180 ) { +if (intno <0 || intno >=0x1ff ) { name ="Unknown" ; + }else if (intno >=0x180 ) { + name ="Hyperprivileged Trap Instruction" ; }else if (intno >=0x100 ) { name ="Trap Instruction" ; }else if (intno >=0xc0 ) {
@@ -135,16 +137,36 @@ void sparc_cpu_do_interrupt(CPUState *cs) tsptr->tnpc = env->npc; tsptr->tt = intno; +if (cpu_has_hypervisor (env)) { + env->htstate[env->tl] = env->hpstate; +/* XXX OpenSPARC T1 - UltraSPARC T3 have MAXPTL=2 +but this may change in the future */ +if (env->tl >2 ) { + env->hpstate |=HS_PRIV ; + } + } +switch (intno) {case TT_IVEC : -cpu_change_pstate (env,PS_PEF |PS_PRIV |PS_IG ); +if (!cpu_has_hypervisor (env)) { +cpu_change_pstate (env,PS_PEF |PS_PRIV |PS_IG ); + }break ;case TT_TFAULT :case TT_DFAULT : case TT_TMISS ... TT_TMISS + 3: case TT_DMISS ... TT_DMISS + 3: case TT_DPROT ... TT_DPROT + 3: -cpu_change_pstate (env,PS_PEF |PS_PRIV |PS_MG ); +if (cpu_has_hypervisor (env)) { + env->hpstate |=HS_PRIV ; + env->pstate =PS_PEF |PS_PRIV ; + }else { +cpu_change_pstate (env,PS_PEF |PS_PRIV |PS_MG ); + } +break ; + case TT_INSN_REAL_TRANSLATION_MISS ... TT_DATA_REAL_TRANSLATION_MISS: + case TT_HTRAP ... TT_HTRAP + 127: + env->hpstate |=HS_PRIV ;break ;default :cpu_change_pstate (env,PS_PEF |PS_PRIV |PS_AG );
@@ -158,8 +180,13 @@ void sparc_cpu_do_interrupt(CPUState *cs) }else if ((intno &0x1c0 ) ==TT_FILL ) {cpu_set_cwp (env,cpu_cwp_inc (env, env->cwp +1 )); } - env->pc = env->tbr & ~0x7fffULL ; - env->pc |= ((env->tl >1 ) ?1 <<14 :0 ) | (intno <<5 ); + +if (cpu_hypervisor_mode (env)) { + env->pc = (env->htba & ~0x3fffULL ) | (intno <<5 ); + }else { + env->pc = env->tbr & ~0x7fffULL ; + env->pc |= ((env->tl >1 ) ?1 <<14 :0 ) | (intno <<5 ); + } env->npc = env->pc +4 ; cs->exception_index =-1 ; }
target/sparc/win_helper.c +6 -0
@@ -366,6 +366,9 @@ void helper_done(CPUSPARCState *env) env->asi = (tsptr->tstate >>24 ) &0xff ;cpu_change_pstate (env, (tsptr->tstate >>8 ) &0xf3f );cpu_put_cwp64 (env, tsptr->tstate &0xff ); +if (cpu_has_hypervisor (env)) { + env->hpstate = env->htstate[env->tl]; + } env->tl--;trace_win_helper_done (env->tl);
@@ -387,6 +390,9 @@ void helper_retry(CPUSPARCState *env) env->asi = (tsptr->tstate >>24 ) &0xff ;cpu_change_pstate (env, (tsptr->tstate >>8 ) &0xf3f );cpu_put_cwp64 (env, tsptr->tstate &0xff ); +if (cpu_has_hypervisor (env)) { + env->hpstate = env->htstate[env->tl]; + } env->tl--;trace_win_helper_retry (env->tl);
Signature · 1 line
1.8.3.1
PATCH v2 12/30 target-sparc: implement UA2005 GL register
In reply to Artyom Tarasenko--- target/sparc/cpu.c | 13 ++++++++++--- target/sparc/cpu.h | 2 ++ target/sparc/helper.h | 1 + target/sparc/int64_helper.c | 6 ++++++ target/sparc/translate.c | 3 +-- target/sparc/win_helper.c | 40 ++++++++++++++++++++++++++++++++++++++-- 6 files changed, 58 insertions(+), 7 deletions(-)
target/sparc/cpu.c +10 -3
@@ -58,9 +58,13 @@ static void sparc_cpu_reset(CPUState *s) env->psrps =1 ;#endif #ifdef TARGET_SPARC64 - env->pstate =PS_PRIV |PS_RED |PS_PEF |PS_AG ; + env->pstate =PS_PRIV |PS_RED |PS_PEF ; +if (!cpu_has_hypervisor (env)) { + env->pstate |=PS_AG ; + } env->hpstate =cpu_has_hypervisor (env) ?HS_PRIV :0 ; env->tl = env->maxtl; + env->gl =2 ;cpu_tsptr (env)->tt =TT_POWER_ON_RESET ; env->lsu =0 ;#else
@@ -745,14 +749,17 @@ void sparc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,cpu_print_cc (f, cpu_fprintf,cpu_get_ccr (env) <<PSR_CARRY_SHIFT );cpu_fprintf (f," xcc: " );cpu_print_cc (f, cpu_fprintf,cpu_get_ccr (env) << (PSR_CARRY_SHIFT -4 )); -cpu_fprintf (f,") asi: %02x tl: %d pil: %x\n" , env->asi, env->tl, - env->psrpil); +cpu_fprintf (f,") asi: %02x tl: %d pil: %x gl: %d\n" , env->asi, env->tl, + env->psrpil, env->gl); +cpu_fprintf (f,"tbr: " TARGET_FMT_lx" hpstate: " TARGET_FMT_lx" htba: " + TARGET_FMT_lx"\n" , env->tbr, env->hpstate, env->htba);cpu_fprintf (f,"cansave: %d canrestore: %d otherwin: %d wstate: %d " "cleanwin: %d cwp: %d\n" , env->cansave, env->canrestore, env->otherwin, env->wstate, env->cleanwin, env->nwindows -1 - env->cwp);cpu_fprintf (f,"fsr: " TARGET_FMT_lx" y: " TARGET_FMT_lx" fprs: " TARGET_FMT_lx"\n" , env->fsr, env->y, env->fprs); +#else cpu_fprintf (f,"psr: %08x (icc: " ,cpu_get_psr (env));cpu_print_cc (f, cpu_fprintf,cpu_get_psr (env));
target/sparc/cpu.h +2 -0
@@ -512,6 +512,7 @@ struct CPUSPARCState {uint64_t bgregs[8 ];/* backup for normal global registers */ uint64_t igregs[8 ];/* interrupt general registers */ uint64_t mgregs[8 ];/* mmu general registers */ +uint64_t glregs[8 *MAXTL_MAX ];uint64_t fprs;uint64_t tick_cmpr, stick_cmpr;CPUTimer *tick, *stick;
@@ -612,6 +613,7 @@ void cpu_put_ccr(CPUSPARCState *env1, target_ulong val);target_ulong cpu_get_cwp64 (CPUSPARCState *env1);void cpu_put_cwp64 (CPUSPARCState *env1,int cwp);void cpu_change_pstate (CPUSPARCState *env1,uint32_t new_pstate); +void cpu_gl_switch_gregs (CPUSPARCState *env,uint32_t new_gl);#endif int cpu_cwp_inc (CPUSPARCState *env1,int cwp);int cpu_cwp_dec (CPUSPARCState *env1,int cwp);
target/sparc/helper.h +1 -0
@@ -5,6 +5,7 @@ DEF_HELPER_1(rdpsr, tl, env) DEF_HELPER_1(power_down, void, env)#else DEF_HELPER_FLAGS_2(wrpil, TCG_CALL_NO_RWG, void, env, tl) +DEF_HELPER_2(wrgl, void, env, tl) DEF_HELPER_2(wrpstate, void, env, tl) DEF_HELPER_1(done, void, env)DEF_HELPER_1 (retry, void, env)
target/sparc/int64_helper.c +6 -0
@@ -146,6 +146,12 @@ void sparc_cpu_do_interrupt(CPUState *cs) } } +if (env->def->features &CPU_FEATURE_GL ) { + tsptr->tstate |= (env->gl &7ULL ) <<40 ; +cpu_gl_switch_gregs (env, env->gl +1 ); + env->gl++; + } +switch (intno) {case TT_IVEC :if (!cpu_has_hypervisor (env)) {
target/sparc/translate.c +1 -2
@@ -4558,8 +4558,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)break ;case 16 :// UA2005 gl CHECK_IU_FEATURE (dc,GL ); -tcg_gen_st32_tl (cpu_tmp0, cpu_env, - offsetof(CPUSPARCState , gl)); +gen_helper_wrgl (cpu_env, cpu_tmp0);break ;case 26 :// UA2005 strand status CHECK_IU_FEATURE (dc,HYPV );
target/sparc/win_helper.c +38 -2
@@ -290,6 +290,10 @@ void helper_wrcwp(CPUSPARCState *env, target_ulong new_cwp)static inline uint64_t *get_gregset (CPUSPARCState *env,uint32_t pstate) { +if (env->def->features &CPU_FEATURE_GL ) { +return env->glregs + (env->gl &7 ) *8 ; + } +switch (pstate) {default :trace_win_helper_gregset_error (pstate);
@@ -305,14 +309,40 @@ static inline uint64_t *get_gregset(CPUSPARCState *env, uint32_t pstate) } } +static inline uint64_t *get_gl_gregset (CPUSPARCState *env,uint32_t gl) +{ +return env->glregs + (gl &7 ) *8 ; +} + +/* Switch global register bank */ +void cpu_gl_switch_gregs (CPUSPARCState *env,uint32_t new_gl) +{ +uint64_t *src, *dst; + src =get_gl_gregset (env, new_gl); + dst =get_gl_gregset (env, env->gl); + +if (src != dst) { +memcpy32 (dst, env->gregs); +memcpy32 (env->gregs, src); + } +} + +void helper_wrgl (CPUSPARCState *env,target_ulong new_gl) +{ +cpu_gl_switch_gregs (env, new_gl &7 ); + env->gl = new_gl &7 ; +} +void cpu_change_pstate (CPUSPARCState *env,uint32_t new_pstate) {uint32_t pstate_regs, new_pstate_regs;uint64_t *src, *dst;if (env->def->features &CPU_FEATURE_GL ) { -/* PS_AG is not implemented in this case */ - new_pstate &= ~PS_AG ; +/* PS_AG, IG and MG are not implemented in this case */ + new_pstate &= ~(PS_AG |PS_IG |PS_MG ); + env->pstate = new_pstate; +return ; } pstate_regs = env->pstate &0xc01 ;
@@ -367,7 +397,10 @@ void helper_done(CPUSPARCState *env)cpu_change_pstate (env, (tsptr->tstate >>8 ) &0xf3f );cpu_put_cwp64 (env, tsptr->tstate &0xff );if (cpu_has_hypervisor (env)) { +uint32_t new_gl = (tsptr->tstate >>40 ) &7 ; env->hpstate = env->htstate[env->tl]; +cpu_gl_switch_gregs (env, new_gl); + env->gl = new_gl; } env->tl--;
@@ -391,7 +424,10 @@ void helper_retry(CPUSPARCState *env)cpu_change_pstate (env, (tsptr->tstate >>8 ) &0xf3f );cpu_put_cwp64 (env, tsptr->tstate &0xff );if (cpu_has_hypervisor (env)) { +uint32_t new_gl = (tsptr->tstate >>40 ) &7 ; env->hpstate = env->htstate[env->tl]; +cpu_gl_switch_gregs (env, new_gl); + env->gl = new_gl; } env->tl--;
Signature · 1 line
1.8.3.1
PATCH v2 13/30 target-sparc: implement UA2005 rdhpstate and wrhpstate instructions
In reply to Artyom Tarasenko--- target/sparc/translate.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
target/sparc/translate.c +5 -2
@@ -3468,7 +3468,8 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) rs1 =GET_FIELD (insn,13 ,17 );switch (rs1) {case 0 :// hpstate -// gen_op_rdhpstate(); +tcg_gen_ld_i64 (cpu_dst, cpu_env, + offsetof(CPUSPARCState , hpstate));break ;case 1 :// htstate // gen_op_rdhtstate();
@@ -4592,7 +4593,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)tcg_gen_xor_tl (cpu_tmp0, cpu_src1, cpu_src2);switch (rd) {case 0 :// hpstate -// XXX gen_op_wrhpstate(); +tcg_gen_st_i64 (cpu_tmp0, cpu_env, + offsetof(CPUSPARCState , + hpstate));save_state (dc);gen_op_next_insn ();tcg_gen_exit_tb (0 );
Signature · 1 line
1.8.3.1
PATCH v2 14/30 target-sparc: fix immediate UA2005 traps
In reply to Artyom Tarasenko--- target/sparc/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
target/sparc/translate.c +1 -1
@@ -3298,7 +3298,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn) rs1 =GET_FIELD_SP (insn,14 ,18 );if (IS_IMM ) { - rs2 =GET_FIELD_SP (insn,0 ,6 ); + rs2 =GET_FIELD_SP (insn,0 ,7 );if (rs1 ==0 ) {tcg_gen_movi_i32 (trap, (rs2 & mask) +TT_TRAP );/* Signal that the trap value is fully constant. */
Signature · 1 line
1.8.3.1
PATCH v2 15/30 target-sparc: use direct address translation in hyperprivileged mode
In reply to Artyom TarasenkoPlease note that QEMU doesn't impelement Real->Physical address translation. The "Real Address" is always the "Physical Address".
--- target/sparc/cpu.h | 7 +++---- target/sparc/translate.c | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-)
target/sparc/cpu.h +3 -4
@@ -230,7 +230,7 @@ enum { #if !defined(TARGET_SPARC64) #define NB_MMU_MODES 3 #else -#define NB_MMU_MODES 7 +#define NB_MMU_MODES 6 typedef struct trap_state { uint64_t tpc; uint64_t tnpc;
@@ -673,8 +673,7 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);#define MMU_KERNEL_IDX 2#define MMU_KERNEL_SECONDARY_IDX 3#define MMU_NUCLEUS_IDX 4 -#define MMU_HYPV_IDX 5 -#define MMU_PHYS_IDX 6 +#define MMU_PHYS_IDX 5#else #define MMU_USER_IDX 0#define MMU_KERNEL_IDX 1
@@ -720,7 +719,7 @@ static inline int cpu_mmu_index(CPUSPARCState *env, bool ifetch) : (env->lsu & DMMU_E) == 0) {return MMU_PHYS_IDX ; } else if (cpu_hypervisor_mode(env)) { -return MMU_HYPV_IDX ; +return MMU_PHYS_IDX ; } else if (env->tl > 0) {return MMU_NUCLEUS_IDX ; } else if (cpu_supervisor_mode(env)) {
target/sparc/translate.c +1 -1
@@ -2143,7 +2143,7 @@ static DisasASI get_asi(DisasContext *dc, int insn, TCGMemOp memop)case ASI_NUCLEUS_QUAD_LDD :case ASI_NUCLEUS_QUAD_LDD_L :if (hypervisor (dc)) { - mem_idx =MMU_HYPV_IDX ; + mem_idx =MMU_PHYS_IDX ; }else { mem_idx =MMU_NUCLEUS_IDX ; }
Signature · 1 line
1.8.3.1
PATCH v2 16/30 target-sparc: allow priveleged ASIs in hyperprivileged mode
In reply to Artyom Tarasenko--- target/sparc/ldst_helper.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-)
target/sparc/ldst_helper.c +16 -14
@@ -293,6 +293,20 @@ static inline target_ulong asi_address_mask(CPUSPARCState *env, }return addr; } + +static inline void do_check_asi (CPUSPARCState *env,int asi,uintptr_t ra) +{ +/* ASIs >= 0x80 are user mode. +* ASIs >= 0x30 are hyper mode (or super if hyper is not available). +* ASIs <= 0x2f are super mode. +*/ +if (asi <0x80 + && !cpu_hypervisor_mode (env) + && (!cpu_supervisor_mode (env) + || (asi >=0x30 &&cpu_has_hypervisor (env)))) { +cpu_raise_exception_ra (env,TT_PRIV_ACT , ra); + } +}#endif static void do_check_align(CPUSPARCState *env, target_ulong addr,
@@ -1118,13 +1132,7 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, asi &=0xff ; -if ((asi <0x80 && (env->pstate &PS_PRIV ) ==0 ) - || (cpu_has_hypervisor (env) - && asi >=0x30 && asi <0x80 - && !(env->hpstate &HS_PRIV ))) { -cpu_raise_exception_ra (env,TT_PRIV_ACT ,GETPC ()); - } - +do_check_asi (env, asi,GETPC ());do_check_align (env, addr, size -1 ,GETPC ()); addr =asi_address_mask (env, asi, addr);
@@ -1423,13 +1431,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val, asi &=0xff ; -if ((asi <0x80 && (env->pstate &PS_PRIV ) ==0 ) - || (cpu_has_hypervisor (env) - && asi >=0x30 && asi <0x80 - && !(env->hpstate &HS_PRIV ))) { -cpu_raise_exception_ra (env,TT_PRIV_ACT ,GETPC ()); - } - +do_check_asi (env, asi,GETPC ());do_check_align (env, addr, size -1 ,GETPC ()); addr =asi_address_mask (env, asi, addr);
Signature · 1 line
1.8.3.1
PATCH v2 17/30 target-sparc: ignore writes to UA2005 CPU mondo queue register
In reply to Artyom Tarasenko--- target/sparc/ldst_helper.c | 1 + 1 file changed, 1 insertion(+)
target/sparc/ldst_helper.c +1 -0
@@ -1629,6 +1629,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val, env->scratch[i] = val;return ; } +case ASI_QUEUE :/* UA2005 CPU mondo queue */ case ASI_DCACHE_DATA :/* D-cache data */ case ASI_DCACHE_TAG :/* D-cache tag access */ case ASI_ESTATE_ERROR_EN :/* E-cache error enable */
Signature · 1 line
1.8.3.1
PATCH v2 18/30 target-sparc: replace the last tlb entry when no free entries left
In reply to Artyom TarasenkoImplement the behavior described in the chapter 13.9.11 of UltraSPARC T1™ Supplement to the UltraSPARC Architecture 2005:
"If a TLB Data-In replacement is attempted with all TLB entries locked and valid, the last TLB entry (entry 63) is replaced."
--- target/sparc/ldst_helper.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
target/sparc/ldst_helper.c +4 -2
@@ -246,9 +246,11 @@ static void replace_tlb_1bit_lru(SparcTLBEntry *tlb, }#ifdef DEBUG_MMU -DPRINTF_MMU ("%s lru replacement failed: no entries available\n" , strmmu); +DPRINTF_MMU ("%s lru replacement: no free entries available, " +"replacing the last one\n" , strmmu);#endif -/* error state? */ +/* corner case: the last entry is replaced anyway */ +replace_tlb_entry (&tlb[63 ], tlb_tag, tlb_tte, env1); }#endif
Signature · 1 line
1.8.3.1
PATCH v2 19/30 target-sparc: use SparcV9MMU type for sparc64 I/D-MMUs
In reply to Artyom Tarasenko--- linux-user/main.c | 2 +- target/sparc/cpu.h | 48 +++++++++++++++++----------------------------- target/sparc/ldst_helper.c | 8 ++++---- target/sparc/machine.c | 4 ++-- 4 files changed, 25 insertions(+), 37 deletions(-)
linux-user/main.c +1 -1
@@ -1166,7 +1166,7 @@ void cpu_loop (CPUSPARCState *env)/* XXX: check env->error_code */ info.si_code =TARGET_SEGV_MAPERR ;if (trapnr ==TT_DFAULT ) - info._sifields._sigfault._addr = env->dmmuregs[4 ]; + info._sifields._sigfault._addr = env->dmmu.mmuregs[4 ];else info._sifields._sigfault._addr =cpu_tsptr (env)->tpc;queue_signal (env, info.si_signo,QEMU_SI_FAULT , &info);
target/sparc/cpu.h +18 -30
60 lines not on this page · raw message
target/sparc/ldst_helper.c +4 -4
@@ -1481,7 +1481,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,int reg = (addr >>3 ) &0xf ;uint64_t oldreg; - oldreg = env->immuregs[reg]; + oldreg = env->immu.mmuregs[reg];switch (reg) {case 0 :/* RO */ return ;
@@ -1512,7 +1512,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,break ; } -if (oldreg != env->immuregs[reg]) { +if (oldreg != env->immu.mmuregs[reg]) {DPRINTF_MMU ("immu change reg[%d]: 0x%016" PRIx64" -> 0x%016" PRIx64"\n" , reg, oldreg, env->immuregs[reg]); }
@@ -1546,7 +1546,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,int reg = (addr >>3 ) &0xf ;uint64_t oldreg; - oldreg = env->dmmuregs[reg]; + oldreg = env->dmmu.mmuregs[reg];switch (reg) {case 0 :/* RO */ case 4 :
@@ -1589,7 +1589,7 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,break ; } -if (oldreg != env->dmmuregs[reg]) { +if (oldreg != env->dmmu.mmuregs[reg]) {DPRINTF_MMU ("dmmu change reg[%d]: 0x%016" PRIx64" -> 0x%016" PRIx64"\n" , reg, oldreg, env->dmmuregs[reg]); }
target/sparc/machine.c +2 -2
@@ -148,8 +148,8 @@ const VMStateDescription vmstate_sparc_cpu = {VMSTATE_UINT64_ARRAY (env.mmubpregs,SPARCCPU ,4 ), #elseVMSTATE_UINT64 (env.lsu,SPARCCPU ), -VMSTATE_UINT64_ARRAY (env.immuregs,SPARCCPU ,16 ), -VMSTATE_UINT64_ARRAY (env.dmmuregs,SPARCCPU ,16 ), +VMSTATE_UINT64_ARRAY (env.immu.mmuregs,SPARCCPU ,16 ), +VMSTATE_UINT64_ARRAY (env.dmmu.mmuregs,SPARCCPU ,16 ),VMSTATE_STRUCT_ARRAY (env.itlb,SPARCCPU ,64 ,0 , vmstate_tlb_entry, SparcTLBEntry), VMSTATE_STRUCT_ARRAY(env.dtlb, SPARCCPU, 64, 0,
Signature · 1 line
1.8.3.1
PATCH v2 20/30 target-sparc: implement UA2005 TSB Pointers
In reply to Artyom Tarasenko--- target/sparc/cpu.h | 2 + target/sparc/ldst_helper.c | 124 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 104 insertions(+), 22 deletions(-)
target/sparc/cpu.h +2 -0
@@ -417,6 +417,8 @@ typedef union {uint64_t tag_access;uint64_t virtual_watchpoint;uint64_t physical_watchpoint; +uint64_t sun4v_ctx_config[2 ]; + uint64_t sun4v_tsb_pointers[4]; }; } SparcV9MMU;#endif
target/sparc/ldst_helper.c +102 -22
173 lines not on this page · raw message
Signature · 1 line
1.8.3.1
PATCH v2 21/30 target-sparc: simplify ultrasparc_tsb_pointer
In reply to Artyom Tarasenko--- target/sparc/ldst_helper.c | 51 ++++++++++++++-------------------------------- 1 file changed, 15 insertions(+), 36 deletions(-)
target/sparc/ldst_helper.c +15 -36
@@ -70,44 +70,35 @@#define QT1 (env->qt1)#if defined(TARGET_SPARC64 ) && !defined(CONFIG_USER_ONLY ) -static uint64_t ultrasparc_tsb_pointer (CPUSPARCState *env,uint64_t tsb, -uint64_t *tsb_ptr, -uint64_t tag_access_register, -int idx,uint64_t *cfg_ptr)/* Calculates TSB pointer value for fault page size * UltraSPARC IIi has fixed sizes (8k or 64k) for the page pointers * UA2005 holds the page size configuration in mmu_ctx registers */ +static uint64_t ultrasparc_tsb_pointer (CPUSPARCState *env, +const SparcV9MMU *mmu,const int idx) {uint64_t tsb_register;int page_size;if (cpu_has_hypervisor (env)) {int tsb_index =0 ; -int ctx = tag_access_register &0x1fffULL ; -uint64_t ctx_register = cfg_ptr[ctx ?1 :0 ]; +int ctx = mmu->tag_access &0x1fffULL ; +uint64_t ctx_register = mmu->sun4v_ctx_config[ctx ?1 :0 ]; tsb_index = idx; tsb_index |= ctx ?2 :0 ; page_size = idx ? ctx_register >>8 : ctx_register; page_size &=7 ; - tsb_register = tsb_ptr[tsb_index]; + tsb_register = mmu->sun4v_tsb_pointers[tsb_index]; }else { page_size = idx; - tsb_register = tsb; + tsb_register = mmu->tsb; } -uint64_t tsb_base = tsb_register & ~0x1fffULL ;int tsb_split = (tsb_register &0x1000ULL ) ?1 :0 ;int tsb_size = tsb_register &0xf ; -/* discard lower 13 bits which hold tag access context */ -uint64_t tag_access_va = tag_access_register & ~0x1fffULL ; +uint64_t tsb_base_mask = (~0x1fffULL ) << tsb_size; -/* now reorder bits */ -uint64_t tsb_base_mask = ~0x1fffULL ; -uint64_t va = tag_access_va; - -/* move va bits to correct position */ - va >>=3 * page_size +9 ; - - tsb_base_mask <<= tsb_size; +/* move va bits to correct position, +* the context bits will be masked out later */ +uint64_t va = mmu->tag_access >> (3 * page_size +9 );/* calculate tsb_base mask and adjust va if split is in use */ if (tsb_split) {
@@ -119,7 +110,7 @@ static uint64_t ultrasparc_tsb_pointer(CPUSPARCState *env, uint64_t tsb, tsb_base_mask <<=1 ; } -return ((tsb_base & tsb_base_mask) | (va & ~tsb_base_mask)) & ~0xfULL ; +return ((tsb_register & tsb_base_mask) | (va & ~tsb_base_mask)) & ~0xfULL ; }/* Calculates tag target register value by reordering bits
@@ -1266,20 +1257,14 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, {/* env->immuregs[5] holds I-MMU TSB register value env->immuregs[6] holds I-MMU Tag Access register value */ - ret =ultrasparc_tsb_pointer (env, env->immu.tsb, - env->immu.sun4v_tsb_pointers, - env->immu.tag_access, -0 , env->immu.sun4v_ctx_config); + ret =ultrasparc_tsb_pointer (env, &env->immu,0 );break ; }case ASI_IMMU_TSB_64KB_PTR :/* I-MMU 64k TSB pointer */ {/* env->immuregs[5] holds I-MMU TSB register value env->immuregs[6] holds I-MMU Tag Access register value */ - ret =ultrasparc_tsb_pointer (env, env->immu.tsb, - env->immu.sun4v_tsb_pointers, - env->immu.tag_access, -1 , env->immu.sun4v_ctx_config); + ret =ultrasparc_tsb_pointer (env, &env->immu,1 );break ; }case ASI_ITLB_DATA_ACCESS :/* I-MMU data access */
@@ -1338,20 +1323,14 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, {/* env->dmmuregs[5] holds D-MMU TSB register value env->dmmuregs[6] holds D-MMU Tag Access register value */ - ret =ultrasparc_tsb_pointer (env, env->dmmu.tsb, - env->dmmu.sun4v_tsb_pointers, - env->dmmu.tag_access, -0 , env->dmmu.sun4v_ctx_config); + ret =ultrasparc_tsb_pointer (env, &env->dmmu,0 );break ; }case ASI_DMMU_TSB_64KB_PTR :/* D-MMU 64k TSB pointer */ {/* env->dmmuregs[5] holds D-MMU TSB register value env->dmmuregs[6] holds D-MMU Tag Access register value */ - ret =ultrasparc_tsb_pointer (env, env->dmmu.tsb, - env->dmmu.sun4v_tsb_pointers, - env->dmmu.tag_access, -1 , env->dmmu.sun4v_ctx_config); + ret =ultrasparc_tsb_pointer (env, &env->dmmu,1 );break ; }case ASI_DTLB_DATA_ACCESS :/* D-MMU data access */
Signature · 1 line
1.8.3.1
PATCH v2 22/30 target-sparc: allow 256M sized pages
In reply to Artyom Tarasenko--- target/sparc/mmu_helper.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-)
target/sparc/mmu_helper.c +1 -17
@@ -456,23 +456,7 @@ static inline int ultrasparc_tag_match(SparcTLBEntry *tlb, uint64_t address, uint64_t context, hwaddr *physical) { - uint64_t mask; - -switch (TTE_PGSIZE (tlb->tte)) { -default : -case 0x0 :/* 8k */ - mask =0xffffffffffffe000ULL ; -break ; -case 0x1 :/* 64k */ - mask =0xffffffffffff0000ULL ; -break ; -case 0x2 :/* 512k */ - mask =0xfffffffffff80000ULL ; -break ; -case 0x3 :/* 4M */ - mask =0xffffffffffc00000ULL ; -break ; - } + uint64_t mask = -(8192ULL << 3 * TTE_PGSIZE(tlb->tte));/* valid, context match, virtual address match? */ if (TTE_IS_VALID(tlb->tte) &&
Signature · 1 line
1.8.3.1
PATCH v2 23/30 target-sparc: implement auto-demapping for UA2005 CPUs
In reply to Artyom Tarasenko--- target/sparc/ldst_helper.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
target/sparc/ldst_helper.c +22 -0
@@ -210,6 +210,28 @@ static void replace_tlb_1bit_lru(SparcTLBEntry *tlb, {unsigned int i, replace_used; +if (cpu_has_hypervisor (env1)) { +uint64_t new_vaddr = tlb_tag & ~0x1fffULL ; +uint64_t new_size =8192ULL <<3 *TTE_PGSIZE (tlb_tte); +uint32_t new_ctx = tlb_tag &0x1fffU ; +for (i =0 ; i <64 ; i++) { +uint32_t ctx = tlb[i].tag &0x1fffU ; +/* check if new mapping overlaps an existing one */ +if (new_ctx == ctx) { +uint64_t vaddr = tlb[i].tag & ~0x1fffULL ; +uint64_t size =8192ULL <<3 *TTE_PGSIZE (tlb[i].tte); +if (new_vaddr == vaddr + || (new_vaddr < vaddr + size + && vaddr < new_vaddr + new_size)) { +DPRINTF_MMU ("auto demap entry [%d] %lx->%lx\n" , i, vaddr, + new_vaddr); +replace_tlb_entry (&tlb[i], tlb_tag, tlb_tte, env1); +return ; + } + } + + } + }/* Try replacing invalid entry */ for (i =0 ; i <64 ; i++) {if (!TTE_IS_VALID (tlb[i].tte)) {
Signature · 1 line
1.8.3.1
PATCH v2 24/30 target-sparc: add more registers to dump_mmu
In reply to Artyom Tarasenko--- target/sparc/mmu_helper.c | 2 ++ 1 file changed, 2 insertions(+)
target/sparc/mmu_helper.c +2 -0
@@ -741,6 +741,8 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUSPARCState *env) PRId64"\n" , env->dmmu.mmu_primary_context, env->dmmu.mmu_secondary_context); + (*cpu_fprintf)(f,"DMMU Tag Access: %" PRIx64", TSB Tag Target: %" PRIx64 +"\n" , env->dmmu.tag_access, env->dmmu.tsb_tag_target);if ((env->lsu &DMMU_E ) ==0 ) { (*cpu_fprintf)(f,"DMMU disabled\n" ); }else {
Signature · 1 line
1.8.3.1
PATCH v2 25/30 target-sparc: implement UA2005 ASI_MMU (0x21)
In reply to Artyom Tarasenko--- target/sparc/ldst_helper.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
target/sparc/ldst_helper.c +31 -0
@@ -1394,6 +1394,18 @@ uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, ret = env->scratch[i];break ; } +case ASI_MMU :/* UA2005 Context ID registers */ +switch ((addr >>3 ) &0x3 ) { +case 1 : + ret = env->dmmu.mmu_primary_context; +break ; +case 2 : + ret = env->dmmu.mmu_secondary_context; +break ; +default : +cpu_unassigned_access (cs, addr, true, false,1 , size); + } +break ;case ASI_DCACHE_DATA :/* D-cache data */ case ASI_DCACHE_TAG :/* D-cache tag access */ case ASI_ESTATE_ERROR_EN :/* E-cache error enable */
@@ -1712,6 +1724,25 @@ void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val, env->scratch[i] = val;return ; } +case ASI_MMU :/* UA2005 Context ID registers */ + { +switch ((addr >>3 ) &0x3 ) { +case 1 : + env->dmmu.mmu_primary_context = val; + env->immu.mmu_primary_context = val; +tlb_flush_by_mmuidx (CPU (cpu),MMU_USER_IDX ,MMU_KERNEL_IDX ,-1 ); +break ; +case 2 : + env->dmmu.mmu_secondary_context = val; + env->immu.mmu_secondary_context = val; +tlb_flush_by_mmuidx (CPU (cpu),MMU_USER_SECONDARY_IDX , +MMU_KERNEL_SECONDARY_IDX ,-1 ); +break ; +default : +cpu_unassigned_access (cs, addr, true, false,1 , size); + } + } +return ;case ASI_QUEUE :/* UA2005 CPU mondo queue */ case ASI_DCACHE_DATA :/* D-cache data */ case ASI_DCACHE_TAG :/* D-cache tag access */
Signature · 1 line
1.8.3.1
PATCH v2 27/30 target-sparc: add ST_BLKINIT_ ASIs for UA2005+ CPUs
In reply to Artyom TarasenkoIn OpenSPARC T1+ TWINX ASIs in store instructions are aliased with Block Initializing Store ASIs.
"UltraSPARC T1 Supplement Draft D2.1, 14 May 2007" describes them in the chapter "5.9 Block Initializing Store ASIs"
Integer stores of all sizes are allowed with these ASIs.
--- target/sparc/translate.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
target/sparc/translate.c +11 -0
@@ -2321,8 +2321,19 @@ static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr,case GET_ASI_EXCP :break ;case GET_ASI_DTWINX :/* Reserved for stda. */ +#ifndef TARGET_SPARC64 gen_exception (dc,TT_ILL_INSN );break ; +#else +if (!(dc->def->features &CPU_FEATURE_HYPV )) { +/* Pre OpenSPARC CPUs don't have these */ +gen_exception (dc,TT_ILL_INSN ); +return ; + } +/* in OpenSPARC T1+ CPUs TWINX ASIs in store instructions +* are ST_BLKINIT_ ASIs */ +/* fall through */ +#endif case GET_ASI_DIRECT :gen_address_mask (dc, addr);tcg_gen_qemu_st_tl (src, addr, da.mem_idx, da.memop);
Signature · 1 line
1.8.3.1
PATCH v2 28/30 target-sparc: implement sun4v RTC
In reply to Artyom Tarasenko--- MAINTAINERS | 6 +++ hw/timer/Makefile.objs | 2 + hw/timer/sun4v-rtc.c | 102 +++++++++++++++++++++++++++++++++++++++++++ include/hw/timer/sun4v-rtc.h | 1 + 4 files changed, 111 insertions(+) create mode 100644 hw/timer/sun4v-rtc.c create mode 100644 include/hw/timer/sun4v-rtc.h
MAINTAINERS +6 -0
@@ -1098,6 +1098,12 @@ F: hw/nvram/chrp_nvram.c F: include/hw/nvram/chrp_nvram.h F: tests/prom-env-test.c +sun4v RTC +M: Artyom Tarasenko <[email protected]> +S: Maintained +F: hw/timer/sun4v-rtc.c +F: include/hw/timer/sun4v-rtc.h + Subsystems ---------- Audio
hw/timer/Makefile.objs +2 -0
@@ -34,3 +34,5 @@ obj-$(CONFIG_ALLWINNER_A10_PIT) += allwinner-a10-pit.o common-obj-$(CONFIG_STM32F2XX_TIMER) += stm32f2xx_timer.o common-obj-$(CONFIG_ASPEED_SOC) += aspeed_timer.o + +common-obj-$(CONFIG_SUN4V_RTC) += sun4v-rtc.o
hw/timer/sun4v-rtc.c new file +102 -0
102 lines not on this page · raw message
include/hw/timer/sun4v-rtc.h new file +1 -0
@@ -0,0 +1 @@ +void sun4v_rtc_init (hwaddr addr);
Signature · 1 line
1.8.3.1
PATCH v2 30/30 target-sparc: fix up niagara machine
In reply to Artyom TarasenkoRemove the Niagara stub implementation from sun4u.c and add a machine, compatible with Legion simulator from the OpenSPARC T1 project.
The machine uses the firmware supplied with the OpenSPARC T1 project,
http://download.oracle.com/technetwork/systems/opensparc/OpenSPARCT1_Arch.1.5.tar.bz2
in the directory S10image/, and is able to boot the supplied Solaris 10 image.
Note that for compatibility with the naming conventions for SPARC machines the new machine name is lowercase niagara.
--- MAINTAINERS | 13 +-- default-configs/sparc64-softmmu.mak | 2 + hw/sparc64/Makefile.objs | 1 + hw/sparc64/niagara.c | 177 ++++++++++++++++++++++++++++++++++++ hw/sparc64/sun4u.c | 31 ------- qemu-doc.texi | 14 ++- 6 files changed, 199 insertions(+), 39 deletions(-) create mode 100644 hw/sparc64/niagara.c
MAINTAINERS +7 -6
@@ -725,6 +725,13 @@ S: Maintained F: hw/sparc64/sun4u.c F: pc-bios/openbios-sparc64 +Sun4v +M: Artyom Tarasenko <[email protected]> +S: Maintained +F: hw/sparc64/sun4v.c +F: hw/timer/sun4v-rtc.c +F: include/hw/timer/sun4v-rtc.h + Leon3 M: Fabien Chouteau <[email protected]> S: Maintained
@@ -1098,12 +1105,6 @@ F: hw/nvram/chrp_nvram.c F: include/hw/nvram/chrp_nvram.h F: tests/prom-env-test.c -sun4v RTC -M: Artyom Tarasenko <[email protected]> -S: Maintained -F: hw/timer/sun4v-rtc.c -F: include/hw/timer/sun4v-rtc.h - Subsystems ---------- Audio
default-configs/sparc64-softmmu.mak +2 -0
@@ -13,3 +13,5 @@ CONFIG_IDE_CMD646=y CONFIG_PCI_APB=y CONFIG_MC146818RTC=y CONFIG_ISA_TESTDEV=y +CONFIG_EMPTY_SLOT=y +CONFIG_SUN4V_RTC=y
hw/sparc64/Makefile.objs +1 -0
@@ -1,2 +1,3 @@ obj-y += sparc64.o obj-y += sun4u.o +obj-y += niagara.o
hw/sparc64/niagara.c new file +177 -0
177 lines not on this page · raw message
hw/sparc64/sun4u.c +0 -31
@@ -542,7 +542,6 @@ static void sun4uv_init(MemoryRegion *address_space_mem,enum { sun4u_id =0 , sun4v_id =64 , - niagara_id, };static const struct hwdef hwdefs[] = {
@@ -560,13 +559,6 @@ static const struct hwdef hwdefs[] = { .prom_addr = 0x1fff0000000ULL, .console_serial_base = 0, }, -/* Sun4v generic Niagara machine */ - { - .default_cpu_model = "Sun UltraSparc T1", - .machine_id = niagara_id, - .prom_addr = 0xfff0000000ULL, - .console_serial_base = 0xfff0c2c000ULL, - }, };/* Sun4u hardware initialisation */
@@ -581,12 +573,6 @@ static void sun4v_init(MachineState *machine)sun4uv_init (get_system_memory (), machine, &hwdefs[1 ]); } -/* Niagara hardware initialisation */ -static void niagara_init (MachineState *machine) -{ -sun4uv_init (get_system_memory (), machine, &hwdefs[2 ]); -} -static void sun4u_class_init (ObjectClass *oc,void *data) {MachineClass *mc =MACHINE_CLASS (oc);
@@ -620,22 +606,6 @@ static const TypeInfo sun4v_type = { .class_init = sun4v_class_init, }; -static void niagara_class_init (ObjectClass *oc,void *data) -{ -MachineClass *mc =MACHINE_CLASS (oc); - - mc->desc ="Sun4v platform, Niagara" ; - mc->init = niagara_init; - mc->max_cpus =1 ;/* XXX for now */ - mc->default_boot_order ="c" ; -} - -static const TypeInfo niagara_type = { - .name =MACHINE_TYPE_NAME ("Niagara" ), - .parent =TYPE_MACHINE , - .class_init = niagara_class_init, -}; -static void sun4u_register_types (void ) {type_register_static (&ebus_info);
@@ -644,7 +614,6 @@ static void sun4u_register_types(void)type_register_static (&sun4u_type);type_register_static (&sun4v_type); -type_register_static (&niagara_type); }type_init (sun4u_register_types)
qemu-doc.texi +12 -2
@@ -2138,7 +2138,17 @@ Use the executable @file{qemu-system-sparc64} to simulate a Sun4u (UltraSPARC PC-like machine), Sun4v (T1 PC-like machine), or generic Niagara (T1) machine. The Sun4u emulator is mostly complete, being able to run Linux, NetBSD and OpenBSD in headless (-nographic) mode. The -Sun4v and Niagara emulators are still a work in progress. +Sun4v emulator is still a work in progress. + +The Niagara T1 emulator makes use of firmware and OS binaries supplied in the S10image/ directory +of the OpenSPARC T1 project @url{http://download.oracle.com/technetwork/systems/opensparc/OpenSPARCT1_Arch.1.5.tar.bz2} +and is able to boot the disk.s10hw2 Solaris image. +@example +qemu-system-sparc64 -M niagara -L /path-to/S10image/ \ + -nographic -m 256 \ + -drive if=pflash,readonly=on,file=/S10image/disk.s10hw2 +@end example + QEMU emulates the following peripherals:
@@ -2173,7 +2183,7 @@ Set OpenBIOS variables in NVRAM, for example: qemu-system-sparc64 -prom-env 'auto-boot?=false' @end example -@item -M [sun4u|sun4v|Niagara] +@item -M [sun4u|sun4v|niagara] Set the emulated machine type. The default is sun4u.
Signature · 1 line
1.8.3.1
PATCH v2 29/30 target-sparc: move common cpu initialisation routines to sparc64.c
In reply to Artyom Tarasenko--- hw/sparc64/Makefile.objs | 1 + hw/sparc64/sparc64.c | 378 +++++++++++++++++++++++++++++++++++++++++++++ hw/sparc64/sun4u.c | 348 +---------------------------------------- hw/timer/sun4v-rtc.c | 2 +- include/hw/sparc/sparc64.h | 5 + 5 files changed, 389 insertions(+), 345 deletions(-) create mode 100644 hw/sparc64/sparc64.c create mode 100644 include/hw/sparc/sparc64.h
hw/sparc64/Makefile.objs +1 -0
@@ -1 +1,2 @@ +obj-y += sparc64.o obj-y += sun4u.o
hw/sparc64/sparc64.c new file +378 -0
378 lines not on this page · raw message
hw/sparc64/sun4u.c +4 -344
403 lines not on this page · raw message
hw/timer/sun4v-rtc.c +1 -1
@@ -36,7 +36,7 @@ typedef struct Sun4vRtc {static uint64_t sun4v_rtc_read (void *opaque,hwaddr addr,unsigned size) { -uint64_t val =qemu_clock_get_ms (QEMU_CLOCK_REALTIME ) /1000 ; +uint64_t val =get_clock_realtime () /NANOSECONDS_PER_SECOND ;if (!(addr &4ULL )) {/* accessing the high 32 bits */ val >>=32 ;
include/hw/sparc/sparc64.h new file +5 -0
@@ -0,0 +1,5 @@ + +SPARCCPU *sparc64_cpu_devinit (const char *cpu_model, +const char *dflt_cpu_model,uint64_t prom_addr); + +void sparc64_cpu_set_ivec_irq (void *opaque,int irq,int level);
Signature · 1 line
1.8.3.1
Re: [Qemu-devel] [PATCH v2 30/30] target-sparc: fix up niagara machine
In reply to Artyom Tarasenkoniagara_init() does something naughty, which conflicts with Max's "[PATCH v6 0/9] block: Drop BDS.filename". Details inline.
Quoted 160 lines · Artyom Tarasenko
Remove the Niagara stub implementation from
sun4u.cand add a machine, compatible with Legion simulator from the OpenSPARC T1 project.The machine uses the firmware supplied with the OpenSPARC T1 project,
http://download.oracle.com/technetwork/systems/opensparc/OpenSPARCT1_Arch.1.5.tar.bz2
in the directory S10image/, and is able to boot the supplied Solaris 10 image.Note that for compatibility with the naming conventions for SPARC machines the new machine name is lowercase niagara.
Signed-off-by Artyom Tarasenko <[email protected]>Reviewed-by Richard Henderson <[email protected]>--- MAINTAINERS | 13 +-- default-configs/sparc64-softmmu.mak | 2 + hw/sparc64/Makefile.objs | 1 + hw/sparc64/niagara.c | 177 ++++++++++++++++++++++++++++++++++++ hw/sparc64/sun4u.c | 31 ------- qemu-doc.texi | 14 ++- 6 files changed, 199 insertions(+), 39 deletions(-) create mode 100644 hw/sparc64/niagara.cMAINTAINERS +7
-6@@ -725,6 +725,13 @@ S: Maintained F: hw/sparc64/sun4u.c F: pc-bios/openbios-sparc64 +Sun4v +M: Artyom Tarasenko <[email protected]> +S: Maintained +F: hw/sparc64/sun4v.c +F: hw/timer/sun4v-rtc.c +F: include/hw/timer/sun4v-rtc.h + Leon3 M: Fabien Chouteau <[email protected]> S: Maintained@@ -1098,12 +1105,6 @@ F: hw/nvram/chrp_nvram.c F: include/hw/nvram/chrp_nvram.h F: tests/prom-env-test.c -sun4v RTC -M: Artyom Tarasenko <[email protected]> -S: Maintained -F: hw/timer/sun4v-rtc.c -F: include/hw/timer/sun4v-rtc.h - Subsystems ---------- Audiodefault-configs/sparc64-softmmu.mak +2
-0@@ -13,3 +13,5 @@ CONFIG_IDE_CMD646=y CONFIG_PCI_APB=y CONFIG_MC146818RTC=y CONFIG_ISA_TESTDEV=y +CONFIG_EMPTY_SLOT=y +CONFIG_SUN4V_RTC=yhw/sparc64/Makefile.objs +1
-0@@ -1,2 +1,3 @@ obj-y += sparc64.o obj-y += sun4u.o +obj-y += niagara.ohw/sparc64/niagara.c new file +82
-0@@ -0,0 +1,177 @@ +/* +* QEMU Sun4v/Niagara System Emulator +* +* Copyright (c) 2016 Artyom Tarasenko +* +* 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. +*/ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" +#include "hw/hw.h" +#include "hw/boards.h" +#include "hw/char/serial.h" +#include "hw/empty_slot.h" +#include "hw/loader.h" +#include "hw/sparc/sparc64.h" +#include "hw/timer/sun4v-rtc.h" +#include "exec/address-spaces.h" +#include "sysemu/block-backend.h" + + +typedef struct NiagaraBoardState { +MemoryRegion hv_ram; +MemoryRegion partition_ram; +MemoryRegion nvram; +MemoryRegion md_rom; +MemoryRegion hv_rom; +MemoryRegion vdisk_ram; +MemoryRegion prom; +}NiagaraBoardState ; + +#define NIAGARA_HV_RAM_BASE 0x100000ULL +#define NIAGARA_HV_RAM_SIZE 0x3f00000ULL/* 63 MiB */ + +#define NIAGARA_PARTITION_RAM_BASE 0x80000000ULL + +#define NIAGARA_UART_BASE 0x1f10000000ULL + +#define NIAGARA_NVRAM_BASE 0x1f11000000ULL +#define NIAGARA_NVRAM_SIZE 0x2000 + +#define NIAGARA_MD_ROM_BASE 0x1f12000000ULL +#define NIAGARA_MD_ROM_SIZE 0x2000 + +#define NIAGARA_HV_ROM_BASE 0x1f12080000ULL +#define NIAGARA_HV_ROM_SIZE 0x2000 + +#define NIAGARA_IOBBASE 0x9800000000ULL +#define NIAGARA_IOBSIZE 0x0100000000ULL + +#define NIAGARA_VDISK_BASE 0x1f40000000ULL +#define NIAGARA_RTC_BASE 0xfff0c1fff8ULL +#define NIAGARA_UART_BASE 0x1f10000000ULL + +/* Firmware layout +* +* |------------------| +* | openboot.bin | +* |------------------| PROM_ADDR + OBP_OFFSET +* | q.bin | +* |------------------| PROM_ADDR + Q_OFFSET +* | reset.bin | +* |------------------| PROM_ADDR +*/
hw/sparc64/niagara.c line 92
Quoted 10 lines
hw/sparc64/niagara.c new file +10
-0+#define NIAGARA_PROM_BASE 0xfff0000000ULL +#define NIAGARA_Q_OFFSET 0x10000ULL +#define NIAGARA_OBP_OFFSET 0x80000ULL +#define PROM_SIZE_MAX (4 * 1024 * 1024) + +/* Niagara hardware initialisation */ +static void niagara_init (MachineState *machine) +{ +NiagaraBoardState *s =g_new (NiagaraBoardState,1 ); +DriveInfo *dinfo =drive_get_next (IF_PFLASH );
@dinfo is the first -drive if=pflash (or its sugared form -pflash).
Quoted 32 lines
hw/sparc64/niagara.c new file +32
-0+MemoryRegion *sysmem =get_system_memory (); + +/* init CPUs */ +sparc64_cpu_devinit (machine->cpu_model,"Sun UltraSparc T1" , +NIAGARA_PROM_BASE ); +/* set up devices */ +memory_region_allocate_system_memory (&s->hv_ram,NULL ,"sun4v-hv.ram" , +NIAGARA_HV_RAM_SIZE ); +memory_region_add_subregion (sysmem,NIAGARA_HV_RAM_BASE , &s->hv_ram); + +memory_region_allocate_system_memory (&s->partition_ram,NULL , +"sun4v-partition.ram" , + machine->ram_size); +memory_region_add_subregion (sysmem,NIAGARA_PARTITION_RAM_BASE , + &s->partition_ram); + +memory_region_allocate_system_memory (&s->nvram,NULL , +"sun4v.nvram" ,NIAGARA_NVRAM_SIZE ); +memory_region_add_subregion (sysmem,NIAGARA_NVRAM_BASE , &s->nvram); +memory_region_allocate_system_memory (&s->md_rom,NULL , +"sun4v-md.rom" ,NIAGARA_MD_ROM_SIZE ); +memory_region_add_subregion (sysmem,NIAGARA_MD_ROM_BASE , &s->md_rom); +memory_region_allocate_system_memory (&s->hv_rom,NULL , +"sun4v-hv.rom" ,NIAGARA_HV_ROM_SIZE ); +memory_region_add_subregion (sysmem,NIAGARA_HV_ROM_BASE , &s->hv_rom); +memory_region_allocate_system_memory (&s->prom,NULL , +"sun4v.prom" ,PROM_SIZE_MAX ); +memory_region_add_subregion (sysmem,NIAGARA_PROM_BASE , &s->prom); + +rom_add_file_fixed ("nvram1" ,NIAGARA_NVRAM_BASE ,-1 ); +rom_add_file_fixed ("1up-md.bin" ,NIAGARA_MD_ROM_BASE ,-1 ); +rom_add_file_fixed ("1up-hv.bin" ,NIAGARA_HV_ROM_BASE ,-1 );
hw/sparc64/niagara.c line 134
Quoted 10 lines
hw/sparc64/niagara.c new file +10
-0+ +rom_add_file_fixed ("reset.bin" ,NIAGARA_PROM_BASE ,-1 ); +rom_add_file_fixed ("q.bin" ,NIAGARA_PROM_BASE +NIAGARA_Q_OFFSET ,-1 ); +rom_add_file_fixed ("openboot.bin" ,NIAGARA_PROM_BASE +NIAGARA_OBP_OFFSET , +-1 ); + +/* the virtual ramdisk is kind of initrd, but it resides +outside of the partition RAM */ +if (dinfo) { +BlockBackend *blk =blk_by_legacy_dinfo (dinfo);
This is the block backend created by the first -drive if=pflash.
hw/sparc64/niagara.c line 142
Quoted 8 lines
hw/sparc64/niagara.c new file +8
-0+int size =blk_getlength (blk); +if (size >0 ) { +memory_region_allocate_system_memory (&s->vdisk_ram,NULL , +"sun4v_vdisk.ram" , size); +memory_region_add_subregion (get_system_memory (), +NIAGARA_VDISK_BASE , &s->vdisk_ram); + dinfo->is_default =1 ; +rom_add_file_fixed (blk_bs (blk)->filename,NIAGARA_VDISK_BASE ,-1 );
The block backend isn't actually used. It's merely a carrier for a filename. Naughty. Also conflicts with Max's work to kill ->filename.
What you create for it isn't actually a pflash device. Naughty.
Despite rom_add_file_fixed(), it's RAM, not ROM:
(qemu) info mtree
address-space: memory
0000000000000000-ffffffffffffffff (prio 0, RW): system
0000000000100000-0000000003ffffff (prio 0, RW): sun4v-hv.ram
0000000080000000-0000000087ffffff (prio 0, RW): sun4v-partition.ram
0000001f10000000-0000001f10000007 (prio 0, RW): serial
0000001f11000000-0000001f11001fff (prio 0, RW): sun4v.nvram
0000001f12000000-0000001f12001fff (prio 0, RW): sun4v-md.rom
0000001f12080000-0000001f12081fff (prio 0, RW): sun4v-hv.rom
0000001f40000000-0000001f413fffff (prio 0, RW): sun4v_vdisk.ram
0000009800000000-00000098ffffffff (prio 0, RW): empty-slot
000000fff0000000-000000fff03fffff (prio 0, RW): sun4v.prom
000000fff0c1fff8-000000fff0c1ffff (prio 0, RW): sun4v-rtc
address-space: I/O
0000000000000000-000000000000ffff (prio 0, RW): io
address-space: cpu-memory
0000000000000000-ffffffffffffffff (prio 0, RW): system
0000000000100000-0000000003ffffff (prio 0, RW): sun4v-hv.ram
0000000080000000-0000000087ffffff (prio 0, RW): sun4v-partition.ram
0000001f10000000-0000001f10000007 (prio 0, RW): serial
0000001f11000000-0000001f11001fff (prio 0, RW): sun4v.nvram
0000001f12000000-0000001f12001fff (prio 0, RW): sun4v-md.rom
0000001f12080000-0000001f12081fff (prio 0, RW): sun4v-hv.rom
---> 0000001f40000000-0000001f413fffff (prio 0, RW): sun4v_vdisk.ram
0000009800000000-00000098ffffffff (prio 0, RW): empty-slot
000000fff0000000-000000fff03fffff (prio 0, RW): sun4v.promNote that sun4v-md.rom and sun4v-hv.rom aren't ROM, either.
The monkey-patching of dinfo->is_default is to silence the "Orphaned drive without device" warning. Naughty.
This use of -drive if=pflash is highly unorthodox. To suggest better ways, we need to understand the role of "the virtual ramdisk". Can you explain? How does it work on a physical system?
Quoted 136 lines
hw/sparc64/niagara.c new file +35
-0+ }else { +fprintf (stderr,"qemu: could not load ram disk '%s'\n" , +blk_bs (blk)->filename); +exit (1 ); + } + } +serial_mm_init (sysmem,NIAGARA_UART_BASE ,0 ,NULL ,115200 , + serial_hds[0 ],DEVICE_BIG_ENDIAN ); + +empty_slot_init (NIAGARA_IOBBASE ,NIAGARA_IOBSIZE ); +sun4v_rtc_init (NIAGARA_RTC_BASE ); +} + +static void niagara_class_init (ObjectClass *oc,void *data) +{ +MachineClass *mc =MACHINE_CLASS (oc); + + mc->desc ="Sun4v platform, Niagara" ; + mc->init = niagara_init; + mc->max_cpus =1 ;/* XXX for now */ + mc->default_boot_order ="c" ; +} + +static const TypeInfo niagara_type = { + .name =MACHINE_TYPE_NAME ("niagara" ), + .parent =TYPE_MACHINE , + .class_init = niagara_class_init, +}; + +static void niagara_register_types (void ) +{ +type_register_static (&niagara_type); +} + +type_init (niagara_register_types)hw/sparc64/sun4u.c +0
-31@@ -542,7 +542,6 @@ static void sun4uv_init(MemoryRegion *address_space_mem,enum { sun4u_id =0 , sun4v_id =64 , - niagara_id, };static const struct hwdef hwdefs[] = {@@ -560,13 +559,6 @@ static const struct hwdef hwdefs[] = { .prom_addr = 0x1fff0000000ULL, .console_serial_base = 0, }, -/* Sun4v generic Niagara machine */ - { - .default_cpu_model = "Sun UltraSparc T1", - .machine_id = niagara_id, - .prom_addr = 0xfff0000000ULL, - .console_serial_base = 0xfff0c2c000ULL, - }, };/* Sun4u hardware initialisation */ @@ -581,12 +573,6 @@ static void sun4v_init(MachineState *machine)sun4uv_init (get_system_memory (), machine, &hwdefs[1 ]); } -/* Niagara hardware initialisation */ -static void niagara_init (MachineState *machine) -{ -sun4uv_init (get_system_memory (), machine, &hwdefs[2 ]); -} -static void sun4u_class_init (ObjectClass *oc,void *data) {MachineClass *mc =MACHINE_CLASS (oc);@@ -620,22 +606,6 @@ static const TypeInfo sun4v_type = { .class_init = sun4v_class_init, }; -static void niagara_class_init (ObjectClass *oc,void *data) -{ -MachineClass *mc =MACHINE_CLASS (oc); - - mc->desc ="Sun4v platform, Niagara" ; - mc->init = niagara_init; - mc->max_cpus =1 ;/* XXX for now */ - mc->default_boot_order ="c" ; -} - -static const TypeInfo niagara_type = { - .name =MACHINE_TYPE_NAME ("Niagara" ), - .parent =TYPE_MACHINE , - .class_init = niagara_class_init, -}; -static void sun4u_register_types (void ) {type_register_static (&ebus_info);@@ -644,7 +614,6 @@ static void sun4u_register_types(void)type_register_static (&sun4u_type);type_register_static (&sun4v_type); -type_register_static (&niagara_type); }type_init (sun4u_register_types)qemu-doc.texi +12
-2@@ -2138,7 +2138,17 @@ Use the executable @file{qemu-system-sparc64} to simulate a Sun4u (UltraSPARC PC-like machine), Sun4v (T1 PC-like machine), or generic Niagara (T1) machine. The Sun4u emulator is mostly complete, being able to run Linux, NetBSD and OpenBSD in headless (-nographic) mode. The -Sun4v and Niagara emulators are still a work in progress. +Sun4v emulator is still a work in progress. + +The Niagara T1 emulator makes use of firmware and OS binaries supplied in the S10image/ directory +of the OpenSPARC T1 project @url{http://download.oracle.com/technetwork/systems/opensparc/OpenSPARCT1_Arch.1.5.tar.bz2} +and is able to boot the disk.s10hw2 Solaris image. +@example +qemu-system-sparc64 -M niagara -L /path-to/S10image/ \ + -nographic -m 256 \ + -drive if=pflash,readonly=on,file=/S10image/disk.s10hw2 +@end example + QEMU emulates the following peripherals:@@ -2173,7 +2183,7 @@ Set OpenBIOS variables in NVRAM, for example: qemu-system-sparc64 -prom-env 'auto-boot?=false' @end example -@item -M [sun4u|sun4v|Niagara] +@item -M [sun4u|sun4v|niagara] Set the emulated machine type. The default is sun4u.
Re: [Qemu-devel] [PATCH v2 30/30] target-sparc: fix up niagara machine
Quoted 268 lines · Markus Armbruster
niagara_init()does something naughty, which conflicts with Max's "[PATCH v6 0/9] block: Drop BDS.filename". Details inline.Quoted 160 lines · Artyom Tarasenko
Remove the Niagara stub implementation from
sun4u.cand add a machine, compatible with Legion simulator from the OpenSPARC T1 project.The machine uses the firmware supplied with the OpenSPARC T1 project,
http://download.oracle.com/technetwork/systems/opensparc/OpenSPARCT1_Arch.1.5.tar.bz2
in the directory S10image/, and is able to boot the supplied Solaris 10 image.Note that for compatibility with the naming conventions for SPARC machines the new machine name is lowercase niagara.
Signed-off-by Artyom Tarasenko <[email protected]>Reviewed-by Richard Henderson <[email protected]>--- MAINTAINERS | 13 +-- default-configs/sparc64-softmmu.mak | 2 + hw/sparc64/Makefile.objs | 1 + hw/sparc64/niagara.c | 177 ++++++++++++++++++++++++++++++++++++ hw/sparc64/sun4u.c | 31 ------- qemu-doc.texi | 14 ++- 6 files changed, 199 insertions(+), 39 deletions(-) create mode 100644 hw/sparc64/niagara.cMAINTAINERS +7
-6@@ -725,6 +725,13 @@ S: Maintained F: hw/sparc64/sun4u.c F: pc-bios/openbios-sparc64 +Sun4v +M: Artyom Tarasenko <[email protected]> +S: Maintained +F: hw/sparc64/sun4v.c +F: hw/timer/sun4v-rtc.c +F: include/hw/timer/sun4v-rtc.h + Leon3 M: Fabien Chouteau <[email protected]> S: Maintained@@ -1098,12 +1105,6 @@ F: hw/nvram/chrp_nvram.c F: include/hw/nvram/chrp_nvram.h F: tests/prom-env-test.c -sun4v RTC -M: Artyom Tarasenko <[email protected]> -S: Maintained -F: hw/timer/sun4v-rtc.c -F: include/hw/timer/sun4v-rtc.h - Subsystems ---------- Audiodefault-configs/sparc64-softmmu.mak +2
-0@@ -13,3 +13,5 @@ CONFIG_IDE_CMD646=y CONFIG_PCI_APB=y CONFIG_MC146818RTC=y CONFIG_ISA_TESTDEV=y +CONFIG_EMPTY_SLOT=y +CONFIG_SUN4V_RTC=yhw/sparc64/Makefile.objs +1
-0@@ -1,2 +1,3 @@ obj-y += sparc64.o obj-y += sun4u.o +obj-y += niagara.ohw/sparc64/niagara.c new file +82
-0@@ -0,0 +1,177 @@ +/* +* QEMU Sun4v/Niagara System Emulator +* +* Copyright (c) 2016 Artyom Tarasenko +* +* 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. +*/ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" +#include "hw/hw.h" +#include "hw/boards.h" +#include "hw/char/serial.h" +#include "hw/empty_slot.h" +#include "hw/loader.h" +#include "hw/sparc/sparc64.h" +#include "hw/timer/sun4v-rtc.h" +#include "exec/address-spaces.h" +#include "sysemu/block-backend.h" + + +typedef struct NiagaraBoardState { +MemoryRegion hv_ram; +MemoryRegion partition_ram; +MemoryRegion nvram; +MemoryRegion md_rom; +MemoryRegion hv_rom; +MemoryRegion vdisk_ram; +MemoryRegion prom; +}NiagaraBoardState ; + +#define NIAGARA_HV_RAM_BASE 0x100000ULL +#define NIAGARA_HV_RAM_SIZE 0x3f00000ULL/* 63 MiB */ + +#define NIAGARA_PARTITION_RAM_BASE 0x80000000ULL + +#define NIAGARA_UART_BASE 0x1f10000000ULL + +#define NIAGARA_NVRAM_BASE 0x1f11000000ULL +#define NIAGARA_NVRAM_SIZE 0x2000 + +#define NIAGARA_MD_ROM_BASE 0x1f12000000ULL +#define NIAGARA_MD_ROM_SIZE 0x2000 + +#define NIAGARA_HV_ROM_BASE 0x1f12080000ULL +#define NIAGARA_HV_ROM_SIZE 0x2000 + +#define NIAGARA_IOBBASE 0x9800000000ULL +#define NIAGARA_IOBSIZE 0x0100000000ULL + +#define NIAGARA_VDISK_BASE 0x1f40000000ULL +#define NIAGARA_RTC_BASE 0xfff0c1fff8ULL +#define NIAGARA_UART_BASE 0x1f10000000ULL + +/* Firmware layout +* +* |------------------| +* | openboot.bin | +* |------------------| PROM_ADDR + OBP_OFFSET +* | q.bin | +* |------------------| PROM_ADDR + Q_OFFSET +* | reset.bin | +* |------------------| PROM_ADDR +*/ hw/sparc64/niagara.c line 92
Quoted 10 lines
hw/sparc64/niagara.c new file +10
-0+#define NIAGARA_PROM_BASE 0xfff0000000ULL +#define NIAGARA_Q_OFFSET 0x10000ULL +#define NIAGARA_OBP_OFFSET 0x80000ULL +#define PROM_SIZE_MAX (4 * 1024 * 1024) + +/* Niagara hardware initialisation */ +static void niagara_init (MachineState *machine) +{ +NiagaraBoardState *s =g_new (NiagaraBoardState,1 ); +DriveInfo *dinfo =drive_get_next (IF_PFLASH );@dinfo is the first -drive if=pflash (or its sugared form -pflash).
Quoted 32 lines
hw/sparc64/niagara.c new file +32
-0+MemoryRegion *sysmem =get_system_memory (); + +/* init CPUs */ +sparc64_cpu_devinit (machine->cpu_model,"Sun UltraSparc T1" , +NIAGARA_PROM_BASE ); +/* set up devices */ +memory_region_allocate_system_memory (&s->hv_ram,NULL ,"sun4v-hv.ram" , +NIAGARA_HV_RAM_SIZE ); +memory_region_add_subregion (sysmem,NIAGARA_HV_RAM_BASE , &s->hv_ram); + +memory_region_allocate_system_memory (&s->partition_ram,NULL , +"sun4v-partition.ram" , + machine->ram_size); +memory_region_add_subregion (sysmem,NIAGARA_PARTITION_RAM_BASE , + &s->partition_ram); + +memory_region_allocate_system_memory (&s->nvram,NULL , +"sun4v.nvram" ,NIAGARA_NVRAM_SIZE ); +memory_region_add_subregion (sysmem,NIAGARA_NVRAM_BASE , &s->nvram); +memory_region_allocate_system_memory (&s->md_rom,NULL , +"sun4v-md.rom" ,NIAGARA_MD_ROM_SIZE ); +memory_region_add_subregion (sysmem,NIAGARA_MD_ROM_BASE , &s->md_rom); +memory_region_allocate_system_memory (&s->hv_rom,NULL , +"sun4v-hv.rom" ,NIAGARA_HV_ROM_SIZE ); +memory_region_add_subregion (sysmem,NIAGARA_HV_ROM_BASE , &s->hv_rom); +memory_region_allocate_system_memory (&s->prom,NULL , +"sun4v.prom" ,PROM_SIZE_MAX ); +memory_region_add_subregion (sysmem,NIAGARA_PROM_BASE , &s->prom); + +rom_add_file_fixed ("nvram1" ,NIAGARA_NVRAM_BASE ,-1 ); +rom_add_file_fixed ("1up-md.bin" ,NIAGARA_MD_ROM_BASE ,-1 ); +rom_add_file_fixed ("1up-hv.bin" ,NIAGARA_HV_ROM_BASE ,-1 );hw/sparc64/niagara.c line 134
Quoted 10 lines
hw/sparc64/niagara.c new file +10
-0+ +rom_add_file_fixed ("reset.bin" ,NIAGARA_PROM_BASE ,-1 ); +rom_add_file_fixed ("q.bin" ,NIAGARA_PROM_BASE +NIAGARA_Q_OFFSET ,-1 ); +rom_add_file_fixed ("openboot.bin" ,NIAGARA_PROM_BASE +NIAGARA_OBP_OFFSET , +-1 ); + +/* the virtual ramdisk is kind of initrd, but it resides +outside of the partition RAM */ +if (dinfo) { +BlockBackend *blk =blk_by_legacy_dinfo (dinfo);This is the block backend created by the first -drive if=pflash.
hw/sparc64/niagara.c line 142
Quoted 8 lines
hw/sparc64/niagara.c new file +8
-0+int size =blk_getlength (blk); +if (size >0 ) { +memory_region_allocate_system_memory (&s->vdisk_ram,NULL , +"sun4v_vdisk.ram" , size); +memory_region_add_subregion (get_system_memory (), +NIAGARA_VDISK_BASE , &s->vdisk_ram); + dinfo->is_default =1 ; +rom_add_file_fixed (blk_bs (blk)->filename,NIAGARA_VDISK_BASE ,-1 );The block backend isn't actually used. It's merely a carrier for a filename. Naughty. Also conflicts with Max's work to kill ->filename.
What you create for it isn't actually a pflash device. Naughty.
Despite
rom_add_file_fixed(), it's RAM, not ROM:(qemu) info mtree address-space: memory 0000000000000000-ffffffffffffffff (prio 0, RW): system 0000000000100000-0000000003ffffff (prio 0, RW): sun4v-hv.ram 0000000080000000-0000000087ffffff (prio 0, RW): sun4v-partition.ram 0000001f10000000-0000001f10000007 (prio 0, RW): serial 0000001f11000000-0000001f11001fff (prio 0, RW): sun4v.nvram 0000001f12000000-0000001f12001fff (prio 0, RW): sun4v-md.rom 0000001f12080000-0000001f12081fff (prio 0, RW): sun4v-hv.rom 0000001f40000000-0000001f413fffff (prio 0, RW): sun4v_vdisk.ram 0000009800000000-00000098ffffffff (prio 0, RW): empty-slot 000000fff0000000-000000fff03fffff (prio 0, RW): sun4v.prom 000000fff0c1fff8-000000fff0c1ffff (prio 0, RW): sun4v-rtc address-space: I/O 0000000000000000-000000000000ffff (prio 0, RW): io address-space: cpu-memory 0000000000000000-ffffffffffffffff (prio 0, RW): system 0000000000100000-0000000003ffffff (prio 0, RW): sun4v-hv.ram 0000000080000000-0000000087ffffff (prio 0, RW): sun4v-partition.ram 0000001f10000000-0000001f10000007 (prio 0, RW): serial 0000001f11000000-0000001f11001fff (prio 0, RW): sun4v.nvram 0000001f12000000-0000001f12001fff (prio 0, RW): sun4v-md.rom 0000001f12080000-0000001f12081fff (prio 0, RW): sun4v-hv.rom ---> 0000001f40000000-0000001f413fffff (prio 0, RW): sun4v_vdisk.ram 0000009800000000-00000098ffffffff (prio 0, RW): empty-slot 000000fff0000000-000000fff03fffff (prio 0, RW): sun4v.prom
Quoted 1 line
Note that sun4v-md.rom and sun4v-hv.rom aren't ROM, either.
Is rom_add_file_fixed supposed to mark the memory region read-only? Or should it be created read-only before calling rom_add_file_fixed?
Quoted 6 lines
The monkey-patching of
dinfo->is_defaultis to silence the "Orphaned drive without device" warning. Naughty.This use of -drive if=pflash is highly unorthodox. To suggest better ways, we need to understand the role of "the virtual ramdisk". Can you explain? How does it work on a physical system?
AFAIK except for simulators it's only used on FPGA boards. It's what the comment says: a kind of initrd, but it resides outside of the partition RAM. So, it is a RAM region pre-filled with data in the way not visible to the guest.
I would have used an -initrd option instead of -pflash, but it required a -kernel option, and there is no sensible way to use the -kernel with Solaris.
If QEMU had something like a nvram-disk - it would have worked here the best.
Quoted 136 lines
Quoted 136 lines
hw/sparc64/niagara.c new file +35
-0+ }else { +fprintf (stderr,"qemu: could not load ram disk '%s'\n" , +blk_bs (blk)->filename); +exit (1 ); + } + } +serial_mm_init (sysmem,NIAGARA_UART_BASE ,0 ,NULL ,115200 , + serial_hds[0 ],DEVICE_BIG_ENDIAN ); + +empty_slot_init (NIAGARA_IOBBASE ,NIAGARA_IOBSIZE ); +sun4v_rtc_init (NIAGARA_RTC_BASE ); +} + +static void niagara_class_init (ObjectClass *oc,void *data) +{ +MachineClass *mc =MACHINE_CLASS (oc); + + mc->desc ="Sun4v platform, Niagara" ; + mc->init = niagara_init; + mc->max_cpus =1 ;/* XXX for now */ + mc->default_boot_order ="c" ; +} + +static const TypeInfo niagara_type = { + .name =MACHINE_TYPE_NAME ("niagara" ), + .parent =TYPE_MACHINE , + .class_init = niagara_class_init, +}; + +static void niagara_register_types (void ) +{ +type_register_static (&niagara_type); +} + +type_init (niagara_register_types)hw/sparc64/sun4u.c +0
-31@@ -542,7 +542,6 @@ static void sun4uv_init(MemoryRegion *address_space_mem,enum { sun4u_id =0 , sun4v_id =64 , - niagara_id, };static const struct hwdef hwdefs[] = {@@ -560,13 +559,6 @@ static const struct hwdef hwdefs[] = { .prom_addr = 0x1fff0000000ULL, .console_serial_base = 0, }, -/* Sun4v generic Niagara machine */ - { - .default_cpu_model = "Sun UltraSparc T1", - .machine_id = niagara_id, - .prom_addr = 0xfff0000000ULL, - .console_serial_base = 0xfff0c2c000ULL, - }, };/* Sun4u hardware initialisation */ @@ -581,12 +573,6 @@ static void sun4v_init(MachineState *machine)sun4uv_init (get_system_memory (), machine, &hwdefs[1 ]); } -/* Niagara hardware initialisation */ -static void niagara_init (MachineState *machine) -{ -sun4uv_init (get_system_memory (), machine, &hwdefs[2 ]); -} -static void sun4u_class_init (ObjectClass *oc,void *data) {MachineClass *mc =MACHINE_CLASS (oc);@@ -620,22 +606,6 @@ static const TypeInfo sun4v_type = { .class_init = sun4v_class_init, }; -static void niagara_class_init (ObjectClass *oc,void *data) -{ -MachineClass *mc =MACHINE_CLASS (oc); - - mc->desc ="Sun4v platform, Niagara" ; - mc->init = niagara_init; - mc->max_cpus =1 ;/* XXX for now */ - mc->default_boot_order ="c" ; -} - -static const TypeInfo niagara_type = { - .name =MACHINE_TYPE_NAME ("Niagara" ), - .parent =TYPE_MACHINE , - .class_init = niagara_class_init, -}; -static void sun4u_register_types (void ) {type_register_static (&ebus_info);@@ -644,7 +614,6 @@ static void sun4u_register_types(void)type_register_static (&sun4u_type);type_register_static (&sun4v_type); -type_register_static (&niagara_type); }type_init (sun4u_register_types)qemu-doc.texi +12
-2@@ -2138,7 +2138,17 @@ Use the executable @file{qemu-system-sparc64} to simulate a Sun4u (UltraSPARC PC-like machine), Sun4v (T1 PC-like machine), or generic Niagara (T1) machine. The Sun4u emulator is mostly complete, being able to run Linux, NetBSD and OpenBSD in headless (-nographic) mode. The -Sun4v and Niagara emulators are still a work in progress. +Sun4v emulator is still a work in progress. + +The Niagara T1 emulator makes use of firmware and OS binaries supplied in the S10image/ directory +of the OpenSPARC T1 project @url{http://download.oracle.com/technetwork/systems/opensparc/OpenSPARCT1_Arch.1.5.tar.bz2} +and is able to boot the disk.s10hw2 Solaris image. +@example +qemu-system-sparc64 -M niagara -L /path-to/S10image/ \ + -nographic -m 256 \ + -drive if=pflash,readonly=on,file=/S10image/disk.s10hw2 +@end example + QEMU emulates the following peripherals:@@ -2173,7 +2183,7 @@ Set OpenBIOS variables in NVRAM, for example: qemu-system-sparc64 -prom-env 'auto-boot?=false' @end example -@item -M [sun4u|sun4v|Niagara] +@item -M [sun4u|sun4v|niagara] Set the emulated machine type. The default is sun4u.
Signature · 4 lines
Regards, Artyom Tarasenko SPARC and PPC PReP under qemu blog: http://tyom.blogspot.com/search/label/qemu
Re: [Qemu-devel] [PATCH v2 30/30] target-sparc: fix up niagara machine
Quoted 269 lines · Artyom Tarasenko
Quoted 268 lines · Markus Armbruster
niagara_init()does something naughty, which conflicts with Max's "[PATCH v6 0/9] block: Drop BDS.filename". Details inline.Quoted 160 lines · Artyom Tarasenko
Remove the Niagara stub implementation from
sun4u.cand add a machine, compatible with Legion simulator from the OpenSPARC T1 project.The machine uses the firmware supplied with the OpenSPARC T1 project,
http://download.oracle.com/technetwork/systems/opensparc/OpenSPARCT1_Arch.1.5.tar.bz2
in the directory S10image/, and is able to boot the supplied Solaris 10 image.Note that for compatibility with the naming conventions for SPARC machines the new machine name is lowercase niagara.
Signed-off-by Artyom Tarasenko <[email protected]>Reviewed-by Richard Henderson <[email protected]>--- MAINTAINERS | 13 +-- default-configs/sparc64-softmmu.mak | 2 + hw/sparc64/Makefile.objs | 1 + hw/sparc64/niagara.c | 177 ++++++++++++++++++++++++++++++++++++ hw/sparc64/sun4u.c | 31 ------- qemu-doc.texi | 14 ++- 6 files changed, 199 insertions(+), 39 deletions(-) create mode 100644 hw/sparc64/niagara.cMAINTAINERS +7
-6@@ -725,6 +725,13 @@ S: Maintained F: hw/sparc64/sun4u.c F: pc-bios/openbios-sparc64 +Sun4v +M: Artyom Tarasenko <[email protected]> +S: Maintained +F: hw/sparc64/sun4v.c +F: hw/timer/sun4v-rtc.c +F: include/hw/timer/sun4v-rtc.h + Leon3 M: Fabien Chouteau <[email protected]> S: Maintained@@ -1098,12 +1105,6 @@ F: hw/nvram/chrp_nvram.c F: include/hw/nvram/chrp_nvram.h F: tests/prom-env-test.c -sun4v RTC -M: Artyom Tarasenko <[email protected]> -S: Maintained -F: hw/timer/sun4v-rtc.c -F: include/hw/timer/sun4v-rtc.h - Subsystems ---------- Audiodefault-configs/sparc64-softmmu.mak +2
-0@@ -13,3 +13,5 @@ CONFIG_IDE_CMD646=y CONFIG_PCI_APB=y CONFIG_MC146818RTC=y CONFIG_ISA_TESTDEV=y +CONFIG_EMPTY_SLOT=y +CONFIG_SUN4V_RTC=yhw/sparc64/Makefile.objs +1
-0@@ -1,2 +1,3 @@ obj-y += sparc64.o obj-y += sun4u.o +obj-y += niagara.ohw/sparc64/niagara.c new file +82
-0@@ -0,0 +1,177 @@ +/* +* QEMU Sun4v/Niagara System Emulator +* +* Copyright (c) 2016 Artyom Tarasenko +* +* 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. +*/ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu-common.h" +#include "cpu.h" +#include "hw/hw.h" +#include "hw/boards.h" +#include "hw/char/serial.h" +#include "hw/empty_slot.h" +#include "hw/loader.h" +#include "hw/sparc/sparc64.h" +#include "hw/timer/sun4v-rtc.h" +#include "exec/address-spaces.h" +#include "sysemu/block-backend.h" + + +typedef struct NiagaraBoardState { +MemoryRegion hv_ram; +MemoryRegion partition_ram; +MemoryRegion nvram; +MemoryRegion md_rom; +MemoryRegion hv_rom; +MemoryRegion vdisk_ram; +MemoryRegion prom; +}NiagaraBoardState ; + +#define NIAGARA_HV_RAM_BASE 0x100000ULL +#define NIAGARA_HV_RAM_SIZE 0x3f00000ULL/* 63 MiB */ + +#define NIAGARA_PARTITION_RAM_BASE 0x80000000ULL + +#define NIAGARA_UART_BASE 0x1f10000000ULL + +#define NIAGARA_NVRAM_BASE 0x1f11000000ULL +#define NIAGARA_NVRAM_SIZE 0x2000 + +#define NIAGARA_MD_ROM_BASE 0x1f12000000ULL +#define NIAGARA_MD_ROM_SIZE 0x2000 + +#define NIAGARA_HV_ROM_BASE 0x1f12080000ULL +#define NIAGARA_HV_ROM_SIZE 0x2000 + +#define NIAGARA_IOBBASE 0x9800000000ULL +#define NIAGARA_IOBSIZE 0x0100000000ULL + +#define NIAGARA_VDISK_BASE 0x1f40000000ULL +#define NIAGARA_RTC_BASE 0xfff0c1fff8ULL +#define NIAGARA_UART_BASE 0x1f10000000ULL + +/* Firmware layout +* +* |------------------| +* | openboot.bin | +* |------------------| PROM_ADDR + OBP_OFFSET +* | q.bin | +* |------------------| PROM_ADDR + Q_OFFSET +* | reset.bin | +* |------------------| PROM_ADDR +*/ hw/sparc64/niagara.c line 92
Quoted 10 lines
hw/sparc64/niagara.c new file +10
-0+#define NIAGARA_PROM_BASE 0xfff0000000ULL +#define NIAGARA_Q_OFFSET 0x10000ULL +#define NIAGARA_OBP_OFFSET 0x80000ULL +#define PROM_SIZE_MAX (4 * 1024 * 1024) + +/* Niagara hardware initialisation */ +static void niagara_init (MachineState *machine) +{ +NiagaraBoardState *s =g_new (NiagaraBoardState,1 ); +DriveInfo *dinfo =drive_get_next (IF_PFLASH );@dinfo is the first -drive if=pflash (or its sugared form -pflash).
Quoted 32 lines
hw/sparc64/niagara.c new file +32
-0+MemoryRegion *sysmem =get_system_memory (); + +/* init CPUs */ +sparc64_cpu_devinit (machine->cpu_model,"Sun UltraSparc T1" , +NIAGARA_PROM_BASE ); +/* set up devices */ +memory_region_allocate_system_memory (&s->hv_ram,NULL ,"sun4v-hv.ram" , +NIAGARA_HV_RAM_SIZE ); +memory_region_add_subregion (sysmem,NIAGARA_HV_RAM_BASE , &s->hv_ram); + +memory_region_allocate_system_memory (&s->partition_ram,NULL , +"sun4v-partition.ram" , + machine->ram_size); +memory_region_add_subregion (sysmem,NIAGARA_PARTITION_RAM_BASE , + &s->partition_ram); + +memory_region_allocate_system_memory (&s->nvram,NULL , +"sun4v.nvram" ,NIAGARA_NVRAM_SIZE ); +memory_region_add_subregion (sysmem,NIAGARA_NVRAM_BASE , &s->nvram); +memory_region_allocate_system_memory (&s->md_rom,NULL , +"sun4v-md.rom" ,NIAGARA_MD_ROM_SIZE ); +memory_region_add_subregion (sysmem,NIAGARA_MD_ROM_BASE , &s->md_rom); +memory_region_allocate_system_memory (&s->hv_rom,NULL , +"sun4v-hv.rom" ,NIAGARA_HV_ROM_SIZE ); +memory_region_add_subregion (sysmem,NIAGARA_HV_ROM_BASE , &s->hv_rom); +memory_region_allocate_system_memory (&s->prom,NULL , +"sun4v.prom" ,PROM_SIZE_MAX ); +memory_region_add_subregion (sysmem,NIAGARA_PROM_BASE , &s->prom); + +rom_add_file_fixed ("nvram1" ,NIAGARA_NVRAM_BASE ,-1 ); +rom_add_file_fixed ("1up-md.bin" ,NIAGARA_MD_ROM_BASE ,-1 ); +rom_add_file_fixed ("1up-hv.bin" ,NIAGARA_HV_ROM_BASE ,-1 );hw/sparc64/niagara.c line 134
Quoted 10 lines
hw/sparc64/niagara.c new file +10
-0+ +rom_add_file_fixed ("reset.bin" ,NIAGARA_PROM_BASE ,-1 ); +rom_add_file_fixed ("q.bin" ,NIAGARA_PROM_BASE +NIAGARA_Q_OFFSET ,-1 ); +rom_add_file_fixed ("openboot.bin" ,NIAGARA_PROM_BASE +NIAGARA_OBP_OFFSET , +-1 ); + +/* the virtual ramdisk is kind of initrd, but it resides +outside of the partition RAM */ +if (dinfo) { +BlockBackend *blk =blk_by_legacy_dinfo (dinfo);This is the block backend created by the first -drive if=pflash.
hw/sparc64/niagara.c line 142
Quoted 8 lines
hw/sparc64/niagara.c new file +8
-0+int size =blk_getlength (blk); +if (size >0 ) { +memory_region_allocate_system_memory (&s->vdisk_ram,NULL , +"sun4v_vdisk.ram" , size); +memory_region_add_subregion (get_system_memory (), +NIAGARA_VDISK_BASE , &s->vdisk_ram); + dinfo->is_default =1 ; +rom_add_file_fixed (blk_bs (blk)->filename,NIAGARA_VDISK_BASE ,-1 );The block backend isn't actually used. It's merely a carrier for a filename. Naughty. Also conflicts with Max's work to kill ->filename.
What you create for it isn't actually a pflash device. Naughty.
Despite
rom_add_file_fixed(), it's RAM, not ROM:(qemu) info mtree address-space: memory 0000000000000000-ffffffffffffffff (prio 0, RW): system 0000000000100000-0000000003ffffff (prio 0, RW): sun4v-hv.ram 0000000080000000-0000000087ffffff (prio 0, RW): sun4v-partition.ram 0000001f10000000-0000001f10000007 (prio 0, RW): serial 0000001f11000000-0000001f11001fff (prio 0, RW): sun4v.nvram 0000001f12000000-0000001f12001fff (prio 0, RW): sun4v-md.rom 0000001f12080000-0000001f12081fff (prio 0, RW): sun4v-hv.rom 0000001f40000000-0000001f413fffff (prio 0, RW): sun4v_vdisk.ram 0000009800000000-00000098ffffffff (prio 0, RW): empty-slot 000000fff0000000-000000fff03fffff (prio 0, RW): sun4v.prom 000000fff0c1fff8-000000fff0c1ffff (prio 0, RW): sun4v-rtc address-space: I/O 0000000000000000-000000000000ffff (prio 0, RW): io address-space: cpu-memory 0000000000000000-ffffffffffffffff (prio 0, RW): system 0000000000100000-0000000003ffffff (prio 0, RW): sun4v-hv.ram 0000000080000000-0000000087ffffff (prio 0, RW): sun4v-partition.ram 0000001f10000000-0000001f10000007 (prio 0, RW): serial 0000001f11000000-0000001f11001fff (prio 0, RW): sun4v.nvram 0000001f12000000-0000001f12001fff (prio 0, RW): sun4v-md.rom 0000001f12080000-0000001f12081fff (prio 0, RW): sun4v-hv.rom ---> 0000001f40000000-0000001f413fffff (prio 0, RW): sun4v_vdisk.ram 0000009800000000-00000098ffffffff (prio 0, RW): empty-slot 000000fff0000000-000000fff03fffff (prio 0, RW): sun4v.prom
Quoted 4 lines
Quoted 1 line
Note that sun4v-md.rom and sun4v-hv.rom aren't ROM, either.
Is
rom_add_file_fixedsupposed to mark the memory region read-only? Or should it be created read-only before callingrom_add_file_fixed?
I'm not familiar with the memory API, but the fact that you're getting RW suggests that you need to mark read-only yourself. Suggest to examine similar code elsewhere for additional clues.
Quoted 12 lines
Quoted 6 lines
The monkey-patching of
dinfo->is_defaultis to silence the "Orphaned drive without device" warning. Naughty.This use of -drive if=pflash is highly unorthodox. To suggest better ways, we need to understand the role of "the virtual ramdisk". Can you explain? How does it work on a physical system?
AFAIK except for simulators it's only used on FPGA boards. It's what the comment says: a kind of initrd, but it resides outside of the partition RAM. So, it is a RAM region pre-filled with data in the way not visible to the guest.
Quoted 4 lines
I would have used an -initrd option instead of -pflash, but it required a -kernel option, and there is no sensible way to use the -kernel with Solaris.
If QEMU had something like a nvram-disk - it would have worked here the best.
Have you considered pressing -bios into service? -option-rom? -object memory-backend-file? Paolo, any recommendations?
Re: [Qemu-devel] [PATCH v2 30/30] target-sparc: fix up niagara machine
Quoted 17 lines · Markus Armbruster
Quoted 2 lines
Is
rom_add_file_fixedsupposed to mark the memory region read-only? Or should it be created read-only before callingrom_add_file_fixed?I'm not familiar with the memory API, but the fact that you're getting RW suggests that you need to mark read-only yourself. Suggest to examine similar code elsewhere for additional clues.
Quoted 11 lines
Quoted 6 lines
The monkey-patching of
dinfo->is_defaultis to silence the "Orphaned drive without device" warning. Naughty.This use of -drive if=pflash is highly unorthodox. To suggest better ways, we need to understand the role of "the virtual ramdisk". Can you explain? How does it work on a physical system?
AFAIK except for simulators it's only used on FPGA boards. It's what the comment says: a kind of initrd, but it resides outside of the partition RAM. So, it is a RAM region pre-filled with data in the way not visible to the guest.
Quoted 7 lines
Quoted 4 lines
I would have used an -initrd option instead of -pflash, but it required a -kernel option, and there is no sensible way to use the -kernel with Solaris.
If QEMU had something like a nvram-disk - it would have worked here the best.Have you considered pressing -bios into service? -option-rom? -object memory-backend-file? Paolo, any recommendations?
Yeah, I think -bios is closest. By the way, where do I get all the .rom files for the Niagara board? "make check" complains about them.
Paolo
Re: [Qemu-devel] [PATCH v2 30/30] target-sparc: fix up niagara machine
Quoted 25 lines · Paolo Bonzini
Quoted 22 lines · Markus Armbruster
Quoted 2 lines
Is
rom_add_file_fixedsupposed to mark the memory region read-only? Or should it be created read-only before callingrom_add_file_fixed?I'm not familiar with the memory API, but the fact that you're getting RW suggests that you need to mark read-only yourself. Suggest to examine similar code elsewhere for additional clues.
Quoted 15 lines
Quoted 6 lines
The monkey-patching of
dinfo->is_defaultis to silence the "Orphaned drive without device" warning. Naughty.This use of -drive if=pflash is highly unorthodox. To suggest better ways, we need to understand the role of "the virtual ramdisk". Can you explain? How does it work on a physical system?
AFAIK except for simulators it's only used on FPGA boards. It's what the comment says: a kind of initrd, but it resides outside of the partition RAM. So, it is a RAM region pre-filled with data in the way not visible to the guest.
I would have used an -initrd option instead of -pflash, but it required a -kernel option, and there is no sensible way to use the -kernel with Solaris.
If QEMU had something like a nvram-disk - it would have worked here the best.
Quoted 4 lines
Quoted 2 lines
Have you considered pressing -bios into service? -option-rom? -object memory-backend-file? Paolo, any recommendations?
Yeah, I think -bios is closest.
I think it may sound misleading to a user: it's an optional (NV)RAM-disk, not a part of a firmware.
Maybe -object memory-backend-file would do it, but it clears the file on reset, doesn't it?
Quoted 2 lines
By the way, where do I get all the .rom
files for the Niagara board? "make check" complains about them.
The machine uses the firmware supplied with the OpenSPARC T1 project,
http://download.oracle.com/technetwork/systems/opensparc/OpenSPARCT1_Arch.1.5.tar.bz2
in the directory S10image/
Also I posted a patch to silence "make check" a couple of days ago.
Signature · 4 lines
Regards, Artyom Tarasenko SPARC and PPC PReP under qemu blog: http://tyom.blogspot.com/search/label/qemu