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