Use initial CPU definition structure for some CPU fields instead of copying
them around, based on patch by Luis Pureza. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5042 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
1a7de94aa4
commit
5578ceab94
@ -187,6 +187,54 @@ typedef struct trap_state {
|
||||
} trap_state;
|
||||
#endif
|
||||
|
||||
typedef struct sparc_def_t {
|
||||
const char *name;
|
||||
target_ulong iu_version;
|
||||
uint32_t fpu_version;
|
||||
uint32_t mmu_version;
|
||||
uint32_t mmu_bm;
|
||||
uint32_t mmu_ctpr_mask;
|
||||
uint32_t mmu_cxr_mask;
|
||||
uint32_t mmu_sfsr_mask;
|
||||
uint32_t mmu_trcr_mask;
|
||||
uint32_t features;
|
||||
uint32_t nwindows;
|
||||
uint32_t maxtl;
|
||||
} sparc_def_t;
|
||||
|
||||
#define CPU_FEATURE_FLOAT (1 << 0)
|
||||
#define CPU_FEATURE_FLOAT128 (1 << 1)
|
||||
#define CPU_FEATURE_SWAP (1 << 2)
|
||||
#define CPU_FEATURE_MUL (1 << 3)
|
||||
#define CPU_FEATURE_DIV (1 << 4)
|
||||
#define CPU_FEATURE_FLUSH (1 << 5)
|
||||
#define CPU_FEATURE_FSQRT (1 << 6)
|
||||
#define CPU_FEATURE_FMUL (1 << 7)
|
||||
#define CPU_FEATURE_VIS1 (1 << 8)
|
||||
#define CPU_FEATURE_VIS2 (1 << 9)
|
||||
#define CPU_FEATURE_FSMULD (1 << 10)
|
||||
#define CPU_FEATURE_HYPV (1 << 11)
|
||||
#define CPU_FEATURE_CMT (1 << 12)
|
||||
#define CPU_FEATURE_GL (1 << 13)
|
||||
#ifndef TARGET_SPARC64
|
||||
#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \
|
||||
CPU_FEATURE_MUL | CPU_FEATURE_DIV | \
|
||||
CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \
|
||||
CPU_FEATURE_FMUL | CPU_FEATURE_FSMULD)
|
||||
#else
|
||||
#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \
|
||||
CPU_FEATURE_MUL | CPU_FEATURE_DIV | \
|
||||
CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \
|
||||
CPU_FEATURE_FMUL | CPU_FEATURE_VIS1 | \
|
||||
CPU_FEATURE_VIS2 | CPU_FEATURE_FSMULD)
|
||||
enum {
|
||||
mmu_us_12, // Ultrasparc < III (64 entry TLB)
|
||||
mmu_us_3, // Ultrasparc III (512 entry TLB)
|
||||
mmu_us_4, // Ultrasparc IV (several TLBs, 32 and 256MB pages)
|
||||
mmu_sun4v, // T1, T2
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef struct CPUSPARCState {
|
||||
target_ulong gregs[8]; /* general registers */
|
||||
target_ulong *regwptr; /* pointer to current register window */
|
||||
@ -217,11 +265,6 @@ typedef struct CPUSPARCState {
|
||||
int psref; /* enable fpu */
|
||||
target_ulong version;
|
||||
int interrupt_index;
|
||||
uint32_t mmu_bm;
|
||||
uint32_t mmu_ctpr_mask;
|
||||
uint32_t mmu_cxr_mask;
|
||||
uint32_t mmu_sfsr_mask;
|
||||
uint32_t mmu_trcr_mask;
|
||||
uint32_t nwindows;
|
||||
/* NOTE: we allow 8 more registers to handle wrapping */
|
||||
target_ulong regbase[MAX_NWINDOWS * 16 + 8];
|
||||
@ -275,42 +318,9 @@ typedef struct CPUSPARCState {
|
||||
uint64_t hpstate, htstate[MAXTL_MAX], hintp, htba, hver, hstick_cmpr, ssr;
|
||||
void *hstick; // UA 2005
|
||||
#endif
|
||||
uint32_t features;
|
||||
sparc_def_t *def;
|
||||
} CPUSPARCState;
|
||||
|
||||
#define CPU_FEATURE_FLOAT (1 << 0)
|
||||
#define CPU_FEATURE_FLOAT128 (1 << 1)
|
||||
#define CPU_FEATURE_SWAP (1 << 2)
|
||||
#define CPU_FEATURE_MUL (1 << 3)
|
||||
#define CPU_FEATURE_DIV (1 << 4)
|
||||
#define CPU_FEATURE_FLUSH (1 << 5)
|
||||
#define CPU_FEATURE_FSQRT (1 << 6)
|
||||
#define CPU_FEATURE_FMUL (1 << 7)
|
||||
#define CPU_FEATURE_VIS1 (1 << 8)
|
||||
#define CPU_FEATURE_VIS2 (1 << 9)
|
||||
#define CPU_FEATURE_FSMULD (1 << 10)
|
||||
#define CPU_FEATURE_HYPV (1 << 11)
|
||||
#define CPU_FEATURE_CMT (1 << 12)
|
||||
#define CPU_FEATURE_GL (1 << 13)
|
||||
#ifndef TARGET_SPARC64
|
||||
#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \
|
||||
CPU_FEATURE_MUL | CPU_FEATURE_DIV | \
|
||||
CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \
|
||||
CPU_FEATURE_FMUL | CPU_FEATURE_FSMULD)
|
||||
#else
|
||||
#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \
|
||||
CPU_FEATURE_MUL | CPU_FEATURE_DIV | \
|
||||
CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \
|
||||
CPU_FEATURE_FMUL | CPU_FEATURE_VIS1 | \
|
||||
CPU_FEATURE_VIS2 | CPU_FEATURE_FSMULD)
|
||||
enum {
|
||||
mmu_us_12, // Ultrasparc < III (64 entry TLB)
|
||||
mmu_us_3, // Ultrasparc III (512 entry TLB)
|
||||
mmu_us_4, // Ultrasparc IV (several TLBs, 32 and 256MB pages)
|
||||
mmu_sun4v, // T1, T2
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_SPARC64)
|
||||
#define GET_FSR32(env) (env->fsr & 0xcfc1ffff)
|
||||
#define PUT_FSR32(env, val) do { uint32_t _tmp = val; \
|
||||
|
@ -34,23 +34,6 @@
|
||||
//#define DEBUG_FEATURES
|
||||
//#define DEBUG_PCALL
|
||||
|
||||
typedef struct sparc_def_t sparc_def_t;
|
||||
|
||||
struct sparc_def_t {
|
||||
const char *name;
|
||||
target_ulong iu_version;
|
||||
uint32_t fpu_version;
|
||||
uint32_t mmu_version;
|
||||
uint32_t mmu_bm;
|
||||
uint32_t mmu_ctpr_mask;
|
||||
uint32_t mmu_cxr_mask;
|
||||
uint32_t mmu_sfsr_mask;
|
||||
uint32_t mmu_trcr_mask;
|
||||
uint32_t features;
|
||||
uint32_t nwindows;
|
||||
uint32_t maxtl;
|
||||
};
|
||||
|
||||
static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model);
|
||||
|
||||
/* Sparc MMU emulation */
|
||||
@ -137,7 +120,7 @@ static int get_physical_address(CPUState *env, target_phys_addr_t *physical,
|
||||
|
||||
if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
|
||||
// Boot mode: instruction fetches are taken from PROM
|
||||
if (rw == 2 && (env->mmuregs[0] & env->mmu_bm)) {
|
||||
if (rw == 2 && (env->mmuregs[0] & env->def->mmu_bm)) {
|
||||
*physical = env->prom_addr | (address & 0x7ffffULL);
|
||||
*prot = PAGE_READ | PAGE_EXEC;
|
||||
return 0;
|
||||
@ -759,7 +742,7 @@ void do_interrupt(CPUState *env)
|
||||
env->tsptr->tpc = env->pc;
|
||||
env->tsptr->tnpc = env->npc;
|
||||
env->tsptr->tt = intno;
|
||||
if (!(env->features & CPU_FEATURE_GL)) {
|
||||
if (!(env->def->features & CPU_FEATURE_GL)) {
|
||||
switch (intno) {
|
||||
case TT_IVEC:
|
||||
change_pstate(PS_PEF | PS_PRIV | PS_IG);
|
||||
@ -923,7 +906,7 @@ void cpu_reset(CPUSPARCState *env)
|
||||
#else
|
||||
env->pc = 0;
|
||||
env->mmuregs[0] &= ~(MMU_E | MMU_NF);
|
||||
env->mmuregs[0] |= env->mmu_bm;
|
||||
env->mmuregs[0] |= env->def->mmu_bm;
|
||||
#endif
|
||||
env->npc = env->pc + 4;
|
||||
#endif
|
||||
@ -936,17 +919,17 @@ static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
|
||||
if (cpu_sparc_find_by_name(def, cpu_model) < 0)
|
||||
return -1;
|
||||
|
||||
env->features = def->features;
|
||||
env->def = qemu_mallocz(sizeof(*def));
|
||||
memcpy(env->def, def, sizeof(*def));
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
if ((env->def->features & CPU_FEATURE_FLOAT))
|
||||
env->def->features |= CPU_FEATURE_FLOAT128;
|
||||
#endif
|
||||
env->cpu_model_str = cpu_model;
|
||||
env->version = def->iu_version;
|
||||
env->fsr = def->fpu_version;
|
||||
env->nwindows = def->nwindows;
|
||||
#if !defined(TARGET_SPARC64)
|
||||
env->mmu_bm = def->mmu_bm;
|
||||
env->mmu_ctpr_mask = def->mmu_ctpr_mask;
|
||||
env->mmu_cxr_mask = def->mmu_cxr_mask;
|
||||
env->mmu_sfsr_mask = def->mmu_sfsr_mask;
|
||||
env->mmu_trcr_mask = def->mmu_trcr_mask;
|
||||
env->mmuregs[0] |= def->mmu_version;
|
||||
cpu_sparc_set_id(env, 0);
|
||||
#else
|
||||
@ -960,6 +943,7 @@ static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
|
||||
|
||||
static void cpu_sparc_close(CPUSPARCState *env)
|
||||
{
|
||||
free(env->def);
|
||||
free(env);
|
||||
}
|
||||
|
||||
|
@ -1203,15 +1203,15 @@ void helper_st_asi(target_ulong addr, uint64_t val, int asi, int size)
|
||||
(val & 0x00ffffff);
|
||||
// Mappings generated during no-fault mode or MMU
|
||||
// disabled mode are invalid in normal mode
|
||||
if ((oldreg & (MMU_E | MMU_NF | env->mmu_bm)) !=
|
||||
(env->mmuregs[reg] & (MMU_E | MMU_NF | env->mmu_bm)))
|
||||
if ((oldreg & (MMU_E | MMU_NF | env->def->mmu_bm)) !=
|
||||
(env->mmuregs[reg] & (MMU_E | MMU_NF | env->def->mmu_bm)))
|
||||
tlb_flush(env, 1);
|
||||
break;
|
||||
case 1: // Context Table Pointer Register
|
||||
env->mmuregs[reg] = val & env->mmu_ctpr_mask;
|
||||
env->mmuregs[reg] = val & env->def->mmu_ctpr_mask;
|
||||
break;
|
||||
case 2: // Context Register
|
||||
env->mmuregs[reg] = val & env->mmu_cxr_mask;
|
||||
env->mmuregs[reg] = val & env->def->mmu_cxr_mask;
|
||||
if (oldreg != env->mmuregs[reg]) {
|
||||
/* we flush when the MMU context changes because
|
||||
QEMU has no MMU context support */
|
||||
@ -1222,10 +1222,10 @@ void helper_st_asi(target_ulong addr, uint64_t val, int asi, int size)
|
||||
case 4: // Synchronous Fault Address Register
|
||||
break;
|
||||
case 0x10: // TLB Replacement Control Register
|
||||
env->mmuregs[reg] = val & env->mmu_trcr_mask;
|
||||
env->mmuregs[reg] = val & env->def->mmu_trcr_mask;
|
||||
break;
|
||||
case 0x13: // Synchronous Fault Status Register with Read and Clear
|
||||
env->mmuregs[3] = val & env->mmu_sfsr_mask;
|
||||
env->mmuregs[3] = val & env->def->mmu_sfsr_mask;
|
||||
break;
|
||||
case 0x14: // Synchronous Fault Address Register
|
||||
env->mmuregs[4] = val;
|
||||
@ -1552,7 +1552,8 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
|
||||
#endif
|
||||
|
||||
if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
|
||||
|| ((env->features & CPU_FEATURE_HYPV) && asi >= 0x30 && asi < 0x80
|
||||
|| ((env->def->features & CPU_FEATURE_HYPV)
|
||||
&& asi >= 0x30 && asi < 0x80
|
||||
&& !(env->hpstate & HS_PRIV)))
|
||||
raise_exception(TT_PRIV_ACT);
|
||||
|
||||
@ -1565,7 +1566,8 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
|
||||
case 0x88: // Primary LE
|
||||
case 0x8a: // Primary no-fault LE
|
||||
if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
|
||||
if ((env->features & CPU_FEATURE_HYPV) && env->hpstate & HS_PRIV) {
|
||||
if ((env->def->features & CPU_FEATURE_HYPV)
|
||||
&& env->hpstate & HS_PRIV) {
|
||||
switch(size) {
|
||||
case 1:
|
||||
ret = ldub_hypv(addr);
|
||||
@ -1791,7 +1793,8 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
|
||||
dump_asi("write", addr, asi, size, val);
|
||||
#endif
|
||||
if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
|
||||
|| ((env->features & CPU_FEATURE_HYPV) && asi >= 0x30 && asi < 0x80
|
||||
|| ((env->def->features & CPU_FEATURE_HYPV)
|
||||
&& asi >= 0x30 && asi < 0x80
|
||||
&& !(env->hpstate & HS_PRIV)))
|
||||
raise_exception(TT_PRIV_ACT);
|
||||
|
||||
@ -1828,7 +1831,8 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
|
||||
case 0x80: // Primary
|
||||
case 0x88: // Primary LE
|
||||
if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
|
||||
if ((env->features & CPU_FEATURE_HYPV) && env->hpstate & HS_PRIV) {
|
||||
if ((env->def->features & CPU_FEATURE_HYPV)
|
||||
&& env->hpstate & HS_PRIV) {
|
||||
switch(size) {
|
||||
case 1:
|
||||
stb_hypv(addr, val);
|
||||
@ -2108,7 +2112,8 @@ 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->features & CPU_FEATURE_HYPV) && asi >= 0x30 && asi < 0x80
|
||||
|| ((env->def->features & CPU_FEATURE_HYPV)
|
||||
&& asi >= 0x30 && asi < 0x80
|
||||
&& !(env->hpstate & HS_PRIV)))
|
||||
raise_exception(TT_PRIV_ACT);
|
||||
|
||||
@ -2682,7 +2687,7 @@ void change_pstate(uint64_t new_pstate)
|
||||
|
||||
void helper_wrpstate(target_ulong new_state)
|
||||
{
|
||||
if (!(env->features & CPU_FEATURE_GL))
|
||||
if (!(env->def->features & CPU_FEATURE_GL))
|
||||
change_pstate(new_state & 0xf3f);
|
||||
}
|
||||
|
||||
|
@ -59,7 +59,7 @@ typedef struct DisasContext {
|
||||
int fpu_enabled;
|
||||
int address_mask_32bit;
|
||||
struct TranslationBlock *tb;
|
||||
uint32_t features;
|
||||
sparc_def_t *def;
|
||||
} DisasContext;
|
||||
|
||||
// This function uses non-native bit order
|
||||
@ -1905,10 +1905,10 @@ static inline TCGv get_src2(unsigned int insn, TCGv def)
|
||||
}
|
||||
|
||||
#define CHECK_IU_FEATURE(dc, FEATURE) \
|
||||
if (!((dc)->features & CPU_FEATURE_ ## FEATURE)) \
|
||||
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
|
||||
goto illegal_insn;
|
||||
#define CHECK_FPU_FEATURE(dc, FEATURE) \
|
||||
if (!((dc)->features & CPU_FEATURE_ ## FEATURE)) \
|
||||
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
|
||||
goto nfpu_insn;
|
||||
|
||||
/* before an instruction, dc->pc must be static */
|
||||
@ -4141,7 +4141,7 @@ static void disas_sparc_insn(DisasContext * dc)
|
||||
goto jmp_insn;
|
||||
#endif
|
||||
case 0x3b: /* flush */
|
||||
if (!((dc)->features & CPU_FEATURE_FLUSH))
|
||||
if (!((dc)->def->features & CPU_FEATURE_FLUSH))
|
||||
goto unimp_flush;
|
||||
tcg_gen_helper_0_1(helper_flush, cpu_dst);
|
||||
break;
|
||||
@ -4742,13 +4742,10 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
|
||||
last_pc = dc->pc;
|
||||
dc->npc = (target_ulong) tb->cs_base;
|
||||
dc->mem_idx = cpu_mmu_index(env);
|
||||
dc->features = env->features;
|
||||
if ((dc->features & CPU_FEATURE_FLOAT)) {
|
||||
dc->def = env->def;
|
||||
if ((dc->def->features & CPU_FEATURE_FLOAT))
|
||||
dc->fpu_enabled = cpu_fpu_enabled(env);
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
dc->features |= CPU_FEATURE_FLOAT128;
|
||||
#endif
|
||||
} else
|
||||
else
|
||||
dc->fpu_enabled = 0;
|
||||
#ifdef TARGET_SPARC64
|
||||
dc->address_mask_32bit = env->pstate & PS_AM;
|
||||
|
Loading…
Reference in New Issue
Block a user