qemu-devel
[Top][All Lists]
Advanced

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

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


From: Blue Swirl
Subject: Re: [Qemu-devel] [RFC v1] Add declarations for hierarchical memory region API
Date: Fri, 20 May 2011 20:59:44 +0300

On Thu, May 19, 2011 at 5:12 PM, Avi Kivity <address@hidden> 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 <address@hidden>
> ---
>  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?



reply via email to

[Prev in Thread] Current Thread [Next in Thread]