Commit 43057ab1272ba2b9b052b19a3453fb0f3b510149

Authored by bellard
1 parent c5d6edc3

use constants for TLB handling (Thiemo Seufer)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1978 c046a42c-6fe2-441c-8c8c-71466251a162
target-mips/cpu.h
... ... @@ -87,7 +87,7 @@ struct CPUMIPSState {
87 87  
88 88 #endif
89 89 #if defined(MIPS_USES_R4K_TLB)
90   - tlb_t tlb[16];
  90 + tlb_t tlb[MIPS_TLB_NB];
91 91 #endif
92 92 uint32_t CP0_index;
93 93 uint32_t CP0_random;
... ...
target-mips/helper.c
... ... @@ -28,53 +28,56 @@
28 28 #include "cpu.h"
29 29 #include "exec-all.h"
30 30  
  31 +enum {
  32 + TLBRET_DIRTY = -4,
  33 + TLBRET_INVALID = -3,
  34 + TLBRET_NOMATCH = -2,
  35 + TLBRET_BADADDR = -1,
  36 + TLBRET_MATCH = 0
  37 +};
  38 +
31 39 /* MIPS32 4K MMU emulation */
32 40 #ifdef MIPS_USES_R4K_TLB
33 41 static int map_address (CPUState *env, target_ulong *physical, int *prot,
34 42 target_ulong address, int rw, int access_type)
35 43 {
  44 + target_ulong tag = address & (TARGET_PAGE_MASK << 1);
  45 + uint8_t ASID = env->CP0_EntryHi & 0xFF;
36 46 tlb_t *tlb;
37   - target_ulong tag;
38   - uint8_t ASID;
39 47 int i, n;
40   - int ret;
41 48  
42   - ret = -2;
43   - tag = address & 0xFFFFE000;
44   - ASID = env->CP0_EntryHi & 0xFF;
45 49 for (i = 0; i < MIPS_TLB_NB; i++) {
46 50 tlb = &env->tlb[i];
47 51 /* Check ASID, virtual page number & size */
48 52 if ((tlb->G == 1 || tlb->ASID == ASID) &&
49 53 tlb->VPN == tag && address < tlb->end2) {
50 54 /* TLB match */
51   - n = (address >> 12) & 1;
  55 + n = (address >> TARGET_PAGE_BITS) & 1;
52 56 /* Check access rights */
53   - if (!(n ? tlb->V1 : tlb->V0))
54   - return -3;
55   - if (rw == 0 || (n ? tlb->D1 : tlb->D0)) {
56   - *physical = tlb->PFN[n] | (address & 0xFFF);
  57 + if (!(n ? tlb->V1 : tlb->V0))
  58 + return TLBRET_INVALID;
  59 + if (rw == 0 || (n ? tlb->D1 : tlb->D0)) {
  60 + *physical = tlb->PFN[n] | (address & ~TARGET_PAGE_MASK);
57 61 *prot = PAGE_READ;
58 62 if (n ? tlb->D1 : tlb->D0)
59 63 *prot |= PAGE_WRITE;
60   - return 0;
  64 + return TLBRET_MATCH;
61 65 }
62   - return -4;
  66 + return TLBRET_DIRTY;
63 67 }
64 68 }
65   -
66   - return ret;
  69 + return TLBRET_NOMATCH;
67 70 }
68 71 #endif
69 72  
70   -int get_physical_address (CPUState *env, target_ulong *physical, int *prot,
71   - target_ulong address, int rw, int access_type)
  73 +static int get_physical_address (CPUState *env, target_ulong *physical,
  74 + int *prot, target_ulong address,
  75 + int rw, int access_type)
72 76 {
73   - int user_mode;
74   - int ret;
75   -
76 77 /* User mode can only access useg */
77   - user_mode = (env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM;
  78 + int user_mode = (env->hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM;
  79 + int ret = TLBRET_MATCH;
  80 +
78 81 #if 0
79 82 if (logfile) {
80 83 fprintf(logfile, "user mode %d h %08x\n",
... ... @@ -82,8 +85,7 @@ int get_physical_address (CPUState *env, target_ulong *physical, int *prot,
82 85 }
83 86 #endif
84 87 if (user_mode && address > 0x7FFFFFFFUL)
85   - return -1;
86   - ret = 0;
  88 + return TLBRET_BADADDR;
87 89 if (address < 0x80000000UL) {
88 90 if (!(env->hflags & MIPS_HFLAG_ERL)) {
89 91 #ifdef MIPS_USES_R4K_TLB
... ... @@ -181,7 +183,7 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
181 183 access_type = ACCESS_INT;
182 184 if (env->user_mode_only) {
183 185 /* user mode only emulation */
184   - ret = -2;
  186 + ret = TLBRET_NOMATCH;
185 187 goto do_fault;
186 188 }
187 189 ret = get_physical_address(env, &physical, &prot,
... ... @@ -190,14 +192,15 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
190 192 fprintf(logfile, "%s address=%08x ret %d physical %08x prot %d\n",
191 193 __func__, address, ret, physical, prot);
192 194 }
193   - if (ret == 0) {
194   - ret = tlb_set_page(env, address & ~0xFFF, physical & ~0xFFF, prot,
195   - is_user, is_softmmu);
  195 + if (ret == TLBRET_MATCH) {
  196 + ret = tlb_set_page(env, address & TARGET_PAGE_MASK,
  197 + physical & TARGET_PAGE_MASK, prot,
  198 + is_user, is_softmmu);
196 199 } else if (ret < 0) {
197 200 do_fault:
198 201 switch (ret) {
199 202 default:
200   - case -1:
  203 + case TLBRET_BADADDR:
201 204 /* Reference to kernel address from user mode or supervisor mode */
202 205 /* Reference to supervisor address from user mode */
203 206 if (rw)
... ... @@ -205,7 +208,7 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
205 208 else
206 209 exception = EXCP_AdEL;
207 210 break;
208   - case -2:
  211 + case TLBRET_NOMATCH:
209 212 /* No TLB match for a mapped address */
210 213 if (rw)
211 214 exception = EXCP_TLBS;
... ... @@ -213,14 +216,14 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
213 216 exception = EXCP_TLBL;
214 217 error_code = 1;
215 218 break;
216   - case -3:
  219 + case TLBRET_INVALID:
217 220 /* TLB match with no valid bit */
218 221 if (rw)
219 222 exception = EXCP_TLBS;
220 223 else
221 224 exception = EXCP_TLBL;
222 225 break;
223   - case -4:
  226 + case TLBRET_DIRTY:
224 227 /* TLB match but 'D' bit is cleared */
225 228 exception = EXCP_LTLBL;
226 229 break;
... ... @@ -231,7 +234,7 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
231 234 env->CP0_Context = (env->CP0_Context & 0xff800000) |
232 235 ((address >> 9) & 0x007ffff0);
233 236 env->CP0_EntryHi =
234   - (env->CP0_EntryHi & 0xFF) | (address & 0xFFFFE000);
  237 + (env->CP0_EntryHi & 0xFF) | (address & (TARGET_PAGE_MASK << 1));
235 238 env->exception_index = exception;
236 239 env->error_code = error_code;
237 240 ret = 1;
... ...