PAGE_EXEC support (Blue Swirl)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1692 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
f881a0d4f6
commit
227671c93b
@ -75,10 +75,27 @@ static const int access_table[8][8] = {
|
|||||||
{ 2, 2, 2, 0, 2, 2, 2, 0 }
|
{ 2, 2, 2, 0, 2, 2, 2, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 1 = write OK */
|
static const int perm_table[2][8] = {
|
||||||
static const int rw_table[2][8] = {
|
{
|
||||||
{ 0, 1, 0, 1, 0, 1, 0, 1 },
|
PAGE_READ,
|
||||||
{ 0, 1, 0, 1, 0, 0, 0, 0 }
|
PAGE_READ | PAGE_WRITE,
|
||||||
|
PAGE_READ | PAGE_EXEC,
|
||||||
|
PAGE_READ | PAGE_WRITE | PAGE_EXEC,
|
||||||
|
PAGE_EXEC,
|
||||||
|
PAGE_READ | PAGE_WRITE,
|
||||||
|
PAGE_READ | PAGE_EXEC,
|
||||||
|
PAGE_READ | PAGE_WRITE | PAGE_EXEC
|
||||||
|
},
|
||||||
|
{
|
||||||
|
PAGE_READ,
|
||||||
|
PAGE_READ | PAGE_WRITE,
|
||||||
|
PAGE_READ | PAGE_EXEC,
|
||||||
|
PAGE_READ | PAGE_WRITE | PAGE_EXEC,
|
||||||
|
PAGE_EXEC,
|
||||||
|
PAGE_READ,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
|
int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
|
||||||
@ -95,7 +112,7 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot
|
|||||||
virt_addr = address & TARGET_PAGE_MASK;
|
virt_addr = address & TARGET_PAGE_MASK;
|
||||||
if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
|
if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
|
||||||
*physical = address;
|
*physical = address;
|
||||||
*prot = PAGE_READ | PAGE_WRITE;
|
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,12 +194,11 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot
|
|||||||
return error_code;
|
return error_code;
|
||||||
|
|
||||||
/* the page can be put in the TLB */
|
/* the page can be put in the TLB */
|
||||||
*prot = PAGE_READ;
|
*prot = perm_table[is_user][access_perms];
|
||||||
if (pde & PG_MODIFIED_MASK) {
|
if (!(pde & PG_MODIFIED_MASK)) {
|
||||||
/* only set write access if already dirty... otherwise wait
|
/* only set write access if already dirty... otherwise wait
|
||||||
for dirty access */
|
for dirty access */
|
||||||
if (rw_table[is_user][access_perms])
|
*prot &= ~PAGE_WRITE;
|
||||||
*prot |= PAGE_WRITE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Even if large ptes, we map only one 4KB page in the cache to
|
/* Even if large ptes, we map only one 4KB page in the cache to
|
||||||
@ -206,7 +222,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
|
|||||||
#ifdef DEBUG_MMU
|
#ifdef DEBUG_MMU
|
||||||
printf("Translate at 0x%lx -> 0x%lx, vaddr 0x%lx\n", (long)address, (long)paddr, (long)vaddr);
|
printf("Translate at 0x%lx -> 0x%lx, vaddr 0x%lx\n", (long)address, (long)paddr, (long)vaddr);
|
||||||
#endif
|
#endif
|
||||||
ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu);
|
ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,8 +237,8 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
|
|||||||
// neverland. Fake/overridden mappings will be flushed when
|
// neverland. Fake/overridden mappings will be flushed when
|
||||||
// switching to normal mode.
|
// switching to normal mode.
|
||||||
vaddr = address & TARGET_PAGE_MASK;
|
vaddr = address & TARGET_PAGE_MASK;
|
||||||
prot = PAGE_READ | PAGE_WRITE;
|
prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
|
||||||
ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu);
|
ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
if (rw & 2)
|
if (rw & 2)
|
||||||
@ -405,7 +421,7 @@ static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical
|
|||||||
|
|
||||||
if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */
|
if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */
|
||||||
*physical = address;
|
*physical = address;
|
||||||
*prot = PAGE_READ;
|
*prot = PAGE_EXEC;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -441,7 +457,7 @@ static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
*physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
|
*physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
|
||||||
*prot = PAGE_READ;
|
*prot = PAGE_EXEC;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -477,7 +493,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
|
|||||||
#ifdef DEBUG_MMU
|
#ifdef DEBUG_MMU
|
||||||
printf("Translate at 0x%llx -> 0x%llx, vaddr 0x%llx\n", address, paddr, vaddr);
|
printf("Translate at 0x%llx -> 0x%llx, vaddr 0x%llx\n", address, paddr, vaddr);
|
||||||
#endif
|
#endif
|
||||||
ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu);
|
ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
// XXX
|
// XXX
|
||||||
|
Loading…
Reference in New Issue
Block a user