mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 08:13:54 -06:00
memory: per-AddressSpace dispatch
Currently we use a global radix tree to dispatch memory access. This only works with a single address space; to support multiple address spaces we make the radix tree a member of AddressSpace (via an intermediate structure AddressSpaceDispatch to avoid exposing too many internals). A side effect is that address_space_io also gains a dispatch table. When we remove all the pre-memory-API I/O registrations, we can use that for dispatching I/O and get rid of the original I/O dispatch. Signed-off-by: Avi Kivity <avi@redhat.com>
This commit is contained in:
parent
0e8a6d47af
commit
ac1970fbe8
6 changed files with 194 additions and 71 deletions
62
memory.h
62
memory.h
|
@ -169,6 +169,7 @@ struct AddressSpace {
|
|||
struct FlatView *current_map;
|
||||
int ioeventfd_nb;
|
||||
struct MemoryRegionIoeventfd *ioeventfds;
|
||||
struct AddressSpaceDispatch *dispatch;
|
||||
QTAILQ_ENTRY(AddressSpace) address_spaces_link;
|
||||
};
|
||||
|
||||
|
@ -803,6 +804,67 @@ void mtree_info(fprintf_function mon_printf, void *f);
|
|||
*/
|
||||
void address_space_init(AddressSpace *as, MemoryRegion *root);
|
||||
|
||||
/**
|
||||
* address_space_rw: read from or write to an address space.
|
||||
*
|
||||
* @as: #AddressSpace to be accessed
|
||||
* @addr: address within that address space
|
||||
* @buf: buffer with the data transferred
|
||||
* @is_write: indicates the transfer direction
|
||||
*/
|
||||
void address_space_rw(AddressSpace *as, target_phys_addr_t addr, uint8_t *buf,
|
||||
int len, bool is_write);
|
||||
|
||||
/**
|
||||
* address_space_write: write to address space.
|
||||
*
|
||||
* @as: #AddressSpace to be accessed
|
||||
* @addr: address within that address space
|
||||
* @buf: buffer with the data transferred
|
||||
*/
|
||||
void address_space_write(AddressSpace *as, target_phys_addr_t addr,
|
||||
const uint8_t *buf, int len);
|
||||
|
||||
/**
|
||||
* address_space_read: read from an address space.
|
||||
*
|
||||
* @as: #AddressSpace to be accessed
|
||||
* @addr: address within that address space
|
||||
* @buf: buffer with the data transferred
|
||||
*/
|
||||
void address_space_read(AddressSpace *as, target_phys_addr_t addr, uint8_t *buf, int len);
|
||||
|
||||
/* address_space_map: map a physical memory region into a host virtual address
|
||||
*
|
||||
* May map a subset of the requested range, given by and returned in @plen.
|
||||
* May return %NULL if resources needed to perform the mapping are exhausted.
|
||||
* Use only for reads OR writes - not for read-modify-write operations.
|
||||
* Use cpu_register_map_client() to know when retrying the map operation is
|
||||
* likely to succeed.
|
||||
*
|
||||
* @as: #AddressSpace to be accessed
|
||||
* @addr: address within that address space
|
||||
* @plen: pointer to length of buffer; updated on return
|
||||
* @is_write: indicates the transfer direction
|
||||
*/
|
||||
void *address_space_map(AddressSpace *as, target_phys_addr_t addr,
|
||||
target_phys_addr_t *plen, bool is_write);
|
||||
|
||||
/* address_space_unmap: Unmaps a memory region previously mapped by address_space_map()
|
||||
*
|
||||
* Will also mark the memory as dirty if @is_write == %true. @access_len gives
|
||||
* the amount of memory that was actually read or written by the caller.
|
||||
*
|
||||
* @as: #AddressSpace used
|
||||
* @addr: address within that address space
|
||||
* @len: buffer length as returned by address_space_map()
|
||||
* @access_len: amount of data actually transferred
|
||||
* @is_write: indicates the transfer direction
|
||||
*/
|
||||
void address_space_unmap(AddressSpace *as, void *buffer, target_phys_addr_t len,
|
||||
int is_write, target_phys_addr_t access_len);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue