From e2177955a899483b19bd54e547db3b61db95eaf7 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Thu, 8 Dec 2011 15:00:18 +0200 Subject: memory: introduce memory_region_find() Given an address space (represented by the top-level memory region), returns the memory region that maps a given range. Useful for implementing DMA. The implementation is a simplistic binary search. Once we have a tree representation this can be optimized. Signed-off-by: Avi Kivity --- memory.h | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'memory.h') diff --git a/memory.h b/memory.h index 87fb9740c7..4d8f39ad09 100644 --- a/memory.h +++ b/memory.h @@ -148,6 +148,24 @@ struct MemoryRegionPortio { #define PORTIO_END_OF_LIST() { } +typedef struct MemoryRegionSection MemoryRegionSection; + +/** + * MemoryRegionSection: describes a fragment of a #MemoryRegion + * + * @mr: the region, or %NULL if empty + * @offset_within_region: the beginning of the section, relative to @mr's start + * @size: the size of the section; will not exceed @mr's boundaries + * @offset_within_address_space: the address of the first byte of the section + * relative to the region's address space + */ +struct MemoryRegionSection { + MemoryRegion *mr; + target_phys_addr_t offset_within_region; + uint64_t size; + target_phys_addr_t offset_within_address_space; +}; + /** * memory_region_init: Initialize a memory region * @@ -568,6 +586,27 @@ void memory_region_set_address(MemoryRegion *mr, target_phys_addr_t addr); void memory_region_set_alias_offset(MemoryRegion *mr, target_phys_addr_t offset); +/** + * memory_region_find: locate a MemoryRegion in an address space + * + * Locates the first #MemoryRegion within an address space given by + * @address_space that overlaps the range given by @addr and @size. + * + * Returns a #MemoryRegionSection that describes a contiguous overlap. + * It will have the following characteristics: + * .@offset_within_address_space >= @addr + * .@offset_within_address_space + .@size <= @addr + @size + * .@size = 0 iff no overlap was found + * .@mr is non-%NULL iff an overlap was found + * + * @address_space: a top-level (i.e. parentless) region that contains + * the region to be found + * @addr: start of the area within @address_space to be searched + * @size: size of the area to be searched + */ +MemoryRegionSection memory_region_find(MemoryRegion *address_space, + target_phys_addr_t addr, uint64_t size); + /** * memory_region_transaction_begin: Start a transaction. * -- cgit v1.2.3-55-g7522