blob: f0c17e8d2082bfe89d322858aca8455f7ba731ef [file] [log] [blame]
Greg Hartman76d05dc2016-11-23 15:51:27 -08001#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
40static inline u32 vp_get_features(unsigned int ioaddr)
41{
42 return inl(ioaddr + VIRTIO_PCI_HOST_FEATURES);
43}
44
45static inline void vp_set_features(unsigned int ioaddr, u32 features)
46{
47 outl(features, ioaddr + VIRTIO_PCI_GUEST_FEATURES);
48}
49
50static 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
60static inline u8 vp_get_status(unsigned int ioaddr)
61{
62 return inb(ioaddr + VIRTIO_PCI_STATUS);
63}
64
65static 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
73static inline void vp_reset(unsigned int ioaddr)
74{
75 outb(0, ioaddr + VIRTIO_PCI_STATUS);
76 (void)inb(ioaddr + VIRTIO_PCI_ISR);
77}
78
79static inline void vp_notify(unsigned int ioaddr, int queue_index)
80{
81 outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_NOTIFY);
82}
83
84static 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
95int vp_find_vq(unsigned int ioaddr, int queue_index,
96 struct vring_virtqueue *vq);
97#endif /* _VIRTIO_PCI_H_ */