diff options
author | ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-01-04 17:52:57 +0000 |
---|---|---|
committer | ths <ths@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-01-04 17:52:57 +0000 |
commit | b67bfe8d9f7251c485cf0ffad514486f8db39509 (patch) | |
tree | bc63321def5cd75ade68ec02c9cf5c8929090fdf /target-mips/helper.c | |
parent | 9a5d878f6e7c9c87d92d391f97a593e94be92031 (diff) |
Handle some more exception types.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3886 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-mips/helper.c')
-rw-r--r-- | target-mips/helper.c | 72 |
1 files changed, 43 insertions, 29 deletions
diff --git a/target-mips/helper.c b/target-mips/helper.c index 2645a44d78..867c522be8 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -442,23 +442,13 @@ void do_interrupt (CPUState *env) env->CP0_Cause &= ~(1 << CP0Ca_BD); env->PC[env->current_tc] = (int32_t)0xBFC00000; break; - case EXCP_MCHECK: - cause = 24; - goto set_EPC; case EXCP_EXT_INTERRUPT: cause = 0; if (env->CP0_Cause & (1 << CP0Ca_IV)) offset = 0x200; goto set_EPC; - case EXCP_DWATCH: - cause = 23; - /* XXX: TODO: manage defered watch exceptions */ - goto set_EPC; - case EXCP_AdEL: - cause = 4; - goto set_EPC; - case EXCP_AdES: - cause = 5; + case EXCP_LTLBL: + cause = 1; goto set_EPC; case EXCP_TLBL: cause = 2; @@ -476,6 +466,28 @@ void do_interrupt (CPUState *env) offset = 0x000; } goto set_EPC; + case EXCP_TLBS: + cause = 3; + if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) { +#if defined(TARGET_MIPS64) + int R = env->CP0_BadVAddr >> 62; + int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0; + int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0; + int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0; + + if ((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX)) + offset = 0x080; + else +#endif + offset = 0x000; + } + goto set_EPC; + case EXCP_AdEL: + cause = 4; + goto set_EPC; + case EXCP_AdES: + cause = 5; + goto set_EPC; case EXCP_IBE: cause = 6; goto set_EPC; @@ -505,27 +517,29 @@ void do_interrupt (CPUState *env) case EXCP_FPE: cause = 15; goto set_EPC; - case EXCP_LTLBL: - cause = 1; + case EXCP_C2E: + cause = 18; goto set_EPC; - case EXCP_TLBS: - cause = 3; - if (env->error_code == 1 && !(env->CP0_Status & (1 << CP0St_EXL))) { -#if defined(TARGET_MIPS64) - int R = env->CP0_BadVAddr >> 62; - int UX = (env->CP0_Status & (1 << CP0St_UX)) != 0; - int SX = (env->CP0_Status & (1 << CP0St_SX)) != 0; - int KX = (env->CP0_Status & (1 << CP0St_KX)) != 0; - - if ((R == 0 && UX) || (R == 1 && SX) || (R == 3 && KX)) - offset = 0x080; - else -#endif - offset = 0x000; - } + case EXCP_MDMX: + cause = 22; + goto set_EPC; + case EXCP_DWATCH: + cause = 23; + /* XXX: TODO: manage defered watch exceptions */ + goto set_EPC; + case EXCP_MCHECK: + cause = 24; goto set_EPC; case EXCP_THREAD: cause = 25; + goto set_EPC; + case EXCP_CACHE: + cause = 30; + if (env->CP0_Status & (1 << CP0St_BEV)) { + offset = 0x100; + } else { + offset = 0x20000100; + } set_EPC: if (!(env->CP0_Status & (1 << CP0St_EXL))) { if (env->hflags & MIPS_HFLAG_BMASK) { |