Commit 227671c93ba454a4687ba0ddc5c7f3c55a166900
1 parent
f881a0d4
PAGE_EXEC support (Blue Swirl)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1692 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
31 additions
and
15 deletions
target-sparc/helper.c
... | ... | @@ -75,10 +75,27 @@ static const int access_table[8][8] = { |
75 | 75 | { 2, 2, 2, 0, 2, 2, 2, 0 } |
76 | 76 | }; |
77 | 77 | |
78 | -/* 1 = write OK */ | |
79 | -static const int rw_table[2][8] = { | |
80 | - { 0, 1, 0, 1, 0, 1, 0, 1 }, | |
81 | - { 0, 1, 0, 1, 0, 0, 0, 0 } | |
78 | +static const int perm_table[2][8] = { | |
79 | + { | |
80 | + PAGE_READ, | |
81 | + PAGE_READ | PAGE_WRITE, | |
82 | + PAGE_READ | PAGE_EXEC, | |
83 | + PAGE_READ | PAGE_WRITE | PAGE_EXEC, | |
84 | + PAGE_EXEC, | |
85 | + PAGE_READ | PAGE_WRITE, | |
86 | + PAGE_READ | PAGE_EXEC, | |
87 | + PAGE_READ | PAGE_WRITE | PAGE_EXEC | |
88 | + }, | |
89 | + { | |
90 | + PAGE_READ, | |
91 | + PAGE_READ | PAGE_WRITE, | |
92 | + PAGE_READ | PAGE_EXEC, | |
93 | + PAGE_READ | PAGE_WRITE | PAGE_EXEC, | |
94 | + PAGE_EXEC, | |
95 | + PAGE_READ, | |
96 | + 0, | |
97 | + 0, | |
98 | + } | |
82 | 99 | }; |
83 | 100 | |
84 | 101 | 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 |
95 | 112 | virt_addr = address & TARGET_PAGE_MASK; |
96 | 113 | if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */ |
97 | 114 | *physical = address; |
98 | - *prot = PAGE_READ | PAGE_WRITE; | |
115 | + *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; | |
99 | 116 | return 0; |
100 | 117 | } |
101 | 118 | |
... | ... | @@ -177,12 +194,11 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot |
177 | 194 | return error_code; |
178 | 195 | |
179 | 196 | /* the page can be put in the TLB */ |
180 | - *prot = PAGE_READ; | |
181 | - if (pde & PG_MODIFIED_MASK) { | |
197 | + *prot = perm_table[is_user][access_perms]; | |
198 | + if (!(pde & PG_MODIFIED_MASK)) { | |
182 | 199 | /* only set write access if already dirty... otherwise wait |
183 | 200 | for dirty access */ |
184 | - if (rw_table[is_user][access_perms]) | |
185 | - *prot |= PAGE_WRITE; | |
201 | + *prot &= ~PAGE_WRITE; | |
186 | 202 | } |
187 | 203 | |
188 | 204 | /* 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, |
206 | 222 | #ifdef DEBUG_MMU |
207 | 223 | printf("Translate at 0x%lx -> 0x%lx, vaddr 0x%lx\n", (long)address, (long)paddr, (long)vaddr); |
208 | 224 | #endif |
209 | - ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu); | |
225 | + ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu); | |
210 | 226 | return ret; |
211 | 227 | } |
212 | 228 | |
... | ... | @@ -221,8 +237,8 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, |
221 | 237 | // neverland. Fake/overridden mappings will be flushed when |
222 | 238 | // switching to normal mode. |
223 | 239 | vaddr = address & TARGET_PAGE_MASK; |
224 | - prot = PAGE_READ | PAGE_WRITE; | |
225 | - ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu); | |
240 | + prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; | |
241 | + ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu); | |
226 | 242 | return ret; |
227 | 243 | } else { |
228 | 244 | if (rw & 2) |
... | ... | @@ -405,7 +421,7 @@ static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical |
405 | 421 | |
406 | 422 | if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */ |
407 | 423 | *physical = address; |
408 | - *prot = PAGE_READ; | |
424 | + *prot = PAGE_EXEC; | |
409 | 425 | return 0; |
410 | 426 | } |
411 | 427 | |
... | ... | @@ -441,7 +457,7 @@ static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical |
441 | 457 | return 1; |
442 | 458 | } |
443 | 459 | *physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL); |
444 | - *prot = PAGE_READ; | |
460 | + *prot = PAGE_EXEC; | |
445 | 461 | return 0; |
446 | 462 | } |
447 | 463 | } |
... | ... | @@ -477,7 +493,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, |
477 | 493 | #ifdef DEBUG_MMU |
478 | 494 | printf("Translate at 0x%llx -> 0x%llx, vaddr 0x%llx\n", address, paddr, vaddr); |
479 | 495 | #endif |
480 | - ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu); | |
496 | + ret = tlb_set_page_exec(env, vaddr, paddr, prot, is_user, is_softmmu); | |
481 | 497 | return ret; |
482 | 498 | } |
483 | 499 | // XXX | ... | ... |