aboutsummaryrefslogtreecommitdiff
path: root/target-sparc
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2005-03-13 09:43:36 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2005-03-13 09:43:36 +0000
commit6f7e9aec5eb5bdfa57a9e458e391b785c283a007 (patch)
tree8679501a365f5fa7ee5b4e6fdd8d6a4f6e92f679 /target-sparc
parentb756921ad18c8d293da634ff3b4e950ec8ae3f80 (diff)
downloadqemu-6f7e9aec5eb5bdfa57a9e458e391b785c283a007.zip
qemu-6f7e9aec5eb5bdfa57a9e458e391b785c283a007.tar.gz
qemu-6f7e9aec5eb5bdfa57a9e458e391b785c283a007.tar.bz2
sparc fixes (Blue Swirl)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1326 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-sparc')
-rw-r--r--target-sparc/helper.c18
-rw-r--r--target-sparc/op_helper.c4
2 files changed, 11 insertions, 11 deletions
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index bf28a36..e6891cc 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -138,6 +138,7 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot
}
*access_index = ((rw & 1) << 2) | (rw & 2) | (is_user? 0 : 1);
+ *physical = 0xfffff000;
/* SPARC reference MMU table walk: Context table->L1->L2->PTE */
/* Context base + context number */
@@ -210,7 +211,7 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot
/* check access */
access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;
error_code = access_table[*access_index][access_perms];
- if (error_code)
+ if (error_code && !(env->mmuregs[0] & MMU_NF))
return error_code;
/* the page can be put in the TLB */
@@ -225,7 +226,7 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot
/* Even if large ptes, we map only one 4KB page in the cache to
avoid filling it too fast */
*physical = ((pde & PTE_ADDR_MASK) << 4) + page_offset;
- return 0;
+ return error_code;
}
/* Perform address translation */
@@ -251,17 +252,14 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
env->mmuregs[4] = address; /* Fault address register */
if ((env->mmuregs[0] & MMU_NF) || env->psret == 0) {
-#if 0
- // No fault
+ // No fault mode: if a mapping is available, just override
+ // permissions. If no mapping is available, redirect accesses to
+ // neverland. Fake/overridden mappings will be flushed when
+ // switching to normal mode.
vaddr = address & TARGET_PAGE_MASK;
- paddr = 0xfffff000;
prot = PAGE_READ | PAGE_WRITE;
ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu);
return ret;
-#else
- cpu_abort(env, "MMU no fault case no handled");
- return 0;
-#endif
} else {
if (rw & 2)
env->exception_index = TT_TFAULT;
@@ -316,8 +314,8 @@ void do_interrupt(int intno)
count, intno,
env->pc,
env->npc, env->regwptr[6]);
-#if 1
cpu_dump_state(env, logfile, fprintf, 0);
+#if 0
{
int i;
uint8_t *ptr;
diff --git a/target-sparc/op_helper.c b/target-sparc/op_helper.c
index 4c65c64..9cb3de4 100644
--- a/target-sparc/op_helper.c
+++ b/target-sparc/op_helper.c
@@ -164,7 +164,9 @@ void helper_st_asi(int asi, int size, int sign)
case 0:
env->mmuregs[reg] &= ~(MMU_E | MMU_NF);
env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF);
- if ((oldreg & MMU_E) != (env->mmuregs[reg] & MMU_E))
+ // Mappings generated during no-fault mode or MMU
+ // disabled mode are invalid in normal mode
+ if (oldreg != env->mmuregs[reg])
tlb_flush(env, 1);
break;
case 2: