blob: e4c1abd8715293a7bed25287227cdd45df80ef14 [file] [log] [blame]
pbrook502a5392006-05-13 16:11:23 +00001/*
2 * QEMU Uninorth PCI host (for all Mac99 and newer machines)
3 *
4 * Copyright (c) 2006 Fabrice Bellard
ths5fafdf22007-09-16 21:08:06 +00005 *
pbrook502a5392006-05-13 16:11:23 +00006 * 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 Armbruster0b8fa322019-05-23 16:35:07 +020024
Peter Maydell0d755902016-01-26 18:16:58 +000025#include "qemu/osdep.h"
Markus Armbruster64552b62019-08-12 07:23:42 +020026#include "hw/irq.h"
Markus Armbrustera27bd6c2019-08-12 07:23:51 +020027#include "hw/qdev-properties.h"
Markus Armbruster0b8fa322019-05-23 16:35:07 +020028#include "qemu/module.h"
Markus Armbrusteredf5ca52022-12-22 11:03:28 +010029#include "hw/pci/pci_device.h"
Paolo Bonzini83c9f4c2013-02-04 15:40:22 +010030#include "hw/pci/pci_host.h"
Mark Cave-Ayland5d2eaa02018-03-06 20:30:49 +000031#include "hw/pci-host/uninorth.h"
Mark Cave-Ayland0b0c5e92018-01-26 09:20:28 +000032#include "trace.h"
blueswir1f3902382009-02-05 20:22:07 +000033
pbrookd2b59312006-09-24 00:16:34 +000034static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num)
pbrook502a5392006-05-13 16:11:23 +000035{
Benjamin Herrenschmidt39d97e12016-11-21 00:12:31 +100036 return (irq_num + (pci_dev->devfn >> 3)) & 3;
pbrookd2b59312006-09-24 00:16:34 +000037}
38
Juan Quintela5d4e84c2009-08-28 15:28:17 +020039static void pci_unin_set_irq(void *opaque, int irq_num, int level)
pbrookd2b59312006-09-24 00:16:34 +000040{
Mark Cave-Aylandc90c3932018-03-06 20:31:00 +000041 UNINHostState *s = opaque;
Juan Quintela5d4e84c2009-08-28 15:28:17 +020042
Mark Cave-Ayland40a0deb2020-10-13 12:49:22 +010043 trace_unin_set_irq(irq_num, level);
Mark Cave-Aylande7755cc2018-03-06 20:30:58 +000044 qemu_set_irq(s->irqs[irq_num], level);
pbrook502a5392006-05-13 16:11:23 +000045}
46
Alexander Grafd86f0e32010-02-09 17:37:01 +010047static uint32_t unin_get_config_reg(uint32_t reg, uint32_t addr)
48{
49 uint32_t retval;
50
51 if (reg & (1u << 31)) {
52 /* XXX OpenBIOS compatibility hack */
53 retval = reg | (addr & 3);
54 } else if (reg & 1) {
55 /* CFA1 style */
56 retval = (reg & ~7u) | (addr & 7);
57 } else {
58 uint32_t slot, func;
59
60 /* Grab CFA0 style values */
Stefan Hajnoczi5863d372015-03-23 15:29:25 +000061 slot = ctz32(reg & 0xfffff800);
62 if (slot == 32) {
63 slot = -1; /* XXX: should this be 0? */
64 }
Philippe Mathieu-Daudéd08b9c12020-10-11 17:22:04 +020065 func = PCI_FUNC(reg >> 8);
Alexander Grafd86f0e32010-02-09 17:37:01 +010066
67 /* ... and then convert them to x86 format */
68 /* config pointer */
69 retval = (reg & (0xff - 7)) | (addr & 7);
Philippe Mathieu-Daudé4934e472020-10-12 08:36:41 +020070 /* slot, fn */
71 retval |= PCI_DEVFN(slot, func) << 8;
Alexander Grafd86f0e32010-02-09 17:37:01 +010072 }
73
Mark Cave-Ayland0b0c5e92018-01-26 09:20:28 +000074 trace_unin_get_config_reg(reg, addr, retval);
Alexander Grafd86f0e32010-02-09 17:37:01 +010075
76 return retval;
77}
78
Avi Kivitya8170e52012-10-23 12:30:10 +020079static void unin_data_write(void *opaque, hwaddr addr,
Avi Kivityd0ed8072011-07-24 17:47:18 +030080 uint64_t val, unsigned len)
Alexander Grafd86f0e32010-02-09 17:37:01 +010081{
Mark Cave-Aylandc90c3932018-03-06 20:31:00 +000082 UNINHostState *s = opaque;
Andreas Färber67c332f2012-08-20 19:08:09 +020083 PCIHostState *phb = PCI_HOST_BRIDGE(s);
Mark Cave-Ayland0b0c5e92018-01-26 09:20:28 +000084 trace_unin_data_write(addr, len, val);
Andreas Färber67c332f2012-08-20 19:08:09 +020085 pci_data_write(phb->bus,
86 unin_get_config_reg(phb->config_reg, addr),
Alexander Grafd86f0e32010-02-09 17:37:01 +010087 val, len);
88}
89
Avi Kivitya8170e52012-10-23 12:30:10 +020090static uint64_t unin_data_read(void *opaque, hwaddr addr,
Avi Kivityd0ed8072011-07-24 17:47:18 +030091 unsigned len)
Alexander Grafd86f0e32010-02-09 17:37:01 +010092{
Mark Cave-Aylandc90c3932018-03-06 20:31:00 +000093 UNINHostState *s = opaque;
Andreas Färber67c332f2012-08-20 19:08:09 +020094 PCIHostState *phb = PCI_HOST_BRIDGE(s);
Alexander Grafd86f0e32010-02-09 17:37:01 +010095 uint32_t val;
96
Andreas Färber67c332f2012-08-20 19:08:09 +020097 val = pci_data_read(phb->bus,
98 unin_get_config_reg(phb->config_reg, addr),
Alexander Grafd86f0e32010-02-09 17:37:01 +010099 len);
Mark Cave-Ayland0b0c5e92018-01-26 09:20:28 +0000100 trace_unin_data_read(addr, len, val);
Alexander Grafd86f0e32010-02-09 17:37:01 +0100101 return val;
102}
103
Avi Kivityd0ed8072011-07-24 17:47:18 +0300104static const MemoryRegionOps unin_data_ops = {
105 .read = unin_data_read,
106 .write = unin_data_write,
107 .endianness = DEVICE_LITTLE_ENDIAN,
108};
109
Mark Cave-Ayland03756c82018-08-29 17:59:10 +0100110static char *pci_unin_main_ofw_unit_address(const SysBusDevice *dev)
111{
112 UNINHostState *s = UNI_NORTH_PCI_HOST_BRIDGE(dev);
113
114 return g_strdup_printf("%x", s->ofw_addr);
115}
116
Mark Cave-Ayland32cde612018-03-06 20:30:53 +0000117static void pci_unin_main_realize(DeviceState *dev, Error **errp)
118{
Mark Cave-Aylandc90c3932018-03-06 20:31:00 +0000119 UNINHostState *s = UNI_NORTH_PCI_HOST_BRIDGE(dev);
Mark Cave-Ayland32cde612018-03-06 20:30:53 +0000120 PCIHostState *h = PCI_HOST_BRIDGE(dev);
121
122 h->bus = pci_register_root_bus(dev, NULL,
123 pci_unin_set_irq, pci_unin_map_irq,
Mark Cave-Aylande7755cc2018-03-06 20:30:58 +0000124 s,
Mark Cave-Ayland32cde612018-03-06 20:30:53 +0000125 &s->pci_mmio,
Mark Cave-Aylande226efb2018-03-06 20:30:59 +0000126 &s->pci_io,
Mark Cave-Ayland32cde612018-03-06 20:30:53 +0000127 PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS);
128
Mark Cave-Aylandc1d66d32018-03-06 20:30:54 +0000129 pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-pci");
Mark Cave-Ayland32cde612018-03-06 20:30:53 +0000130
Igor Mammedovb1fbf242022-11-29 11:13:40 +0100131 /*
132 * DEC 21154 bridge was unused for many years, this comment is
133 * a placeholder for whoever wishes to resurrect it
134 */
Mark Cave-Ayland32cde612018-03-06 20:30:53 +0000135}
136
Mark Cave-Ayland02034592018-03-06 20:30:47 +0000137static void pci_unin_main_init(Object *obj)
pbrook502a5392006-05-13 16:11:23 +0000138{
Mark Cave-Aylandc90c3932018-03-06 20:31:00 +0000139 UNINHostState *s = UNI_NORTH_PCI_HOST_BRIDGE(obj);
Mark Cave-Ayland02034592018-03-06 20:30:47 +0000140 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
141 PCIHostState *h = PCI_HOST_BRIDGE(obj);
pbrook502a5392006-05-13 16:11:23 +0000142
143 /* Use values found on a real PowerMac */
144 /* Uninorth main bus */
Paolo Bonzini40c5dce2013-06-06 21:25:08 -0400145 memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops,
Mark Cave-Ayland132e9902018-03-06 20:30:51 +0000146 obj, "unin-pci-conf-idx", 0x1000);
Mark Cave-Ayland02034592018-03-06 20:30:47 +0000147 memory_region_init_io(&h->data_mem, OBJECT(h), &unin_data_ops, obj,
Mark Cave-Ayland132e9902018-03-06 20:30:51 +0000148 "unin-pci-conf-data", 0x1000);
149
150 memory_region_init(&s->pci_mmio, OBJECT(s), "unin-pci-mmio",
151 0x100000000ULL);
Mark Cave-Aylande226efb2018-03-06 20:30:59 +0000152 memory_region_init_io(&s->pci_io, OBJECT(s), &unassigned_io_ops, obj,
153 "unin-pci-isa-mmio", 0x00800000);
Mark Cave-Ayland132e9902018-03-06 20:30:51 +0000154
Mark Cave-Ayland7b193182018-03-06 20:30:56 +0000155 memory_region_init_alias(&s->pci_hole, OBJECT(s),
156 "unin-pci-hole", &s->pci_mmio,
157 0x80000000ULL, 0x10000000ULL);
158
Mark Cave-Ayland02034592018-03-06 20:30:47 +0000159 sysbus_init_mmio(sbd, &h->conf_mem);
160 sysbus_init_mmio(sbd, &h->data_mem);
Mark Cave-Ayland7b193182018-03-06 20:30:56 +0000161 sysbus_init_mmio(sbd, &s->pci_hole);
Mark Cave-Aylande226efb2018-03-06 20:30:59 +0000162 sysbus_init_mmio(sbd, &s->pci_io);
Mark Cave-Ayland40a0deb2020-10-13 12:49:22 +0100163
164 qdev_init_gpio_out(DEVICE(obj), s->irqs, ARRAY_SIZE(s->irqs));
Blue Swirl2e29bd02009-07-31 20:23:28 +0000165}
166
Mark Cave-Ayland32cde612018-03-06 20:30:53 +0000167static void pci_u3_agp_realize(DeviceState *dev, Error **errp)
168{
Mark Cave-Aylandc90c3932018-03-06 20:31:00 +0000169 UNINHostState *s = U3_AGP_HOST_BRIDGE(dev);
Mark Cave-Ayland32cde612018-03-06 20:30:53 +0000170 PCIHostState *h = PCI_HOST_BRIDGE(dev);
171
172 h->bus = pci_register_root_bus(dev, NULL,
173 pci_unin_set_irq, pci_unin_map_irq,
Mark Cave-Aylande7755cc2018-03-06 20:30:58 +0000174 s,
Mark Cave-Ayland32cde612018-03-06 20:30:53 +0000175 &s->pci_mmio,
Mark Cave-Aylande226efb2018-03-06 20:30:59 +0000176 &s->pci_io,
Mark Cave-Ayland32cde612018-03-06 20:30:53 +0000177 PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS);
178
179 pci_create_simple(h->bus, PCI_DEVFN(11, 0), "u3-agp");
180}
181
Mark Cave-Ayland02034592018-03-06 20:30:47 +0000182static void pci_u3_agp_init(Object *obj)
Alexander Graf0f921192010-02-09 17:37:02 +0100183{
Mark Cave-Aylandc90c3932018-03-06 20:31:00 +0000184 UNINHostState *s = U3_AGP_HOST_BRIDGE(obj);
Mark Cave-Ayland02034592018-03-06 20:30:47 +0000185 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
186 PCIHostState *h = PCI_HOST_BRIDGE(obj);
Alexander Graf0f921192010-02-09 17:37:02 +0100187
188 /* Uninorth U3 AGP bus */
Paolo Bonzini40c5dce2013-06-06 21:25:08 -0400189 memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops,
Mark Cave-Ayland132e9902018-03-06 20:30:51 +0000190 obj, "unin-pci-conf-idx", 0x1000);
Mark Cave-Ayland02034592018-03-06 20:30:47 +0000191 memory_region_init_io(&h->data_mem, OBJECT(h), &unin_data_ops, obj,
Mark Cave-Ayland132e9902018-03-06 20:30:51 +0000192 "unin-pci-conf-data", 0x1000);
193
194 memory_region_init(&s->pci_mmio, OBJECT(s), "unin-pci-mmio",
195 0x100000000ULL);
Mark Cave-Aylande226efb2018-03-06 20:30:59 +0000196 memory_region_init_io(&s->pci_io, OBJECT(s), &unassigned_io_ops, obj,
197 "unin-pci-isa-mmio", 0x00800000);
Mark Cave-Ayland132e9902018-03-06 20:30:51 +0000198
Mark Cave-Ayland8ce3f742018-03-06 20:30:57 +0000199 memory_region_init_alias(&s->pci_hole, OBJECT(s),
200 "unin-pci-hole", &s->pci_mmio,
201 0x80000000ULL, 0x70000000ULL);
202
Mark Cave-Ayland02034592018-03-06 20:30:47 +0000203 sysbus_init_mmio(sbd, &h->conf_mem);
204 sysbus_init_mmio(sbd, &h->data_mem);
Mark Cave-Ayland8ce3f742018-03-06 20:30:57 +0000205 sysbus_init_mmio(sbd, &s->pci_hole);
Mark Cave-Aylande226efb2018-03-06 20:30:59 +0000206 sysbus_init_mmio(sbd, &s->pci_io);
Mark Cave-Ayland40a0deb2020-10-13 12:49:22 +0100207
208 qdev_init_gpio_out(DEVICE(obj), s->irqs, ARRAY_SIZE(s->irqs));
Alexander Graf0f921192010-02-09 17:37:02 +0100209}
210
Mark Cave-Ayland32cde612018-03-06 20:30:53 +0000211static void pci_unin_agp_realize(DeviceState *dev, Error **errp)
212{
Mark Cave-Aylandc90c3932018-03-06 20:31:00 +0000213 UNINHostState *s = UNI_NORTH_AGP_HOST_BRIDGE(dev);
Mark Cave-Ayland32cde612018-03-06 20:30:53 +0000214 PCIHostState *h = PCI_HOST_BRIDGE(dev);
215
216 h->bus = pci_register_root_bus(dev, NULL,
217 pci_unin_set_irq, pci_unin_map_irq,
Mark Cave-Aylande7755cc2018-03-06 20:30:58 +0000218 s,
Mark Cave-Ayland32cde612018-03-06 20:30:53 +0000219 &s->pci_mmio,
Mark Cave-Aylande226efb2018-03-06 20:30:59 +0000220 &s->pci_io,
Mark Cave-Ayland32cde612018-03-06 20:30:53 +0000221 PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS);
Mark Cave-Aylandc1d66d32018-03-06 20:30:54 +0000222
223 pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-agp");
Mark Cave-Ayland32cde612018-03-06 20:30:53 +0000224}
225
Mark Cave-Ayland02034592018-03-06 20:30:47 +0000226static void pci_unin_agp_init(Object *obj)
Blue Swirl2e29bd02009-07-31 20:23:28 +0000227{
Mark Cave-Aylandc90c3932018-03-06 20:31:00 +0000228 UNINHostState *s = UNI_NORTH_AGP_HOST_BRIDGE(obj);
Mark Cave-Ayland02034592018-03-06 20:30:47 +0000229 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
230 PCIHostState *h = PCI_HOST_BRIDGE(obj);
Blue Swirl2e29bd02009-07-31 20:23:28 +0000231
232 /* Uninorth AGP bus */
Paolo Bonzini40c5dce2013-06-06 21:25:08 -0400233 memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops,
Mark Cave-Ayland132e9902018-03-06 20:30:51 +0000234 obj, "unin-agp-conf-idx", 0x1000);
Paolo Bonzini40c5dce2013-06-06 21:25:08 -0400235 memory_region_init_io(&h->data_mem, OBJECT(h), &pci_host_data_le_ops,
Mark Cave-Ayland132e9902018-03-06 20:30:51 +0000236 obj, "unin-agp-conf-data", 0x1000);
Mark Cave-Aylande7755cc2018-03-06 20:30:58 +0000237
Mark Cave-Ayland02034592018-03-06 20:30:47 +0000238 sysbus_init_mmio(sbd, &h->conf_mem);
239 sysbus_init_mmio(sbd, &h->data_mem);
Mark Cave-Ayland40a0deb2020-10-13 12:49:22 +0100240
241 qdev_init_gpio_out(DEVICE(obj), s->irqs, ARRAY_SIZE(s->irqs));
Blue Swirl2e29bd02009-07-31 20:23:28 +0000242}
243
Mark Cave-Ayland1ff861d2018-03-06 20:30:55 +0000244static void pci_unin_internal_realize(DeviceState *dev, Error **errp)
245{
Mark Cave-Aylandc90c3932018-03-06 20:31:00 +0000246 UNINHostState *s = UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE(dev);
Mark Cave-Ayland1ff861d2018-03-06 20:30:55 +0000247 PCIHostState *h = PCI_HOST_BRIDGE(dev);
248
249 h->bus = pci_register_root_bus(dev, NULL,
250 pci_unin_set_irq, pci_unin_map_irq,
Mark Cave-Aylande7755cc2018-03-06 20:30:58 +0000251 s,
Mark Cave-Ayland1ff861d2018-03-06 20:30:55 +0000252 &s->pci_mmio,
Mark Cave-Aylande226efb2018-03-06 20:30:59 +0000253 &s->pci_io,
Mark Cave-Ayland1ff861d2018-03-06 20:30:55 +0000254 PCI_DEVFN(14, 0), 4, TYPE_PCI_BUS);
255
256 pci_create_simple(h->bus, PCI_DEVFN(14, 0), "uni-north-internal-pci");
257}
258
Mark Cave-Ayland02034592018-03-06 20:30:47 +0000259static void pci_unin_internal_init(Object *obj)
Blue Swirl2e29bd02009-07-31 20:23:28 +0000260{
Mark Cave-Aylandc90c3932018-03-06 20:31:00 +0000261 UNINHostState *s = UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE(obj);
Mark Cave-Ayland02034592018-03-06 20:30:47 +0000262 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
263 PCIHostState *h = PCI_HOST_BRIDGE(obj);
Blue Swirl2e29bd02009-07-31 20:23:28 +0000264
265 /* Uninorth internal bus */
Paolo Bonzini40c5dce2013-06-06 21:25:08 -0400266 memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops,
Mark Cave-Ayland132e9902018-03-06 20:30:51 +0000267 obj, "unin-pci-conf-idx", 0x1000);
Paolo Bonzini40c5dce2013-06-06 21:25:08 -0400268 memory_region_init_io(&h->data_mem, OBJECT(h), &pci_host_data_le_ops,
Mark Cave-Ayland132e9902018-03-06 20:30:51 +0000269 obj, "unin-pci-conf-data", 0x1000);
Mark Cave-Aylande7755cc2018-03-06 20:30:58 +0000270
Mark Cave-Ayland02034592018-03-06 20:30:47 +0000271 sysbus_init_mmio(sbd, &h->conf_mem);
272 sysbus_init_mmio(sbd, &h->data_mem);
Mark Cave-Ayland40a0deb2020-10-13 12:49:22 +0100273
274 qdev_init_gpio_out(DEVICE(obj), s->irqs, ARRAY_SIZE(s->irqs));
Blue Swirl2e29bd02009-07-31 20:23:28 +0000275}
276
Markus Armbruster9af21db2015-01-19 15:52:30 +0100277static void unin_main_pci_host_realize(PCIDevice *d, Error **errp)
Blue Swirl2e29bd02009-07-31 20:23:28 +0000278{
Philippe Mathieu-Daudé8a8c9c32023-01-05 18:37:02 +0100279 d->config[PCI_CACHE_LINE_SIZE] = 0x08;
280 d->config[PCI_LATENCY_TIMER] = 0x10;
281 d->config[PCI_CAPABILITY_LIST] = 0x00;
Mark Cave-Ayland4d309c92018-03-06 20:30:45 +0000282
Programmingkid98ae3b22016-01-22 11:09:23 -0500283 /*
284 * Set kMacRISCPCIAddressSelect (0x48) register to indicate PCI
285 * memory space with base 0x80000000, size 0x10000000 for Apple's
286 * AppleMacRiscPCI driver
287 */
288 d->config[0x48] = 0x0;
289 d->config[0x49] = 0x0;
290 d->config[0x4a] = 0x0;
291 d->config[0x4b] = 0x1;
Blue Swirl2e29bd02009-07-31 20:23:28 +0000292}
pbrook502a5392006-05-13 16:11:23 +0000293
Mark Cave-Aylandc1d66d32018-03-06 20:30:54 +0000294static void unin_agp_pci_host_realize(PCIDevice *d, Error **errp)
295{
Philippe Mathieu-Daudé8a8c9c32023-01-05 18:37:02 +0100296 d->config[PCI_CACHE_LINE_SIZE] = 0x08;
297 d->config[PCI_LATENCY_TIMER] = 0x10;
298 /* d->config[PCI_CAPABILITY_LIST] = 0x80; */
Mark Cave-Aylandc1d66d32018-03-06 20:30:54 +0000299}
300
Markus Armbruster9af21db2015-01-19 15:52:30 +0100301static void u3_agp_pci_host_realize(PCIDevice *d, Error **errp)
Alexander Graf0f921192010-02-09 17:37:02 +0100302{
Philippe Mathieu-Daudé8a8c9c32023-01-05 18:37:02 +0100303 d->config[PCI_CACHE_LINE_SIZE] = 0x08;
304 d->config[PCI_LATENCY_TIMER] = 0x10;
Alexander Graf0f921192010-02-09 17:37:02 +0100305}
306
Markus Armbruster9af21db2015-01-19 15:52:30 +0100307static void unin_internal_pci_host_realize(PCIDevice *d, Error **errp)
Blue Swirl2e29bd02009-07-31 20:23:28 +0000308{
Philippe Mathieu-Daudé8a8c9c32023-01-05 18:37:02 +0100309 d->config[PCI_CACHE_LINE_SIZE] = 0x08;
310 d->config[PCI_LATENCY_TIMER] = 0x10;
311 d->config[PCI_CAPABILITY_LIST] = 0x00;
pbrook502a5392006-05-13 16:11:23 +0000312}
Blue Swirl2e29bd02009-07-31 20:23:28 +0000313
Anthony Liguori40021f02011-12-04 12:22:06 -0600314static void unin_main_pci_host_class_init(ObjectClass *klass, void *data)
315{
316 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
Markus Armbruster08c58f92013-11-28 17:26:58 +0100317 DeviceClass *dc = DEVICE_CLASS(klass);
Anthony Liguori40021f02011-12-04 12:22:06 -0600318
Markus Armbruster9af21db2015-01-19 15:52:30 +0100319 k->realize = unin_main_pci_host_realize;
Anthony Liguori40021f02011-12-04 12:22:06 -0600320 k->vendor_id = PCI_VENDOR_ID_APPLE;
321 k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_PCI;
322 k->revision = 0x00;
323 k->class_id = PCI_CLASS_BRIDGE_HOST;
Markus Armbruster08c58f92013-11-28 17:26:58 +0100324 /*
325 * PCI-facing part of the host bridge, not usable without the
326 * host-facing part, which can't be device_add'ed, yet.
327 */
Eduardo Habkoste90f2a82017-05-03 17:35:44 -0300328 dc->user_creatable = false;
Anthony Liguori40021f02011-12-04 12:22:06 -0600329}
330
Andreas Färber4240abf2012-08-20 19:07:56 +0200331static const TypeInfo unin_main_pci_host_info = {
Anthony Liguori40021f02011-12-04 12:22:06 -0600332 .name = "uni-north-pci",
Anthony Liguori39bffca2011-12-07 21:34:16 -0600333 .parent = TYPE_PCI_DEVICE,
334 .instance_size = sizeof(PCIDevice),
Anthony Liguori40021f02011-12-04 12:22:06 -0600335 .class_init = unin_main_pci_host_class_init,
Eduardo Habkostfd3b02c2017-09-27 16:56:34 -0300336 .interfaces = (InterfaceInfo[]) {
337 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
338 { },
339 },
Blue Swirl2e29bd02009-07-31 20:23:28 +0000340};
341
Anthony Liguori40021f02011-12-04 12:22:06 -0600342static void u3_agp_pci_host_class_init(ObjectClass *klass, void *data)
343{
344 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
Markus Armbruster08c58f92013-11-28 17:26:58 +0100345 DeviceClass *dc = DEVICE_CLASS(klass);
Anthony Liguori40021f02011-12-04 12:22:06 -0600346
Markus Armbruster9af21db2015-01-19 15:52:30 +0100347 k->realize = u3_agp_pci_host_realize;
Anthony Liguori40021f02011-12-04 12:22:06 -0600348 k->vendor_id = PCI_VENDOR_ID_APPLE;
349 k->device_id = PCI_DEVICE_ID_APPLE_U3_AGP;
350 k->revision = 0x00;
351 k->class_id = PCI_CLASS_BRIDGE_HOST;
Markus Armbruster08c58f92013-11-28 17:26:58 +0100352 /*
353 * PCI-facing part of the host bridge, not usable without the
354 * host-facing part, which can't be device_add'ed, yet.
355 */
Eduardo Habkoste90f2a82017-05-03 17:35:44 -0300356 dc->user_creatable = false;
Anthony Liguori40021f02011-12-04 12:22:06 -0600357}
358
Andreas Färber4240abf2012-08-20 19:07:56 +0200359static const TypeInfo u3_agp_pci_host_info = {
Anthony Liguori40021f02011-12-04 12:22:06 -0600360 .name = "u3-agp",
Anthony Liguori39bffca2011-12-07 21:34:16 -0600361 .parent = TYPE_PCI_DEVICE,
362 .instance_size = sizeof(PCIDevice),
Anthony Liguori40021f02011-12-04 12:22:06 -0600363 .class_init = u3_agp_pci_host_class_init,
Eduardo Habkostfd3b02c2017-09-27 16:56:34 -0300364 .interfaces = (InterfaceInfo[]) {
365 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
366 { },
367 },
Alexander Graf0f921192010-02-09 17:37:02 +0100368};
369
Anthony Liguori40021f02011-12-04 12:22:06 -0600370static void unin_agp_pci_host_class_init(ObjectClass *klass, void *data)
371{
372 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
Markus Armbruster08c58f92013-11-28 17:26:58 +0100373 DeviceClass *dc = DEVICE_CLASS(klass);
Anthony Liguori40021f02011-12-04 12:22:06 -0600374
Markus Armbruster9af21db2015-01-19 15:52:30 +0100375 k->realize = unin_agp_pci_host_realize;
Anthony Liguori40021f02011-12-04 12:22:06 -0600376 k->vendor_id = PCI_VENDOR_ID_APPLE;
377 k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP;
378 k->revision = 0x00;
379 k->class_id = PCI_CLASS_BRIDGE_HOST;
Markus Armbruster08c58f92013-11-28 17:26:58 +0100380 /*
381 * PCI-facing part of the host bridge, not usable without the
382 * host-facing part, which can't be device_add'ed, yet.
383 */
Eduardo Habkoste90f2a82017-05-03 17:35:44 -0300384 dc->user_creatable = false;
Anthony Liguori40021f02011-12-04 12:22:06 -0600385}
386
Andreas Färber4240abf2012-08-20 19:07:56 +0200387static const TypeInfo unin_agp_pci_host_info = {
Anthony Liguori40021f02011-12-04 12:22:06 -0600388 .name = "uni-north-agp",
Anthony Liguori39bffca2011-12-07 21:34:16 -0600389 .parent = TYPE_PCI_DEVICE,
390 .instance_size = sizeof(PCIDevice),
Anthony Liguori40021f02011-12-04 12:22:06 -0600391 .class_init = unin_agp_pci_host_class_init,
Eduardo Habkostfd3b02c2017-09-27 16:56:34 -0300392 .interfaces = (InterfaceInfo[]) {
393 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
394 { },
395 },
Blue Swirl2e29bd02009-07-31 20:23:28 +0000396};
397
Anthony Liguori40021f02011-12-04 12:22:06 -0600398static void unin_internal_pci_host_class_init(ObjectClass *klass, void *data)
399{
400 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
Markus Armbruster08c58f92013-11-28 17:26:58 +0100401 DeviceClass *dc = DEVICE_CLASS(klass);
Anthony Liguori40021f02011-12-04 12:22:06 -0600402
Markus Armbruster9af21db2015-01-19 15:52:30 +0100403 k->realize = unin_internal_pci_host_realize;
Anthony Liguori40021f02011-12-04 12:22:06 -0600404 k->vendor_id = PCI_VENDOR_ID_APPLE;
405 k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_I_PCI;
406 k->revision = 0x00;
407 k->class_id = PCI_CLASS_BRIDGE_HOST;
Markus Armbruster08c58f92013-11-28 17:26:58 +0100408 /*
409 * PCI-facing part of the host bridge, not usable without the
410 * host-facing part, which can't be device_add'ed, yet.
411 */
Eduardo Habkoste90f2a82017-05-03 17:35:44 -0300412 dc->user_creatable = false;
Anthony Liguori40021f02011-12-04 12:22:06 -0600413}
414
Andreas Färber4240abf2012-08-20 19:07:56 +0200415static const TypeInfo unin_internal_pci_host_info = {
Anthony Liguori40021f02011-12-04 12:22:06 -0600416 .name = "uni-north-internal-pci",
Anthony Liguori39bffca2011-12-07 21:34:16 -0600417 .parent = TYPE_PCI_DEVICE,
418 .instance_size = sizeof(PCIDevice),
Anthony Liguori40021f02011-12-04 12:22:06 -0600419 .class_init = unin_internal_pci_host_class_init,
Eduardo Habkostfd3b02c2017-09-27 16:56:34 -0300420 .interfaces = (InterfaceInfo[]) {
421 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
422 { },
423 },
Blue Swirl2e29bd02009-07-31 20:23:28 +0000424};
425
Mark Cave-Ayland03756c82018-08-29 17:59:10 +0100426static Property pci_unin_main_pci_host_props[] = {
427 DEFINE_PROP_UINT32("ofw-addr", UNINHostState, ofw_addr, -1),
428 DEFINE_PROP_END_OF_LIST()
429};
430
Anthony Liguori999e12b2012-01-24 13:12:29 -0600431static void pci_unin_main_class_init(ObjectClass *klass, void *data)
432{
Laurent Vivier1d16f862015-09-26 18:22:09 +0200433 DeviceClass *dc = DEVICE_CLASS(klass);
Mark Cave-Ayland03756c82018-08-29 17:59:10 +0100434 SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
Anthony Liguori999e12b2012-01-24 13:12:29 -0600435
Mark Cave-Ayland32cde612018-03-06 20:30:53 +0000436 dc->realize = pci_unin_main_realize;
Marc-André Lureau4f67d302020-01-10 19:30:32 +0400437 device_class_set_props(dc, pci_unin_main_pci_host_props);
Laurent Vivier1d16f862015-09-26 18:22:09 +0200438 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
Mark Cave-Ayland03756c82018-08-29 17:59:10 +0100439 dc->fw_name = "pci";
440 sbc->explicit_ofw_unit_address = pci_unin_main_ofw_unit_address;
Anthony Liguori999e12b2012-01-24 13:12:29 -0600441}
442
Andreas Färber4240abf2012-08-20 19:07:56 +0200443static const TypeInfo pci_unin_main_info = {
Andreas Färber57fd7b72012-08-20 19:08:06 +0200444 .name = TYPE_UNI_NORTH_PCI_HOST_BRIDGE,
Andreas Färber8558d942012-08-20 19:08:08 +0200445 .parent = TYPE_PCI_HOST_BRIDGE,
Mark Cave-Aylandc90c3932018-03-06 20:31:00 +0000446 .instance_size = sizeof(UNINHostState),
Mark Cave-Ayland02034592018-03-06 20:30:47 +0000447 .instance_init = pci_unin_main_init,
Anthony Liguori39bffca2011-12-07 21:34:16 -0600448 .class_init = pci_unin_main_class_init,
Andreas Färber70f9c982012-01-19 07:40:16 +0000449};
450
Anthony Liguori999e12b2012-01-24 13:12:29 -0600451static void pci_u3_agp_class_init(ObjectClass *klass, void *data)
452{
Laurent Vivier1d16f862015-09-26 18:22:09 +0200453 DeviceClass *dc = DEVICE_CLASS(klass);
Anthony Liguori999e12b2012-01-24 13:12:29 -0600454
Mark Cave-Ayland32cde612018-03-06 20:30:53 +0000455 dc->realize = pci_u3_agp_realize;
Laurent Vivier1d16f862015-09-26 18:22:09 +0200456 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
Anthony Liguori999e12b2012-01-24 13:12:29 -0600457}
458
Andreas Färber4240abf2012-08-20 19:07:56 +0200459static const TypeInfo pci_u3_agp_info = {
Andreas Färber57fd7b72012-08-20 19:08:06 +0200460 .name = TYPE_U3_AGP_HOST_BRIDGE,
Andreas Färber8558d942012-08-20 19:08:08 +0200461 .parent = TYPE_PCI_HOST_BRIDGE,
Mark Cave-Aylandc90c3932018-03-06 20:31:00 +0000462 .instance_size = sizeof(UNINHostState),
Mark Cave-Ayland02034592018-03-06 20:30:47 +0000463 .instance_init = pci_u3_agp_init,
Anthony Liguori39bffca2011-12-07 21:34:16 -0600464 .class_init = pci_u3_agp_class_init,
Andreas Färber70f9c982012-01-19 07:40:16 +0000465};
466
Anthony Liguori999e12b2012-01-24 13:12:29 -0600467static void pci_unin_agp_class_init(ObjectClass *klass, void *data)
468{
Laurent Vivier1d16f862015-09-26 18:22:09 +0200469 DeviceClass *dc = DEVICE_CLASS(klass);
Anthony Liguori999e12b2012-01-24 13:12:29 -0600470
Mark Cave-Ayland32cde612018-03-06 20:30:53 +0000471 dc->realize = pci_unin_agp_realize;
Laurent Vivier1d16f862015-09-26 18:22:09 +0200472 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
Anthony Liguori999e12b2012-01-24 13:12:29 -0600473}
474
Andreas Färber4240abf2012-08-20 19:07:56 +0200475static const TypeInfo pci_unin_agp_info = {
Andreas Färber57fd7b72012-08-20 19:08:06 +0200476 .name = TYPE_UNI_NORTH_AGP_HOST_BRIDGE,
Andreas Färber8558d942012-08-20 19:08:08 +0200477 .parent = TYPE_PCI_HOST_BRIDGE,
Mark Cave-Aylandc90c3932018-03-06 20:31:00 +0000478 .instance_size = sizeof(UNINHostState),
Mark Cave-Ayland02034592018-03-06 20:30:47 +0000479 .instance_init = pci_unin_agp_init,
Anthony Liguori39bffca2011-12-07 21:34:16 -0600480 .class_init = pci_unin_agp_class_init,
Andreas Färber70f9c982012-01-19 07:40:16 +0000481};
482
Anthony Liguori999e12b2012-01-24 13:12:29 -0600483static void pci_unin_internal_class_init(ObjectClass *klass, void *data)
484{
Laurent Vivier1d16f862015-09-26 18:22:09 +0200485 DeviceClass *dc = DEVICE_CLASS(klass);
Anthony Liguori999e12b2012-01-24 13:12:29 -0600486
Mark Cave-Ayland1ff861d2018-03-06 20:30:55 +0000487 dc->realize = pci_unin_internal_realize;
Laurent Vivier1d16f862015-09-26 18:22:09 +0200488 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
Anthony Liguori999e12b2012-01-24 13:12:29 -0600489}
490
Andreas Färber4240abf2012-08-20 19:07:56 +0200491static const TypeInfo pci_unin_internal_info = {
Andreas Färber57fd7b72012-08-20 19:08:06 +0200492 .name = TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE,
Andreas Färber8558d942012-08-20 19:08:08 +0200493 .parent = TYPE_PCI_HOST_BRIDGE,
Mark Cave-Aylandc90c3932018-03-06 20:31:00 +0000494 .instance_size = sizeof(UNINHostState),
Mark Cave-Ayland02034592018-03-06 20:30:47 +0000495 .instance_init = pci_unin_internal_init,
Anthony Liguori39bffca2011-12-07 21:34:16 -0600496 .class_init = pci_unin_internal_class_init,
Andreas Färber70f9c982012-01-19 07:40:16 +0000497};
498
Mark Cave-Ayland06629462018-05-03 21:24:39 +0100499/* UniN device */
500static void unin_write(void *opaque, hwaddr addr, uint64_t value,
501 unsigned size)
502{
503 trace_unin_write(addr, value);
Mark Cave-Ayland06629462018-05-03 21:24:39 +0100504}
505
506static uint64_t unin_read(void *opaque, hwaddr addr, unsigned size)
507{
508 uint32_t value;
509
Mark Cave-Ayland06629462018-05-03 21:24:39 +0100510 switch (addr) {
511 case 0:
Mark Cave-Ayland45fefe72018-05-06 15:20:05 +0100512 value = UNINORTH_VERSION_10A;
513 break;
514 default:
515 value = 0;
Mark Cave-Ayland06629462018-05-03 21:24:39 +0100516 }
517
518 trace_unin_read(addr, value);
519
520 return value;
521}
522
523static const MemoryRegionOps unin_ops = {
524 .read = unin_read,
525 .write = unin_write,
526 .endianness = DEVICE_BIG_ENDIAN,
527};
528
529static void unin_init(Object *obj)
530{
531 UNINState *s = UNI_NORTH(obj);
532 SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
533
Mark Cave-Ayland45fefe72018-05-06 15:20:05 +0100534 memory_region_init_io(&s->mem, obj, &unin_ops, s, "unin", 0x1000);
Mark Cave-Ayland06629462018-05-03 21:24:39 +0100535
536 sysbus_init_mmio(sbd, &s->mem);
537}
538
539static void unin_class_init(ObjectClass *klass, void *data)
540{
541 DeviceClass *dc = DEVICE_CLASS(klass);
542
543 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
544}
545
546static const TypeInfo unin_info = {
547 .name = TYPE_UNI_NORTH,
548 .parent = TYPE_SYS_BUS_DEVICE,
549 .instance_size = sizeof(UNINState),
550 .instance_init = unin_init,
551 .class_init = unin_class_init,
552};
553
Andreas Färber83f7d432012-02-09 15:20:55 +0100554static void unin_register_types(void)
Blue Swirl2e29bd02009-07-31 20:23:28 +0000555{
Anthony Liguori39bffca2011-12-07 21:34:16 -0600556 type_register_static(&unin_main_pci_host_info);
557 type_register_static(&u3_agp_pci_host_info);
558 type_register_static(&unin_agp_pci_host_info);
559 type_register_static(&unin_internal_pci_host_info);
Anthony Liguori999e12b2012-01-24 13:12:29 -0600560
Anthony Liguori39bffca2011-12-07 21:34:16 -0600561 type_register_static(&pci_unin_main_info);
562 type_register_static(&pci_u3_agp_info);
563 type_register_static(&pci_unin_agp_info);
564 type_register_static(&pci_unin_internal_info);
Mark Cave-Ayland06629462018-05-03 21:24:39 +0100565
566 type_register_static(&unin_info);
Blue Swirl2e29bd02009-07-31 20:23:28 +0000567}
568
Andreas Färber83f7d432012-02-09 15:20:55 +0100569type_init(unin_register_types)