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,10 +75,27 @@ static const int access_table[8][8] = {
75 { 2, 2, 2, 0, 2, 2, 2, 0 } 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 int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot, 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,7 +112,7 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot
95 virt_addr = address & TARGET_PAGE_MASK; 112 virt_addr = address & TARGET_PAGE_MASK;
96 if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */ 113 if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
97 *physical = address; 114 *physical = address;
98 - *prot = PAGE_READ | PAGE_WRITE; 115 + *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
99 return 0; 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,12 +194,11 @@ int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot
177 return error_code; 194 return error_code;
178 195
179 /* the page can be put in the TLB */ 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 /* only set write access if already dirty... otherwise wait 199 /* only set write access if already dirty... otherwise wait
183 for dirty access */ 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 /* Even if large ptes, we map only one 4KB page in the cache to 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,7 +222,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
206 #ifdef DEBUG_MMU 222 #ifdef DEBUG_MMU
207 printf("Translate at 0x%lx -> 0x%lx, vaddr 0x%lx\n", (long)address, (long)paddr, (long)vaddr); 223 printf("Translate at 0x%lx -> 0x%lx, vaddr 0x%lx\n", (long)address, (long)paddr, (long)vaddr);
208 #endif 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 return ret; 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,8 +237,8 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
221 // neverland. Fake/overridden mappings will be flushed when 237 // neverland. Fake/overridden mappings will be flushed when
222 // switching to normal mode. 238 // switching to normal mode.
223 vaddr = address & TARGET_PAGE_MASK; 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 return ret; 242 return ret;
227 } else { 243 } else {
228 if (rw & 2) 244 if (rw & 2)
@@ -405,7 +421,7 @@ static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical @@ -405,7 +421,7 @@ static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical
405 421
406 if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */ 422 if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */
407 *physical = address; 423 *physical = address;
408 - *prot = PAGE_READ; 424 + *prot = PAGE_EXEC;
409 return 0; 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,7 +457,7 @@ static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical
441 return 1; 457 return 1;
442 } 458 }
443 *physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL); 459 *physical = (env->itlb_tte[i] & mask & 0x1fffffff000ULL) + (address & ~mask & 0x1fffffff000ULL);
444 - *prot = PAGE_READ; 460 + *prot = PAGE_EXEC;
445 return 0; 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,7 +493,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
477 #ifdef DEBUG_MMU 493 #ifdef DEBUG_MMU
478 printf("Translate at 0x%llx -> 0x%llx, vaddr 0x%llx\n", address, paddr, vaddr); 494 printf("Translate at 0x%llx -> 0x%llx, vaddr 0x%llx\n", address, paddr, vaddr);
479 #endif 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 return ret; 497 return ret;
482 } 498 }
483 // XXX 499 // XXX