]> git.proxmox.com Git - mirror_qemu.git/blob - hw/pci-host/apb.c
apb: handle reading/writing of IOMMU control registers
[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 "hw/sysbus.h"
31 #include "hw/pci/pci.h"
32 #include "hw/pci/pci_host.h"
33 #include "hw/pci/pci_bridge.h"
34 #include "hw/pci/pci_bus.h"
35 #include "hw/pci-host/apb.h"
36 #include "sysemu/sysemu.h"
37 #include "exec/address-spaces.h"
38
39 /* debug APB */
40 //#define DEBUG_APB
41
42 #ifdef DEBUG_APB
43 #define APB_DPRINTF(fmt, ...) \
44 do { printf("APB: " fmt , ## __VA_ARGS__); } while (0)
45 #else
46 #define APB_DPRINTF(fmt, ...)
47 #endif
48
49 /* debug IOMMU */
50 //#define DEBUG_IOMMU
51
52 #ifdef DEBUG_IOMMU
53 #define IOMMU_DPRINTF(fmt, ...) \
54 do { printf("IOMMU: " fmt , ## __VA_ARGS__); } while (0)
55 #else
56 #define IOMMU_DPRINTF(fmt, ...)
57 #endif
58
59 /*
60 * Chipset docs:
61 * PBM: "UltraSPARC IIi User's Manual",
62 * http://www.sun.com/processors/manuals/805-0087.pdf
63 *
64 * APB: "Advanced PCI Bridge (APB) User's Manual",
65 * http://www.sun.com/processors/manuals/805-1251.pdf
66 */
67
68 #define PBM_PCI_IMR_MASK 0x7fffffff
69 #define PBM_PCI_IMR_ENABLED 0x80000000
70
71 #define POR (1U << 31)
72 #define SOFT_POR (1U << 30)
73 #define SOFT_XIR (1U << 29)
74 #define BTN_POR (1U << 28)
75 #define BTN_XIR (1U << 27)
76 #define RESET_MASK 0xf8000000
77 #define RESET_WCMASK 0x98000000
78 #define RESET_WMASK 0x60000000
79
80 #define MAX_IVEC 0x40
81 #define NO_IRQ_REQUEST (MAX_IVEC + 1)
82
83 #define IOMMU_NREGS 3
84 #define IOMMU_CTRL 0x0
85 #define IOMMU_BASE 0x8
86
87 typedef struct IOMMUState {
88 uint64_t regs[IOMMU_NREGS];
89 } IOMMUState;
90
91 #define TYPE_APB "pbm"
92
93 #define APB_DEVICE(obj) \
94 OBJECT_CHECK(APBState, (obj), TYPE_APB)
95
96 typedef struct APBState {
97 PCIHostState parent_obj;
98
99 MemoryRegion apb_config;
100 MemoryRegion pci_config;
101 MemoryRegion pci_mmio;
102 MemoryRegion pci_ioport;
103 uint64_t pci_irq_in;
104 IOMMUState iommu;
105 uint32_t pci_control[16];
106 uint32_t pci_irq_map[8];
107 uint32_t obio_irq_map[32];
108 qemu_irq *pbm_irqs;
109 qemu_irq *ivec_irqs;
110 unsigned int irq_request;
111 uint32_t reset_control;
112 unsigned int nr_resets;
113 } APBState;
114
115 static inline void pbm_set_request(APBState *s, unsigned int irq_num)
116 {
117 APB_DPRINTF("%s: request irq %d\n", __func__, irq_num);
118
119 s->irq_request = irq_num;
120 qemu_set_irq(s->ivec_irqs[irq_num], 1);
121 }
122
123 static inline void pbm_check_irqs(APBState *s)
124 {
125
126 unsigned int i;
127
128 /* Previous request is not acknowledged, resubmit */
129 if (s->irq_request != NO_IRQ_REQUEST) {
130 pbm_set_request(s, s->irq_request);
131 return;
132 }
133 /* no request pending */
134 if (s->pci_irq_in == 0ULL) {
135 return;
136 }
137 for (i = 0; i < 32; i++) {
138 if (s->pci_irq_in & (1ULL << i)) {
139 if (s->pci_irq_map[i >> 2] & PBM_PCI_IMR_ENABLED) {
140 pbm_set_request(s, i);
141 return;
142 }
143 }
144 }
145 for (i = 32; i < 64; i++) {
146 if (s->pci_irq_in & (1ULL << i)) {
147 if (s->obio_irq_map[i - 32] & PBM_PCI_IMR_ENABLED) {
148 pbm_set_request(s, i);
149 break;
150 }
151 }
152 }
153 }
154
155 static inline void pbm_clear_request(APBState *s, unsigned int irq_num)
156 {
157 APB_DPRINTF("%s: clear request irq %d\n", __func__, irq_num);
158 qemu_set_irq(s->ivec_irqs[irq_num], 0);
159 s->irq_request = NO_IRQ_REQUEST;
160 }
161
162 static void iommu_config_write(void *opaque, hwaddr addr,
163 uint64_t val, unsigned size)
164 {
165 IOMMUState *is = opaque;
166
167 IOMMU_DPRINTF("IOMMU config write: 0x%" HWADDR_PRIx " val: %" PRIx64
168 " size: %d\n", addr, val, size);
169
170 switch (addr) {
171 case IOMMU_CTRL:
172 if (size == 4) {
173 is->regs[IOMMU_CTRL >> 3] &= 0xffffffffULL;
174 is->regs[IOMMU_CTRL >> 3] |= val << 32;
175 } else {
176 is->regs[IOMMU_CTRL] = val;
177 }
178 break;
179 case IOMMU_CTRL + 0x4:
180 is->regs[IOMMU_CTRL >> 3] &= 0xffffffff00000000ULL;
181 is->regs[IOMMU_CTRL >> 3] |= val & 0xffffffffULL;
182 break;
183 case IOMMU_BASE:
184 if (size == 4) {
185 is->regs[IOMMU_BASE >> 3] &= 0xffffffffULL;
186 is->regs[IOMMU_BASE >> 3] |= val << 32;
187 } else {
188 is->regs[IOMMU_BASE] = val;
189 }
190 break;
191 case IOMMU_BASE + 0x4:
192 is->regs[IOMMU_BASE >> 3] &= 0xffffffff00000000ULL;
193 is->regs[IOMMU_BASE >> 3] |= val & 0xffffffffULL;
194 break;
195 default:
196 qemu_log_mask(LOG_UNIMP,
197 "apb iommu: Unimplemented register write "
198 "reg 0x%" HWADDR_PRIx " size 0x%x value 0x%" PRIx64 "\n",
199 addr, size, val);
200 break;
201 }
202 }
203
204 static uint64_t iommu_config_read(void *opaque, hwaddr addr, unsigned size)
205 {
206 IOMMUState *is = opaque;
207 uint64_t val;
208
209 switch (addr) {
210 case IOMMU_CTRL:
211 if (size == 4) {
212 val = is->regs[IOMMU_CTRL >> 3] >> 32;
213 } else {
214 val = is->regs[IOMMU_CTRL >> 3];
215 }
216 break;
217 case IOMMU_CTRL + 0x4:
218 val = is->regs[IOMMU_CTRL >> 3] & 0xffffffffULL;
219 break;
220 case IOMMU_BASE:
221 if (size == 4) {
222 val = is->regs[IOMMU_BASE >> 3] >> 32;
223 } else {
224 val = is->regs[IOMMU_BASE >> 3];
225 }
226 break;
227 case IOMMU_BASE + 0x4:
228 val = is->regs[IOMMU_BASE >> 3] & 0xffffffffULL;
229 break;
230 default:
231 qemu_log_mask(LOG_UNIMP,
232 "apb iommu: Unimplemented register read "
233 "reg 0x%" HWADDR_PRIx " size 0x%x\n",
234 addr, size);
235 val = 0;
236 break;
237 }
238
239 IOMMU_DPRINTF("IOMMU config read: 0x%" HWADDR_PRIx " val: %" PRIx64
240 " size: %d\n", addr, val, size);
241
242 return val;
243 }
244
245 static void apb_config_writel (void *opaque, hwaddr addr,
246 uint64_t val, unsigned size)
247 {
248 APBState *s = opaque;
249 IOMMUState *is = &s->iommu;
250
251 APB_DPRINTF("%s: addr " TARGET_FMT_plx " val %" PRIx64 "\n", __func__, addr, val);
252
253 switch (addr & 0xffff) {
254 case 0x30 ... 0x4f: /* DMA error registers */
255 /* XXX: not implemented yet */
256 break;
257 case 0x200 ... 0x217: /* IOMMU */
258 iommu_config_write(is, (addr & 0xf), val, size);
259 break;
260 case 0xc00 ... 0xc3f: /* PCI interrupt control */
261 if (addr & 4) {
262 unsigned int ino = (addr & 0x3f) >> 3;
263 s->pci_irq_map[ino] &= PBM_PCI_IMR_MASK;
264 s->pci_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
265 if ((s->irq_request == ino) && !(val & ~PBM_PCI_IMR_MASK)) {
266 pbm_clear_request(s, ino);
267 }
268 pbm_check_irqs(s);
269 }
270 break;
271 case 0x1000 ... 0x1080: /* OBIO interrupt control */
272 if (addr & 4) {
273 unsigned int ino = ((addr & 0xff) >> 3);
274 s->obio_irq_map[ino] &= PBM_PCI_IMR_MASK;
275 s->obio_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
276 if ((s->irq_request == (ino | 0x20))
277 && !(val & ~PBM_PCI_IMR_MASK)) {
278 pbm_clear_request(s, ino | 0x20);
279 }
280 pbm_check_irqs(s);
281 }
282 break;
283 case 0x1400 ... 0x14ff: /* PCI interrupt clear */
284 if (addr & 4) {
285 unsigned int ino = (addr & 0xff) >> 5;
286 if ((s->irq_request / 4) == ino) {
287 pbm_clear_request(s, s->irq_request);
288 pbm_check_irqs(s);
289 }
290 }
291 break;
292 case 0x1800 ... 0x1860: /* OBIO interrupt clear */
293 if (addr & 4) {
294 unsigned int ino = ((addr & 0xff) >> 3) | 0x20;
295 if (s->irq_request == ino) {
296 pbm_clear_request(s, ino);
297 pbm_check_irqs(s);
298 }
299 }
300 break;
301 case 0x2000 ... 0x202f: /* PCI control */
302 s->pci_control[(addr & 0x3f) >> 2] = val;
303 break;
304 case 0xf020 ... 0xf027: /* Reset control */
305 if (addr & 4) {
306 val &= RESET_MASK;
307 s->reset_control &= ~(val & RESET_WCMASK);
308 s->reset_control |= val & RESET_WMASK;
309 if (val & SOFT_POR) {
310 s->nr_resets = 0;
311 qemu_system_reset_request();
312 } else if (val & SOFT_XIR) {
313 qemu_system_reset_request();
314 }
315 }
316 break;
317 case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
318 case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
319 case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
320 case 0xf000 ... 0xf01f: /* FFB config, memory control */
321 /* we don't care */
322 default:
323 break;
324 }
325 }
326
327 static uint64_t apb_config_readl (void *opaque,
328 hwaddr addr, unsigned size)
329 {
330 APBState *s = opaque;
331 IOMMUState *is = &s->iommu;
332 uint32_t val;
333
334 switch (addr & 0xffff) {
335 case 0x30 ... 0x4f: /* DMA error registers */
336 val = 0;
337 /* XXX: not implemented yet */
338 break;
339 case 0x200 ... 0x217: /* IOMMU */
340 val = iommu_config_read(is, (addr & 0xf), size);
341 break;
342 case 0xc00 ... 0xc3f: /* PCI interrupt control */
343 if (addr & 4) {
344 val = s->pci_irq_map[(addr & 0x3f) >> 3];
345 } else {
346 val = 0;
347 }
348 break;
349 case 0x1000 ... 0x1080: /* OBIO interrupt control */
350 if (addr & 4) {
351 val = s->obio_irq_map[(addr & 0xff) >> 3];
352 } else {
353 val = 0;
354 }
355 break;
356 case 0x2000 ... 0x202f: /* PCI control */
357 val = s->pci_control[(addr & 0x3f) >> 2];
358 break;
359 case 0xf020 ... 0xf027: /* Reset control */
360 if (addr & 4) {
361 val = s->reset_control;
362 } else {
363 val = 0;
364 }
365 break;
366 case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
367 case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
368 case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
369 case 0xf000 ... 0xf01f: /* FFB config, memory control */
370 /* we don't care */
371 default:
372 val = 0;
373 break;
374 }
375 APB_DPRINTF("%s: addr " TARGET_FMT_plx " -> %x\n", __func__, addr, val);
376
377 return val;
378 }
379
380 static const MemoryRegionOps apb_config_ops = {
381 .read = apb_config_readl,
382 .write = apb_config_writel,
383 .endianness = DEVICE_NATIVE_ENDIAN,
384 };
385
386 static void apb_pci_config_write(void *opaque, hwaddr addr,
387 uint64_t val, unsigned size)
388 {
389 APBState *s = opaque;
390 PCIHostState *phb = PCI_HOST_BRIDGE(s);
391
392 val = qemu_bswap_len(val, size);
393 APB_DPRINTF("%s: addr " TARGET_FMT_plx " val %" PRIx64 "\n", __func__, addr, val);
394 pci_data_write(phb->bus, addr, val, size);
395 }
396
397 static uint64_t apb_pci_config_read(void *opaque, hwaddr addr,
398 unsigned size)
399 {
400 uint32_t ret;
401 APBState *s = opaque;
402 PCIHostState *phb = PCI_HOST_BRIDGE(s);
403
404 ret = pci_data_read(phb->bus, addr, size);
405 ret = qemu_bswap_len(ret, size);
406 APB_DPRINTF("%s: addr " TARGET_FMT_plx " -> %x\n", __func__, addr, ret);
407 return ret;
408 }
409
410 /* The APB host has an IRQ line for each IRQ line of each slot. */
411 static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num)
412 {
413 return ((pci_dev->devfn & 0x18) >> 1) + irq_num;
414 }
415
416 static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)
417 {
418 int bus_offset;
419 if (pci_dev->devfn & 1)
420 bus_offset = 16;
421 else
422 bus_offset = 0;
423 return (bus_offset + (PCI_SLOT(pci_dev->devfn) << 2) + irq_num) & 0x1f;
424 }
425
426 static void pci_apb_set_irq(void *opaque, int irq_num, int level)
427 {
428 APBState *s = opaque;
429
430 APB_DPRINTF("%s: set irq_in %d level %d\n", __func__, irq_num, level);
431 /* PCI IRQ map onto the first 32 INO. */
432 if (irq_num < 32) {
433 if (level) {
434 s->pci_irq_in |= 1ULL << irq_num;
435 if (s->pci_irq_map[irq_num >> 2] & PBM_PCI_IMR_ENABLED) {
436 pbm_set_request(s, irq_num);
437 }
438 } else {
439 s->pci_irq_in &= ~(1ULL << irq_num);
440 }
441 } else {
442 /* OBIO IRQ map onto the next 32 INO. */
443 if (level) {
444 APB_DPRINTF("%s: set irq %d level %d\n", __func__, irq_num, level);
445 s->pci_irq_in |= 1ULL << irq_num;
446 if ((s->irq_request == NO_IRQ_REQUEST)
447 && (s->obio_irq_map[irq_num - 32] & PBM_PCI_IMR_ENABLED)) {
448 pbm_set_request(s, irq_num);
449 }
450 } else {
451 s->pci_irq_in &= ~(1ULL << irq_num);
452 }
453 }
454 }
455
456 static int apb_pci_bridge_initfn(PCIDevice *dev)
457 {
458 int rc;
459
460 rc = pci_bridge_initfn(dev, TYPE_PCI_BUS);
461 if (rc < 0) {
462 return rc;
463 }
464
465 /*
466 * command register:
467 * According to PCI bridge spec, after reset
468 * bus master bit is off
469 * memory space enable bit is off
470 * According to manual (805-1251.pdf).
471 * the reset value should be zero unless the boot pin is tied high
472 * (which is true) and thus it should be PCI_COMMAND_MEMORY.
473 */
474 pci_set_word(dev->config + PCI_COMMAND,
475 PCI_COMMAND_MEMORY);
476 pci_set_word(dev->config + PCI_STATUS,
477 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
478 PCI_STATUS_DEVSEL_MEDIUM);
479 return 0;
480 }
481
482 PCIBus *pci_apb_init(hwaddr special_base,
483 hwaddr mem_base,
484 qemu_irq *ivec_irqs, PCIBus **bus2, PCIBus **bus3,
485 qemu_irq **pbm_irqs)
486 {
487 DeviceState *dev;
488 SysBusDevice *s;
489 PCIHostState *phb;
490 APBState *d;
491 IOMMUState *is;
492 PCIDevice *pci_dev;
493 PCIBridge *br;
494
495 /* Ultrasparc PBM main bus */
496 dev = qdev_create(NULL, TYPE_APB);
497 qdev_init_nofail(dev);
498 s = SYS_BUS_DEVICE(dev);
499 /* apb_config */
500 sysbus_mmio_map(s, 0, special_base);
501 /* PCI configuration space */
502 sysbus_mmio_map(s, 1, special_base + 0x1000000ULL);
503 /* pci_ioport */
504 sysbus_mmio_map(s, 2, special_base + 0x2000000ULL);
505 d = APB_DEVICE(dev);
506
507 memory_region_init(&d->pci_mmio, OBJECT(s), "pci-mmio", 0x100000000ULL);
508 memory_region_add_subregion(get_system_memory(), mem_base, &d->pci_mmio);
509
510 phb = PCI_HOST_BRIDGE(dev);
511 phb->bus = pci_register_bus(DEVICE(phb), "pci",
512 pci_apb_set_irq, pci_pbm_map_irq, d,
513 &d->pci_mmio,
514 get_system_io(),
515 0, 32, TYPE_PCI_BUS);
516
517 *pbm_irqs = d->pbm_irqs;
518 d->ivec_irqs = ivec_irqs;
519
520 pci_create_simple(phb->bus, 0, "pbm-pci");
521
522 /* APB IOMMU */
523 is = &d->iommu;
524 memset(is, 0, sizeof(IOMMUState));
525
526 /* APB secondary busses */
527 pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 0), true,
528 "pbm-bridge");
529 br = PCI_BRIDGE(pci_dev);
530 pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 1",
531 pci_apb_map_irq);
532 qdev_init_nofail(&pci_dev->qdev);
533 *bus2 = pci_bridge_get_sec_bus(br);
534
535 pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 1), true,
536 "pbm-bridge");
537 br = PCI_BRIDGE(pci_dev);
538 pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 2",
539 pci_apb_map_irq);
540 qdev_init_nofail(&pci_dev->qdev);
541 *bus3 = pci_bridge_get_sec_bus(br);
542
543 return phb->bus;
544 }
545
546 static void pci_pbm_reset(DeviceState *d)
547 {
548 unsigned int i;
549 APBState *s = APB_DEVICE(d);
550
551 for (i = 0; i < 8; i++) {
552 s->pci_irq_map[i] &= PBM_PCI_IMR_MASK;
553 }
554 for (i = 0; i < 32; i++) {
555 s->obio_irq_map[i] &= PBM_PCI_IMR_MASK;
556 }
557
558 s->irq_request = NO_IRQ_REQUEST;
559 s->pci_irq_in = 0ULL;
560
561 if (s->nr_resets++ == 0) {
562 /* Power on reset */
563 s->reset_control = POR;
564 }
565 }
566
567 static const MemoryRegionOps pci_config_ops = {
568 .read = apb_pci_config_read,
569 .write = apb_pci_config_write,
570 .endianness = DEVICE_NATIVE_ENDIAN,
571 };
572
573 static int pci_pbm_init_device(SysBusDevice *dev)
574 {
575 APBState *s;
576 unsigned int i;
577
578 s = APB_DEVICE(dev);
579 for (i = 0; i < 8; i++) {
580 s->pci_irq_map[i] = (0x1f << 6) | (i << 2);
581 }
582 for (i = 0; i < 32; i++) {
583 s->obio_irq_map[i] = ((0x1f << 6) | 0x20) + i;
584 }
585 s->pbm_irqs = qemu_allocate_irqs(pci_apb_set_irq, s, MAX_IVEC);
586 s->irq_request = NO_IRQ_REQUEST;
587 s->pci_irq_in = 0ULL;
588
589 /* apb_config */
590 memory_region_init_io(&s->apb_config, OBJECT(s), &apb_config_ops, s,
591 "apb-config", 0x10000);
592 /* at region 0 */
593 sysbus_init_mmio(dev, &s->apb_config);
594
595 memory_region_init_io(&s->pci_config, OBJECT(s), &pci_config_ops, s,
596 "apb-pci-config", 0x1000000);
597 /* at region 1 */
598 sysbus_init_mmio(dev, &s->pci_config);
599
600 /* pci_ioport */
601 memory_region_init_alias(&s->pci_ioport, OBJECT(s), "apb-pci-ioport",
602 get_system_io(), 0, 0x10000);
603 /* at region 2 */
604 sysbus_init_mmio(dev, &s->pci_ioport);
605
606 return 0;
607 }
608
609 static int pbm_pci_host_init(PCIDevice *d)
610 {
611 pci_set_word(d->config + PCI_COMMAND,
612 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
613 pci_set_word(d->config + PCI_STATUS,
614 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
615 PCI_STATUS_DEVSEL_MEDIUM);
616 return 0;
617 }
618
619 static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
620 {
621 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
622 DeviceClass *dc = DEVICE_CLASS(klass);
623
624 k->init = pbm_pci_host_init;
625 k->vendor_id = PCI_VENDOR_ID_SUN;
626 k->device_id = PCI_DEVICE_ID_SUN_SABRE;
627 k->class_id = PCI_CLASS_BRIDGE_HOST;
628 /*
629 * PCI-facing part of the host bridge, not usable without the
630 * host-facing part, which can't be device_add'ed, yet.
631 */
632 dc->cannot_instantiate_with_device_add_yet = true;
633 }
634
635 static const TypeInfo pbm_pci_host_info = {
636 .name = "pbm-pci",
637 .parent = TYPE_PCI_DEVICE,
638 .instance_size = sizeof(PCIDevice),
639 .class_init = pbm_pci_host_class_init,
640 };
641
642 static void pbm_host_class_init(ObjectClass *klass, void *data)
643 {
644 DeviceClass *dc = DEVICE_CLASS(klass);
645 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
646
647 k->init = pci_pbm_init_device;
648 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
649 dc->reset = pci_pbm_reset;
650 }
651
652 static const TypeInfo pbm_host_info = {
653 .name = TYPE_APB,
654 .parent = TYPE_PCI_HOST_BRIDGE,
655 .instance_size = sizeof(APBState),
656 .class_init = pbm_host_class_init,
657 };
658
659 static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
660 {
661 DeviceClass *dc = DEVICE_CLASS(klass);
662 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
663
664 k->init = apb_pci_bridge_initfn;
665 k->exit = pci_bridge_exitfn;
666 k->vendor_id = PCI_VENDOR_ID_SUN;
667 k->device_id = PCI_DEVICE_ID_SUN_SIMBA;
668 k->revision = 0x11;
669 k->config_write = pci_bridge_write_config;
670 k->is_bridge = 1;
671 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
672 dc->reset = pci_bridge_reset;
673 dc->vmsd = &vmstate_pci_device;
674 }
675
676 static const TypeInfo pbm_pci_bridge_info = {
677 .name = "pbm-bridge",
678 .parent = TYPE_PCI_BRIDGE,
679 .class_init = pbm_pci_bridge_class_init,
680 };
681
682 static void pbm_register_types(void)
683 {
684 type_register_static(&pbm_host_info);
685 type_register_static(&pbm_pci_host_info);
686 type_register_static(&pbm_pci_bridge_info);
687 }
688
689 type_init(pbm_register_types)