From patchwork Tue May 7 14:16:50 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 242352 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 331592C016B for ; Wed, 8 May 2013 01:17:29 +1000 (EST) Received: from localhost ([::1]:37921 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UZikR-0001gj-J4 for incoming@patchwork.ozlabs.org; Tue, 07 May 2013 10:20:07 -0400 Received: from eggs.gnu.org ([208.118.235.92]:56976) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UZiia-0000HZ-3q for qemu-devel@nongnu.org; Tue, 07 May 2013 10:18:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UZiiU-0005sS-Oo for qemu-devel@nongnu.org; Tue, 07 May 2013 10:18:12 -0400 Received: from mail-wg0-x22a.google.com ([2a00:1450:400c:c00::22a]:41267) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UZiiU-0005rx-BG for qemu-devel@nongnu.org; Tue, 07 May 2013 10:18:06 -0400 Received: by mail-wg0-f42.google.com with SMTP id j13so3936354wgh.1 for ; Tue, 07 May 2013 07:18:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:sender:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references; bh=JdwHm977uoxVGA2KrDZACEU2ba4QeErQFYg2A2CgouI=; b=JwkmRmNy4IIUEXkKJqw2HIjce5LOyZ80ydZDHQInV0sZ+/cAHuFkj4giUpALeN5qNy ZnvOWZMY7IJ5sca2g4TxuZucPOKnbwh8WtiD0R7peiS0K3bDKmuesa9t5CRSAh1Btr1G +58sOvAjkeU2YN9VZBJVQAdecSyIeN1vY07yp+kgaq2tMj4ey7V6ms2qQPPedDxafyOz 3eAGvAyRLjPYeFmkVNuw6o91ENfpbLh5hZBuyBhV66XvRAUvsHQSJEYMmwwCYkKtdhYc nlHkL486RAUI1ndL+/6FAwgk+UN3wZ/iCTrWASzYVD6AEsu9ReGtzaxBbzjOBQmT3CFv D4Vg== X-Received: by 10.194.8.7 with SMTP id n7mr3753110wja.55.1367936285439; Tue, 07 May 2013 07:18:05 -0700 (PDT) Received: from localhost.localdomain (93-34-176-20.ip50.fastwebnet.it. [93.34.176.20]) by mx.google.com with ESMTPSA id ge7sm3335978wib.6.2013.05.07.07.18.03 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 07 May 2013 07:18:04 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Tue, 7 May 2013 16:16:50 +0200 Message-Id: <1367936238-12196-13-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1367936238-12196-1-git-send-email-pbonzini@redhat.com> References: <1367936238-12196-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:400c:c00::22a Cc: aik@ozlabs.ru, jan.kiszka@siemens.com, qemulist@gmail.com, stefanha@redhat.com, david@gibson.dropbear.id.au Subject: [Qemu-devel] [PATCH 12/40] memory: add address_space_translate X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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. Signed-off-by: Paolo Bonzini --- cputlb.c | 20 +++--- exec.c | 184 ++++++++++++++++++++++++++---------------------- include/exec/cputlb.h | 12 ++-- include/exec/memory.h | 31 ++++----- translate-all.c | 6 +- 5 files changed, 133 insertions(+), 120 deletions(-) diff --git a/cputlb.c b/cputlb.c index aba7e44..1f85da0 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", @@ -269,15 +274,14 @@ void tlb_set_page(CPUArchState *env, target_ulong vaddr, } if (memory_region_is_ram(section->mr) || memory_region_is_romd(section->mr)) { - 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; } else { addend = 0; } 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; @@ -300,9 +304,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; diff --git a/exec.c b/exec.c index 405de9f..9709bc4 100644 --- a/exec.c +++ b/exec.c @@ -182,24 +182,36 @@ static void phys_page_set(AddressSpaceDispatch *d, phys_page_set_level(&d->phys_map, &index, &nb, leaf, P_L2_LEVELS - 1); } -MemoryRegionSection *phys_page_find(AddressSpaceDispatch *d, hwaddr index) +static MemoryRegionSection *phys_page_find(AddressSpaceDispatch *d, hwaddr index) { PhysPageEntry lp = d->phys_map; PhysPageEntry *p; int i; - uint16_t s_index = phys_section_unassigned; for (i = P_L2_LEVELS - 1; i >= 0 && !lp.is_leaf; i--) { if (lp.ptr == PHYS_MAP_NODE_NIL) { - goto not_found; + return &phys_sections[phys_section_unassigned]; } p = phys_map_nodes[lp.ptr]; lp = p[(index >> (i * L2_BITS)) & (L2_SIZE - 1)]; } + return &phys_sections[lp.ptr]; +} + +MemoryRegionSection *address_space_translate(AddressSpace *as, hwaddr addr, + hwaddr *xlat, hwaddr *plen, + bool is_write) +{ + MemoryRegionSection *section; + + section = phys_page_find(as->dispatch, addr >> TARGET_PAGE_BITS); + /* Compute offset with MemoryRegionSection */ + addr -= section->offset_within_address_space; + *plen = MIN(section->size - addr, *plen); - s_index = lp.ptr; -not_found: - return &phys_sections[s_index]; + /* Compute offset with MemoryRegion */ + *xlat = addr + section->offset_within_region; + return section; } bool memory_region_is_unassigned(MemoryRegion *mr) @@ -620,11 +632,11 @@ static int cpu_physical_memory_set_dirty_tracking(int enable) } hwaddr memory_region_section_get_iotlb(CPUArchState *env, - MemoryRegionSection *section, - target_ulong vaddr, - hwaddr paddr, - int prot, - target_ulong *address) + MemoryRegionSection *section, + target_ulong vaddr, + hwaddr paddr, hwaddr xlat, + int prot, + target_ulong *address) { hwaddr iotlb; CPUWatchpoint *wp; @@ -632,7 +644,7 @@ hwaddr memory_region_section_get_iotlb(CPUArchState *env, if (memory_region_is_ram(section->mr)) { /* Normal RAM. */ iotlb = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK) - + memory_region_section_addr(section, paddr); + + xlat; if (!section->readonly) { iotlb |= phys_section_notdirty; } else { @@ -640,7 +652,7 @@ hwaddr memory_region_section_get_iotlb(CPUArchState *env, } } else { iotlb = section - phys_sections; - iotlb += memory_region_section_addr(section, paddr); + iotlb += xlat; } /* Make accesses to pages with watchpoints go via the @@ -1903,24 +1915,18 @@ static void invalidate_and_set_dirty(hwaddr addr, void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf, int len, bool is_write) { - AddressSpaceDispatch *d = as->dispatch; - int l; + hwaddr l; uint8_t *ptr; uint32_t val; - hwaddr page; + hwaddr addr1; MemoryRegionSection *section; while (len > 0) { - page = addr & TARGET_PAGE_MASK; - l = (page + TARGET_PAGE_SIZE) - addr; - if (l > len) - l = len; - section = phys_page_find(d, page >> TARGET_PAGE_BITS); + l = len; + section = address_space_translate(as, addr, &addr1, &l, is_write); if (is_write) { if (!memory_region_is_ram(section->mr)) { - hwaddr addr1; - addr1 = memory_region_section_addr(section, addr); /* XXX: could force cpu_single_env to NULL to avoid potential bugs */ if (l >= 4 && ((addr1 & 3) == 0)) { @@ -1940,9 +1946,7 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf, l = 1; } } else if (!section->readonly) { - ram_addr_t addr1; - addr1 = memory_region_get_ram_addr(section->mr) - + memory_region_section_addr(section, addr); + addr1 += memory_region_get_ram_addr(section->mr); /* RAM case */ ptr = qemu_get_ram_ptr(addr1); memcpy(ptr, buf, l); @@ -1952,9 +1956,7 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf, } else { if (!(memory_region_is_ram(section->mr) || memory_region_is_romd(section->mr))) { - hwaddr addr1; /* I/O case */ - addr1 = memory_region_section_addr(section, addr); if (l >= 4 && ((addr1 & 3) == 0)) { /* 32 bit read access */ val = io_mem_read(section->mr, addr1, 4); @@ -1973,9 +1975,7 @@ void address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf, } } else { /* RAM case */ - ptr = qemu_get_ram_ptr(section->mr->ram_addr - + memory_region_section_addr(section, - addr)); + ptr = qemu_get_ram_ptr(section->mr->ram_addr + addr1); memcpy(buf, ptr, l); qemu_put_ram_ptr(ptr); } @@ -2015,26 +2015,21 @@ void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf, void cpu_physical_memory_write_rom(hwaddr addr, const uint8_t *buf, int len) { - AddressSpaceDispatch *d = address_space_memory.dispatch; - int l; + hwaddr l; uint8_t *ptr; - hwaddr page; + hwaddr addr1; MemoryRegionSection *section; while (len > 0) { - page = addr & TARGET_PAGE_MASK; - l = (page + TARGET_PAGE_SIZE) - addr; - if (l > len) - l = len; - section = phys_page_find(d, page >> TARGET_PAGE_BITS); + l = len; + section = address_space_translate(&address_space_memory, + addr, &addr1, &l, true); if (!(memory_region_is_ram(section->mr) || memory_region_is_romd(section->mr))) { /* do nothing */ } else { - unsigned long addr1; - addr1 = memory_region_get_ram_addr(section->mr) - + memory_region_section_addr(section, addr); + addr1 += memory_region_get_ram_addr(section->mr); /* ROM/RAM case */ ptr = qemu_get_ram_ptr(addr1); memcpy(ptr, buf, l); @@ -2095,18 +2090,12 @@ static void cpu_notify_map_clients(void) bool address_space_valid(AddressSpace *as, hwaddr addr, int len, bool is_write) { - AddressSpaceDispatch *d = as->dispatch; MemoryRegionSection *section; - int l; - hwaddr page; + hwaddr l, xlat; while (len > 0) { - page = addr & TARGET_PAGE_MASK; - l = (page + TARGET_PAGE_SIZE) - addr; - if (l > len) { - l = len; - } - section = phys_page_find(d, addr >> TARGET_PAGE_BITS); + l = len; + section = address_space_translate(as, addr, &xlat, &l, is_write); if (section->mr == &io_mem_unassigned) { return false; } @@ -2129,22 +2118,17 @@ void *address_space_map(AddressSpace *as, hwaddr *plen, bool is_write) { - AddressSpaceDispatch *d = as->dispatch; hwaddr len = *plen; hwaddr todo = 0; - int l; - hwaddr page; + hwaddr l, xlat; MemoryRegionSection *section; ram_addr_t raddr = RAM_ADDR_MAX; ram_addr_t rlen; void *ret; while (len > 0) { - page = addr & TARGET_PAGE_MASK; - l = (page + TARGET_PAGE_SIZE) - addr; - if (l > len) - l = len; - section = phys_page_find(d, page >> TARGET_PAGE_BITS); + l = len; + section = address_space_translate(as, addr, &xlat, &l, is_write); if (!(memory_region_is_ram(section->mr) && !section->readonly)) { if (todo || bounce.buffer) { @@ -2161,8 +2145,11 @@ void *address_space_map(AddressSpace *as, return bounce.buffer; } if (!todo) { - raddr = memory_region_get_ram_addr(section->mr) - + memory_region_section_addr(section, addr); + raddr = memory_region_get_ram_addr(section->mr) + xlat; + } else { + if (memory_region_get_ram_addr(section->mr) + xlat != raddr + todo) { + break; + } } len -= l; @@ -2228,13 +2215,17 @@ static inline uint32_t ldl_phys_internal(hwaddr addr, uint8_t *ptr; uint32_t val; MemoryRegionSection *section; + hwaddr l = 4; - section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS); + section = address_space_translate(&address_space_memory, addr, &addr, &l, + false); + if (l < 4) { + return -1; + } if (!(memory_region_is_ram(section->mr) || memory_region_is_romd(section->mr))) { /* I/O case */ - addr = memory_region_section_addr(section, addr); val = io_mem_read(section->mr, addr, 4); #if defined(TARGET_WORDS_BIGENDIAN) if (endian == DEVICE_LITTLE_ENDIAN) { @@ -2249,7 +2240,7 @@ static inline uint32_t ldl_phys_internal(hwaddr addr, /* RAM case */ ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK) - + memory_region_section_addr(section, addr)); + + addr); switch (endian) { case DEVICE_LITTLE_ENDIAN: val = ldl_le_p(ptr); @@ -2287,13 +2278,17 @@ static inline uint64_t ldq_phys_internal(hwaddr addr, uint8_t *ptr; uint64_t val; MemoryRegionSection *section; + hwaddr l = 8; - section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS); + section = address_space_translate(&address_space_memory, addr, &addr, &l, + false); + if (l < 8) { + return -1; + } if (!(memory_region_is_ram(section->mr) || memory_region_is_romd(section->mr))) { /* I/O case */ - addr = memory_region_section_addr(section, addr); /* XXX This is broken when device endian != cpu endian. Fix and add "endian" variable check */ @@ -2308,7 +2303,7 @@ static inline uint64_t ldq_phys_internal(hwaddr addr, /* RAM case */ ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK) - + memory_region_section_addr(section, addr)); + + addr); switch (endian) { case DEVICE_LITTLE_ENDIAN: val = ldq_le_p(ptr); @@ -2354,13 +2349,17 @@ static inline uint32_t lduw_phys_internal(hwaddr addr, uint8_t *ptr; uint64_t val; MemoryRegionSection *section; + hwaddr l = 2; - section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS); + section = address_space_translate(&address_space_memory, addr, &addr, &l, + false); + if (l < 2) { + return -1; + } if (!(memory_region_is_ram(section->mr) || memory_region_is_romd(section->mr))) { /* I/O case */ - addr = memory_region_section_addr(section, addr); val = io_mem_read(section->mr, addr, 2); #if defined(TARGET_WORDS_BIGENDIAN) if (endian == DEVICE_LITTLE_ENDIAN) { @@ -2375,7 +2374,7 @@ static inline uint32_t lduw_phys_internal(hwaddr addr, /* RAM case */ ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK) - + memory_region_section_addr(section, addr)); + + addr); switch (endian) { case DEVICE_LITTLE_ENDIAN: val = lduw_le_p(ptr); @@ -2413,11 +2412,15 @@ void stl_phys_notdirty(hwaddr addr, uint32_t val) { uint8_t *ptr; MemoryRegionSection *section; + hwaddr l = 2; - section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS); + section = address_space_translate(&address_space_memory, addr, &addr, &l, + true); + if (l < 2) { + return; + } if (!memory_region_is_ram(section->mr) || section->readonly) { - addr = memory_region_section_addr(section, addr); if (memory_region_is_ram(section->mr)) { section = &phys_sections[phys_section_rom]; } @@ -2425,7 +2428,7 @@ void stl_phys_notdirty(hwaddr addr, uint32_t val) } else { unsigned long addr1 = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK) - + memory_region_section_addr(section, addr); + + addr; ptr = qemu_get_ram_ptr(addr1); stl_p(ptr, val); @@ -2445,11 +2448,15 @@ void stq_phys_notdirty(hwaddr addr, uint64_t val) { uint8_t *ptr; MemoryRegionSection *section; + hwaddr l = 4; - section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS); + section = address_space_translate(&address_space_memory, addr, &addr, &l, + true); + if (l < 4) { + return; + } if (!memory_region_is_ram(section->mr) || section->readonly) { - addr = memory_region_section_addr(section, addr); if (memory_region_is_ram(section->mr)) { section = &phys_sections[phys_section_rom]; } @@ -2463,7 +2470,7 @@ void stq_phys_notdirty(hwaddr addr, uint64_t val) } else { ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK) - + memory_region_section_addr(section, addr)); + + addr); stq_p(ptr, val); } } @@ -2474,11 +2481,15 @@ static inline void stl_phys_internal(hwaddr addr, uint32_t val, { uint8_t *ptr; MemoryRegionSection *section; + hwaddr l = 8; - section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS); + section = address_space_translate(&address_space_memory, addr, &addr, &l, + true); + if (l < 8) { + return; + } if (!memory_region_is_ram(section->mr) || section->readonly) { - addr = memory_region_section_addr(section, addr); if (memory_region_is_ram(section->mr)) { section = &phys_sections[phys_section_rom]; } @@ -2495,7 +2506,7 @@ static inline void stl_phys_internal(hwaddr addr, uint32_t val, } else { unsigned long addr1; addr1 = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK) - + memory_region_section_addr(section, addr); + + addr; /* RAM case */ ptr = qemu_get_ram_ptr(addr1); switch (endian) { @@ -2541,11 +2552,15 @@ static inline void stw_phys_internal(hwaddr addr, uint32_t val, { uint8_t *ptr; MemoryRegionSection *section; + hwaddr l = 4; - section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS); + section = address_space_translate(&address_space_memory, addr, &addr, &l, + true); + if (l < 4) { + return; + } if (!memory_region_is_ram(section->mr) || section->readonly) { - addr = memory_region_section_addr(section, addr); if (memory_region_is_ram(section->mr)) { section = &phys_sections[phys_section_rom]; } @@ -2562,7 +2577,7 @@ static inline void stw_phys_internal(hwaddr addr, uint32_t val, } else { unsigned long addr1; addr1 = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK) - + memory_region_section_addr(section, addr); + + addr; /* RAM case */ ptr = qemu_get_ram_ptr(addr1); switch (endian) { @@ -2666,9 +2681,10 @@ bool virtio_is_big_endian(void) bool cpu_physical_memory_is_io(hwaddr phys_addr) { MemoryRegionSection *section; + hwaddr l = 1; - section = phys_page_find(address_space_memory.dispatch, - phys_addr >> TARGET_PAGE_BITS); + section = address_space_translate(&address_space_memory, + phys_addr, &phys_addr, &l, false); return !(memory_region_is_ram(section->mr) || memory_region_is_romd(section->mr)); diff --git a/include/exec/cputlb.h b/include/exec/cputlb.h index 733c885..e821660 100644 --- a/include/exec/cputlb.h +++ b/include/exec/cputlb.h @@ -26,8 +26,6 @@ void tlb_unprotect_code_phys(CPUArchState *env, ram_addr_t ram_addr, target_ulong vaddr); void tlb_reset_dirty_range(CPUTLBEntry *tlb_entry, uintptr_t start, uintptr_t length); -MemoryRegionSection *phys_page_find(struct AddressSpaceDispatch *d, - hwaddr index); void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length); void tlb_set_dirty(CPUArchState *env, target_ulong vaddr); extern int tlb_flush_count; @@ -35,11 +33,11 @@ extern int tlb_flush_count; /* exec.c */ void tb_flush_jmp_cache(CPUArchState *env, target_ulong addr); hwaddr memory_region_section_get_iotlb(CPUArchState *env, - MemoryRegionSection *section, - target_ulong vaddr, - hwaddr paddr, - int prot, - target_ulong *address); + MemoryRegionSection *section, + target_ulong vaddr, + hwaddr paddr, hwaddr xlat, + int prot, + target_ulong *address); bool memory_region_is_unassigned(MemoryRegion *mr); #endif diff --git a/include/exec/memory.h b/include/exec/memory.h index c38e974..914f5d4 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -740,23 +740,6 @@ MemoryRegionSection memory_region_find(MemoryRegion *mr, hwaddr addr, uint64_t size); /** - * memory_region_section_addr: get offset within MemoryRegionSection - * - * Returns offset within MemoryRegionSection - * - * @section: the memory region section being queried - * @addr: address in address space - */ -static inline hwaddr -memory_region_section_addr(MemoryRegionSection *section, - hwaddr addr) -{ - addr -= section->offset_within_address_space; - addr += section->offset_within_region; - return addr; -} - -/** * address_space_sync_dirty_bitmap: synchronize the dirty log for all memory * * Synchronizes the dirty page log for an entire address space. @@ -857,6 +840,20 @@ void address_space_write(AddressSpace *as, hwaddr addr, */ void address_space_read(AddressSpace *as, hwaddr addr, uint8_t *buf, int len); +/* address_space_translate: translate an address range into an address space + * into a MemoryRegionSection and an address range into that section + * + * @as: #AddressSpace to be accessed + * @addr: address within that address space + * @xlat: pointer to address within the returned memory region section's + * #MemoryRegion. + * @len: pointer to length + * @is_write: indicates the transfer direction + */ +MemoryRegionSection *address_space_translate(AddressSpace *as, hwaddr addr, + hwaddr *xlat, hwaddr *len, + bool is_write); + /* address_space_valid: check for validity of an address space range * * Check whether access to the given address space range is permitted by diff --git a/translate-all.c b/translate-all.c index 0d84b0d..7a7d537 100644 --- a/translate-all.c +++ b/translate-all.c @@ -1355,15 +1355,15 @@ void tb_invalidate_phys_addr(hwaddr addr) { ram_addr_t ram_addr; MemoryRegionSection *section; + hwaddr l = 1; - section = phys_page_find(address_space_memory.dispatch, - addr >> TARGET_PAGE_BITS); + section = address_space_translate(&address_space_memory, addr, &addr, &l, false); if (!(memory_region_is_ram(section->mr) || memory_region_is_romd(section->mr))) { return; } ram_addr = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK) - + memory_region_section_addr(section, addr); + + addr; tb_invalidate_phys_page_range(ram_addr, ram_addr + 1, 0); } #endif /* TARGET_HAS_ICE && !defined(CONFIG_USER_ONLY) */