aboutsummaryrefslogtreecommitdiff
path: root/lib/libhvcall
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-01-13 12:07:42 +1100
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2012-01-19 17:17:50 +1100
commitca610c931e2b0004c44f748cb813580b09c60489 (patch)
treecf17ebaa02078827068b534bb95d4540bd848678 /lib/libhvcall
parentadde61dfebe5ba4c519b120e8b33f1f8a3c93151 (diff)
downloadSLOF-ca610c931e2b0004c44f748cb813580b09c60489.zip
SLOF-ca610c931e2b0004c44f748cb813580b09c60489.tar.gz
SLOF-ca610c931e2b0004c44f748cb813580b09c60489.tar.bz2
Move virtio to a separate library
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'lib/libhvcall')
-rw-r--r--lib/libhvcall/Makefile2
-rw-r--r--lib/libhvcall/hvcall.code41
-rw-r--r--lib/libhvcall/hvcall.in7
-rw-r--r--lib/libhvcall/virtio-blk.c160
-rw-r--r--lib/libhvcall/virtio-blk.h60
-rw-r--r--lib/libhvcall/virtio.c192
-rw-r--r--lib/libhvcall/virtio.h84
7 files changed, 1 insertions, 545 deletions
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 <libhvcall.h>
-#include <virtio.h>
-#include <virtio-blk.h>
// : 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 <stdio.h>
-#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 <stdint.h>
-
-
-/* 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 <cpu.h>
-#include <cache.h>
-#include <byteorder.h>
-#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 <stdint.h>
-
-/* 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 */