X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=memory.h;h=64d2b341b6dae88c980af528124c6a7fc7b63055;hb=95d2994a2f756c9c8684709421d40c45e63e4e04;hp=70f57fbc12d1625840c973936c87f7504a01bddc;hpb=c47f3223658119219bbe0b8d09da733d1c06e76f;p=qemu.git diff --git a/memory.h b/memory.h index 70f57fbc1..64d2b341b 100644 --- a/memory.h +++ b/memory.h @@ -43,6 +43,14 @@ struct MemoryRegionMmio { CPUWriteMemoryFunc *write[3]; }; +/* Internal use; thunks between old-style IORange and MemoryRegions. */ +typedef struct MemoryRegionIORange MemoryRegionIORange; +struct MemoryRegionIORange { + IORange iorange; + MemoryRegion *mr; + target_phys_addr_t offset; +}; + /* * Memory region callbacks */ @@ -115,10 +123,8 @@ struct MemoryRegion { MemoryRegion *parent; Int128 size; target_phys_addr_t addr; - target_phys_addr_t offset; void (*destructor)(MemoryRegion *mr); ram_addr_t ram_addr; - IORange iorange; bool subpage; bool terminates; bool readable; @@ -126,6 +132,8 @@ struct MemoryRegion { bool readonly; /* For RAM regions */ bool enabled; bool rom_device; + bool warning_printed; /* For reservations */ + bool flush_coalesced_mmio; MemoryRegion *alias; target_phys_addr_t alias_offset; unsigned priority; @@ -149,6 +157,21 @@ struct MemoryRegionPortio { #define PORTIO_END_OF_LIST() { } +typedef struct AddressSpace AddressSpace; + +/** + * AddressSpace: describes a mapping of addresses to #MemoryRegion objects + */ +struct AddressSpace { + /* All fields are private. */ + const char *name; + MemoryRegion *root; + struct FlatView *current_map; + int ioeventfd_nb; + struct MemoryRegionIoeventfd *ioeventfds; + QTAILQ_ENTRY(AddressSpace) address_spaces_link; +}; + typedef struct MemoryRegionSection MemoryRegionSection; /** @@ -160,6 +183,7 @@ typedef struct MemoryRegionSection MemoryRegionSection; * @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 + * @readonly: writes to this section are ignored */ struct MemoryRegionSection { MemoryRegion *mr; @@ -167,6 +191,7 @@ struct MemoryRegionSection { target_phys_addr_t offset_within_region; uint64_t size; target_phys_addr_t offset_within_address_space; + bool readonly; }; typedef struct MemoryListener MemoryListener; @@ -178,14 +203,28 @@ typedef struct MemoryListener MemoryListener; * Use with memory_listener_register() and memory_listener_unregister(). */ struct MemoryListener { + void (*begin)(MemoryListener *listener); + void (*commit)(MemoryListener *listener); void (*region_add)(MemoryListener *listener, MemoryRegionSection *section); void (*region_del)(MemoryListener *listener, MemoryRegionSection *section); + void (*region_nop)(MemoryListener *listener, MemoryRegionSection *section); void (*log_start)(MemoryListener *listener, MemoryRegionSection *section); void (*log_stop)(MemoryListener *listener, MemoryRegionSection *section); void (*log_sync)(MemoryListener *listener, MemoryRegionSection *section); void (*log_global_start)(MemoryListener *listener); void (*log_global_stop)(MemoryListener *listener); - QLIST_ENTRY(MemoryListener) link; + void (*eventfd_add)(MemoryListener *listener, MemoryRegionSection *section, + bool match_data, uint64_t data, EventNotifier *e); + void (*eventfd_del)(MemoryListener *listener, MemoryRegionSection *section, + bool match_data, uint64_t data, EventNotifier *e); + void (*coalesced_mmio_add)(MemoryListener *listener, MemoryRegionSection *section, + target_phys_addr_t addr, target_phys_addr_t len); + void (*coalesced_mmio_del)(MemoryListener *listener, MemoryRegionSection *section, + target_phys_addr_t addr, target_phys_addr_t len); + /* Lower = earlier (during add), later (during del) */ + unsigned priority; + MemoryRegion *address_space_filter; + QTAILQ_ENTRY(MemoryListener) link; }; /** @@ -233,9 +272,9 @@ void memory_region_init_ram(MemoryRegion *mr, uint64_t size); /** - * memory_region_init_ram: Initialize RAM memory region from a user-provided. - * pointer. Accesses into the region will modify - * memory directly. + * memory_region_init_ram_ptr: Initialize RAM memory region from a + * user-provided pointer. Accesses into the + * region will modify memory directly. * * @mr: the #MemoryRegion to be initialized. * @name: the name of the region. @@ -279,6 +318,21 @@ void memory_region_init_rom_device(MemoryRegion *mr, const char *name, uint64_t size); +/** + * memory_region_init_reservation: Initialize a memory region that reserves + * I/O space. + * + * A reservation region primariy serves debugging purposes. It claims I/O + * space that is not supposed to be handled by QEMU itself. Any access via + * the memory API will cause an abort(). + * + * @mr: the #MemoryRegion to be initialized + * @name: used for debugging; not visible to the user or ABI + * @size: size of the region. + */ +void memory_region_init_reservation(MemoryRegion *mr, + const char *name, + uint64_t size); /** * memory_region_destroy: Destroy a memory region and reclaim all resources. * @@ -304,6 +358,19 @@ uint64_t memory_region_size(MemoryRegion *mr); */ bool memory_region_is_ram(MemoryRegion *mr); +/** + * memory_region_is_romd: check whether a memory region is ROMD + * + * Returns %true is a memory region is ROMD and currently set to allow + * direct reads. + * + * @mr: the memory region being queried + */ +static inline bool memory_region_is_romd(MemoryRegion *mr) +{ + return mr->rom_device && mr->readable; +} + /** * memory_region_name: get a memory region's name * @@ -342,14 +409,6 @@ bool memory_region_is_rom(MemoryRegion *mr); */ void *memory_region_get_ram_ptr(MemoryRegion *mr); -/** - * memory_region_set_offset: Sets an offset to be added to MemoryRegionOps - * callbacks. - * - * This function is deprecated and should not be used in new code. - */ -void memory_region_set_offset(MemoryRegion *mr, target_phys_addr_t offset); - /** * memory_region_set_log: Turn dirty logging on or off for a region. * @@ -364,30 +423,34 @@ void memory_region_set_offset(MemoryRegion *mr, target_phys_addr_t offset); void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client); /** - * memory_region_get_dirty: Check whether a page is dirty for a specified - * client. + * memory_region_get_dirty: Check whether a range of bytes is dirty + * for a specified client. * - * Checks whether a page has been written to since the last + * Checks whether a range of bytes has been written to since the last * call to memory_region_reset_dirty() with the same @client. Dirty logging * must be enabled. * * @mr: the memory region being queried. * @addr: the address (relative to the start of the region) being queried. + * @size: the size of the range being queried. * @client: the user of the logging information; %DIRTY_MEMORY_MIGRATION or * %DIRTY_MEMORY_VGA. */ bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t addr, - unsigned client); + target_phys_addr_t size, unsigned client); /** - * memory_region_set_dirty: Mark a page as dirty in a memory region. + * memory_region_set_dirty: Mark a range of bytes as dirty in a memory region. * - * Marks a page as dirty, after it has been dirtied outside guest code. + * Marks a range of bytes as dirty, after it has been dirtied outside + * guest code. * - * @mr: the memory region being queried. + * @mr: the memory region being dirtied. * @addr: the address (relative to the start of the region) being dirtied. + * @size: size of the range being dirtied. */ -void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr); +void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr, + target_phys_addr_t size); /** * memory_region_sync_dirty_bitmap: Synchronize a region's dirty bitmap with @@ -477,6 +540,31 @@ void memory_region_add_coalescing(MemoryRegion *mr, */ void memory_region_clear_coalescing(MemoryRegion *mr); +/** + * memory_region_set_flush_coalesced: Enforce memory coalescing flush before + * accesses. + * + * Ensure that pending coalesced MMIO request are flushed before the memory + * region is accessed. This property is automatically enabled for all regions + * passed to memory_region_set_coalescing() and memory_region_add_coalescing(). + * + * @mr: the memory region to be updated. + */ +void memory_region_set_flush_coalesced(MemoryRegion *mr); + +/** + * memory_region_clear_flush_coalesced: Disable memory coalescing flush before + * accesses. + * + * Clear the automatic coalesced MMIO flushing enabled via + * memory_region_set_flush_coalesced. Note that this service has no effect on + * memory regions that have MMIO coalescing enabled for themselves. For them, + * automatic flushing will stop once coalescing is disabled. + * + * @mr: the memory region to be updated. + */ +void memory_region_clear_flush_coalesced(MemoryRegion *mr); + /** * memory_region_add_eventfd: Request an eventfd to be triggered when a word * is written to a location. @@ -498,7 +586,7 @@ void memory_region_add_eventfd(MemoryRegion *mr, unsigned size, bool match_data, uint64_t data, - int fd); + EventNotifier *e); /** * memory_region_del_eventfd: Cancel an eventfd. @@ -518,7 +606,8 @@ void memory_region_del_eventfd(MemoryRegion *mr, unsigned size, bool match_data, uint64_t data, - int fd); + EventNotifier *e); + /** * memory_region_add_subregion: Add a subregion to a container. * @@ -537,7 +626,8 @@ void memory_region_add_subregion(MemoryRegion *mr, target_phys_addr_t offset, MemoryRegion *subregion); /** - * memory_region_add_subregion: Add a subregion to a container, with overlap. + * memory_region_add_subregion_overlap: Add a subregion to a container + * with overlap. * * Adds a subregion at @offset. The subregion may overlap with other * subregions. Conflicts are resolved by having a higher @priority hide a @@ -561,7 +651,7 @@ void memory_region_add_subregion_overlap(MemoryRegion *mr, * memory_region_get_ram_addr: Get the ram address associated with a memory * region * - * DO NOT USE THIS FUCNTION. This is a temporary workaround while the Xen + * DO NOT USE THIS FUNCTION. This is a temporary workaround while the Xen * code is being reworked. */ ram_addr_t memory_region_get_ram_addr(MemoryRegion *mr); @@ -636,6 +726,22 @@ void memory_region_set_alias_offset(MemoryRegion *mr, MemoryRegionSection memory_region_find(MemoryRegion *address_space, target_phys_addr_t 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 target_phys_addr_t +memory_region_section_addr(MemoryRegionSection *section, + target_phys_addr_t addr) +{ + addr -= section->offset_within_address_space; + addr += section->offset_within_region; + return addr; +} /** * memory_global_sync_dirty_bitmap: synchronize the dirty log for all memory @@ -650,7 +756,7 @@ void memory_global_sync_dirty_bitmap(MemoryRegion *address_space); * memory_region_transaction_begin: Start a transaction. * * During a transaction, changes will be accumulated and made visible - * only when the transaction ends (is commited). + * only when the transaction ends (is committed). */ void memory_region_transaction_begin(void); @@ -666,8 +772,9 @@ void memory_region_transaction_commit(void); * space * * @listener: an object containing the callbacks to be called + * @filter: if non-%NULL, only regions in this address space will be observed */ -void memory_listener_register(MemoryListener *listener); +void memory_listener_register(MemoryListener *listener, MemoryRegion *filter); /** * memory_listener_unregister: undo the effect of memory_listener_register() @@ -682,12 +789,20 @@ void memory_listener_unregister(MemoryListener *listener); void memory_global_dirty_log_start(void); /** - * memory_global_dirty_log_stop: begin dirty logging for all regions + * memory_global_dirty_log_stop: end dirty logging for all regions */ void memory_global_dirty_log_stop(void); void mtree_info(fprintf_function mon_printf, void *f); +/** + * address_space_init: initializes an address space + * + * @as: an uninitialized #AddressSpace + * @root: a #MemoryRegion that routes addesses for the address space + */ +void address_space_init(AddressSpace *as, MemoryRegion *root); + #endif #endif