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