Commit 5578ceab945bd2181d220ab17462c26014f29cae
1 parent
1a7de94a
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
Showing
4 changed files
with
83 additions
and
87 deletions
target-sparc/cpu.h
... | ... | @@ -187,6 +187,54 @@ typedef struct trap_state { |
187 | 187 | } trap_state; |
188 | 188 | #endif |
189 | 189 | |
190 | +typedef struct sparc_def_t { | |
191 | + const char *name; | |
192 | + target_ulong iu_version; | |
193 | + uint32_t fpu_version; | |
194 | + uint32_t mmu_version; | |
195 | + uint32_t mmu_bm; | |
196 | + uint32_t mmu_ctpr_mask; | |
197 | + uint32_t mmu_cxr_mask; | |
198 | + uint32_t mmu_sfsr_mask; | |
199 | + uint32_t mmu_trcr_mask; | |
200 | + uint32_t features; | |
201 | + uint32_t nwindows; | |
202 | + uint32_t maxtl; | |
203 | +} sparc_def_t; | |
204 | + | |
205 | +#define CPU_FEATURE_FLOAT (1 << 0) | |
206 | +#define CPU_FEATURE_FLOAT128 (1 << 1) | |
207 | +#define CPU_FEATURE_SWAP (1 << 2) | |
208 | +#define CPU_FEATURE_MUL (1 << 3) | |
209 | +#define CPU_FEATURE_DIV (1 << 4) | |
210 | +#define CPU_FEATURE_FLUSH (1 << 5) | |
211 | +#define CPU_FEATURE_FSQRT (1 << 6) | |
212 | +#define CPU_FEATURE_FMUL (1 << 7) | |
213 | +#define CPU_FEATURE_VIS1 (1 << 8) | |
214 | +#define CPU_FEATURE_VIS2 (1 << 9) | |
215 | +#define CPU_FEATURE_FSMULD (1 << 10) | |
216 | +#define CPU_FEATURE_HYPV (1 << 11) | |
217 | +#define CPU_FEATURE_CMT (1 << 12) | |
218 | +#define CPU_FEATURE_GL (1 << 13) | |
219 | +#ifndef TARGET_SPARC64 | |
220 | +#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \ | |
221 | + CPU_FEATURE_MUL | CPU_FEATURE_DIV | \ | |
222 | + CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \ | |
223 | + CPU_FEATURE_FMUL | CPU_FEATURE_FSMULD) | |
224 | +#else | |
225 | +#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \ | |
226 | + CPU_FEATURE_MUL | CPU_FEATURE_DIV | \ | |
227 | + CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \ | |
228 | + CPU_FEATURE_FMUL | CPU_FEATURE_VIS1 | \ | |
229 | + CPU_FEATURE_VIS2 | CPU_FEATURE_FSMULD) | |
230 | +enum { | |
231 | + mmu_us_12, // Ultrasparc < III (64 entry TLB) | |
232 | + mmu_us_3, // Ultrasparc III (512 entry TLB) | |
233 | + mmu_us_4, // Ultrasparc IV (several TLBs, 32 and 256MB pages) | |
234 | + mmu_sun4v, // T1, T2 | |
235 | +}; | |
236 | +#endif | |
237 | + | |
190 | 238 | typedef struct CPUSPARCState { |
191 | 239 | target_ulong gregs[8]; /* general registers */ |
192 | 240 | target_ulong *regwptr; /* pointer to current register window */ |
... | ... | @@ -217,11 +265,6 @@ typedef struct CPUSPARCState { |
217 | 265 | int psref; /* enable fpu */ |
218 | 266 | target_ulong version; |
219 | 267 | int interrupt_index; |
220 | - uint32_t mmu_bm; | |
221 | - uint32_t mmu_ctpr_mask; | |
222 | - uint32_t mmu_cxr_mask; | |
223 | - uint32_t mmu_sfsr_mask; | |
224 | - uint32_t mmu_trcr_mask; | |
225 | 268 | uint32_t nwindows; |
226 | 269 | /* NOTE: we allow 8 more registers to handle wrapping */ |
227 | 270 | target_ulong regbase[MAX_NWINDOWS * 16 + 8]; |
... | ... | @@ -275,42 +318,9 @@ typedef struct CPUSPARCState { |
275 | 318 | uint64_t hpstate, htstate[MAXTL_MAX], hintp, htba, hver, hstick_cmpr, ssr; |
276 | 319 | void *hstick; // UA 2005 |
277 | 320 | #endif |
278 | - uint32_t features; | |
321 | + sparc_def_t *def; | |
279 | 322 | } CPUSPARCState; |
280 | 323 | |
281 | -#define CPU_FEATURE_FLOAT (1 << 0) | |
282 | -#define CPU_FEATURE_FLOAT128 (1 << 1) | |
283 | -#define CPU_FEATURE_SWAP (1 << 2) | |
284 | -#define CPU_FEATURE_MUL (1 << 3) | |
285 | -#define CPU_FEATURE_DIV (1 << 4) | |
286 | -#define CPU_FEATURE_FLUSH (1 << 5) | |
287 | -#define CPU_FEATURE_FSQRT (1 << 6) | |
288 | -#define CPU_FEATURE_FMUL (1 << 7) | |
289 | -#define CPU_FEATURE_VIS1 (1 << 8) | |
290 | -#define CPU_FEATURE_VIS2 (1 << 9) | |
291 | -#define CPU_FEATURE_FSMULD (1 << 10) | |
292 | -#define CPU_FEATURE_HYPV (1 << 11) | |
293 | -#define CPU_FEATURE_CMT (1 << 12) | |
294 | -#define CPU_FEATURE_GL (1 << 13) | |
295 | -#ifndef TARGET_SPARC64 | |
296 | -#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \ | |
297 | - CPU_FEATURE_MUL | CPU_FEATURE_DIV | \ | |
298 | - CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \ | |
299 | - CPU_FEATURE_FMUL | CPU_FEATURE_FSMULD) | |
300 | -#else | |
301 | -#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \ | |
302 | - CPU_FEATURE_MUL | CPU_FEATURE_DIV | \ | |
303 | - CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \ | |
304 | - CPU_FEATURE_FMUL | CPU_FEATURE_VIS1 | \ | |
305 | - CPU_FEATURE_VIS2 | CPU_FEATURE_FSMULD) | |
306 | -enum { | |
307 | - mmu_us_12, // Ultrasparc < III (64 entry TLB) | |
308 | - mmu_us_3, // Ultrasparc III (512 entry TLB) | |
309 | - mmu_us_4, // Ultrasparc IV (several TLBs, 32 and 256MB pages) | |
310 | - mmu_sun4v, // T1, T2 | |
311 | -}; | |
312 | -#endif | |
313 | - | |
314 | 324 | #if defined(TARGET_SPARC64) |
315 | 325 | #define GET_FSR32(env) (env->fsr & 0xcfc1ffff) |
316 | 326 | #define PUT_FSR32(env, val) do { uint32_t _tmp = val; \ | ... | ... |
target-sparc/helper.c
... | ... | @@ -34,23 +34,6 @@ |
34 | 34 | //#define DEBUG_FEATURES |
35 | 35 | //#define DEBUG_PCALL |
36 | 36 | |
37 | -typedef struct sparc_def_t sparc_def_t; | |
38 | - | |
39 | -struct sparc_def_t { | |
40 | - const char *name; | |
41 | - target_ulong iu_version; | |
42 | - uint32_t fpu_version; | |
43 | - uint32_t mmu_version; | |
44 | - uint32_t mmu_bm; | |
45 | - uint32_t mmu_ctpr_mask; | |
46 | - uint32_t mmu_cxr_mask; | |
47 | - uint32_t mmu_sfsr_mask; | |
48 | - uint32_t mmu_trcr_mask; | |
49 | - uint32_t features; | |
50 | - uint32_t nwindows; | |
51 | - uint32_t maxtl; | |
52 | -}; | |
53 | - | |
54 | 37 | static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model); |
55 | 38 | |
56 | 39 | /* Sparc MMU emulation */ |
... | ... | @@ -137,7 +120,7 @@ static int get_physical_address(CPUState *env, target_phys_addr_t *physical, |
137 | 120 | |
138 | 121 | if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */ |
139 | 122 | // Boot mode: instruction fetches are taken from PROM |
140 | - if (rw == 2 && (env->mmuregs[0] & env->mmu_bm)) { | |
123 | + if (rw == 2 && (env->mmuregs[0] & env->def->mmu_bm)) { | |
141 | 124 | *physical = env->prom_addr | (address & 0x7ffffULL); |
142 | 125 | *prot = PAGE_READ | PAGE_EXEC; |
143 | 126 | return 0; |
... | ... | @@ -759,7 +742,7 @@ void do_interrupt(CPUState *env) |
759 | 742 | env->tsptr->tpc = env->pc; |
760 | 743 | env->tsptr->tnpc = env->npc; |
761 | 744 | env->tsptr->tt = intno; |
762 | - if (!(env->features & CPU_FEATURE_GL)) { | |
745 | + if (!(env->def->features & CPU_FEATURE_GL)) { | |
763 | 746 | switch (intno) { |
764 | 747 | case TT_IVEC: |
765 | 748 | change_pstate(PS_PEF | PS_PRIV | PS_IG); |
... | ... | @@ -923,7 +906,7 @@ void cpu_reset(CPUSPARCState *env) |
923 | 906 | #else |
924 | 907 | env->pc = 0; |
925 | 908 | env->mmuregs[0] &= ~(MMU_E | MMU_NF); |
926 | - env->mmuregs[0] |= env->mmu_bm; | |
909 | + env->mmuregs[0] |= env->def->mmu_bm; | |
927 | 910 | #endif |
928 | 911 | env->npc = env->pc + 4; |
929 | 912 | #endif |
... | ... | @@ -936,17 +919,17 @@ static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model) |
936 | 919 | if (cpu_sparc_find_by_name(def, cpu_model) < 0) |
937 | 920 | return -1; |
938 | 921 | |
939 | - env->features = def->features; | |
922 | + env->def = qemu_mallocz(sizeof(*def)); | |
923 | + memcpy(env->def, def, sizeof(*def)); | |
924 | +#if defined(CONFIG_USER_ONLY) | |
925 | + if ((env->def->features & CPU_FEATURE_FLOAT)) | |
926 | + env->def->features |= CPU_FEATURE_FLOAT128; | |
927 | +#endif | |
940 | 928 | env->cpu_model_str = cpu_model; |
941 | 929 | env->version = def->iu_version; |
942 | 930 | env->fsr = def->fpu_version; |
943 | 931 | env->nwindows = def->nwindows; |
944 | 932 | #if !defined(TARGET_SPARC64) |
945 | - env->mmu_bm = def->mmu_bm; | |
946 | - env->mmu_ctpr_mask = def->mmu_ctpr_mask; | |
947 | - env->mmu_cxr_mask = def->mmu_cxr_mask; | |
948 | - env->mmu_sfsr_mask = def->mmu_sfsr_mask; | |
949 | - env->mmu_trcr_mask = def->mmu_trcr_mask; | |
950 | 933 | env->mmuregs[0] |= def->mmu_version; |
951 | 934 | cpu_sparc_set_id(env, 0); |
952 | 935 | #else |
... | ... | @@ -960,6 +943,7 @@ static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model) |
960 | 943 | |
961 | 944 | static void cpu_sparc_close(CPUSPARCState *env) |
962 | 945 | { |
946 | + free(env->def); | |
963 | 947 | free(env); |
964 | 948 | } |
965 | 949 | ... | ... |
target-sparc/op_helper.c
... | ... | @@ -1203,15 +1203,15 @@ void helper_st_asi(target_ulong addr, uint64_t val, int asi, int size) |
1203 | 1203 | (val & 0x00ffffff); |
1204 | 1204 | // Mappings generated during no-fault mode or MMU |
1205 | 1205 | // disabled mode are invalid in normal mode |
1206 | - if ((oldreg & (MMU_E | MMU_NF | env->mmu_bm)) != | |
1207 | - (env->mmuregs[reg] & (MMU_E | MMU_NF | env->mmu_bm))) | |
1206 | + if ((oldreg & (MMU_E | MMU_NF | env->def->mmu_bm)) != | |
1207 | + (env->mmuregs[reg] & (MMU_E | MMU_NF | env->def->mmu_bm))) | |
1208 | 1208 | tlb_flush(env, 1); |
1209 | 1209 | break; |
1210 | 1210 | case 1: // Context Table Pointer Register |
1211 | - env->mmuregs[reg] = val & env->mmu_ctpr_mask; | |
1211 | + env->mmuregs[reg] = val & env->def->mmu_ctpr_mask; | |
1212 | 1212 | break; |
1213 | 1213 | case 2: // Context Register |
1214 | - env->mmuregs[reg] = val & env->mmu_cxr_mask; | |
1214 | + env->mmuregs[reg] = val & env->def->mmu_cxr_mask; | |
1215 | 1215 | if (oldreg != env->mmuregs[reg]) { |
1216 | 1216 | /* we flush when the MMU context changes because |
1217 | 1217 | QEMU has no MMU context support */ |
... | ... | @@ -1222,10 +1222,10 @@ void helper_st_asi(target_ulong addr, uint64_t val, int asi, int size) |
1222 | 1222 | case 4: // Synchronous Fault Address Register |
1223 | 1223 | break; |
1224 | 1224 | case 0x10: // TLB Replacement Control Register |
1225 | - env->mmuregs[reg] = val & env->mmu_trcr_mask; | |
1225 | + env->mmuregs[reg] = val & env->def->mmu_trcr_mask; | |
1226 | 1226 | break; |
1227 | 1227 | case 0x13: // Synchronous Fault Status Register with Read and Clear |
1228 | - env->mmuregs[3] = val & env->mmu_sfsr_mask; | |
1228 | + env->mmuregs[3] = val & env->def->mmu_sfsr_mask; | |
1229 | 1229 | break; |
1230 | 1230 | case 0x14: // Synchronous Fault Address Register |
1231 | 1231 | env->mmuregs[4] = val; |
... | ... | @@ -1552,7 +1552,8 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) |
1552 | 1552 | #endif |
1553 | 1553 | |
1554 | 1554 | if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0) |
1555 | - || ((env->features & CPU_FEATURE_HYPV) && asi >= 0x30 && asi < 0x80 | |
1555 | + || ((env->def->features & CPU_FEATURE_HYPV) | |
1556 | + && asi >= 0x30 && asi < 0x80 | |
1556 | 1557 | && !(env->hpstate & HS_PRIV))) |
1557 | 1558 | raise_exception(TT_PRIV_ACT); |
1558 | 1559 | |
... | ... | @@ -1565,7 +1566,8 @@ uint64_t helper_ld_asi(target_ulong addr, int asi, int size, int sign) |
1565 | 1566 | case 0x88: // Primary LE |
1566 | 1567 | case 0x8a: // Primary no-fault LE |
1567 | 1568 | if ((asi & 0x80) && (env->pstate & PS_PRIV)) { |
1568 | - if ((env->features & CPU_FEATURE_HYPV) && env->hpstate & HS_PRIV) { | |
1569 | + if ((env->def->features & CPU_FEATURE_HYPV) | |
1570 | + && env->hpstate & HS_PRIV) { | |
1569 | 1571 | switch(size) { |
1570 | 1572 | case 1: |
1571 | 1573 | ret = ldub_hypv(addr); |
... | ... | @@ -1791,7 +1793,8 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size) |
1791 | 1793 | dump_asi("write", addr, asi, size, val); |
1792 | 1794 | #endif |
1793 | 1795 | if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0) |
1794 | - || ((env->features & CPU_FEATURE_HYPV) && asi >= 0x30 && asi < 0x80 | |
1796 | + || ((env->def->features & CPU_FEATURE_HYPV) | |
1797 | + && asi >= 0x30 && asi < 0x80 | |
1795 | 1798 | && !(env->hpstate & HS_PRIV))) |
1796 | 1799 | raise_exception(TT_PRIV_ACT); |
1797 | 1800 | |
... | ... | @@ -1828,7 +1831,8 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size) |
1828 | 1831 | case 0x80: // Primary |
1829 | 1832 | case 0x88: // Primary LE |
1830 | 1833 | if ((asi & 0x80) && (env->pstate & PS_PRIV)) { |
1831 | - if ((env->features & CPU_FEATURE_HYPV) && env->hpstate & HS_PRIV) { | |
1834 | + if ((env->def->features & CPU_FEATURE_HYPV) | |
1835 | + && env->hpstate & HS_PRIV) { | |
1832 | 1836 | switch(size) { |
1833 | 1837 | case 1: |
1834 | 1838 | stb_hypv(addr, val); |
... | ... | @@ -2108,7 +2112,8 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size) |
2108 | 2112 | void helper_ldda_asi(target_ulong addr, int asi, int rd) |
2109 | 2113 | { |
2110 | 2114 | if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0) |
2111 | - || ((env->features & CPU_FEATURE_HYPV) && asi >= 0x30 && asi < 0x80 | |
2115 | + || ((env->def->features & CPU_FEATURE_HYPV) | |
2116 | + && asi >= 0x30 && asi < 0x80 | |
2112 | 2117 | && !(env->hpstate & HS_PRIV))) |
2113 | 2118 | raise_exception(TT_PRIV_ACT); |
2114 | 2119 | |
... | ... | @@ -2682,7 +2687,7 @@ void change_pstate(uint64_t new_pstate) |
2682 | 2687 | |
2683 | 2688 | void helper_wrpstate(target_ulong new_state) |
2684 | 2689 | { |
2685 | - if (!(env->features & CPU_FEATURE_GL)) | |
2690 | + if (!(env->def->features & CPU_FEATURE_GL)) | |
2686 | 2691 | change_pstate(new_state & 0xf3f); |
2687 | 2692 | } |
2688 | 2693 | ... | ... |
target-sparc/translate.c
... | ... | @@ -59,7 +59,7 @@ typedef struct DisasContext { |
59 | 59 | int fpu_enabled; |
60 | 60 | int address_mask_32bit; |
61 | 61 | struct TranslationBlock *tb; |
62 | - uint32_t features; | |
62 | + sparc_def_t *def; | |
63 | 63 | } DisasContext; |
64 | 64 | |
65 | 65 | // This function uses non-native bit order |
... | ... | @@ -1905,10 +1905,10 @@ static inline TCGv get_src2(unsigned int insn, TCGv def) |
1905 | 1905 | } |
1906 | 1906 | |
1907 | 1907 | #define CHECK_IU_FEATURE(dc, FEATURE) \ |
1908 | - if (!((dc)->features & CPU_FEATURE_ ## FEATURE)) \ | |
1908 | + if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \ | |
1909 | 1909 | goto illegal_insn; |
1910 | 1910 | #define CHECK_FPU_FEATURE(dc, FEATURE) \ |
1911 | - if (!((dc)->features & CPU_FEATURE_ ## FEATURE)) \ | |
1911 | + if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \ | |
1912 | 1912 | goto nfpu_insn; |
1913 | 1913 | |
1914 | 1914 | /* before an instruction, dc->pc must be static */ |
... | ... | @@ -4141,7 +4141,7 @@ static void disas_sparc_insn(DisasContext * dc) |
4141 | 4141 | goto jmp_insn; |
4142 | 4142 | #endif |
4143 | 4143 | case 0x3b: /* flush */ |
4144 | - if (!((dc)->features & CPU_FEATURE_FLUSH)) | |
4144 | + if (!((dc)->def->features & CPU_FEATURE_FLUSH)) | |
4145 | 4145 | goto unimp_flush; |
4146 | 4146 | tcg_gen_helper_0_1(helper_flush, cpu_dst); |
4147 | 4147 | break; |
... | ... | @@ -4742,13 +4742,10 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb, |
4742 | 4742 | last_pc = dc->pc; |
4743 | 4743 | dc->npc = (target_ulong) tb->cs_base; |
4744 | 4744 | dc->mem_idx = cpu_mmu_index(env); |
4745 | - dc->features = env->features; | |
4746 | - if ((dc->features & CPU_FEATURE_FLOAT)) { | |
4745 | + dc->def = env->def; | |
4746 | + if ((dc->def->features & CPU_FEATURE_FLOAT)) | |
4747 | 4747 | dc->fpu_enabled = cpu_fpu_enabled(env); |
4748 | -#if defined(CONFIG_USER_ONLY) | |
4749 | - dc->features |= CPU_FEATURE_FLOAT128; | |
4750 | -#endif | |
4751 | - } else | |
4748 | + else | |
4752 | 4749 | dc->fpu_enabled = 0; |
4753 | 4750 | #ifdef TARGET_SPARC64 |
4754 | 4751 | dc->address_mask_32bit = env->pstate & PS_AM; | ... | ... |