pbrook | 502a539 | 2006-05-13 16:11:23 +0000 | [diff] [blame] | 1 | /* |
| 2 | * QEMU Uninorth PCI host (for all Mac99 and newer machines) |
| 3 | * |
| 4 | * Copyright (c) 2006 Fabrice Bellard |
ths | 5fafdf2 | 2007-09-16 21:08:06 +0000 | [diff] [blame] | 5 | * |
pbrook | 502a539 | 2006-05-13 16:11:23 +0000 | [diff] [blame] | 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 | */ |
Markus Armbruster | 0b8fa32 | 2019-05-23 16:35:07 +0200 | [diff] [blame] | 24 | |
Peter Maydell | 0d75590 | 2016-01-26 18:16:58 +0000 | [diff] [blame] | 25 | #include "qemu/osdep.h" |
Markus Armbruster | 64552b6 | 2019-08-12 07:23:42 +0200 | [diff] [blame] | 26 | #include "hw/irq.h" |
Paolo Bonzini | 83c9f4c | 2013-02-04 15:40:22 +0100 | [diff] [blame] | 27 | #include "hw/ppc/mac.h" |
Markus Armbruster | a27bd6c | 2019-08-12 07:23:51 +0200 | [diff] [blame] | 28 | #include "hw/qdev-properties.h" |
Markus Armbruster | 0b8fa32 | 2019-05-23 16:35:07 +0200 | [diff] [blame] | 29 | #include "qemu/module.h" |
Paolo Bonzini | 83c9f4c | 2013-02-04 15:40:22 +0100 | [diff] [blame] | 30 | #include "hw/pci/pci.h" |
| 31 | #include "hw/pci/pci_host.h" |
Mark Cave-Ayland | 5d2eaa0 | 2018-03-06 20:30:49 +0000 | [diff] [blame] | 32 | #include "hw/pci-host/uninorth.h" |
Mark Cave-Ayland | 0b0c5e9 | 2018-01-26 09:20:28 +0000 | [diff] [blame] | 33 | #include "trace.h" |
blueswir1 | f390238 | 2009-02-05 20:22:07 +0000 | [diff] [blame] | 34 | |
Alexander Graf | fa0be69 | 2010-02-09 17:37:04 +0100 | [diff] [blame] | 35 | static const int unin_irq_line[] = { 0x1b, 0x1c, 0x1d, 0x1e }; |
| 36 | |
pbrook | d2b5931 | 2006-09-24 00:16:34 +0000 | [diff] [blame] | 37 | static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num) |
pbrook | 502a539 | 2006-05-13 16:11:23 +0000 | [diff] [blame] | 38 | { |
Benjamin Herrenschmidt | 39d97e1 | 2016-11-21 00:12:31 +1000 | [diff] [blame] | 39 | return (irq_num + (pci_dev->devfn >> 3)) & 3; |
pbrook | d2b5931 | 2006-09-24 00:16:34 +0000 | [diff] [blame] | 40 | } |
| 41 | |
Juan Quintela | 5d4e84c | 2009-08-28 15:28:17 +0200 | [diff] [blame] | 42 | static void pci_unin_set_irq(void *opaque, int irq_num, int level) |
pbrook | d2b5931 | 2006-09-24 00:16:34 +0000 | [diff] [blame] | 43 | { |
Mark Cave-Ayland | c90c393 | 2018-03-06 20:31:00 +0000 | [diff] [blame] | 44 | UNINHostState *s = opaque; |
Juan Quintela | 5d4e84c | 2009-08-28 15:28:17 +0200 | [diff] [blame] | 45 | |
Mark Cave-Ayland | 0b0c5e9 | 2018-01-26 09:20:28 +0000 | [diff] [blame] | 46 | trace_unin_set_irq(unin_irq_line[irq_num], level); |
Mark Cave-Ayland | e7755cc | 2018-03-06 20:30:58 +0000 | [diff] [blame] | 47 | qemu_set_irq(s->irqs[irq_num], level); |
pbrook | 502a539 | 2006-05-13 16:11:23 +0000 | [diff] [blame] | 48 | } |
| 49 | |
Alexander Graf | d86f0e3 | 2010-02-09 17:37:01 +0100 | [diff] [blame] | 50 | static uint32_t unin_get_config_reg(uint32_t reg, uint32_t addr) |
| 51 | { |
| 52 | uint32_t retval; |
| 53 | |
| 54 | if (reg & (1u << 31)) { |
| 55 | /* XXX OpenBIOS compatibility hack */ |
| 56 | retval = reg | (addr & 3); |
| 57 | } else if (reg & 1) { |
| 58 | /* CFA1 style */ |
| 59 | retval = (reg & ~7u) | (addr & 7); |
| 60 | } else { |
| 61 | uint32_t slot, func; |
| 62 | |
| 63 | /* Grab CFA0 style values */ |
Stefan Hajnoczi | 5863d37 | 2015-03-23 15:29:25 +0000 | [diff] [blame] | 64 | slot = ctz32(reg & 0xfffff800); |
| 65 | if (slot == 32) { |
| 66 | slot = -1; /* XXX: should this be 0? */ |
| 67 | } |
Alexander Graf | d86f0e3 | 2010-02-09 17:37:01 +0100 | [diff] [blame] | 68 | func = (reg >> 8) & 7; |
| 69 | |
| 70 | /* ... and then convert them to x86 format */ |
| 71 | /* config pointer */ |
| 72 | retval = (reg & (0xff - 7)) | (addr & 7); |
| 73 | /* slot */ |
| 74 | retval |= slot << 11; |
| 75 | /* fn */ |
| 76 | retval |= func << 8; |
| 77 | } |
| 78 | |
Mark Cave-Ayland | 0b0c5e9 | 2018-01-26 09:20:28 +0000 | [diff] [blame] | 79 | trace_unin_get_config_reg(reg, addr, retval); |
Alexander Graf | d86f0e3 | 2010-02-09 17:37:01 +0100 | [diff] [blame] | 80 | |
| 81 | return retval; |
| 82 | } |
| 83 | |
Avi Kivity | a8170e5 | 2012-10-23 12:30:10 +0200 | [diff] [blame] | 84 | static void unin_data_write(void *opaque, hwaddr addr, |
Avi Kivity | d0ed807 | 2011-07-24 17:47:18 +0300 | [diff] [blame] | 85 | uint64_t val, unsigned len) |
Alexander Graf | d86f0e3 | 2010-02-09 17:37:01 +0100 | [diff] [blame] | 86 | { |
Mark Cave-Ayland | c90c393 | 2018-03-06 20:31:00 +0000 | [diff] [blame] | 87 | UNINHostState *s = opaque; |
Andreas Färber | 67c332f | 2012-08-20 19:08:09 +0200 | [diff] [blame] | 88 | PCIHostState *phb = PCI_HOST_BRIDGE(s); |
Mark Cave-Ayland | 0b0c5e9 | 2018-01-26 09:20:28 +0000 | [diff] [blame] | 89 | trace_unin_data_write(addr, len, val); |
Andreas Färber | 67c332f | 2012-08-20 19:08:09 +0200 | [diff] [blame] | 90 | pci_data_write(phb->bus, |
| 91 | unin_get_config_reg(phb->config_reg, addr), |
Alexander Graf | d86f0e3 | 2010-02-09 17:37:01 +0100 | [diff] [blame] | 92 | val, len); |
| 93 | } |
| 94 | |
Avi Kivity | a8170e5 | 2012-10-23 12:30:10 +0200 | [diff] [blame] | 95 | static uint64_t unin_data_read(void *opaque, hwaddr addr, |
Avi Kivity | d0ed807 | 2011-07-24 17:47:18 +0300 | [diff] [blame] | 96 | unsigned len) |
Alexander Graf | d86f0e3 | 2010-02-09 17:37:01 +0100 | [diff] [blame] | 97 | { |
Mark Cave-Ayland | c90c393 | 2018-03-06 20:31:00 +0000 | [diff] [blame] | 98 | UNINHostState *s = opaque; |
Andreas Färber | 67c332f | 2012-08-20 19:08:09 +0200 | [diff] [blame] | 99 | PCIHostState *phb = PCI_HOST_BRIDGE(s); |
Alexander Graf | d86f0e3 | 2010-02-09 17:37:01 +0100 | [diff] [blame] | 100 | uint32_t val; |
| 101 | |
Andreas Färber | 67c332f | 2012-08-20 19:08:09 +0200 | [diff] [blame] | 102 | val = pci_data_read(phb->bus, |
| 103 | unin_get_config_reg(phb->config_reg, addr), |
Alexander Graf | d86f0e3 | 2010-02-09 17:37:01 +0100 | [diff] [blame] | 104 | len); |
Mark Cave-Ayland | 0b0c5e9 | 2018-01-26 09:20:28 +0000 | [diff] [blame] | 105 | trace_unin_data_read(addr, len, val); |
Alexander Graf | d86f0e3 | 2010-02-09 17:37:01 +0100 | [diff] [blame] | 106 | return val; |
| 107 | } |
| 108 | |
Avi Kivity | d0ed807 | 2011-07-24 17:47:18 +0300 | [diff] [blame] | 109 | static const MemoryRegionOps unin_data_ops = { |
| 110 | .read = unin_data_read, |
| 111 | .write = unin_data_write, |
| 112 | .endianness = DEVICE_LITTLE_ENDIAN, |
| 113 | }; |
| 114 | |
Mark Cave-Ayland | c90c393 | 2018-03-06 20:31:00 +0000 | [diff] [blame] | 115 | static void pci_unin_init_irqs(UNINHostState *s) |
Mark Cave-Ayland | e7755cc | 2018-03-06 20:30:58 +0000 | [diff] [blame] | 116 | { |
| 117 | int i; |
| 118 | |
| 119 | for (i = 0; i < ARRAY_SIZE(s->irqs); i++) { |
| 120 | s->irqs[i] = qdev_get_gpio_in(DEVICE(s->pic), unin_irq_line[i]); |
| 121 | } |
| 122 | } |
| 123 | |
Mark Cave-Ayland | 03756c8 | 2018-08-29 17:59:10 +0100 | [diff] [blame] | 124 | static char *pci_unin_main_ofw_unit_address(const SysBusDevice *dev) |
| 125 | { |
| 126 | UNINHostState *s = UNI_NORTH_PCI_HOST_BRIDGE(dev); |
| 127 | |
| 128 | return g_strdup_printf("%x", s->ofw_addr); |
| 129 | } |
| 130 | |
Mark Cave-Ayland | 32cde61 | 2018-03-06 20:30:53 +0000 | [diff] [blame] | 131 | static void pci_unin_main_realize(DeviceState *dev, Error **errp) |
| 132 | { |
Mark Cave-Ayland | c90c393 | 2018-03-06 20:31:00 +0000 | [diff] [blame] | 133 | UNINHostState *s = UNI_NORTH_PCI_HOST_BRIDGE(dev); |
Mark Cave-Ayland | 32cde61 | 2018-03-06 20:30:53 +0000 | [diff] [blame] | 134 | PCIHostState *h = PCI_HOST_BRIDGE(dev); |
| 135 | |
| 136 | h->bus = pci_register_root_bus(dev, NULL, |
| 137 | pci_unin_set_irq, pci_unin_map_irq, |
Mark Cave-Ayland | e7755cc | 2018-03-06 20:30:58 +0000 | [diff] [blame] | 138 | s, |
Mark Cave-Ayland | 32cde61 | 2018-03-06 20:30:53 +0000 | [diff] [blame] | 139 | &s->pci_mmio, |
Mark Cave-Ayland | e226efb | 2018-03-06 20:30:59 +0000 | [diff] [blame] | 140 | &s->pci_io, |
Mark Cave-Ayland | 32cde61 | 2018-03-06 20:30:53 +0000 | [diff] [blame] | 141 | PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); |
| 142 | |
Mark Cave-Ayland | c1d66d3 | 2018-03-06 20:30:54 +0000 | [diff] [blame] | 143 | pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-pci"); |
Mark Cave-Ayland | e7755cc | 2018-03-06 20:30:58 +0000 | [diff] [blame] | 144 | pci_unin_init_irqs(s); |
Mark Cave-Ayland | 32cde61 | 2018-03-06 20:30:53 +0000 | [diff] [blame] | 145 | |
| 146 | /* DEC 21154 bridge */ |
| 147 | #if 0 |
| 148 | /* XXX: not activated as PPC BIOS doesn't handle multiple buses properly */ |
| 149 | pci_create_simple(h->bus, PCI_DEVFN(12, 0), "dec-21154"); |
| 150 | #endif |
| 151 | } |
| 152 | |
Mark Cave-Ayland | 0203459 | 2018-03-06 20:30:47 +0000 | [diff] [blame] | 153 | static void pci_unin_main_init(Object *obj) |
pbrook | 502a539 | 2006-05-13 16:11:23 +0000 | [diff] [blame] | 154 | { |
Mark Cave-Ayland | c90c393 | 2018-03-06 20:31:00 +0000 | [diff] [blame] | 155 | UNINHostState *s = UNI_NORTH_PCI_HOST_BRIDGE(obj); |
Mark Cave-Ayland | 0203459 | 2018-03-06 20:30:47 +0000 | [diff] [blame] | 156 | SysBusDevice *sbd = SYS_BUS_DEVICE(obj); |
| 157 | PCIHostState *h = PCI_HOST_BRIDGE(obj); |
pbrook | 502a539 | 2006-05-13 16:11:23 +0000 | [diff] [blame] | 158 | |
| 159 | /* Use values found on a real PowerMac */ |
| 160 | /* Uninorth main bus */ |
Paolo Bonzini | 40c5dce | 2013-06-06 21:25:08 -0400 | [diff] [blame] | 161 | memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, |
Mark Cave-Ayland | 132e990 | 2018-03-06 20:30:51 +0000 | [diff] [blame] | 162 | obj, "unin-pci-conf-idx", 0x1000); |
Mark Cave-Ayland | 0203459 | 2018-03-06 20:30:47 +0000 | [diff] [blame] | 163 | memory_region_init_io(&h->data_mem, OBJECT(h), &unin_data_ops, obj, |
Mark Cave-Ayland | 132e990 | 2018-03-06 20:30:51 +0000 | [diff] [blame] | 164 | "unin-pci-conf-data", 0x1000); |
| 165 | |
| 166 | memory_region_init(&s->pci_mmio, OBJECT(s), "unin-pci-mmio", |
| 167 | 0x100000000ULL); |
Mark Cave-Ayland | e226efb | 2018-03-06 20:30:59 +0000 | [diff] [blame] | 168 | memory_region_init_io(&s->pci_io, OBJECT(s), &unassigned_io_ops, obj, |
| 169 | "unin-pci-isa-mmio", 0x00800000); |
Mark Cave-Ayland | 132e990 | 2018-03-06 20:30:51 +0000 | [diff] [blame] | 170 | |
Mark Cave-Ayland | 7b19318 | 2018-03-06 20:30:56 +0000 | [diff] [blame] | 171 | memory_region_init_alias(&s->pci_hole, OBJECT(s), |
| 172 | "unin-pci-hole", &s->pci_mmio, |
| 173 | 0x80000000ULL, 0x10000000ULL); |
| 174 | |
Mark Cave-Ayland | e7755cc | 2018-03-06 20:30:58 +0000 | [diff] [blame] | 175 | object_property_add_link(obj, "pic", TYPE_OPENPIC, |
| 176 | (Object **) &s->pic, |
| 177 | qdev_prop_allow_set_link_before_realize, |
| 178 | 0, NULL); |
| 179 | |
Mark Cave-Ayland | 0203459 | 2018-03-06 20:30:47 +0000 | [diff] [blame] | 180 | sysbus_init_mmio(sbd, &h->conf_mem); |
| 181 | sysbus_init_mmio(sbd, &h->data_mem); |
Mark Cave-Ayland | 7b19318 | 2018-03-06 20:30:56 +0000 | [diff] [blame] | 182 | sysbus_init_mmio(sbd, &s->pci_hole); |
Mark Cave-Ayland | e226efb | 2018-03-06 20:30:59 +0000 | [diff] [blame] | 183 | sysbus_init_mmio(sbd, &s->pci_io); |
Blue Swirl | 2e29bd0 | 2009-07-31 20:23:28 +0000 | [diff] [blame] | 184 | } |
| 185 | |
Mark Cave-Ayland | 32cde61 | 2018-03-06 20:30:53 +0000 | [diff] [blame] | 186 | static void pci_u3_agp_realize(DeviceState *dev, Error **errp) |
| 187 | { |
Mark Cave-Ayland | c90c393 | 2018-03-06 20:31:00 +0000 | [diff] [blame] | 188 | UNINHostState *s = U3_AGP_HOST_BRIDGE(dev); |
Mark Cave-Ayland | 32cde61 | 2018-03-06 20:30:53 +0000 | [diff] [blame] | 189 | PCIHostState *h = PCI_HOST_BRIDGE(dev); |
| 190 | |
| 191 | h->bus = pci_register_root_bus(dev, NULL, |
| 192 | pci_unin_set_irq, pci_unin_map_irq, |
Mark Cave-Ayland | e7755cc | 2018-03-06 20:30:58 +0000 | [diff] [blame] | 193 | s, |
Mark Cave-Ayland | 32cde61 | 2018-03-06 20:30:53 +0000 | [diff] [blame] | 194 | &s->pci_mmio, |
Mark Cave-Ayland | e226efb | 2018-03-06 20:30:59 +0000 | [diff] [blame] | 195 | &s->pci_io, |
Mark Cave-Ayland | 32cde61 | 2018-03-06 20:30:53 +0000 | [diff] [blame] | 196 | PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); |
| 197 | |
| 198 | pci_create_simple(h->bus, PCI_DEVFN(11, 0), "u3-agp"); |
Mark Cave-Ayland | e7755cc | 2018-03-06 20:30:58 +0000 | [diff] [blame] | 199 | pci_unin_init_irqs(s); |
Mark Cave-Ayland | 32cde61 | 2018-03-06 20:30:53 +0000 | [diff] [blame] | 200 | } |
| 201 | |
Mark Cave-Ayland | 0203459 | 2018-03-06 20:30:47 +0000 | [diff] [blame] | 202 | static void pci_u3_agp_init(Object *obj) |
Alexander Graf | 0f92119 | 2010-02-09 17:37:02 +0100 | [diff] [blame] | 203 | { |
Mark Cave-Ayland | c90c393 | 2018-03-06 20:31:00 +0000 | [diff] [blame] | 204 | UNINHostState *s = U3_AGP_HOST_BRIDGE(obj); |
Mark Cave-Ayland | 0203459 | 2018-03-06 20:30:47 +0000 | [diff] [blame] | 205 | SysBusDevice *sbd = SYS_BUS_DEVICE(obj); |
| 206 | PCIHostState *h = PCI_HOST_BRIDGE(obj); |
Alexander Graf | 0f92119 | 2010-02-09 17:37:02 +0100 | [diff] [blame] | 207 | |
| 208 | /* Uninorth U3 AGP bus */ |
Paolo Bonzini | 40c5dce | 2013-06-06 21:25:08 -0400 | [diff] [blame] | 209 | memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, |
Mark Cave-Ayland | 132e990 | 2018-03-06 20:30:51 +0000 | [diff] [blame] | 210 | obj, "unin-pci-conf-idx", 0x1000); |
Mark Cave-Ayland | 0203459 | 2018-03-06 20:30:47 +0000 | [diff] [blame] | 211 | memory_region_init_io(&h->data_mem, OBJECT(h), &unin_data_ops, obj, |
Mark Cave-Ayland | 132e990 | 2018-03-06 20:30:51 +0000 | [diff] [blame] | 212 | "unin-pci-conf-data", 0x1000); |
| 213 | |
| 214 | memory_region_init(&s->pci_mmio, OBJECT(s), "unin-pci-mmio", |
| 215 | 0x100000000ULL); |
Mark Cave-Ayland | e226efb | 2018-03-06 20:30:59 +0000 | [diff] [blame] | 216 | memory_region_init_io(&s->pci_io, OBJECT(s), &unassigned_io_ops, obj, |
| 217 | "unin-pci-isa-mmio", 0x00800000); |
Mark Cave-Ayland | 132e990 | 2018-03-06 20:30:51 +0000 | [diff] [blame] | 218 | |
Mark Cave-Ayland | 8ce3f74 | 2018-03-06 20:30:57 +0000 | [diff] [blame] | 219 | memory_region_init_alias(&s->pci_hole, OBJECT(s), |
| 220 | "unin-pci-hole", &s->pci_mmio, |
| 221 | 0x80000000ULL, 0x70000000ULL); |
| 222 | |
Mark Cave-Ayland | e7755cc | 2018-03-06 20:30:58 +0000 | [diff] [blame] | 223 | object_property_add_link(obj, "pic", TYPE_OPENPIC, |
| 224 | (Object **) &s->pic, |
| 225 | qdev_prop_allow_set_link_before_realize, |
| 226 | 0, NULL); |
| 227 | |
Mark Cave-Ayland | 0203459 | 2018-03-06 20:30:47 +0000 | [diff] [blame] | 228 | sysbus_init_mmio(sbd, &h->conf_mem); |
| 229 | sysbus_init_mmio(sbd, &h->data_mem); |
Mark Cave-Ayland | 8ce3f74 | 2018-03-06 20:30:57 +0000 | [diff] [blame] | 230 | sysbus_init_mmio(sbd, &s->pci_hole); |
Mark Cave-Ayland | e226efb | 2018-03-06 20:30:59 +0000 | [diff] [blame] | 231 | sysbus_init_mmio(sbd, &s->pci_io); |
Alexander Graf | 0f92119 | 2010-02-09 17:37:02 +0100 | [diff] [blame] | 232 | } |
| 233 | |
Mark Cave-Ayland | 32cde61 | 2018-03-06 20:30:53 +0000 | [diff] [blame] | 234 | static void pci_unin_agp_realize(DeviceState *dev, Error **errp) |
| 235 | { |
Mark Cave-Ayland | c90c393 | 2018-03-06 20:31:00 +0000 | [diff] [blame] | 236 | UNINHostState *s = UNI_NORTH_AGP_HOST_BRIDGE(dev); |
Mark Cave-Ayland | 32cde61 | 2018-03-06 20:30:53 +0000 | [diff] [blame] | 237 | PCIHostState *h = PCI_HOST_BRIDGE(dev); |
| 238 | |
| 239 | h->bus = pci_register_root_bus(dev, NULL, |
| 240 | pci_unin_set_irq, pci_unin_map_irq, |
Mark Cave-Ayland | e7755cc | 2018-03-06 20:30:58 +0000 | [diff] [blame] | 241 | s, |
Mark Cave-Ayland | 32cde61 | 2018-03-06 20:30:53 +0000 | [diff] [blame] | 242 | &s->pci_mmio, |
Mark Cave-Ayland | e226efb | 2018-03-06 20:30:59 +0000 | [diff] [blame] | 243 | &s->pci_io, |
Mark Cave-Ayland | 32cde61 | 2018-03-06 20:30:53 +0000 | [diff] [blame] | 244 | PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS); |
Mark Cave-Ayland | c1d66d3 | 2018-03-06 20:30:54 +0000 | [diff] [blame] | 245 | |
| 246 | pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-agp"); |
Mark Cave-Ayland | e7755cc | 2018-03-06 20:30:58 +0000 | [diff] [blame] | 247 | pci_unin_init_irqs(s); |
Mark Cave-Ayland | 32cde61 | 2018-03-06 20:30:53 +0000 | [diff] [blame] | 248 | } |
| 249 | |
Mark Cave-Ayland | 0203459 | 2018-03-06 20:30:47 +0000 | [diff] [blame] | 250 | static void pci_unin_agp_init(Object *obj) |
Blue Swirl | 2e29bd0 | 2009-07-31 20:23:28 +0000 | [diff] [blame] | 251 | { |
Mark Cave-Ayland | c90c393 | 2018-03-06 20:31:00 +0000 | [diff] [blame] | 252 | UNINHostState *s = UNI_NORTH_AGP_HOST_BRIDGE(obj); |
Mark Cave-Ayland | 0203459 | 2018-03-06 20:30:47 +0000 | [diff] [blame] | 253 | SysBusDevice *sbd = SYS_BUS_DEVICE(obj); |
| 254 | PCIHostState *h = PCI_HOST_BRIDGE(obj); |
Blue Swirl | 2e29bd0 | 2009-07-31 20:23:28 +0000 | [diff] [blame] | 255 | |
| 256 | /* Uninorth AGP bus */ |
Paolo Bonzini | 40c5dce | 2013-06-06 21:25:08 -0400 | [diff] [blame] | 257 | memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, |
Mark Cave-Ayland | 132e990 | 2018-03-06 20:30:51 +0000 | [diff] [blame] | 258 | obj, "unin-agp-conf-idx", 0x1000); |
Paolo Bonzini | 40c5dce | 2013-06-06 21:25:08 -0400 | [diff] [blame] | 259 | memory_region_init_io(&h->data_mem, OBJECT(h), &pci_host_data_le_ops, |
Mark Cave-Ayland | 132e990 | 2018-03-06 20:30:51 +0000 | [diff] [blame] | 260 | obj, "unin-agp-conf-data", 0x1000); |
Mark Cave-Ayland | e7755cc | 2018-03-06 20:30:58 +0000 | [diff] [blame] | 261 | |
| 262 | object_property_add_link(obj, "pic", TYPE_OPENPIC, |
| 263 | (Object **) &s->pic, |
| 264 | qdev_prop_allow_set_link_before_realize, |
| 265 | 0, NULL); |
| 266 | |
Mark Cave-Ayland | 0203459 | 2018-03-06 20:30:47 +0000 | [diff] [blame] | 267 | sysbus_init_mmio(sbd, &h->conf_mem); |
| 268 | sysbus_init_mmio(sbd, &h->data_mem); |
Blue Swirl | 2e29bd0 | 2009-07-31 20:23:28 +0000 | [diff] [blame] | 269 | } |
| 270 | |
Mark Cave-Ayland | 1ff861d | 2018-03-06 20:30:55 +0000 | [diff] [blame] | 271 | static void pci_unin_internal_realize(DeviceState *dev, Error **errp) |
| 272 | { |
Mark Cave-Ayland | c90c393 | 2018-03-06 20:31:00 +0000 | [diff] [blame] | 273 | UNINHostState *s = UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE(dev); |
Mark Cave-Ayland | 1ff861d | 2018-03-06 20:30:55 +0000 | [diff] [blame] | 274 | PCIHostState *h = PCI_HOST_BRIDGE(dev); |
| 275 | |
| 276 | h->bus = pci_register_root_bus(dev, NULL, |
| 277 | pci_unin_set_irq, pci_unin_map_irq, |
Mark Cave-Ayland | e7755cc | 2018-03-06 20:30:58 +0000 | [diff] [blame] | 278 | s, |
Mark Cave-Ayland | 1ff861d | 2018-03-06 20:30:55 +0000 | [diff] [blame] | 279 | &s->pci_mmio, |
Mark Cave-Ayland | e226efb | 2018-03-06 20:30:59 +0000 | [diff] [blame] | 280 | &s->pci_io, |
Mark Cave-Ayland | 1ff861d | 2018-03-06 20:30:55 +0000 | [diff] [blame] | 281 | PCI_DEVFN(14, 0), 4, TYPE_PCI_BUS); |
| 282 | |
| 283 | pci_create_simple(h->bus, PCI_DEVFN(14, 0), "uni-north-internal-pci"); |
Mark Cave-Ayland | e7755cc | 2018-03-06 20:30:58 +0000 | [diff] [blame] | 284 | pci_unin_init_irqs(s); |
Mark Cave-Ayland | 1ff861d | 2018-03-06 20:30:55 +0000 | [diff] [blame] | 285 | } |
| 286 | |
Mark Cave-Ayland | 0203459 | 2018-03-06 20:30:47 +0000 | [diff] [blame] | 287 | static void pci_unin_internal_init(Object *obj) |
Blue Swirl | 2e29bd0 | 2009-07-31 20:23:28 +0000 | [diff] [blame] | 288 | { |
Mark Cave-Ayland | c90c393 | 2018-03-06 20:31:00 +0000 | [diff] [blame] | 289 | UNINHostState *s = UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE(obj); |
Mark Cave-Ayland | 0203459 | 2018-03-06 20:30:47 +0000 | [diff] [blame] | 290 | SysBusDevice *sbd = SYS_BUS_DEVICE(obj); |
| 291 | PCIHostState *h = PCI_HOST_BRIDGE(obj); |
Blue Swirl | 2e29bd0 | 2009-07-31 20:23:28 +0000 | [diff] [blame] | 292 | |
| 293 | /* Uninorth internal bus */ |
Paolo Bonzini | 40c5dce | 2013-06-06 21:25:08 -0400 | [diff] [blame] | 294 | memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops, |
Mark Cave-Ayland | 132e990 | 2018-03-06 20:30:51 +0000 | [diff] [blame] | 295 | obj, "unin-pci-conf-idx", 0x1000); |
Paolo Bonzini | 40c5dce | 2013-06-06 21:25:08 -0400 | [diff] [blame] | 296 | memory_region_init_io(&h->data_mem, OBJECT(h), &pci_host_data_le_ops, |
Mark Cave-Ayland | 132e990 | 2018-03-06 20:30:51 +0000 | [diff] [blame] | 297 | obj, "unin-pci-conf-data", 0x1000); |
Mark Cave-Ayland | e7755cc | 2018-03-06 20:30:58 +0000 | [diff] [blame] | 298 | |
| 299 | object_property_add_link(obj, "pic", TYPE_OPENPIC, |
| 300 | (Object **) &s->pic, |
| 301 | qdev_prop_allow_set_link_before_realize, |
| 302 | 0, NULL); |
| 303 | |
Mark Cave-Ayland | 0203459 | 2018-03-06 20:30:47 +0000 | [diff] [blame] | 304 | sysbus_init_mmio(sbd, &h->conf_mem); |
| 305 | sysbus_init_mmio(sbd, &h->data_mem); |
Blue Swirl | 2e29bd0 | 2009-07-31 20:23:28 +0000 | [diff] [blame] | 306 | } |
| 307 | |
Markus Armbruster | 9af21db | 2015-01-19 15:52:30 +0100 | [diff] [blame] | 308 | static void unin_main_pci_host_realize(PCIDevice *d, Error **errp) |
Blue Swirl | 2e29bd0 | 2009-07-31 20:23:28 +0000 | [diff] [blame] | 309 | { |
Mark Cave-Ayland | 4d309c9 | 2018-03-06 20:30:45 +0000 | [diff] [blame] | 310 | /* cache_line_size */ |
| 311 | d->config[0x0C] = 0x08; |
| 312 | /* latency_timer */ |
| 313 | d->config[0x0D] = 0x10; |
| 314 | /* capabilities_pointer */ |
| 315 | d->config[0x34] = 0x00; |
Mark Cave-Ayland | 4d309c9 | 2018-03-06 20:30:45 +0000 | [diff] [blame] | 316 | |
Programmingkid | 98ae3b2 | 2016-01-22 11:09:23 -0500 | [diff] [blame] | 317 | /* |
| 318 | * Set kMacRISCPCIAddressSelect (0x48) register to indicate PCI |
| 319 | * memory space with base 0x80000000, size 0x10000000 for Apple's |
| 320 | * AppleMacRiscPCI driver |
| 321 | */ |
| 322 | d->config[0x48] = 0x0; |
| 323 | d->config[0x49] = 0x0; |
| 324 | d->config[0x4a] = 0x0; |
| 325 | d->config[0x4b] = 0x1; |
Blue Swirl | 2e29bd0 | 2009-07-31 20:23:28 +0000 | [diff] [blame] | 326 | } |
pbrook | 502a539 | 2006-05-13 16:11:23 +0000 | [diff] [blame] | 327 | |
Mark Cave-Ayland | c1d66d3 | 2018-03-06 20:30:54 +0000 | [diff] [blame] | 328 | static void unin_agp_pci_host_realize(PCIDevice *d, Error **errp) |
| 329 | { |
| 330 | /* cache_line_size */ |
| 331 | d->config[0x0C] = 0x08; |
| 332 | /* latency_timer */ |
| 333 | d->config[0x0D] = 0x10; |
| 334 | /* capabilities_pointer |
| 335 | d->config[0x34] = 0x80; */ |
| 336 | } |
| 337 | |
Markus Armbruster | 9af21db | 2015-01-19 15:52:30 +0100 | [diff] [blame] | 338 | static void u3_agp_pci_host_realize(PCIDevice *d, Error **errp) |
Alexander Graf | 0f92119 | 2010-02-09 17:37:02 +0100 | [diff] [blame] | 339 | { |
Alexander Graf | 0f92119 | 2010-02-09 17:37:02 +0100 | [diff] [blame] | 340 | /* cache line size */ |
| 341 | d->config[0x0C] = 0x08; |
| 342 | /* latency timer */ |
| 343 | d->config[0x0D] = 0x10; |
Alexander Graf | 0f92119 | 2010-02-09 17:37:02 +0100 | [diff] [blame] | 344 | } |
| 345 | |
Markus Armbruster | 9af21db | 2015-01-19 15:52:30 +0100 | [diff] [blame] | 346 | static void unin_internal_pci_host_realize(PCIDevice *d, Error **errp) |
Blue Swirl | 2e29bd0 | 2009-07-31 20:23:28 +0000 | [diff] [blame] | 347 | { |
Mark Cave-Ayland | 4d309c9 | 2018-03-06 20:30:45 +0000 | [diff] [blame] | 348 | /* cache_line_size */ |
| 349 | d->config[0x0C] = 0x08; |
| 350 | /* latency_timer */ |
| 351 | d->config[0x0D] = 0x10; |
| 352 | /* capabilities_pointer */ |
| 353 | d->config[0x34] = 0x00; |
pbrook | 502a539 | 2006-05-13 16:11:23 +0000 | [diff] [blame] | 354 | } |
Blue Swirl | 2e29bd0 | 2009-07-31 20:23:28 +0000 | [diff] [blame] | 355 | |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 356 | static void unin_main_pci_host_class_init(ObjectClass *klass, void *data) |
| 357 | { |
| 358 | PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); |
Markus Armbruster | 08c58f9 | 2013-11-28 17:26:58 +0100 | [diff] [blame] | 359 | DeviceClass *dc = DEVICE_CLASS(klass); |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 360 | |
Markus Armbruster | 9af21db | 2015-01-19 15:52:30 +0100 | [diff] [blame] | 361 | k->realize = unin_main_pci_host_realize; |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 362 | k->vendor_id = PCI_VENDOR_ID_APPLE; |
| 363 | k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_PCI; |
| 364 | k->revision = 0x00; |
| 365 | k->class_id = PCI_CLASS_BRIDGE_HOST; |
Markus Armbruster | 08c58f9 | 2013-11-28 17:26:58 +0100 | [diff] [blame] | 366 | /* |
| 367 | * PCI-facing part of the host bridge, not usable without the |
| 368 | * host-facing part, which can't be device_add'ed, yet. |
| 369 | */ |
Eduardo Habkost | e90f2a8 | 2017-05-03 17:35:44 -0300 | [diff] [blame] | 370 | dc->user_creatable = false; |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 371 | } |
| 372 | |
Andreas Färber | 4240abf | 2012-08-20 19:07:56 +0200 | [diff] [blame] | 373 | static const TypeInfo unin_main_pci_host_info = { |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 374 | .name = "uni-north-pci", |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 375 | .parent = TYPE_PCI_DEVICE, |
| 376 | .instance_size = sizeof(PCIDevice), |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 377 | .class_init = unin_main_pci_host_class_init, |
Eduardo Habkost | fd3b02c | 2017-09-27 16:56:34 -0300 | [diff] [blame] | 378 | .interfaces = (InterfaceInfo[]) { |
| 379 | { INTERFACE_CONVENTIONAL_PCI_DEVICE }, |
| 380 | { }, |
| 381 | }, |
Blue Swirl | 2e29bd0 | 2009-07-31 20:23:28 +0000 | [diff] [blame] | 382 | }; |
| 383 | |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 384 | static void u3_agp_pci_host_class_init(ObjectClass *klass, void *data) |
| 385 | { |
| 386 | PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); |
Markus Armbruster | 08c58f9 | 2013-11-28 17:26:58 +0100 | [diff] [blame] | 387 | DeviceClass *dc = DEVICE_CLASS(klass); |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 388 | |
Markus Armbruster | 9af21db | 2015-01-19 15:52:30 +0100 | [diff] [blame] | 389 | k->realize = u3_agp_pci_host_realize; |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 390 | k->vendor_id = PCI_VENDOR_ID_APPLE; |
| 391 | k->device_id = PCI_DEVICE_ID_APPLE_U3_AGP; |
| 392 | k->revision = 0x00; |
| 393 | k->class_id = PCI_CLASS_BRIDGE_HOST; |
Markus Armbruster | 08c58f9 | 2013-11-28 17:26:58 +0100 | [diff] [blame] | 394 | /* |
| 395 | * PCI-facing part of the host bridge, not usable without the |
| 396 | * host-facing part, which can't be device_add'ed, yet. |
| 397 | */ |
Eduardo Habkost | e90f2a8 | 2017-05-03 17:35:44 -0300 | [diff] [blame] | 398 | dc->user_creatable = false; |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 399 | } |
| 400 | |
Andreas Färber | 4240abf | 2012-08-20 19:07:56 +0200 | [diff] [blame] | 401 | static const TypeInfo u3_agp_pci_host_info = { |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 402 | .name = "u3-agp", |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 403 | .parent = TYPE_PCI_DEVICE, |
| 404 | .instance_size = sizeof(PCIDevice), |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 405 | .class_init = u3_agp_pci_host_class_init, |
Eduardo Habkost | fd3b02c | 2017-09-27 16:56:34 -0300 | [diff] [blame] | 406 | .interfaces = (InterfaceInfo[]) { |
| 407 | { INTERFACE_CONVENTIONAL_PCI_DEVICE }, |
| 408 | { }, |
| 409 | }, |
Alexander Graf | 0f92119 | 2010-02-09 17:37:02 +0100 | [diff] [blame] | 410 | }; |
| 411 | |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 412 | static void unin_agp_pci_host_class_init(ObjectClass *klass, void *data) |
| 413 | { |
| 414 | PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); |
Markus Armbruster | 08c58f9 | 2013-11-28 17:26:58 +0100 | [diff] [blame] | 415 | DeviceClass *dc = DEVICE_CLASS(klass); |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 416 | |
Markus Armbruster | 9af21db | 2015-01-19 15:52:30 +0100 | [diff] [blame] | 417 | k->realize = unin_agp_pci_host_realize; |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 418 | k->vendor_id = PCI_VENDOR_ID_APPLE; |
| 419 | k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP; |
| 420 | k->revision = 0x00; |
| 421 | k->class_id = PCI_CLASS_BRIDGE_HOST; |
Markus Armbruster | 08c58f9 | 2013-11-28 17:26:58 +0100 | [diff] [blame] | 422 | /* |
| 423 | * PCI-facing part of the host bridge, not usable without the |
| 424 | * host-facing part, which can't be device_add'ed, yet. |
| 425 | */ |
Eduardo Habkost | e90f2a8 | 2017-05-03 17:35:44 -0300 | [diff] [blame] | 426 | dc->user_creatable = false; |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 427 | } |
| 428 | |
Andreas Färber | 4240abf | 2012-08-20 19:07:56 +0200 | [diff] [blame] | 429 | static const TypeInfo unin_agp_pci_host_info = { |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 430 | .name = "uni-north-agp", |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 431 | .parent = TYPE_PCI_DEVICE, |
| 432 | .instance_size = sizeof(PCIDevice), |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 433 | .class_init = unin_agp_pci_host_class_init, |
Eduardo Habkost | fd3b02c | 2017-09-27 16:56:34 -0300 | [diff] [blame] | 434 | .interfaces = (InterfaceInfo[]) { |
| 435 | { INTERFACE_CONVENTIONAL_PCI_DEVICE }, |
| 436 | { }, |
| 437 | }, |
Blue Swirl | 2e29bd0 | 2009-07-31 20:23:28 +0000 | [diff] [blame] | 438 | }; |
| 439 | |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 440 | static void unin_internal_pci_host_class_init(ObjectClass *klass, void *data) |
| 441 | { |
| 442 | PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); |
Markus Armbruster | 08c58f9 | 2013-11-28 17:26:58 +0100 | [diff] [blame] | 443 | DeviceClass *dc = DEVICE_CLASS(klass); |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 444 | |
Markus Armbruster | 9af21db | 2015-01-19 15:52:30 +0100 | [diff] [blame] | 445 | k->realize = unin_internal_pci_host_realize; |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 446 | k->vendor_id = PCI_VENDOR_ID_APPLE; |
| 447 | k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_I_PCI; |
| 448 | k->revision = 0x00; |
| 449 | k->class_id = PCI_CLASS_BRIDGE_HOST; |
Markus Armbruster | 08c58f9 | 2013-11-28 17:26:58 +0100 | [diff] [blame] | 450 | /* |
| 451 | * PCI-facing part of the host bridge, not usable without the |
| 452 | * host-facing part, which can't be device_add'ed, yet. |
| 453 | */ |
Eduardo Habkost | e90f2a8 | 2017-05-03 17:35:44 -0300 | [diff] [blame] | 454 | dc->user_creatable = false; |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 455 | } |
| 456 | |
Andreas Färber | 4240abf | 2012-08-20 19:07:56 +0200 | [diff] [blame] | 457 | static const TypeInfo unin_internal_pci_host_info = { |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 458 | .name = "uni-north-internal-pci", |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 459 | .parent = TYPE_PCI_DEVICE, |
| 460 | .instance_size = sizeof(PCIDevice), |
Anthony Liguori | 40021f0 | 2011-12-04 12:22:06 -0600 | [diff] [blame] | 461 | .class_init = unin_internal_pci_host_class_init, |
Eduardo Habkost | fd3b02c | 2017-09-27 16:56:34 -0300 | [diff] [blame] | 462 | .interfaces = (InterfaceInfo[]) { |
| 463 | { INTERFACE_CONVENTIONAL_PCI_DEVICE }, |
| 464 | { }, |
| 465 | }, |
Blue Swirl | 2e29bd0 | 2009-07-31 20:23:28 +0000 | [diff] [blame] | 466 | }; |
| 467 | |
Mark Cave-Ayland | 03756c8 | 2018-08-29 17:59:10 +0100 | [diff] [blame] | 468 | static Property pci_unin_main_pci_host_props[] = { |
| 469 | DEFINE_PROP_UINT32("ofw-addr", UNINHostState, ofw_addr, -1), |
| 470 | DEFINE_PROP_END_OF_LIST() |
| 471 | }; |
| 472 | |
Anthony Liguori | 999e12b | 2012-01-24 13:12:29 -0600 | [diff] [blame] | 473 | static void pci_unin_main_class_init(ObjectClass *klass, void *data) |
| 474 | { |
Laurent Vivier | 1d16f86 | 2015-09-26 18:22:09 +0200 | [diff] [blame] | 475 | DeviceClass *dc = DEVICE_CLASS(klass); |
Mark Cave-Ayland | 03756c8 | 2018-08-29 17:59:10 +0100 | [diff] [blame] | 476 | SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); |
Anthony Liguori | 999e12b | 2012-01-24 13:12:29 -0600 | [diff] [blame] | 477 | |
Mark Cave-Ayland | 32cde61 | 2018-03-06 20:30:53 +0000 | [diff] [blame] | 478 | dc->realize = pci_unin_main_realize; |
Mark Cave-Ayland | 03756c8 | 2018-08-29 17:59:10 +0100 | [diff] [blame] | 479 | dc->props = pci_unin_main_pci_host_props; |
Laurent Vivier | 1d16f86 | 2015-09-26 18:22:09 +0200 | [diff] [blame] | 480 | set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); |
Mark Cave-Ayland | 03756c8 | 2018-08-29 17:59:10 +0100 | [diff] [blame] | 481 | dc->fw_name = "pci"; |
| 482 | sbc->explicit_ofw_unit_address = pci_unin_main_ofw_unit_address; |
Anthony Liguori | 999e12b | 2012-01-24 13:12:29 -0600 | [diff] [blame] | 483 | } |
| 484 | |
Andreas Färber | 4240abf | 2012-08-20 19:07:56 +0200 | [diff] [blame] | 485 | static const TypeInfo pci_unin_main_info = { |
Andreas Färber | 57fd7b7 | 2012-08-20 19:08:06 +0200 | [diff] [blame] | 486 | .name = TYPE_UNI_NORTH_PCI_HOST_BRIDGE, |
Andreas Färber | 8558d94 | 2012-08-20 19:08:08 +0200 | [diff] [blame] | 487 | .parent = TYPE_PCI_HOST_BRIDGE, |
Mark Cave-Ayland | c90c393 | 2018-03-06 20:31:00 +0000 | [diff] [blame] | 488 | .instance_size = sizeof(UNINHostState), |
Mark Cave-Ayland | 0203459 | 2018-03-06 20:30:47 +0000 | [diff] [blame] | 489 | .instance_init = pci_unin_main_init, |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 490 | .class_init = pci_unin_main_class_init, |
Andreas Färber | 70f9c98 | 2012-01-19 07:40:16 +0000 | [diff] [blame] | 491 | }; |
| 492 | |
Anthony Liguori | 999e12b | 2012-01-24 13:12:29 -0600 | [diff] [blame] | 493 | static void pci_u3_agp_class_init(ObjectClass *klass, void *data) |
| 494 | { |
Laurent Vivier | 1d16f86 | 2015-09-26 18:22:09 +0200 | [diff] [blame] | 495 | DeviceClass *dc = DEVICE_CLASS(klass); |
Anthony Liguori | 999e12b | 2012-01-24 13:12:29 -0600 | [diff] [blame] | 496 | |
Mark Cave-Ayland | 32cde61 | 2018-03-06 20:30:53 +0000 | [diff] [blame] | 497 | dc->realize = pci_u3_agp_realize; |
Laurent Vivier | 1d16f86 | 2015-09-26 18:22:09 +0200 | [diff] [blame] | 498 | set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); |
Anthony Liguori | 999e12b | 2012-01-24 13:12:29 -0600 | [diff] [blame] | 499 | } |
| 500 | |
Andreas Färber | 4240abf | 2012-08-20 19:07:56 +0200 | [diff] [blame] | 501 | static const TypeInfo pci_u3_agp_info = { |
Andreas Färber | 57fd7b7 | 2012-08-20 19:08:06 +0200 | [diff] [blame] | 502 | .name = TYPE_U3_AGP_HOST_BRIDGE, |
Andreas Färber | 8558d94 | 2012-08-20 19:08:08 +0200 | [diff] [blame] | 503 | .parent = TYPE_PCI_HOST_BRIDGE, |
Mark Cave-Ayland | c90c393 | 2018-03-06 20:31:00 +0000 | [diff] [blame] | 504 | .instance_size = sizeof(UNINHostState), |
Mark Cave-Ayland | 0203459 | 2018-03-06 20:30:47 +0000 | [diff] [blame] | 505 | .instance_init = pci_u3_agp_init, |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 506 | .class_init = pci_u3_agp_class_init, |
Andreas Färber | 70f9c98 | 2012-01-19 07:40:16 +0000 | [diff] [blame] | 507 | }; |
| 508 | |
Anthony Liguori | 999e12b | 2012-01-24 13:12:29 -0600 | [diff] [blame] | 509 | static void pci_unin_agp_class_init(ObjectClass *klass, void *data) |
| 510 | { |
Laurent Vivier | 1d16f86 | 2015-09-26 18:22:09 +0200 | [diff] [blame] | 511 | DeviceClass *dc = DEVICE_CLASS(klass); |
Anthony Liguori | 999e12b | 2012-01-24 13:12:29 -0600 | [diff] [blame] | 512 | |
Mark Cave-Ayland | 32cde61 | 2018-03-06 20:30:53 +0000 | [diff] [blame] | 513 | dc->realize = pci_unin_agp_realize; |
Laurent Vivier | 1d16f86 | 2015-09-26 18:22:09 +0200 | [diff] [blame] | 514 | set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); |
Anthony Liguori | 999e12b | 2012-01-24 13:12:29 -0600 | [diff] [blame] | 515 | } |
| 516 | |
Andreas Färber | 4240abf | 2012-08-20 19:07:56 +0200 | [diff] [blame] | 517 | static const TypeInfo pci_unin_agp_info = { |
Andreas Färber | 57fd7b7 | 2012-08-20 19:08:06 +0200 | [diff] [blame] | 518 | .name = TYPE_UNI_NORTH_AGP_HOST_BRIDGE, |
Andreas Färber | 8558d94 | 2012-08-20 19:08:08 +0200 | [diff] [blame] | 519 | .parent = TYPE_PCI_HOST_BRIDGE, |
Mark Cave-Ayland | c90c393 | 2018-03-06 20:31:00 +0000 | [diff] [blame] | 520 | .instance_size = sizeof(UNINHostState), |
Mark Cave-Ayland | 0203459 | 2018-03-06 20:30:47 +0000 | [diff] [blame] | 521 | .instance_init = pci_unin_agp_init, |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 522 | .class_init = pci_unin_agp_class_init, |
Andreas Färber | 70f9c98 | 2012-01-19 07:40:16 +0000 | [diff] [blame] | 523 | }; |
| 524 | |
Anthony Liguori | 999e12b | 2012-01-24 13:12:29 -0600 | [diff] [blame] | 525 | static void pci_unin_internal_class_init(ObjectClass *klass, void *data) |
| 526 | { |
Laurent Vivier | 1d16f86 | 2015-09-26 18:22:09 +0200 | [diff] [blame] | 527 | DeviceClass *dc = DEVICE_CLASS(klass); |
Anthony Liguori | 999e12b | 2012-01-24 13:12:29 -0600 | [diff] [blame] | 528 | |
Mark Cave-Ayland | 1ff861d | 2018-03-06 20:30:55 +0000 | [diff] [blame] | 529 | dc->realize = pci_unin_internal_realize; |
Laurent Vivier | 1d16f86 | 2015-09-26 18:22:09 +0200 | [diff] [blame] | 530 | set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); |
Anthony Liguori | 999e12b | 2012-01-24 13:12:29 -0600 | [diff] [blame] | 531 | } |
| 532 | |
Andreas Färber | 4240abf | 2012-08-20 19:07:56 +0200 | [diff] [blame] | 533 | static const TypeInfo pci_unin_internal_info = { |
Andreas Färber | 57fd7b7 | 2012-08-20 19:08:06 +0200 | [diff] [blame] | 534 | .name = TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE, |
Andreas Färber | 8558d94 | 2012-08-20 19:08:08 +0200 | [diff] [blame] | 535 | .parent = TYPE_PCI_HOST_BRIDGE, |
Mark Cave-Ayland | c90c393 | 2018-03-06 20:31:00 +0000 | [diff] [blame] | 536 | .instance_size = sizeof(UNINHostState), |
Mark Cave-Ayland | 0203459 | 2018-03-06 20:30:47 +0000 | [diff] [blame] | 537 | .instance_init = pci_unin_internal_init, |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 538 | .class_init = pci_unin_internal_class_init, |
Andreas Färber | 70f9c98 | 2012-01-19 07:40:16 +0000 | [diff] [blame] | 539 | }; |
| 540 | |
Mark Cave-Ayland | 0662946 | 2018-05-03 21:24:39 +0100 | [diff] [blame] | 541 | /* UniN device */ |
| 542 | static void unin_write(void *opaque, hwaddr addr, uint64_t value, |
| 543 | unsigned size) |
| 544 | { |
| 545 | trace_unin_write(addr, value); |
Mark Cave-Ayland | 0662946 | 2018-05-03 21:24:39 +0100 | [diff] [blame] | 546 | } |
| 547 | |
| 548 | static uint64_t unin_read(void *opaque, hwaddr addr, unsigned size) |
| 549 | { |
| 550 | uint32_t value; |
| 551 | |
Mark Cave-Ayland | 0662946 | 2018-05-03 21:24:39 +0100 | [diff] [blame] | 552 | switch (addr) { |
| 553 | case 0: |
Mark Cave-Ayland | 45fefe7 | 2018-05-06 15:20:05 +0100 | [diff] [blame] | 554 | value = UNINORTH_VERSION_10A; |
| 555 | break; |
| 556 | default: |
| 557 | value = 0; |
Mark Cave-Ayland | 0662946 | 2018-05-03 21:24:39 +0100 | [diff] [blame] | 558 | } |
| 559 | |
| 560 | trace_unin_read(addr, value); |
| 561 | |
| 562 | return value; |
| 563 | } |
| 564 | |
| 565 | static const MemoryRegionOps unin_ops = { |
| 566 | .read = unin_read, |
| 567 | .write = unin_write, |
| 568 | .endianness = DEVICE_BIG_ENDIAN, |
| 569 | }; |
| 570 | |
| 571 | static void unin_init(Object *obj) |
| 572 | { |
| 573 | UNINState *s = UNI_NORTH(obj); |
| 574 | SysBusDevice *sbd = SYS_BUS_DEVICE(obj); |
| 575 | |
Mark Cave-Ayland | 45fefe7 | 2018-05-06 15:20:05 +0100 | [diff] [blame] | 576 | memory_region_init_io(&s->mem, obj, &unin_ops, s, "unin", 0x1000); |
Mark Cave-Ayland | 0662946 | 2018-05-03 21:24:39 +0100 | [diff] [blame] | 577 | |
| 578 | sysbus_init_mmio(sbd, &s->mem); |
| 579 | } |
| 580 | |
| 581 | static void unin_class_init(ObjectClass *klass, void *data) |
| 582 | { |
| 583 | DeviceClass *dc = DEVICE_CLASS(klass); |
| 584 | |
| 585 | set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); |
| 586 | } |
| 587 | |
| 588 | static const TypeInfo unin_info = { |
| 589 | .name = TYPE_UNI_NORTH, |
| 590 | .parent = TYPE_SYS_BUS_DEVICE, |
| 591 | .instance_size = sizeof(UNINState), |
| 592 | .instance_init = unin_init, |
| 593 | .class_init = unin_class_init, |
| 594 | }; |
| 595 | |
Andreas Färber | 83f7d43 | 2012-02-09 15:20:55 +0100 | [diff] [blame] | 596 | static void unin_register_types(void) |
Blue Swirl | 2e29bd0 | 2009-07-31 20:23:28 +0000 | [diff] [blame] | 597 | { |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 598 | type_register_static(&unin_main_pci_host_info); |
| 599 | type_register_static(&u3_agp_pci_host_info); |
| 600 | type_register_static(&unin_agp_pci_host_info); |
| 601 | type_register_static(&unin_internal_pci_host_info); |
Anthony Liguori | 999e12b | 2012-01-24 13:12:29 -0600 | [diff] [blame] | 602 | |
Anthony Liguori | 39bffca | 2011-12-07 21:34:16 -0600 | [diff] [blame] | 603 | type_register_static(&pci_unin_main_info); |
| 604 | type_register_static(&pci_u3_agp_info); |
| 605 | type_register_static(&pci_unin_agp_info); |
| 606 | type_register_static(&pci_unin_internal_info); |
Mark Cave-Ayland | 0662946 | 2018-05-03 21:24:39 +0100 | [diff] [blame] | 607 | |
| 608 | type_register_static(&unin_info); |
Blue Swirl | 2e29bd0 | 2009-07-31 20:23:28 +0000 | [diff] [blame] | 609 | } |
| 610 | |
Andreas Färber | 83f7d43 | 2012-02-09 15:20:55 +0100 | [diff] [blame] | 611 | type_init(unin_register_types) |