X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/5270589032f450ae7c3448730855aa18ff68ccff..0ac8ef71329ee242951074eb2dc7136f99421d8c:/target-sparc/cpu.h diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h index 0c5a7ef54d..1be66e7fa6 100644 --- a/target-sparc/cpu.h +++ b/target-sparc/cpu.h @@ -2,23 +2,24 @@ #define CPU_SPARC_H #include "config.h" +#include "qemu-common.h" #if !defined(TARGET_SPARC64) #define TARGET_LONG_BITS 32 #define TARGET_FPREGS 32 #define TARGET_PAGE_BITS 12 /* 4k */ +#define TARGET_PHYS_ADDR_SPACE_BITS 36 +#define TARGET_VIRT_ADDR_SPACE_BITS 32 +#else +#define TARGET_LONG_BITS 64 +#define TARGET_FPREGS 64 +#define TARGET_PAGE_BITS 13 /* 8k */ #define TARGET_PHYS_ADDR_SPACE_BITS 41 # ifdef TARGET_ABI32 # define TARGET_VIRT_ADDR_SPACE_BITS 32 # else # define TARGET_VIRT_ADDR_SPACE_BITS 44 # endif -#else -#define TARGET_LONG_BITS 64 -#define TARGET_FPREGS 64 -#define TARGET_PAGE_BITS 13 /* 8k */ -#define TARGET_PHYS_ADDR_SPACE_BITS 36 -#define TARGET_VIRT_ADDR_SPACE_BITS 32 #endif #define CPUState struct CPUSPARCState @@ -79,7 +80,7 @@ #define TT_DPROT 0x6c #define TT_SPILL 0x80 #define TT_FILL 0xc0 -#define TT_WOTHER 0x10 +#define TT_WOTHER (1 << 5) #define TT_TRAP 0x100 #endif @@ -92,12 +93,14 @@ #define PSR_CARRY_SHIFT 20 #define PSR_CARRY (1 << PSR_CARRY_SHIFT) #define PSR_ICC (PSR_NEG|PSR_ZERO|PSR_OVF|PSR_CARRY) +#if !defined(TARGET_SPARC64) #define PSR_EF (1<<12) #define PSR_PIL 0xf00 #define PSR_S (1<<7) #define PSR_PS (1<<6) #define PSR_ET (1<<5) #define PSR_CWP 0x1f +#endif #define CC_SRC (env->cc_src) #define CC_SRC2 (env->cc_src2) @@ -224,7 +227,7 @@ enum { #if !defined(TARGET_SPARC64) #define NB_MMU_MODES 2 #else -#define NB_MMU_MODES 3 +#define NB_MMU_MODES 6 typedef struct trap_state { uint64_t tpc; uint64_t tnpc; @@ -341,14 +344,16 @@ typedef struct CPUSPARCState { uint32_t wim; /* window invalid mask */ #endif target_ulong tbr; /* trap base register */ +#if !defined(TARGET_SPARC64) int psrs; /* supervisor mode (extracted from PSR) */ int psrps; /* previous supervisor mode */ -#if !defined(TARGET_SPARC64) int psret; /* enable traps */ #endif uint32_t psrpil; /* interrupt blocking level */ uint32_t pil_in; /* incoming interrupt level bitmap */ +#if !defined(TARGET_SPARC64) int psref; /* enable fpu */ +#endif target_ulong version; int interrupt_index; uint32_t nwindows; @@ -434,13 +439,11 @@ typedef struct CPUSPARCState { sparc_def_t *def; } CPUSPARCState; +#ifndef NO_CPU_IO_DEFS /* helper.c */ CPUSPARCState *cpu_sparc_init(const char *cpu_model); void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu); -void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, - ...)); -void cpu_lock(void); -void cpu_unlock(void); +void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf); int cpu_sparc_handle_mmu_fault(CPUSPARCState *env1, target_ulong address, int rw, int mmu_idx, int is_softmmu); #define cpu_handle_mmu_fault cpu_sparc_handle_mmu_fault @@ -453,105 +456,49 @@ void gen_intermediate_code_init(CPUSPARCState *env); /* cpu-exec.c */ int cpu_sparc_exec(CPUSPARCState *s); -#if !defined (TARGET_SPARC64) -#define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \ - (env->psref? PSR_EF : 0) | \ - (env->psrpil << 8) | \ - (env->psrs? PSR_S : 0) | \ - (env->psrps? PSR_PS : 0) | \ - (env->psret? PSR_ET : 0) | env->cwp) -#else -#define GET_PSR(env) (env->version | (env->psr & PSR_ICC) | \ - (env->psref? PSR_EF : 0) | \ - (env->psrpil << 8) | \ - (env->psrs? PSR_S : 0) | \ - (env->psrps? PSR_PS : 0) | \ - env->cwp) -#endif - -#ifndef NO_CPU_IO_DEFS - -static inline int cpu_cwp_inc(CPUSPARCState *env1, int cwp) -{ - if (unlikely(cwp >= env1->nwindows)) - cwp -= env1->nwindows; - return cwp; -} - -static inline int cpu_cwp_dec(CPUSPARCState *env1, int cwp) -{ - if (unlikely(cwp < 0)) - cwp += env1->nwindows; - return cwp; -} +/* op_helper.c */ +target_ulong cpu_get_psr(CPUState *env1); +void cpu_put_psr(CPUState *env1, target_ulong val); +#ifdef TARGET_SPARC64 +target_ulong cpu_get_ccr(CPUState *env1); +void cpu_put_ccr(CPUState *env1, target_ulong val); +target_ulong cpu_get_cwp64(CPUState *env1); +void cpu_put_cwp64(CPUState *env1, int cwp); #endif - -static inline void memcpy32(target_ulong *dst, const target_ulong *src) -{ - dst[0] = src[0]; - dst[1] = src[1]; - dst[2] = src[2]; - dst[3] = src[3]; - dst[4] = src[4]; - dst[5] = src[5]; - dst[6] = src[6]; - dst[7] = src[7]; -} - -static inline void cpu_set_cwp(CPUSPARCState *env1, int new_cwp) -{ - /* put the modified wrap registers at their proper location */ - if (env1->cwp == env1->nwindows - 1) - memcpy32(env1->regbase, env1->regbase + env1->nwindows * 16); - env1->cwp = new_cwp; - /* put the wrap registers at their temporary location */ - if (new_cwp == env1->nwindows - 1) - memcpy32(env1->regbase + env1->nwindows * 16, env1->regbase); - env1->regwptr = env1->regbase + (new_cwp * 16); -} +int cpu_cwp_inc(CPUState *env1, int cwp); +int cpu_cwp_dec(CPUState *env1, int cwp); +void cpu_set_cwp(CPUState *env1, int new_cwp); /* sun4m.c, sun4u.c */ void cpu_check_irqs(CPUSPARCState *env); -static inline void PUT_PSR(CPUSPARCState *env1, target_ulong val) +#if defined (TARGET_SPARC64) + +static inline int compare_masked(uint64_t x, uint64_t y, uint64_t mask) { - env1->psr = val & PSR_ICC; - env1->psref = (val & PSR_EF)? 1 : 0; - env1->psrpil = (val & PSR_PIL) >> 8; -#if ((!defined (TARGET_SPARC64)) && !defined(CONFIG_USER_ONLY)) - cpu_check_irqs(env1); -#endif - env1->psrs = (val & PSR_S)? 1 : 0; - env1->psrps = (val & PSR_PS)? 1 : 0; -#if !defined (TARGET_SPARC64) - env1->psret = (val & PSR_ET)? 1 : 0; -#endif - cpu_set_cwp(env1, val & PSR_CWP); - env1->cc_op = CC_OP_FLAGS; + return (x & mask) == (y & mask); } -#ifdef TARGET_SPARC64 -#define GET_CCR(env) (((env->xcc >> 20) << 4) | ((env->psr & PSR_ICC) >> 20)) -#define PUT_CCR(env, val) do { int _tmp = val; \ - env->xcc = (_tmp >> 4) << 20; \ - env->psr = (_tmp & 0xf) << 20; \ - CC_OP = CC_OP_FLAGS; \ - } while (0) -#define GET_CWP64(env) (env->nwindows - 1 - (env)->cwp) +#define MMU_CONTEXT_BITS 13 +#define MMU_CONTEXT_MASK ((1 << MMU_CONTEXT_BITS) - 1) -#ifndef NO_CPU_IO_DEFS -static inline void PUT_CWP64(CPUSPARCState *env1, int cwp) +static inline int tlb_compare_context(const SparcTLBEntry *tlb, + uint64_t context) { - if (unlikely(cwp >= env1->nwindows || cwp < 0)) - cwp %= env1->nwindows; - cpu_set_cwp(env1, env1->nwindows - 1 - cwp); + return compare_masked(context, tlb->tag, MMU_CONTEXT_MASK); } + #endif #endif /* cpu-exec.c */ +#if !defined(CONFIG_USER_ONLY) void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec, int is_asi, int size); +target_phys_addr_t cpu_get_phys_page_nofault(CPUState *env, target_ulong addr, + int mmu_idx); + +#endif int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc); #define cpu_init cpu_sparc_init @@ -563,14 +510,42 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc); #define CPU_SAVE_VERSION 6 /* MMU modes definitions */ +#if defined (TARGET_SPARC64) +#define MMU_USER_IDX 0 #define MMU_MODE0_SUFFIX _user -#define MMU_MODE1_SUFFIX _kernel -#ifdef TARGET_SPARC64 -#define MMU_MODE2_SUFFIX _hypv -#endif +#define MMU_USER_SECONDARY_IDX 1 +#define MMU_MODE1_SUFFIX _user_secondary +#define MMU_KERNEL_IDX 2 +#define MMU_MODE2_SUFFIX _kernel +#define MMU_KERNEL_SECONDARY_IDX 3 +#define MMU_MODE3_SUFFIX _kernel_secondary +#define MMU_NUCLEUS_IDX 4 +#define MMU_MODE4_SUFFIX _nucleus +#define MMU_HYPV_IDX 5 +#define MMU_MODE5_SUFFIX _hypv +#else #define MMU_USER_IDX 0 +#define MMU_MODE0_SUFFIX _user #define MMU_KERNEL_IDX 1 -#define MMU_HYPV_IDX 2 +#define MMU_MODE1_SUFFIX _kernel +#endif + +#if defined (TARGET_SPARC64) +static inline int cpu_has_hypervisor(CPUState *env1) +{ + return env1->def->features & CPU_FEATURE_HYPV; +} + +static inline int cpu_hypervisor_mode(CPUState *env1) +{ + return cpu_has_hypervisor(env1) && (env1->hpstate & HS_PRIV); +} + +static inline int cpu_supervisor_mode(CPUState *env1) +{ + return env1->pstate & PS_PRIV; +} +#endif static inline int cpu_mmu_index(CPUState *env1) { @@ -579,12 +554,15 @@ static inline int cpu_mmu_index(CPUState *env1) #elif !defined(TARGET_SPARC64) return env1->psrs; #else - if (!env1->psrs) - return MMU_USER_IDX; - else if ((env1->hpstate & HS_PRIV) == 0) - return MMU_KERNEL_IDX; - else + if (env1->tl > 0) { + return MMU_NUCLEUS_IDX; + } else if (cpu_hypervisor_mode(env1)) { return MMU_HYPV_IDX; + } else if (cpu_supervisor_mode(env1)) { + return MMU_KERNEL_IDX; + } else { + return MMU_USER_IDX; + } #endif } @@ -635,7 +613,6 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) #endif #include "cpu-all.h" -#include "exec-all.h" #ifdef TARGET_SPARC64 /* sun4u.c */ @@ -645,12 +622,6 @@ void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit); trap_state* cpu_tsptr(CPUState* env); #endif -static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) -{ - env->pc = tb->pc; - env->npc = tb->cs_base; -} - static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, target_ulong *cs_base, int *flags) { @@ -658,9 +629,13 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, *cs_base = env->npc; #ifdef TARGET_SPARC64 // AM . Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled - *flags = ((env->pstate & PS_AM) << 2) - | (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2)) - | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2); + *flags = ((env->pstate & PS_AM) << 2) /* 5 */ + | (((env->pstate & PS_PEF) >> 1) /* 3 */ + | ((env->fprs & FPRS_FEF) << 2)) /* 4 */ + | (env->pstate & PS_PRIV) /* 2 */ + | ((env->lsu & (DMMU_E | IMMU_E)) >> 2) /* 1, 0 */ + | ((env->tl & 0xff) << 8) + | (env->dmmu.mmu_primary_context << 16); /* 16... */ #else // FPU enable . Supervisor *flags = (env->psref << 4) | env->psrs;