Revision 24c7b0e3 target-mips/helper.c
b/target-mips/helper.c | ||
---|---|---|
90 | 90 |
if (user_mode && address > 0x7FFFFFFFUL) |
91 | 91 |
return TLBRET_BADADDR; |
92 | 92 |
if (address < (int32_t)0x80000000UL) { |
93 |
if (!(env->hflags & MIPS_HFLAG_ERL)) {
|
|
93 |
if (!(env->CP0_Status & (1 << CP0St_ERL))) {
|
|
94 | 94 |
#ifdef MIPS_USES_R4K_TLB |
95 | 95 |
ret = map_address(env, physical, prot, address, rw, access_type); |
96 | 96 |
#else |
... | ... | |
289 | 289 |
goto set_DEPC; |
290 | 290 |
case EXCP_DDBL: |
291 | 291 |
env->CP0_Debug |= 1 << CP0DB_DDBL; |
292 |
goto set_DEPC; |
|
293 | 292 |
set_DEPC: |
294 | 293 |
if (env->hflags & MIPS_HFLAG_BMASK) { |
295 | 294 |
/* If the exception was raised from a delay slot, |
296 | 295 |
come back to the jump. */ |
297 | 296 |
env->CP0_DEPC = env->PC - 4; |
298 |
if (!(env->hflags & MIPS_HFLAG_EXL)) |
|
299 |
env->CP0_Cause |= (1 << CP0Ca_BD); |
|
300 | 297 |
env->hflags &= ~MIPS_HFLAG_BMASK; |
301 | 298 |
} else { |
302 | 299 |
env->CP0_DEPC = env->PC; |
303 |
env->CP0_Cause &= ~(1 << CP0Ca_BD); |
|
304 | 300 |
} |
305 | 301 |
enter_debug_mode: |
306 | 302 |
env->hflags |= MIPS_HFLAG_DM; |
303 |
env->hflags &= ~MIPS_HFLAG_UM; |
|
307 | 304 |
/* EJTAG probe trap enable is not implemented... */ |
308 | 305 |
env->PC = (int32_t)0xBFC00480; |
309 | 306 |
break; |
... | ... | |
311 | 308 |
cpu_reset(env); |
312 | 309 |
break; |
313 | 310 |
case EXCP_SRESET: |
314 |
env->CP0_Status = (1 << CP0St_SR); |
|
311 |
env->CP0_Status |= (1 << CP0St_SR);
|
|
315 | 312 |
env->CP0_WatchLo = 0; |
316 | 313 |
goto set_error_EPC; |
317 | 314 |
case EXCP_NMI: |
318 |
env->CP0_Status = (1 << CP0St_NMI); |
|
315 |
env->CP0_Status |= (1 << CP0St_NMI);
|
|
319 | 316 |
set_error_EPC: |
320 | 317 |
if (env->hflags & MIPS_HFLAG_BMASK) { |
321 | 318 |
/* If the exception was raised from a delay slot, |
322 | 319 |
come back to the jump. */ |
323 | 320 |
env->CP0_ErrorEPC = env->PC - 4; |
324 |
if (!(env->hflags & MIPS_HFLAG_EXL)) |
|
325 |
env->CP0_Cause |= (1 << CP0Ca_BD); |
|
326 | 321 |
env->hflags &= ~MIPS_HFLAG_BMASK; |
327 | 322 |
} else { |
328 | 323 |
env->CP0_ErrorEPC = env->PC; |
329 |
env->CP0_Cause &= ~(1 << CP0Ca_BD); |
|
330 | 324 |
} |
331 |
env->hflags |= MIPS_HFLAG_ERL;
|
|
332 |
env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV);
|
|
325 |
env->CP0_Status |= (1 << CP0St_ERL) | (1 << CP0St_BEV);
|
|
326 |
env->hflags &= ~MIPS_HFLAG_UM;
|
|
333 | 327 |
env->PC = (int32_t)0xBFC00000; |
334 | 328 |
break; |
335 | 329 |
case EXCP_MCHECK: |
... | ... | |
350 | 344 |
goto set_EPC; |
351 | 345 |
case EXCP_TLBL: |
352 | 346 |
cause = 2; |
353 |
if (env->error_code == 1 && !(env->hflags & MIPS_HFLAG_EXL))
|
|
347 |
if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL)))
|
|
354 | 348 |
offset = 0x000; |
355 | 349 |
goto set_EPC; |
356 | 350 |
case EXCP_IBE: |
... | ... | |
384 | 378 |
goto set_EPC; |
385 | 379 |
case EXCP_TLBS: |
386 | 380 |
cause = 3; |
387 |
if (env->error_code == 1 && !(env->hflags & MIPS_HFLAG_EXL))
|
|
381 |
if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL)))
|
|
388 | 382 |
offset = 0x000; |
389 |
goto set_EPC; |
|
390 | 383 |
set_EPC: |
391 |
if (env->hflags & MIPS_HFLAG_BMASK) {
|
|
392 |
/* If the exception was raised from a delay slot,
|
|
393 |
come back to the jump. */
|
|
394 |
env->CP0_EPC = env->PC - 4;
|
|
395 |
if (!(env->hflags & MIPS_HFLAG_EXL))
|
|
384 |
if (!(env->CP0_Status & (1 << CP0St_EXL))) {
|
|
385 |
if (env->hflags & MIPS_HFLAG_BMASK) {
|
|
386 |
/* If the exception was raised from a delay slot,
|
|
387 |
come back to the jump. */
|
|
388 |
env->CP0_EPC = env->PC - 4;
|
|
396 | 389 |
env->CP0_Cause |= (1 << CP0Ca_BD); |
397 |
env->hflags &= ~MIPS_HFLAG_BMASK; |
|
390 |
env->hflags &= ~MIPS_HFLAG_BMASK; |
|
391 |
} else { |
|
392 |
env->CP0_EPC = env->PC; |
|
393 |
env->CP0_Cause &= ~(1 << CP0Ca_BD); |
|
394 |
} |
|
398 | 395 |
} else { |
399 |
env->CP0_EPC = env->PC;
|
|
400 |
env->CP0_Cause &= ~(1 << CP0Ca_BD);
|
|
396 |
env->CP0_Status |= (1 << CP0St_EXL);
|
|
397 |
env->hflags &= ~MIPS_HFLAG_UM;
|
|
401 | 398 |
} |
402 | 399 |
if (env->CP0_Status & (1 << CP0St_BEV)) { |
403 | 400 |
env->PC = (int32_t)0xBFC00200; |
404 | 401 |
} else { |
405 | 402 |
env->PC = (int32_t)0x80000000; |
406 | 403 |
} |
407 |
env->hflags |= MIPS_HFLAG_EXL; |
|
408 |
env->CP0_Status |= (1 << CP0St_EXL); |
|
409 | 404 |
env->PC += offset; |
410 | 405 |
env->CP0_Cause = (env->CP0_Cause & ~0x7C) | (cause << 2); |
411 | 406 |
break; |
Also available in: Unified diff