From 1fa2f27dd30465de9cc70114fc556d764af7dc13 Mon Sep 17 00:00:00 2001 From: Jian Jun Chen Date: Thu, 29 Mar 2018 12:09:09 +0800 Subject: [PATCH] dm/VBS-U: implement read/write callbacks of device-specific cfg This patch implements the read/write callbacks for the registers in the device-specific region. This region is implemented in the modern MMIO bar. Signed-off-by: Jian Jun Chen Reviewed-by: Hao Li Reviewed-by: Zhao Yakui Acked-by: Eddie Dong --- devicemodel/hw/pci/virtio/virtio.c | 53 ++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/devicemodel/hw/pci/virtio/virtio.c b/devicemodel/hw/pci/virtio/virtio.c index d4b70e5a4..0d160470a 100644 --- a/devicemodel/hw/pci/virtio/virtio.c +++ b/devicemodel/hw/pci/virtio/virtio.c @@ -1267,15 +1267,62 @@ virtio_isr_cfg_read(struct pci_vdev *dev, uint64_t offset, int size) static uint32_t virtio_device_cfg_read(struct pci_vdev *dev, uint64_t offset, int size) { - /* TODO: to be implemented */ - return 0; + struct virtio_base *base = dev->arg; + struct virtio_ops *vops; + const char *name; + uint32_t value; + uint64_t max; + int error; + + vops = base->vops; + name = vops->name; + value = size == 1 ? 0xff : size == 2 ? 0xffff : 0xffffffff; + max = vops->cfgsize ? vops->cfgsize : 0x100000000; + + if (offset + size > max) { + fprintf(stderr, + "%s: reading from 0x%lx size %d exceeds limit\r\n", + name, offset, size); + return value; + } + + error = (*vops->cfgread)(DEV_STRUCT(base), offset, size, &value); + if (error) { + fprintf(stderr, + "%s: reading from 0x%lx size %d failed %d\r\n", + name, offset, size, error); + value = size == 1 ? 0xff : size == 2 ? 0xffff : 0xffffffff; + } + + return value; } static void virtio_device_cfg_write(struct pci_vdev *dev, uint64_t offset, int size, uint64_t value) { - /* TODO: to be implemented */ + struct virtio_base *base = dev->arg; + struct virtio_ops *vops; + const char *name; + uint64_t max; + int error; + + vops = base->vops; + name = vops->name; + max = vops->cfgsize ? vops->cfgsize : 0x100000000; + + if (offset + size > max) { + fprintf(stderr, + "%s: writing to 0x%lx size %d exceeds limit\r\n", + name, offset, size); + return; + } + + error = (*vops->cfgwrite)(DEV_STRUCT(base), offset, size, value); + if (error) + fprintf(stderr, + "%s: writing ot 0x%lx size %d failed %d\r\n", + name, offset, size, error); } /*