}
}
}
+
+static inline
+void virtio_mmio_cwrite_bytes(const void *addr, const __u8 offset,
+ const void *buf, int len, int type_len)
+{
+ int i = 0;
+ __u64 io_addr;
+ int count;
+
+ count = len / type_len;
+ for (i = 0; i < count; i++) {
+ io_addr = ((unsigned long)addr) + offset + (i * type_len);
+ switch (type_len) {
+ case 1:
+ writeb((__u8 *)io_addr, ((__u8 *)buf)[i * type_len]);
+ break;
+ case 2:
+ writew((__u16 *)io_addr, ((__u16 *)buf)[i * type_len]);
+ break;
+ case 4:
+ writel((__u32 *)io_addr, ((__u32 *)buf)[i * type_len]);
+ break;
+ default:
+ UK_CRASH("Unsupported virtio write operation\n");
+ }
+ }
+}
+
+static inline
+void virtio_mmio_cread_bytes(const void *addr, const __u8 offset,
+ void *buf, int len, int type_len)
+{
+ int i = 0;
+ __u64 io_addr;
+ int count;
+
+ count = len / type_len;
+ for (i = 0; i < count; i++) {
+ io_addr = ((unsigned long)addr) + offset + (i * type_len);
+ switch (type_len) {
+ case 1:
+ ((__u8 *)buf)[i * type_len] = readb((__u8 *)io_addr);
+ break;
+ case 2:
+ ((__u16 *)buf)[i * type_len] = readw((__u16 *)io_addr);
+ break;
+ case 4:
+ ((__u32 *)buf)[i * type_len] = readl((__u32 *)io_addr);
+ break;
+ case 8:
+ ((__u64 *)buf)[i * type_len] = readq((__u64 *)io_addr);
+ break;
+ default:
+ UK_CRASH("Unsupported virtio read operation\n");
+ }
+ }
+}
#else /* !CONFIG_ARCH_X86_64 */
/* IO barriers */
#define __iormb() rmb()
#define __iowmb() wmb()
+#define virtio_mmio_cwrite_bytes virtio_cwrite_bytes
+#define virtio_mmio_cread_bytes virtio_cread_bytes
+
static inline void virtio_cwrite_bytes(const void *addr, const __u8 offset,
const void *buf, int len, int type_len)
{
__u8 *buf, __u32 len)
{
__u8 old_buf[len];
- int check = -1;
+ int check;
int cnt = 0;
__u32 i = 0;
virtio_cwrite_bytes(addr, offset, &data, sizeof(data), sizeof(data));
}
+/**
+ * Read an 8-bit item from the device's config space
+ *
+ * @param addr
+ * The base address of the device.
+ * @param offset
+ * The offset with the device address space.
+ * @return __u8
+ * Returns the value configuration register.
+ */
+static inline __u8 virtio_mmio_cread8(const void *addr, const __u8 offset)
+{
+ __u8 buf = 0;
+
+ virtio_mmio_cread_bytes(addr, offset, &buf, sizeof(buf), sizeof(buf));
+
+ return buf;
+}
+
+/**
+ * Read a 16-bit item from the device's config space
+ *
+ * @param addr
+ * The base address of the device.
+ * @param offset
+ * The offset with the device address space.
+ * @return __u16
+ * Returns the value configuration register.
+ */
+static inline __u16 virtio_mmio_cread16(const void *addr, const __u8 offset)
+{
+ __u16 buf = 0;
+
+ virtio_mmio_cread_bytes(addr, offset, &buf, sizeof(buf), sizeof(buf));
+
+ return buf;
+}
+
+/**
+ * Read a 32-bit item from the device's config space
+ *
+ * @param addr
+ * The base address of the device.
+ * @param offset
+ * The offset with the device address space.
+ * @return __u32
+ * Returns the value configuration register.
+ */
+static inline __u32 virtio_mmio_cread32(const void *addr, const __u8 offset)
+{
+ __u32 buf = 0;
+
+ virtio_mmio_cread_bytes(addr, offset, &buf, sizeof(buf), sizeof(buf));
+
+ return buf;
+}
+
+/**
+ * Write an 8-bit item from the device's config space
+ *
+ * @param addr
+ * The base address of the device.
+ * @param offset
+ * The offset with the device address space.
+ * @param data
+ * The value to write to the configuration.
+ */
+static inline void virtio_mmio_cwrite8(const void *addr, const __u8 offset,
+ const __u8 data)
+{
+ virtio_mmio_cwrite_bytes(addr, offset, &data, sizeof(data),
+ sizeof(data));
+}
+
+/**
+ * Write a 16-bit item from the device's config space
+ *
+ * @param addr
+ * The base address of the device.
+ * @param offset
+ * The offset with the device address space.
+ * @param data
+ * The value to write to the configuration.
+ */
+static inline void virtio_mmio_cwrite16(const void *addr, const __u8 offset,
+ const __u16 data)
+{
+ virtio_mmio_cwrite_bytes(addr, offset, &data, sizeof(data),
+ sizeof(data));
+}
+
+/**
+ * Write a 32-bit item from the device's config space
+ *
+ * @param addr
+ * The base address of the device.
+ * @param offset
+ * The offset with the device address space.
+ * @param data
+ * The value to write to the configuration.
+ */
+static inline void virtio_mmio_cwrite32(const void *addr, const __u8 offset,
+ const __u32 data)
+{
+ virtio_mmio_cwrite_bytes(addr, offset, &data, sizeof(data),
+ sizeof(data));
+}
+
#ifdef __cplusplus
}
#endif /* __cplusplus __ */
struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
__u64 features = 0;
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_DEVICE_FEATURES_SEL, 1);
- features = virtio_cread32(vm_dev->base, VIRTIO_MMIO_DEVICE_FEATURES);
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_DEVICE_FEATURES_SEL, 1);
+ features = virtio_mmio_cread32(vm_dev->base,
+ VIRTIO_MMIO_DEVICE_FEATURES);
features <<= 32;
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_DEVICE_FEATURES_SEL, 0);
- features |= virtio_cread32(vm_dev->base, VIRTIO_MMIO_DEVICE_FEATURES);
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_DEVICE_FEATURES_SEL, 0);
+ features |= virtio_mmio_cread32(vm_dev->base,
+ VIRTIO_MMIO_DEVICE_FEATURES);
return features;
}
return;
}
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_DRIVER_FEATURES_SEL, 1);
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_DRIVER_FEATURES,
- (__u32)(vdev->features >> 32));
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_DRIVER_FEATURES_SEL, 1);
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_DRIVER_FEATURES,
+ (__u32)(vdev->features >> 32));
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_DRIVER_FEATURES_SEL, 0);
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_DRIVER_FEATURES,
- (__u32)vdev->features);
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_DRIVER_FEATURES_SEL, 0);
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_DRIVER_FEATURES,
+ (__u32)vdev->features);
}
static int vm_get(struct virtio_dev *vdev, __u16 offset,
if (vm_dev->version == 1) {
__u8 *ptr = buf;
- unsigned int i;
+ __u8 i;
for (i = 0; i < len; i++)
- ptr[i] = virtio_cread8(base, offset + i);
+ ptr[i] = virtio_mmio_cread8(base, offset + i);
return len;
}
switch (len) {
case 1:
- b = virtio_cread8(base, offset);
+ b = virtio_mmio_cread8(base, offset);
memcpy(buf, &b, sizeof(b));
break;
case 2:
- w = (virtio_cread16(base, offset));
+ w = (virtio_mmio_cread16(base, offset));
memcpy(buf, &w, sizeof(w));
break;
case 4:
- l = (virtio_cread32(base, offset));
+ l = (virtio_mmio_cread32(base, offset));
memcpy(buf, &l, sizeof(l));
break;
case 8:
- l = (virtio_cread32(base, offset));
+ l = (virtio_mmio_cread32(base, offset));
memcpy(buf, &l, sizeof(l));
- l = (virtio_cread32(base, offset + sizeof(l)));
+ l = (virtio_mmio_cread32(base, offset + sizeof(l)));
memcpy(buf + sizeof(l), &l, sizeof(l));
break;
default:
- _virtio_cread_bytes(base, offset, buf, len, 1);
- uk_pr_warn("Unaligned io read: %d bytes\n", len);
+ virtio_mmio_cread_bytes(base, offset, buf, len, 1);
+ uk_pr_warn("Unaligned mmio read: %d bytes\n", len);
}
return len;
__u32 i;
for (i = 0; i < len; i++)
- virtio_cwrite8(base, offset + i, ptr[i]);
+ virtio_mmio_cwrite8(base, offset + i, ptr[i]);
return 0;
}
switch (len) {
case 1:
memcpy(&b, buf, sizeof(b));
- virtio_cwrite8(base, offset, b);
+ virtio_mmio_cwrite8(base, offset, b);
break;
case 2:
memcpy(&w, buf, sizeof(w));
- virtio_cwrite16(base, offset, w);
+ virtio_mmio_cwrite16(base, offset, w);
break;
case 4:
memcpy(&l, buf, sizeof(l));
- virtio_cwrite32(base, offset, l);
+ virtio_mmio_cwrite32(base, offset, l);
break;
case 8:
memcpy(&l, buf, sizeof(l));
- virtio_cwrite32(base, offset, l);
+ virtio_mmio_cwrite32(base, offset, l);
memcpy(&l, buf + sizeof(l), sizeof(l));
- virtio_cwrite32(base, offset + sizeof(l), l);
+ virtio_mmio_cwrite32(base, offset + sizeof(l), l);
break;
default:
- _virtio_cwrite_bytes(base, offset, buf, len, 1);
- uk_pr_warn("Unaligned io write: %d bytes\n", len);
+ virtio_mmio_cwrite_bytes(base, offset, buf, len, 1);
+ uk_pr_warn("Unaligned mmio write: %d bytes\n", len);
}
return 0;
{
struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
- return virtio_cread32(vm_dev->base, VIRTIO_MMIO_STATUS) & 0xff;
+ return virtio_mmio_cread32(vm_dev->base, VIRTIO_MMIO_STATUS) & 0xff;
}
static void vm_set_status(struct virtio_dev *vdev, __u8 status)
/* We should never be setting status to 0. */
UK_BUGON(status == 0);
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_STATUS, status);
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_STATUS, status);
}
static void vm_reset(struct virtio_dev *vdev)
struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
/* 0 status means a reset. */
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_STATUS, 0);
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_STATUS, 0);
}
/* Transport interface */
* We write the queue's selector into the notification register to
* signal the other end
*/
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_NOTIFY, queue_id);
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_NOTIFY, queue_id);
return 1;
}
struct virtqueue *vq;
/* Read and acknowledge interrupts */
- status = virtio_cread32(vm_dev->base, VIRTIO_MMIO_INTERRUPT_STATUS);
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_INTERRUPT_ACK, status);
+ status = virtio_mmio_cread32(vm_dev->base,
+ VIRTIO_MMIO_INTERRUPT_STATUS);
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_INTERRUPT_ACK, status);
if (unlikely(status & VIRTIO_MMIO_INT_CONFIG)) {
uk_pr_warn("Unsupported config change interrupt received on virtio-mmio device %p\n",
}
/* Select the queue we're interested in */
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_SEL, queue_id);
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_SEL, queue_id);
/* Activate the queue */
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_NUM, num_desc);
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_NUM, num_desc);
if (vm_dev->version == 1) {
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_ALIGN, __PAGE_SIZE);
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_PFN,
- virtqueue_physaddr(vq) >> __PAGE_SHIFT);
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_ALIGN,
+ __PAGE_SIZE);
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_PFN,
+ virtqueue_physaddr(vq) >> __PAGE_SHIFT);
} else {
__u64 addr;
addr = virtqueue_physaddr(vq);
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_DESC_LOW, (__u32)addr);
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_DESC_HIGH,
- (__u32)(addr >> 32));
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_DESC_LOW,
+ (__u32)addr);
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_DESC_HIGH,
+ (__u32)(addr >> 32));
addr = virtqueue_get_avail_addr(vq);
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_AVAIL_LOW, (__u32)addr);
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_AVAIL_HIGH,
- (__u32)(addr >> 32));
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_AVAIL_LOW,
+ (__u32)addr);
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_AVAIL_HIGH,
+ (__u32)(addr >> 32));
addr = virtqueue_get_used_addr(vq);
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_USED_LOW, (__u32)addr);
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_USED_HIGH,
- (__u32)(addr >> 32));
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_USED_LOW,
+ (__u32)addr);
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_USED_HIGH,
+ (__u32)(addr >> 32));
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_READY, 1);
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_READY, 1);
}
flags = ukplat_lcpu_save_irqf();
for (i = 0; i < num_vqs; ++i) {
/* Select the queue we're interested in */
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_SEL, i);
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_QUEUE_SEL, i);
/* Queue shouldn't already be set up. */
- if (virtio_cread32(vm_dev->base, (vm_dev->version == 1 ?
+ if (virtio_mmio_cread32(vm_dev->base, (vm_dev->version == 1 ?
VIRTIO_MMIO_QUEUE_PFN : VIRTIO_MMIO_QUEUE_READY))) {
uk_pr_err("vm_find_vqs error mmio queue not ready\n");
err = -ENOENT;
goto error_exit;
}
- qdesc_size[i] = virtio_cread32(vm_dev->base, VIRTIO_MMIO_QUEUE_NUM_MAX);
+ qdesc_size[i] = virtio_mmio_cread32(vm_dev->base,
+ VIRTIO_MMIO_QUEUE_NUM_MAX);
if (qdesc_size[i] == 0) {
err = -ENOENT;
goto error_exit;
goto free_vmdev;
}
- magic = virtio_cread32(vm_dev->base, VIRTIO_MMIO_MAGIC_VALUE);
+ magic = virtio_mmio_cread32(vm_dev->base, VIRTIO_MMIO_MAGIC_VALUE);
if (magic != ('v' | 'i' << 8 | 'r' << 16 | 't' << 24)) {
uk_pr_err("Wrong magic value 0x%x!\n", magic);
rc = -ENODEV;
}
/* Check device version */
- vm_dev->version = virtio_cread32(vm_dev->base, VIRTIO_MMIO_VERSION);
+ vm_dev->version = virtio_mmio_cread32(vm_dev->base,
+ VIRTIO_MMIO_VERSION);
if (vm_dev->version < 1 || vm_dev->version > 2) {
uk_pr_err("Version %ld not supported!\n", vm_dev->version);
rc = -ENXIO;
goto free_vmdev;
}
- vm_dev->vdev.id.virtio_device_id = virtio_cread32(vm_dev->base, VIRTIO_MMIO_DEVICE_ID);
+ vm_dev->vdev.id.virtio_device_id = virtio_mmio_cread32(vm_dev->base,
+ VIRTIO_MMIO_DEVICE_ID);
if (vm_dev->vdev.id.virtio_device_id == 0) {
/*
* virtio-mmio device with an ID 0 is a (dummy) placeholder
rc = -ENODEV;
goto free_vmdev;
}
- vm_dev->id.vendor = virtio_cread32(vm_dev->base, VIRTIO_MMIO_VENDOR_ID);
+ vm_dev->id.vendor = virtio_mmio_cread32(vm_dev->base,
+ VIRTIO_MMIO_VENDOR_ID);
- virtio_cwrite32(vm_dev->base, VIRTIO_MMIO_GUEST_PAGE_SIZE, __PAGE_SIZE);
+ if (vm_dev->version <= 1)
+ virtio_mmio_cwrite32(vm_dev->base, VIRTIO_MMIO_GUEST_PAGE_SIZE,
+ __PAGE_SIZE);
rc = virtio_bus_register_device(&vm_dev->vdev);
if (rc != 0) {