From ca610c931e2b0004c44f748cb813580b09c60489 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 13 Jan 2012 12:07:42 +1100 Subject: Move virtio to a separate library Signed-off-by: Benjamin Herrenschmidt --- lib/libhvcall/Makefile | 2 +- lib/libhvcall/hvcall.code | 41 ---------- lib/libhvcall/hvcall.in | 7 -- lib/libhvcall/virtio-blk.c | 160 ------------------------------------- lib/libhvcall/virtio-blk.h | 60 -------------- lib/libhvcall/virtio.c | 192 --------------------------------------------- lib/libhvcall/virtio.h | 84 -------------------- 7 files changed, 1 insertion(+), 545 deletions(-) delete mode 100644 lib/libhvcall/virtio-blk.c delete mode 100644 lib/libhvcall/virtio-blk.h delete mode 100644 lib/libhvcall/virtio.c delete mode 100644 lib/libhvcall/virtio.h (limited to 'lib/libhvcall') diff --git a/lib/libhvcall/Makefile b/lib/libhvcall/Makefile index da30a07..53ed98f 100644 --- a/lib/libhvcall/Makefile +++ b/lib/libhvcall/Makefile @@ -22,7 +22,7 @@ TARGET = ../libhvcall.a all: $(TARGET) -SRCS = virtio.c virtio-blk.c +SRCS = SRCSS = hvcall.S diff --git a/lib/libhvcall/hvcall.code b/lib/libhvcall/hvcall.code index e07a2ef..ebaaac8 100644 --- a/lib/libhvcall/hvcall.code +++ b/lib/libhvcall/hvcall.code @@ -11,8 +11,6 @@ *****************************************************************************/ #include -#include -#include // : hv-putchar ( hvtermno char -- ) PRIM(hv_X2d_putchar) @@ -97,42 +95,3 @@ PRIM(RX_X21) hv_logical_ci_store(8, qaddr, val); MIRP - -// : virtio-vring-size ( queuesize -- ringsize ) -PRIM(virtio_X2d_vring_X2d_size) - TOS.u = virtio_vring_size(TOS.u); -MIRP - -// : virtio-get-qsize ( dev queue -- queuesize ) -PRIM(virtio_X2d_get_X2d_qsize) - int queue = TOS.u; POP; - TOS.u = virtio_get_qsize(TOS.a, queue); -MIRP - -// : virtio-get-config ( dev offset size -- val ) -PRIM(virtio_X2d_get_X2d_config) - int size = TOS.u; POP; - int offset = TOS.u; POP; - TOS.u = virtio_get_config(TOS.a, offset, size); -MIRP - -// : virtio-blk-init ( dev -- ) -PRIM(virtio_X2d_blk_X2d_init) - void *dev = TOS.a; POP; - virtioblk_init(dev); -MIRP - -// : virtio-blk-shutdown ( dev -- ) -PRIM(virtio_X2d_blk_X2d_shutdown) - void *dev = TOS.a; POP; - virtioblk_shutdown(dev); -MIRP - -// : virtio-blk-read ( dev blkno cnt reg -- #read ) -PRIM(virtio_X2d_blk_X2d_read) - void *dev = TOS.a; POP; - long cnt = TOS.n; POP; - long blkno = TOS.n; POP; - void *buf = TOS.a; - TOS.n = virtioblk_read(dev, buf, blkno, cnt); -MIRP diff --git a/lib/libhvcall/hvcall.in b/lib/libhvcall/hvcall.in index b28eedf..abbb2c8 100644 --- a/lib/libhvcall/hvcall.in +++ b/lib/libhvcall/hvcall.in @@ -26,10 +26,3 @@ cod(RL@) cod(RL!) cod(RX@) cod(RX!) - -cod(virtio-vring-size) -cod(virtio-get-qsize) -cod(virtio-get-config) -cod(virtio-blk-init) -cod(virtio-blk-shutdown) -cod(virtio-blk-read) diff --git a/lib/libhvcall/virtio-blk.c b/lib/libhvcall/virtio-blk.c deleted file mode 100644 index d4cdb04..0000000 --- a/lib/libhvcall/virtio-blk.c +++ /dev/null @@ -1,160 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#include -#include "virtio.h" -#include "virtio-blk.h" -#include "libhvcall.h" - - -#define sync() asm volatile (" sync \n" ::: "memory") - - -/** - * Initialize virtio-block device. - * @param dev pointer to virtio device information - */ -int -virtioblk_init(struct virtio_device *dev) -{ - struct vring_avail *vq_avail; - - /* Reset device */ - // virtio_reset_device(dev); - - /* Acknowledge device. */ - virtio_set_status(dev, VIRTIO_STAT_ACKNOWLEDGE); - - /* Tell HV that we know how to drive the device. */ - virtio_set_status(dev, VIRTIO_STAT_ACKNOWLEDGE|VIRTIO_STAT_DRIVER); - - /* Device specific setup - we do not support special features right now */ - virtio_set_guest_features(dev, 0); - - vq_avail = virtio_get_vring_avail(dev, 0); - vq_avail->flags = VRING_AVAIL_F_NO_INTERRUPT; - vq_avail->idx = 0; - - /* Tell HV that setup succeeded */ - virtio_set_status(dev, VIRTIO_STAT_ACKNOWLEDGE|VIRTIO_STAT_DRIVER - |VIRTIO_STAT_DRIVER_OK); - - return 0; -} - - -/** - * Shutdown the virtio-block device. - * @param dev pointer to virtio device information - */ -void -virtioblk_shutdown(struct virtio_device *dev) -{ - /* Quiesce device */ - virtio_set_status(dev, VIRTIO_STAT_FAILED); - - /* Reset device */ - virtio_reset_device(dev); -} - - -/** - * Read blocks - * @param reg pointer to "reg" property - * @param buf pointer to destination buffer - * @param blocknum block number of the first block that should be read - * @param cnt amount of blocks that should be read - * @return number of blocks that have been read successfully - */ -int -virtioblk_read(struct virtio_device *dev, char *buf, long blocknum, long cnt) -{ - struct vring_desc *desc; - int id, i; - static struct virtio_blk_req blkhdr; - //struct virtio_blk_config *blkconf; - uint64_t capacity; - uint32_t vq_size; - struct vring_desc *vq_desc; /* Descriptor vring */ - struct vring_avail *vq_avail; /* "Available" vring */ - struct vring_used *vq_used; /* "Used" vring */ - volatile uint8_t status = -1; - volatile uint16_t *current_used_idx; - uint16_t last_used_idx; - - //printf("virtioblk_read: dev=%p buf=%p blocknum=%li count=%li\n", - // dev, buf, blocknum, cnt); - - /* Check whether request is within disk capacity */ - capacity = virtio_get_config(dev, 0, sizeof(capacity)); - if (blocknum + cnt - 1 > capacity) { - puts("virtioblk_read: Access beyond end of device!"); - return 0; - } - - vq_size = virtio_get_qsize(dev, 0); - vq_desc = virtio_get_vring_desc(dev, 0); - vq_avail = virtio_get_vring_avail(dev, 0); - vq_used = virtio_get_vring_used(dev, 0); - - last_used_idx = vq_used->idx; - current_used_idx = &vq_used->idx; - - /* Set up header */ - blkhdr.type = VIRTIO_BLK_T_IN | VIRTIO_BLK_T_BARRIER; - blkhdr.ioprio = 1; - blkhdr.sector = blocknum; - - /* Determine descriptor index */ - id = (vq_avail->idx * 3) % vq_size; - - /* Set up virtqueue descriptor for header */ - desc = &vq_desc[id]; - desc->addr = (uint64_t)&blkhdr; - desc->len = sizeof(struct virtio_blk_req); - desc->flags = VRING_DESC_F_NEXT; - desc->next = (id + 1) % vq_size; - - /* Set up virtqueue descriptor for data */ - desc = &vq_desc[(id + 1) % vq_size]; - desc->addr = (uint64_t)buf; - desc->len = cnt * 512; - desc->flags = VRING_DESC_F_NEXT | VRING_DESC_F_WRITE; - desc->next = (id + 2) % vq_size; - - /* Set up virtqueue descriptor for status */ - desc = &vq_desc[(id + 2) % vq_size]; - desc->addr = (uint64_t)&status; - desc->len = 1; - desc->flags = VRING_DESC_F_WRITE; - desc->next = 0; - - vq_avail->ring[vq_avail->idx % vq_size] = id; - sync(); - vq_avail->idx += 1; - - /* Tell HV that the queue is ready */ - virtio_queue_notify(dev, 0); - - /* Wait for host to consume the descriptor */ - i = 10000000; - while (*current_used_idx == last_used_idx && i-- > 0) { - sync(); - } - - if (status == 0) - return cnt; - - printf("virtioblk_read failed! status = %i\n", status); - - return 0; -} diff --git a/lib/libhvcall/virtio-blk.h b/lib/libhvcall/virtio-blk.h deleted file mode 100644 index 7c2b7e0..0000000 --- a/lib/libhvcall/virtio-blk.h +++ /dev/null @@ -1,60 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -/* - * Virtio block device definitions. - * See Virtio Spec, Appendix D, for details - */ - -#ifndef _VIRTIO_BLK_H -#define _VIRTIO_BLK_H - -#include - - -/* Device configuration layout */ -/* -struct virtio_blk_config { - uint64_t capacity; - uint32_t size_max; - uint32_t seg_max; - struct virtio_blk_geometry { - uint16_t cylinders; - uint8_t heads; - uint8_t sectors; - } geometry; - uint32_t blk_size; - uint32_t sectors_max; -}; -*/ - -/* Block request */ -struct virtio_blk_req { - uint32_t type ; - uint32_t ioprio ; - uint64_t sector ; -}; - -/* Block request types */ -#define VIRTIO_BLK_T_IN 0 -#define VIRTIO_BLK_T_OUT 1 -#define VIRTIO_BLK_T_SCSI_CMD 2 -#define VIRTIO_BLK_T_SCSI_CMD_OUT 3 -#define VIRTIO_BLK_T_FLUSH 4 -#define VIRTIO_BLK_T_FLUSH_OUT 5 -#define VIRTIO_BLK_T_BARRIER 0x80000000 - -extern int virtioblk_init(struct virtio_device *dev); -extern void virtioblk_shutdown(struct virtio_device *dev); -extern int virtioblk_read(struct virtio_device *dev, char *buf, long blocknum, long cnt); - -#endif /* _VIRTIO_BLK_H */ diff --git a/lib/libhvcall/virtio.c b/lib/libhvcall/virtio.c deleted file mode 100644 index 0a3e91b..0000000 --- a/lib/libhvcall/virtio.c +++ /dev/null @@ -1,192 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#include -#include -#include -#include "virtio.h" -#include "libhvcall.h" - -/* PCI virtio header offsets */ -#define VIRTIOHDR_DEVICE_FEATURES 0 -#define VIRTIOHDR_GUEST_FEATURES 4 -#define VIRTIOHDR_QUEUE_ADDRESS 8 -#define VIRTIOHDR_QUEUE_SIZE 12 -#define VIRTIOHDR_QUEUE_SELECT 14 -#define VIRTIOHDR_QUEUE_NOTIFY 16 -#define VIRTIOHDR_DEVICE_STATUS 18 -#define VIRTIOHDR_ISR_STATUS 19 -#define VIRTIOHDR_DEVICE_CONFIG 20 - - -/** - * Calculate ring size according to queue size number - */ -unsigned long virtio_vring_size(unsigned int qsize) -{ - return VQ_ALIGN(sizeof(struct vring_desc) * qsize + 2 * (2 + qsize)) - + VQ_ALIGN(sizeof(struct vring_used_elem) * qsize); -} - - -/** - * Get number of elements in a vring - * @param dev pointer to virtio device information - * @param queue virtio queue number - * @return number of elements - */ -int virtio_get_qsize(struct virtio_device *dev, int queue) -{ - int size = 0; - - if (dev->type == VIRTIO_TYPE_PCI) { - ci_write_16(dev->base+VIRTIOHDR_QUEUE_SELECT, - cpu_to_le16(queue)); - eieio(); - size = le16_to_cpu(ci_read_16(dev->base+VIRTIOHDR_QUEUE_SIZE)); - } - - return size; -} - - -/** - * Get address of descriptor vring - * @param dev pointer to virtio device information - * @param queue virtio queue number - * @return pointer to the descriptor ring - */ -struct vring_desc *virtio_get_vring_desc(struct virtio_device *dev, int queue) -{ - struct vring_desc *desc = 0; - - if (dev->type == VIRTIO_TYPE_PCI) { - ci_write_16(dev->base+VIRTIOHDR_QUEUE_SELECT, - cpu_to_le16(queue)); - eieio(); - desc = (void*)(4096L * - le32_to_cpu(ci_read_32(dev->base+VIRTIOHDR_QUEUE_ADDRESS))); - } - - return desc; -} - - -/** - * Get address of "available" vring - * @param dev pointer to virtio device information - * @param queue virtio queue number - * @return pointer to the "available" ring - */ -struct vring_avail *virtio_get_vring_avail(struct virtio_device *dev, int queue) -{ - return (void*)((uint64_t)virtio_get_vring_desc(dev, queue) - + virtio_get_qsize(dev, queue) * sizeof(struct vring_desc)); -} - - -/** - * Get address of "used" vring - * @param dev pointer to virtio device information - * @param queue virtio queue number - * @return pointer to the "used" ring - */ -struct vring_used *virtio_get_vring_used(struct virtio_device *dev, int queue) -{ - return (void*)VQ_ALIGN((uint64_t)virtio_get_vring_avail(dev, queue) - + virtio_get_qsize(dev, queue) - * sizeof(struct vring_avail)); -} - - -/** - * Reset virtio device - */ -void virtio_reset_device(struct virtio_device *dev) -{ - if (dev->type == VIRTIO_TYPE_PCI) { - ci_write_8(dev->base+VIRTIOHDR_DEVICE_STATUS, 0); - } -} - - -/** - * Notify hypervisor about queue update - */ -void virtio_queue_notify(struct virtio_device *dev, int queue) -{ - if (dev->type == VIRTIO_TYPE_PCI) { - ci_write_16(dev->base+VIRTIOHDR_QUEUE_NOTIFY, cpu_to_le16(queue)); - } -} - - -/** - * Set device status bits - */ -void virtio_set_status(struct virtio_device *dev, int status) -{ - if (dev->type == VIRTIO_TYPE_PCI) { - ci_write_8(dev->base+VIRTIOHDR_DEVICE_STATUS, status); - } -} - - -/** - * Set guest feature bits - */ -void virtio_set_guest_features(struct virtio_device *dev, int features) - -{ - if (dev->type == VIRTIO_TYPE_PCI) { - ci_write_32(dev->base+VIRTIOHDR_GUEST_FEATURES, features); - } -} - - -/** - * Get additional config values - */ -uint64_t virtio_get_config(struct virtio_device *dev, int offset, int size) -{ - uint64_t val = ~0ULL; - void *confbase; - - switch (dev->type) { - case VIRTIO_TYPE_PCI: - confbase = dev->base+VIRTIOHDR_DEVICE_CONFIG; - break; - default: - return ~0ULL; - } - switch (size) { - case 1: - val = ci_read_8(confbase+offset); - break; - case 2: - val = ci_read_16(confbase+offset); - break; - case 4: - val = ci_read_32(confbase+offset); - break; - case 8: - /* We don't support 8 bytes PIO accesses - * in qemu and this is all PIO - */ - val = ci_read_32(confbase+offset); - val <<= 32; - val |= ci_read_32(confbase+offset+4); - break; - } - - return val; -} diff --git a/lib/libhvcall/virtio.h b/lib/libhvcall/virtio.h deleted file mode 100644 index 7355043..0000000 --- a/lib/libhvcall/virtio.h +++ /dev/null @@ -1,84 +0,0 @@ -/****************************************************************************** - * Copyright (c) 2011 IBM Corporation - * All rights reserved. - * This program and the accompanying materials - * are made available under the terms of the BSD License - * which accompanies this distribution, and is available at - * http://www.opensource.org/licenses/bsd-license.php - * - * Contributors: - * IBM Corporation - initial implementation - *****************************************************************************/ - -#ifndef _LIBVIRTIO_H -#define _LIBVIRTIO_H - -#include - -/* Device status bits */ -#define VIRTIO_STAT_ACKNOWLEDGE 1 -#define VIRTIO_STAT_DRIVER 2 -#define VIRTIO_STAT_DRIVER_OK 4 -#define VIRTIO_STAT_FAILED 128 - -/* Definitions for vring_desc.flags */ -#define VRING_DESC_F_NEXT 1 /* buffer continues via the next field */ -#define VRING_DESC_F_WRITE 2 /* buffer is write-only (otherwise read-only) */ -#define VRING_DESC_F_INDIRECT 4 /* buffer contains a list of buffer descriptors */ - -/* Descriptor table entry - see Virtio Spec chapter 2.3.2 */ -struct vring_desc { - uint64_t addr; /* Address (guest-physical) */ - uint32_t len; /* Length */ - uint16_t flags; /* The flags as indicated above */ - uint16_t next; /* Next field if flags & NEXT */ -}; - -/* Definitions for vring_avail.flags */ -#define VRING_AVAIL_F_NO_INTERRUPT 1 - -/* Available ring - see Virtio Spec chapter 2.3.4 */ -struct vring_avail { - uint16_t flags; - uint16_t idx; - uint16_t ring[]; -}; - - -/* Definitions for vring_used.flags */ -#define VRING_USED_F_NO_NOTIFY 1 - -struct vring_used_elem { - uint32_t id; /* Index of start of used descriptor chain */ - uint32_t len; /* Total length of the descriptor chain which was used */ -}; - -struct vring_used { - uint16_t flags; - uint16_t idx; - struct vring_used_elem ring[]; -}; - -#define VIRTIO_TYPE_PCI 0 /* For virtio-pci interface */ -struct virtio_device { - void *base; /* base address */ - int type; /* VIRTIO_TYPE_PCI or VIRTIO_TYPE_VIO */ -}; - -/* Parts of the virtqueue are aligned on a 4096 byte page boundary */ -#define VQ_ALIGN(addr) (((addr) + 0xfff) & ~0xfff) - -extern unsigned long virtio_vring_size(unsigned int qsize); -extern int virtio_get_qsize(struct virtio_device *dev, int queue); -extern struct vring_desc *virtio_get_vring_desc(struct virtio_device *dev, int queue); -extern struct vring_avail *virtio_get_vring_avail(struct virtio_device *dev, int queue); -extern struct vring_used *virtio_get_vring_used(struct virtio_device *dev, int queue); - -extern void virtio_reset_device(struct virtio_device *dev); -extern void virtio_queue_notify(struct virtio_device *dev, int queue); -extern void virtio_set_status(struct virtio_device *dev, int status); -extern void virtio_set_guest_features(struct virtio_device *dev, int features); -extern uint64_t virtio_get_config(struct virtio_device *dev, int offset, int size); - - -#endif /* _LIBVIRTIO_H */ -- cgit v1.1