Commit 227671c93ba454a4687ba0ddc5c7f3c55a166900

Authored by bellard
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
... ...