From: Blue Swirl <blauwirbel@gmail.com>
To: Richard Henderson <rth@twiddle.net>
Cc: paul@codesourcery.com, agraf@suse.de, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 0/2] [RFC] 64-bit io paths
Date: Fri, 23 Apr 2010 21:30:48 +0300 [thread overview]
Message-ID: <p2pf43fc5581004231130qaf3f21b3v7d9196ba58909045@mail.gmail.com> (raw)
In-Reply-To: <4BD0BD6E.4010000@twiddle.net>
On 4/23/10, Richard Henderson <rth@twiddle.net> wrote:
> On 04/22/2010 01:01 PM, Blue Swirl wrote:
> >> This is also fine. Although by using NULL all you'd get is a qemu
> >> null pointer dereference; I suppose this might get caught and
> >> translated to an cpu exception, but I think it would be preferable
> >> long-term to be more explicit about this and fill in the entries
> >> with a function that would explicitly raise the exception.
> >
> > Perhaps also the bus layer could do something here.
>
>
> What do you mean?
If we had a bus layer that handled conversion from bus width to device
width (discussed earlier), it could as well handle the cases where
instead of conversion, a bus error should be reported.
> > Interesting. Could you make a summary of the design for the benefit of the list?
>
>
> The basic device interface looks like
>
> +/* Object based memory region registration. */
> +
> +typedef struct MemoryRegion MemoryRegion;
> +
> +typedef uint32_t MemoryCallbackRead(MemoryRegion *, target_phys_addr_t ofs);
> +typedef uint64_t MemoryCallbackRead64(MemoryRegion *, target_phys_addr_t ofs);
> +typedef void MemoryCallbackWrite(MemoryRegion *, target_phys_addr_t ofs,
> + uint32_t val);
> +typedef void MemoryCallbackWrite64(MemoryRegion *, target_phys_addr_t ofs,
> + uint64_t val);
> +
> +typedef struct MemoryCallbackInfo {
> + MemoryCallbackRead *read8;
> + MemoryCallbackRead *read16;
> + MemoryCallbackRead *read32;
> + MemoryCallbackRead64 *read64;
> +
> + MemoryCallbackWrite *write8;
> + MemoryCallbackWrite *write16;
> + MemoryCallbackWrite *write32;
> + MemoryCallbackWrite64 *write64;
> +
> + /* This describes RAM. The callbacks above need not be used, and
> + the host memory backing the RAM begins at qemu_get_ram_ptr_r. */
> + _Bool ram;
> +
> + /* Legacy shim: propagate the IO_MEM_ROMD bit. */
> + _Bool romd;
> +} MemoryCallbackInfo;
> +
> +/* This structure describes the region. It is logically opaque -- drivers
> + should not be peeking inside. But in the interest of efficiency we want
> + to directly embed this structure in the driver's private strucure. In
> + this way we can avoid having to have an extra table of opaque pointers
> + for consumption by the driver. The intended use is
> +
> + struct FooDeviceState {
> + DeviceState qdev;
> + MemoryRegion mem_region;
> + ...
> + };
> +
> + static uint32_t foo_read8(MemoryRegion *region, target_phys_addr_t ofs)
> + {
> + FooDeviceState *s = container_of(region, FooDeviceState, mem_region);
> + ...
> + }
> +*/
> +
> +struct MemoryRegion {
> + const MemoryCallbackInfo *cb;
> + target_phys_addr_t start;
> + target_phys_addr_t size;
> +
> + /* If this value is not -1, this memory region is registred in
> + the io_mem_region array, used by softmmu_header.h to resolve
> + memory-mapped operations in the guest address space. */
> + int io_index;
> +};
> +
> +/* Register a memory region at START_ADDR/SIZE. The REGION structure will
> + be initialized appropriately for DEV using CB as the operation set. */
> +extern void cpu_register_memory_region(MemoryRegion *region,
> + const MemoryCallbackInfo *cb,
> + target_phys_addr_t start_addr,
> + target_phys_addr_t size);
> +
> +/* Unregister a memory region. */
> +extern void cpu_unregister_memory_region(MemoryRegion *);
> +
> +/* Allocate ram for use with cpu_register_memory_region. */
> +extern const MemoryCallbackInfo *qemu_ram_alloc_r(ram_addr_t);
> +extern void qemu_ram_free_r(const MemoryCallbackInfo *);
>
> The Basic Idea is that we have a MemoryRegion object that describes
> a contiguous mapping within the guest address space. This object
> needs to handle RAM, ROM and devices. The desire to handle memory
> and devices the same comes from the wish to have PCI device BARs
> show up as plain memory in the TLB as plain memory, and to be able
> to handle all PCI device regions identically within sysbus.
>
> There are a number of restrictions on the interface above what we
> currently support:
>
> * Objects may not be mapped over the top of existing objects.
> This is most abused by pflash devices with their IO_MEM_ROMD thing.
Perhaps with small changes we could make this design stackable, so
that a device providing a bus inside another bus could use the same
registration functions, only the bus handle would change. Like:
upa = bus_register_memory_region(cpu_bus,,);
pci = bus_register_memory_region(upa,,);
ebus = bus_register_memory_region(pci,,):
ide = bus_register_memory_region(ebus,,):
Currently "cpu_bus" is always implicit and pci has separate
registration functions.
I'd suppose that ROMD, subpages and unassigned memory handlers could
be implemented by stacking instead of special casing them.
> * Objects must be unmapped explicitly, rather than mapping
> IO_MEM_UNASSIGNED over the top of an object. This is most
> abused by the PCI subsystem.
>
> The use of the MemoryRegion pointer doubling as the device's opaque
> pointer means that it's easy to implement generic helpers such as
>
> uint64_t composite_read64(MemoryRegion *region, target_phys_addr_t ofs)
> {
> uint32_t v1 = region->cb->read32(region, ofs);
> uint32_t v2 = region->cb->read32(region, ofs + 4);
>
> return combine_for_target_endian(v1, v2);
> }
>
> or even
>
> uin32_t invalid_read8(MemoryRegion *region, target_phys_addr_t ofs)
> {
> do_unassigned_access(region->start + ofs, 0, 0, 0, 1);
> return 0;
> }
>
> without having to have supplementary opaque pointer caches, as we
> currently do for e.g. subpage_t.
>
> These can be entered into the device's MemoryCallbackInfo structure
> so that we're sure that there's defined semantics for every access,
> and the device need not invent its own invalid_read functions as
> quite a few do now.
>
> I will admit that I do not yet have a good replacement for IO_MEM_ROMD,
> or toggling the read-only bit on a RAM region. Or even for the way
> that pc.c allocates RAM around the 640k-1M hole.
Read-only bit could be implemented in the stackable design by creating
a simple bus which can suppress writes when configured so, The device
behind would be just RAM.
Likewise for PC RAM mapping, the memory controller provides a bus
where the addresses may be twisted as needed before passing to
underlying RAM.
However, the outcome of the Generic DMA discussions (last year?) was
that instead of read/write functions, a mapping API would be better
because then we have the possibility to do zero copy DMA. Perhaps the
same applies here, too. This would be a bigger change obviously but if
there will be widespread changes to devices, it would be nice to get
this right.
next prev parent reply other threads:[~2010-04-23 18:30 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-04-20 20:26 [Qemu-devel] [PATCH 0/2] [RFC] 64-bit io paths Richard Henderson
2010-04-20 19:54 ` [Qemu-devel] [PATCH 1/2] io: Add CPUIOMemoryOps and use it Richard Henderson
2010-04-20 20:22 ` [Qemu-devel] [PATCH 2/2] io: Add readq/writeq hooks and use them Richard Henderson
2010-04-22 19:38 ` [Qemu-devel] [PATCH 0/2] [RFC] 64-bit io paths Blue Swirl
2010-04-22 19:55 ` Richard Henderson
2010-04-22 20:01 ` Blue Swirl
2010-04-22 21:19 ` Richard Henderson
2010-04-23 18:30 ` Blue Swirl [this message]
2010-05-28 20:45 ` Paul Brook
2010-04-22 23:47 ` [Qemu-devel] [PATCH] Remove IO_MEM_SUBWIDTH Richard Henderson
2010-04-25 15:06 ` [Qemu-devel] " Blue Swirl
2010-04-26 21:54 ` Artyom Tarasenko
2010-04-27 18:30 ` Richard Henderson
2010-04-28 19:29 ` Artyom Tarasenko
2010-05-06 20:25 ` Artyom Tarasenko
2010-05-07 15:28 ` Blue Swirl
2010-05-07 16:52 ` [Qemu-devel] [PATCH] Fill in unassigned mem read/write callbacks Richard Henderson
2010-05-07 17:02 ` [Qemu-devel] " Blue Swirl
-- strict thread matches above, loose matches on Subject: below --
2010-05-28 21:03 [Qemu-devel] [PATCH 0/2] [RFC] 64-bit io paths Paul Brook
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=p2pf43fc5581004231130qaf3f21b3v7d9196ba58909045@mail.gmail.com \
--to=blauwirbel@gmail.com \
--cc=agraf@suse.de \
--cc=paul@codesourcery.com \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).