Commit fb79ceb9 authored by blueswir1's avatar blueswir1

Make UA200x features selectable, add MMU types


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4911 c046a42c-6fe2-441c-8c8c-71466251a162
parent cb3df91a
...@@ -238,6 +238,7 @@ typedef struct CPUSPARCState { ...@@ -238,6 +238,7 @@ typedef struct CPUSPARCState {
uint64_t itlb_tte[64]; uint64_t itlb_tte[64];
uint64_t dtlb_tag[64]; uint64_t dtlb_tag[64];
uint64_t dtlb_tte[64]; uint64_t dtlb_tte[64];
uint32_t mmu_version;
#else #else
uint32_t mmuregs[32]; uint32_t mmuregs[32];
uint64_t mxccdata[4]; uint64_t mxccdata[4];
...@@ -285,6 +286,9 @@ typedef struct CPUSPARCState { ...@@ -285,6 +286,9 @@ typedef struct CPUSPARCState {
#define CPU_FEATURE_VIS1 (1 << 8) #define CPU_FEATURE_VIS1 (1 << 8)
#define CPU_FEATURE_VIS2 (1 << 9) #define CPU_FEATURE_VIS2 (1 << 9)
#define CPU_FEATURE_FSMULD (1 << 10) #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 #ifndef TARGET_SPARC64
#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \ #define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \
CPU_FEATURE_MUL | CPU_FEATURE_DIV | \ CPU_FEATURE_MUL | CPU_FEATURE_DIV | \
...@@ -296,6 +300,12 @@ typedef struct CPUSPARCState { ...@@ -296,6 +300,12 @@ typedef struct CPUSPARCState {
CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \ CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \
CPU_FEATURE_FMUL | CPU_FEATURE_VIS1 | \ CPU_FEATURE_FMUL | CPU_FEATURE_VIS1 | \
CPU_FEATURE_VIS2 | CPU_FEATURE_FSMULD) 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 #endif
#if defined(TARGET_SPARC64) #if defined(TARGET_SPARC64)
......
...@@ -758,7 +758,8 @@ void do_interrupt(CPUState *env) ...@@ -758,7 +758,8 @@ void do_interrupt(CPUState *env)
env->tsptr->tpc = env->pc; env->tsptr->tpc = env->pc;
env->tsptr->tnpc = env->npc; env->tsptr->tnpc = env->npc;
env->tsptr->tt = intno; env->tsptr->tt = intno;
change_pstate(PS_PEF | PS_PRIV | PS_AG); if (!(env->features & CPU_FEATURE_GL))
change_pstate(PS_PEF | PS_PRIV | PS_AG);
if (intno == TT_CLRWIN) if (intno == TT_CLRWIN)
cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1)); cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
...@@ -934,6 +935,7 @@ static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model) ...@@ -934,6 +935,7 @@ static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
env->mmuregs[0] |= def->mmu_version; env->mmuregs[0] |= def->mmu_version;
cpu_sparc_set_id(env, 0); cpu_sparc_set_id(env, 0);
#else #else
env->mmu_version = def->mmu_version;
env->version |= def->nwindows - 1; env->version |= def->nwindows - 1;
#endif #endif
return 0; return 0;
...@@ -978,7 +980,7 @@ static const sparc_def_t sparc_defs[] = { ...@@ -978,7 +980,7 @@ static const sparc_def_t sparc_defs[] = {
.iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24) .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)
| (MAXTL << 8)), | (MAXTL << 8)),
.fpu_version = 0x00000000, .fpu_version = 0x00000000,
.mmu_version = 0, .mmu_version = mmu_us_12,
.nwindows = 4, .nwindows = 4,
.features = CPU_DEFAULT_FEATURES, .features = CPU_DEFAULT_FEATURES,
}, },
...@@ -987,7 +989,7 @@ static const sparc_def_t sparc_defs[] = { ...@@ -987,7 +989,7 @@ static const sparc_def_t sparc_defs[] = {
.iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24) .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)
| (MAXTL << 8)), | (MAXTL << 8)),
.fpu_version = 0x00000000, .fpu_version = 0x00000000,
.mmu_version = 0, .mmu_version = mmu_us_12,
.nwindows = 5, .nwindows = 5,
.features = CPU_DEFAULT_FEATURES, .features = CPU_DEFAULT_FEATURES,
}, },
...@@ -996,7 +998,7 @@ static const sparc_def_t sparc_defs[] = { ...@@ -996,7 +998,7 @@ static const sparc_def_t sparc_defs[] = {
.iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24) .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)
| (MAXTL << 8)), | (MAXTL << 8)),
.fpu_version = 0x00000000, .fpu_version = 0x00000000,
.mmu_version = 0, .mmu_version = mmu_us_12,
.nwindows = 8, .nwindows = 8,
.features = CPU_DEFAULT_FEATURES, .features = CPU_DEFAULT_FEATURES,
}, },
...@@ -1005,7 +1007,7 @@ static const sparc_def_t sparc_defs[] = { ...@@ -1005,7 +1007,7 @@ static const sparc_def_t sparc_defs[] = {
.iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24) .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)
| (MAXTL << 8)), | (MAXTL << 8)),
.fpu_version = 0x00000000, .fpu_version = 0x00000000,
.mmu_version = 0, .mmu_version = mmu_us_12,
.nwindows = 8, .nwindows = 8,
.features = CPU_DEFAULT_FEATURES, .features = CPU_DEFAULT_FEATURES,
}, },
...@@ -1014,7 +1016,7 @@ static const sparc_def_t sparc_defs[] = { ...@@ -1014,7 +1016,7 @@ static const sparc_def_t sparc_defs[] = {
.iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24) .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
| (MAXTL << 8)), | (MAXTL << 8)),
.fpu_version = 0x00000000, .fpu_version = 0x00000000,
.mmu_version = 0, .mmu_version = mmu_us_12,
.nwindows = 8, .nwindows = 8,
.features = CPU_DEFAULT_FEATURES, .features = CPU_DEFAULT_FEATURES,
}, },
...@@ -1023,7 +1025,7 @@ static const sparc_def_t sparc_defs[] = { ...@@ -1023,7 +1025,7 @@ static const sparc_def_t sparc_defs[] = {
.iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24) .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)
| (MAXTL << 8)), | (MAXTL << 8)),
.fpu_version = 0x00000000, .fpu_version = 0x00000000,
.mmu_version = 0, .mmu_version = mmu_us_12,
.nwindows = 8, .nwindows = 8,
.features = CPU_DEFAULT_FEATURES, .features = CPU_DEFAULT_FEATURES,
}, },
...@@ -1032,7 +1034,7 @@ static const sparc_def_t sparc_defs[] = { ...@@ -1032,7 +1034,7 @@ static const sparc_def_t sparc_defs[] = {
.iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24) .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)
| (MAXTL << 8)), | (MAXTL << 8)),
.fpu_version = 0x00000000, .fpu_version = 0x00000000,
.mmu_version = 0, .mmu_version = mmu_us_12,
.nwindows = 8, .nwindows = 8,
.features = CPU_DEFAULT_FEATURES, .features = CPU_DEFAULT_FEATURES,
}, },
...@@ -1041,7 +1043,7 @@ static const sparc_def_t sparc_defs[] = { ...@@ -1041,7 +1043,7 @@ static const sparc_def_t sparc_defs[] = {
.iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24) .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)
| (MAXTL << 8)), | (MAXTL << 8)),
.fpu_version = 0x00000000, .fpu_version = 0x00000000,
.mmu_version = 0, .mmu_version = mmu_us_12,
.nwindows = 8, .nwindows = 8,
.features = CPU_DEFAULT_FEATURES, .features = CPU_DEFAULT_FEATURES,
}, },
...@@ -1050,7 +1052,7 @@ static const sparc_def_t sparc_defs[] = { ...@@ -1050,7 +1052,7 @@ static const sparc_def_t sparc_defs[] = {
.iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24) .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)
| (MAXTL << 8)), | (MAXTL << 8)),
.fpu_version = 0x00000000, .fpu_version = 0x00000000,
.mmu_version = 0, .mmu_version = mmu_us_12,
.nwindows = 8, .nwindows = 8,
.features = CPU_DEFAULT_FEATURES, .features = CPU_DEFAULT_FEATURES,
}, },
...@@ -1059,7 +1061,7 @@ static const sparc_def_t sparc_defs[] = { ...@@ -1059,7 +1061,7 @@ static const sparc_def_t sparc_defs[] = {
.iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24) .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)
| (MAXTL << 8)), | (MAXTL << 8)),
.fpu_version = 0x00000000, .fpu_version = 0x00000000,
.mmu_version = 0, .mmu_version = mmu_us_3,
.nwindows = 8, .nwindows = 8,
.features = CPU_DEFAULT_FEATURES, .features = CPU_DEFAULT_FEATURES,
}, },
...@@ -1068,7 +1070,7 @@ static const sparc_def_t sparc_defs[] = { ...@@ -1068,7 +1070,7 @@ static const sparc_def_t sparc_defs[] = {
.iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24) .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)
| (MAXTL << 8)), | (MAXTL << 8)),
.fpu_version = 0x00000000, .fpu_version = 0x00000000,
.mmu_version = 0, .mmu_version = mmu_us_12,
.nwindows = 8, .nwindows = 8,
.features = CPU_DEFAULT_FEATURES, .features = CPU_DEFAULT_FEATURES,
}, },
...@@ -1077,7 +1079,7 @@ static const sparc_def_t sparc_defs[] = { ...@@ -1077,7 +1079,7 @@ static const sparc_def_t sparc_defs[] = {
.iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24) .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)
| (MAXTL << 8)), | (MAXTL << 8)),
.fpu_version = 0x00000000, .fpu_version = 0x00000000,
.mmu_version = 0, .mmu_version = mmu_us_4,
.nwindows = 8, .nwindows = 8,
.features = CPU_DEFAULT_FEATURES, .features = CPU_DEFAULT_FEATURES,
}, },
...@@ -1086,16 +1088,16 @@ static const sparc_def_t sparc_defs[] = { ...@@ -1086,16 +1088,16 @@ static const sparc_def_t sparc_defs[] = {
.iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24) .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)
| (MAXTL << 8)), | (MAXTL << 8)),
.fpu_version = 0x00000000, .fpu_version = 0x00000000,
.mmu_version = 0, .mmu_version = mmu_us_12,
.nwindows = 8, .nwindows = 8,
.features = CPU_DEFAULT_FEATURES, .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT,
}, },
{ {
.name = "Sun UltraSparc IIIi+", .name = "Sun UltraSparc IIIi+",
.iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24) .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)
| (MAXTL << 8)), | (MAXTL << 8)),
.fpu_version = 0x00000000, .fpu_version = 0x00000000,
.mmu_version = 0, .mmu_version = mmu_us_3,
.nwindows = 8, .nwindows = 8,
.features = CPU_DEFAULT_FEATURES, .features = CPU_DEFAULT_FEATURES,
}, },
...@@ -1104,7 +1106,7 @@ static const sparc_def_t sparc_defs[] = { ...@@ -1104,7 +1106,7 @@ static const sparc_def_t sparc_defs[] = {
.iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24) .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
| (MAXTL << 8)), | (MAXTL << 8)),
.fpu_version = 0x00000000, .fpu_version = 0x00000000,
.mmu_version = 0, .mmu_version = mmu_us_12,
.nwindows = 8, .nwindows = 8,
.features = CPU_DEFAULT_FEATURES, .features = CPU_DEFAULT_FEATURES,
}, },
...@@ -1417,6 +1419,9 @@ static const char * const feature_name[] = { ...@@ -1417,6 +1419,9 @@ static const char * const feature_name[] = {
"vis1", "vis1",
"vis2", "vis2",
"fsmuld", "fsmuld",
"hypv",
"cmt",
"gl",
}; };
static void print_features(FILE *f, static void print_features(FILE *f,
......
...@@ -1549,7 +1549,8 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) ...@@ -1549,7 +1549,8 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
#endif #endif
if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0) if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
|| (asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV))) || ((env->features & CPU_FEATURE_HYPV) && asi >= 0x30 && asi < 0x80
&& !(env->hpstate & HS_PRIV)))
raise_exception(TT_PRIV_ACT); raise_exception(TT_PRIV_ACT);
helper_check_align(addr, size - 1); helper_check_align(addr, size - 1);
...@@ -1561,7 +1562,7 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) ...@@ -1561,7 +1562,7 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign)
case 0x88: // Primary LE case 0x88: // Primary LE
case 0x8a: // Primary no-fault LE case 0x8a: // Primary no-fault LE
if ((asi & 0x80) && (env->pstate & PS_PRIV)) { if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
if (env->hpstate & HS_PRIV) { if ((env->features & CPU_FEATURE_HYPV) && env->hpstate & HS_PRIV) {
switch(size) { switch(size) {
case 1: case 1:
ret = ldub_hypv(addr); ret = ldub_hypv(addr);
...@@ -1837,7 +1838,8 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size) ...@@ -1837,7 +1838,8 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
dump_asi("write", addr, asi, size, val); dump_asi("write", addr, asi, size, val);
#endif #endif
if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0) if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
|| (asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV))) || ((env->features & CPU_FEATURE_HYPV) && asi >= 0x30 && asi < 0x80
&& !(env->hpstate & HS_PRIV)))
raise_exception(TT_PRIV_ACT); raise_exception(TT_PRIV_ACT);
helper_check_align(addr, size - 1); helper_check_align(addr, size - 1);
...@@ -1873,7 +1875,7 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size) ...@@ -1873,7 +1875,7 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
case 0x80: // Primary case 0x80: // Primary
case 0x88: // Primary LE case 0x88: // Primary LE
if ((asi & 0x80) && (env->pstate & PS_PRIV)) { if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
if (env->hpstate & HS_PRIV) { if ((env->features & CPU_FEATURE_HYPV) && env->hpstate & HS_PRIV) {
switch(size) { switch(size) {
case 1: case 1:
stb_hypv(addr, val); stb_hypv(addr, val);
...@@ -2153,7 +2155,8 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size) ...@@ -2153,7 +2155,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) void helper_ldda_asi(target_ulong addr, int asi, int rd)
{ {
if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0) if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
|| (asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV))) || ((env->features & CPU_FEATURE_HYPV) && asi >= 0x30 && asi < 0x80
&& !(env->hpstate & HS_PRIV)))
raise_exception(TT_PRIV_ACT); raise_exception(TT_PRIV_ACT);
switch (asi) { switch (asi) {
...@@ -2726,7 +2729,8 @@ void change_pstate(uint64_t new_pstate) ...@@ -2726,7 +2729,8 @@ void change_pstate(uint64_t new_pstate)
void helper_wrpstate(target_ulong new_state) void helper_wrpstate(target_ulong new_state)
{ {
change_pstate(new_state & 0xf3f); if (!(env->features & CPU_FEATURE_GL))
change_pstate(new_state & 0xf3f);
} }
void helper_done(void) void helper_done(void)
......
...@@ -2175,6 +2175,7 @@ static void disas_sparc_insn(DisasContext * dc) ...@@ -2175,6 +2175,7 @@ static void disas_sparc_insn(DisasContext * dc)
goto priv_insn; goto priv_insn;
tcg_gen_helper_1_0(helper_rdpsr, cpu_dst); tcg_gen_helper_1_0(helper_rdpsr, cpu_dst);
#else #else
CHECK_IU_FEATURE(dc, HYPV);
if (!hypervisor(dc)) if (!hypervisor(dc))
goto priv_insn; goto priv_insn;
rs1 = GET_FIELD(insn, 13, 17); rs1 = GET_FIELD(insn, 13, 17);
...@@ -2325,11 +2326,13 @@ static void disas_sparc_insn(DisasContext * dc) ...@@ -2325,11 +2326,13 @@ static void disas_sparc_insn(DisasContext * dc)
tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32); tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
break; break;
case 16: // UA2005 gl case 16: // UA2005 gl
CHECK_IU_FEATURE(dc, GL);
tcg_gen_ld_i32(cpu_tmp32, cpu_env, tcg_gen_ld_i32(cpu_tmp32, cpu_env,
offsetof(CPUSPARCState, gl)); offsetof(CPUSPARCState, gl));
tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32); tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
break; break;
case 26: // UA2005 strand status case 26: // UA2005 strand status
CHECK_IU_FEATURE(dc, HYPV);
if (!hypervisor(dc)) if (!hypervisor(dc))
goto priv_insn; goto priv_insn;
tcg_gen_ld_i32(cpu_tmp32, cpu_env, tcg_gen_ld_i32(cpu_tmp32, cpu_env,
...@@ -3431,11 +3434,13 @@ static void disas_sparc_insn(DisasContext * dc) ...@@ -3431,11 +3434,13 @@ static void disas_sparc_insn(DisasContext * dc)
wstate)); wstate));
break; break;
case 16: // UA2005 gl case 16: // UA2005 gl
CHECK_IU_FEATURE(dc, GL);
tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0); tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
tcg_gen_st_i32(cpu_tmp32, cpu_env, tcg_gen_st_i32(cpu_tmp32, cpu_env,
offsetof(CPUSPARCState, gl)); offsetof(CPUSPARCState, gl));
break; break;
case 26: // UA2005 strand status case 26: // UA2005 strand status
CHECK_IU_FEATURE(dc, HYPV);
if (!hypervisor(dc)) if (!hypervisor(dc))
goto priv_insn; goto priv_insn;
tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0); tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
...@@ -3461,6 +3466,7 @@ static void disas_sparc_insn(DisasContext * dc) ...@@ -3461,6 +3466,7 @@ static void disas_sparc_insn(DisasContext * dc)
tcg_gen_st_tl(cpu_tmp0, cpu_env, tcg_gen_st_tl(cpu_tmp0, cpu_env,
offsetof(CPUSPARCState, tbr)); offsetof(CPUSPARCState, tbr));
#else #else
CHECK_IU_FEATURE(dc, HYPV);
if (!hypervisor(dc)) if (!hypervisor(dc))
goto priv_insn; goto priv_insn;
tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2); tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment