]> git.proxmox.com Git - mirror_qemu.git/blame - hw/pci-host/apb.c
apb: move the two secondary PCI bridges objects into APBState
[mirror_qemu.git] / hw / pci-host / apb.c
CommitLineData
502a5395
PB
1/*
2 * QEMU Ultrasparc APB PCI host
3 *
4 * Copyright (c) 2006 Fabrice Bellard
9625036d 5 * Copyright (c) 2012,2013 Artyom Tarasenko
5fafdf24 6 *
502a5395
PB
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 */
80b3ada7 25
a94fd955 26/* XXX This file and most of its contents are somewhat misnamed. The
80b3ada7
PB
27 Ultrasparc PCI host is called the PCI Bus Module (PBM). The APB is
28 the secondary PCI bridge. */
29
97d5408f 30#include "qemu/osdep.h"
83c9f4ca
PB
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"
0d09e41a 36#include "hw/pci-host/apb.h"
9c17d615 37#include "sysemu/sysemu.h"
022c62cb 38#include "exec/address-spaces.h"
03dd024f 39#include "qemu/log.h"
a94fd955
BS
40
41/* debug APB */
42//#define DEBUG_APB
43
44#ifdef DEBUG_APB
001faf32
BS
45#define APB_DPRINTF(fmt, ...) \
46do { printf("APB: " fmt , ## __VA_ARGS__); } while (0)
a94fd955 47#else
001faf32 48#define APB_DPRINTF(fmt, ...)
a94fd955
BS
49#endif
50
f38b1612
MCA
51/* debug IOMMU */
52//#define DEBUG_IOMMU
53
54#ifdef DEBUG_IOMMU
55#define IOMMU_DPRINTF(fmt, ...) \
56do { printf("IOMMU: " fmt , ## __VA_ARGS__); } while (0)
57#else
58#define IOMMU_DPRINTF(fmt, ...)
59#endif
60
930f3fe1
BS
61/*
62 * Chipset docs:
63 * PBM: "UltraSPARC IIi User's Manual",
64 * http://www.sun.com/processors/manuals/805-0087.pdf
65 *
66 * APB: "Advanced PCI Bridge (APB) User's Manual",
67 * http://www.sun.com/processors/manuals/805-1251.pdf
68 */
69
95819af0
BS
70#define PBM_PCI_IMR_MASK 0x7fffffff
71#define PBM_PCI_IMR_ENABLED 0x80000000
72
af23906d
PM
73#define POR (1U << 31)
74#define SOFT_POR (1U << 30)
75#define SOFT_XIR (1U << 29)
76#define BTN_POR (1U << 28)
77#define BTN_XIR (1U << 27)
95819af0
BS
78#define RESET_MASK 0xf8000000
79#define RESET_WCMASK 0x98000000
80#define RESET_WMASK 0x60000000
81
9625036d 82#define NO_IRQ_REQUEST (MAX_IVEC + 1)
361dea40 83
9625036d
AT
84static inline void pbm_set_request(APBState *s, unsigned int irq_num)
85{
86 APB_DPRINTF("%s: request irq %d\n", __func__, irq_num);
87
88 s->irq_request = irq_num;
89 qemu_set_irq(s->ivec_irqs[irq_num], 1);
90}
91
92static inline void pbm_check_irqs(APBState *s)
93{
94
95 unsigned int i;
96
97 /* Previous request is not acknowledged, resubmit */
98 if (s->irq_request != NO_IRQ_REQUEST) {
99 pbm_set_request(s, s->irq_request);
100 return;
101 }
102 /* no request pending */
103 if (s->pci_irq_in == 0ULL) {
104 return;
105 }
106 for (i = 0; i < 32; i++) {
107 if (s->pci_irq_in & (1ULL << i)) {
108 if (s->pci_irq_map[i >> 2] & PBM_PCI_IMR_ENABLED) {
109 pbm_set_request(s, i);
110 return;
111 }
112 }
113 }
114 for (i = 32; i < 64; i++) {
115 if (s->pci_irq_in & (1ULL << i)) {
116 if (s->obio_irq_map[i - 32] & PBM_PCI_IMR_ENABLED) {
117 pbm_set_request(s, i);
118 break;
119 }
120 }
121 }
122}
123
124static inline void pbm_clear_request(APBState *s, unsigned int irq_num)
125{
126 APB_DPRINTF("%s: clear request irq %d\n", __func__, irq_num);
127 qemu_set_irq(s->ivec_irqs[irq_num], 0);
128 s->irq_request = NO_IRQ_REQUEST;
129}
94d19914 130
ae74bbe7
MCA
131static AddressSpace *pbm_pci_dma_iommu(PCIBus *bus, void *opaque, int devfn)
132{
133 IOMMUState *is = opaque;
134
135 return &is->iommu_as;
136}
137
79e2b9ae 138/* Called from RCU critical section */
3df9d748 139static IOMMUTLBEntry pbm_translate_iommu(IOMMUMemoryRegion *iommu, hwaddr addr,
bf55b7af 140 IOMMUAccessFlags flag)
ae74bbe7
MCA
141{
142 IOMMUState *is = container_of(iommu, IOMMUState, iommu);
143 hwaddr baseaddr, offset;
144 uint64_t tte;
145 uint32_t tsbsize;
146 IOMMUTLBEntry ret = {
147 .target_as = &address_space_memory,
148 .iova = 0,
149 .translated_addr = 0,
150 .addr_mask = ~(hwaddr)0,
151 .perm = IOMMU_NONE,
152 };
153
154 if (!(is->regs[IOMMU_CTRL >> 3] & IOMMU_CTRL_MMU_EN)) {
155 /* IOMMU disabled, passthrough using standard 8K page */
156 ret.iova = addr & IOMMU_PAGE_MASK_8K;
157 ret.translated_addr = addr;
158 ret.addr_mask = IOMMU_PAGE_MASK_8K;
159 ret.perm = IOMMU_RW;
160
161 return ret;
162 }
163
164 baseaddr = is->regs[IOMMU_BASE >> 3];
165 tsbsize = (is->regs[IOMMU_CTRL >> 3] >> IOMMU_CTRL_TSB_SHIFT) & 0x7;
166
167 if (is->regs[IOMMU_CTRL >> 3] & IOMMU_CTRL_TBW_SIZE) {
168 /* 64K */
169 switch (tsbsize) {
170 case 0:
171 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_64M) >> 13;
172 break;
173 case 1:
174 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_128M) >> 13;
175 break;
176 case 2:
177 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_256M) >> 13;
178 break;
179 case 3:
180 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_512M) >> 13;
181 break;
182 case 4:
183 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_1G) >> 13;
184 break;
185 case 5:
186 offset = (addr & IOMMU_TSB_64K_OFFSET_MASK_2G) >> 13;
187 break;
188 default:
189 /* Not implemented, error */
190 return ret;
191 }
192 } else {
193 /* 8K */
194 switch (tsbsize) {
195 case 0:
196 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_8M) >> 10;
197 break;
198 case 1:
199 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_16M) >> 10;
200 break;
201 case 2:
202 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_32M) >> 10;
203 break;
204 case 3:
205 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_64M) >> 10;
206 break;
207 case 4:
208 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_128M) >> 10;
209 break;
210 case 5:
211 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_256M) >> 10;
212 break;
213 case 6:
214 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_512M) >> 10;
215 break;
216 case 7:
217 offset = (addr & IOMMU_TSB_8K_OFFSET_MASK_1G) >> 10;
218 break;
219 }
220 }
221
42874d3a
PM
222 tte = address_space_ldq_be(&address_space_memory, baseaddr + offset,
223 MEMTXATTRS_UNSPECIFIED, NULL);
ae74bbe7
MCA
224
225 if (!(tte & IOMMU_TTE_DATA_V)) {
226 /* Invalid mapping */
227 return ret;
228 }
229
230 if (tte & IOMMU_TTE_DATA_W) {
231 /* Writeable */
232 ret.perm = IOMMU_RW;
233 } else {
234 ret.perm = IOMMU_RO;
235 }
236
237 /* Extract phys */
238 if (tte & IOMMU_TTE_DATA_SIZE) {
239 /* 64K */
240 ret.iova = addr & IOMMU_PAGE_MASK_64K;
241 ret.translated_addr = tte & IOMMU_TTE_PHYS_MASK_64K;
242 ret.addr_mask = (IOMMU_PAGE_SIZE_64K - 1);
243 } else {
244 /* 8K */
245 ret.iova = addr & IOMMU_PAGE_MASK_8K;
246 ret.translated_addr = tte & IOMMU_TTE_PHYS_MASK_8K;
247 ret.addr_mask = (IOMMU_PAGE_SIZE_8K - 1);
248 }
249
250 return ret;
251}
252
f38b1612
MCA
253static void iommu_config_write(void *opaque, hwaddr addr,
254 uint64_t val, unsigned size)
255{
256 IOMMUState *is = opaque;
257
258 IOMMU_DPRINTF("IOMMU config write: 0x%" HWADDR_PRIx " val: %" PRIx64
259 " size: %d\n", addr, val, size);
260
261 switch (addr) {
262 case IOMMU_CTRL:
263 if (size == 4) {
264 is->regs[IOMMU_CTRL >> 3] &= 0xffffffffULL;
265 is->regs[IOMMU_CTRL >> 3] |= val << 32;
266 } else {
68716da7 267 is->regs[IOMMU_CTRL >> 3] = val;
f38b1612
MCA
268 }
269 break;
270 case IOMMU_CTRL + 0x4:
271 is->regs[IOMMU_CTRL >> 3] &= 0xffffffff00000000ULL;
272 is->regs[IOMMU_CTRL >> 3] |= val & 0xffffffffULL;
273 break;
274 case IOMMU_BASE:
275 if (size == 4) {
276 is->regs[IOMMU_BASE >> 3] &= 0xffffffffULL;
277 is->regs[IOMMU_BASE >> 3] |= val << 32;
278 } else {
68716da7 279 is->regs[IOMMU_BASE >> 3] = val;
f38b1612
MCA
280 }
281 break;
282 case IOMMU_BASE + 0x4:
283 is->regs[IOMMU_BASE >> 3] &= 0xffffffff00000000ULL;
284 is->regs[IOMMU_BASE >> 3] |= val & 0xffffffffULL;
285 break;
b87b0644
MCA
286 case IOMMU_FLUSH:
287 case IOMMU_FLUSH + 0x4:
288 break;
f38b1612
MCA
289 default:
290 qemu_log_mask(LOG_UNIMP,
291 "apb iommu: Unimplemented register write "
292 "reg 0x%" HWADDR_PRIx " size 0x%x value 0x%" PRIx64 "\n",
293 addr, size, val);
294 break;
295 }
296}
297
298static uint64_t iommu_config_read(void *opaque, hwaddr addr, unsigned size)
299{
300 IOMMUState *is = opaque;
301 uint64_t val;
302
303 switch (addr) {
304 case IOMMU_CTRL:
305 if (size == 4) {
306 val = is->regs[IOMMU_CTRL >> 3] >> 32;
307 } else {
308 val = is->regs[IOMMU_CTRL >> 3];
309 }
310 break;
311 case IOMMU_CTRL + 0x4:
312 val = is->regs[IOMMU_CTRL >> 3] & 0xffffffffULL;
313 break;
314 case IOMMU_BASE:
315 if (size == 4) {
316 val = is->regs[IOMMU_BASE >> 3] >> 32;
317 } else {
318 val = is->regs[IOMMU_BASE >> 3];
319 }
320 break;
321 case IOMMU_BASE + 0x4:
322 val = is->regs[IOMMU_BASE >> 3] & 0xffffffffULL;
323 break;
b87b0644
MCA
324 case IOMMU_FLUSH:
325 case IOMMU_FLUSH + 0x4:
326 val = 0;
327 break;
f38b1612
MCA
328 default:
329 qemu_log_mask(LOG_UNIMP,
330 "apb iommu: Unimplemented register read "
331 "reg 0x%" HWADDR_PRIx " size 0x%x\n",
332 addr, size);
333 val = 0;
334 break;
335 }
336
337 IOMMU_DPRINTF("IOMMU config read: 0x%" HWADDR_PRIx " val: %" PRIx64
338 " size: %d\n", addr, val, size);
339
340 return val;
341}
342
a8170e5e 343static void apb_config_writel (void *opaque, hwaddr addr,
3812ed0b 344 uint64_t val, unsigned size)
502a5395 345{
95819af0 346 APBState *s = opaque;
ea9a6606 347 IOMMUState *is = &s->iommu;
95819af0 348
c0907c9e 349 APB_DPRINTF("%s: addr " TARGET_FMT_plx " val %" PRIx64 "\n", __func__, addr, val);
95819af0
BS
350
351 switch (addr & 0xffff) {
352 case 0x30 ... 0x4f: /* DMA error registers */
353 /* XXX: not implemented yet */
354 break;
fd7fbc8f 355 case 0x200 ... 0x217: /* IOMMU */
b87b0644 356 iommu_config_write(is, (addr & 0x1f), val, size);
95819af0 357 break;
95819af0
BS
358 case 0xc00 ... 0xc3f: /* PCI interrupt control */
359 if (addr & 4) {
9625036d
AT
360 unsigned int ino = (addr & 0x3f) >> 3;
361 s->pci_irq_map[ino] &= PBM_PCI_IMR_MASK;
362 s->pci_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
363 if ((s->irq_request == ino) && !(val & ~PBM_PCI_IMR_MASK)) {
364 pbm_clear_request(s, ino);
365 }
366 pbm_check_irqs(s);
95819af0
BS
367 }
368 break;
de739df8 369 case 0x1000 ... 0x107f: /* OBIO interrupt control */
361dea40 370 if (addr & 4) {
9625036d
AT
371 unsigned int ino = ((addr & 0xff) >> 3);
372 s->obio_irq_map[ino] &= PBM_PCI_IMR_MASK;
373 s->obio_irq_map[ino] |= val & ~PBM_PCI_IMR_MASK;
374 if ((s->irq_request == (ino | 0x20))
375 && !(val & ~PBM_PCI_IMR_MASK)) {
376 pbm_clear_request(s, ino | 0x20);
377 }
378 pbm_check_irqs(s);
361dea40
BS
379 }
380 break;
9625036d 381 case 0x1400 ... 0x14ff: /* PCI interrupt clear */
94d19914 382 if (addr & 4) {
9625036d
AT
383 unsigned int ino = (addr & 0xff) >> 5;
384 if ((s->irq_request / 4) == ino) {
385 pbm_clear_request(s, s->irq_request);
386 pbm_check_irqs(s);
387 }
94d19914
AT
388 }
389 break;
390 case 0x1800 ... 0x1860: /* OBIO interrupt clear */
391 if (addr & 4) {
9625036d
AT
392 unsigned int ino = ((addr & 0xff) >> 3) | 0x20;
393 if (s->irq_request == ino) {
394 pbm_clear_request(s, ino);
395 pbm_check_irqs(s);
396 }
94d19914
AT
397 }
398 break;
95819af0
BS
399 case 0x2000 ... 0x202f: /* PCI control */
400 s->pci_control[(addr & 0x3f) >> 2] = val;
401 break;
402 case 0xf020 ... 0xf027: /* Reset control */
403 if (addr & 4) {
404 val &= RESET_MASK;
405 s->reset_control &= ~(val & RESET_WCMASK);
406 s->reset_control |= val & RESET_WMASK;
407 if (val & SOFT_POR) {
9c0afd0e 408 s->nr_resets = 0;
cf83f140 409 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
95819af0 410 } else if (val & SOFT_XIR) {
cf83f140 411 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
95819af0
BS
412 }
413 }
414 break;
415 case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
416 case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
417 case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
418 case 0xf000 ... 0xf01f: /* FFB config, memory control */
419 /* we don't care */
502a5395 420 default:
f930d07e 421 break;
502a5395
PB
422 }
423}
424
3812ed0b 425static uint64_t apb_config_readl (void *opaque,
a8170e5e 426 hwaddr addr, unsigned size)
502a5395 427{
95819af0 428 APBState *s = opaque;
ea9a6606 429 IOMMUState *is = &s->iommu;
502a5395
PB
430 uint32_t val;
431
95819af0
BS
432 switch (addr & 0xffff) {
433 case 0x30 ... 0x4f: /* DMA error registers */
434 val = 0;
435 /* XXX: not implemented yet */
436 break;
fd7fbc8f 437 case 0x200 ... 0x217: /* IOMMU */
b87b0644 438 val = iommu_config_read(is, (addr & 0x1f), size);
95819af0 439 break;
95819af0
BS
440 case 0xc00 ... 0xc3f: /* PCI interrupt control */
441 if (addr & 4) {
442 val = s->pci_irq_map[(addr & 0x3f) >> 3];
443 } else {
444 val = 0;
445 }
446 break;
de739df8 447 case 0x1000 ... 0x107f: /* OBIO interrupt control */
361dea40
BS
448 if (addr & 4) {
449 val = s->obio_irq_map[(addr & 0xff) >> 3];
450 } else {
451 val = 0;
452 }
453 break;
de739df8
MCA
454 case 0x1080 ... 0x108f: /* PCI bus error */
455 if (addr & 4) {
456 val = s->pci_err_irq_map[(addr & 0xf) >> 3];
457 } else {
458 val = 0;
459 }
460 break;
95819af0
BS
461 case 0x2000 ... 0x202f: /* PCI control */
462 val = s->pci_control[(addr & 0x3f) >> 2];
463 break;
464 case 0xf020 ... 0xf027: /* Reset control */
465 if (addr & 4) {
466 val = s->reset_control;
467 } else {
468 val = 0;
469 }
470 break;
471 case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
472 case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
473 case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
474 case 0xf000 ... 0xf01f: /* FFB config, memory control */
475 /* we don't care */
502a5395 476 default:
f930d07e
BS
477 val = 0;
478 break;
502a5395 479 }
c0907c9e 480 APB_DPRINTF("%s: addr " TARGET_FMT_plx " -> %x\n", __func__, addr, val);
95819af0 481
502a5395
PB
482 return val;
483}
484
3812ed0b
AK
485static const MemoryRegionOps apb_config_ops = {
486 .read = apb_config_readl,
487 .write = apb_config_writel,
b2f9005a 488 .endianness = DEVICE_BIG_ENDIAN,
502a5395
PB
489};
490
a8170e5e 491static void apb_pci_config_write(void *opaque, hwaddr addr,
3812ed0b 492 uint64_t val, unsigned size)
5a5d4a76 493{
3812ed0b 494 APBState *s = opaque;
2b8fbcd8 495 PCIHostState *phb = PCI_HOST_BRIDGE(s);
63e6f31d 496
c0907c9e 497 APB_DPRINTF("%s: addr " TARGET_FMT_plx " val %" PRIx64 "\n", __func__, addr, val);
2b8fbcd8 498 pci_data_write(phb->bus, addr, val, size);
5a5d4a76
BS
499}
500
a8170e5e 501static uint64_t apb_pci_config_read(void *opaque, hwaddr addr,
3812ed0b 502 unsigned size)
5a5d4a76
BS
503{
504 uint32_t ret;
3812ed0b 505 APBState *s = opaque;
2b8fbcd8 506 PCIHostState *phb = PCI_HOST_BRIDGE(s);
5a5d4a76 507
2b8fbcd8 508 ret = pci_data_read(phb->bus, addr, size);
c0907c9e 509 APB_DPRINTF("%s: addr " TARGET_FMT_plx " -> %x\n", __func__, addr, ret);
5a5d4a76
BS
510 return ret;
511}
512
80b3ada7 513/* The APB host has an IRQ line for each IRQ line of each slot. */
d2b59317 514static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num)
502a5395 515{
6864fa38
MCA
516 /* Return the irq as swizzled by the PBM */
517 return irq_num;
80b3ada7
PB
518}
519
520static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)
521{
6864fa38
MCA
522 PBMPCIBridge *br = PBM_PCI_BRIDGE(pci_bridge_get_device(
523 PCI_BUS(qdev_get_parent_bus(DEVICE(pci_dev)))));
524
80b3ada7 525 int bus_offset;
6864fa38
MCA
526 if (br->busA) {
527 bus_offset = 0x0;
528
529 /* The on-board devices have fixed (legacy) OBIO intnos */
530 switch (PCI_SLOT(pci_dev->devfn)) {
531 case 1:
532 /* Onboard NIC */
533 return 0x21;
534 case 3:
535 /* Onboard IDE */
536 return 0x20;
537
538 default:
539 /* Normal intno, fall through */
540 break;
541 }
542 } else {
543 bus_offset = 0x10;
544 }
903ce9fe 545 return (bus_offset + (PCI_SLOT(pci_dev->devfn) << 2) + irq_num) & 0x1f;
d2b59317
PB
546}
547
5d4e84c8 548static void pci_apb_set_irq(void *opaque, int irq_num, int level)
d2b59317 549{
95819af0 550 APBState *s = opaque;
5d4e84c8 551
9625036d 552 APB_DPRINTF("%s: set irq_in %d level %d\n", __func__, irq_num, level);
80b3ada7 553 /* PCI IRQ map onto the first 32 INO. */
95819af0 554 if (irq_num < 32) {
9625036d
AT
555 if (level) {
556 s->pci_irq_in |= 1ULL << irq_num;
557 if (s->pci_irq_map[irq_num >> 2] & PBM_PCI_IMR_ENABLED) {
558 pbm_set_request(s, irq_num);
559 }
361dea40 560 } else {
9625036d 561 s->pci_irq_in &= ~(1ULL << irq_num);
361dea40
BS
562 }
563 } else {
9625036d
AT
564 /* OBIO IRQ map onto the next 32 INO. */
565 if (level) {
361dea40 566 APB_DPRINTF("%s: set irq %d level %d\n", __func__, irq_num, level);
9625036d
AT
567 s->pci_irq_in |= 1ULL << irq_num;
568 if ((s->irq_request == NO_IRQ_REQUEST)
569 && (s->obio_irq_map[irq_num - 32] & PBM_PCI_IMR_ENABLED)) {
570 pbm_set_request(s, irq_num);
571 }
95819af0 572 } else {
9625036d 573 s->pci_irq_in &= ~(1ULL << irq_num);
95819af0
BS
574 }
575 }
502a5395
PB
576}
577
be0d9760 578static void apb_pci_bridge_realize(PCIDevice *dev, Error **errp)
d6318738 579{
d6318738
MT
580 /*
581 * command register:
582 * According to PCI bridge spec, after reset
583 * bus master bit is off
584 * memory space enable bit is off
585 * According to manual (805-1251.pdf).
586 * the reset value should be zero unless the boot pin is tied high
587 * (which is true) and thus it should be PCI_COMMAND_MEMORY.
588 */
e5fd1eb0
MCA
589 uint16_t cmd = PCI_COMMAND_MEMORY;
590 PBMPCIBridge *br = PBM_PCI_BRIDGE(dev);
591
592 pci_bridge_initfn(dev, TYPE_PCI_BUS);
593
594 /* If initialising busA, ensure that we allow IO transactions so that
595 we get the early serial console until OpenBIOS configures the bridge */
596 if (br->busA) {
597 cmd |= PCI_COMMAND_IO;
598 }
599
600 pci_set_word(dev->config + PCI_COMMAND, cmd);
9fe52c7f
BS
601 pci_set_word(dev->config + PCI_STATUS,
602 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
603 PCI_STATUS_DEVSEL_MEDIUM);
e5fd1eb0 604
6864fa38
MCA
605 /* Allow 32-bit IO addresses */
606 pci_set_word(dev->config + PCI_IO_BASE, PCI_IO_RANGE_TYPE_32);
607 pci_set_word(dev->config + PCI_IO_LIMIT, PCI_IO_RANGE_TYPE_32);
608 pci_set_word(dev->wmask + PCI_IO_BASE_UPPER16, 0xffff);
609 pci_set_word(dev->wmask + PCI_IO_LIMIT_UPPER16, 0xffff);
610
e5fd1eb0 611 pci_bridge_update_mappings(PCI_BRIDGE(br));
d6318738
MT
612}
613
588978c0 614APBState *pci_apb_init(hwaddr special_base,
4272ad40 615 hwaddr mem_base)
502a5395 616{
72f44c8c
BS
617 DeviceState *dev;
618 SysBusDevice *s;
2b8fbcd8 619 PCIHostState *phb;
72f44c8c 620 APBState *d;
ea9a6606 621 IOMMUState *is;
68f79994 622 PCIDevice *pci_dev;
502a5395 623
80b3ada7 624 /* Ultrasparc PBM main bus */
2b8fbcd8 625 dev = qdev_create(NULL, TYPE_APB);
2f3ae0b2
MA
626 d = APB_DEVICE(dev);
627 phb = PCI_HOST_BRIDGE(dev);
628 phb->bus = pci_register_bus(DEVICE(phb), "pci",
6864fa38 629 pci_apb_set_irq, pci_apb_map_irq, d,
2f3ae0b2 630 &d->pci_mmio,
6864fa38 631 &d->pci_ioport,
2f3ae0b2 632 0, 32, TYPE_PCI_BUS);
e23a1b33 633 qdev_init_nofail(dev);
1356b98d 634 s = SYS_BUS_DEVICE(dev);
72f44c8c 635 /* apb_config */
bae7b517 636 sysbus_mmio_map(s, 0, special_base);
d63baf92
IK
637 /* PCI configuration space */
638 sysbus_mmio_map(s, 1, special_base + 0x1000000ULL);
72f44c8c 639 /* pci_ioport */
d63baf92 640 sysbus_mmio_map(s, 2, special_base + 0x2000000ULL);
d63baf92 641
40c5dce9 642 memory_region_init(&d->pci_mmio, OBJECT(s), "pci-mmio", 0x100000000ULL);
f69539b1
BS
643 memory_region_add_subregion(get_system_memory(), mem_base, &d->pci_mmio);
644
2b8fbcd8 645 pci_create_simple(phb->bus, 0, "pbm-pci");
d63baf92 646
ea9a6606
MCA
647 /* APB IOMMU */
648 is = &d->iommu;
649 memset(is, 0, sizeof(IOMMUState));
650
1221a474
AK
651 memory_region_init_iommu(&is->iommu, sizeof(is->iommu),
652 TYPE_APB_IOMMU_MEMORY_REGION, OBJECT(dev),
ae74bbe7 653 "iommu-apb", UINT64_MAX);
3df9d748 654 address_space_init(&is->iommu_as, MEMORY_REGION(&is->iommu), "pbm-as");
ae74bbe7
MCA
655 pci_setup_iommu(phb->bus, pbm_pci_dma_iommu, is);
656
72f44c8c 657 /* APB secondary busses */
2b8fbcd8 658 pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 0), true,
e5fd1eb0 659 TYPE_PBM_PCI_BRIDGE);
4272ad40
MCA
660 d->bridgeB = PCI_BRIDGE(pci_dev);
661 pci_bridge_map_irq(d->bridgeB, "pciB", pci_pbm_map_irq);
68f79994 662 qdev_init_nofail(&pci_dev->qdev);
68f79994 663
2b8fbcd8 664 pci_dev = pci_create_multifunction(phb->bus, PCI_DEVFN(1, 1), true,
e5fd1eb0 665 TYPE_PBM_PCI_BRIDGE);
4272ad40
MCA
666 d->bridgeA = PCI_BRIDGE(pci_dev);
667 pci_bridge_map_irq(d->bridgeA, "pciA", pci_pbm_map_irq);
e5fd1eb0 668 qdev_prop_set_bit(DEVICE(pci_dev), "busA", true);
68f79994 669 qdev_init_nofail(&pci_dev->qdev);
502a5395 670
588978c0 671 return d;
72f44c8c
BS
672}
673
95819af0 674static void pci_pbm_reset(DeviceState *d)
72f44c8c 675{
95819af0 676 unsigned int i;
2b8fbcd8 677 APBState *s = APB_DEVICE(d);
72f44c8c 678
95819af0
BS
679 for (i = 0; i < 8; i++) {
680 s->pci_irq_map[i] &= PBM_PCI_IMR_MASK;
681 }
d1d80055
AT
682 for (i = 0; i < 32; i++) {
683 s->obio_irq_map[i] &= PBM_PCI_IMR_MASK;
684 }
95819af0 685
9625036d
AT
686 s->irq_request = NO_IRQ_REQUEST;
687 s->pci_irq_in = 0ULL;
688
9c0afd0e 689 if (s->nr_resets++ == 0) {
95819af0
BS
690 /* Power on reset */
691 s->reset_control = POR;
692 }
693}
694
3812ed0b
AK
695static const MemoryRegionOps pci_config_ops = {
696 .read = apb_pci_config_read,
697 .write = apb_pci_config_write,
b2f9005a 698 .endianness = DEVICE_LITTLE_ENDIAN,
3812ed0b
AK
699};
700
b26f4419 701static int pci_pbm_init_device(DeviceState *dev)
95819af0 702{
b26f4419
MCA
703 APBState *s = APB_DEVICE(dev);
704 SysBusDevice *sbd = SYS_BUS_DEVICE(s);
95819af0 705 unsigned int i;
72f44c8c 706
95819af0
BS
707 for (i = 0; i < 8; i++) {
708 s->pci_irq_map[i] = (0x1f << 6) | (i << 2);
709 }
de739df8
MCA
710 for (i = 0; i < 2; i++) {
711 s->pci_err_irq_map[i] = (0x1f << 6) | 0x30;
712 }
d1d80055
AT
713 for (i = 0; i < 32; i++) {
714 s->obio_irq_map[i] = ((0x1f << 6) | 0x20) + i;
715 }
361dea40 716 s->pbm_irqs = qemu_allocate_irqs(pci_apb_set_irq, s, MAX_IVEC);
2a4d6af5 717 qdev_init_gpio_out_named(DEVICE(s), s->ivec_irqs, "ivec-irq", MAX_IVEC);
9625036d
AT
718 s->irq_request = NO_IRQ_REQUEST;
719 s->pci_irq_in = 0ULL;
95819af0 720
72f44c8c 721 /* apb_config */
40c5dce9
PB
722 memory_region_init_io(&s->apb_config, OBJECT(s), &apb_config_ops, s,
723 "apb-config", 0x10000);
d63baf92 724 /* at region 0 */
b26f4419 725 sysbus_init_mmio(sbd, &s->apb_config);
d63baf92 726
40c5dce9
PB
727 memory_region_init_io(&s->pci_config, OBJECT(s), &pci_config_ops, s,
728 "apb-pci-config", 0x1000000);
d63baf92 729 /* at region 1 */
b26f4419 730 sysbus_init_mmio(sbd, &s->pci_config);
d63baf92
IK
731
732 /* pci_ioport */
6864fa38
MCA
733 memory_region_init(&s->pci_ioport, OBJECT(s), "apb-pci-ioport", 0x1000000);
734
d63baf92 735 /* at region 2 */
b26f4419 736 sysbus_init_mmio(sbd, &s->pci_ioport);
d63baf92 737
81a322d4 738 return 0;
72f44c8c 739}
502a5395 740
9af21dbe 741static void pbm_pci_host_realize(PCIDevice *d, Error **errp)
72f44c8c 742{
9fe52c7f
BS
743 pci_set_word(d->config + PCI_COMMAND,
744 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
745 pci_set_word(d->config + PCI_STATUS,
746 PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
747 PCI_STATUS_DEVSEL_MEDIUM);
72f44c8c 748}
80b3ada7 749
40021f08
AL
750static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
751{
752 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
08c58f92 753 DeviceClass *dc = DEVICE_CLASS(klass);
40021f08 754
9af21dbe 755 k->realize = pbm_pci_host_realize;
40021f08
AL
756 k->vendor_id = PCI_VENDOR_ID_SUN;
757 k->device_id = PCI_DEVICE_ID_SUN_SABRE;
758 k->class_id = PCI_CLASS_BRIDGE_HOST;
08c58f92
MA
759 /*
760 * PCI-facing part of the host bridge, not usable without the
761 * host-facing part, which can't be device_add'ed, yet.
762 */
e90f2a8c 763 dc->user_creatable = false;
40021f08
AL
764}
765
8c43a6f0 766static const TypeInfo pbm_pci_host_info = {
39bffca2
AL
767 .name = "pbm-pci",
768 .parent = TYPE_PCI_DEVICE,
769 .instance_size = sizeof(PCIDevice),
770 .class_init = pbm_pci_host_class_init,
fd3b02c8
EH
771 .interfaces = (InterfaceInfo[]) {
772 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
773 { },
774 },
72f44c8c
BS
775};
776
999e12bb
AL
777static void pbm_host_class_init(ObjectClass *klass, void *data)
778{
39bffca2 779 DeviceClass *dc = DEVICE_CLASS(klass);
999e12bb 780
b26f4419 781 dc->init = pci_pbm_init_device;
39bffca2 782 dc->reset = pci_pbm_reset;
b26f4419 783 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
999e12bb
AL
784}
785
8c43a6f0 786static const TypeInfo pbm_host_info = {
2b8fbcd8
PB
787 .name = TYPE_APB,
788 .parent = TYPE_PCI_HOST_BRIDGE,
39bffca2
AL
789 .instance_size = sizeof(APBState),
790 .class_init = pbm_host_class_init,
95819af0 791};
68f79994 792
e5fd1eb0
MCA
793static Property pbm_pci_properties[] = {
794 DEFINE_PROP_BOOL("busA", PBMPCIBridge, busA, false),
795 DEFINE_PROP_END_OF_LIST(),
796};
797
40021f08
AL
798static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
799{
39bffca2 800 DeviceClass *dc = DEVICE_CLASS(klass);
40021f08
AL
801 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
802
be0d9760 803 k->realize = apb_pci_bridge_realize;
40021f08
AL
804 k->exit = pci_bridge_exitfn;
805 k->vendor_id = PCI_VENDOR_ID_SUN;
806 k->device_id = PCI_DEVICE_ID_SUN_SIMBA;
807 k->revision = 0x11;
808 k->config_write = pci_bridge_write_config;
809 k->is_bridge = 1;
125ee0ed 810 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
39bffca2
AL
811 dc->reset = pci_bridge_reset;
812 dc->vmsd = &vmstate_pci_device;
e5fd1eb0 813 dc->props = pbm_pci_properties;
40021f08
AL
814}
815
8c43a6f0 816static const TypeInfo pbm_pci_bridge_info = {
e5fd1eb0 817 .name = TYPE_PBM_PCI_BRIDGE,
f055e96b 818 .parent = TYPE_PCI_BRIDGE,
39bffca2 819 .class_init = pbm_pci_bridge_class_init,
e5fd1eb0 820 .instance_size = sizeof(PBMPCIBridge),
fd3b02c8
EH
821 .interfaces = (InterfaceInfo[]) {
822 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
823 { },
824 },
68f79994
IY
825};
826
1221a474
AK
827static void pbm_iommu_memory_region_class_init(ObjectClass *klass, void *data)
828{
829 IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
830
831 imrc->translate = pbm_translate_iommu;
832}
833
834static const TypeInfo pbm_iommu_memory_region_info = {
835 .parent = TYPE_IOMMU_MEMORY_REGION,
836 .name = TYPE_APB_IOMMU_MEMORY_REGION,
837 .class_init = pbm_iommu_memory_region_class_init,
838};
839
83f7d43a 840static void pbm_register_types(void)
72f44c8c 841{
39bffca2
AL
842 type_register_static(&pbm_host_info);
843 type_register_static(&pbm_pci_host_info);
844 type_register_static(&pbm_pci_bridge_info);
1221a474 845 type_register_static(&pbm_iommu_memory_region_info);
502a5395 846}
72f44c8c 847
83f7d43a 848type_init(pbm_register_types)