mirror of
https://github.com/qemu/qemu.git
synced 2024-11-28 14:24:02 +08:00
sparc64: fix pstate privilege bits
- refactor code to handle hpstate only if available for current cpu - conditionally set hypervisor bit in hpstate register - reorder softmmu indices so user accessable ones go first, translation context macros supervisor() and hypervisor() adjusted as well - disable sparcv8 registers for TARGET_SPARC64 - fix cpu_mmu_index to use sparcv9 bits only Signed-off-by: Igor V. Kovalenko <igor.v.kovalenko@gmail.com> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
This commit is contained in:
parent
b8e9fc0625
commit
2aae2b8e0a
@ -92,12 +92,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)
|
||||
@ -341,14 +343,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;
|
||||
@ -508,21 +512,41 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
|
||||
#define CPU_SAVE_VERSION 6
|
||||
|
||||
/* MMU modes definitions */
|
||||
#define MMU_MODE0_SUFFIX _user
|
||||
#define MMU_MODE1_SUFFIX _kernel
|
||||
#ifdef TARGET_SPARC64
|
||||
#define MMU_MODE2_SUFFIX _hypv
|
||||
#define MMU_MODE3_SUFFIX _nucleus
|
||||
#define MMU_MODE4_SUFFIX _user_secondary
|
||||
#define MMU_MODE5_SUFFIX _kernel_secondary
|
||||
#endif
|
||||
#if defined (TARGET_SPARC64)
|
||||
#define MMU_USER_IDX 0
|
||||
#define MMU_MODE0_SUFFIX _user
|
||||
#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
|
||||
#ifdef TARGET_SPARC64
|
||||
#define MMU_NUCLEUS_IDX 3
|
||||
#define MMU_USER_SECONDARY_IDX 4
|
||||
#define MMU_KERNEL_SECONDARY_IDX 5
|
||||
#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)
|
||||
@ -532,12 +556,13 @@ 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 (cpu_hypervisor_mode(env1)) {
|
||||
return MMU_HYPV_IDX;
|
||||
} else if (cpu_supervisor_mode(env1)) {
|
||||
return MMU_KERNEL_IDX;
|
||||
} else {
|
||||
return MMU_USER_IDX;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -746,12 +746,12 @@ void cpu_reset(CPUSPARCState *env)
|
||||
#else
|
||||
#if !defined(TARGET_SPARC64)
|
||||
env->psret = 0;
|
||||
#endif
|
||||
env->psrs = 1;
|
||||
env->psrps = 1;
|
||||
#endif
|
||||
#ifdef TARGET_SPARC64
|
||||
env->pstate = PS_PRIV|PS_RED|PS_PEF|PS_AG;
|
||||
env->hpstate = HS_PRIV;
|
||||
env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0;
|
||||
env->tl = env->maxtl;
|
||||
cpu_tsptr(env)->tt = TT_POWER_ON_RESET;
|
||||
env->lsu = 0;
|
||||
|
@ -1404,11 +1404,7 @@ static target_ulong get_psr(void)
|
||||
(env->psrps? PSR_PS : 0) |
|
||||
(env->psret? PSR_ET : 0) | env->cwp;
|
||||
#else
|
||||
return 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;
|
||||
return env->psr & PSR_ICC;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1427,17 +1423,19 @@ target_ulong cpu_get_psr(CPUState *env1)
|
||||
static void put_psr(target_ulong val)
|
||||
{
|
||||
env->psr = val & PSR_ICC;
|
||||
#if !defined (TARGET_SPARC64)
|
||||
env->psref = (val & PSR_EF)? 1 : 0;
|
||||
env->psrpil = (val & PSR_PIL) >> 8;
|
||||
#endif
|
||||
#if ((!defined (TARGET_SPARC64)) && !defined(CONFIG_USER_ONLY))
|
||||
cpu_check_irqs(env);
|
||||
#endif
|
||||
#if !defined (TARGET_SPARC64)
|
||||
env->psrs = (val & PSR_S)? 1 : 0;
|
||||
env->psrps = (val & PSR_PS)? 1 : 0;
|
||||
#if !defined (TARGET_SPARC64)
|
||||
env->psret = (val & PSR_ET)? 1 : 0;
|
||||
#endif
|
||||
set_cwp(val & PSR_CWP);
|
||||
#endif
|
||||
env->cc_op = CC_OP_FLAGS;
|
||||
}
|
||||
|
||||
@ -2326,7 +2324,7 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
|
||||
asi &= 0xff;
|
||||
|
||||
if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
|
||||
|| ((env->def->features & CPU_FEATURE_HYPV)
|
||||
|| (cpu_has_hypervisor(env)
|
||||
&& asi >= 0x30 && asi < 0x80
|
||||
&& !(env->hpstate & HS_PRIV)))
|
||||
raise_exception(TT_PRIV_ACT);
|
||||
@ -2361,8 +2359,7 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
|
||||
case 0xe2: // UA2007 Primary block init
|
||||
case 0xe3: // UA2007 Secondary block init
|
||||
if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
|
||||
if ((env->def->features & CPU_FEATURE_HYPV)
|
||||
&& env->hpstate & HS_PRIV) {
|
||||
if (cpu_hypervisor_mode(env)) {
|
||||
switch(size) {
|
||||
case 1:
|
||||
ret = ldub_hypv(addr);
|
||||
@ -2678,7 +2675,7 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
|
||||
asi &= 0xff;
|
||||
|
||||
if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
|
||||
|| ((env->def->features & CPU_FEATURE_HYPV)
|
||||
|| (cpu_has_hypervisor(env)
|
||||
&& asi >= 0x30 && asi < 0x80
|
||||
&& !(env->hpstate & HS_PRIV)))
|
||||
raise_exception(TT_PRIV_ACT);
|
||||
@ -2722,8 +2719,7 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
|
||||
case 0xe2: // UA2007 Primary block init
|
||||
case 0xe3: // UA2007 Secondary block init
|
||||
if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
|
||||
if ((env->def->features & CPU_FEATURE_HYPV)
|
||||
&& env->hpstate & HS_PRIV) {
|
||||
if (cpu_hypervisor_mode(env)) {
|
||||
switch(size) {
|
||||
case 1:
|
||||
stb_hypv(addr, val);
|
||||
@ -3048,7 +3044,7 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
|
||||
void helper_ldda_asi(target_ulong addr, int asi, int rd)
|
||||
{
|
||||
if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
|
||||
|| ((env->def->features & CPU_FEATURE_HYPV)
|
||||
|| (cpu_has_hypervisor(env)
|
||||
&& asi >= 0x30 && asi < 0x80
|
||||
&& !(env->hpstate & HS_PRIV)))
|
||||
raise_exception(TT_PRIV_ACT);
|
||||
|
@ -183,9 +183,9 @@ static void gen_op_store_QT0_fpr(unsigned int dst)
|
||||
#define hypervisor(dc) 0
|
||||
#endif
|
||||
#else
|
||||
#define supervisor(dc) (dc->mem_idx >= 1)
|
||||
#define supervisor(dc) (dc->mem_idx >= MMU_KERNEL_IDX)
|
||||
#ifdef TARGET_SPARC64
|
||||
#define hypervisor(dc) (dc->mem_idx == 2)
|
||||
#define hypervisor(dc) (dc->mem_idx == MMU_HYPV_IDX)
|
||||
#else
|
||||
#endif
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user