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); | ... | ... |