Since this device bypasses PCI and registers I/O ports directly with the system bus, it needs further attention. Signed-off-by: Avi Kivity <avi@xxxxxxxxxx> --- hw/xen_platform.c | 110 ++++++++++++++++++++++++++++++++++++---------------- 1 files changed, 76 insertions(+), 34 deletions(-) diff --git a/hw/xen_platform.c b/hw/xen_platform.c index b167eee..b5da08f 100644 --- a/hw/xen_platform.c +++ b/hw/xen_platform.c @@ -51,6 +51,9 @@ typedef struct PCIXenPlatformState { PCIDevice pci_dev; + MemoryRegion fixed_io; + MemoryRegion bar; + MemoryRegion mmio_bar; uint8_t flags; /* used only for version_id == 2 */ int drivers_blacklisted; uint16_t driver_product_version; @@ -173,6 +176,35 @@ static uint32_t platform_fixed_ioport_readb(void *opaque, uint32_t addr) } } +static uint64_t platform_fixed_ioport_read(void *opaque, + target_phys_addr_t addr, + unsigned size) +{ + addr += XEN_PLATFORM_IOPORT; + + switch (size) { + case 1: return platform_fixed_ioport_readb(opaque, addr); + case 2: return platform_fixed_ioport_readw(opaque, addr); + case 4: return -1u; + default: abort(); + } +} + +static void platform_fixed_ioport_write(void *opaque, + target_phys_addr_t addr, + uint64_t data, + unsigned size) +{ + addr += XEN_PLATFORM_IOPORT; + + switch (size) { + case 1: return platform_fixed_ioport_writeb(opaque, addr, data); + case 2: return platform_fixed_ioport_writew(opaque, addr, data); + case 4: return platform_fixed_ioport_writel(opaque, addr, data); + default: abort(); + } +} + static void platform_fixed_ioport_reset(void *opaque) { PCIXenPlatformState *s = opaque; @@ -180,21 +212,27 @@ static void platform_fixed_ioport_reset(void *opaque) platform_fixed_ioport_writeb(s, XEN_PLATFORM_IOPORT, 0); } +static MemoryRegionOps platform_fixed_io_ops = { + .read = platform_fixed_ioport_read, + .write = platform_fixed_ioport_write, + .endianness = DEVICE_NATIVE_ENDIAN, +}; + +#include "exec-memory.h" + static void platform_fixed_ioport_init(PCIXenPlatformState* s) { - register_ioport_write(XEN_PLATFORM_IOPORT, 16, 4, platform_fixed_ioport_writel, s); - register_ioport_write(XEN_PLATFORM_IOPORT, 16, 2, platform_fixed_ioport_writew, s); - register_ioport_write(XEN_PLATFORM_IOPORT, 16, 1, platform_fixed_ioport_writeb, s); - register_ioport_read(XEN_PLATFORM_IOPORT, 16, 2, platform_fixed_ioport_readw, s); - register_ioport_read(XEN_PLATFORM_IOPORT, 16, 1, platform_fixed_ioport_readb, s); + memory_region_init_io(&s->fixed_io, &platform_fixed_io_ops, s, + "xen-fixed", 16); + memory_region_add_subregion(get_system_io(), XEN_PLATFORM_IOPORT, + &s->fixed_io); } /* Xen Platform PCI Device */ -static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr) +static uint64_t xen_platform_ioport_read(void *opaque, target_phys_addr_t addr, + unsigned size) { - addr &= 0xff; - if (addr == 0) { return platform_fixed_ioport_readb(opaque, XEN_PLATFORM_IOPORT); } else { @@ -202,13 +240,11 @@ static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr) } } -static void xen_platform_ioport_writeb(void *opaque, uint32_t addr, uint32_t val) +static void xen_platform_ioport_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { PCIXenPlatformState *s = opaque; - addr &= 0xff; - val &= 0xff; - switch (addr) { case 0: /* Platform flags */ platform_fixed_ioport_writeb(opaque, XEN_PLATFORM_IOPORT, val); @@ -221,15 +257,23 @@ static void xen_platform_ioport_writeb(void *opaque, uint32_t addr, uint32_t val } } -static void platform_ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr, pcibus_t size, int type) -{ - PCIXenPlatformState *d = DO_UPCAST(PCIXenPlatformState, pci_dev, pci_dev); +static MemoryRegionOps xen_pci_io_ops = { + .read = xen_platform_ioport_read, + .write = xen_platform_ioport_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 1, + .max_access_size = 1, + }, +}; - register_ioport_write(addr, size, 1, xen_platform_ioport_writeb, d); - register_ioport_read(addr, size, 1, xen_platform_ioport_readb, d); +static void platform_ioport_bar_setup(PCIXenPlatformState *d) +{ + memory_region_init_io(&d->bar, &xen_pci_io_ops, d, "xen-pci", 0x100); } -static uint32_t platform_mmio_read(ReadWriteHandler *handler, pcibus_t addr, int len) +static uint64_t platform_mmio_read(void *opaque, target_phys_addr_t addr, + unsigned size) { DPRINTF("Warning: attempted read from physical address " "0x" TARGET_FMT_plx " in xen platform mmio space\n", addr); @@ -237,28 +281,24 @@ static uint32_t platform_mmio_read(ReadWriteHandler *handler, pcibus_t addr, int return 0; } -static void platform_mmio_write(ReadWriteHandler *handler, pcibus_t addr, - uint32_t val, int len) +static void platform_mmio_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { - DPRINTF("Warning: attempted write of 0x%x to physical " + DPRINTF("Warning: attempted write of 0x%"PRIx64" to physical " "address 0x" TARGET_FMT_plx " in xen platform mmio space\n", val, addr); } -static ReadWriteHandler platform_mmio_handler = { +static MemoryRegionOps platform_mmio_handler = { .read = &platform_mmio_read, .write = &platform_mmio_write, + .endianness = DEVICE_NATIVE_ENDIAN, }; -static void platform_mmio_map(PCIDevice *d, int region_num, - pcibus_t addr, pcibus_t size, int type) +static void platform_mmio_setup(PCIXenPlatformState *d) { - int mmio_io_addr; - - mmio_io_addr = cpu_register_io_memory_simple(&platform_mmio_handler, - DEVICE_NATIVE_ENDIAN); - - cpu_register_physical_memory(addr, size, mmio_io_addr); + memory_region_init_io(&d->mmio_bar, &platform_mmio_handler, d, + "xen-mmio", 0x1000000); } static int xen_platform_post_load(void *opaque, int version_id) @@ -304,12 +344,14 @@ static int xen_platform_initfn(PCIDevice *dev) pci_conf[PCI_INTERRUPT_PIN] = 1; - pci_register_bar(&d->pci_dev, 0, 0x100, - PCI_BASE_ADDRESS_SPACE_IO, platform_ioport_map); + platform_ioport_bar_setup(d); + pci_register_bar_region(&d->pci_dev, 0, + PCI_BASE_ADDRESS_SPACE_IO, &d->bar); /* reserve 16MB mmio address for share memory*/ - pci_register_bar(&d->pci_dev, 1, 0x1000000, - PCI_BASE_ADDRESS_MEM_PREFETCH, platform_mmio_map); + platform_mmio_setup(d); + pci_register_bar_region(&d->pci_dev, 1, + PCI_BASE_ADDRESS_MEM_PREFETCH, &d->mmio_bar); platform_fixed_ioport_init(d); -- 1.7.5.3 -- 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