Revision 7483750d target-sparc/helper.c
b/target-sparc/helper.c | ||
---|---|---|
137 | 137 |
return 0; |
138 | 138 |
} |
139 | 139 |
|
140 |
*access_index = ((rw & 1) << 2) | (rw & 2) | (is_user? 0 : 1); |
|
141 |
|
|
140 | 142 |
/* SPARC reference MMU table walk: Context table->L1->L2->PTE */ |
141 | 143 |
/* Context base + context number */ |
142 | 144 |
pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 4); |
... | ... | |
146 | 148 |
switch (pde & PTE_ENTRYTYPE_MASK) { |
147 | 149 |
default: |
148 | 150 |
case 0: /* Invalid */ |
149 |
return 1; |
|
151 |
return 1 << 2;
|
|
150 | 152 |
case 2: /* L0 PTE, maybe should not happen? */ |
151 | 153 |
case 3: /* Reserved */ |
152 |
return 4; |
|
154 |
return 4 << 2;
|
|
153 | 155 |
case 1: /* L0 PDE */ |
154 | 156 |
pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4); |
155 | 157 |
pde = ldl_phys(pde_ptr); |
... | ... | |
157 | 159 |
switch (pde & PTE_ENTRYTYPE_MASK) { |
158 | 160 |
default: |
159 | 161 |
case 0: /* Invalid */ |
160 |
return 1;
|
|
162 |
return (1 << 8) | (1 << 2);
|
|
161 | 163 |
case 3: /* Reserved */ |
162 |
return 4;
|
|
164 |
return (1 << 8) | (4 << 2);
|
|
163 | 165 |
case 1: /* L1 PDE */ |
164 | 166 |
pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4); |
165 | 167 |
pde = ldl_phys(pde_ptr); |
... | ... | |
167 | 169 |
switch (pde & PTE_ENTRYTYPE_MASK) { |
168 | 170 |
default: |
169 | 171 |
case 0: /* Invalid */ |
170 |
return 1;
|
|
172 |
return (2 << 8) | (1 << 2);
|
|
171 | 173 |
case 3: /* Reserved */ |
172 |
return 4;
|
|
174 |
return (2 << 8) | (4 << 2);
|
|
173 | 175 |
case 1: /* L2 PDE */ |
174 | 176 |
pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4); |
175 | 177 |
pde = ldl_phys(pde_ptr); |
... | ... | |
177 | 179 |
switch (pde & PTE_ENTRYTYPE_MASK) { |
178 | 180 |
default: |
179 | 181 |
case 0: /* Invalid */ |
180 |
return 1;
|
|
182 |
return (3 << 8) | (1 << 2);
|
|
181 | 183 |
case 1: /* PDE, should not happen */ |
182 | 184 |
case 3: /* Reserved */ |
183 |
return 4;
|
|
185 |
return (3 << 8) | (4 << 2);
|
|
184 | 186 |
case 2: /* L3 PTE */ |
185 | 187 |
virt_addr = address & TARGET_PAGE_MASK; |
186 | 188 |
page_offset = (address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1); |
... | ... | |
206 | 208 |
stl_phys_notdirty(pde_ptr, pde); |
207 | 209 |
} |
208 | 210 |
/* check access */ |
209 |
*access_index = ((rw & 1) << 2) | (rw & 2) | (is_user? 0 : 1); |
|
210 | 211 |
access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT; |
211 | 212 |
error_code = access_table[*access_index][access_perms]; |
212 | 213 |
if (error_code) |
... | ... | |
246 | 247 |
|
247 | 248 |
if (env->mmuregs[3]) /* Fault status register */ |
248 | 249 |
env->mmuregs[3] = 1; /* overflow (not read before another fault) */ |
249 |
env->mmuregs[3] |= (access_index << 5) | (error_code << 2) | 2;
|
|
250 |
env->mmuregs[3] |= (access_index << 5) | error_code | 2;
|
|
250 | 251 |
env->mmuregs[4] = address; /* Fault address register */ |
251 | 252 |
|
252 | 253 |
if ((env->mmuregs[0] & MMU_NF) || env->psret == 0) { |
254 |
#if 0 |
|
253 | 255 |
// No fault |
254 |
cpu_abort(env, "Unsupported MMU no fault case"); |
|
256 |
vaddr = address & TARGET_PAGE_MASK; |
|
257 |
paddr = 0xfffff000; |
|
258 |
prot = PAGE_READ | PAGE_WRITE; |
|
259 |
ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu); |
|
260 |
return ret; |
|
261 |
#else |
|
262 |
cpu_abort(env, "MMU no fault case no handled"); |
|
263 |
return 0; |
|
264 |
#endif |
|
265 |
} else { |
|
266 |
if (rw & 2) |
|
267 |
env->exception_index = TT_TFAULT; |
|
268 |
else |
|
269 |
env->exception_index = TT_DFAULT; |
|
270 |
return 1; |
|
255 | 271 |
} |
256 |
if (rw & 2) |
|
257 |
env->exception_index = TT_TFAULT; |
|
258 |
else |
|
259 |
env->exception_index = TT_DFAULT; |
|
260 |
return 1; |
|
261 | 272 |
} |
262 | 273 |
#endif |
263 | 274 |
|
Also available in: Unified diff