Alexander Graf
2012-Oct-08 12:23 UTC
[PATCH 00/14] Remove old_portio users for memory region PIO mapping
When running on PowerPC, we don''t have native PIO support. There are a few hacks around to enable PIO access on PowerPC nevertheless. The most typical one is the isa-mmio device. It takes MMIO requests and converts them to PIO requests on the (QEMU internal) PIO bus. This however is not how real hardware works and it limits us in the ability to spawn eventfd''s on PIO ports which doesn''t work with this approach. Instead, let''s model it more easily. Let''s just map the PIO memory region into MMIO space. For this to work, we need to get rid of all old_portio struct users, as they break with this approach. This is what this patch set does. It also converts the e500 machines and sPAPR to the new memory region model. Alex Alexander Graf (14): ac97: convert PIO to new memory api read/write virtio-pci: convert PIO to new memory api read/write es1370: convert PIO to new memory api read/write i8254: convert PIO to new memory api read/write m48t59: convert PIO to new memory api read/write mc146818rtc: convert PIO to new memory api read/write pc port92: convert PIO to new memory api read/write pckbd: convert PIO to new memory api read/write rtl8139: convert PIO to new memory api read/write serial: convert PIO to new memory api read/write vmport: convert PIO to new memory api read/write xen_platform: convert PIO to new memory api read/write PPC: e500: Map PIO space into core memory region PPC: pseries: Remove hack for PIO window hw/ac97.c | 109 +++++++++++++++++++++++++++++++++++++-------- hw/es1370.c | 46 +++++++++++++++---- hw/i8254.c | 20 +++++---- hw/m48t59.c | 24 ++++++---- hw/mc146818rtc.c | 19 +++++--- hw/pc.c | 19 +++++--- hw/pckbd.c | 48 +++++++++++--------- hw/ppc/e500.c | 3 +- hw/ppce500_pci.c | 9 +++- hw/rtl8139.c | 78 +++++++++++++++------------------ hw/serial.c | 31 ++++++++----- hw/spapr_pci.c | 44 +------------------ hw/spapr_pci.h | 2 +- hw/virtio-pci.c | 126 ++++++++++++++++++++-------------------------------- hw/vmport.c | 21 +++++---- hw/xen_platform.c | 48 ++++++++++++++++---- 16 files changed, 362 insertions(+), 285 deletions(-)
Alexander Graf
2012-Oct-08 12:23 UTC
[PATCH 01/14] ac97: convert PIO to new memory api read/write
Signed-off-by: Alexander Graf <agraf@suse.de> --- hw/ac97.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 89 insertions(+), 20 deletions(-) diff --git a/hw/ac97.c b/hw/ac97.c index 0f561fa..c1cc3dd 100644 --- a/hw/ac97.c +++ b/hw/ac97.c @@ -1226,32 +1226,101 @@ static const VMStateDescription vmstate_ac97 = { } }; -static const MemoryRegionPortio nam_portio[] = { - { 0, 256 * 1, 1, .read = nam_readb, }, - { 0, 256 * 2, 2, .read = nam_readw, }, - { 0, 256 * 4, 4, .read = nam_readl, }, - { 0, 256 * 1, 1, .write = nam_writeb, }, - { 0, 256 * 2, 2, .write = nam_writew, }, - { 0, 256 * 4, 4, .write = nam_writel, }, - PORTIO_END_OF_LIST (), -}; +static uint64_t nam_read(void *opaque, target_phys_addr_t addr, unsigned size) +{ + if ((addr / size) > 256) { + return -1; + } + + switch (size) { + case 1: + return nam_readb(opaque, addr); + case 2: + return nam_readw(opaque, addr); + case 4: + return nam_readl(opaque, addr); + default: + return -1; + } +} + +static void nam_write(void *opaque, target_phys_addr_t addr, uint64_t val, + unsigned size) +{ + if ((addr / size) > 256) { + return; + } + + switch (size) { + case 1: + nam_writeb(opaque, addr, val); + break; + case 2: + nam_writew(opaque, addr, val); + break; + case 4: + nam_writel(opaque, addr, val); + break; + } +} static const MemoryRegionOps ac97_io_nam_ops = { - .old_portio = nam_portio, + .read = nam_read, + .write = nam_write, + .impl = { + .min_access_size = 1, + .max_access_size = 4, + }, + .endianness = DEVICE_LITTLE_ENDIAN, }; -static const MemoryRegionPortio nabm_portio[] = { - { 0, 64 * 1, 1, .read = nabm_readb, }, - { 0, 64 * 2, 2, .read = nabm_readw, }, - { 0, 64 * 4, 4, .read = nabm_readl, }, - { 0, 64 * 1, 1, .write = nabm_writeb, }, - { 0, 64 * 2, 2, .write = nabm_writew, }, - { 0, 64 * 4, 4, .write = nabm_writel, }, - PORTIO_END_OF_LIST () -}; +static uint64_t nabm_read(void *opaque, target_phys_addr_t addr, unsigned size) +{ + if ((addr / size) > 64) { + return -1; + } + + switch (size) { + case 1: + return nabm_readb(opaque, addr); + case 2: + return nabm_readw(opaque, addr); + case 4: + return nabm_readl(opaque, addr); + default: + return -1; + } +} + +static void nabm_write(void *opaque, target_phys_addr_t addr, uint64_t val, + unsigned size) +{ + if ((addr / size) > 64) { + return; + } + + switch (size) { + case 1: + nabm_writeb(opaque, addr, val); + break; + case 2: + nabm_writew(opaque, addr, val); + break; + case 4: + nabm_writel(opaque, addr, val); + break; + } +} + static const MemoryRegionOps ac97_io_nabm_ops = { - .old_portio = nabm_portio, + .read = nabm_read, + .write = nabm_write, + .impl = { + .min_access_size = 1, + .max_access_size = 4, + }, + .endianness = DEVICE_LITTLE_ENDIAN, }; static void ac97_on_reset (void *opaque) -- 1.6.0.2
Alexander Graf
2012-Oct-08 12:23 UTC
[PATCH 02/14] virtio-pci: convert PIO to new memory api read/write
Signed-off-by: Alexander Graf <agraf@suse.de> --- hw/virtio-pci.c | 126 +++++++++++++++++++++--------------------------------- 1 files changed, 49 insertions(+), 77 deletions(-) diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c index 400f3c2..e28254f 100644 --- a/hw/virtio-pci.c +++ b/hw/virtio-pci.c @@ -374,79 +374,39 @@ static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr) return ret; } -static uint32_t virtio_pci_config_readb(void *opaque, uint32_t addr) -{ - VirtIOPCIProxy *proxy = opaque; - uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); - if (addr < config) - return virtio_ioport_read(proxy, addr); - addr -= config; - return virtio_config_readb(proxy->vdev, addr); -} - -static uint32_t virtio_pci_config_readw(void *opaque, uint32_t addr) -{ - VirtIOPCIProxy *proxy = opaque; - uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); - uint16_t val; - if (addr < config) - return virtio_ioport_read(proxy, addr); - addr -= config; - val = virtio_config_readw(proxy->vdev, addr); - if (virtio_is_big_endian()) { - /* - * virtio is odd, ioports are LE but config space is target native - * endian. However, in qemu, all PIO is LE, so we need to re-swap - * on BE targets - */ - val = bswap16(val); - } - return val; -} - -static uint32_t virtio_pci_config_readl(void *opaque, uint32_t addr) -{ - VirtIOPCIProxy *proxy = opaque; - uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); - uint32_t val; - if (addr < config) - return virtio_ioport_read(proxy, addr); - addr -= config; - val = virtio_config_readl(proxy->vdev, addr); - if (virtio_is_big_endian()) { - val = bswap32(val); - } - return val; -} - -static void virtio_pci_config_writeb(void *opaque, uint32_t addr, uint32_t val) +static uint64_t virtio_pci_config_read(void *opaque, target_phys_addr_t addr, + unsigned size) { VirtIOPCIProxy *proxy = opaque; uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); + uint64_t val = 0; if (addr < config) { - virtio_ioport_write(proxy, addr, val); - return; + return virtio_ioport_read(proxy, addr); } addr -= config; - virtio_config_writeb(proxy->vdev, addr, val); -} -static void virtio_pci_config_writew(void *opaque, uint32_t addr, uint32_t val) -{ - VirtIOPCIProxy *proxy = opaque; - uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); - if (addr < config) { - virtio_ioport_write(proxy, addr, val); - return; - } - addr -= config; - if (virtio_is_big_endian()) { - val = bswap16(val); + switch (size) { + case 1: + val = virtio_config_readb(proxy->vdev, addr); + break; + case 2: + val = virtio_config_readw(proxy->vdev, addr); + if (virtio_is_big_endian()) { + val = bswap16(val); + } + break; + case 4: + val = virtio_config_readl(proxy->vdev, addr); + if (virtio_is_big_endian()) { + val = bswap32(val); + } + break; } - virtio_config_writew(proxy->vdev, addr, val); + return val; } -static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val) +static void virtio_pci_config_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { VirtIOPCIProxy *proxy = opaque; uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); @@ -455,24 +415,36 @@ static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val) return; } addr -= config; - if (virtio_is_big_endian()) { - val = bswap32(val); + /* + * Virtio-PCI is odd. Ioports are LE but config space is target native + * endian. + */ + switch (size) { + case 1: + virtio_config_writeb(proxy->vdev, addr, val); + break; + case 2: + if (virtio_is_big_endian()) { + val = bswap16(val); + } + virtio_config_writew(proxy->vdev, addr, val); + break; + case 4: + if (virtio_is_big_endian()) { + val = bswap32(val); + } + virtio_config_writel(proxy->vdev, addr, val); + break; } - virtio_config_writel(proxy->vdev, addr, val); } -static const MemoryRegionPortio virtio_portio[] = { - { 0, 0x10000, 1, .write = virtio_pci_config_writeb, }, - { 0, 0x10000, 2, .write = virtio_pci_config_writew, }, - { 0, 0x10000, 4, .write = virtio_pci_config_writel, }, - { 0, 0x10000, 1, .read = virtio_pci_config_readb, }, - { 0, 0x10000, 2, .read = virtio_pci_config_readw, }, - { 0, 0x10000, 4, .read = virtio_pci_config_readl, }, - PORTIO_END_OF_LIST() -}; - static const MemoryRegionOps virtio_pci_config_ops = { - .old_portio = virtio_portio, + .read = virtio_pci_config_read, + .write = virtio_pci_config_write, + .impl = { + .min_access_size = 1, + .max_access_size = 4, + }, .endianness = DEVICE_LITTLE_ENDIAN, }; -- 1.6.0.2
Alexander Graf
2012-Oct-08 12:23 UTC
[PATCH 03/14] es1370: convert PIO to new memory api read/write
Signed-off-by: Alexander Graf <agraf@suse.de> --- hw/es1370.c | 46 ++++++++++++++++++++++++++++++++++++---------- 1 files changed, 36 insertions(+), 10 deletions(-) diff --git a/hw/es1370.c b/hw/es1370.c index e34234c..308f2c2 100644 --- a/hw/es1370.c +++ b/hw/es1370.c @@ -908,18 +908,44 @@ static void es1370_adc_callback (void *opaque, int avail) es1370_run_channel (s, ADC_CHANNEL, avail); } -static const MemoryRegionPortio es1370_portio[] = { - { 0, 0x40 * 4, 1, .write = es1370_writeb, }, - { 0, 0x40 * 2, 2, .write = es1370_writew, }, - { 0, 0x40, 4, .write = es1370_writel, }, - { 0, 0x40 * 4, 1, .read = es1370_readb, }, - { 0, 0x40 * 2, 2, .read = es1370_readw, }, - { 0, 0x40, 4, .read = es1370_readl, }, - PORTIO_END_OF_LIST () -}; +static uint64_t es1370_read(void *opaque, target_phys_addr_t addr, + unsigned size) +{ + switch (size) { + case 1: + return es1370_readb(opaque, addr); + case 2: + return es1370_readw(opaque, addr); + case 4: + return es1370_readl(opaque, addr); + default: + return -1; + } +} + +static void es1370_write(void *opaque, target_phys_addr_t addr, uint64_t val, + unsigned size) +{ + switch (size) { + case 1: + es1370_writeb(opaque, addr, val); + break; + case 2: + es1370_writew(opaque, addr, val); + break; + case 4: + es1370_writel(opaque, addr, val); + break; + } +} static const MemoryRegionOps es1370_io_ops = { - .old_portio = es1370_portio, + .read = es1370_read, + .write = es1370_write, + .impl = { + .min_access_size = 1, + .max_access_size = 4, + }, .endianness = DEVICE_LITTLE_ENDIAN, }; -- 1.6.0.2
Alexander Graf
2012-Oct-08 12:23 UTC
[PATCH 04/14] i8254: convert PIO to new memory api read/write
Signed-off-by: Alexander Graf <agraf@suse.de> --- hw/i8254.c | 20 +++++++++++--------- 1 files changed, 11 insertions(+), 9 deletions(-) diff --git a/hw/i8254.c b/hw/i8254.c index 77bd5e8..cea8d13 100644 --- a/hw/i8254.c +++ b/hw/i8254.c @@ -111,7 +111,8 @@ static void pit_latch_count(PITChannelState *s) } } -static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val) +static void pit_ioport_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { PITCommonState *pit = opaque; int channel, access; @@ -178,7 +179,8 @@ static void pit_ioport_write(void *opaque, uint32_t addr, uint32_t val) } } -static uint32_t pit_ioport_read(void *opaque, uint32_t addr) +static uint64_t pit_ioport_read(void *opaque, target_phys_addr_t addr, + unsigned size) { PITCommonState *pit = opaque; int ret, count; @@ -290,14 +292,14 @@ static void pit_irq_control(void *opaque, int n, int enable) } } -static const MemoryRegionPortio pit_portio[] = { - { 0, 4, 1, .write = pit_ioport_write }, - { 0, 3, 1, .read = pit_ioport_read }, - PORTIO_END_OF_LIST() -}; - static const MemoryRegionOps pit_ioport_ops = { - .old_portio = pit_portio + .read = pit_ioport_read, + .write = pit_ioport_write, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, + .endianness = DEVICE_LITTLE_ENDIAN, }; static void pit_post_load(PITCommonState *s) -- 1.6.0.2
Alexander Graf
2012-Oct-08 12:23 UTC
[PATCH 05/14] m48t59: convert PIO to new memory api read/write
Signed-off-by: Alexander Graf <agraf@suse.de> --- hw/m48t59.c | 24 ++++++++++++++---------- 1 files changed, 14 insertions(+), 10 deletions(-) diff --git a/hw/m48t59.c b/hw/m48t59.c index dd6cb37..389f6c9 100644 --- a/hw/m48t59.c +++ b/hw/m48t59.c @@ -27,6 +27,7 @@ #include "sysemu.h" #include "sysbus.h" #include "isa.h" +#include "exec-memory.h" //#define DEBUG_NVRAM @@ -80,6 +81,7 @@ typedef struct M48t59ISAState { typedef struct M48t59SysBusState { SysBusDevice busdev; M48t59State state; + MemoryRegion io; } M48t59SysBusState; /* Fake timer functions */ @@ -481,7 +483,8 @@ void m48t59_toggle_lock (void *opaque, int lock) } /* IO access to NVRAM */ -static void NVRAM_writeb (void *opaque, uint32_t addr, uint32_t val) +static void NVRAM_writeb(void *opaque, target_phys_addr_t addr, uint64_t val, + unsigned size) { M48t59State *NVRAM = opaque; @@ -504,7 +507,7 @@ static void NVRAM_writeb (void *opaque, uint32_t addr, uint32_t val) } } -static uint32_t NVRAM_readb (void *opaque, uint32_t addr) +static uint64_t NVRAM_readb(void *opaque, target_phys_addr_t addr, unsigned size) { M48t59State *NVRAM = opaque; uint32_t retval; @@ -626,13 +629,14 @@ static void m48t59_reset_sysbus(DeviceState *d) m48t59_reset_common(NVRAM); } -static const MemoryRegionPortio m48t59_portio[] = { - {0, 4, 1, .read = NVRAM_readb, .write = NVRAM_writeb }, - PORTIO_END_OF_LIST(), -}; - static const MemoryRegionOps m48t59_io_ops = { - .old_portio = m48t59_portio, + .read = NVRAM_readb, + .write = NVRAM_writeb, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, + .endianness = DEVICE_LITTLE_ENDIAN, }; /* Initialisation routine */ @@ -653,9 +657,9 @@ M48t59State *m48t59_init(qemu_irq IRQ, target_phys_addr_t mem_base, d = FROM_SYSBUS(M48t59SysBusState, s); state = &d->state; sysbus_connect_irq(s, 0, IRQ); + memory_region_init_io(&d->io, &m48t59_io_ops, state, "m48t59", 4); if (io_base != 0) { - register_ioport_read(io_base, 0x04, 1, NVRAM_readb, state); - register_ioport_write(io_base, 0x04, 1, NVRAM_writeb, state); + memory_region_add_subregion(get_system_io(), io_base, &d->io); } if (mem_base != 0) { sysbus_mmio_map(s, 0, mem_base); -- 1.6.0.2
Alexander Graf
2012-Oct-08 12:23 UTC
[PATCH 06/14] mc146818rtc: convert PIO to new memory api read/write
Signed-off-by: Alexander Graf <agraf@suse.de> --- hw/mc146818rtc.c | 19 +++++++++++-------- 1 files changed, 11 insertions(+), 8 deletions(-) diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c index 332a77d..670f826 100644 --- a/hw/mc146818rtc.c +++ b/hw/mc146818rtc.c @@ -383,7 +383,8 @@ static void rtc_update_timer(void *opaque) check_update_timer(s); } -static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data) +static void cmos_ioport_write(void *opaque, target_phys_addr_t addr, + uint64_t data, unsigned size) { RTCState *s = opaque; @@ -595,7 +596,8 @@ static int update_in_progress(RTCState *s) return 0; } -static uint32_t cmos_ioport_read(void *opaque, uint32_t addr) +static uint64_t cmos_ioport_read(void *opaque, target_phys_addr_t addr, + unsigned size) { RTCState *s = opaque; int ret; @@ -769,13 +771,14 @@ static void rtc_reset(void *opaque) #endif } -static const MemoryRegionPortio cmos_portio[] = { - {0, 2, 1, .read = cmos_ioport_read, .write = cmos_ioport_write }, - PORTIO_END_OF_LIST(), -}; - static const MemoryRegionOps cmos_ops = { - .old_portio = cmos_portio + .read = cmos_ioport_read, + .write = cmos_ioport_write, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, + .endianness = DEVICE_LITTLE_ENDIAN, }; static void rtc_get_date(Object *obj, Visitor *v, void *opaque, -- 1.6.0.2
Alexander Graf
2012-Oct-08 12:23 UTC
[PATCH 07/14] pc port92: convert PIO to new memory api read/write
Signed-off-by: Alexander Graf <agraf@suse.de> --- hw/pc.c | 19 +++++++++++-------- 1 files changed, 11 insertions(+), 8 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index 7e7e0e2..9eb1230 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -422,7 +422,8 @@ typedef struct Port92State { qemu_irq *a20_out; } Port92State; -static void port92_write(void *opaque, uint32_t addr, uint32_t val) +static void port92_write(void *opaque, target_phys_addr_t addr, uint64_t val, + unsigned size) { Port92State *s = opaque; @@ -434,7 +435,8 @@ static void port92_write(void *opaque, uint32_t addr, uint32_t val) } } -static uint32_t port92_read(void *opaque, uint32_t addr) +static uint64_t port92_read(void *opaque, target_phys_addr_t addr, + unsigned size) { Port92State *s = opaque; uint32_t ret; @@ -469,13 +471,14 @@ static void port92_reset(DeviceState *d) s->outport &= ~1; } -static const MemoryRegionPortio port92_portio[] = { - { 0, 1, 1, .read = port92_read, .write = port92_write }, - PORTIO_END_OF_LIST(), -}; - static const MemoryRegionOps port92_ops = { - .old_portio = port92_portio + .read = port92_read, + .write = port92_write, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, + .endianness = DEVICE_LITTLE_ENDIAN, }; static int port92_initfn(ISADevice *dev) -- 1.6.0.2
Alexander Graf
2012-Oct-08 12:23 UTC
[PATCH 08/14] pckbd: convert PIO to new memory api read/write
Signed-off-by: Alexander Graf <agraf@suse.de> --- hw/pckbd.c | 48 +++++++++++++++++++++++++++--------------------- 1 files changed, 27 insertions(+), 21 deletions(-) diff --git a/hw/pckbd.c b/hw/pckbd.c index 69857ba..2c78f7d 100644 --- a/hw/pckbd.c +++ b/hw/pckbd.c @@ -194,7 +194,8 @@ static void kbd_update_aux_irq(void *opaque, int level) kbd_update_irq(s); } -static uint32_t kbd_read_status(void *opaque, uint32_t addr) +static uint64_t kbd_read_status(void *opaque, target_phys_addr_t addr, + unsigned size) { KBDState *s = opaque; int val; @@ -223,7 +224,8 @@ static void outport_write(KBDState *s, uint32_t val) } } -static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val) +static void kbd_write_command(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { KBDState *s = opaque; @@ -303,12 +305,13 @@ static void kbd_write_command(void *opaque, uint32_t addr, uint32_t val) /* ignore that */ break; default: - fprintf(stderr, "qemu: unsupported keyboard cmd=0x%02x\n", val); + fprintf(stderr, "qemu: unsupported keyboard cmd=0x%02x\n", (int)val); break; } } -static uint32_t kbd_read_data(void *opaque, uint32_t addr) +static uint64_t kbd_read_data(void *opaque, target_phys_addr_t addr, + unsigned size) { KBDState *s = opaque; uint32_t val; @@ -322,7 +325,8 @@ static uint32_t kbd_read_data(void *opaque, uint32_t addr) return val; } -static void kbd_write_data(void *opaque, uint32_t addr, uint32_t val) +static void kbd_write_data(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { KBDState *s = opaque; @@ -385,9 +389,9 @@ static uint32_t kbd_mm_readb (void *opaque, target_phys_addr_t addr) KBDState *s = opaque; if (addr & s->mask) - return kbd_read_status(s, 0) & 0xff; + return kbd_read_status(s, 0, 1) & 0xff; else - return kbd_read_data(s, 0) & 0xff; + return kbd_read_data(s, 0, 1) & 0xff; } static void kbd_mm_writeb (void *opaque, target_phys_addr_t addr, uint32_t value) @@ -395,9 +399,9 @@ static void kbd_mm_writeb (void *opaque, target_phys_addr_t addr, uint32_t value KBDState *s = opaque; if (addr & s->mask) - kbd_write_command(s, 0, value & 0xff); + kbd_write_command(s, 0, value & 0xff, 1); else - kbd_write_data(s, 0, value & 0xff); + kbd_write_data(s, 0, value & 0xff, 1); } static const MemoryRegionOps i8042_mmio_ops = { @@ -459,22 +463,24 @@ static const VMStateDescription vmstate_kbd_isa = { } }; -static const MemoryRegionPortio i8042_data_portio[] = { - { 0, 1, 1, .read = kbd_read_data, .write = kbd_write_data }, - PORTIO_END_OF_LIST() -}; - -static const MemoryRegionPortio i8042_cmd_portio[] = { - { 0, 1, 1, .read = kbd_read_status, .write = kbd_write_command }, - PORTIO_END_OF_LIST() -}; - static const MemoryRegionOps i8042_data_ops = { - .old_portio = i8042_data_portio + .read = kbd_read_data, + .write = kbd_write_data, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, + .endianness = DEVICE_LITTLE_ENDIAN, }; static const MemoryRegionOps i8042_cmd_ops = { - .old_portio = i8042_cmd_portio + .read = kbd_read_status, + .write = kbd_write_command, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, + .endianness = DEVICE_LITTLE_ENDIAN, }; static int i8042_initfn(ISADevice *dev) -- 1.6.0.2
Alexander Graf
2012-Oct-08 12:23 UTC
[PATCH 09/14] rtl8139: convert PIO to new memory api read/write
Signed-off-by: Alexander Graf <agraf@suse.de> --- hw/rtl8139.c | 78 ++++++++++++++++++++++++++------------------------------- 1 files changed, 36 insertions(+), 42 deletions(-) diff --git a/hw/rtl8139.c b/hw/rtl8139.c index b7c82ee..6be6883 100644 --- a/hw/rtl8139.c +++ b/hw/rtl8139.c @@ -3186,38 +3186,6 @@ static uint32_t rtl8139_io_readl(void *opaque, uint8_t addr) /* */ -static void rtl8139_ioport_writeb(void *opaque, uint32_t addr, uint32_t val) -{ - rtl8139_io_writeb(opaque, addr & 0xFF, val); -} - -static void rtl8139_ioport_writew(void *opaque, uint32_t addr, uint32_t val) -{ - rtl8139_io_writew(opaque, addr & 0xFF, val); -} - -static void rtl8139_ioport_writel(void *opaque, uint32_t addr, uint32_t val) -{ - rtl8139_io_writel(opaque, addr & 0xFF, val); -} - -static uint32_t rtl8139_ioport_readb(void *opaque, uint32_t addr) -{ - return rtl8139_io_readb(opaque, addr & 0xFF); -} - -static uint32_t rtl8139_ioport_readw(void *opaque, uint32_t addr) -{ - return rtl8139_io_readw(opaque, addr & 0xFF); -} - -static uint32_t rtl8139_ioport_readl(void *opaque, uint32_t addr) -{ - return rtl8139_io_readl(opaque, addr & 0xFF); -} - -/* */ - static void rtl8139_mmio_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) { rtl8139_io_writeb(opaque, addr & 0xFF, val); @@ -3381,18 +3349,44 @@ static const VMStateDescription vmstate_rtl8139 = { /***********************************************************/ /* PCI RTL8139 definitions */ -static const MemoryRegionPortio rtl8139_portio[] = { - { 0, 0x100, 1, .read = rtl8139_ioport_readb, }, - { 0, 0x100, 1, .write = rtl8139_ioport_writeb, }, - { 0, 0x100, 2, .read = rtl8139_ioport_readw, }, - { 0, 0x100, 2, .write = rtl8139_ioport_writew, }, - { 0, 0x100, 4, .read = rtl8139_ioport_readl, }, - { 0, 0x100, 4, .write = rtl8139_ioport_writel, }, - PORTIO_END_OF_LIST() -}; +static void rtl8139_ioport_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) +{ + switch (size) { + case 1: + rtl8139_io_writeb(opaque, addr, val); + break; + case 2: + rtl8139_io_writew(opaque, addr, val); + break; + case 4: + rtl8139_io_writel(opaque, addr, val); + break; + } +} + +static uint64_t rtl8139_ioport_read(void *opaque, target_phys_addr_t addr, + unsigned size) +{ + switch (size) { + case 1: + return rtl8139_io_readb(opaque, addr); + case 2: + return rtl8139_io_readw(opaque, addr); + case 4: + return rtl8139_io_readl(opaque, addr); + } + + return -1; +} static const MemoryRegionOps rtl8139_io_ops = { - .old_portio = rtl8139_portio, + .read = rtl8139_ioport_read, + .write = rtl8139_ioport_write, + .impl = { + .min_access_size = 1, + .max_access_size = 4, + }, .endianness = DEVICE_LITTLE_ENDIAN, }; -- 1.6.0.2
Alexander Graf
2012-Oct-08 12:23 UTC
[PATCH 10/14] serial: convert PIO to new memory api read/write
Signed-off-by: Alexander Graf <agraf@suse.de> --- hw/serial.c | 31 ++++++++++++++++++------------- 1 files changed, 18 insertions(+), 13 deletions(-) diff --git a/hw/serial.c b/hw/serial.c index a421d1e..abae1e7 100644 --- a/hw/serial.c +++ b/hw/serial.c @@ -28,6 +28,7 @@ #include "pc.h" #include "qemu-timer.h" #include "sysemu.h" +#include "exec-memory.h" //#define DEBUG_SERIAL @@ -367,7 +368,8 @@ static void serial_xmit(void *opaque) } -static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val) +static void serial_ioport_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { SerialState *s = opaque; @@ -513,7 +515,8 @@ static void serial_ioport_write(void *opaque, uint32_t addr, uint32_t val) } } -static uint32_t serial_ioport_read(void *opaque, uint32_t addr) +static uint64_t serial_ioport_read(void *opaque, target_phys_addr_t addr, + unsigned size) { SerialState *s = opaque; uint32_t ret; @@ -682,7 +685,7 @@ static int serial_post_load(void *opaque, int version_id) s->fcr_vmstate = 0; } /* Initialize fcr via setter to perform essential side-effects */ - serial_ioport_write(s, 0x02, s->fcr_vmstate); + serial_ioport_write(s, 0x02, s->fcr_vmstate, 1); serial_update_parameters(s); return 0; } @@ -764,13 +767,14 @@ void serial_set_frequency(SerialState *s, uint32_t frequency) static const int isa_serial_io[MAX_SERIAL_PORTS] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 }; static const int isa_serial_irq[MAX_SERIAL_PORTS] = { 4, 3, 4, 3 }; -static const MemoryRegionPortio serial_portio[] = { - { 0, 8, 1, .read = serial_ioport_read, .write = serial_ioport_write }, - PORTIO_END_OF_LIST() -}; - static const MemoryRegionOps serial_io_ops = { - .old_portio = serial_portio + .read = serial_ioport_read, + .write = serial_ioport_write, + .impl = { + .min_access_size = 1, + .max_access_size = 1, + }, + .endianness = DEVICE_LITTLE_ENDIAN, }; static int serial_isa_initfn(ISADevice *dev) @@ -823,8 +827,9 @@ SerialState *serial_init(int base, qemu_irq irq, int baudbase, vmstate_register(NULL, base, &vmstate_serial, s); - register_ioport_write(base, 8, 1, serial_ioport_write, s); - register_ioport_read(base, 8, 1, serial_ioport_read, s); + memory_region_init_io(&s->io, &serial_io_ops, s, "serial", 8); + memory_region_add_subregion(get_system_io(), base, &s->io); + return s; } @@ -833,7 +838,7 @@ static uint64_t serial_mm_read(void *opaque, target_phys_addr_t addr, unsigned size) { SerialState *s = opaque; - return serial_ioport_read(s, addr >> s->it_shift); + return serial_ioport_read(s, addr >> s->it_shift, 1); } static void serial_mm_write(void *opaque, target_phys_addr_t addr, @@ -841,7 +846,7 @@ static void serial_mm_write(void *opaque, target_phys_addr_t addr, { SerialState *s = opaque; value &= ~0u >> (32 - (size * 8)); - serial_ioport_write(s, addr >> s->it_shift, value); + serial_ioport_write(s, addr >> s->it_shift, value, 1); } static const MemoryRegionOps serial_mm_ops[3] = { -- 1.6.0.2
Alexander Graf
2012-Oct-08 12:23 UTC
[PATCH 11/14] vmport: convert PIO to new memory api read/write
Signed-off-by: Alexander Graf <agraf@suse.de> --- hw/vmport.c | 21 ++++++++++++--------- 1 files changed, 12 insertions(+), 9 deletions(-) diff --git a/hw/vmport.c b/hw/vmport.c index a4f52ee..77dc8d6 100644 --- a/hw/vmport.c +++ b/hw/vmport.c @@ -54,7 +54,8 @@ void vmport_register(unsigned char command, IOPortReadFunc *func, void *opaque) port_state->opaque[command] = opaque; } -static uint32_t vmport_ioport_read(void *opaque, uint32_t addr) +static uint64_t vmport_ioport_read(void *opaque, target_phys_addr_t addr, + unsigned size) { VMPortState *s = opaque; CPUX86State *env = cpu_single_env; @@ -81,11 +82,12 @@ static uint32_t vmport_ioport_read(void *opaque, uint32_t addr) return s->func[command](s->opaque[command], addr); } -static void vmport_ioport_write(void *opaque, uint32_t addr, uint32_t val) +static void vmport_ioport_write(void *opaque, target_phys_addr_t addr, + uint64_t val, unsigned size) { CPUX86State *env = cpu_single_env; - env->regs[R_EAX] = vmport_ioport_read(opaque, addr); + env->regs[R_EAX] = vmport_ioport_read(opaque, addr, 4); } static uint32_t vmport_cmd_get_version(void *opaque, uint32_t addr) @@ -121,13 +123,14 @@ void vmmouse_set_data(const uint32_t *data) env->regs[R_ESI] = data[4]; env->regs[R_EDI] = data[5]; } -static const MemoryRegionPortio vmport_portio[] = { - {0, 1, 4, .read = vmport_ioport_read, .write = vmport_ioport_write }, - PORTIO_END_OF_LIST(), -}; - static const MemoryRegionOps vmport_ops = { - .old_portio = vmport_portio + .read = vmport_ioport_read, + .write = vmport_ioport_write, + .impl = { + .min_access_size = 4, + .max_access_size = 4, + }, + .endianness = DEVICE_LITTLE_ENDIAN, }; static int vmport_initfn(ISADevice *dev) -- 1.6.0.2
Alexander Graf
2012-Oct-08 12:23 UTC
[PATCH 12/14] xen_platform: convert PIO to new memory api read/write
Signed-off-by: Alexander Graf <agraf@suse.de> --- hw/xen_platform.c | 48 ++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 38 insertions(+), 10 deletions(-) diff --git a/hw/xen_platform.c b/hw/xen_platform.c index 956dbfe..171f8ff 100644 --- a/hw/xen_platform.c +++ b/hw/xen_platform.c @@ -228,18 +228,46 @@ static void platform_fixed_ioport_reset(void *opaque) platform_fixed_ioport_writeb(s, 0, 0); } -const MemoryRegionPortio xen_platform_ioport[] = { - { 0, 16, 4, .write = platform_fixed_ioport_writel, }, - { 0, 16, 2, .write = platform_fixed_ioport_writew, }, - { 0, 16, 1, .write = platform_fixed_ioport_writeb, }, - { 0, 16, 2, .read = platform_fixed_ioport_readw, }, - { 0, 16, 1, .read = platform_fixed_ioport_readb, }, - PORTIO_END_OF_LIST() -}; +static uint64_t platform_fixed_ioport_read(void *opaque, + target_phys_addr_t addr, + unsigned size) +{ + switch (size) { + case 1: + return platform_fixed_ioport_readb(opaque, addr); + case 2: + return platform_fixed_ioport_readw(opaque, addr); + default: + return -1; + } +} + +static void platform_fixed_ioport_write(void *opaque, target_phys_addr_t addr, + + uint64_t val, unsigned size) +{ + switch (size) { + case 1: + platform_fixed_ioport_writeb(opaque, addr, val); + break; + case 2: + platform_fixed_ioport_writew(opaque, addr, val); + break; + case 4: + platform_fixed_ioport_writel(opaque, addr, val); + break; + } +} + static const MemoryRegionOps platform_fixed_io_ops = { - .old_portio = xen_platform_ioport, - .endianness = DEVICE_NATIVE_ENDIAN, + .read = platform_fixed_ioport_read, + .write = platform_fixed_ioport_write, + .impl = { + .min_access_size = 1, + .max_access_size = 4, + }, + .endianness = DEVICE_LITTLE_ENDIAN, }; static void platform_fixed_ioport_init(PCIXenPlatformState* s) -- 1.6.0.2
Alexander Graf
2012-Oct-08 12:23 UTC
[PATCH 13/14] PPC: e500: Map PIO space into core memory region
On PPC, we don''t have PIO. So usually PIO space behind a PCI bridge is accessible via MMIO. Do this mapping explicitly by mapping the PIO space of our PCI bus into a memory region that lives in memory space. Signed-off-by: Alexander Graf <agraf@suse.de> --- hw/ppc/e500.c | 3 +-- hw/ppce500_pci.c | 9 +++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index d23f9b2..857d4dc 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -52,7 +52,6 @@ #define MPC8544_PCI_REGS_BASE (MPC8544_CCSRBAR_BASE + 0x8000ULL) #define MPC8544_PCI_REGS_SIZE 0x1000ULL #define MPC8544_PCI_IO 0xE1000000ULL -#define MPC8544_PCI_IOLEN 0x10000ULL #define MPC8544_UTIL_BASE (MPC8544_CCSRBAR_BASE + 0xe0000ULL) #define MPC8544_SPIN_BASE 0xEF000000ULL @@ -511,7 +510,7 @@ void ppce500_init(PPCE500Params *params) if (!pci_bus) printf("couldn''t create PCI controller!\n"); - isa_mmio_init(MPC8544_PCI_IO, MPC8544_PCI_IOLEN); + sysbus_mmio_map(sysbus_from_qdev(dev), 1, MPC8544_PCI_IO); if (pci_bus) { /* Register network interfaces. */ diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c index 92b1dc0..27c6d7d 100644 --- a/hw/ppce500_pci.c +++ b/hw/ppce500_pci.c @@ -31,6 +31,8 @@ #define PCIE500_ALL_SIZE 0x1000 #define PCIE500_REG_SIZE (PCIE500_ALL_SIZE - PCIE500_REG_BASE) +#define PCIE500_PCI_IOLEN 0x10000ULL + #define PPCE500_PCI_CONFIG_ADDR 0x0 #define PPCE500_PCI_CONFIG_DATA 0x4 #define PPCE500_PCI_INTACK 0x8 @@ -87,6 +89,7 @@ struct PPCE500PCIState { /* mmio maps */ MemoryRegion container; MemoryRegion iomem; + MemoryRegion pio; }; typedef struct PPCE500PCIState PPCE500PCIState; @@ -314,7 +317,6 @@ static int e500_pcihost_initfn(SysBusDevice *dev) PCIBus *b; int i; MemoryRegion *address_space_mem = get_system_memory(); - MemoryRegion *address_space_io = get_system_io(); h = PCI_HOST_BRIDGE(dev); s = PPC_E500_PCI_HOST_BRIDGE(dev); @@ -323,9 +325,11 @@ static int e500_pcihost_initfn(SysBusDevice *dev) sysbus_init_irq(dev, &s->irq[i]); } + memory_region_init(&s->pio, "pci-pio", PCIE500_PCI_IOLEN); + b = pci_register_bus(DEVICE(dev), NULL, mpc85xx_pci_set_irq, mpc85xx_pci_map_irq, s->irq, address_space_mem, - address_space_io, PCI_DEVFN(0x11, 0), 4); + &s->pio, PCI_DEVFN(0x11, 0), 4); h->bus = b; pci_create_simple(b, 0, "e500-host-bridge"); @@ -341,6 +345,7 @@ static int e500_pcihost_initfn(SysBusDevice *dev) memory_region_add_subregion(&s->container, PCIE500_CFGDATA, &h->data_mem); memory_region_add_subregion(&s->container, PCIE500_REG_BASE, &s->iomem); sysbus_init_mmio(dev, &s->container); + sysbus_init_mmio(dev, &s->pio); return 0; } -- 1.6.0.2
Alexander Graf
2012-Oct-08 12:23 UTC
[PATCH 14/14] PPC: pseries: Remove hack for PIO window
Now that all users of old_portio are gone, we can remove the hack that enabled us to support them. Signed-off-by: Alexander Graf <agraf@suse.de> --- hw/spapr_pci.c | 44 +------------------------------------------- hw/spapr_pci.h | 2 +- 2 files changed, 2 insertions(+), 44 deletions(-) diff --git a/hw/spapr_pci.c b/hw/spapr_pci.c index b628f89..0128f3e 100644 --- a/hw/spapr_pci.c +++ b/hw/spapr_pci.c @@ -439,43 +439,6 @@ static void pci_spapr_set_irq(void *opaque, int irq_num, int level) qemu_set_irq(spapr_phb_lsi_qirq(phb, irq_num), level); } -static uint64_t spapr_io_read(void *opaque, target_phys_addr_t addr, - unsigned size) -{ - switch (size) { - case 1: - return cpu_inb(addr); - case 2: - return cpu_inw(addr); - case 4: - return cpu_inl(addr); - } - assert(0); -} - -static void spapr_io_write(void *opaque, target_phys_addr_t addr, - uint64_t data, unsigned size) -{ - switch (size) { - case 1: - cpu_outb(addr, data); - return; - case 2: - cpu_outw(addr, data); - return; - case 4: - cpu_outl(addr, data); - return; - } - assert(0); -} - -static const MemoryRegionOps spapr_io_ops = { - .endianness = DEVICE_LITTLE_ENDIAN, - .read = spapr_io_read, - .write = spapr_io_write -}; - /* * MSI/MSIX memory region implementation. * The handler handles both MSI and MSIX. @@ -545,14 +508,9 @@ static int spapr_phb_init(SysBusDevice *s) * old_portion are updated */ sprintf(namebuf, "%s.io", sphb->dtbusname); memory_region_init(&sphb->iospace, namebuf, SPAPR_PCI_IO_WIN_SIZE); - /* FIXME: fix to support multiple PHBs */ - memory_region_add_subregion(get_system_io(), 0, &sphb->iospace); - sprintf(namebuf, "%s.io-alias", sphb->dtbusname); - memory_region_init_io(&sphb->iowindow, &spapr_io_ops, sphb, - namebuf, SPAPR_PCI_IO_WIN_SIZE); memory_region_add_subregion(get_system_memory(), sphb->io_win_addr, - &sphb->iowindow); + &sphb->iospace); /* As MSI/MSIX interrupts trigger by writing at MSI/MSIX vectors, * we need to allocate some memory to catch those writes coming diff --git a/hw/spapr_pci.h b/hw/spapr_pci.h index 670dc62..02163a7 100644 --- a/hw/spapr_pci.h +++ b/hw/spapr_pci.h @@ -44,7 +44,7 @@ typedef struct sPAPRPHBState { MemoryRegion memspace, iospace; target_phys_addr_t mem_win_addr, mem_win_size, io_win_addr, io_win_size; target_phys_addr_t msi_win_addr; - MemoryRegion memwindow, iowindow, msiwindow; + MemoryRegion memwindow, msiwindow; uint32_t dma_liobn; uint64_t dma_window_start; -- 1.6.0.2
Andreas Färber
2012-Oct-08 16:18 UTC
Re: [PATCH 00/14] Remove old_portio users for memory region PIO mapping
Am 08.10.2012 14:23, schrieb Alexander Graf:> When running on PowerPC, we don''t have native PIO support. There are a few hacks > around to enable PIO access on PowerPC nevertheless. > > The most typical one is the isa-mmio device. It takes MMIO requests and converts > them to PIO requests on the (QEMU internal) PIO bus. > > This however is not how real hardware works and it limits us in the ability to > spawn eventfd''s on PIO ports which doesn''t work with this approach. Instead, > let''s model it more easily. Let''s just map the PIO memory region into MMIO > space. > > For this to work, we need to get rid of all old_portio struct users, as they > break with this approach. This is what this patch set does.Looks sensible to me as far as reviewed, but I''m missing a patch 13 that actually rips out old_portio afterwards. :) Andreas> It also converts > the e500 machines and sPAPR to the new memory region model. > > > Alex-- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Alexander Graf
2012-Oct-08 16:32 UTC
Re: [PATCH 00/14] Remove old_portio users for memory region PIO mapping
On 08.10.2012, at 18:18, Andreas Färber <afaerber@suse.de> wrote:> Am 08.10.2012 14:23, schrieb Alexander Graf: >> When running on PowerPC, we don''t have native PIO support. There are a few hacks >> around to enable PIO access on PowerPC nevertheless. >> >> The most typical one is the isa-mmio device. It takes MMIO requests and converts >> them to PIO requests on the (QEMU internal) PIO bus. >> >> This however is not how real hardware works and it limits us in the ability to >> spawn eventfd''s on PIO ports which doesn''t work with this approach. Instead, >> let''s model it more easily. Let''s just map the PIO memory region into MMIO >> space. >> >> For this to work, we need to get rid of all old_portio struct users, as they >> break with this approach. This is what this patch set does. > > Looks sensible to me as far as reviewed, but I''m missing a patch 13 that > actually rips out old_portio afterwards. :)I''ll leave that as an exercise for the reader :) Alex> > Andreas > >> It also converts >> the e500 machines and sPAPR to the new memory region model. >> >> >> Alex > > -- > SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany > GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
Scott Wood
2012-Oct-08 20:20 UTC
Re: [PATCH 13/14] PPC: e500: Map PIO space into core memory region
On 10/08/2012 07:23:52 AM, Alexander Graf wrote:> On PPC, we don''t have PIO. So usually PIO space behind a PCI bridge is > accessible via MMIO. Do this mapping explicitly by mapping the PIO > space > of our PCI bus into a memory region that lives in memory space. > > Signed-off-by: Alexander Graf <agraf@suse.de> > --- > hw/ppc/e500.c | 3 +-- > hw/ppce500_pci.c | 9 +++++++-- > 2 files changed, 8 insertions(+), 4 deletions(-) > > diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c > index d23f9b2..857d4dc 100644 > --- a/hw/ppc/e500.c > +++ b/hw/ppc/e500.c > @@ -52,7 +52,6 @@ > #define MPC8544_PCI_REGS_BASE (MPC8544_CCSRBAR_BASE + 0x8000ULL) > #define MPC8544_PCI_REGS_SIZE 0x1000ULL > #define MPC8544_PCI_IO 0xE1000000ULL > -#define MPC8544_PCI_IOLEN 0x10000ULL > #define MPC8544_UTIL_BASE (MPC8544_CCSRBAR_BASE + > 0xe0000ULL) > #define MPC8544_SPIN_BASE 0xEF000000ULL > > @@ -511,7 +510,7 @@ void ppce500_init(PPCE500Params *params) > if (!pci_bus) > printf("couldn''t create PCI controller!\n"); > > - isa_mmio_init(MPC8544_PCI_IO, MPC8544_PCI_IOLEN); > + sysbus_mmio_map(sysbus_from_qdev(dev), 1, MPC8544_PCI_IO); > > if (pci_bus) { > /* Register network interfaces. */ > diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c > index 92b1dc0..27c6d7d 100644 > --- a/hw/ppce500_pci.c > +++ b/hw/ppce500_pci.c > @@ -31,6 +31,8 @@ > #define PCIE500_ALL_SIZE 0x1000 > #define PCIE500_REG_SIZE (PCIE500_ALL_SIZE - PCIE500_REG_BASE) > > +#define PCIE500_PCI_IOLEN 0x10000ULLI don''t think this belongs in ppce500_pci.c -- it''s board config (or rather, a board-related default of something that is supposed to be software configurable), just like the base address. Any chance of similarly constraining PCI MMIO to its proper window? -Scott
Alexander Graf
2012-Oct-08 20:48 UTC
Re: [PATCH 13/14] PPC: e500: Map PIO space into core memory region
On 08.10.2012, at 22:20, Scott Wood wrote:> On 10/08/2012 07:23:52 AM, Alexander Graf wrote: >> On PPC, we don''t have PIO. So usually PIO space behind a PCI bridge is >> accessible via MMIO. Do this mapping explicitly by mapping the PIO space >> of our PCI bus into a memory region that lives in memory space. >> Signed-off-by: Alexander Graf <agraf@suse.de> >> --- >> hw/ppc/e500.c | 3 +-- >> hw/ppce500_pci.c | 9 +++++++-- >> 2 files changed, 8 insertions(+), 4 deletions(-) >> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c >> index d23f9b2..857d4dc 100644 >> --- a/hw/ppc/e500.c >> +++ b/hw/ppc/e500.c >> @@ -52,7 +52,6 @@ >> #define MPC8544_PCI_REGS_BASE (MPC8544_CCSRBAR_BASE + 0x8000ULL) >> #define MPC8544_PCI_REGS_SIZE 0x1000ULL >> #define MPC8544_PCI_IO 0xE1000000ULL >> -#define MPC8544_PCI_IOLEN 0x10000ULL >> #define MPC8544_UTIL_BASE (MPC8544_CCSRBAR_BASE + 0xe0000ULL) >> #define MPC8544_SPIN_BASE 0xEF000000ULL >> @@ -511,7 +510,7 @@ void ppce500_init(PPCE500Params *params) >> if (!pci_bus) >> printf("couldn''t create PCI controller!\n"); >> - isa_mmio_init(MPC8544_PCI_IO, MPC8544_PCI_IOLEN); >> + sysbus_mmio_map(sysbus_from_qdev(dev), 1, MPC8544_PCI_IO); >> if (pci_bus) { >> /* Register network interfaces. */ >> diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c >> index 92b1dc0..27c6d7d 100644 >> --- a/hw/ppce500_pci.c >> +++ b/hw/ppce500_pci.c >> @@ -31,6 +31,8 @@ >> #define PCIE500_ALL_SIZE 0x1000 >> #define PCIE500_REG_SIZE (PCIE500_ALL_SIZE - PCIE500_REG_BASE) >> +#define PCIE500_PCI_IOLEN 0x10000ULL > > I don''t think this belongs in ppce500_pci.c -- it''s board config (or rather, a board-related default of something that is supposed to be software configurable), just like the base address.Actually this one is fixed in PCI. There are only 64k PIO ports.> Any chance of similarly constraining PCI MMIO to its proper window?We can''t distinguish between inbound and outbound right now. If we only need to restrict CPU -> PCI access, then yes. Alex
Scott Wood
2012-Oct-08 21:05 UTC
Re: [PATCH 13/14] PPC: e500: Map PIO space into core memory region
On 10/08/2012 03:48:42 PM, Alexander Graf wrote:> > On 08.10.2012, at 22:20, Scott Wood wrote: > > > On 10/08/2012 07:23:52 AM, Alexander Graf wrote: > >> On PPC, we don''t have PIO. So usually PIO space behind a PCI > bridge is > >> accessible via MMIO. Do this mapping explicitly by mapping the PIO > space > >> of our PCI bus into a memory region that lives in memory space. > >> Signed-off-by: Alexander Graf <agraf@suse.de> > >> --- > >> hw/ppc/e500.c | 3 +-- > >> hw/ppce500_pci.c | 9 +++++++-- > >> 2 files changed, 8 insertions(+), 4 deletions(-) > >> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c > >> index d23f9b2..857d4dc 100644 > >> --- a/hw/ppc/e500.c > >> +++ b/hw/ppc/e500.c > >> @@ -52,7 +52,6 @@ > >> #define MPC8544_PCI_REGS_BASE (MPC8544_CCSRBAR_BASE + > 0x8000ULL) > >> #define MPC8544_PCI_REGS_SIZE 0x1000ULL > >> #define MPC8544_PCI_IO 0xE1000000ULL > >> -#define MPC8544_PCI_IOLEN 0x10000ULL > >> #define MPC8544_UTIL_BASE (MPC8544_CCSRBAR_BASE + > 0xe0000ULL) > >> #define MPC8544_SPIN_BASE 0xEF000000ULL > >> @@ -511,7 +510,7 @@ void ppce500_init(PPCE500Params *params) > >> if (!pci_bus) > >> printf("couldn''t create PCI controller!\n"); > >> - isa_mmio_init(MPC8544_PCI_IO, MPC8544_PCI_IOLEN); > >> + sysbus_mmio_map(sysbus_from_qdev(dev), 1, MPC8544_PCI_IO); > >> if (pci_bus) { > >> /* Register network interfaces. */ > >> diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c > >> index 92b1dc0..27c6d7d 100644 > >> --- a/hw/ppce500_pci.c > >> +++ b/hw/ppce500_pci.c > >> @@ -31,6 +31,8 @@ > >> #define PCIE500_ALL_SIZE 0x1000 > >> #define PCIE500_REG_SIZE (PCIE500_ALL_SIZE - PCIE500_REG_BASE) > >> +#define PCIE500_PCI_IOLEN 0x10000ULL > > > > I don''t think this belongs in ppce500_pci.c -- it''s board config > (or rather, a board-related default of something that is supposed to > be software configurable), just like the base address. > > Actually this one is fixed in PCI. There are only 64k PIO ports.Are you sure about that? Certainly that''s the limit on x86 due to the I/O instructions, and some (buggy?) PCI devices might have trouble with larger I/O addresses, but I didn''t think it was actually illegal. Some mpc85xx boards have default configs with larger I/O windows (though probably not for any good reason).> > Any chance of similarly constraining PCI MMIO to its proper window? > > We can''t distinguish between inbound and outbound right now. If we > only need to restrict CPU -> PCI access, then yes.Better than nothing. :-) -Scott
Alexander Graf
2012-Oct-08 21:08 UTC
Re: [PATCH 13/14] PPC: e500: Map PIO space into core memory region
On 08.10.2012, at 23:05, Scott Wood wrote:> On 10/08/2012 03:48:42 PM, Alexander Graf wrote: >> On 08.10.2012, at 22:20, Scott Wood wrote: >> > On 10/08/2012 07:23:52 AM, Alexander Graf wrote: >> >> On PPC, we don''t have PIO. So usually PIO space behind a PCI bridge is >> >> accessible via MMIO. Do this mapping explicitly by mapping the PIO space >> >> of our PCI bus into a memory region that lives in memory space. >> >> Signed-off-by: Alexander Graf <agraf@suse.de> >> >> --- >> >> hw/ppc/e500.c | 3 +-- >> >> hw/ppce500_pci.c | 9 +++++++-- >> >> 2 files changed, 8 insertions(+), 4 deletions(-) >> >> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c >> >> index d23f9b2..857d4dc 100644 >> >> --- a/hw/ppc/e500.c >> >> +++ b/hw/ppc/e500.c >> >> @@ -52,7 +52,6 @@ >> >> #define MPC8544_PCI_REGS_BASE (MPC8544_CCSRBAR_BASE + 0x8000ULL) >> >> #define MPC8544_PCI_REGS_SIZE 0x1000ULL >> >> #define MPC8544_PCI_IO 0xE1000000ULL >> >> -#define MPC8544_PCI_IOLEN 0x10000ULL >> >> #define MPC8544_UTIL_BASE (MPC8544_CCSRBAR_BASE + 0xe0000ULL) >> >> #define MPC8544_SPIN_BASE 0xEF000000ULL >> >> @@ -511,7 +510,7 @@ void ppce500_init(PPCE500Params *params) >> >> if (!pci_bus) >> >> printf("couldn''t create PCI controller!\n"); >> >> - isa_mmio_init(MPC8544_PCI_IO, MPC8544_PCI_IOLEN); >> >> + sysbus_mmio_map(sysbus_from_qdev(dev), 1, MPC8544_PCI_IO); >> >> if (pci_bus) { >> >> /* Register network interfaces. */ >> >> diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c >> >> index 92b1dc0..27c6d7d 100644 >> >> --- a/hw/ppce500_pci.c >> >> +++ b/hw/ppce500_pci.c >> >> @@ -31,6 +31,8 @@ >> >> #define PCIE500_ALL_SIZE 0x1000 >> >> #define PCIE500_REG_SIZE (PCIE500_ALL_SIZE - PCIE500_REG_BASE) >> >> +#define PCIE500_PCI_IOLEN 0x10000ULL >> > >> > I don''t think this belongs in ppce500_pci.c -- it''s board config (or rather, a board-related default of something that is supposed to be software configurable), just like the base address. >> Actually this one is fixed in PCI. There are only 64k PIO ports. > > Are you sure about that? Certainly that''s the limit on x86 due to the I/O instructions, and some (buggy?) PCI devices might have trouble with larger I/O addresses, but I didn''t think it was actually illegal. Some mpc85xx boards have default configs with larger I/O windows (though probably not for any good reason).What sense would it make to model an ioport range that exceeds what x86 can do? I''m fairly sure if you''d ever start using that, you''ll see a lot of PCI devices fail at you anyway.> >> > Any chance of similarly constraining PCI MMIO to its proper window? >> We can''t distinguish between inbound and outbound right now. If we only need to restrict CPU -> PCI access, then yes. > > Better than nothing. :-)If you can point me to the part of the spec that specifies how that window should look like, I can cook up a patch. Or you can do it of course ;). Alex
Scott Wood
2012-Oct-08 21:30 UTC
Re: [PATCH 13/14] PPC: e500: Map PIO space into core memory region
On 10/08/2012 04:08:31 PM, Alexander Graf wrote:> > On 08.10.2012, at 23:05, Scott Wood wrote: > > > On 10/08/2012 03:48:42 PM, Alexander Graf wrote: > >> On 08.10.2012, at 22:20, Scott Wood wrote: > >> > On 10/08/2012 07:23:52 AM, Alexander Graf wrote: > >> >> On PPC, we don''t have PIO. So usually PIO space behind a PCI > bridge is > >> >> accessible via MMIO. Do this mapping explicitly by mapping the > PIO space > >> >> of our PCI bus into a memory region that lives in memory space. > >> >> Signed-off-by: Alexander Graf <agraf@suse.de> > >> >> --- > >> >> hw/ppc/e500.c | 3 +-- > >> >> hw/ppce500_pci.c | 9 +++++++-- > >> >> 2 files changed, 8 insertions(+), 4 deletions(-) > >> >> diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c > >> >> index d23f9b2..857d4dc 100644 > >> >> --- a/hw/ppc/e500.c > >> >> +++ b/hw/ppc/e500.c > >> >> @@ -52,7 +52,6 @@ > >> >> #define MPC8544_PCI_REGS_BASE (MPC8544_CCSRBAR_BASE + > 0x8000ULL) > >> >> #define MPC8544_PCI_REGS_SIZE 0x1000ULL > >> >> #define MPC8544_PCI_IO 0xE1000000ULL > >> >> -#define MPC8544_PCI_IOLEN 0x10000ULL > >> >> #define MPC8544_UTIL_BASE (MPC8544_CCSRBAR_BASE + > 0xe0000ULL) > >> >> #define MPC8544_SPIN_BASE 0xEF000000ULL > >> >> @@ -511,7 +510,7 @@ void ppce500_init(PPCE500Params *params) > >> >> if (!pci_bus) > >> >> printf("couldn''t create PCI controller!\n"); > >> >> - isa_mmio_init(MPC8544_PCI_IO, MPC8544_PCI_IOLEN); > >> >> + sysbus_mmio_map(sysbus_from_qdev(dev), 1, MPC8544_PCI_IO); > >> >> if (pci_bus) { > >> >> /* Register network interfaces. */ > >> >> diff --git a/hw/ppce500_pci.c b/hw/ppce500_pci.c > >> >> index 92b1dc0..27c6d7d 100644 > >> >> --- a/hw/ppce500_pci.c > >> >> +++ b/hw/ppce500_pci.c > >> >> @@ -31,6 +31,8 @@ > >> >> #define PCIE500_ALL_SIZE 0x1000 > >> >> #define PCIE500_REG_SIZE (PCIE500_ALL_SIZE - > PCIE500_REG_BASE) > >> >> +#define PCIE500_PCI_IOLEN 0x10000ULL > >> > > >> > I don''t think this belongs in ppce500_pci.c -- it''s board config > (or rather, a board-related default of something that is supposed to > be software configurable), just like the base address. > >> Actually this one is fixed in PCI. There are only 64k PIO ports. > > > > Are you sure about that? Certainly that''s the limit on x86 due to > the I/O instructions, and some (buggy?) PCI devices might have > trouble with larger I/O addresses, but I didn''t think it was actually > illegal. Some mpc85xx boards have default configs with larger I/O > windows (though probably not for any good reason). > > What sense would it make to model an ioport range that exceeds what > x86 can do?Well, as I said there''s probably not a good reason for actually doing it, but if you want to more faithfully emulate the hardware... That said, when I first complained I misread the constant and thought you were hardcoding 1M rather than 64K.> >> > Any chance of similarly constraining PCI MMIO to its proper > window? > >> We can''t distinguish between inbound and outbound right now. If we > only need to restrict CPU -> PCI access, then yes. > > > > Better than nothing. :-) > > If you can point me to the part of the spec that specifies how that > window should look like, I can cook up a patch. Or you can do it of > course ;).Outbound windows are configured by PO*AR/PEXO*AR, and inbound by PI*AR/PEXI*AR (plus BAR0). It''s not a high priority, just curious what would be involved. -Scott