Openrisc misc features / fixes
v2 cover Openrisc misc features / fixes
Hello,
I have got a few response on the last series and have fixed them up. Also I have dropped the shutdown patch.
These patches I added while working on upcoming openrisc smp support. This does not allow for SMP openrisc on qemu "yet" but it does help to allow booting of an SMP kernel on the uni-processor qemu system which I was using as a sanity check before testing on fpga hardware.
Changes Since v1:
o Added Tim's patches to this series (since the vmstate patch depends on in)
o Changed vmstate patch to bump version numbers + support evbar saving
o Changed Shadow Register patch to use accessor functions
o Added reviewed-by's
o Added a patch to remote the features field and enums
o Dropped shutdown on l.nop 1 patch
-Stafford
Stafford Horne (7):
target/openrisc: Fixes for memory debugging target/openrisc: add numcores and coreid support
migration: Add VMSTATE_UINTTL_2DARRAY() target/openrisc: implement shadow registers
migration: Add VMSTATE_STRUCT_2DARRAY() target/openrisc: Implement full vmstate serialization target/openrisc: Remove duplicate features property
Tim 'mithro' Ansell (2):
target/openrisc: Implement EVBAR register
target/openrisc: Implement EPH bit
include/migration/cpu.h | 7 ++++ include/migration/vmstate.h | 15 ++++++++ linux-user/elfload.c | 2 +- linux-user/main.c | 18 ++++----- linux-user/openrisc/target_cpu.h | 6 +-- linux-user/openrisc/target_signal.h | 2 +- linux-user/signal.c | 16 ++++---- target/openrisc/cpu.c | 13 ++----- target/openrisc/cpu.h | 36 ++++++++++-------- target/openrisc/gdbstub.c | 4 +- target/openrisc/interrupt.c | 9 ++++- target/openrisc/machine.c | 75 +++++++++++++++++++++++++++++++++++-- target/openrisc/mmu.c | 23 ++++++++++-- target/openrisc/sys_helper.c | 22 +++++++++++ target/openrisc/translate.c | 5 ++- 15 files changed, 194 insertions(+), 59 deletions(-)
Signature · 1 line
2.9.3
PATCH v2 1/9 target/openrisc: Implement EVBAR register
From: Tim 'mithro' Ansell <[email protected]>
Exception Vector Base Address Register (EVBAR) - This optional register can be used to apply an offset to the exception vector addresses.
The significant bits (31-12) of the vector offset address for each exception depend on the setting of the Supervision Register (SR)'s EPH bit and the Exception Vector Base Address Register (EVBAR).
Its presence is indicated by the EVBARP bit in the CPU Configuration Register (CPUCFGR).
--- target/openrisc/cpu.c | 2 ++ target/openrisc/cpu.h | 7 +++++++ target/openrisc/interrupt.c | 6 +++++- target/openrisc/sys_helper.c | 7 +++++++ 4 files changed, 21 insertions(+), 1 deletion(-)
target/openrisc/cpu.c +2 -0
@@ -134,6 +134,7 @@ static void or1200_initfn(Object *obj)set_feature (cpu,OPENRISC_FEATURE_OB32S );set_feature (cpu,OPENRISC_FEATURE_OF32S ); +set_feature (cpu,OPENRISC_FEATURE_EVBAR ); }static void openrisc_any_initfn (Object *obj)
@@ -141,6 +142,7 @@ static void openrisc_any_initfn(Object *obj)OpenRISCCPU *cpu =OPENRISC_CPU (obj);set_feature (cpu,OPENRISC_FEATURE_OB32S ); +set_feature (cpu,OPENRISC_FEATURE_EVBAR ); } typedef struct OpenRISCCPUInfo {
target/openrisc/cpu.h +7 -0
@@ -111,6 +111,11 @@ enum {CPUCFGR_OF32S = (1 <<7 ),CPUCFGR_OF64S = (1 <<8 ),CPUCFGR_OV64S = (1 <<9 ), +/* CPUCFGR_ND = (1 << 10), */ +/* CPUCFGR_AVRP = (1 << 11), */ + CPUCFGR_EVBARP = (1 << 12), + /* CPUCFGR_ISRP = (1 << 13), */ + /* CPUCFGR_AECSRP = (1 << 14), */ };/* DMMU configure register */
@@ -200,6 +205,7 @@ enum {OPENRISC_FEATURE_OF32S = (1 <<7 ),OPENRISC_FEATURE_OF64S = (1 <<8 ),OPENRISC_FEATURE_OV64S = (1 <<9 ), + OPENRISC_FEATURE_EVBAR = (1 << 12), };/* Tick Timer Mode Register */
@@ -289,6 +295,7 @@ typedef struct CPUOpenRISCState {uint32_t dmmucfgr;/* DMMU configure register */ uint32_t immucfgr;/* IMMU configure register */ uint32_t esr;/* Exception supervisor register */ +uint32_t evbar;/* Exception vector base address register */ uint32_t fpcsr;/* Float register */ float_status fp_status;
target/openrisc/interrupt.c +5 -1
@@ -65,7 +65,11 @@ void openrisc_cpu_do_interrupt(CPUState *cs) env->lock_addr =-1 ;if (cs->exception_index >0 && cs->exception_index <EXCP_NR ) { - env->pc = (cs->exception_index <<8 ); +hwaddr vect_pc = cs->exception_index <<8 ; +if (env->cpucfgr &CPUCFGR_EVBARP ) { + vect_pc |= env->evbar; + } + env->pc = vect_pc; }else {cpu_abort (cs,"Unhandled exception 0x%x\n" , cs->exception_index); }
target/openrisc/sys_helper.c +7 -0
@@ -39,6 +39,10 @@ void HELPER(mtspr)(CPUOpenRISCState *env, env->vr = rb;break ; +case TO_SPR (0 ,11 ):/* EVBAR */ + env->evbar = rb; +break ; +case TO_SPR (0 ,16 ):/* NPC */ cpu_restore_state (cs,GETPC ());/* ??? Mirror or1ksim in not trashing delayed branch state
@@ -206,6 +210,9 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,case TO_SPR (0 ,4 ):/* IMMUCFGR */ return env->immucfgr; +case TO_SPR (0 ,11 ):/* EVBAR */ +return env->evbar; +case TO_SPR (0 ,16 ):/* NPC (equals PC) */ cpu_restore_state (cs,GETPC ());return env->pc;
Signature · 1 line
2.9.3
PATCH v2 2/9 target/openrisc: Implement EPH bit
In reply to Stafford HorneFrom: Tim 'mithro' Ansell <[email protected]>
Exception Prefix High (EPH) control bit of the Supervision Register (SR).
The significant bits (31-12) of the vector offset address for each exception depend on the setting of the Supervision Register (SR)'s EPH bit and the Exception Vector Base Address Register (EVBAR).
If SR[EPH] is set, the vector offset is logically ORed with the offset 0xF0000000.
This means if EPH is;
* 0 - Exceptions vectors start at EVBAR
* 1 - Exception vectors start at EVBAR | 0xF0000000
--- target/openrisc/interrupt.c | 3 +++ 1 file changed, 3 insertions(+)
target/openrisc/interrupt.c +3 -0
@@ -69,6 +69,9 @@ void openrisc_cpu_do_interrupt(CPUState *cs)if (env->cpucfgr &CPUCFGR_EVBARP ) { vect_pc |= env->evbar; } +if (env->sr &SR_EPH ) { + vect_pc |=0xf0000000 ; + } env->pc = vect_pc; }else {cpu_abort (cs,"Unhandled exception 0x%x\n" , cs->exception_index);
Signature · 1 line
2.9.3
PATCH v2 3/9 target/openrisc: Fixes for memory debugging
In reply to Stafford HorneWhen debugging in gdb you might want to inspect instructions in mapped pages or in exception vectors like 0x800 etc. This was previously not possible in qemu since the *get_phys_page_debug() routine only looked into the data tlb.
Change to fall back to look into instruction tlb and plain physical pages.
--- target/openrisc/mmu.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-)
target/openrisc/mmu.c +19 -4
@@ -124,7 +124,7 @@ static int cpu_openrisc_get_phys_addr(OpenRISCCPU *cpu, {int ret =TLBRET_MATCH ; -if (rw ==2 ) {/* ITLB */ +if (rw ==MMU_INST_FETCH ) {/* ITLB */ *physical =0 ; ret = cpu->env.tlb->cpu_openrisc_map_address_code (cpu, physical, prot, address, rw);
@@ -221,12 +221,27 @@ hwaddr openrisc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)OpenRISCCPU *cpu =OPENRISC_CPU (cs);hwaddr phys_addr;int prot; +int miss; -if (cpu_openrisc_get_phys_addr (cpu, &phys_addr, &prot, addr,0 )) { -return -1 ; +/* Check memory for any kind of address, since during debug the +gdb can ask for anything, check data tlb for address */ + miss =cpu_openrisc_get_phys_addr (cpu, &phys_addr, &prot, addr,0 ); + +/* Check instruction tlb */ +if (miss) { + miss =cpu_openrisc_get_phys_addr (cpu, &phys_addr, &prot, addr,MMU_INST_FETCH ); + } + +/* Last, fall back to a plain address */ +if (miss) { + miss =cpu_openrisc_get_phys_nommu (cpu, &phys_addr, &prot, addr,0 ); } -return phys_addr; +if (miss) { +return -1 ; + }else { +return phys_addr; + } }void cpu_openrisc_mmu_init (OpenRISCCPU *cpu)
Signature · 1 line
2.9.3
PATCH v2 4/9 target/openrisc: add numcores and coreid support
In reply to Stafford HorneThese are used to identify the processor in SMP system. Their definition has been defined in verilog cores but it not yet part of the spec but it will be soon.
The proposal for this is available:
https://openrisc.io/proposals/core-identifier-and-number-of-cores
--- target/openrisc/sys_helper.c | 6 ++++++ 1 file changed, 6 insertions(+)
target/openrisc/sys_helper.c +6 -0
@@ -233,6 +233,12 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,case TO_SPR (0 ,64 ):/* ESR */ return env->esr; +case TO_SPR (0 ,128 ):/* COREID */ +return 0 ; + +case TO_SPR (0 ,129 ):/* NUMCORES */ +return 1 ; + case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */ idx = spr -TO_SPR (1 ,512 );return env->tlb->dtlb[0 ][idx].mr;
Signature · 1 line
2.9.3
PATCH v2 5/9 migration: Add VMSTATE_UINTTL_2DARRAY()
In reply to Stafford HorneIn openRISC we are implementing the shadow registers as a 2d array. Using this target long method rather than direct 32-bit alternatives is consistent with the rest of our vm state serialization logic.
--- include/migration/cpu.h | 7 +++++++ 1 file changed, 7 insertions(+)
include/migration/cpu.h +7 -0
@@ -18,6 +18,8 @@ VMSTATE_UINT64_EQUAL_V(_f, _s, _v)#define VMSTATE_UINTTL_ARRAY_V (_f, _s, _n, _v) \ VMSTATE_UINT64_ARRAY_V(_f, _s, _n, _v) +#define VMSTATE_UINTTL_2DARRAY_V (_f, _s, _n1, _n2, _v) \ + VMSTATE_UINT64_2DARRAY_V(_f, _s, _n1, _n2, _v)#define VMSTATE_UINTTL_TEST (_f, _s, _t) \ VMSTATE_UINT64_TEST(_f, _s, _t)#define vmstate_info_uinttl vmstate_info_uint64
@@ -37,6 +39,8 @@ VMSTATE_UINT32_EQUAL_V(_f, _s, _v)#define VMSTATE_UINTTL_ARRAY_V (_f, _s, _n, _v) \ VMSTATE_UINT32_ARRAY_V(_f, _s, _n, _v) +#define VMSTATE_UINTTL_2DARRAY_V (_f, _s, _n1, _n2, _v) \ + VMSTATE_UINT32_2DARRAY_V(_f, _s, _n1, _n2, _v)#define VMSTATE_UINTTL_TEST (_f, _s, _t) \ VMSTATE_UINT32_TEST(_f, _s, _t)#define vmstate_info_uinttl vmstate_info_uint32
@@ -48,5 +52,8 @@ VMSTATE_UINTTL_EQUAL_V(_f, _s, 0)#define VMSTATE_UINTTL_ARRAY (_f, _s, _n) \ VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, 0) +#define VMSTATE_UINTTL_2DARRAY (_f, _s, _n1, _n2) \ + VMSTATE_UINTTL_2DARRAY_V(_f, _s, _n1, _n2, 0) +#endif
Signature · 1 line
2.9.3
PATCH v2 6/9 target/openrisc: implement shadow registers
In reply to Stafford HorneShadow registers are part of the openrisc spec along with sr[cid], as part of the fast context switching feature. When exceptions occur, instead of having to save registers to the stack if enabled the CID will increment and a new set of registers will be available.
This patch only implements shadow registers which can be used as extra scratch registers via the mfspr and mtspr if required. This is implemented in a way where it would be easy to add on the fast context switching, currently cid is hardcoded to 0.
This is need for openrisc linux smp kernels to boot correctly.
---
Changes since v1:
o Use accessor functions cpu_get_gpr()/cpu_set_gpr()
linux-user/elfload.c | 2 +- linux-user/main.c | 18 +++++++++--------- linux-user/openrisc/target_cpu.h | 6 +++--- linux-user/openrisc/target_signal.h | 2 +- linux-user/signal.c | 16 ++++++++-------- target/openrisc/cpu.c | 4 +++- target/openrisc/cpu.h | 15 +++++++++++++-- target/openrisc/gdbstub.c | 4 ++-- target/openrisc/machine.c | 6 +++--- target/openrisc/sys_helper.c | 9 +++++++++ target/openrisc/translate.c | 5 +++-- 11 files changed, 55 insertions(+), 32 deletions(-)
linux-user/elfload.c +1 -1
@@ -1052,7 +1052,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,int i;for (i =0 ; i <32 ; i++) { - (*regs)[i] =tswapreg (env->gpr[i]); + (*regs)[i] =tswapreg (cpu_get_gpr (env, i)); } (*regs)[32 ] =tswapreg (env->pc); (*regs)[33 ] =tswapreg (cpu_get_sr (env));
linux-user/main.c +9 -9
@@ -2590,17 +2590,17 @@ void cpu_loop(CPUOpenRISCState *env)case EXCP_SYSCALL : env->pc +=4 ;/* 0xc00; */ ret =do_syscall (env, - env->gpr[11 ],/* return value */ - env->gpr[3 ],/* r3 - r7 are params */ - env->gpr[4 ], - env->gpr[5 ], - env->gpr[6 ], - env->gpr[7 ], - env->gpr[8 ],0 ,0 ); +cpu_get_gpr (env,11 ),/* return value */ +cpu_get_gpr (env,3 ),/* r3 - r7 are params */ +cpu_get_gpr (env,4 ), +cpu_get_gpr (env,5 ), +cpu_get_gpr (env,6 ), +cpu_get_gpr (env,7 ), +cpu_get_gpr (env,8 ),0 ,0 );if (ret == -TARGET_ERESTARTSYS ) { env->pc -=4 ; }else if (ret != -TARGET_QEMU_ESIGRETURN ) { - env->gpr[11 ] = ret; +cpu_set_gpr (env,11 , ret); }break ;case EXCP_DPF :
@@ -4765,7 +4765,7 @@ int main(int argc, char **argv, char **envp)int i;for (i =0 ; i <32 ; i++) { - env->gpr[i] = regs->gpr[i]; +cpu_set_gpr (env, i, regs->gpr[i]); } env->pc = regs->pc;cpu_set_sr (env, regs->sr);
linux-user/openrisc/target_cpu.h +3 -3
@@ -23,14 +23,14 @@static inline void cpu_clone_regs (CPUOpenRISCState *env,target_ulong newsp) {if (newsp) { - env->gpr[1 ] = newsp; +cpu_set_gpr (env,1 , newsp); } - env->gpr[11 ] =0 ; +cpu_set_gpr (env,11 ,0 ); }static inline void cpu_set_tls (CPUOpenRISCState *env,target_ulong newtls) { - env->gpr[10 ] = newtls; +cpu_set_gpr (env,10 , newtls); }#endif
linux-user/openrisc/target_signal.h +1 -1
@@ -20,7 +20,7 @@ typedef struct target_sigaltstack {static inline abi_ulong get_sp_from_cpustate (CPUOpenRISCState *state) { -return state->gpr[1 ]; +return cpu_get_gpr (state,1 ); }
linux-user/signal.c +8 -8
@@ -4411,7 +4411,7 @@ static void setup_sigcontext(struct target_sigcontext *sc, CPUOpenRISCState *regs, unsigned long mask) { -unsigned long usp = regs->gpr[1 ]; +unsigned long usp =cpu_get_gpr (regs,1 );/* copy the regs. they are first in sc so we can use sc directly */
@@ -4436,7 +4436,7 @@ static inline abi_ulong get_sigframe(struct target_sigaction *ka, CPUOpenRISCState *regs, size_t frame_size) { -unsigned long sp = regs->gpr[1 ]; +unsigned long sp =cpu_get_gpr (regs,1 );int onsigstack =on_sig_stack (sp);/* redzone */
@@ -4489,7 +4489,7 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,__put_user (0 , &frame->uc.tuc_link);__put_user (target_sigaltstack_used.ss_sp, &frame->uc.tuc_stack.ss_sp); -__put_user (sas_ss_flags (env->gpr[1 ]), &frame->uc.tuc_stack.ss_flags); +__put_user (sas_ss_flags (cpu_get_gpr (env,1 )), &frame->uc.tuc_stack.ss_flags);__put_user (target_sigaltstack_used.ss_size, &frame->uc.tuc_stack.ss_size);setup_sigcontext (&frame->sc, env, set->sig[0 ]);
@@ -4512,13 +4512,13 @@ static void setup_rt_frame(int sig, struct target_sigaction *ka,/* Set up registers for signal handler */ env->pc = (unsigned long )ka->_sa_handler;/* what we enter NOW */ - env->gpr[9 ] = (unsigned long )return_ip;/* what we enter LATER */ - env->gpr[3 ] = (unsigned long )sig;/* arg 1: signo */ - env->gpr[4 ] = (unsigned long )&frame->info;/* arg 2: (siginfo_t*) */ - env->gpr[5 ] = (unsigned long )&frame->uc;/* arg 3: ucontext */ +cpu_set_gpr (env,9 , (unsigned long )return_ip);/* what we enter LATER */ +cpu_set_gpr (env,3 , (unsigned long )sig);/* arg 1: signo */ +cpu_set_gpr (env,4 , (unsigned long )&frame->info);/* arg 2: (siginfo_t*) */ +cpu_set_gpr (env,5 , (unsigned long )&frame->uc);/* arg 3: ucontext */ /* actually move the usp to reflect the stacked frame */ - env->gpr[1 ] = (unsigned long )frame; +cpu_set_gpr (env,1 , (unsigned long )frame);return ;
target/openrisc/cpu.c +3 -1
@@ -52,7 +52,7 @@ static void openrisc_cpu_reset(CPUState *s) s->exception_index =-1 ; cpu->env.upr =UPR_UP |UPR_DMP |UPR_IMP |UPR_PICP |UPR_TTP ; - cpu->env.cpucfgr =CPUCFGR_OB32S |CPUCFGR_OF32S ; + cpu->env.cpucfgr =CPUCFGR_OB32S |CPUCFGR_OF32S |CPUCFGR_NSGF ; cpu->env.dmmucfgr = (DMMUCFGR_NTW & (0 <<2 )) | (DMMUCFGR_NTS & (6 <<2 )); cpu->env.immucfgr = (IMMUCFGR_NTW & (0 <<2 )) | (IMMUCFGR_NTS & (6 <<2 ));
@@ -132,6 +132,7 @@ static void or1200_initfn(Object *obj) {OpenRISCCPU *cpu =OPENRISC_CPU (obj); +set_feature (cpu,OPENRISC_FEATURE_NSGF );set_feature (cpu,OPENRISC_FEATURE_OB32S );set_feature (cpu,OPENRISC_FEATURE_OF32S );set_feature (cpu,OPENRISC_FEATURE_EVBAR );
@@ -141,6 +142,7 @@ static void openrisc_any_initfn(Object *obj) {OpenRISCCPU *cpu =OPENRISC_CPU (obj); +set_feature (cpu,OPENRISC_FEATURE_NSGF );set_feature (cpu,OPENRISC_FEATURE_OB32S );set_feature (cpu,OPENRISC_FEATURE_EVBAR ); }
target/openrisc/cpu.h +13 -2
@@ -275,7 +275,8 @@ typedef struct CPUOpenRISCTLBContext {#endif typedef struct CPUOpenRISCState { - target_ulong gpr[32]; /* General registers */ + target_ulong shadow_gpr[16][32]; /* Shadow registers */ + target_ulong pc; /* Program counter */ target_ulong ppc; /* Prev PC */ target_ulong jmp_pc; /* Jump PC */
@@ -399,6 +400,16 @@ int cpu_openrisc_get_phys_data(OpenRISCCPU *cpu,#define TB_FLAGS_R0_0 2#define TB_FLAGS_OVE SR_OVE +static inline uint32_t cpu_get_gpr (const CPUOpenRISCState *env,int i) +{ +return env->shadow_gpr[0 ][i]; +} + +static inline void cpu_set_gpr (CPUOpenRISCState *env,int i,uint32_t val) +{ + env->shadow_gpr[0 ][i] = val; +} +static inline void cpu_get_tb_cpu_state (CPUOpenRISCState *env,target_ulong *pc,target_ulong *cs_base,uint32_t *flags)
@@ -406,7 +417,7 @@ static inline void cpu_get_tb_cpu_state(CPUOpenRISCState *env, *pc = env->pc; *cs_base =0 ; *flags = (env->dflag - | (env->gpr[0 ] ==0 ?TB_FLAGS_R0_0 :0 ) + | (cpu_get_gpr (env,0 ) ==0 ?TB_FLAGS_R0_0 :0 ) | (env->sr &SR_OVE )); }
target/openrisc/gdbstub.c +2 -2
@@ -28,7 +28,7 @@ int openrisc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)CPUOpenRISCState *env = &cpu->env;if (n <32 ) { -return gdb_get_reg32 (mem_buf, env->gpr[n]); +return gdb_get_reg32 (mem_buf,cpu_get_gpr (env, n)); }else {switch (n) {case 32 :/* PPC */
@@ -61,7 +61,7 @@ int openrisc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) tmp =ldl_p (mem_buf);if (n <32 ) { - env->gpr[n] = tmp; +cpu_set_gpr (env, n, tmp); }else {switch (n) {case 32 :/* PPC */
target/openrisc/machine.c +3 -3
@@ -47,10 +47,10 @@ static const VMStateInfo vmstate_sr = {static const VMStateDescription vmstate_env = { .name ="env" , - .version_id =4 , - .minimum_version_id =4 , + .version_id =5 , + .minimum_version_id =5 , .fields = (VMStateField []) { -VMSTATE_UINTTL_ARRAY (gpr, CPUOpenRISCState,32 ), +VMSTATE_UINTTL_2DARRAY (shadow_gpr, CPUOpenRISCState,16 ,32 ),VMSTATE_UINTTL (pc, CPUOpenRISCState),VMSTATE_UINTTL (ppc, CPUOpenRISCState),VMSTATE_UINTTL (jmp_pc, CPUOpenRISCState),
target/openrisc/sys_helper.c +9 -0
@@ -92,6 +92,11 @@ void HELPER(mtspr)(CPUOpenRISCState *env,case TO_SPR (0 ,64 ):/* ESR */ env->esr = rb;break ; + + case TO_SPR(0, 1024) ... TO_SPR(0, 1024 + (16 * 32)): /* Shadow GPRs */ + idx = (spr -1024 ); + env->shadow_gpr[idx /32 ][idx %32 ] = rb; + case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */ idx = spr -TO_SPR (1 ,512 );if (!(rb &1 )) {
@@ -239,6 +244,10 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env,case TO_SPR (0 ,129 ):/* NUMCORES */ return 1 ; + case TO_SPR(0, 1024) ... TO_SPR(0, 1024 + (16 * 32)): /* Shadow GPRs */ + idx = (spr -1024 ); +return env->shadow_gpr[idx /32 ][idx %32 ]; + case TO_SPR(1, 512) ... TO_SPR(1, 512+DTLB_SIZE-1): /* DTLBW0MR 0-127 */ idx = spr -TO_SPR (1 ,512 );return env->tlb->dtlb[0 ][idx].mr;
target/openrisc/translate.c +3 -2
@@ -107,7 +107,8 @@ void openrisc_translate_init(void) "mac");for (i =0 ; i <32 ; i++) { cpu_R[i] =tcg_global_mem_new (cpu_env, - offsetof(CPUOpenRISCState, gpr[i]), + offsetof(CPUOpenRISCState , + shadow_gpr[0][i]), regnames[i]); } cpu_R0 = cpu_R[0 ];
@@ -1662,7 +1663,7 @@ void openrisc_cpu_dump_state(CPUState *cs, FILE *f,cpu_fprintf (f,"PC=%08x\n" , env->pc);for (i =0 ; i <32 ; ++i) { -cpu_fprintf (f,"R%02d=%08x%c" , i, env->gpr[i], +cpu_fprintf (f,"R%02d=%08x%c" , i,cpu_get_gpr (env, i), (i %4 ) ==3 ?'\n' :' ' ); } }
Signature · 1 line
2.9.3
PATCH v2 7/9 migration: Add VMSTATE_STRUCT_2DARRAY()
In reply to Stafford HorneFor openrisc we implement tlb state as a 2d array of tlb entry structs. This is added to allow easy storing of state of 2d arrays.
--- include/migration/vmstate.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
include/migration/vmstate.h +15 -0
@@ -499,6 +499,17 @@ extern const VMStateInfo vmstate_info_qtailq; .offset = vmstate_offset_array(_state, _field, _type, _num),\ } +#define VMSTATE_STRUCT_2DARRAY_TEST (_field, _state, _n1, _n2, _test, _version, _vmsd, _type) { \ + .name = (stringify(_field)), \ + .num = (_n1) * (_n2), \ + .field_exists = (_test), \ + .version_id = (_version), \ + .vmsd = &(_vmsd), \ + .size = sizeof(_type), \ + .flags = VMS_STRUCT|VMS_ARRAY, \ + .offset = vmstate_offset_2darray(_state, _field, _type, _n1, _n2),\ +} +#define VMSTATE_STRUCT_VARRAY_UINT8 (_field, _state, _field_num, _version, _vmsd, _type) { \ .name = (stringify(_field)), \ .num_offset = vmstate_offset_value(_state, _field_num, uint8_t), \
@@ -746,6 +757,10 @@ extern const VMStateInfo vmstate_info_qtailq;VMSTATE_STRUCT_ARRAY_TEST (_field, _state, _num,NULL , _version, \ _vmsd, _type) +#define VMSTATE_STRUCT_2DARRAY (_field, _state, _n1, _n2, _version, _vmsd, _type) \ + VMSTATE_STRUCT_2DARRAY_TEST(_field, _state, _n1, _n2, NULL, _version, \ + _vmsd, _type) +#define VMSTATE_BUFFER_UNSAFE_INFO (_field, _state, _version, _info, _size) \ VMSTATE_BUFFER_UNSAFE_INFO_TEST(_field, _state, NULL, _version, _info, \ _size)
Signature · 1 line
2.9.3
PATCH v2 8/9 target/openrisc: Implement full vmstate serialization
In reply to Stafford HornePreviously serialization did not persist the tlb, timer, pic and other key state items. This meant snapshotting and restoring a running os would crash. After adding these I am able to take snapshots of a running linux os and restore at a later time.
I am currently not trying to maintain capatibility with older versions as I do not believe this really worked before or anyone used it.
---
Changes since v1:
o Added evbar
o Bumped version on vmstate_env
target/openrisc/machine.c | 73 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 2 deletions(-)
target/openrisc/machine.c +71 -2
@@ -24,6 +24,63 @@#include "hw/boards.h" #include "migration/cpu.h" +static int env_post_load (void *opaque,int version_id) +{ +CPUOpenRISCState *env = opaque; + +/* Restore MMU handlers */ +if (env->sr &SR_DME ) { + env->tlb->cpu_openrisc_map_address_data = + &cpu_openrisc_get_phys_data; + }else { + env->tlb->cpu_openrisc_map_address_data = + &cpu_openrisc_get_phys_nommu; + } + +if (env->sr &SR_IME ) { + env->tlb->cpu_openrisc_map_address_code = + &cpu_openrisc_get_phys_code; + }else { + env->tlb->cpu_openrisc_map_address_code = + &cpu_openrisc_get_phys_nommu; + } + + +return 0 ; +} + +static const VMStateDescription vmstate_tlb_entry = { + .name ="tlb_entry" , + .version_id =1 , + .minimum_version_id =1 , + .minimum_version_id_old =1 , + .fields = (VMStateField []) { +VMSTATE_UINTTL (mr, OpenRISCTLBEntry), +VMSTATE_UINTTL (tr, OpenRISCTLBEntry), +VMSTATE_END_OF_LIST () + } +}; + +static const VMStateDescription vmstate_cpu_tlb = { + .name ="cpu_tlb" , + .version_id =1 , + .minimum_version_id =1 , + .minimum_version_id_old =1 , + .fields = (VMStateField []) { +VMSTATE_STRUCT_2DARRAY (itlb, CPUOpenRISCTLBContext, +ITLB_WAYS ,ITLB_SIZE ,0 , + vmstate_tlb_entry, OpenRISCTLBEntry), +VMSTATE_STRUCT_2DARRAY (dtlb, CPUOpenRISCTLBContext, +DTLB_WAYS ,DTLB_SIZE ,0 , + vmstate_tlb_entry, OpenRISCTLBEntry), +VMSTATE_END_OF_LIST () + } +}; + +#define VMSTATE_CPU_TLB (_f, _s) \ + VMSTATE_STRUCT_POINTER(_f, _s, vmstate_cpu_tlb, CPUOpenRISCTLBContext) + +static int get_sr (QEMUFile *f,void *opaque,size_t size,VMStateField *field) {CPUOpenRISCState *env = opaque;
@@ -47,8 +104,9 @@ static const VMStateInfo vmstate_sr = {static const VMStateDescription vmstate_env = { .name ="env" , - .version_id =5 , - .minimum_version_id =5 , + .version_id =6 , + .minimum_version_id =6 , + .post_load = env_post_load, .fields = (VMStateField []) {VMSTATE_UINTTL_2DARRAY (shadow_gpr, CPUOpenRISCState,16 ,32 ),VMSTATE_UINTTL (pc, CPUOpenRISCState),
@@ -79,9 +137,20 @@ static const VMStateDescription vmstate_env = { VMSTATE_UINT32(cpucfgr, CPUOpenRISCState), VMSTATE_UINT32(dmmucfgr, CPUOpenRISCState), VMSTATE_UINT32(immucfgr, CPUOpenRISCState), + VMSTATE_UINT32(evbar, CPUOpenRISCState), VMSTATE_UINT32(esr, CPUOpenRISCState), VMSTATE_UINT32(fpcsr, CPUOpenRISCState), VMSTATE_UINT64(mac, CPUOpenRISCState), + + VMSTATE_CPU_TLB(tlb, CPUOpenRISCState), + + VMSTATE_TIMER_PTR(timer, CPUOpenRISCState), + VMSTATE_UINT32(ttmr, CPUOpenRISCState), + VMSTATE_UINT32(ttcr, CPUOpenRISCState), + + VMSTATE_UINT32(picmr, CPUOpenRISCState), + VMSTATE_UINT32(picsr, CPUOpenRISCState), +VMSTATE_END_OF_LIST () } };
Signature · 1 line
2.9.3
PATCH v2 9/9 target/openrisc: Remove duplicate features property
In reply to Stafford HorneThe features property has stored the exact same thing as the cpucfgr spr. Remove the feature enum and property as it is not needed.
In order to preserve the behavior or keeping features accross reset this patch moves cpucfgr into the non reset region of the state struct. Since the cpucfgr is read only this means we only need to sset cpucfgr once during class init.
--- target/openrisc/cpu.c | 17 +++-------------- target/openrisc/cpu.h | 16 ++-------------- 2 files changed, 5 insertions(+), 28 deletions(-)
target/openrisc/cpu.c +3 -14
@@ -52,7 +52,6 @@ static void openrisc_cpu_reset(CPUState *s) s->exception_index =-1 ; cpu->env.upr =UPR_UP |UPR_DMP |UPR_IMP |UPR_PICP |UPR_TTP ; - cpu->env.cpucfgr =CPUCFGR_OB32S |CPUCFGR_OF32S |CPUCFGR_NSGF ; cpu->env.dmmucfgr = (DMMUCFGR_NTW & (0 <<2 )) | (DMMUCFGR_NTS & (6 <<2 )); cpu->env.immucfgr = (IMMUCFGR_NTW & (0 <<2 )) | (IMMUCFGR_NTS & (6 <<2 ));
@@ -65,12 +64,6 @@ static void openrisc_cpu_reset(CPUState *s)#endif } -static inline void set_feature (OpenRISCCPU *cpu,int feature) -{ - cpu->feature |= feature; - cpu->env.cpucfgr = cpu->feature; -} -static void openrisc_cpu_realizefn (DeviceState *dev,Error **errp) {CPUState *cs =CPU (dev);
@@ -132,19 +125,15 @@ static void or1200_initfn(Object *obj) {OpenRISCCPU *cpu =OPENRISC_CPU (obj); -set_feature (cpu,OPENRISC_FEATURE_NSGF ); -set_feature (cpu,OPENRISC_FEATURE_OB32S ); -set_feature (cpu,OPENRISC_FEATURE_OF32S ); -set_feature (cpu,OPENRISC_FEATURE_EVBAR ); + cpu->env.cpucfgr =CPUCFGR_NSGF |CPUCFGR_OB32S |CPUCFGR_OF32S | +CPUCFGR_EVBARP ; }static void openrisc_any_initfn (Object *obj) {OpenRISCCPU *cpu =OPENRISC_CPU (obj); -set_feature (cpu,OPENRISC_FEATURE_NSGF ); -set_feature (cpu,OPENRISC_FEATURE_OB32S ); -set_feature (cpu,OPENRISC_FEATURE_EVBAR ); + cpu->env.cpucfgr =CPUCFGR_NSGF |CPUCFGR_OB32S |CPUCFGR_EVBARP ; } typedef struct OpenRISCCPUInfo {
target/openrisc/cpu.h +2 -14
@@ -196,18 +196,6 @@ enum { SR_SCE = (1 << 17), }; -/* OpenRISC Hardware Capabilities */ -enum { -OPENRISC_FEATURE_NSGF = (15 <<0 ), -OPENRISC_FEATURE_CGF = (1 <<4 ), -OPENRISC_FEATURE_OB32S = (1 <<5 ), -OPENRISC_FEATURE_OB64S = (1 <<6 ), -OPENRISC_FEATURE_OF32S = (1 <<7 ), -OPENRISC_FEATURE_OF64S = (1 <<8 ), -OPENRISC_FEATURE_OV64S = (1 <<9 ), -OPENRISC_FEATURE_EVBAR = (1 <<12 ), -}; -/* Tick Timer Mode Register */ enum {TTMR_TP = (0xfffffff ),
@@ -292,7 +280,6 @@ typedef struct CPUOpenRISCState {uint32_t sr;/* Supervisor register, without SR_{F,CY,OV} */ uint32_t vr;/* Version register */ uint32_t upr;/* Unit presence register */ -uint32_t cpucfgr;/* CPU configure register */ uint32_t dmmucfgr;/* DMMU configure register */ uint32_t immucfgr;/* IMMU configure register */ uint32_t esr;/* Exception supervisor register */
@@ -311,6 +298,8 @@ typedef struct CPUOpenRISCState {CPU_COMMON /* Fields from here on are preserved across CPU reset. */ + uint32_t cpucfgr; /* CPU configure register */ +#ifndef CONFIG_USER_ONLY CPUOpenRISCTLBContext * tlb;
@@ -337,7 +326,6 @@ typedef struct OpenRISCCPU {CPUOpenRISCState env; -uint32_t feature;/* CPU Capabilities */ } OpenRISCCPU;static inline OpenRISCCPU *openrisc_env_get_cpu (CPUOpenRISCState *env)
Signature · 1 line
2.9.3
This series seems to have some coding style problems. See output below for more information:
Hi,
This series seems to have some coding style problems. See output below for more information:
Message-id: cover.1492986468.git.shorne at gmail.com
Subject: [Qemu-devel] [PATCH v2 0/9] Openrisc misc features / fixes
Type: series
=== TEST SCRIPT BEGIN ===
#!/bin/bash
BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0
# Useful git options
git config --local diff.renamelimit 0
git config --local diff.renames True
commits="$(git log --format=%H --reverse $BASE..)" for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))done
exit $failed
=== TEST SCRIPT END ===
Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384 Switched to a new branch 'test'
e25195d target/openrisc: Remove duplicate features property 7ed50bd target/openrisc: Implement full vmstate serialization 49d0127 migration: Add VMSTATE_STRUCT_2DARRAY() 27c47a9 target/openrisc: implement shadow registers 7cf6151 migration: Add VMSTATE_UINTTL_2DARRAY() 649863f target/openrisc: add numcores and coreid support dab96ab target/openrisc: Fixes for memory debugging 9fe0bd9 target/openrisc: Implement EPH bit
42314a9 target/openrisc: Implement EVBAR register
=== OUTPUT BEGIN ===
Checking PATCH 1/9: target/openrisc: Implement EVBAR register... Checking PATCH 2/9: target/openrisc: Implement EPH bit... Checking PATCH 3/9: target/openrisc: Fixes for memory debugging...
WARNING: line over 80 characters
#45: FILE: target/openrisc/mmu.c:232:
+ miss = cpu_openrisc_get_phys_addr(cpu, &phys_addr, &prot, addr, MMU_INST_FETCH);
total: 0 errors, 1 warnings, 38 lines checked
Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS.
Checking PATCH 4/9: target/openrisc: add numcores and coreid support... Checking PATCH 5/9: migration: Add VMSTATE_UINTTL_2DARRAY()... Checking PATCH 6/9: target/openrisc: implement shadow registers...
WARNING: line over 80 characters
#135: FILE: linux-user/signal.c:4492:
+ __put_user(sas_ss_flags(cpu_get_gpr(env, 1)), &frame->uc.tuc_stack.ss_flags);
total: 0 errors, 1 warnings, 230 lines checked
Your patch has style problems, please review. If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 7/9: migration: Add VMSTATE_STRUCT_2DARRAY()...
ERROR: line over 90 characters
#20: FILE: include/migration/vmstate.h:503:
+#define VMSTATE_STRUCT_2DARRAY_TEST(_field, _state, _n1, _n2, _test, _version, _vmsd, _type) { \
ERROR: spaces required around that '|' (ctx:VxV)
#27: FILE: include/migration/vmstate.h:510:
+ .flags = VMS_STRUCT|VMS_ARRAY, \
^WARNING: line over 80 characters
#38: FILE: include/migration/vmstate.h:761:
+#define VMSTATE_STRUCT_2DARRAY(_field, _state, _n1, _n2, _version, _vmsd, _type) \
total: 2 errors, 1 warnings, 27 lines checked
Your patch has style problems, please review. If any of these errors are false positives report them to the maintainer, see CHECKPATCH in MAINTAINERS.
Checking PATCH 8/9: target/openrisc: Implement full vmstate serialization... Checking PATCH 9/9: target/openrisc: Remove duplicate features property... === OUTPUT END ===
Test command exited with code: 1
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel at freelists.org