Annotation of qemu/roms/SLOF/lib/libvirtio/virtio.c, revision 1.1.1.1

1.1       root        1: /******************************************************************************
                      2:  * Copyright (c) 2011 IBM Corporation
                      3:  * All rights reserved.
                      4:  * This program and the accompanying materials
                      5:  * are made available under the terms of the BSD License
                      6:  * which accompanies this distribution, and is available at
                      7:  * http://www.opensource.org/licenses/bsd-license.php
                      8:  *
                      9:  * Contributors:
                     10:  *     IBM Corporation - initial implementation
                     11:  *****************************************************************************/
                     12: 
                     13: #include <cpu.h>
                     14: #include <cache.h>
                     15: #include <byteorder.h>
                     16: #include "virtio.h"
                     17: 
                     18: /* PCI virtio header offsets */
                     19: #define VIRTIOHDR_DEVICE_FEATURES      0
                     20: #define VIRTIOHDR_GUEST_FEATURES       4
                     21: #define VIRTIOHDR_QUEUE_ADDRESS        8
                     22: #define VIRTIOHDR_QUEUE_SIZE           12
                     23: #define VIRTIOHDR_QUEUE_SELECT         14
                     24: #define VIRTIOHDR_QUEUE_NOTIFY         16
                     25: #define VIRTIOHDR_DEVICE_STATUS        18
                     26: #define VIRTIOHDR_ISR_STATUS           19
                     27: #define VIRTIOHDR_DEVICE_CONFIG        20
                     28: 
                     29: 
                     30: /**
                     31:  * Calculate ring size according to queue size number
                     32:  */
                     33: unsigned long virtio_vring_size(unsigned int qsize)
                     34: {
                     35:        return VQ_ALIGN(sizeof(struct vring_desc) * qsize + 2 * (2 + qsize))
                     36:                + VQ_ALIGN(sizeof(struct vring_used_elem) * qsize);
                     37: }
                     38: 
                     39: 
                     40: /**
                     41:  * Get number of elements in a vring
                     42:  * @param   dev  pointer to virtio device information
                     43:  * @param   queue virtio queue number
                     44:  * @return  number of elements
                     45:  */
                     46: int virtio_get_qsize(struct virtio_device *dev, int queue)
                     47: {
                     48:        int size = 0;
                     49: 
                     50:        if (dev->type == VIRTIO_TYPE_PCI) {
                     51:                ci_write_16(dev->base+VIRTIOHDR_QUEUE_SELECT,
                     52:                            cpu_to_le16(queue));
                     53:                eieio();
                     54:                size = le16_to_cpu(ci_read_16(dev->base+VIRTIOHDR_QUEUE_SIZE));
                     55:        }
                     56: 
                     57:        return size;
                     58: }
                     59: 
                     60: 
                     61: /**
                     62:  * Get address of descriptor vring
                     63:  * @param   dev  pointer to virtio device information
                     64:  * @param   queue virtio queue number
                     65:  * @return  pointer to the descriptor ring
                     66:  */
                     67: struct vring_desc *virtio_get_vring_desc(struct virtio_device *dev, int queue)
                     68: {
                     69:        struct vring_desc *desc = 0;
                     70: 
                     71:        if (dev->type == VIRTIO_TYPE_PCI) {
                     72:                ci_write_16(dev->base+VIRTIOHDR_QUEUE_SELECT,
                     73:                            cpu_to_le16(queue));
                     74:                eieio();
                     75:                desc = (void*)(4096L *
                     76:                   le32_to_cpu(ci_read_32(dev->base+VIRTIOHDR_QUEUE_ADDRESS)));
                     77:        }
                     78: 
                     79:        return desc;
                     80: }
                     81: 
                     82: 
                     83: /**
                     84:  * Get address of "available" vring
                     85:  * @param   dev  pointer to virtio device information
                     86:  * @param   queue virtio queue number
                     87:  * @return  pointer to the "available" ring
                     88:  */
                     89: struct vring_avail *virtio_get_vring_avail(struct virtio_device *dev, int queue)
                     90: {
                     91:        return (void*)((uint64_t)virtio_get_vring_desc(dev, queue)
                     92:                        + virtio_get_qsize(dev, queue) * sizeof(struct vring_desc));
                     93: }
                     94: 
                     95: 
                     96: /**
                     97:  * Get address of "used" vring
                     98:  * @param   dev  pointer to virtio device information
                     99:  * @param   queue virtio queue number
                    100:  * @return  pointer to the "used" ring
                    101:  */
                    102: struct vring_used *virtio_get_vring_used(struct virtio_device *dev, int queue)
                    103: {
                    104:        return (void*)VQ_ALIGN((uint64_t)virtio_get_vring_avail(dev, queue)
                    105:                                  + virtio_get_qsize(dev, queue)
                    106:                                    * sizeof(struct vring_avail));
                    107: }
                    108: 
                    109: 
                    110: /**
                    111:  * Reset virtio device
                    112:  */
                    113: void virtio_reset_device(struct virtio_device *dev)
                    114: {
                    115:        if (dev->type == VIRTIO_TYPE_PCI) {
                    116:                ci_write_8(dev->base+VIRTIOHDR_DEVICE_STATUS, 0);
                    117:        }
                    118: }
                    119: 
                    120: 
                    121: /**
                    122:  * Notify hypervisor about queue update
                    123:  */
                    124: void virtio_queue_notify(struct virtio_device *dev, int queue)
                    125: {
                    126:        if (dev->type == VIRTIO_TYPE_PCI) {
                    127:                ci_write_16(dev->base+VIRTIOHDR_QUEUE_NOTIFY, cpu_to_le16(queue));
                    128:        }
                    129: }
                    130: 
                    131: 
                    132: /**
                    133:  * Set device status bits
                    134:  */
                    135: void virtio_set_status(struct virtio_device *dev, int status)
                    136: {
                    137:        if (dev->type == VIRTIO_TYPE_PCI) {
                    138:                ci_write_8(dev->base+VIRTIOHDR_DEVICE_STATUS, status);
                    139:        }
                    140: }
                    141: 
                    142: 
                    143: /**
                    144:  * Set guest feature bits
                    145:  */
                    146: void virtio_set_guest_features(struct virtio_device *dev, int features)
                    147: 
                    148: {
                    149:        if (dev->type == VIRTIO_TYPE_PCI) {
                    150:                ci_write_32(dev->base+VIRTIOHDR_GUEST_FEATURES, features);
                    151:        }
                    152: }
                    153: 
                    154: 
                    155: /**
                    156:  * Get additional config values
                    157:  */
                    158: uint64_t virtio_get_config(struct virtio_device *dev, int offset, int size)
                    159: {
                    160:        uint64_t val = ~0ULL;
                    161:        void *confbase;
                    162: 
                    163:        switch (dev->type) {
                    164:         case VIRTIO_TYPE_PCI:
                    165:                confbase = dev->base+VIRTIOHDR_DEVICE_CONFIG;
                    166:                break;
                    167:         default:
                    168:                return ~0ULL;
                    169:        }
                    170:        switch (size) {
                    171:         case 1:
                    172:                val = ci_read_8(confbase+offset);
                    173:                break;
                    174:         case 2:
                    175:                val = ci_read_16(confbase+offset);
                    176:                break;
                    177:         case 4:
                    178:                val = ci_read_32(confbase+offset);
                    179:                break;
                    180:         case 8:
                    181:                /* We don't support 8 bytes PIO accesses
                    182:                 * in qemu and this is all PIO
                    183:                 */
                    184:                val = ci_read_32(confbase+offset);
                    185:                val <<= 32;
                    186:                val |= ci_read_32(confbase+offset+4);
                    187:                break;
                    188:        }
                    189: 
                    190:        return val;
                    191: }
                    192: 
                    193: /**
                    194:  * Get config blob
                    195:  */
                    196: int __virtio_read_config(struct virtio_device *dev, void *dst,
                    197:                          int offset, int len)
                    198: {
                    199:        void *confbase;
                    200:        unsigned char *buf = dst;
                    201:        int i;
                    202: 
                    203:        switch (dev->type) {
                    204:         case VIRTIO_TYPE_PCI:
                    205:                confbase = dev->base+VIRTIOHDR_DEVICE_CONFIG;
                    206:                break;
                    207:         default:
                    208:                return 0;
                    209:        }
                    210:        for (i = 0; i < len; i++)
                    211:                buf[i] = ci_read_8(confbase + offset + i);
                    212:        return len;
                    213: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.