Re: [Qemu-devel] [RFC v1] Add declarations for hierarchical memory region API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, May 19, 2011 at 5:12 PM, Avi Kivity <avi@xxxxxxxxxx> wrote:
> The memory API separates the attributes of a memory region (its size, how
> reads or writes are handled, dirty logging, and coalescing) from where it
> is mapped and whether it is enabled. ÂThis allows a device to configure
> a memory region once, then hand it off to its parent bus to map it according
> to the bus configuration.
>
> Hierarchical registration also allows a device to compose a region out of
> a number of sub-regions with different properties; for example some may be
> RAM while others may be MMIO.
>
> Signed-off-by: Avi Kivity <avi@xxxxxxxxxx>
> ---
> Âmemory.h | Â142 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> Â1 files changed, 142 insertions(+), 0 deletions(-)
> Âcreate mode 100644 memory.h
>
> diff --git a/memory.h b/memory.h
> new file mode 100644
> index 0000000..77c5951
> --- /dev/null
> +++ b/memory.h
> @@ -0,0 +1,142 @@
> +#ifndef MEMORY_H
> +#define MEMORY_H
> +
> +#include <stdint.h>
> +#include <stdbool.h>
> +#include "qemu-common.h"
> +#include "cpu-common.h"
> +#include "targphys.h"
> +#include "qemu-queue.h"
> +
> +typedef struct MemoryRegionOps MemoryRegionOps;
> +typedef struct MemoryRegion MemoryRegion;
> +
> +/*
> + * Memory region callbacks
> + */
> +struct MemoryRegionOps {
> + Â Â/* Read from the memory region. @addr is relative to @mr; @size is
> + Â Â * in bytes. */
> + Â Âuint64_t (*read)(MemoryRegion *mr,
> + Â Â Â Â Â Â Â Â Â Â target_phys_addr_t addr,
> + Â Â Â Â Â Â Â Â Â Â unsigned size);
> + Â Â/* Write to the memory region. @addr is relative to @mr; @size is
> + Â Â * in bytes. */
> + Â Âvoid (*write)(MemoryRegion *mr,
> + Â Â Â Â Â Â Â Â Âtarget_phys_addr_t addr,
> + Â Â Â Â Â Â Â Â Âuint64_t data,
> + Â Â Â Â Â Â Â Â Âunsigned size);
> + Â Â/* Guest-visible constraints: */
> + Â Âstruct {
> + Â Â Â Â/* If nonzero, specify bounds on access sizes beyond which a machine
> + Â Â Â Â * check is thrown.
> + Â Â Â Â */
> + Â Â Â Âunsigned min_access_size;
> + Â Â Â Âunsigned max_access_size;
> + Â Â Â Â/* If true, unaligned accesses are supported. ÂOtherwise unaligned
> + Â Â Â Â * accesses throw machine checks.
> + Â Â Â Â */
> + Â Â Â Â bool unaligned;
> + Â Â} valid;
> + Â Â/* Internal implementation constraints: */
> + Â Âstruct {
> + Â Â Â Â/* If nonzero, specifies the minimum size implemented. ÂSmaller sizes
> + Â Â Â Â * will be rounded upwards and a partial result will be returned.
> + Â Â Â Â */
> + Â Â Â Âunsigned min_access_size;
> + Â Â Â Â/* If nonzero, specifies the maximum size implemented. ÂLarger sizes
> + Â Â Â Â * will be done as a series of accesses with smaller sizes.
> + Â Â Â Â */
> + Â Â Â Âunsigned max_access_size;
> + Â Â Â Â/* If true, unaligned accesses are supported. ÂOtherwise all accesses
> + Â Â Â Â * are converted to (possibly multiple) naturally aligned accesses.
> + Â Â Â Â */
> + Â Â Â Â bool unaligned;
> + Â Â} impl;
> +};
> +
> +typedef struct CoalescedMemoryRange CoalescedMemoryRange;
> +
> +struct CoalescedMemoryRange {
> + Â Âtarget_phys_addr_t start;
> + Â Âtarget_phys_addr_t size;
> + Â ÂQTAILQ_ENTRY(coalesced_ranges) link;
> +};
> +
> +struct MemoryRegion {
> + Â Â/* All fields are private - violators will be prosecuted */
> + Â Âconst MemoryRegionOps *ops;
> + Â ÂMemoryRegion *parent;
> + Â Âtarget_phys_addr_t size;
> + Â Âtarget_phys_addr_t addr;
> + Â Âram_addr_t ram_addr;
> + Â Âunsigned priority;
> + Â Âbool may_overlap;
> + Â ÂQTAILQ_HEAD(subregions, MemoryRegion) subregions;
> + Â ÂQTAILQ_ENTRY(subregions) subregions_link;
> + Â ÂQTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced;
> +};
> +
> +/* Initialize a memory region
> + *
> + * The region typically acts as a container for other memory regions.
> + */
> +void memory_region_init(MemoryRegion *mr,
> + Â Â Â Â Â Â Â Â Â Â Â Âtarget_phys_addr_t size);
> +/* Initialize an I/O memory region. ÂAccesses into the region will be
> + * cause the callbacks in @ops to be called.
> + *
> + * if @size is nonzero, subregions will be clipped to @size.
> + */
> +void memory_region_init_io(MemoryRegion *mr,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â const MemoryRegionOps *ops,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â target_phys_addr_t size);
> +/* Initialize an I/O memory region. ÂAccesses into the region will be
> + * modify memory directly.
> + */
> +void memory_region_init_ram(MemoryRegion *mr,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Âtarget_phys_addr_t size);
> +/* Initialize a RAM memory region. ÂAccesses into the region will be
> + * modify memory in @ptr directly.
> + */
> +void memory_region_init_ram_ptr(MemoryRegion *mr,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âtarget_phys_addr_t size,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âvoid *ptr);
> +/* Destroy a memory region. ÂThe memory becomes inaccessible. */
> +void memory_region_destroy(MemoryRegion *mr);

