Commit fb79ceb91a6ff9ee52265893f9d66dd6833726da
1 parent
cb3df91a
Make UA200x features selectable, add MMU types
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4911 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
48 additions
and
23 deletions
target-sparc/cpu.h
... | ... | @@ -238,6 +238,7 @@ typedef struct CPUSPARCState { |
238 | 238 | uint64_t itlb_tte[64]; |
239 | 239 | uint64_t dtlb_tag[64]; |
240 | 240 | uint64_t dtlb_tte[64]; |
241 | + uint32_t mmu_version; | |
241 | 242 | #else |
242 | 243 | uint32_t mmuregs[32]; |
243 | 244 | uint64_t mxccdata[4]; |
... | ... | @@ -285,6 +286,9 @@ typedef struct CPUSPARCState { |
285 | 286 | #define CPU_FEATURE_VIS1 (1 << 8) |
286 | 287 | #define CPU_FEATURE_VIS2 (1 << 9) |
287 | 288 | #define CPU_FEATURE_FSMULD (1 << 10) |
289 | +#define CPU_FEATURE_HYPV (1 << 11) | |
290 | +#define CPU_FEATURE_CMT (1 << 12) | |
291 | +#define CPU_FEATURE_GL (1 << 13) | |
288 | 292 | #ifndef TARGET_SPARC64 |
289 | 293 | #define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \ |
290 | 294 | CPU_FEATURE_MUL | CPU_FEATURE_DIV | \ |
... | ... | @@ -296,6 +300,12 @@ typedef struct CPUSPARCState { |
296 | 300 | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \ |
297 | 301 | CPU_FEATURE_FMUL | CPU_FEATURE_VIS1 | \ |
298 | 302 | CPU_FEATURE_VIS2 | CPU_FEATURE_FSMULD) |
303 | +enum { | |
304 | + mmu_us_12, // Ultrasparc < III (64 entry TLB) | |
305 | + mmu_us_3, // Ultrasparc III (512 entry TLB) | |
306 | + mmu_us_4, // Ultrasparc IV (several TLBs, 32 and 256MB pages) | |
307 | + mmu_sun4v, // T1, T2 | |
308 | +}; | |
299 | 309 | #endif |
300 | 310 | |
301 | 311 | #if defined(TARGET_SPARC64) | ... | ... |
target-sparc/helper.c
... | ... | @@ -758,7 +758,8 @@ void do_interrupt(CPUState *env) |
758 | 758 | env->tsptr->tpc = env->pc; |
759 | 759 | env->tsptr->tnpc = env->npc; |
760 | 760 | env->tsptr->tt = intno; |
761 | - change_pstate(PS_PEF | PS_PRIV | PS_AG); | |
761 | + if (!(env->features & CPU_FEATURE_GL)) | |
762 | + change_pstate(PS_PEF | PS_PRIV | PS_AG); | |
762 | 763 | |
763 | 764 | if (intno == TT_CLRWIN) |
764 | 765 | 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 | 935 | env->mmuregs[0] |= def->mmu_version; |
935 | 936 | cpu_sparc_set_id(env, 0); |
936 | 937 | #else |
938 | + env->mmu_version = def->mmu_version; | |
937 | 939 | env->version |= def->nwindows - 1; |
938 | 940 | #endif |
939 | 941 | return 0; |
... | ... | @@ -978,7 +980,7 @@ static const sparc_def_t sparc_defs[] = { |
978 | 980 | .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24) |
979 | 981 | | (MAXTL << 8)), |
980 | 982 | .fpu_version = 0x00000000, |
981 | - .mmu_version = 0, | |
983 | + .mmu_version = mmu_us_12, | |
982 | 984 | .nwindows = 4, |
983 | 985 | .features = CPU_DEFAULT_FEATURES, |
984 | 986 | }, |
... | ... | @@ -987,7 +989,7 @@ static const sparc_def_t sparc_defs[] = { |
987 | 989 | .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24) |
988 | 990 | | (MAXTL << 8)), |
989 | 991 | .fpu_version = 0x00000000, |
990 | - .mmu_version = 0, | |
992 | + .mmu_version = mmu_us_12, | |
991 | 993 | .nwindows = 5, |
992 | 994 | .features = CPU_DEFAULT_FEATURES, |
993 | 995 | }, |
... | ... | @@ -996,7 +998,7 @@ static const sparc_def_t sparc_defs[] = { |
996 | 998 | .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24) |
997 | 999 | | (MAXTL << 8)), |
998 | 1000 | .fpu_version = 0x00000000, |
999 | - .mmu_version = 0, | |
1001 | + .mmu_version = mmu_us_12, | |
1000 | 1002 | .nwindows = 8, |
1001 | 1003 | .features = CPU_DEFAULT_FEATURES, |
1002 | 1004 | }, |
... | ... | @@ -1005,7 +1007,7 @@ static const sparc_def_t sparc_defs[] = { |
1005 | 1007 | .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24) |
1006 | 1008 | | (MAXTL << 8)), |
1007 | 1009 | .fpu_version = 0x00000000, |
1008 | - .mmu_version = 0, | |
1010 | + .mmu_version = mmu_us_12, | |
1009 | 1011 | .nwindows = 8, |
1010 | 1012 | .features = CPU_DEFAULT_FEATURES, |
1011 | 1013 | }, |
... | ... | @@ -1014,7 +1016,7 @@ static const sparc_def_t sparc_defs[] = { |
1014 | 1016 | .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24) |
1015 | 1017 | | (MAXTL << 8)), |
1016 | 1018 | .fpu_version = 0x00000000, |
1017 | - .mmu_version = 0, | |
1019 | + .mmu_version = mmu_us_12, | |
1018 | 1020 | .nwindows = 8, |
1019 | 1021 | .features = CPU_DEFAULT_FEATURES, |
1020 | 1022 | }, |
... | ... | @@ -1023,7 +1025,7 @@ static const sparc_def_t sparc_defs[] = { |
1023 | 1025 | .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24) |
1024 | 1026 | | (MAXTL << 8)), |
1025 | 1027 | .fpu_version = 0x00000000, |
1026 | - .mmu_version = 0, | |
1028 | + .mmu_version = mmu_us_12, | |
1027 | 1029 | .nwindows = 8, |
1028 | 1030 | .features = CPU_DEFAULT_FEATURES, |
1029 | 1031 | }, |
... | ... | @@ -1032,7 +1034,7 @@ static const sparc_def_t sparc_defs[] = { |
1032 | 1034 | .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24) |
1033 | 1035 | | (MAXTL << 8)), |
1034 | 1036 | .fpu_version = 0x00000000, |
1035 | - .mmu_version = 0, | |
1037 | + .mmu_version = mmu_us_12, | |
1036 | 1038 | .nwindows = 8, |
1037 | 1039 | .features = CPU_DEFAULT_FEATURES, |
1038 | 1040 | }, |
... | ... | @@ -1041,7 +1043,7 @@ static const sparc_def_t sparc_defs[] = { |
1041 | 1043 | .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24) |
1042 | 1044 | | (MAXTL << 8)), |
1043 | 1045 | .fpu_version = 0x00000000, |
1044 | - .mmu_version = 0, | |
1046 | + .mmu_version = mmu_us_12, | |
1045 | 1047 | .nwindows = 8, |
1046 | 1048 | .features = CPU_DEFAULT_FEATURES, |
1047 | 1049 | }, |
... | ... | @@ -1050,7 +1052,7 @@ static const sparc_def_t sparc_defs[] = { |
1050 | 1052 | .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24) |
1051 | 1053 | | (MAXTL << 8)), |
1052 | 1054 | .fpu_version = 0x00000000, |
1053 | - .mmu_version = 0, | |
1055 | + .mmu_version = mmu_us_12, | |
1054 | 1056 | .nwindows = 8, |
1055 | 1057 | .features = CPU_DEFAULT_FEATURES, |
1056 | 1058 | }, |
... | ... | @@ -1059,7 +1061,7 @@ static const sparc_def_t sparc_defs[] = { |
1059 | 1061 | .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24) |
1060 | 1062 | | (MAXTL << 8)), |
1061 | 1063 | .fpu_version = 0x00000000, |
1062 | - .mmu_version = 0, | |
1064 | + .mmu_version = mmu_us_3, | |
1063 | 1065 | .nwindows = 8, |
1064 | 1066 | .features = CPU_DEFAULT_FEATURES, |
1065 | 1067 | }, |
... | ... | @@ -1068,7 +1070,7 @@ static const sparc_def_t sparc_defs[] = { |
1068 | 1070 | .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24) |
1069 | 1071 | | (MAXTL << 8)), |
1070 | 1072 | .fpu_version = 0x00000000, |
1071 | - .mmu_version = 0, | |
1073 | + .mmu_version = mmu_us_12, | |
1072 | 1074 | .nwindows = 8, |
1073 | 1075 | .features = CPU_DEFAULT_FEATURES, |
1074 | 1076 | }, |
... | ... | @@ -1077,7 +1079,7 @@ static const sparc_def_t sparc_defs[] = { |
1077 | 1079 | .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24) |
1078 | 1080 | | (MAXTL << 8)), |
1079 | 1081 | .fpu_version = 0x00000000, |
1080 | - .mmu_version = 0, | |
1082 | + .mmu_version = mmu_us_4, | |
1081 | 1083 | .nwindows = 8, |
1082 | 1084 | .features = CPU_DEFAULT_FEATURES, |
1083 | 1085 | }, |
... | ... | @@ -1086,16 +1088,16 @@ static const sparc_def_t sparc_defs[] = { |
1086 | 1088 | .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24) |
1087 | 1089 | | (MAXTL << 8)), |
1088 | 1090 | .fpu_version = 0x00000000, |
1089 | - .mmu_version = 0, | |
1091 | + .mmu_version = mmu_us_12, | |
1090 | 1092 | .nwindows = 8, |
1091 | - .features = CPU_DEFAULT_FEATURES, | |
1093 | + .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT, | |
1092 | 1094 | }, |
1093 | 1095 | { |
1094 | 1096 | .name = "Sun UltraSparc IIIi+", |
1095 | 1097 | .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24) |
1096 | 1098 | | (MAXTL << 8)), |
1097 | 1099 | .fpu_version = 0x00000000, |
1098 | - .mmu_version = 0, | |
1100 | + .mmu_version = mmu_us_3, | |
1099 | 1101 | .nwindows = 8, |
1100 | 1102 | .features = CPU_DEFAULT_FEATURES, |
1101 | 1103 | }, |
... | ... | @@ -1104,7 +1106,7 @@ static const sparc_def_t sparc_defs[] = { |
1104 | 1106 | .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24) |
1105 | 1107 | | (MAXTL << 8)), |
1106 | 1108 | .fpu_version = 0x00000000, |
1107 | - .mmu_version = 0, | |
1109 | + .mmu_version = mmu_us_12, | |
1108 | 1110 | .nwindows = 8, |
1109 | 1111 | .features = CPU_DEFAULT_FEATURES, |
1110 | 1112 | }, |
... | ... | @@ -1417,6 +1419,9 @@ static const char * const feature_name[] = { |
1417 | 1419 | "vis1", |
1418 | 1420 | "vis2", |
1419 | 1421 | "fsmuld", |
1422 | + "hypv", | |
1423 | + "cmt", | |
1424 | + "gl", | |
1420 | 1425 | }; |
1421 | 1426 | |
1422 | 1427 | static void print_features(FILE *f, | ... | ... |
target-sparc/op_helper.c
... | ... | @@ -1549,7 +1549,8 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) |
1549 | 1549 | #endif |
1550 | 1550 | |
1551 | 1551 | if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0) |
1552 | - || (asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV))) | |
1552 | + || ((env->features & CPU_FEATURE_HYPV) && asi >= 0x30 && asi < 0x80 | |
1553 | + && !(env->hpstate & HS_PRIV))) | |
1553 | 1554 | raise_exception(TT_PRIV_ACT); |
1554 | 1555 | |
1555 | 1556 | 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 | 1562 | case 0x88: // Primary LE |
1562 | 1563 | case 0x8a: // Primary no-fault LE |
1563 | 1564 | if ((asi & 0x80) && (env->pstate & PS_PRIV)) { |
1564 | - if (env->hpstate & HS_PRIV) { | |
1565 | + if ((env->features & CPU_FEATURE_HYPV) && env->hpstate & HS_PRIV) { | |
1565 | 1566 | switch(size) { |
1566 | 1567 | case 1: |
1567 | 1568 | ret = ldub_hypv(addr); |
... | ... | @@ -1837,7 +1838,8 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size) |
1837 | 1838 | dump_asi("write", addr, asi, size, val); |
1838 | 1839 | #endif |
1839 | 1840 | if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0) |
1840 | - || (asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV))) | |
1841 | + || ((env->features & CPU_FEATURE_HYPV) && asi >= 0x30 && asi < 0x80 | |
1842 | + && !(env->hpstate & HS_PRIV))) | |
1841 | 1843 | raise_exception(TT_PRIV_ACT); |
1842 | 1844 | |
1843 | 1845 | 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 | 1875 | case 0x80: // Primary |
1874 | 1876 | case 0x88: // Primary LE |
1875 | 1877 | if ((asi & 0x80) && (env->pstate & PS_PRIV)) { |
1876 | - if (env->hpstate & HS_PRIV) { | |
1878 | + if ((env->features & CPU_FEATURE_HYPV) && env->hpstate & HS_PRIV) { | |
1877 | 1879 | switch(size) { |
1878 | 1880 | case 1: |
1879 | 1881 | stb_hypv(addr, val); |
... | ... | @@ -2153,7 +2155,8 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size) |
2153 | 2155 | void helper_ldda_asi(target_ulong addr, int asi, int rd) |
2154 | 2156 | { |
2155 | 2157 | if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0) |
2156 | - || (asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV))) | |
2158 | + || ((env->features & CPU_FEATURE_HYPV) && asi >= 0x30 && asi < 0x80 | |
2159 | + && !(env->hpstate & HS_PRIV))) | |
2157 | 2160 | raise_exception(TT_PRIV_ACT); |
2158 | 2161 | |
2159 | 2162 | switch (asi) { |
... | ... | @@ -2726,7 +2729,8 @@ void change_pstate(uint64_t new_pstate) |
2726 | 2729 | |
2727 | 2730 | void helper_wrpstate(target_ulong new_state) |
2728 | 2731 | { |
2729 | - change_pstate(new_state & 0xf3f); | |
2732 | + if (!(env->features & CPU_FEATURE_GL)) | |
2733 | + change_pstate(new_state & 0xf3f); | |
2730 | 2734 | } |
2731 | 2735 | |
2732 | 2736 | void helper_done(void) | ... | ... |
target-sparc/translate.c
... | ... | @@ -2175,6 +2175,7 @@ static void disas_sparc_insn(DisasContext * dc) |
2175 | 2175 | goto priv_insn; |
2176 | 2176 | tcg_gen_helper_1_0(helper_rdpsr, cpu_dst); |
2177 | 2177 | #else |
2178 | + CHECK_IU_FEATURE(dc, HYPV); | |
2178 | 2179 | if (!hypervisor(dc)) |
2179 | 2180 | goto priv_insn; |
2180 | 2181 | rs1 = GET_FIELD(insn, 13, 17); |
... | ... | @@ -2325,11 +2326,13 @@ static void disas_sparc_insn(DisasContext * dc) |
2325 | 2326 | tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32); |
2326 | 2327 | break; |
2327 | 2328 | case 16: // UA2005 gl |
2329 | + CHECK_IU_FEATURE(dc, GL); | |
2328 | 2330 | tcg_gen_ld_i32(cpu_tmp32, cpu_env, |
2329 | 2331 | offsetof(CPUSPARCState, gl)); |
2330 | 2332 | tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32); |
2331 | 2333 | break; |
2332 | 2334 | case 26: // UA2005 strand status |
2335 | + CHECK_IU_FEATURE(dc, HYPV); | |
2333 | 2336 | if (!hypervisor(dc)) |
2334 | 2337 | goto priv_insn; |
2335 | 2338 | tcg_gen_ld_i32(cpu_tmp32, cpu_env, |
... | ... | @@ -3431,11 +3434,13 @@ static void disas_sparc_insn(DisasContext * dc) |
3431 | 3434 | wstate)); |
3432 | 3435 | break; |
3433 | 3436 | case 16: // UA2005 gl |
3437 | + CHECK_IU_FEATURE(dc, GL); | |
3434 | 3438 | tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0); |
3435 | 3439 | tcg_gen_st_i32(cpu_tmp32, cpu_env, |
3436 | 3440 | offsetof(CPUSPARCState, gl)); |
3437 | 3441 | break; |
3438 | 3442 | case 26: // UA2005 strand status |
3443 | + CHECK_IU_FEATURE(dc, HYPV); | |
3439 | 3444 | if (!hypervisor(dc)) |
3440 | 3445 | goto priv_insn; |
3441 | 3446 | tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0); |
... | ... | @@ -3461,6 +3466,7 @@ static void disas_sparc_insn(DisasContext * dc) |
3461 | 3466 | tcg_gen_st_tl(cpu_tmp0, cpu_env, |
3462 | 3467 | offsetof(CPUSPARCState, tbr)); |
3463 | 3468 | #else |
3469 | + CHECK_IU_FEATURE(dc, HYPV); | |
3464 | 3470 | if (!hypervisor(dc)) |
3465 | 3471 | goto priv_insn; |
3466 | 3472 | tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2); | ... | ... |