blob: e1d972dc53275bddfd4966c0295ed91682f9ac06 [file] [log] [blame]
Gleb Natapov89acfa32010-05-10 11:36:37 +03001#ifndef _VIRTIO_PCI_H
2#define _VIRTIO_PCI_H
3
Kevin O'Connor7d09d0e2010-05-10 21:51:38 -04004#include "ioport.h" // inl
5
Gleb Natapov89acfa32010-05-10 11:36:37 +03006/* 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
42static inline u32 vp_get_features(unsigned int ioaddr)
43{
44 return inl(ioaddr + VIRTIO_PCI_HOST_FEATURES);
45}
46
47static inline void vp_set_features(unsigned int ioaddr, u32 features)
48{
49 outl(features, ioaddr + VIRTIO_PCI_GUEST_FEATURES);
50}
51
52static 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
62static inline u8 vp_get_status(unsigned int ioaddr)
63{
64 return inb(ioaddr + VIRTIO_PCI_STATUS);
65}
66
67static 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
Stefan Hajnoczi4e0daae2010-07-07 13:34:22 +010074static inline u8 vp_get_isr(unsigned int ioaddr)
75{
76 return inb(ioaddr + VIRTIO_PCI_ISR);
77}
Gleb Natapov89acfa32010-05-10 11:36:37 +030078
79static inline void vp_reset(unsigned int ioaddr)
80{
81 outb(0, ioaddr + VIRTIO_PCI_STATUS);
82 (void)inb(ioaddr + VIRTIO_PCI_ISR);
83}
84
85static inline void vp_notify(unsigned int ioaddr, int queue_index)
86{
87 outw(queue_index, ioaddr + VIRTIO_PCI_QUEUE_NOTIFY);
88}
89
90static 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
Kevin O'Connor7d09d0e2010-05-10 21:51:38 -0400101struct vring_virtqueue;
Paolo Bonzini4e343322011-11-16 13:02:56 +0100102u16 vp_init_simple(u16 bdf);
Gleb Natapov89acfa32010-05-10 11:36:37 +0300103int vp_find_vq(unsigned int ioaddr, int queue_index,
Paolo Bonzinie1a17bb2011-11-16 13:02:57 +0100104 struct vring_virtqueue **p_vq);
Gleb Natapov89acfa32010-05-10 11:36:37 +0300105#endif /* _VIRTIO_PCI_H_ */