aboutsummaryrefslogtreecommitdiff
path: root/target-mips/helper.c
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2005-12-05 19:59:36 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2005-12-05 19:59:36 +0000
commit4ad40f366f20f6991b640d7af63c9fc3a59246fa (patch)
treec895253e1b6f236ff8d874b7ac7fddf98e486795 /target-mips/helper.c
parent6810e154907c4ed3883f3f9fc03507fe45a679ea (diff)
MIPS fixes (Daniel Jacobowitz)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1690 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-mips/helper.c')
-rw-r--r--target-mips/helper.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 8d2617557a..8b4deb3ddc 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -46,7 +46,7 @@ static int map_address (CPUState *env, target_ulong *physical, int *prot,
tlb = &env->tlb[i];
/* Check ASID, virtual page number & size */
if ((tlb->G == 1 || tlb->ASID == ASID) &&
- tlb->VPN == tag && address < tlb->end) {
+ tlb->VPN == tag && address < tlb->end2) {
/* TLB match */
n = (address >> 12) & 1;
/* Check access rights */
@@ -167,10 +167,15 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
int ret = 0;
if (logfile) {
+#if 0
cpu_dump_state(env, logfile, fprintf, 0);
+#endif
fprintf(logfile, "%s pc %08x ad %08x rw %d is_user %d smmu %d\n",
__func__, env->PC, address, rw, is_user, is_softmmu);
}
+
+ rw &= 1;
+
/* data access */
/* XXX: put correct access by using cpu_restore_state()
correctly */
@@ -226,7 +231,7 @@ int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
/* Raise exception */
env->CP0_BadVAddr = address;
env->CP0_Context = (env->CP0_Context & 0xff800000) |
- ((address >> 8) & 0x007ffff0);
+ ((address >> 9) & 0x007ffff0);
env->CP0_EntryHi =
(env->CP0_EntryHi & 0x000000FF) | (address & 0xFFFFF000);
env->exception_index = exception;
@@ -276,11 +281,12 @@ void do_interrupt (CPUState *env)
env->CP0_Debug |= 1 << CP0DB_DDBL;
goto set_DEPC;
set_DEPC:
- if (env->hflags & MIPS_HFLAG_DS) {
+ if (env->hflags & MIPS_HFLAG_BMASK) {
/* If the exception was raised from a delay slot,
* come back to the jump
*/
env->CP0_DEPC = env->PC - 4;
+ env->hflags &= ~MIPS_HFLAG_BMASK;
} else {
env->CP0_DEPC = env->PC;
}
@@ -316,8 +322,7 @@ void do_interrupt (CPUState *env)
env->CP0_Status = (1 << CP0St_CU0) | (1 << CP0St_BEV) |
(1 << CP0St_NMI);
set_error_EPC:
- env->hflags = MIPS_HFLAG_ERL;
- if (env->hflags & MIPS_HFLAG_DS) {
+ if (env->hflags & MIPS_HFLAG_BMASK) {
/* If the exception was raised from a delay slot,
* come back to the jump
*/
@@ -325,6 +330,7 @@ void do_interrupt (CPUState *env)
} else {
env->CP0_ErrorEPC = env->PC;
}
+ env->hflags = MIPS_HFLAG_ERL;
pc = 0xBFC00000;
break;
case EXCP_MCHECK:
@@ -366,7 +372,7 @@ void do_interrupt (CPUState *env)
goto set_EPC;
case EXCP_CpU:
cause = 11;
- /* XXX: fill in the faulty unit number */
+ env->CP0_Cause = (env->CP0_Cause & ~0x03000000) | (env->error_code << 28);
goto set_EPC;
case EXCP_OVERFLOW:
cause = 12;
@@ -391,12 +397,13 @@ void do_interrupt (CPUState *env)
env->hflags |= MIPS_HFLAG_EXL;
pc += offset;
env->CP0_Cause = (env->CP0_Cause & ~0x7C) | (cause << 2);
- if (env->hflags & MIPS_HFLAG_DS) {
+ if (env->hflags & MIPS_HFLAG_BMASK) {
/* If the exception was raised from a delay slot,
* come back to the jump
*/
env->CP0_EPC = env->PC - 4;
env->CP0_Cause |= 0x80000000;
+ env->hflags &= ~MIPS_HFLAG_BMASK;
} else {
env->CP0_EPC = env->PC;
env->CP0_Cause &= ~0x80000000;