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