virtio-pci: convert PIO to new memory api read/write

Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
Alexander Graf 2012-10-08 13:02:30 +02:00
parent d6a6d362aa
commit df6db5b32a

View File

@ -374,52 +374,39 @@ static uint32_t virtio_ioport_read(VirtIOPCIProxy *proxy, uint32_t addr)
return ret; return ret;
} }
static uint32_t virtio_pci_config_readb(void *opaque, uint32_t addr) static uint64_t virtio_pci_config_read(void *opaque, hwaddr addr,
unsigned size)
{ {
VirtIOPCIProxy *proxy = opaque; VirtIOPCIProxy *proxy = opaque;
uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
if (addr < config) uint64_t val = 0;
if (addr < config) {
return virtio_ioport_read(proxy, addr); return virtio_ioport_read(proxy, addr);
}
addr -= config; addr -= config;
return virtio_config_readb(proxy->vdev, addr);
}
static uint32_t virtio_pci_config_readw(void *opaque, uint32_t addr) switch (size) {
{ case 1:
VirtIOPCIProxy *proxy = opaque; val = virtio_config_readb(proxy->vdev, addr);
uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); break;
uint16_t val; case 2:
if (addr < config) val = virtio_config_readw(proxy->vdev, addr);
return virtio_ioport_read(proxy, addr); if (virtio_is_big_endian()) {
addr -= config; val = bswap16(val);
val = virtio_config_readw(proxy->vdev, addr); }
if (virtio_is_big_endian()) { break;
/* case 4:
* virtio is odd, ioports are LE but config space is target native val = virtio_config_readl(proxy->vdev, addr);
* endian. However, in qemu, all PIO is LE, so we need to re-swap if (virtio_is_big_endian()) {
* on BE targets val = bswap32(val);
*/ }
val = bswap16(val); break;
} }
return val; return val;
} }
static uint32_t virtio_pci_config_readl(void *opaque, uint32_t addr) static void virtio_pci_config_write(void *opaque, hwaddr addr,
{ uint64_t val, unsigned size)
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)
{ {
VirtIOPCIProxy *proxy = opaque; VirtIOPCIProxy *proxy = opaque;
uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev); uint32_t config = VIRTIO_PCI_CONFIG(&proxy->pci_dev);
@ -428,51 +415,36 @@ static void virtio_pci_config_writeb(void *opaque, uint32_t addr, uint32_t val)
return; return;
} }
addr -= config; addr -= config;
virtio_config_writeb(proxy->vdev, addr, 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;
}
} }
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);
}
virtio_config_writew(proxy->vdev, addr, val);
}
static void virtio_pci_config_writel(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 = bswap32(val);
}
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 = { 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, .endianness = DEVICE_LITTLE_ENDIAN,
}; };