Doesn't the lower priority region become accessible instead in some cases?

> +/* Sets an offset to be added to MemoryRegionOps callbacks. */
> +void memory_region_set_offset(MemoryRegion *mr, target_phys_addr_t offset);
> +/* Turn loggging on or off for specified client (display, migration) */

g--

> +void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client);
> +/* Enable memory coalescing for the region. ÂMMIO ->write callbacks may be
> + * delayed until a non-coalesced MMIO is issued.
> + */
> +void memory_region_set_coalescing(MemoryRegion *mr);
> +/* Enable memory coalescing for a sub-range of the region. ÂMMIO ->write
> + * callbacks may be delayed until a non-coalesced MMIO is issued.
> + */
> +void memory_region_add_coalescing(MemoryRegion *mr,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âtarget_phys_addr_t offset,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âtarget_phys_addr_t size);
> +/* Disable MMIO coalescing for the region. */
> +void memory_region_clear_coalescing(MemoryRegion *mr);

Perhaps the interface could be more generic, like
+void memory_region_set_property(MemoryRegion *mr, unsigned flags);
+void memory_region_clear_property(MemoryRegion *mr, unsigned flags);

> +
> +/* Add a sub-region at @offset. ÂThe sub-region may not overlap with other
> + * subregions (except for those explicitly marked as overlapping)
> + */
> +void memory_region_add_subregion(MemoryRegion *mr,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â target_phys_addr_t offset,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â MemoryRegion *subregion);
> +/* Add a sub-region at @offset. ÂThe sun-region may overlap other subregions;

Sunny regions?

> + * conflicts are resolved by having a higher @priority hide a lower @priority.
> + * Subregions without priority are taken as @priority 0.
> + */
> +void memory_region_add_subregion_overlap(MemoryRegion *mr,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â target_phys_addr_t offset,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â MemoryRegion *subregion,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â unsigned priority);
> +/* Remove a subregion. */
> +void memory_region_del_subregion(MemoryRegion *mr,
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â MemoryRegion *subregion);

What would the subregions be used for?
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux