aboutsummaryrefslogtreecommitdiff
path: root/memory.h
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2012-10-03 16:22:53 +0200
committerAvi Kivity <avi@redhat.com>2012-10-22 14:50:08 +0200
commitac1970fbe8ad5a70174f462109ac0f6c7bf1bc43 (patch)
treeaa2f9702bfd593515b6fb7ee438f6cc5bacef74e /memory.h
parent0e8a6d47afcc88564079387928f2da45736d36e8 (diff)
downloadqemu-ac1970fbe8ad5a70174f462109ac0f6c7bf1bc43.zip
qemu-ac1970fbe8ad5a70174f462109ac0f6c7bf1bc43.tar.gz
qemu-ac1970fbe8ad5a70174f462109ac0f6c7bf1bc43.tar.bz2
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>
Diffstat (limited to 'memory.h')
-rw-r--r--memory.h62
1 files changed, 62 insertions, 0 deletions
diff --git a/memory.h b/memory.h
index f5a13a4..d36c2ba 100644
--- a/memory.h
+++ b/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