Revision d4c430a8 target-sparc/helper.c
b/target-sparc/helper.c | ||
---|---|---|
102 | 102 |
|
103 | 103 |
static int get_physical_address(CPUState *env, target_phys_addr_t *physical, |
104 | 104 |
int *prot, int *access_index, |
105 |
target_ulong address, int rw, int mmu_idx) |
|
105 |
target_ulong address, int rw, int mmu_idx, |
|
106 |
target_ulong *page_size) |
|
106 | 107 |
{ |
107 | 108 |
int access_perms = 0; |
108 | 109 |
target_phys_addr_t pde_ptr; |
... | ... | |
113 | 114 |
is_user = mmu_idx == MMU_USER_IDX; |
114 | 115 |
|
115 | 116 |
if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */ |
117 |
*page_size = TARGET_PAGE_SIZE; |
|
116 | 118 |
// Boot mode: instruction fetches are taken from PROM |
117 | 119 |
if (rw == 2 && (env->mmuregs[0] & env->def->mmu_bm)) { |
118 | 120 |
*physical = env->prom_addr | (address & 0x7ffffULL); |
... | ... | |
175 | 177 |
page_offset = (address & TARGET_PAGE_MASK) & |
176 | 178 |
(TARGET_PAGE_SIZE - 1); |
177 | 179 |
} |
180 |
*page_size = TARGET_PAGE_SIZE; |
|
178 | 181 |
break; |
179 | 182 |
case 2: /* L2 PTE */ |
180 | 183 |
page_offset = address & 0x3ffff; |
184 |
*page_size = 0x40000; |
|
181 | 185 |
} |
182 | 186 |
break; |
183 | 187 |
case 2: /* L1 PTE */ |
184 | 188 |
page_offset = address & 0xffffff; |
189 |
*page_size = 0x1000000; |
|
185 | 190 |
} |
186 | 191 |
} |
187 | 192 |
|
... | ... | |
220 | 225 |
{ |
221 | 226 |
target_phys_addr_t paddr; |
222 | 227 |
target_ulong vaddr; |
223 |
int error_code = 0, prot, ret = 0, access_index; |
|
228 |
target_ulong page_size; |
|
229 |
int error_code = 0, prot, access_index; |
|
224 | 230 |
|
225 | 231 |
error_code = get_physical_address(env, &paddr, &prot, &access_index, |
226 |
address, rw, mmu_idx); |
|
232 |
address, rw, mmu_idx, &page_size);
|
|
227 | 233 |
if (error_code == 0) { |
228 | 234 |
vaddr = address & TARGET_PAGE_MASK; |
229 | 235 |
paddr &= TARGET_PAGE_MASK; |
... | ... | |
231 | 237 |
printf("Translate at " TARGET_FMT_lx " -> " TARGET_FMT_plx ", vaddr " |
232 | 238 |
TARGET_FMT_lx "\n", address, paddr, vaddr); |
233 | 239 |
#endif |
234 |
ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
|
|
235 |
return ret;
|
|
240 |
tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
|
|
241 |
return 0;
|
|
236 | 242 |
} |
237 | 243 |
|
238 | 244 |
if (env->mmuregs[3]) /* Fault status register */ |
... | ... | |
247 | 253 |
// switching to normal mode. |
248 | 254 |
vaddr = address & TARGET_PAGE_MASK; |
249 | 255 |
prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; |
250 |
ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
|
|
251 |
return ret;
|
|
256 |
tlb_set_page(env, vaddr, paddr, prot, mmu_idx, TARGET_PAGE_SIZE);
|
|
257 |
return 0;
|
|
252 | 258 |
} else { |
253 | 259 |
if (rw & 2) |
254 | 260 |
env->exception_index = TT_TFAULT; |
... | ... | |
531 | 537 |
|
532 | 538 |
static int get_physical_address(CPUState *env, target_phys_addr_t *physical, |
533 | 539 |
int *prot, int *access_index, |
534 |
target_ulong address, int rw, int mmu_idx) |
|
540 |
target_ulong address, int rw, int mmu_idx, |
|
541 |
target_ulong *page_size) |
|
535 | 542 |
{ |
536 | 543 |
int is_user = mmu_idx == MMU_USER_IDX; |
537 | 544 |
|
545 |
/* ??? We treat everything as a small page, then explicitly flush |
|
546 |
everything when an entry is evicted. */ |
|
547 |
*page_size = TARGET_PAGE_SIZE; |
|
538 | 548 |
if (rw == 2) |
539 | 549 |
return get_physical_address_code(env, physical, prot, address, |
540 | 550 |
is_user); |
... | ... | |
549 | 559 |
{ |
550 | 560 |
target_ulong virt_addr, vaddr; |
551 | 561 |
target_phys_addr_t paddr; |
552 |
int error_code = 0, prot, ret = 0, access_index; |
|
562 |
target_ulong page_size; |
|
563 |
int error_code = 0, prot, access_index; |
|
553 | 564 |
|
554 | 565 |
error_code = get_physical_address(env, &paddr, &prot, &access_index, |
555 |
address, rw, mmu_idx); |
|
566 |
address, rw, mmu_idx, &page_size);
|
|
556 | 567 |
if (error_code == 0) { |
557 | 568 |
virt_addr = address & TARGET_PAGE_MASK; |
558 | 569 |
vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & |
... | ... | |
561 | 572 |
printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64 |
562 | 573 |
"\n", address, paddr, vaddr); |
563 | 574 |
#endif |
564 |
ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);
|
|
565 |
return ret;
|
|
575 |
tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
|
|
576 |
return 0;
|
|
566 | 577 |
} |
567 | 578 |
// XXX |
568 | 579 |
return 1; |
... | ... | |
656 | 667 |
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr) |
657 | 668 |
{ |
658 | 669 |
target_phys_addr_t phys_addr; |
670 |
target_ulong page_size; |
|
659 | 671 |
int prot, access_index; |
660 | 672 |
|
661 | 673 |
if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2, |
662 |
MMU_KERNEL_IDX) != 0) |
|
674 |
MMU_KERNEL_IDX, &page_size) != 0)
|
|
663 | 675 |
if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, |
664 |
0, MMU_KERNEL_IDX) != 0) |
|
676 |
0, MMU_KERNEL_IDX, &page_size) != 0)
|
|
665 | 677 |
return -1; |
666 | 678 |
if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED) |
667 | 679 |
return -1; |
Also available in: Unified diff