From 149f54b53b7666a3facd45e86eece60ce7d3b114 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 24 May 2013 12:59:37 +0200 Subject: memory: add address_space_translate Using phys_page_find to translate an AddressSpace to a MemoryRegionSection is unwieldy. It requires to pass the page index rather than the address, and later memory_region_section_addr has to be called. Replace memory_region_section_addr with a function that does all of it: call phys_page_find, compute the offset within the region, and check how big the current mapping is. This way, a large flat region can be written with a single lookup rather than a page at a time. address_space_translate will also provide a single point where IOMMU forwarding is implemented. Reviewed-by: Peter Maydell Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- cputlb.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'cputlb.c') diff --git a/cputlb.c b/cputlb.c index b56bc0102c..86666c8d57 100644 --- a/cputlb.c +++ b/cputlb.c @@ -248,13 +248,18 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr, target_ulong code_address; uintptr_t addend; CPUTLBEntry *te; - hwaddr iotlb; + hwaddr iotlb, xlat, sz; assert(size >= TARGET_PAGE_SIZE); if (size != TARGET_PAGE_SIZE) { tlb_add_large_page(env, vaddr, size); } - section = phys_page_find(address_space_memory.dispatch, paddr >> TARGET_PAGE_BITS); + + sz = size; + section = address_space_translate(&address_space_memory, paddr, &xlat, &sz, + false); + assert(sz >= TARGET_PAGE_SIZE); + #if defined(DEBUG_TLB) printf("tlb_set_page: vaddr=" TARGET_FMT_lx " paddr=0x" TARGET_FMT_plx " prot=%x idx=%d pd=0x%08lx\n", @@ -268,13 +273,12 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr, addend = 0; } else { /* TLB_MMIO for rom/romd handled below */ - addend = (uintptr_t)memory_region_get_ram_ptr(section->mr) - + memory_region_section_addr(section, paddr); + addend = (uintptr_t)memory_region_get_ram_ptr(section->mr) + xlat; } code_address = address; - iotlb = memory_region_section_get_iotlb(env, section, vaddr, paddr, prot, - &address); + iotlb = memory_region_section_get_iotlb(env, section, vaddr, paddr, xlat, + prot, &address); index = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); env->iotlb[mmu_idx][index] = iotlb - vaddr; @@ -297,9 +301,7 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr, /* Write access calls the I/O callback. */ te->addr_write = address | TLB_MMIO; } else if (memory_region_is_ram(section->mr) - && !cpu_physical_memory_is_dirty( - section->mr->ram_addr - + memory_region_section_addr(section, paddr))) { + && !cpu_physical_memory_is_dirty(section->mr->ram_addr + xlat)) { te->addr_write = address | TLB_NOTDIRTY; } else { te->addr_write = address; -- cgit v1.2.1