Commit b67bfe8d9f7251c485cf0ffad514486f8db39509
1 parent
9a5d878f
Handle some more exception types.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3886 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
43 additions
and
29 deletions
target-mips/helper.c
| ... | ... | @@ -442,23 +442,13 @@ void do_interrupt (CPUState *env) |
| 442 | 442 | env->CP0_Cause &= ~(1 << CP0Ca_BD); |
| 443 | 443 | env->PC[env->current_tc] = (int32_t)0xBFC00000; |
| 444 | 444 | break; |
| 445 | - case EXCP_MCHECK: | |
| 446 | - cause = 24; | |
| 447 | - goto set_EPC; | |
| 448 | 445 | case EXCP_EXT_INTERRUPT: |
| 449 | 446 | cause = 0; |
| 450 | 447 | if (env->CP0_Cause & (1 << CP0Ca_IV)) |
| 451 | 448 | offset = 0x200; |
| 452 | 449 | goto set_EPC; |
| 453 | - case EXCP_DWATCH: | |
| 454 | - cause = 23; | |
| 455 | - /* XXX: TODO: manage defered watch exceptions */ | |
| 456 | - goto set_EPC; | |
| 457 | - case EXCP_AdEL: | |
| 458 | - cause = 4; | |
| 459 | - goto set_EPC; | |
| 460 | - case EXCP_AdES: | |
| 461 | - cause = 5; | |
| 450 | + case EXCP_LTLBL: | |
| 451 | + cause = 1; | |
| 462 | 452 | goto set_EPC; |
| 463 | 453 | case EXCP_TLBL: |
| 464 | 454 | cause = 2; |
| ... | ... | @@ -476,6 +466,28 @@ void do_interrupt (CPUState *env) |
| 476 | 466 | offset = 0x000; |
| 477 | 467 | } |
| 478 | 468 | goto set_EPC; |
| 469 | + case EXCP_TLBS: | |
| 470 | + cause = 3; | |
| 471 | + if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) { | |
| 472 | +#if defined(TARGET_MIPS64) | |
| 473 | + int R = env->CP0_BadVAddr >> 62; | |
| 474 | + int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0; | |
| 475 | + int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0; | |
| 476 | + int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0; | |
| 477 | + | |
| 478 | + if ((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX)) | |
| 479 | + offset = 0x080; | |
| 480 | + else | |
| 481 | +#endif | |
| 482 | + offset = 0x000; | |
| 483 | + } | |
| 484 | + goto set_EPC; | |
| 485 | + case EXCP_AdEL: | |
| 486 | + cause = 4; | |
| 487 | + goto set_EPC; | |
| 488 | + case EXCP_AdES: | |
| 489 | + cause = 5; | |
| 490 | + goto set_EPC; | |
| 479 | 491 | case EXCP_IBE: |
| 480 | 492 | cause = 6; |
| 481 | 493 | goto set_EPC; |
| ... | ... | @@ -505,27 +517,29 @@ void do_interrupt (CPUState *env) |
| 505 | 517 | case EXCP_FPE: |
| 506 | 518 | cause = 15; |
| 507 | 519 | goto set_EPC; |
| 508 | - case EXCP_LTLBL: | |
| 509 | - cause = 1; | |
| 520 | + case EXCP_C2E: | |
| 521 | + cause = 18; | |
| 510 | 522 | goto set_EPC; |
| 511 | - case EXCP_TLBS: | |
| 512 | - cause = 3; | |
| 513 | - if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) { | |
| 514 | -#if defined(TARGET_MIPS64) | |
| 515 | - int R = env->CP0_BadVAddr >> 62; | |
| 516 | - int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0; | |
| 517 | - int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0; | |
| 518 | - int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0; | |
| 519 | - | |
| 520 | - if ((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX)) | |
| 521 | - offset = 0x080; | |
| 522 | - else | |
| 523 | -#endif | |
| 524 | - offset = 0x000; | |
| 525 | - } | |
| 523 | + case EXCP_MDMX: | |
| 524 | + cause = 22; | |
| 525 | + goto set_EPC; | |
| 526 | + case EXCP_DWATCH: | |
| 527 | + cause = 23; | |
| 528 | + /* XXX: TODO: manage defered watch exceptions */ | |
| 529 | + goto set_EPC; | |
| 530 | + case EXCP_MCHECK: | |
| 531 | + cause = 24; | |
| 526 | 532 | goto set_EPC; |
| 527 | 533 | case EXCP_THREAD: |
| 528 | 534 | cause = 25; |
| 535 | + goto set_EPC; | |
| 536 | + case EXCP_CACHE: | |
| 537 | + cause = 30; | |
| 538 | + if (env->CP0_Status & (1 << CP0St_BEV)) { | |
| 539 | + offset = 0x100; | |
| 540 | + } else { | |
| 541 | + offset = 0x20000100; | |
| 542 | + } | |
| 529 | 543 | set_EPC: |
| 530 | 544 | if (!(env->CP0_Status & (1 << CP0St_EXL))) { |
| 531 | 545 | if (env->hflags & MIPS_HFLAG_BMASK) { | ... | ... |