]> Git Repo - qemu.git/blob - hw/apb_pci.c
sparc64: implement PCI and ISA irqs
[qemu.git] / hw / apb_pci.c
1 /*
2  * QEMU Ultrasparc APB PCI host
3  *
4  * Copyright (c) 2006 Fabrice Bellard
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24
25 /* XXX This file and most of its contents are somewhat misnamed.  The
26    Ultrasparc PCI host is called the PCI Bus Module (PBM).  The APB is
27    the secondary PCI bridge.  */
28
29 #include "sysbus.h"
30 #include "pci.h"
31 #include "pci_host.h"
32 #include "pci_bridge.h"
33 #include "pci_internals.h"
34 #include "apb_pci.h"
35 #include "sysemu.h"
36 #include "exec-memory.h"
37
38 /* debug APB */
39 //#define DEBUG_APB
40
41 #ifdef DEBUG_APB
42 #define APB_DPRINTF(fmt, ...) \
43 do { printf("APB: " fmt , ## __VA_ARGS__); } while (0)
44 #else
45 #define APB_DPRINTF(fmt, ...)
46 #endif
47
48 /*
49  * Chipset docs:
50  * PBM: "UltraSPARC IIi User's Manual",
51  * http://www.sun.com/processors/manuals/805-0087.pdf
52  *
53  * APB: "Advanced PCI Bridge (APB) User's Manual",
54  * http://www.sun.com/processors/manuals/805-1251.pdf
55  */
56
57 #define PBM_PCI_IMR_MASK    0x7fffffff
58 #define PBM_PCI_IMR_ENABLED 0x80000000
59
60 #define POR          (1 << 31)
61 #define SOFT_POR     (1 << 30)
62 #define SOFT_XIR     (1 << 29)
63 #define BTN_POR      (1 << 28)
64 #define BTN_XIR      (1 << 27)
65 #define RESET_MASK   0xf8000000
66 #define RESET_WCMASK 0x98000000
67 #define RESET_WMASK  0x60000000
68
69 #define MAX_IVEC 0x30
70
71 typedef struct APBState {
72     SysBusDevice busdev;
73     PCIBus      *bus;
74     MemoryRegion apb_config;
75     MemoryRegion pci_config;
76     MemoryRegion pci_mmio;
77     MemoryRegion pci_ioport;
78     uint32_t iommu[4];
79     uint32_t pci_control[16];
80     uint32_t pci_irq_map[8];
81     uint32_t obio_irq_map[32];
82     qemu_irq *pbm_irqs;
83     qemu_irq *ivec_irqs;
84     uint32_t reset_control;
85     unsigned int nr_resets;
86 } APBState;
87
88 static void apb_config_writel (void *opaque, target_phys_addr_t addr,
89                                uint64_t val, unsigned size)
90 {
91     APBState *s = opaque;
92
93     APB_DPRINTF("%s: addr " TARGET_FMT_lx " val %" PRIx64 "\n", __func__, addr, val);
94
95     switch (addr & 0xffff) {
96     case 0x30 ... 0x4f: /* DMA error registers */
97         /* XXX: not implemented yet */
98         break;
99     case 0x200 ... 0x20b: /* IOMMU */
100         s->iommu[(addr & 0xf) >> 2] = val;
101         break;
102     case 0x20c ... 0x3ff: /* IOMMU flush */
103         break;
104     case 0xc00 ... 0xc3f: /* PCI interrupt control */
105         if (addr & 4) {
106             s->pci_irq_map[(addr & 0x3f) >> 3] &= PBM_PCI_IMR_MASK;
107             s->pci_irq_map[(addr & 0x3f) >> 3] |= val & ~PBM_PCI_IMR_MASK;
108         }
109         break;
110     case 0x1000 ... 0x1080: /* OBIO interrupt control */
111         if (addr & 4) {
112             s->obio_irq_map[(addr & 0xff) >> 3] &= PBM_PCI_IMR_MASK;
113             s->obio_irq_map[(addr & 0xff) >> 3] |= val & ~PBM_PCI_IMR_MASK;
114         }
115         break;
116     case 0x2000 ... 0x202f: /* PCI control */
117         s->pci_control[(addr & 0x3f) >> 2] = val;
118         break;
119     case 0xf020 ... 0xf027: /* Reset control */
120         if (addr & 4) {
121             val &= RESET_MASK;
122             s->reset_control &= ~(val & RESET_WCMASK);
123             s->reset_control |= val & RESET_WMASK;
124             if (val & SOFT_POR) {
125                 s->nr_resets = 0;
126                 qemu_system_reset_request();
127             } else if (val & SOFT_XIR) {
128                 qemu_system_reset_request();
129             }
130         }
131         break;
132     case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
133     case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
134     case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
135     case 0xf000 ... 0xf01f: /* FFB config, memory control */
136         /* we don't care */
137     default:
138         break;
139     }
140 }
141
142 static uint64_t apb_config_readl (void *opaque,
143                                   target_phys_addr_t addr, unsigned size)
144 {
145     APBState *s = opaque;
146     uint32_t val;
147
148     switch (addr & 0xffff) {
149     case 0x30 ... 0x4f: /* DMA error registers */
150         val = 0;
151         /* XXX: not implemented yet */
152         break;
153     case 0x200 ... 0x20b: /* IOMMU */
154         val = s->iommu[(addr & 0xf) >> 2];
155         break;
156     case 0x20c ... 0x3ff: /* IOMMU flush */
157         val = 0;
158         break;
159     case 0xc00 ... 0xc3f: /* PCI interrupt control */
160         if (addr & 4) {
161             val = s->pci_irq_map[(addr & 0x3f) >> 3];
162         } else {
163             val = 0;
164         }
165         break;
166     case 0x1000 ... 0x1080: /* OBIO interrupt control */
167         if (addr & 4) {
168             val = s->obio_irq_map[(addr & 0xff) >> 3];
169         } else {
170             val = 0;
171         }
172         break;
173     case 0x2000 ... 0x202f: /* PCI control */
174         val = s->pci_control[(addr & 0x3f) >> 2];
175         break;
176     case 0xf020 ... 0xf027: /* Reset control */
177         if (addr & 4) {
178             val = s->reset_control;
179         } else {
180             val = 0;
181         }
182         break;
183     case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */
184     case 0xa400 ... 0xa67f: /* IOMMU diagnostics */
185     case 0xa800 ... 0xa80f: /* Interrupt diagnostics */
186     case 0xf000 ... 0xf01f: /* FFB config, memory control */
187         /* we don't care */
188     default:
189         val = 0;
190         break;
191     }
192     APB_DPRINTF("%s: addr " TARGET_FMT_lx " -> %x\n", __func__, addr, val);
193
194     return val;
195 }
196
197 static const MemoryRegionOps apb_config_ops = {
198     .read = apb_config_readl,
199     .write = apb_config_writel,
200     .endianness = DEVICE_NATIVE_ENDIAN,
201 };
202
203 static void apb_pci_config_write(void *opaque, target_phys_addr_t addr,
204                                  uint64_t val, unsigned size)
205 {
206     APBState *s = opaque;
207
208     val = qemu_bswap_len(val, size);
209     APB_DPRINTF("%s: addr " TARGET_FMT_lx " val %" PRIx64 "\n", __func__, addr, val);
210     pci_data_write(s->bus, addr, val, size);
211 }
212
213 static uint64_t apb_pci_config_read(void *opaque, target_phys_addr_t addr,
214                                     unsigned size)
215 {
216     uint32_t ret;
217     APBState *s = opaque;
218
219     ret = pci_data_read(s->bus, addr, size);
220     ret = qemu_bswap_len(ret, size);
221     APB_DPRINTF("%s: addr " TARGET_FMT_lx " -> %x\n", __func__, addr, ret);
222     return ret;
223 }
224
225 static void pci_apb_iowriteb (void *opaque, target_phys_addr_t addr,
226                                   uint32_t val)
227 {
228     cpu_outb(addr & IOPORTS_MASK, val);
229 }
230
231 static void pci_apb_iowritew (void *opaque, target_phys_addr_t addr,
232                                   uint32_t val)
233 {
234     cpu_outw(addr & IOPORTS_MASK, bswap16(val));
235 }
236
237 static void pci_apb_iowritel (void *opaque, target_phys_addr_t addr,
238                                 uint32_t val)
239 {
240     cpu_outl(addr & IOPORTS_MASK, bswap32(val));
241 }
242
243 static uint32_t pci_apb_ioreadb (void *opaque, target_phys_addr_t addr)
244 {
245     uint32_t val;
246
247     val = cpu_inb(addr & IOPORTS_MASK);
248     return val;
249 }
250
251 static uint32_t pci_apb_ioreadw (void *opaque, target_phys_addr_t addr)
252 {
253     uint32_t val;
254
255     val = bswap16(cpu_inw(addr & IOPORTS_MASK));
256     return val;
257 }
258
259 static uint32_t pci_apb_ioreadl (void *opaque, target_phys_addr_t addr)
260 {
261     uint32_t val;
262
263     val = bswap32(cpu_inl(addr & IOPORTS_MASK));
264     return val;
265 }
266
267 static const MemoryRegionOps pci_ioport_ops = {
268     .old_mmio = {
269         .read = { pci_apb_ioreadb, pci_apb_ioreadw, pci_apb_ioreadl },
270         .write = { pci_apb_iowriteb, pci_apb_iowritew, pci_apb_iowritel, },
271     },
272     .endianness = DEVICE_NATIVE_ENDIAN,
273 };
274
275 /* The APB host has an IRQ line for each IRQ line of each slot.  */
276 static int pci_apb_map_irq(PCIDevice *pci_dev, int irq_num)
277 {
278     return ((pci_dev->devfn & 0x18) >> 1) + irq_num;
279 }
280
281 static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)
282 {
283     int bus_offset;
284     if (pci_dev->devfn & 1)
285         bus_offset = 16;
286     else
287         bus_offset = 0;
288     return bus_offset + irq_num;
289 }
290
291 static void pci_apb_set_irq(void *opaque, int irq_num, int level)
292 {
293     APBState *s = opaque;
294
295     /* PCI IRQ map onto the first 32 INO.  */
296     if (irq_num < 32) {
297         if (s->pci_irq_map[irq_num >> 2] & PBM_PCI_IMR_ENABLED) {
298             APB_DPRINTF("%s: set irq %d level %d\n", __func__, irq_num, level);
299             qemu_set_irq(s->ivec_irqs[irq_num], level);
300         } else {
301             APB_DPRINTF("%s: not enabled: lower irq %d\n", __func__, irq_num);
302             qemu_irq_lower(s->ivec_irqs[irq_num]);
303         }
304     } else {
305         /* OBIO IRQ map onto the next 16 INO.  */
306         if (s->obio_irq_map[irq_num - 32] & PBM_PCI_IMR_ENABLED) {
307             APB_DPRINTF("%s: set irq %d level %d\n", __func__, irq_num, level);
308             qemu_set_irq(s->ivec_irqs[irq_num], level);
309         } else {
310             APB_DPRINTF("%s: not enabled: lower irq %d\n", __func__, irq_num);
311             qemu_irq_lower(s->ivec_irqs[irq_num]);
312         }
313     }
314 }
315
316 static int apb_pci_bridge_initfn(PCIDevice *dev)
317 {
318     int rc;
319
320     rc = pci_bridge_initfn(dev);
321     if (rc < 0) {
322         return rc;
323     }
324
325     /*
326      * command register:
327      * According to PCI bridge spec, after reset
328      *   bus master bit is off
329      *   memory space enable bit is off
330      * According to manual (805-1251.pdf).
331      *   the reset value should be zero unless the boot pin is tied high
332      *   (which is true) and thus it should be PCI_COMMAND_MEMORY.
333      */
334     pci_set_word(dev->config + PCI_COMMAND,
335                  PCI_COMMAND_MEMORY);
336     pci_set_word(dev->config + PCI_STATUS,
337                  PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
338                  PCI_STATUS_DEVSEL_MEDIUM);
339     return 0;
340 }
341
342 PCIBus *pci_apb_init(target_phys_addr_t special_base,
343                      target_phys_addr_t mem_base,
344                      qemu_irq *ivec_irqs, PCIBus **bus2, PCIBus **bus3,
345                      qemu_irq **pbm_irqs)
346 {
347     DeviceState *dev;
348     SysBusDevice *s;
349     APBState *d;
350     PCIDevice *pci_dev;
351     PCIBridge *br;
352
353     /* Ultrasparc PBM main bus */
354     dev = qdev_create(NULL, "pbm");
355     qdev_init_nofail(dev);
356     s = sysbus_from_qdev(dev);
357     /* apb_config */
358     sysbus_mmio_map(s, 0, special_base);
359     /* PCI configuration space */
360     sysbus_mmio_map(s, 1, special_base + 0x1000000ULL);
361     /* pci_ioport */
362     sysbus_mmio_map(s, 2, special_base + 0x2000000ULL);
363     d = FROM_SYSBUS(APBState, s);
364
365     memory_region_init(&d->pci_mmio, "pci-mmio", 0x100000000ULL);
366     memory_region_add_subregion(get_system_memory(), mem_base, &d->pci_mmio);
367
368     d->bus = pci_register_bus(&d->busdev.qdev, "pci",
369                               pci_apb_set_irq, pci_pbm_map_irq, d,
370                               &d->pci_mmio,
371                               get_system_io(),
372                               0, 32);
373
374     *pbm_irqs = d->pbm_irqs;
375     d->ivec_irqs = ivec_irqs;
376
377     pci_create_simple(d->bus, 0, "pbm-pci");
378
379     /* APB secondary busses */
380     pci_dev = pci_create_multifunction(d->bus, PCI_DEVFN(1, 0), true,
381                                    "pbm-bridge");
382     br = DO_UPCAST(PCIBridge, dev, pci_dev);
383     pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 1",
384                        pci_apb_map_irq);
385     qdev_init_nofail(&pci_dev->qdev);
386     *bus2 = pci_bridge_get_sec_bus(br);
387
388     pci_dev = pci_create_multifunction(d->bus, PCI_DEVFN(1, 1), true,
389                                    "pbm-bridge");
390     br = DO_UPCAST(PCIBridge, dev, pci_dev);
391     pci_bridge_map_irq(br, "Advanced PCI Bus secondary bridge 2",
392                        pci_apb_map_irq);
393     qdev_init_nofail(&pci_dev->qdev);
394     *bus3 = pci_bridge_get_sec_bus(br);
395
396     return d->bus;
397 }
398
399 static void pci_pbm_reset(DeviceState *d)
400 {
401     unsigned int i;
402     APBState *s = container_of(d, APBState, busdev.qdev);
403
404     for (i = 0; i < 8; i++) {
405         s->pci_irq_map[i] &= PBM_PCI_IMR_MASK;
406     }
407
408     if (s->nr_resets++ == 0) {
409         /* Power on reset */
410         s->reset_control = POR;
411     }
412 }
413
414 static const MemoryRegionOps pci_config_ops = {
415     .read = apb_pci_config_read,
416     .write = apb_pci_config_write,
417     .endianness = DEVICE_NATIVE_ENDIAN,
418 };
419
420 static int pci_pbm_init_device(SysBusDevice *dev)
421 {
422     APBState *s;
423     unsigned int i;
424
425     s = FROM_SYSBUS(APBState, dev);
426     for (i = 0; i < 8; i++) {
427         s->pci_irq_map[i] = (0x1f << 6) | (i << 2);
428     }
429     s->pbm_irqs = qemu_allocate_irqs(pci_apb_set_irq, s, MAX_IVEC);
430
431     /* apb_config */
432     memory_region_init_io(&s->apb_config, &apb_config_ops, s, "apb-config",
433                           0x10000);
434     /* at region 0 */
435     sysbus_init_mmio(dev, &s->apb_config);
436
437     memory_region_init_io(&s->pci_config, &pci_config_ops, s, "apb-pci-config",
438                           0x1000000);
439     /* at region 1 */
440     sysbus_init_mmio(dev, &s->pci_config);
441
442     /* pci_ioport */
443     memory_region_init_io(&s->pci_ioport, &pci_ioport_ops, s,
444                           "apb-pci-ioport", 0x10000);
445     /* at region 2 */
446     sysbus_init_mmio(dev, &s->pci_ioport);
447
448     return 0;
449 }
450
451 static int pbm_pci_host_init(PCIDevice *d)
452 {
453     pci_set_word(d->config + PCI_COMMAND,
454                  PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
455     pci_set_word(d->config + PCI_STATUS,
456                  PCI_STATUS_FAST_BACK | PCI_STATUS_66MHZ |
457                  PCI_STATUS_DEVSEL_MEDIUM);
458     return 0;
459 }
460
461 static void pbm_pci_host_class_init(ObjectClass *klass, void *data)
462 {
463     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
464
465     k->init = pbm_pci_host_init;
466     k->vendor_id = PCI_VENDOR_ID_SUN;
467     k->device_id = PCI_DEVICE_ID_SUN_SABRE;
468     k->class_id = PCI_CLASS_BRIDGE_HOST;
469 }
470
471 static TypeInfo pbm_pci_host_info = {
472     .name          = "pbm-pci",
473     .parent        = TYPE_PCI_DEVICE,
474     .instance_size = sizeof(PCIDevice),
475     .class_init    = pbm_pci_host_class_init,
476 };
477
478 static void pbm_host_class_init(ObjectClass *klass, void *data)
479 {
480     DeviceClass *dc = DEVICE_CLASS(klass);
481     SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
482
483     k->init = pci_pbm_init_device;
484     dc->reset = pci_pbm_reset;
485 }
486
487 static TypeInfo pbm_host_info = {
488     .name          = "pbm",
489     .parent        = TYPE_SYS_BUS_DEVICE,
490     .instance_size = sizeof(APBState),
491     .class_init    = pbm_host_class_init,
492 };
493
494 static void pbm_pci_bridge_class_init(ObjectClass *klass, void *data)
495 {
496     DeviceClass *dc = DEVICE_CLASS(klass);
497     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
498
499     k->init = apb_pci_bridge_initfn;
500     k->exit = pci_bridge_exitfn;
501     k->vendor_id = PCI_VENDOR_ID_SUN;
502     k->device_id = PCI_DEVICE_ID_SUN_SIMBA;
503     k->revision = 0x11;
504     k->config_write = pci_bridge_write_config;
505     k->is_bridge = 1;
506     dc->reset = pci_bridge_reset;
507     dc->vmsd = &vmstate_pci_device;
508 }
509
510 static TypeInfo pbm_pci_bridge_info = {
511     .name          = "pbm-bridge",
512     .parent        = TYPE_PCI_DEVICE,
513     .instance_size = sizeof(PCIBridge),
514     .class_init    = pbm_pci_bridge_class_init,
515 };
516
517 static void pbm_register_types(void)
518 {
519     type_register_static(&pbm_host_info);
520     type_register_static(&pbm_pci_host_info);
521     type_register_static(&pbm_pci_bridge_info);
522 }
523
524 type_init(pbm_register_types)
This page took 0.053845 seconds and 4 git commands to generate.