]> git.proxmox.com Git - mirror_qemu.git/blob - hw/pci-host/apb.c
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20180111' into...
[mirror_qemu.git] / hw / pci-host / apb.c
1 /*
2 * QEMU Ultrasparc APB PCI host
3 *
4 * Copyright (c) 2006 Fabrice Bellard
5 * Copyright (c) 2012,2013 Artyom Tarasenko
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25
26 /* XXX This file and most of its contents are somewhat misnamed. The
27 Ultrasparc PCI host is called the PCI Bus Module (PBM). The APB is
28 the secondary PCI bridge. */
29
30 #include "qemu/osdep.h"
31 #include "hw/sysbus.h"
32 #include "hw/pci/pci.h"
33 #include "hw/pci/pci_host.h"
34 #include "hw/pci/pci_bridge.h"
35 #include "hw/pci/pci_bus.h"
36 #include "hw/pci-host/apb.h"
37 #include "sysemu/sysemu.h"
38 #include "exec/address-spaces.h"
39 #include "qapi/error.h"
40 #include "qemu/log.h"
41
42 /* debug APB */
43 //#define DEBUG_APB
44
45 #ifdef DEBUG_APB
46 #define APB_DPRINTF(fmt, ...) \
47 do { printf("APB: " fmt , ## __VA_ARGS__); } while (0)
48 #else
49 #define APB_DPRINTF(fmt, ...)
50 #endif
51
52 /*
53 * Chipset docs:
54 * PBM: "UltraSPARC IIi User's Manual",
55 * http://www.sun.com/processors/manuals/805-0087.pdf
56 *
57 * APB: "Advanced PCI Bridge (APB) User's Manual",
58 * http://www.sun.com/processors/manuals/805-1251.pdf
59 */
60
61 #define PBM_PCI_IMR_MASK 0x7fffffff
62 #define PBM_PCI_IMR_ENABLED 0x80000000
63
64 #define POR (1U << 31)
65 #define SOFT_POR (1U << 30)
66 #define SOFT_XIR (1U << 29)
67 #define BTN_POR (1U << 28)
68 #define BTN_XIR (1U << 27)
69 #define RESET_MASK 0xf8000000
70 #define RESET_WCMASK 0x98000000
71 #define RESET_WMASK 0x60000000
72
73 #define NO_IRQ_REQUEST (MAX_IVEC + 1)
74
75 static inline void pbm_set_request(APBState *s, unsigned int irq_num)
76 {
77 APB_DPRINTF("%s: request irq %d\n", __func__, irq_num);
78
79 s->irq_request = irq_num;
80 qemu_set_irq(s->ivec_irqs[irq_num], 1);
81 }
82
83 static inline void pbm_check_irqs(APBState *s)
84 {
85
86 unsigned int i;
87
88 /* Previous request is not acknowledged, resubmit */
89 if (s->irq_request != NO_IRQ_REQUEST) {
90 pbm_set_request(s, s->irq_request);
91 return;
92 }
93 /* no request pending */
94 if (s->pci_irq_in == 0ULL) {
95 return;
96 }
97 for (i = 0; i < 32; i++) {
98 if (s->pci_irq_in & (1ULL << i)) {
99 if (s->pci_irq_map[i >> 2] & PBM_PCI_IMR_ENABLED) {
100 pbm_set_request(s, i);
101 return;
102 }
103 }
104 }
105 for (i = 32; i < 64; i++) {
106 if (s->pci_irq_in & (1ULL << i)) {
107 if (s->obio_irq_map[i - 32] & PBM_PCI_IMR_ENABLED) {
108 pbm_set_request(s, i);
109 break;
110 }
111 }
112 }
113 }
114
115 static inline void pbm_clear_request(APBState *s, unsigned int irq_num)
116 {
117 APB_DPRINTF("%s: clear request irq %d\n", __func__, irq_num);
118 qemu_set_irq(s->ivec_irqs[irq_num], 0);
119 s->irq_request = NO_IRQ_REQUEST;
120 }
121
122 static AddressSpace *pbm_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
123 {
124 IOMMUState *is = opaque;
125
126 return &is->iommu_as;
127 }
128
129 static void apb_config_writel (void *opaque, hwaddr addr,
130 uint64_t val, unsigned size)
131 {
132 APBState *s = opaque;
133
134 APB_DPRINTF("%s: addr " TARGET_FMT_plx " val %" PRIx64 "\n", __func__, addr, val);
135
136 switch (addr & 0xffff) {
137 case 0x30 ... 0x4f: /* DMA error registers */
138 /* XXX: not implemented yet */
139 break;
140 case 0xc00 ... 0xc3f: /* PCI interrupt control */
141 if (addr & 4) {
142 unsigned int ino = (addr & 0x3f) >> 3;
143 s->pci_irq_map[ino] &= PBM_PCI_IMR_MASK;
144 s->pci_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
145 if ((s->irq_request == ino) && !(val & ~PBM_PCI_IMR_MASK)) {
146 pbm_clear_request(s, ino);
147 }
148 pbm_check_irqs(s);
149 }
150 break;
151 case 0x1000 ... 0x107f: /* OBIO interrupt control */
152 if (addr & 4) {
153 unsigned int ino = ((addr & 0xff) >> 3);
154 s->obio_irq_map[ino] &= PBM_PCI_IMR_MASK;
155 s->obio_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
156 if ((s->irq_request == (ino | 0x20))
157 && !(val & ~PBM_PCI_IMR_MASK)) {
158 pbm_clear_request(s, ino | 0x20);
159 }
160 pbm_check_irqs(s);
161 }
162 break;
163 case 0x1400 ... 0x14ff: /* PCI interrupt clear */
164 if (addr & 4) {
165 unsigned int ino = (addr & 0xff) >> 5;
166 if ((s->irq_request / 4) == ino) {
167 pbm_clear_request(s, s->irq_request);
168 pbm_check_irqs(s);
169 }
170 }
171 break;
172 case 0x1800 ... 0x1860: /* OBIO interrupt clear */
173 if (addr & 4) {
174 unsigned int ino = ((addr & 0xff) >> 3) | 0x20;
175 if (s->irq_request == ino) {
176 pbm_clear_request(s, ino);
177 pbm_check_irqs(s);
178 }
179 }
180 break;
181 case 0x2000 ... 0x202f: /* PCI control */
182 s->pci_control[(addr & 0x3f) >> 2] = val;
183 break;
184 case 0xf020 ... 0xf027: /* Reset control */
185 if (addr & 4) {
186 val &= RESET_MASK;
187 s->reset_control &= ~(val & RESET_WCMASK);
188 s->reset_control |= val & RESET_WMASK;
189 if (val & SOFT_POR) {
190 s->nr_resets = 0;
191 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
192 } else if (val & SOFT_XIR) {
193 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
194 }
195 }
196 break;
197 case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
198 case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
199 case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
200 case 0xf000 ... 0xf01f: /* FFB config, memory control */
201 /* we don't care */
202 default:
203 break;
204 }
205 }
206
207 static uint64_t apb_config_readl (void *opaque,
208 hwaddr addr, unsigned size)
209 {
210 APBState *s = opaque;
211 uint32_t val;
212
213 switch (addr & 0xffff) {
214 case 0x30 ... 0x4f: /* DMA error registers */
215 val = 0;
216 /* XXX: not implemented yet */
217 break;
218 case 0xc00 ... 0xc3f: /* PCI interrupt control */
219 if (addr & 4) {
220 val = s->pci_irq_map[(addr & 0x3f) >> 3];
221 } else {
222 val = 0;
223 }
224 break;
225 case 0x1000 ... 0x107f: /* OBIO interrupt control */
226 if (addr & 4) {
227 val = s->obio_irq_map[(addr & 0xff) >> 3];
228 } else {
229 val = 0;
230 }
231 break;
232 case 0x1080 ... 0x108f: /* PCI bus error */
233 if (addr & 4) {
234 val = s->pci_err_irq_map[(addr & 0xf) >> 3];
235 } else {
236 val = 0;
237 }
238 break;
239 case 0x2000 ... 0x202f: /* PCI control */
240 val = s->pci_control[(addr & 0x3f) >> 2];
241 break;
242 case 0xf020 ... 0xf027: /* Reset control */
243 if (addr & 4) {
244 val = s->reset_control;
245 } else {
246 val = 0;
247 }
248 break;
249 case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
250 case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
251 case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
252 case 0xf000 ... 0xf01f: /* FFB config, memory control */
253 /* we don't care */
254 default:
255 val = 0;
256 break;
257 }
258 APB_DPRINTF("%s: addr " TARGET_FMT_plx " -> %x\n", __func__, addr, val);
259
260 return val;
261 }
262
263 static const MemoryRegionOps apb_config_ops = {
264 .read = apb_config_readl,
265 .write = apb_config_writel,
266 .endianness = DEVICE_BIG_ENDIAN,
267 };
268
269 static void apb_pci_config_write(void *opaque, hwaddr addr,
270 uint64_t val, unsigned size)
271 {
272 APBState *s = opaque;
273 PCIHostState *phb = PCI_HOST_BRIDGE(s);
274
275 APB_DPRINTF("%s: addr " TARGET_FMT_plx " val %" PRIx64 "\n", __func__, addr, val);
276 pci_data_write(phb->bus, addr, val, size);
277 }
278
279 static uint64_t apb_pci_config_read(void *opaque, hwaddr addr,
280 unsigned size)
281 {
282 uint32_t ret;
283 APBState *s = opaque;
284 PCIHostState *phb = PCI_HOST_BRIDGE(s);
285
286 ret = pci_data_read(phb->bus, addr, size);
287 APB_DPRINTF("%s: addr " TARGET_FMT_plx " -> %x\n", __func__, addr, ret);
288 return ret;
289 }
290
291 /* The APB host has an IRQ line for each IRQ line of each slot. */
292 static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num)
293 {
294 /* Return the irq as swizzled by the PBM */
295 return irq_num;
296 }
297
298 static int pci_pbmA_map_irq(PCIDevice *pci_dev, int irq_num)
299 {
300 /* The on-board devices have fixed (legacy) OBIO intnos */
301 switch (PCI_SLOT(pci_dev->devfn)) {
302 case 1:
303 /* Onboard NIC */
304 return OBIO_NIC_IRQ;
305 case 3:
306 /* Onboard IDE */
307 return OBIO_HDD_IRQ;
308 default:
309 /* Normal intno, fall through */
310 break;
311 }
312
313 return ((PCI_SLOT(pci_dev->devfn) << 2) + irq_num) & 0x1f;
314 }
315
316 static int pci_pbmB_map_irq(PCIDevice *pci_dev, int irq_num)
317 {
318 return (0x10 + (PCI_SLOT(pci_dev->devfn) << 2) + irq_num) & 0x1f;
319 }
320
321 static void pci_apb_set_irq(void *opaque, int irq_num, int level)
322 {
323 APBState *s = opaque;
324
325 APB_DPRINTF("%s: set irq_in %d level %d\n", __func__, irq_num, level);
326 /* PCI IRQ map onto the first 32 INO. */
327 if (irq_num < 32) {
328 if (level) {
329 s->pci_irq_in |= 1ULL << irq_num;
330 if (s->pci_irq_map[irq_num >> 2] & PBM_PCI_IMR_ENABLED) {
331 pbm_set_request(s, irq_num);
332 }
333 } else {
334 s->pci_irq_in &= ~(1ULL << irq_num);
335 }
336 } else {
337 /* OBIO IRQ map onto the next 32 INO. */
338 if (level) {
339 APB_DPRINTF("%s: set irq %d level %d\n", __func__, irq_num, level);
340 s->pci_irq_in |= 1ULL << irq_num;
341 if ((s->irq_request == NO_IRQ_REQUEST)
342 && (s->obio_irq_map[irq_num - 32] & PBM_PCI_IMR_ENABLED)) {
343 pbm_set_request(s, irq_num);
344 }
345 } else {
346 s->pci_irq_in &= ~(1ULL << irq_num);
347 }
348 }
349 }
350
351 static void apb_pci_bridge_realize(PCIDevice *dev, Error **errp)
352 {
353 /*
354 * command register:
355 * According to PCI bridge spec, after reset
356 * bus master bit is off
357 * memory space enable bit is off
358 * According to manual (805-1251.pdf).
359 * the reset value should be zero unless the boot pin is tied high
360 * (which is true) and thus it should be PCI_COMMAND_MEMORY.
361 */
362 PBMPCIBridge *br = PBM_PCI_BRIDGE(dev);
363
364 pci_bridge_initfn(dev, TYPE_PCI_BUS);
365
366 pci_set_word(dev->config + PCI_COMMAND, PCI_COMMAND_MEMORY);
367 pci_set_word(dev->config + PCI_STATUS,
368 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
369 PCI_STATUS_DEVSEL_MEDIUM);
370
371 /* Allow 32-bit IO addresses */
372 pci_set_word(dev->config + PCI_IO_BASE, PCI_IO_RANGE_TYPE_32);
373 pci_set_word(dev->config + PCI_IO_LIMIT, PCI_IO_RANGE_TYPE_32);
374 pci_set_word(dev->wmask + PCI_IO_BASE_UPPER16, 0xffff);
375 pci_set_word(dev->wmask + PCI_IO_LIMIT_UPPER16, 0xffff);
376
377 pci_bridge_update_mappings(PCI_BRIDGE(br));
378 }
379
380 static void pci_pbm_reset(DeviceState *d)
381 {
382 APBState *s = APB_DEVICE(d);
383 PCIDevice *pci_dev;
384 unsigned int i;
385 uint16_t cmd;
386
387 for (i = 0; i < 8; i++) {
388 s->pci_irq_map[i] &= PBM_PCI_IMR_MASK;
389 }
390 for (i = 0; i < 32; i++) {
391 s->obio_irq_map[i] &= PBM_PCI_IMR_MASK;
392 }
393
394 s->irq_request = NO_IRQ_REQUEST;
395 s->pci_irq_in = 0ULL;
396
397 if (s->nr_resets++ == 0) {
398 /* Power on reset */
399 s->reset_control = POR;
400 }
401
402 /* As this is the busA PCI bridge which contains the on-board devices
403 * attached to the ebus, ensure that we initially allow IO transactions
404 * so that we get the early serial console until OpenBIOS can properly
405 * configure the PCI bridge itself */
406 pci_dev = PCI_DEVICE(s->bridgeA);
407 cmd = pci_get_word(pci_dev->config + PCI_COMMAND);
408 pci_set_word(pci_dev->config + PCI_COMMAND, cmd | PCI_COMMAND_IO);
409 pci_bridge_update_mappings(PCI_BRIDGE(pci_dev));
410 }
411
412 static const MemoryRegionOps pci_config_ops = {
413 .read = apb_pci_config_read,
414 .write = apb_pci_config_write,
415 .endianness = DEVICE_LITTLE_ENDIAN,
416 };
417
418 static void pci_pbm_realize(DeviceState *dev, Error **errp)
419 {
420 APBState *s = APB_DEVICE(dev);
421 PCIHostState *phb = PCI_HOST_BRIDGE(dev);
422 SysBusDevice *sbd = SYS_BUS_DEVICE(s);
423 PCIDevice *pci_dev;
424
425 /* apb_config */
426 sysbus_mmio_map(sbd, 0, s->special_base);
427 /* PCI configuration space */
428 sysbus_mmio_map(sbd, 1, s->special_base + 0x1000000ULL);
429 /* pci_ioport */
430 sysbus_mmio_map(sbd, 2, s->special_base + 0x2000000ULL);
431
432 memory_region_init(&s->pci_mmio, OBJECT(s), "pci-mmio", 0x100000000ULL);
433 memory_region_add_subregion(get_system_memory(), s->mem_base,
434 &s->pci_mmio);
435
436 phb->bus = pci_register_bus(dev, "pci",
437 pci_apb_set_irq, pci_apb_map_irq, s,
438 &s->pci_mmio,
439 &s->pci_ioport,
440 0, 32, TYPE_PCI_BUS);
441
442 pci_create_simple(phb->bus, 0, "pbm-pci");
443
444 /* APB IOMMU */
445 memory_region_add_subregion_overlap(&s->apb_config, 0x200,
446 sysbus_mmio_get_region(SYS_BUS_DEVICE(s->iommu), 0), 1);
447 pci_setup_iommu(phb->bus, pbm_pci_dma_iommu, s->iommu);
448
449 /* APB secondary busses */
450 pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 0), true,
451 TYPE_PBM_PCI_BRIDGE);
452 s->bridgeB = PCI_BRIDGE(pci_dev);
453 pci_bridge_map_irq(s->bridgeB, "pciB", pci_pbmB_map_irq);
454 qdev_init_nofail(&pci_dev->qdev);
455
456 pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 1), true,
457 TYPE_PBM_PCI_BRIDGE);
458 s->bridgeA = PCI_BRIDGE(pci_dev);
459 pci_bridge_map_irq(s->bridgeA, "pciA", pci_pbmA_map_irq);
460 qdev_init_nofail(&pci_dev->qdev);
461 }
462
463 static void pci_pbm_init(Object *obj)
464 {
465 APBState *s = APB_DEVICE(obj);
466 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
467 unsigned int i;
468
469 for (i = 0; i < 8; i++) {
470 s->pci_irq_map[i] = (0x1f << 6) | (i << 2);
471 }
472 for (i = 0; i < 2; i++) {
473 s->pci_err_irq_map[i] = (0x1f << 6) | 0x30;
474 }
475 for (i = 0; i < 32; i++) {
476 s->obio_irq_map[i] = ((0x1f << 6) | 0x20) + i;
477 }
478 qdev_init_gpio_in_named(DEVICE(s), pci_apb_set_irq, "pbm-irq", MAX_IVEC);
479 qdev_init_gpio_out_named(DEVICE(s), s->ivec_irqs, "ivec-irq", MAX_IVEC);
480 s->irq_request = NO_IRQ_REQUEST;
481 s->pci_irq_in = 0ULL;
482
483 /* IOMMU */
484 object_property_add_link(obj, "iommu", TYPE_SUN4U_IOMMU,
485 (Object **) &s->iommu,
486 qdev_prop_allow_set_link_before_realize,
487 0, NULL);
488
489 /* apb_config */
490 memory_region_init_io(&s->apb_config, OBJECT(s), &apb_config_ops, s,
491 "apb-config", 0x10000);
492 /* at region 0 */
493 sysbus_init_mmio(sbd, &s->apb_config);
494
495 memory_region_init_io(&s->pci_config, OBJECT(s), &pci_config_ops, s,
496 "apb-pci-config", 0x1000000);
497 /* at region 1 */
498 sysbus_init_mmio(sbd, &s->pci_config);
499
500 /* pci_ioport */
501 memory_region_init(&s->pci_ioport, OBJECT(s), "apb-pci-ioport", 0x1000000);
502
503 /* at region 2 */
504 sysbus_init_mmio(sbd, &s->pci_ioport);
505 }
506
507 static void pbm_pci_host_realize(PCIDevice *d, Error **errp)
508 {
509 pci_set_word(d->config + PCI_COMMAND,
510 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
511 pci_set_word(d->config + PCI_STATUS,
512 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
513 PCI_STATUS_DEVSEL_MEDIUM);
514 }
515
516 static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
517 {
518 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
519 DeviceClass *dc = DEVICE_CLASS(klass);
520
521 k->realize = pbm_pci_host_realize;
522 k->vendor_id = PCI_VENDOR_ID_SUN;
523 k->device_id = PCI_DEVICE_ID_SUN_SABRE;
524 k->class_id = PCI_CLASS_BRIDGE_HOST;
525 /*
526 * PCI-facing part of the host bridge, not usable without the
527 * host-facing part, which can't be device_add'ed, yet.
528 */
529 dc->user_creatable = false;
530 }
531
532 static const TypeInfo pbm_pci_host_info = {
533 .name = "pbm-pci",
534 .parent = TYPE_PCI_DEVICE,
535 .instance_size = sizeof(PCIDevice),
536 .class_init = pbm_pci_host_class_init,
537 .interfaces = (InterfaceInfo[]) {
538 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
539 { },
540 },
541 };
542
543 static Property pbm_pci_host_properties[] = {
544 DEFINE_PROP_UINT64("special-base", APBState, special_base, 0),
545 DEFINE_PROP_UINT64("mem-base", APBState, mem_base, 0),
546 DEFINE_PROP_END_OF_LIST(),
547 };
548
549 static void pbm_host_class_init(ObjectClass *klass, void *data)
550 {
551 DeviceClass *dc = DEVICE_CLASS(klass);
552
553 dc->realize = pci_pbm_realize;
554 dc->reset = pci_pbm_reset;
555 dc->props = pbm_pci_host_properties;
556 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
557 }
558
559 static const TypeInfo pbm_host_info = {
560 .name = TYPE_APB,
561 .parent = TYPE_PCI_HOST_BRIDGE,
562 .instance_size = sizeof(APBState),
563 .instance_init = pci_pbm_init,
564 .class_init = pbm_host_class_init,
565 };
566
567 static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
568 {
569 DeviceClass *dc = DEVICE_CLASS(klass);
570 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
571
572 k->realize = apb_pci_bridge_realize;
573 k->exit = pci_bridge_exitfn;
574 k->vendor_id = PCI_VENDOR_ID_SUN;
575 k->device_id = PCI_DEVICE_ID_SUN_SIMBA;
576 k->revision = 0x11;
577 k->config_write = pci_bridge_write_config;
578 k->is_bridge = 1;
579 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
580 dc->reset = pci_bridge_reset;
581 dc->vmsd = &vmstate_pci_device;
582 }
583
584 static const TypeInfo pbm_pci_bridge_info = {
585 .name = TYPE_PBM_PCI_BRIDGE,
586 .parent = TYPE_PCI_BRIDGE,
587 .class_init = pbm_pci_bridge_class_init,
588 .instance_size = sizeof(PBMPCIBridge),
589 .interfaces = (InterfaceInfo[]) {
590 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
591 { },
592 },
593 };
594
595 static void pbm_register_types(void)
596 {
597 type_register_static(&pbm_host_info);
598 type_register_static(&pbm_pci_host_info);
599 type_register_static(&pbm_pci_bridge_info);
600 }
601
602 type_init(pbm_register_types)