Commit b67bfe8d9f7251c485cf0ffad514486f8db39509

Authored by ths
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,23 +442,13 @@ void do_interrupt (CPUState *env)
442 env->CP0_Cause &= ~(1 << CP0Ca_BD); 442 env->CP0_Cause &= ~(1 << CP0Ca_BD);
443 env->PC[env->current_tc] = (int32_t)0xBFC00000; 443 env->PC[env->current_tc] = (int32_t)0xBFC00000;
444 break; 444 break;
445 - case EXCP_MCHECK:  
446 - cause = 24;  
447 - goto set_EPC;  
448 case EXCP_EXT_INTERRUPT: 445 case EXCP_EXT_INTERRUPT:
449 cause = 0; 446 cause = 0;
450 if (env->CP0_Cause & (1 << CP0Ca_IV)) 447 if (env->CP0_Cause & (1 << CP0Ca_IV))
451 offset = 0x200; 448 offset = 0x200;
452 goto set_EPC; 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 goto set_EPC; 452 goto set_EPC;
463 case EXCP_TLBL: 453 case EXCP_TLBL:
464 cause = 2; 454 cause = 2;
@@ -476,6 +466,28 @@ void do_interrupt (CPUState *env) @@ -476,6 +466,28 @@ void do_interrupt (CPUState *env)
476 offset = 0x000; 466 offset = 0x000;
477 } 467 }
478 goto set_EPC; 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 case EXCP_IBE: 491 case EXCP_IBE:
480 cause = 6; 492 cause = 6;
481 goto set_EPC; 493 goto set_EPC;
@@ -505,27 +517,29 @@ void do_interrupt (CPUState *env) @@ -505,27 +517,29 @@ void do_interrupt (CPUState *env)
505 case EXCP_FPE: 517 case EXCP_FPE:
506 cause = 15; 518 cause = 15;
507 goto set_EPC; 519 goto set_EPC;
508 - case EXCP_LTLBL:  
509 - cause = 1; 520 + case EXCP_C2E:
  521 + cause = 18;
510 goto set_EPC; 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 goto set_EPC; 532 goto set_EPC;
527 case EXCP_THREAD: 533 case EXCP_THREAD:
528 cause = 25; 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 set_EPC: 543 set_EPC:
530 if (!(env->CP0_Status & (1 << CP0St_EXL))) { 544 if (!(env->CP0_Status & (1 << CP0St_EXL))) {
531 if (env->hflags & MIPS_HFLAG_BMASK) { 545 if (env->hflags & MIPS_HFLAG_BMASK) {