Greg Hartman | 76d05dc | 2016-11-23 15:51:27 -0800 | [diff] [blame] | 1 | #ifndef _VIRTIO_PCI_H_ |
| 2 | # define _VIRTIO_PCI_H_ |
| 3 | |
| 4 | /* A 32-bit r/o bitmask of the features supported by the host */ |
| 5 | #define VIRTIO_PCI_HOST_FEATURES 0 |
| 6 | |
| 7 | /* A 32-bit r/w bitmask of features activated by the guest */ |
| 8 | #define VIRTIO_PCI_GUEST_FEATURES 4 |
| 9 | |
| 10 | /* A 32-bit r/w PFN for the currently selected queue */ |
| 11 | #define VIRTIO_PCI_QUEUE_PFN 8 |
| 12 | |
| 13 | /* A 16-bit r/o queue size for the currently selected queue */ |
| 14 | #define VIRTIO_PCI_QUEUE_NUM 12 |
| 15 | |
| 16 | /* A 16-bit r/w queue selector */ |
| 17 | #define VIRTIO_PCI_QUEUE_SEL 14 |
| 18 | |
| 19 | /* A 16-bit r/w queue notifier */ |
| 20 | #define VIRTIO_PCI_QUEUE_NOTIFY 16 |
| 21 | |
| 22 | /* An 8-bit device status register. */ |
| 23 | #define VIRTIO_PCI_STATUS 18 |
| 24 | |
| 25 | /* An 8-bit r/o interrupt status register. Reading the value will return the |
| 26 | * current contents of the ISR and will also clear it. This is effectively |
| 27 | * a read-and-acknowledge. */ |
| 28 | #define VIRTIO_PCI_ISR 19 |
| 29 | |
| 30 | /* The bit of the ISR which indicates a device configuration change. */ |
| 31 | #define VIRTIO_PCI_ISR_CONFIG 0x2 |
| 32 | |
| 33 | /* The remaining space is defined by each driver as the per-driver |
| 34 | * configuration space */ |
| 35 | #define VIRTIO_PCI_CONFIG 20 |
| 36 | |
| 37 | /* Virtio ABI version, this must match exactly */ |
| 38 | #define VIRTIO_PCI_ABI_VERSION 0 |
| 39 | |
| 40 | static inline u32 vp_get_features(unsigned int ioaddr) |
| 41 | { |
| 42 | return inl(ioaddr + VIRTIO_PCI_HOST_FEATURES); |
| 43 | } |
| 44 | |
| 45 | static inline void vp_set_features(unsigned int ioaddr, u32 features) |
| 46 | { |
| 47 | outl(features, ioaddr + VIRTIO_PCI_GUEST_FEATURES); |
| 48 | } |
| 49 | |
| 50 | static inline void vp_get(unsigned int ioaddr, unsigned offset, |
| 51 | void *buf, unsigned len) |
| 52 | { |
| 53 | u8 *ptr = buf; |
| 54 | unsigned i; |
| 55 | |
| 56 | for (i = 0; i < len; i++) |
| 57 | ptr[i] = inb(ioaddr + VIRTIO_PCI_CONFIG + offset + i); |
| 58 | } |
| 59 | |
| 60 | static inline u8 vp_get_status(unsigned int ioaddr) |
| 61 | { |
| 62 | return inb(ioaddr + VIRTIO_PCI_STATUS); |
| 63 | } |
| 64 | |
| 65 | static inline void vp_set_status(unsigned int ioaddr, u8 status) |
| 66 | { |
| 67 | if (status == 0) /* reset */ |
| 68 | return; |
| 69 | outb(status, ioaddr + VIRTIO_PCI_STATUS); |
| 70 | } |
| 71 | |
| 72 | |
| 73 | static inline void vp_reset(unsigned int ioaddr) |
| 74 | { |
| 75 | outb(0, ioaddr + VIRTIO_PCI_STATUS); |
| 76 | (void)inb(ioaddr + VIRTIO_PCI_ISR); |
| 77 | } |
| 78 | |
| 79 | static inline void vp_notify(unsigned int ioaddr, int queue_index) |
| 80 | { |
| 81 | outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_NOTIFY); |
| 82 | } |
| 83 | |
| 84 | static inline void vp_del_vq(unsigned int ioaddr, int queue_index) |
| 85 | { |
| 86 | /* select the queue */ |
| 87 | |
| 88 | outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_SEL); |
| 89 | |
| 90 | /* deactivate the queue */ |
| 91 | |
| 92 | outl(0, ioaddr + VIRTIO_PCI_QUEUE_PFN); |
| 93 | } |
| 94 | |
| 95 | int vp_find_vq(unsigned int ioaddr, int queue_index, |
| 96 | struct vring_virtqueue *vq); |
| 97 | #endif /* _VIRTIO_PCI_H_ */ |