root / hw / virtio-pci.c @ 15a1956a
History | View | Annotate | Download (10.3 kB)
1 | 53c25cea | Paul Brook | /*
|
---|---|---|---|
2 | 53c25cea | Paul Brook | * Virtio PCI Bindings
|
3 | 53c25cea | Paul Brook | *
|
4 | 53c25cea | Paul Brook | * Copyright IBM, Corp. 2007
|
5 | 53c25cea | Paul Brook | * Copyright (c) 2009 CodeSourcery
|
6 | 53c25cea | Paul Brook | *
|
7 | 53c25cea | Paul Brook | * Authors:
|
8 | 53c25cea | Paul Brook | * Anthony Liguori <aliguori@us.ibm.com>
|
9 | 53c25cea | Paul Brook | * Paul Brook <paul@codesourcery.com>
|
10 | 53c25cea | Paul Brook | *
|
11 | 53c25cea | Paul Brook | * This work is licensed under the terms of the GNU GPL, version 2. See
|
12 | 53c25cea | Paul Brook | * the COPYING file in the top-level directory.
|
13 | 53c25cea | Paul Brook | *
|
14 | 53c25cea | Paul Brook | */
|
15 | 53c25cea | Paul Brook | |
16 | 53c25cea | Paul Brook | #include <inttypes.h> |
17 | 53c25cea | Paul Brook | |
18 | 53c25cea | Paul Brook | #include "virtio.h" |
19 | 53c25cea | Paul Brook | #include "pci.h" |
20 | 1ad2134f | Paul Brook | //#include "sysemu.h"
|
21 | 53c25cea | Paul Brook | |
22 | 53c25cea | Paul Brook | /* from Linux's linux/virtio_pci.h */
|
23 | 53c25cea | Paul Brook | |
24 | 53c25cea | Paul Brook | /* A 32-bit r/o bitmask of the features supported by the host */
|
25 | 53c25cea | Paul Brook | #define VIRTIO_PCI_HOST_FEATURES 0 |
26 | 53c25cea | Paul Brook | |
27 | 53c25cea | Paul Brook | /* A 32-bit r/w bitmask of features activated by the guest */
|
28 | 53c25cea | Paul Brook | #define VIRTIO_PCI_GUEST_FEATURES 4 |
29 | 53c25cea | Paul Brook | |
30 | 53c25cea | Paul Brook | /* A 32-bit r/w PFN for the currently selected queue */
|
31 | 53c25cea | Paul Brook | #define VIRTIO_PCI_QUEUE_PFN 8 |
32 | 53c25cea | Paul Brook | |
33 | 53c25cea | Paul Brook | /* A 16-bit r/o queue size for the currently selected queue */
|
34 | 53c25cea | Paul Brook | #define VIRTIO_PCI_QUEUE_NUM 12 |
35 | 53c25cea | Paul Brook | |
36 | 53c25cea | Paul Brook | /* A 16-bit r/w queue selector */
|
37 | 53c25cea | Paul Brook | #define VIRTIO_PCI_QUEUE_SEL 14 |
38 | 53c25cea | Paul Brook | |
39 | 53c25cea | Paul Brook | /* A 16-bit r/w queue notifier */
|
40 | 53c25cea | Paul Brook | #define VIRTIO_PCI_QUEUE_NOTIFY 16 |
41 | 53c25cea | Paul Brook | |
42 | 53c25cea | Paul Brook | /* An 8-bit device status register. */
|
43 | 53c25cea | Paul Brook | #define VIRTIO_PCI_STATUS 18 |
44 | 53c25cea | Paul Brook | |
45 | 53c25cea | Paul Brook | /* An 8-bit r/o interrupt status register. Reading the value will return the
|
46 | 53c25cea | Paul Brook | * current contents of the ISR and will also clear it. This is effectively
|
47 | 53c25cea | Paul Brook | * a read-and-acknowledge. */
|
48 | 53c25cea | Paul Brook | #define VIRTIO_PCI_ISR 19 |
49 | 53c25cea | Paul Brook | |
50 | 53c25cea | Paul Brook | #define VIRTIO_PCI_CONFIG 20 |
51 | 53c25cea | Paul Brook | |
52 | 53c25cea | Paul Brook | /* Virtio ABI version, if we increment this, we break the guest driver. */
|
53 | 53c25cea | Paul Brook | #define VIRTIO_PCI_ABI_VERSION 0 |
54 | 53c25cea | Paul Brook | |
55 | 53c25cea | Paul Brook | /* How many bits to shift physical queue address written to QUEUE_PFN.
|
56 | 53c25cea | Paul Brook | * 12 is historical, and due to x86 page size. */
|
57 | 53c25cea | Paul Brook | #define VIRTIO_PCI_QUEUE_ADDR_SHIFT 12 |
58 | 53c25cea | Paul Brook | |
59 | 53c25cea | Paul Brook | /* QEMU doesn't strictly need write barriers since everything runs in
|
60 | 53c25cea | Paul Brook | * lock-step. We'll leave the calls to wmb() in though to make it obvious for
|
61 | 53c25cea | Paul Brook | * KVM or if kqemu gets SMP support.
|
62 | 53c25cea | Paul Brook | */
|
63 | 53c25cea | Paul Brook | #define wmb() do { } while (0) |
64 | 53c25cea | Paul Brook | |
65 | 53c25cea | Paul Brook | /* PCI bindings. */
|
66 | 53c25cea | Paul Brook | |
67 | 53c25cea | Paul Brook | typedef struct { |
68 | 53c25cea | Paul Brook | PCIDevice pci_dev; |
69 | 53c25cea | Paul Brook | VirtIODevice *vdev; |
70 | 53c25cea | Paul Brook | uint32_t addr; |
71 | 53c25cea | Paul Brook | |
72 | 53c25cea | Paul Brook | uint16_t vendor; |
73 | 53c25cea | Paul Brook | uint16_t device; |
74 | 53c25cea | Paul Brook | uint16_t subvendor; |
75 | 53c25cea | Paul Brook | uint16_t class_code; |
76 | 53c25cea | Paul Brook | uint8_t pif; |
77 | 53c25cea | Paul Brook | } VirtIOPCIProxy; |
78 | 53c25cea | Paul Brook | |
79 | 53c25cea | Paul Brook | /* virtio device */
|
80 | 53c25cea | Paul Brook | |
81 | 53c25cea | Paul Brook | static void virtio_pci_update_irq(void *opaque) |
82 | 53c25cea | Paul Brook | { |
83 | 53c25cea | Paul Brook | VirtIOPCIProxy *proxy = opaque; |
84 | 53c25cea | Paul Brook | |
85 | 53c25cea | Paul Brook | qemu_set_irq(proxy->pci_dev.irq[0], proxy->vdev->isr & 1); |
86 | 53c25cea | Paul Brook | } |
87 | 53c25cea | Paul Brook | |
88 | 53c25cea | Paul Brook | static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
89 | 53c25cea | Paul Brook | { |
90 | 53c25cea | Paul Brook | VirtIOPCIProxy *proxy = opaque; |
91 | 53c25cea | Paul Brook | VirtIODevice *vdev = proxy->vdev; |
92 | 53c25cea | Paul Brook | target_phys_addr_t pa; |
93 | 53c25cea | Paul Brook | |
94 | 53c25cea | Paul Brook | addr -= proxy->addr; |
95 | 53c25cea | Paul Brook | |
96 | 53c25cea | Paul Brook | switch (addr) {
|
97 | 53c25cea | Paul Brook | case VIRTIO_PCI_GUEST_FEATURES:
|
98 | 53c25cea | Paul Brook | /* Guest does not negotiate properly? We have to assume nothing. */
|
99 | 53c25cea | Paul Brook | if (val & (1 << VIRTIO_F_BAD_FEATURE)) { |
100 | 53c25cea | Paul Brook | if (vdev->bad_features)
|
101 | 53c25cea | Paul Brook | val = vdev->bad_features(vdev); |
102 | 53c25cea | Paul Brook | else
|
103 | 53c25cea | Paul Brook | val = 0;
|
104 | 53c25cea | Paul Brook | } |
105 | 53c25cea | Paul Brook | if (vdev->set_features)
|
106 | 53c25cea | Paul Brook | vdev->set_features(vdev, val); |
107 | 53c25cea | Paul Brook | vdev->features = val; |
108 | 53c25cea | Paul Brook | break;
|
109 | 53c25cea | Paul Brook | case VIRTIO_PCI_QUEUE_PFN:
|
110 | 53c25cea | Paul Brook | pa = (target_phys_addr_t)val << VIRTIO_PCI_QUEUE_ADDR_SHIFT; |
111 | 53c25cea | Paul Brook | virtio_queue_set_addr(vdev, vdev->queue_sel, pa); |
112 | 53c25cea | Paul Brook | break;
|
113 | 53c25cea | Paul Brook | case VIRTIO_PCI_QUEUE_SEL:
|
114 | 53c25cea | Paul Brook | if (val < VIRTIO_PCI_QUEUE_MAX)
|
115 | 53c25cea | Paul Brook | vdev->queue_sel = val; |
116 | 53c25cea | Paul Brook | break;
|
117 | 53c25cea | Paul Brook | case VIRTIO_PCI_QUEUE_NOTIFY:
|
118 | 53c25cea | Paul Brook | virtio_queue_notify(vdev, val); |
119 | 53c25cea | Paul Brook | break;
|
120 | 53c25cea | Paul Brook | case VIRTIO_PCI_STATUS:
|
121 | 53c25cea | Paul Brook | vdev->status = val & 0xFF;
|
122 | 53c25cea | Paul Brook | if (vdev->status == 0) |
123 | 53c25cea | Paul Brook | virtio_reset(vdev); |
124 | 53c25cea | Paul Brook | break;
|
125 | 53c25cea | Paul Brook | } |
126 | 53c25cea | Paul Brook | } |
127 | 53c25cea | Paul Brook | |
128 | 53c25cea | Paul Brook | static uint32_t virtio_ioport_read(void *opaque, uint32_t addr) |
129 | 53c25cea | Paul Brook | { |
130 | 53c25cea | Paul Brook | VirtIOPCIProxy *proxy = opaque; |
131 | 53c25cea | Paul Brook | VirtIODevice *vdev = proxy->vdev; |
132 | 53c25cea | Paul Brook | uint32_t ret = 0xFFFFFFFF;
|
133 | 53c25cea | Paul Brook | |
134 | 53c25cea | Paul Brook | addr -= proxy->addr; |
135 | 53c25cea | Paul Brook | |
136 | 53c25cea | Paul Brook | switch (addr) {
|
137 | 53c25cea | Paul Brook | case VIRTIO_PCI_HOST_FEATURES:
|
138 | 53c25cea | Paul Brook | ret = vdev->get_features(vdev); |
139 | 53c25cea | Paul Brook | ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY) | (1 << VIRTIO_F_BAD_FEATURE); |
140 | 53c25cea | Paul Brook | break;
|
141 | 53c25cea | Paul Brook | case VIRTIO_PCI_GUEST_FEATURES:
|
142 | 53c25cea | Paul Brook | ret = vdev->features; |
143 | 53c25cea | Paul Brook | break;
|
144 | 53c25cea | Paul Brook | case VIRTIO_PCI_QUEUE_PFN:
|
145 | 53c25cea | Paul Brook | ret = virtio_queue_get_addr(vdev, vdev->queue_sel) |
146 | 53c25cea | Paul Brook | >> VIRTIO_PCI_QUEUE_ADDR_SHIFT; |
147 | 53c25cea | Paul Brook | break;
|
148 | 53c25cea | Paul Brook | case VIRTIO_PCI_QUEUE_NUM:
|
149 | 53c25cea | Paul Brook | ret = virtio_queue_get_num(vdev, vdev->queue_sel); |
150 | 53c25cea | Paul Brook | break;
|
151 | 53c25cea | Paul Brook | case VIRTIO_PCI_QUEUE_SEL:
|
152 | 53c25cea | Paul Brook | ret = vdev->queue_sel; |
153 | 53c25cea | Paul Brook | break;
|
154 | 53c25cea | Paul Brook | case VIRTIO_PCI_STATUS:
|
155 | 53c25cea | Paul Brook | ret = vdev->status; |
156 | 53c25cea | Paul Brook | break;
|
157 | 53c25cea | Paul Brook | case VIRTIO_PCI_ISR:
|
158 | 53c25cea | Paul Brook | /* reading from the ISR also clears it. */
|
159 | 53c25cea | Paul Brook | ret = vdev->isr; |
160 | 53c25cea | Paul Brook | vdev->isr = 0;
|
161 | 53c25cea | Paul Brook | virtio_update_irq(vdev); |
162 | 53c25cea | Paul Brook | break;
|
163 | 53c25cea | Paul Brook | default:
|
164 | 53c25cea | Paul Brook | break;
|
165 | 53c25cea | Paul Brook | } |
166 | 53c25cea | Paul Brook | |
167 | 53c25cea | Paul Brook | return ret;
|
168 | 53c25cea | Paul Brook | } |
169 | 53c25cea | Paul Brook | |
170 | 53c25cea | Paul Brook | static uint32_t virtio_pci_config_readb(void *opaque, uint32_t addr) |
171 | 53c25cea | Paul Brook | { |
172 | 53c25cea | Paul Brook | VirtIOPCIProxy *proxy = opaque; |
173 | 53c25cea | Paul Brook | addr -= proxy->addr + VIRTIO_PCI_CONFIG; |
174 | 53c25cea | Paul Brook | return virtio_config_readb(proxy->vdev, addr);
|
175 | 53c25cea | Paul Brook | } |
176 | 53c25cea | Paul Brook | |
177 | 53c25cea | Paul Brook | static uint32_t virtio_pci_config_readw(void *opaque, uint32_t addr) |
178 | 53c25cea | Paul Brook | { |
179 | 53c25cea | Paul Brook | VirtIOPCIProxy *proxy = opaque; |
180 | 53c25cea | Paul Brook | addr -= proxy->addr + VIRTIO_PCI_CONFIG; |
181 | 53c25cea | Paul Brook | return virtio_config_readw(proxy->vdev, addr);
|
182 | 53c25cea | Paul Brook | } |
183 | 53c25cea | Paul Brook | |
184 | 53c25cea | Paul Brook | static uint32_t virtio_pci_config_readl(void *opaque, uint32_t addr) |
185 | 53c25cea | Paul Brook | { |
186 | 53c25cea | Paul Brook | VirtIOPCIProxy *proxy = opaque; |
187 | 53c25cea | Paul Brook | addr -= proxy->addr + VIRTIO_PCI_CONFIG; |
188 | 53c25cea | Paul Brook | return virtio_config_readl(proxy->vdev, addr);
|
189 | 53c25cea | Paul Brook | } |
190 | 53c25cea | Paul Brook | |
191 | 53c25cea | Paul Brook | static void virtio_pci_config_writeb(void *opaque, uint32_t addr, uint32_t val) |
192 | 53c25cea | Paul Brook | { |
193 | 53c25cea | Paul Brook | VirtIOPCIProxy *proxy = opaque; |
194 | 53c25cea | Paul Brook | addr -= proxy->addr + VIRTIO_PCI_CONFIG; |
195 | 53c25cea | Paul Brook | virtio_config_writeb(proxy->vdev, addr, val); |
196 | 53c25cea | Paul Brook | } |
197 | 53c25cea | Paul Brook | |
198 | 53c25cea | Paul Brook | static void virtio_pci_config_writew(void *opaque, uint32_t addr, uint32_t val) |
199 | 53c25cea | Paul Brook | { |
200 | 53c25cea | Paul Brook | VirtIOPCIProxy *proxy = opaque; |
201 | 53c25cea | Paul Brook | addr -= proxy->addr + VIRTIO_PCI_CONFIG; |
202 | 53c25cea | Paul Brook | virtio_config_writew(proxy->vdev, addr, val); |
203 | 53c25cea | Paul Brook | } |
204 | 53c25cea | Paul Brook | |
205 | 53c25cea | Paul Brook | static void virtio_pci_config_writel(void *opaque, uint32_t addr, uint32_t val) |
206 | 53c25cea | Paul Brook | { |
207 | 53c25cea | Paul Brook | VirtIOPCIProxy *proxy = opaque; |
208 | 53c25cea | Paul Brook | addr -= proxy->addr + VIRTIO_PCI_CONFIG; |
209 | 53c25cea | Paul Brook | virtio_config_writel(proxy->vdev, addr, val); |
210 | 53c25cea | Paul Brook | } |
211 | 53c25cea | Paul Brook | |
212 | 53c25cea | Paul Brook | static void virtio_map(PCIDevice *pci_dev, int region_num, |
213 | 53c25cea | Paul Brook | uint32_t addr, uint32_t size, int type)
|
214 | 53c25cea | Paul Brook | { |
215 | 53c25cea | Paul Brook | VirtIOPCIProxy *proxy = container_of(pci_dev, VirtIOPCIProxy, pci_dev); |
216 | 53c25cea | Paul Brook | VirtIODevice *vdev = proxy->vdev; |
217 | 53c25cea | Paul Brook | int i;
|
218 | 53c25cea | Paul Brook | |
219 | 53c25cea | Paul Brook | proxy->addr = addr; |
220 | 53c25cea | Paul Brook | for (i = 0; i < 3; i++) { |
221 | 53c25cea | Paul Brook | register_ioport_write(addr, VIRTIO_PCI_CONFIG, 1 << i,
|
222 | 53c25cea | Paul Brook | virtio_ioport_write, proxy); |
223 | 53c25cea | Paul Brook | register_ioport_read(addr, VIRTIO_PCI_CONFIG, 1 << i,
|
224 | 53c25cea | Paul Brook | virtio_ioport_read, proxy); |
225 | 53c25cea | Paul Brook | } |
226 | 53c25cea | Paul Brook | |
227 | 53c25cea | Paul Brook | if (vdev->config_len) {
|
228 | 53c25cea | Paul Brook | register_ioport_write(addr + VIRTIO_PCI_CONFIG, vdev->config_len, 1,
|
229 | 53c25cea | Paul Brook | virtio_pci_config_writeb, proxy); |
230 | 53c25cea | Paul Brook | register_ioport_write(addr + VIRTIO_PCI_CONFIG, vdev->config_len, 2,
|
231 | 53c25cea | Paul Brook | virtio_pci_config_writew, proxy); |
232 | 53c25cea | Paul Brook | register_ioport_write(addr + VIRTIO_PCI_CONFIG, vdev->config_len, 4,
|
233 | 53c25cea | Paul Brook | virtio_pci_config_writel, proxy); |
234 | 53c25cea | Paul Brook | register_ioport_read(addr + VIRTIO_PCI_CONFIG, vdev->config_len, 1,
|
235 | 53c25cea | Paul Brook | virtio_pci_config_readb, proxy); |
236 | 53c25cea | Paul Brook | register_ioport_read(addr + VIRTIO_PCI_CONFIG, vdev->config_len, 2,
|
237 | 53c25cea | Paul Brook | virtio_pci_config_readw, proxy); |
238 | 53c25cea | Paul Brook | register_ioport_read(addr + VIRTIO_PCI_CONFIG, vdev->config_len, 4,
|
239 | 53c25cea | Paul Brook | virtio_pci_config_readl, proxy); |
240 | 53c25cea | Paul Brook | |
241 | 53c25cea | Paul Brook | vdev->get_config(vdev, vdev->config); |
242 | 53c25cea | Paul Brook | } |
243 | 53c25cea | Paul Brook | } |
244 | 53c25cea | Paul Brook | |
245 | 53c25cea | Paul Brook | static const VirtIOBindings virtio_pci_bindings = { |
246 | 53c25cea | Paul Brook | .update_irq = virtio_pci_update_irq |
247 | 53c25cea | Paul Brook | }; |
248 | 53c25cea | Paul Brook | |
249 | 53c25cea | Paul Brook | static void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev, |
250 | 53c25cea | Paul Brook | uint16_t vendor, uint16_t device, |
251 | 53c25cea | Paul Brook | uint16_t class_code, uint8_t pif) |
252 | 53c25cea | Paul Brook | { |
253 | 53c25cea | Paul Brook | uint8_t *config; |
254 | 53c25cea | Paul Brook | uint32_t size; |
255 | 53c25cea | Paul Brook | |
256 | 53c25cea | Paul Brook | proxy->vdev = vdev; |
257 | 53c25cea | Paul Brook | |
258 | 53c25cea | Paul Brook | config = proxy->pci_dev.config; |
259 | 53c25cea | Paul Brook | pci_config_set_vendor_id(config, vendor); |
260 | 53c25cea | Paul Brook | pci_config_set_device_id(config, device); |
261 | 53c25cea | Paul Brook | |
262 | 53c25cea | Paul Brook | config[0x08] = VIRTIO_PCI_ABI_VERSION;
|
263 | 53c25cea | Paul Brook | |
264 | 53c25cea | Paul Brook | config[0x09] = pif;
|
265 | 53c25cea | Paul Brook | pci_config_set_class(config, class_code); |
266 | 53c25cea | Paul Brook | config[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_NORMAL; |
267 | 53c25cea | Paul Brook | |
268 | 53c25cea | Paul Brook | config[0x2c] = vendor & 0xFF; |
269 | 53c25cea | Paul Brook | config[0x2d] = (vendor >> 8) & 0xFF; |
270 | 53c25cea | Paul Brook | config[0x2e] = vdev->device_id & 0xFF; |
271 | 53c25cea | Paul Brook | config[0x2f] = (vdev->device_id >> 8) & 0xFF; |
272 | 53c25cea | Paul Brook | |
273 | 53c25cea | Paul Brook | config[0x3d] = 1; |
274 | 53c25cea | Paul Brook | |
275 | 53c25cea | Paul Brook | size = 20 + vdev->config_len;
|
276 | 53c25cea | Paul Brook | if (size & (size-1)) |
277 | 53c25cea | Paul Brook | size = 1 << qemu_fls(size);
|
278 | 53c25cea | Paul Brook | |
279 | 28c2c264 | Avi Kivity | pci_register_bar(&proxy->pci_dev, 0, size, PCI_ADDRESS_SPACE_IO,
|
280 | 53c25cea | Paul Brook | virtio_map); |
281 | 53c25cea | Paul Brook | |
282 | 53c25cea | Paul Brook | virtio_bind_device(vdev, &virtio_pci_bindings, proxy); |
283 | 53c25cea | Paul Brook | } |
284 | 53c25cea | Paul Brook | |
285 | 53c25cea | Paul Brook | static void virtio_blk_init_pci(PCIDevice *pci_dev) |
286 | 53c25cea | Paul Brook | { |
287 | 53c25cea | Paul Brook | VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); |
288 | 53c25cea | Paul Brook | VirtIODevice *vdev; |
289 | 53c25cea | Paul Brook | |
290 | 53c25cea | Paul Brook | vdev = virtio_blk_init(&pci_dev->qdev); |
291 | 53c25cea | Paul Brook | virtio_init_pci(proxy, vdev, |
292 | 53c25cea | Paul Brook | PCI_VENDOR_ID_REDHAT_QUMRANET, |
293 | 53c25cea | Paul Brook | PCI_DEVICE_ID_VIRTIO_BLOCK, |
294 | 53c25cea | Paul Brook | PCI_CLASS_STORAGE_OTHER, |
295 | 53c25cea | Paul Brook | 0x00);
|
296 | 53c25cea | Paul Brook | } |
297 | 53c25cea | Paul Brook | |
298 | 53c25cea | Paul Brook | static void virtio_console_init_pci(PCIDevice *pci_dev) |
299 | 53c25cea | Paul Brook | { |
300 | 53c25cea | Paul Brook | VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); |
301 | 53c25cea | Paul Brook | VirtIODevice *vdev; |
302 | 53c25cea | Paul Brook | |
303 | 53c25cea | Paul Brook | vdev = virtio_console_init(&pci_dev->qdev); |
304 | 53c25cea | Paul Brook | virtio_init_pci(proxy, vdev, |
305 | 53c25cea | Paul Brook | PCI_VENDOR_ID_REDHAT_QUMRANET, |
306 | 53c25cea | Paul Brook | PCI_DEVICE_ID_VIRTIO_CONSOLE, |
307 | 53c25cea | Paul Brook | PCI_CLASS_DISPLAY_OTHER, |
308 | 53c25cea | Paul Brook | 0x00);
|
309 | 53c25cea | Paul Brook | } |
310 | 53c25cea | Paul Brook | |
311 | 53c25cea | Paul Brook | static void virtio_net_init_pci(PCIDevice *pci_dev) |
312 | 53c25cea | Paul Brook | { |
313 | 53c25cea | Paul Brook | VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); |
314 | 53c25cea | Paul Brook | VirtIODevice *vdev; |
315 | 53c25cea | Paul Brook | |
316 | 53c25cea | Paul Brook | vdev = virtio_net_init(&pci_dev->qdev); |
317 | 53c25cea | Paul Brook | virtio_init_pci(proxy, vdev, |
318 | 53c25cea | Paul Brook | PCI_VENDOR_ID_REDHAT_QUMRANET, |
319 | 53c25cea | Paul Brook | PCI_DEVICE_ID_VIRTIO_NET, |
320 | 53c25cea | Paul Brook | PCI_CLASS_NETWORK_ETHERNET, |
321 | 53c25cea | Paul Brook | 0x00);
|
322 | 53c25cea | Paul Brook | } |
323 | 53c25cea | Paul Brook | |
324 | 53c25cea | Paul Brook | static void virtio_balloon_init_pci(PCIDevice *pci_dev) |
325 | 53c25cea | Paul Brook | { |
326 | 53c25cea | Paul Brook | VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev); |
327 | 53c25cea | Paul Brook | VirtIODevice *vdev; |
328 | 53c25cea | Paul Brook | |
329 | 53c25cea | Paul Brook | vdev = virtio_balloon_init(&pci_dev->qdev); |
330 | 53c25cea | Paul Brook | virtio_init_pci(proxy, vdev, |
331 | 53c25cea | Paul Brook | PCI_VENDOR_ID_REDHAT_QUMRANET, |
332 | 53c25cea | Paul Brook | PCI_DEVICE_ID_VIRTIO_BALLOON, |
333 | 53c25cea | Paul Brook | PCI_CLASS_MEMORY_RAM, |
334 | 53c25cea | Paul Brook | 0x00);
|
335 | 53c25cea | Paul Brook | } |
336 | 53c25cea | Paul Brook | |
337 | 53c25cea | Paul Brook | static void virtio_pci_register_devices(void) |
338 | 53c25cea | Paul Brook | { |
339 | 53c25cea | Paul Brook | pci_qdev_register("virtio-blk-pci", sizeof(VirtIOPCIProxy), |
340 | 53c25cea | Paul Brook | virtio_blk_init_pci); |
341 | 53c25cea | Paul Brook | pci_qdev_register("virtio-net-pci", sizeof(VirtIOPCIProxy), |
342 | 53c25cea | Paul Brook | virtio_net_init_pci); |
343 | 53c25cea | Paul Brook | pci_qdev_register("virtio-console-pci", sizeof(VirtIOPCIProxy), |
344 | 53c25cea | Paul Brook | virtio_console_init_pci); |
345 | 53c25cea | Paul Brook | pci_qdev_register("virtio-balloon-pci", sizeof(VirtIOPCIProxy), |
346 | 53c25cea | Paul Brook | virtio_balloon_init_pci); |
347 | 53c25cea | Paul Brook | } |
348 | 53c25cea | Paul Brook | |
349 | 53c25cea | Paul Brook | device_init(virtio_pci_register_devices) |