apb: QOMify IOMMU
[qemu/ar7.git] / hw / pci-host / apb.c
blob060e6e6d1c2c247ccf57b2a3d31a1a728b5826ea
1 /*
2 * QEMU Ultrasparc APB PCI host
4 * Copyright (c) 2006 Fabrice Bellard
5 * Copyright (c) 2012,2013 Artyom Tarasenko
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:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
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.
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. */
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"
42 /* debug APB */
43 //#define DEBUG_APB
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
52 /* debug IOMMU */
53 //#define DEBUG_IOMMU
55 #ifdef DEBUG_IOMMU
56 #define IOMMU_DPRINTF(fmt, ...) \
57 do { printf("IOMMU: " fmt , ## __VA_ARGS__); } while (0)
58 #else
59 #define IOMMU_DPRINTF(fmt, ...)
60 #endif
63 * Chipset docs:
64 * PBM: "UltraSPARC IIi User's Manual",
65 * http://www.sun.com/processors/manuals/805-0087.pdf
67 * APB: "Advanced PCI Bridge (APB) User's Manual",
68 * http://www.sun.com/processors/manuals/805-1251.pdf
71 #define PBM_PCI_IMR_MASK 0x7fffffff
72 #define PBM_PCI_IMR_ENABLED 0x80000000
74 #define POR (1U << 31)
75 #define SOFT_POR (1U << 30)
76 #define SOFT_XIR (1U << 29)
77 #define BTN_POR (1U << 28)
78 #define BTN_XIR (1U << 27)
79 #define RESET_MASK 0xf8000000
80 #define RESET_WCMASK 0x98000000
81 #define RESET_WMASK 0x60000000
83 #define NO_IRQ_REQUEST (MAX_IVEC + 1)
85 static inline void pbm_set_request(APBState *s, unsigned int irq_num)
87 APB_DPRINTF("%s: request irq %d\n", __func__, irq_num);
89 s->irq_request = irq_num;
90 qemu_set_irq(s->ivec_irqs[irq_num], 1);
93 static inline void pbm_check_irqs(APBState *s)
96 unsigned int i;
98 /* Previous request is not acknowledged, resubmit */
99 if (s->irq_request != NO_IRQ_REQUEST) {
100 pbm_set_request(s, s->irq_request);
101 return;
103 /* no request pending */
104 if (s->pci_irq_in == 0ULL) {
105 return;
107 for (i = 0; i < 32; i++) {
108 if (s->pci_irq_in & (1ULL << i)) {
109 if (s->pci_irq_map[i >> 2] & PBM_PCI_IMR_ENABLED) {
110 pbm_set_request(s, i);
111 return;
115 for (i = 32; i < 64; i++) {
116 if (s->pci_irq_in & (1ULL << i)) {
117 if (s->obio_irq_map[i - 32] & PBM_PCI_IMR_ENABLED) {
118 pbm_set_request(s, i);
119 break;
125 static inline void pbm_clear_request(APBState *s, unsigned int irq_num)
127 APB_DPRINTF("%s: clear request irq %d\n", __func__, irq_num);
128 qemu_set_irq(s->ivec_irqs[irq_num], 0);
129 s->irq_request = NO_IRQ_REQUEST;
132 static AddressSpace *pbm_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
134 IOMMUState *is = opaque;
136 return &is->iommu_as;
139 /* Called from RCU critical section */
140 static IOMMUTLBEntry pbm_translate_iommu(IOMMUMemoryRegion *iommu, hwaddr addr,
141 IOMMUAccessFlags flag)
143 IOMMUState *is = container_of(iommu, IOMMUState, iommu);
144 hwaddr baseaddr, offset;
145 uint64_t tte;
146 uint32_t tsbsize;
147 IOMMUTLBEntry ret = {
148 .target_as = &address_space_memory,
149 .iova = 0,
150 .translated_addr = 0,
151 .addr_mask = ~(hwaddr)0,
152 .perm = IOMMU_NONE,
155 if (!(is->regs[IOMMU_CTRL >> 3] & IOMMU_CTRL_MMU_EN)) {
156 /* IOMMU disabled, passthrough using standard 8K page */
157 ret.iova = addr & IOMMU_PAGE_MASK_8K;
158 ret.translated_addr = addr;
159 ret.addr_mask = IOMMU_PAGE_MASK_8K;
160 ret.perm = IOMMU_RW;
162 return ret;
165 baseaddr = is->regs[IOMMU_BASE >> 3];
166 tsbsize = (is->regs[IOMMU_CTRL >> 3] >> IOMMU_CTRL_TSB_SHIFT) & 0x7;
168 if (is->regs[IOMMU_CTRL >> 3] & IOMMU_CTRL_TBW_SIZE) {
169 /* 64K */
170 switch (tsbsize) {
171 case 0:
172 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_64M) >> 13;
173 break;
174 case 1:
175 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_128M) >> 13;
176 break;
177 case 2:
178 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_256M) >> 13;
179 break;
180 case 3:
181 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_512M) >> 13;
182 break;
183 case 4:
184 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_1G) >> 13;
185 break;
186 case 5:
187 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_2G) >> 13;
188 break;
189 default:
190 /* Not implemented, error */
191 return ret;
193 } else {
194 /* 8K */
195 switch (tsbsize) {
196 case 0:
197 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_8M) >> 10;
198 break;
199 case 1:
200 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_16M) >> 10;
201 break;
202 case 2:
203 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_32M) >> 10;
204 break;
205 case 3:
206 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_64M) >> 10;
207 break;
208 case 4:
209 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_128M) >> 10;
210 break;
211 case 5:
212 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_256M) >> 10;
213 break;
214 case 6:
215 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_512M) >> 10;
216 break;
217 case 7:
218 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_1G) >> 10;
219 break;
223 tte = address_space_ldq_be(&address_space_memory, baseaddr + offset,
224 MEMTXATTRS_UNSPECIFIED, NULL);
226 if (!(tte & IOMMU_TTE_DATA_V)) {
227 /* Invalid mapping */
228 return ret;
231 if (tte & IOMMU_TTE_DATA_W) {
232 /* Writeable */
233 ret.perm = IOMMU_RW;
234 } else {
235 ret.perm = IOMMU_RO;
238 /* Extract phys */
239 if (tte & IOMMU_TTE_DATA_SIZE) {
240 /* 64K */
241 ret.iova = addr & IOMMU_PAGE_MASK_64K;
242 ret.translated_addr = tte & IOMMU_TTE_PHYS_MASK_64K;
243 ret.addr_mask = (IOMMU_PAGE_SIZE_64K - 1);
244 } else {
245 /* 8K */
246 ret.iova = addr & IOMMU_PAGE_MASK_8K;
247 ret.translated_addr = tte & IOMMU_TTE_PHYS_MASK_8K;
248 ret.addr_mask = (IOMMU_PAGE_SIZE_8K - 1);
251 return ret;
254 static void iommu_mem_write(void *opaque, hwaddr addr,
255 uint64_t val, unsigned size)
257 IOMMUState *is = opaque;
259 IOMMU_DPRINTF("IOMMU config write: 0x%" HWADDR_PRIx " val: %" PRIx64
260 " size: %d\n", addr, val, size);
262 switch (addr) {
263 case IOMMU_CTRL:
264 if (size == 4) {
265 is->regs[IOMMU_CTRL >> 3] &= 0xffffffffULL;
266 is->regs[IOMMU_CTRL >> 3] |= val << 32;
267 } else {
268 is->regs[IOMMU_CTRL >> 3] = val;
270 break;
271 case IOMMU_CTRL + 0x4:
272 is->regs[IOMMU_CTRL >> 3] &= 0xffffffff00000000ULL;
273 is->regs[IOMMU_CTRL >> 3] |= val & 0xffffffffULL;
274 break;
275 case IOMMU_BASE:
276 if (size == 4) {
277 is->regs[IOMMU_BASE >> 3] &= 0xffffffffULL;
278 is->regs[IOMMU_BASE >> 3] |= val << 32;
279 } else {
280 is->regs[IOMMU_BASE >> 3] = val;
282 break;
283 case IOMMU_BASE + 0x4:
284 is->regs[IOMMU_BASE >> 3] &= 0xffffffff00000000ULL;
285 is->regs[IOMMU_BASE >> 3] |= val & 0xffffffffULL;
286 break;
287 case IOMMU_FLUSH:
288 case IOMMU_FLUSH + 0x4:
289 break;
290 default:
291 qemu_log_mask(LOG_UNIMP,
292 "apb iommu: Unimplemented register write "
293 "reg 0x%" HWADDR_PRIx " size 0x%x value 0x%" PRIx64 "\n",
294 addr, size, val);
295 break;
299 static uint64_t iommu_mem_read(void *opaque, hwaddr addr, unsigned size)
301 IOMMUState *is = opaque;
302 uint64_t val;
304 switch (addr) {
305 case IOMMU_CTRL:
306 if (size == 4) {
307 val = is->regs[IOMMU_CTRL >> 3] >> 32;
308 } else {
309 val = is->regs[IOMMU_CTRL >> 3];
311 break;
312 case IOMMU_CTRL + 0x4:
313 val = is->regs[IOMMU_CTRL >> 3] & 0xffffffffULL;
314 break;
315 case IOMMU_BASE:
316 if (size == 4) {
317 val = is->regs[IOMMU_BASE >> 3] >> 32;
318 } else {
319 val = is->regs[IOMMU_BASE >> 3];
321 break;
322 case IOMMU_BASE + 0x4:
323 val = is->regs[IOMMU_BASE >> 3] & 0xffffffffULL;
324 break;
325 case IOMMU_FLUSH:
326 case IOMMU_FLUSH + 0x4:
327 val = 0;
328 break;
329 default:
330 qemu_log_mask(LOG_UNIMP,
331 "apb iommu: Unimplemented register read "
332 "reg 0x%" HWADDR_PRIx " size 0x%x\n",
333 addr, size);
334 val = 0;
335 break;
338 IOMMU_DPRINTF("IOMMU config read: 0x%" HWADDR_PRIx " val: %" PRIx64
339 " size: %d\n", addr, val, size);
341 return val;
344 static void apb_config_writel (void *opaque, hwaddr addr,
345 uint64_t val, unsigned size)
347 APBState *s = opaque;
349 APB_DPRINTF("%s: addr " TARGET_FMT_plx " val %" PRIx64 "\n", __func__, addr, val);
351 switch (addr & 0xffff) {
352 case 0x30 ... 0x4f: /* DMA error registers */
353 /* XXX: not implemented yet */
354 break;
355 case 0xc00 ... 0xc3f: /* PCI interrupt control */
356 if (addr & 4) {
357 unsigned int ino = (addr & 0x3f) >> 3;
358 s->pci_irq_map[ino] &= PBM_PCI_IMR_MASK;
359 s->pci_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
360 if ((s->irq_request == ino) && !(val & ~PBM_PCI_IMR_MASK)) {
361 pbm_clear_request(s, ino);
363 pbm_check_irqs(s);
365 break;
366 case 0x1000 ... 0x107f: /* OBIO interrupt control */
367 if (addr & 4) {
368 unsigned int ino = ((addr & 0xff) >> 3);
369 s->obio_irq_map[ino] &= PBM_PCI_IMR_MASK;
370 s->obio_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
371 if ((s->irq_request == (ino | 0x20))
372 && !(val & ~PBM_PCI_IMR_MASK)) {
373 pbm_clear_request(s, ino | 0x20);
375 pbm_check_irqs(s);
377 break;
378 case 0x1400 ... 0x14ff: /* PCI interrupt clear */
379 if (addr & 4) {
380 unsigned int ino = (addr & 0xff) >> 5;
381 if ((s->irq_request / 4) == ino) {
382 pbm_clear_request(s, s->irq_request);
383 pbm_check_irqs(s);
386 break;
387 case 0x1800 ... 0x1860: /* OBIO interrupt clear */
388 if (addr & 4) {
389 unsigned int ino = ((addr & 0xff) >> 3) | 0x20;
390 if (s->irq_request == ino) {
391 pbm_clear_request(s, ino);
392 pbm_check_irqs(s);
395 break;
396 case 0x2000 ... 0x202f: /* PCI control */
397 s->pci_control[(addr & 0x3f) >> 2] = val;
398 break;
399 case 0xf020 ... 0xf027: /* Reset control */
400 if (addr & 4) {
401 val &= RESET_MASK;
402 s->reset_control &= ~(val & RESET_WCMASK);
403 s->reset_control |= val & RESET_WMASK;
404 if (val & SOFT_POR) {
405 s->nr_resets = 0;
406 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
407 } else if (val & SOFT_XIR) {
408 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
411 break;
412 case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
413 case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
414 case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
415 case 0xf000 ... 0xf01f: /* FFB config, memory control */
416 /* we don't care */
417 default:
418 break;
422 static uint64_t apb_config_readl (void *opaque,
423 hwaddr addr, unsigned size)
425 APBState *s = opaque;
426 uint32_t val;
428 switch (addr & 0xffff) {
429 case 0x30 ... 0x4f: /* DMA error registers */
430 val = 0;
431 /* XXX: not implemented yet */
432 break;
433 case 0xc00 ... 0xc3f: /* PCI interrupt control */
434 if (addr & 4) {
435 val = s->pci_irq_map[(addr & 0x3f) >> 3];
436 } else {
437 val = 0;
439 break;
440 case 0x1000 ... 0x107f: /* OBIO interrupt control */
441 if (addr & 4) {
442 val = s->obio_irq_map[(addr & 0xff) >> 3];
443 } else {
444 val = 0;
446 break;
447 case 0x1080 ... 0x108f: /* PCI bus error */
448 if (addr & 4) {
449 val = s->pci_err_irq_map[(addr & 0xf) >> 3];
450 } else {
451 val = 0;
453 break;
454 case 0x2000 ... 0x202f: /* PCI control */
455 val = s->pci_control[(addr & 0x3f) >> 2];
456 break;
457 case 0xf020 ... 0xf027: /* Reset control */
458 if (addr & 4) {
459 val = s->reset_control;
460 } else {
461 val = 0;
463 break;
464 case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
465 case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
466 case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
467 case 0xf000 ... 0xf01f: /* FFB config, memory control */
468 /* we don't care */
469 default:
470 val = 0;
471 break;
473 APB_DPRINTF("%s: addr " TARGET_FMT_plx " -> %x\n", __func__, addr, val);
475 return val;
478 static const MemoryRegionOps apb_config_ops = {
479 .read = apb_config_readl,
480 .write = apb_config_writel,
481 .endianness = DEVICE_BIG_ENDIAN,
484 static void apb_pci_config_write(void *opaque, hwaddr addr,
485 uint64_t val, unsigned size)
487 APBState *s = opaque;
488 PCIHostState *phb = PCI_HOST_BRIDGE(s);
490 APB_DPRINTF("%s: addr " TARGET_FMT_plx " val %" PRIx64 "\n", __func__, addr, val);
491 pci_data_write(phb->bus, addr, val, size);
494 static uint64_t apb_pci_config_read(void *opaque, hwaddr addr,
495 unsigned size)
497 uint32_t ret;
498 APBState *s = opaque;
499 PCIHostState *phb = PCI_HOST_BRIDGE(s);
501 ret = pci_data_read(phb->bus, addr, size);
502 APB_DPRINTF("%s: addr " TARGET_FMT_plx " -> %x\n", __func__, addr, ret);
503 return ret;
506 /* The APB host has an IRQ line for each IRQ line of each slot. */
507 static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num)
509 /* Return the irq as swizzled by the PBM */
510 return irq_num;
513 static int pci_pbmA_map_irq(PCIDevice *pci_dev, int irq_num)
515 /* The on-board devices have fixed (legacy) OBIO intnos */
516 switch (PCI_SLOT(pci_dev->devfn)) {
517 case 1:
518 /* Onboard NIC */
519 return OBIO_NIC_IRQ;
520 case 3:
521 /* Onboard IDE */
522 return OBIO_HDD_IRQ;
523 default:
524 /* Normal intno, fall through */
525 break;
528 return ((PCI_SLOT(pci_dev->devfn) << 2) + irq_num) & 0x1f;
531 static int pci_pbmB_map_irq(PCIDevice *pci_dev, int irq_num)
533 return (0x10 + (PCI_SLOT(pci_dev->devfn) << 2) + irq_num) & 0x1f;
536 static void pci_apb_set_irq(void *opaque, int irq_num, int level)
538 APBState *s = opaque;
540 APB_DPRINTF("%s: set irq_in %d level %d\n", __func__, irq_num, level);
541 /* PCI IRQ map onto the first 32 INO. */
542 if (irq_num < 32) {
543 if (level) {
544 s->pci_irq_in |= 1ULL << irq_num;
545 if (s->pci_irq_map[irq_num >> 2] & PBM_PCI_IMR_ENABLED) {
546 pbm_set_request(s, irq_num);
548 } else {
549 s->pci_irq_in &= ~(1ULL << irq_num);
551 } else {
552 /* OBIO IRQ map onto the next 32 INO. */
553 if (level) {
554 APB_DPRINTF("%s: set irq %d level %d\n", __func__, irq_num, level);
555 s->pci_irq_in |= 1ULL << irq_num;
556 if ((s->irq_request == NO_IRQ_REQUEST)
557 && (s->obio_irq_map[irq_num - 32] & PBM_PCI_IMR_ENABLED)) {
558 pbm_set_request(s, irq_num);
560 } else {
561 s->pci_irq_in &= ~(1ULL << irq_num);
566 static void apb_pci_bridge_realize(PCIDevice *dev, Error **errp)
569 * command register:
570 * According to PCI bridge spec, after reset
571 * bus master bit is off
572 * memory space enable bit is off
573 * According to manual (805-1251.pdf).
574 * the reset value should be zero unless the boot pin is tied high
575 * (which is true) and thus it should be PCI_COMMAND_MEMORY.
577 PBMPCIBridge *br = PBM_PCI_BRIDGE(dev);
579 pci_bridge_initfn(dev, TYPE_PCI_BUS);
581 pci_set_word(dev->config + PCI_COMMAND, PCI_COMMAND_MEMORY);
582 pci_set_word(dev->config + PCI_STATUS,
583 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
584 PCI_STATUS_DEVSEL_MEDIUM);
586 /* Allow 32-bit IO addresses */
587 pci_set_word(dev->config + PCI_IO_BASE, PCI_IO_RANGE_TYPE_32);
588 pci_set_word(dev->config + PCI_IO_LIMIT, PCI_IO_RANGE_TYPE_32);
589 pci_set_word(dev->wmask + PCI_IO_BASE_UPPER16, 0xffff);
590 pci_set_word(dev->wmask + PCI_IO_LIMIT_UPPER16, 0xffff);
592 pci_bridge_update_mappings(PCI_BRIDGE(br));
595 static void pci_pbm_reset(DeviceState *d)
597 APBState *s = APB_DEVICE(d);
598 PCIDevice *pci_dev;
599 unsigned int i;
600 uint16_t cmd;
602 for (i = 0; i < 8; i++) {
603 s->pci_irq_map[i] &= PBM_PCI_IMR_MASK;
605 for (i = 0; i < 32; i++) {
606 s->obio_irq_map[i] &= PBM_PCI_IMR_MASK;
609 s->irq_request = NO_IRQ_REQUEST;
610 s->pci_irq_in = 0ULL;
612 if (s->nr_resets++ == 0) {
613 /* Power on reset */
614 s->reset_control = POR;
617 /* As this is the busA PCI bridge which contains the on-board devices
618 * attached to the ebus, ensure that we initially allow IO transactions
619 * so that we get the early serial console until OpenBIOS can properly
620 * configure the PCI bridge itself */
621 pci_dev = PCI_DEVICE(s->bridgeA);
622 cmd = pci_get_word(pci_dev->config + PCI_COMMAND);
623 pci_set_word(pci_dev->config + PCI_COMMAND, cmd | PCI_COMMAND_IO);
624 pci_bridge_update_mappings(PCI_BRIDGE(pci_dev));
627 static const MemoryRegionOps pci_config_ops = {
628 .read = apb_pci_config_read,
629 .write = apb_pci_config_write,
630 .endianness = DEVICE_LITTLE_ENDIAN,
633 static void pci_pbm_realize(DeviceState *dev, Error **errp)
635 APBState *s = APB_DEVICE(dev);
636 PCIHostState *phb = PCI_HOST_BRIDGE(dev);
637 SysBusDevice *sbd = SYS_BUS_DEVICE(s);
638 PCIDevice *pci_dev;
640 /* apb_config */
641 sysbus_mmio_map(sbd, 0, s->special_base);
642 /* PCI configuration space */
643 sysbus_mmio_map(sbd, 1, s->special_base + 0x1000000ULL);
644 /* pci_ioport */
645 sysbus_mmio_map(sbd, 2, s->special_base + 0x2000000ULL);
647 memory_region_init(&s->pci_mmio, OBJECT(s), "pci-mmio", 0x100000000ULL);
648 memory_region_add_subregion(get_system_memory(), s->mem_base,
649 &s->pci_mmio);
651 phb->bus = pci_register_bus(dev, "pci",
652 pci_apb_set_irq, pci_apb_map_irq, s,
653 &s->pci_mmio,
654 &s->pci_ioport,
655 0, 32, TYPE_PCI_BUS);
657 pci_create_simple(phb->bus, 0, "pbm-pci");
659 /* APB IOMMU */
660 memory_region_add_subregion_overlap(&s->apb_config, 0x200,
661 sysbus_mmio_get_region(SYS_BUS_DEVICE(s->iommu), 0), 1);
662 pci_setup_iommu(phb->bus, pbm_pci_dma_iommu, s->iommu);
664 /* APB secondary busses */
665 pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 0), true,
666 TYPE_PBM_PCI_BRIDGE);
667 s->bridgeB = PCI_BRIDGE(pci_dev);
668 pci_bridge_map_irq(s->bridgeB, "pciB", pci_pbmB_map_irq);
669 qdev_init_nofail(&pci_dev->qdev);
671 pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 1), true,
672 TYPE_PBM_PCI_BRIDGE);
673 s->bridgeA = PCI_BRIDGE(pci_dev);
674 pci_bridge_map_irq(s->bridgeA, "pciA", pci_pbmA_map_irq);
675 qdev_init_nofail(&pci_dev->qdev);
678 static void pci_pbm_init(Object *obj)
680 APBState *s = APB_DEVICE(obj);
681 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
682 unsigned int i;
684 for (i = 0; i < 8; i++) {
685 s->pci_irq_map[i] = (0x1f << 6) | (i << 2);
687 for (i = 0; i < 2; i++) {
688 s->pci_err_irq_map[i] = (0x1f << 6) | 0x30;
690 for (i = 0; i < 32; i++) {
691 s->obio_irq_map[i] = ((0x1f << 6) | 0x20) + i;
693 qdev_init_gpio_in_named(DEVICE(s), pci_apb_set_irq, "pbm-irq", MAX_IVEC);
694 qdev_init_gpio_out_named(DEVICE(s), s->ivec_irqs, "ivec-irq", MAX_IVEC);
695 s->irq_request = NO_IRQ_REQUEST;
696 s->pci_irq_in = 0ULL;
698 /* IOMMU */
699 object_property_add_link(obj, "iommu", TYPE_SUN4U_IOMMU,
700 (Object **) &s->iommu,
701 qdev_prop_allow_set_link_before_realize,
702 0, NULL);
704 /* apb_config */
705 memory_region_init_io(&s->apb_config, OBJECT(s), &apb_config_ops, s,
706 "apb-config", 0x10000);
707 /* at region 0 */
708 sysbus_init_mmio(sbd, &s->apb_config);
710 memory_region_init_io(&s->pci_config, OBJECT(s), &pci_config_ops, s,
711 "apb-pci-config", 0x1000000);
712 /* at region 1 */
713 sysbus_init_mmio(sbd, &s->pci_config);
715 /* pci_ioport */
716 memory_region_init(&s->pci_ioport, OBJECT(s), "apb-pci-ioport", 0x1000000);
718 /* at region 2 */
719 sysbus_init_mmio(sbd, &s->pci_ioport);
722 static void pbm_pci_host_realize(PCIDevice *d, Error **errp)
724 pci_set_word(d->config + PCI_COMMAND,
725 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
726 pci_set_word(d->config + PCI_STATUS,
727 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
728 PCI_STATUS_DEVSEL_MEDIUM);
731 static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
733 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
734 DeviceClass *dc = DEVICE_CLASS(klass);
736 k->realize = pbm_pci_host_realize;
737 k->vendor_id = PCI_VENDOR_ID_SUN;
738 k->device_id = PCI_DEVICE_ID_SUN_SABRE;
739 k->class_id = PCI_CLASS_BRIDGE_HOST;
741 * PCI-facing part of the host bridge, not usable without the
742 * host-facing part, which can't be device_add'ed, yet.
744 dc->user_creatable = false;
747 static const TypeInfo pbm_pci_host_info = {
748 .name = "pbm-pci",
749 .parent = TYPE_PCI_DEVICE,
750 .instance_size = sizeof(PCIDevice),
751 .class_init = pbm_pci_host_class_init,
752 .interfaces = (InterfaceInfo[]) {
753 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
754 { },
758 static Property pbm_pci_host_properties[] = {
759 DEFINE_PROP_UINT64("special-base", APBState, special_base, 0),
760 DEFINE_PROP_UINT64("mem-base", APBState, mem_base, 0),
761 DEFINE_PROP_END_OF_LIST(),
764 static void pbm_host_class_init(ObjectClass *klass, void *data)
766 DeviceClass *dc = DEVICE_CLASS(klass);
768 dc->realize = pci_pbm_realize;
769 dc->reset = pci_pbm_reset;
770 dc->props = pbm_pci_host_properties;
771 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
774 static const TypeInfo pbm_host_info = {
775 .name = TYPE_APB,
776 .parent = TYPE_PCI_HOST_BRIDGE,
777 .instance_size = sizeof(APBState),
778 .instance_init = pci_pbm_init,
779 .class_init = pbm_host_class_init,
782 static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
784 DeviceClass *dc = DEVICE_CLASS(klass);
785 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
787 k->realize = apb_pci_bridge_realize;
788 k->exit = pci_bridge_exitfn;
789 k->vendor_id = PCI_VENDOR_ID_SUN;
790 k->device_id = PCI_DEVICE_ID_SUN_SIMBA;
791 k->revision = 0x11;
792 k->config_write = pci_bridge_write_config;
793 k->is_bridge = 1;
794 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
795 dc->reset = pci_bridge_reset;
796 dc->vmsd = &vmstate_pci_device;
799 static const TypeInfo pbm_pci_bridge_info = {
800 .name = TYPE_PBM_PCI_BRIDGE,
801 .parent = TYPE_PCI_BRIDGE,
802 .class_init = pbm_pci_bridge_class_init,
803 .instance_size = sizeof(PBMPCIBridge),
804 .interfaces = (InterfaceInfo[]) {
805 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
806 { },
810 static const MemoryRegionOps iommu_mem_ops = {
811 .read = iommu_mem_read,
812 .write = iommu_mem_write,
813 .endianness = DEVICE_BIG_ENDIAN,
816 static void iommu_reset(DeviceState *d)
818 IOMMUState *s = SUN4U_IOMMU(d);
820 memset(s->regs, 0, IOMMU_NREGS * sizeof(uint64_t));
823 static void iommu_init(Object *obj)
825 IOMMUState *s = SUN4U_IOMMU(obj);
826 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
828 memory_region_init_iommu(&s->iommu, sizeof(s->iommu),
829 TYPE_APB_IOMMU_MEMORY_REGION, OBJECT(s),
830 "iommu-apb", UINT64_MAX);
831 address_space_init(&s->iommu_as, MEMORY_REGION(&s->iommu), "pbm-as");
833 memory_region_init_io(&s->iomem, obj, &iommu_mem_ops, s, "iommu",
834 IOMMU_NREGS * sizeof(uint64_t));
835 sysbus_init_mmio(sbd, &s->iomem);
838 static void iommu_class_init(ObjectClass *klass, void *data)
840 DeviceClass *dc = DEVICE_CLASS(klass);
842 dc->reset = iommu_reset;
845 static const TypeInfo pbm_iommu_info = {
846 .name = TYPE_SUN4U_IOMMU,
847 .parent = TYPE_SYS_BUS_DEVICE,
848 .instance_size = sizeof(IOMMUState),
849 .instance_init = iommu_init,
850 .class_init = iommu_class_init,
853 static void pbm_iommu_memory_region_class_init(ObjectClass *klass, void *data)
855 IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
857 imrc->translate = pbm_translate_iommu;
860 static const TypeInfo pbm_iommu_memory_region_info = {
861 .parent = TYPE_IOMMU_MEMORY_REGION,
862 .name = TYPE_APB_IOMMU_MEMORY_REGION,
863 .class_init = pbm_iommu_memory_region_class_init,
866 static void pbm_register_types(void)
868 type_register_static(&pbm_host_info);
869 type_register_static(&pbm_pci_host_info);
870 type_register_static(&pbm_pci_bridge_info);
871 type_register_static(&pbm_iommu_info);
872 type_register_static(&pbm_iommu_memory_region_info);
875 type_init(pbm_register_types)