1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include "qemu/osdep.h"
25#include "hw/hw.h"
26#include "hw/ppc/mac.h"
27#include "hw/pci/pci.h"
28#include "hw/pci/pci_host.h"
29
30
31
32
33#ifdef DEBUG_UNIN
34#define UNIN_DPRINTF(fmt, ...) \
35 do { printf("UNIN: " fmt , ## __VA_ARGS__); } while (0)
36#else
37#define UNIN_DPRINTF(fmt, ...)
38#endif
39
40static const int unin_irq_line[] = { 0x1b, 0x1c, 0x1d, 0x1e };
41
42#define TYPE_UNI_NORTH_PCI_HOST_BRIDGE "uni-north-pci-pcihost"
43#define TYPE_UNI_NORTH_AGP_HOST_BRIDGE "uni-north-agp-pcihost"
44#define TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE "uni-north-internal-pci-pcihost"
45#define TYPE_U3_AGP_HOST_BRIDGE "u3-agp-pcihost"
46
47#define UNI_NORTH_PCI_HOST_BRIDGE(obj) \
48 OBJECT_CHECK(UNINState, (obj), TYPE_UNI_NORTH_PCI_HOST_BRIDGE)
49#define UNI_NORTH_AGP_HOST_BRIDGE(obj) \
50 OBJECT_CHECK(UNINState, (obj), TYPE_UNI_NORTH_AGP_HOST_BRIDGE)
51#define UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE(obj) \
52 OBJECT_CHECK(UNINState, (obj), TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE)
53#define U3_AGP_HOST_BRIDGE(obj) \
54 OBJECT_CHECK(UNINState, (obj), TYPE_U3_AGP_HOST_BRIDGE)
55
56typedef struct UNINState {
57 PCIHostState parent_obj;
58
59 MemoryRegion pci_mmio;
60 MemoryRegion pci_hole;
61} UNINState;
62
63static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num)
64{
65 return (irq_num + (pci_dev->devfn >> 3)) & 3;
66}
67
68static void pci_unin_set_irq(void *opaque, int irq_num, int level)
69{
70 qemu_irq *pic = opaque;
71
72 UNIN_DPRINTF("%s: setting INT %d = %d\n", __func__,
73 unin_irq_line[irq_num], level);
74 qemu_set_irq(pic[unin_irq_line[irq_num]], level);
75}
76
77static uint32_t unin_get_config_reg(uint32_t reg, uint32_t addr)
78{
79 uint32_t retval;
80
81 if (reg & (1u << 31)) {
82
83 retval = reg | (addr & 3);
84 } else if (reg & 1) {
85
86 retval = (reg & ~7u) | (addr & 7);
87 } else {
88 uint32_t slot, func;
89
90
91 slot = ctz32(reg & 0xfffff800);
92 if (slot == 32) {
93 slot = -1;
94 }
95 func = (reg >> 8) & 7;
96
97
98
99 retval = (reg & (0xff - 7)) | (addr & 7);
100
101 retval |= slot << 11;
102
103 retval |= func << 8;
104 }
105
106
107 UNIN_DPRINTF("Converted config space accessor %08x/%08x -> %08x\n",
108 reg, addr, retval);
109
110 return retval;
111}
112
113static void unin_data_write(void *opaque, hwaddr addr,
114 uint64_t val, unsigned len)
115{
116 UNINState *s = opaque;
117 PCIHostState *phb = PCI_HOST_BRIDGE(s);
118 UNIN_DPRINTF("write addr " TARGET_FMT_plx " len %d val %"PRIx64"\n",
119 addr, len, val);
120 pci_data_write(phb->bus,
121 unin_get_config_reg(phb->config_reg, addr),
122 val, len);
123}
124
125static uint64_t unin_data_read(void *opaque, hwaddr addr,
126 unsigned len)
127{
128 UNINState *s = opaque;
129 PCIHostState *phb = PCI_HOST_BRIDGE(s);
130 uint32_t val;
131
132 val = pci_data_read(phb->bus,
133 unin_get_config_reg(phb->config_reg, addr),
134 len);
135 UNIN_DPRINTF("read addr " TARGET_FMT_plx " len %d val %x\n",
136 addr, len, val);
137 return val;
138}
139
140static const MemoryRegionOps unin_data_ops = {
141 .read = unin_data_read,
142 .write = unin_data_write,
143 .endianness = DEVICE_LITTLE_ENDIAN,
144};
145
146static int pci_unin_main_init_device(SysBusDevice *dev)
147{
148 PCIHostState *h;
149
150
151
152 h = PCI_HOST_BRIDGE(dev);
153
154 memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops,
155 dev, "pci-conf-idx", 0x1000);
156 memory_region_init_io(&h->data_mem, OBJECT(h), &unin_data_ops, dev,
157 "pci-conf-data", 0x1000);
158 sysbus_init_mmio(dev, &h->conf_mem);
159 sysbus_init_mmio(dev, &h->data_mem);
160
161 return 0;
162}
163
164
165static int pci_u3_agp_init_device(SysBusDevice *dev)
166{
167 PCIHostState *h;
168
169
170 h = PCI_HOST_BRIDGE(dev);
171
172 memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops,
173 dev, "pci-conf-idx", 0x1000);
174 memory_region_init_io(&h->data_mem, OBJECT(h), &unin_data_ops, dev,
175 "pci-conf-data", 0x1000);
176 sysbus_init_mmio(dev, &h->conf_mem);
177 sysbus_init_mmio(dev, &h->data_mem);
178
179 return 0;
180}
181
182static int pci_unin_agp_init_device(SysBusDevice *dev)
183{
184 PCIHostState *h;
185
186
187 h = PCI_HOST_BRIDGE(dev);
188
189 memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops,
190 dev, "pci-conf-idx", 0x1000);
191 memory_region_init_io(&h->data_mem, OBJECT(h), &pci_host_data_le_ops,
192 dev, "pci-conf-data", 0x1000);
193 sysbus_init_mmio(dev, &h->conf_mem);
194 sysbus_init_mmio(dev, &h->data_mem);
195 return 0;
196}
197
198static int pci_unin_internal_init_device(SysBusDevice *dev)
199{
200 PCIHostState *h;
201
202
203 h = PCI_HOST_BRIDGE(dev);
204
205 memory_region_init_io(&h->conf_mem, OBJECT(h), &pci_host_conf_le_ops,
206 dev, "pci-conf-idx", 0x1000);
207 memory_region_init_io(&h->data_mem, OBJECT(h), &pci_host_data_le_ops,
208 dev, "pci-conf-data", 0x1000);
209 sysbus_init_mmio(dev, &h->conf_mem);
210 sysbus_init_mmio(dev, &h->data_mem);
211 return 0;
212}
213
214PCIBus *pci_pmac_init(qemu_irq *pic,
215 MemoryRegion *address_space_mem,
216 MemoryRegion *address_space_io)
217{
218 DeviceState *dev;
219 SysBusDevice *s;
220 PCIHostState *h;
221 UNINState *d;
222
223
224
225 dev = qdev_create(NULL, TYPE_UNI_NORTH_PCI_HOST_BRIDGE);
226 qdev_init_nofail(dev);
227 s = SYS_BUS_DEVICE(dev);
228 h = PCI_HOST_BRIDGE(s);
229 d = UNI_NORTH_PCI_HOST_BRIDGE(dev);
230 memory_region_init(&d->pci_mmio, OBJECT(d), "pci-mmio", 0x100000000ULL);
231 memory_region_init_alias(&d->pci_hole, OBJECT(d), "pci-hole", &d->pci_mmio,
232 0x80000000ULL, 0x10000000ULL);
233 memory_region_add_subregion(address_space_mem, 0x80000000ULL,
234 &d->pci_hole);
235
236 h->bus = pci_register_bus(dev, NULL,
237 pci_unin_set_irq, pci_unin_map_irq,
238 pic,
239 &d->pci_mmio,
240 address_space_io,
241 PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS);
242
243#if 0
244 pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north");
245#endif
246
247 sysbus_mmio_map(s, 0, 0xf2800000);
248 sysbus_mmio_map(s, 1, 0xf2c00000);
249
250
251#if 0
252
253 pci_create_simple(h->bus, PCI_DEVFN(12, 0), "dec-21154");
254#endif
255
256
257 pci_create_simple(h->bus, PCI_DEVFN(11, 0), "uni-north-agp");
258 dev = qdev_create(NULL, TYPE_UNI_NORTH_AGP_HOST_BRIDGE);
259 qdev_init_nofail(dev);
260 s = SYS_BUS_DEVICE(dev);
261 sysbus_mmio_map(s, 0, 0xf0800000);
262 sysbus_mmio_map(s, 1, 0xf0c00000);
263
264
265#if 0
266
267 pci_create_simple(h->bus, PCI_DEVFN(14, 0),
268 "uni-north-internal-pci");
269 dev = qdev_create(NULL, TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE);
270 qdev_init_nofail(dev);
271 s = SYS_BUS_DEVICE(dev);
272 sysbus_mmio_map(s, 0, 0xf4800000);
273 sysbus_mmio_map(s, 1, 0xf4c00000);
274#endif
275
276 return h->bus;
277}
278
279PCIBus *pci_pmac_u3_init(qemu_irq *pic,
280 MemoryRegion *address_space_mem,
281 MemoryRegion *address_space_io)
282{
283 DeviceState *dev;
284 SysBusDevice *s;
285 PCIHostState *h;
286 UNINState *d;
287
288
289
290 dev = qdev_create(NULL, TYPE_U3_AGP_HOST_BRIDGE);
291 qdev_init_nofail(dev);
292 s = SYS_BUS_DEVICE(dev);
293 h = PCI_HOST_BRIDGE(dev);
294 d = U3_AGP_HOST_BRIDGE(dev);
295
296 memory_region_init(&d->pci_mmio, OBJECT(d), "pci-mmio", 0x100000000ULL);
297 memory_region_init_alias(&d->pci_hole, OBJECT(d), "pci-hole", &d->pci_mmio,
298 0x80000000ULL, 0x70000000ULL);
299 memory_region_add_subregion(address_space_mem, 0x80000000ULL,
300 &d->pci_hole);
301
302 h->bus = pci_register_bus(dev, NULL,
303 pci_unin_set_irq, pci_unin_map_irq,
304 pic,
305 &d->pci_mmio,
306 address_space_io,
307 PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS);
308
309 sysbus_mmio_map(s, 0, 0xf0800000);
310 sysbus_mmio_map(s, 1, 0xf0c00000);
311
312 pci_create_simple(h->bus, 11 << 3, "u3-agp");
313
314 return h->bus;
315}
316
317static void unin_main_pci_host_realize(PCIDevice *d, Error **errp)
318{
319 d->config[0x0C] = 0x08;
320 d->config[0x0D] = 0x10;
321 d->config[0x34] = 0x00;
322}
323
324static void unin_agp_pci_host_realize(PCIDevice *d, Error **errp)
325{
326 d->config[0x0C] = 0x08;
327 d->config[0x0D] = 0x10;
328
329
330
331
332
333
334 d->config[0x48] = 0x0;
335 d->config[0x49] = 0x0;
336 d->config[0x4a] = 0x0;
337 d->config[0x4b] = 0x1;
338}
339
340static void u3_agp_pci_host_realize(PCIDevice *d, Error **errp)
341{
342
343 d->config[0x0C] = 0x08;
344
345 d->config[0x0D] = 0x10;
346}
347
348static void unin_internal_pci_host_realize(PCIDevice *d, Error **errp)
349{
350 d->config[0x0C] = 0x08;
351 d->config[0x0D] = 0x10;
352 d->config[0x34] = 0x00;
353}
354
355static void unin_main_pci_host_class_init(ObjectClass *klass, void *data)
356{
357 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
358 DeviceClass *dc = DEVICE_CLASS(klass);
359
360 k->realize = unin_main_pci_host_realize;
361 k->vendor_id = PCI_VENDOR_ID_APPLE;
362 k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_PCI;
363 k->revision = 0x00;
364 k->class_id = PCI_CLASS_BRIDGE_HOST;
365
366
367
368
369 dc->user_creatable = false;
370}
371
372static const TypeInfo unin_main_pci_host_info = {
373 .name = "uni-north-pci",
374 .parent = TYPE_PCI_DEVICE,
375 .instance_size = sizeof(PCIDevice),
376 .class_init = unin_main_pci_host_class_init,
377 .interfaces = (InterfaceInfo[]) {
378 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
379 { },
380 },
381};
382
383static void u3_agp_pci_host_class_init(ObjectClass *klass, void *data)
384{
385 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
386 DeviceClass *dc = DEVICE_CLASS(klass);
387
388 k->realize = u3_agp_pci_host_realize;
389 k->vendor_id = PCI_VENDOR_ID_APPLE;
390 k->device_id = PCI_DEVICE_ID_APPLE_U3_AGP;
391 k->revision = 0x00;
392 k->class_id = PCI_CLASS_BRIDGE_HOST;
393
394
395
396
397 dc->user_creatable = false;
398}
399
400static const TypeInfo u3_agp_pci_host_info = {
401 .name = "u3-agp",
402 .parent = TYPE_PCI_DEVICE,
403 .instance_size = sizeof(PCIDevice),
404 .class_init = u3_agp_pci_host_class_init,
405 .interfaces = (InterfaceInfo[]) {
406 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
407 { },
408 },
409};
410
411static void unin_agp_pci_host_class_init(ObjectClass *klass, void *data)
412{
413 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
414 DeviceClass *dc = DEVICE_CLASS(klass);
415
416 k->realize = unin_agp_pci_host_realize;
417 k->vendor_id = PCI_VENDOR_ID_APPLE;
418 k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP;
419 k->revision = 0x00;
420 k->class_id = PCI_CLASS_BRIDGE_HOST;
421
422
423
424
425 dc->user_creatable = false;
426}
427
428static const TypeInfo unin_agp_pci_host_info = {
429 .name = "uni-north-agp",
430 .parent = TYPE_PCI_DEVICE,
431 .instance_size = sizeof(PCIDevice),
432 .class_init = unin_agp_pci_host_class_init,
433 .interfaces = (InterfaceInfo[]) {
434 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
435 { },
436 },
437};
438
439static void unin_internal_pci_host_class_init(ObjectClass *klass, void *data)
440{
441 PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
442 DeviceClass *dc = DEVICE_CLASS(klass);
443
444 k->realize = unin_internal_pci_host_realize;
445 k->vendor_id = PCI_VENDOR_ID_APPLE;
446 k->device_id = PCI_DEVICE_ID_APPLE_UNI_N_I_PCI;
447 k->revision = 0x00;
448 k->class_id = PCI_CLASS_BRIDGE_HOST;
449
450
451
452
453 dc->user_creatable = false;
454}
455
456static const TypeInfo unin_internal_pci_host_info = {
457 .name = "uni-north-internal-pci",
458 .parent = TYPE_PCI_DEVICE,
459 .instance_size = sizeof(PCIDevice),
460 .class_init = unin_internal_pci_host_class_init,
461 .interfaces = (InterfaceInfo[]) {
462 { INTERFACE_CONVENTIONAL_PCI_DEVICE },
463 { },
464 },
465};
466
467static void pci_unin_main_class_init(ObjectClass *klass, void *data)
468{
469 SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
470 DeviceClass *dc = DEVICE_CLASS(klass);
471
472 sbc->init = pci_unin_main_init_device;
473 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
474}
475
476static const TypeInfo pci_unin_main_info = {
477 .name = TYPE_UNI_NORTH_PCI_HOST_BRIDGE,
478 .parent = TYPE_PCI_HOST_BRIDGE,
479 .instance_size = sizeof(UNINState),
480 .class_init = pci_unin_main_class_init,
481};
482
483static void pci_u3_agp_class_init(ObjectClass *klass, void *data)
484{
485 SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
486 DeviceClass *dc = DEVICE_CLASS(klass);
487
488 sbc->init = pci_u3_agp_init_device;
489 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
490}
491
492static const TypeInfo pci_u3_agp_info = {
493 .name = TYPE_U3_AGP_HOST_BRIDGE,
494 .parent = TYPE_PCI_HOST_BRIDGE,
495 .instance_size = sizeof(UNINState),
496 .class_init = pci_u3_agp_class_init,
497};
498
499static void pci_unin_agp_class_init(ObjectClass *klass, void *data)
500{
501 SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
502 DeviceClass *dc = DEVICE_CLASS(klass);
503
504 sbc->init = pci_unin_agp_init_device;
505 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
506}
507
508static const TypeInfo pci_unin_agp_info = {
509 .name = TYPE_UNI_NORTH_AGP_HOST_BRIDGE,
510 .parent = TYPE_PCI_HOST_BRIDGE,
511 .instance_size = sizeof(UNINState),
512 .class_init = pci_unin_agp_class_init,
513};
514
515static void pci_unin_internal_class_init(ObjectClass *klass, void *data)
516{
517 SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
518 DeviceClass *dc = DEVICE_CLASS(klass);
519
520 sbc->init = pci_unin_internal_init_device;
521 set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
522}
523
524static const TypeInfo pci_unin_internal_info = {
525 .name = TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE,
526 .parent = TYPE_PCI_HOST_BRIDGE,
527 .instance_size = sizeof(UNINState),
528 .class_init = pci_unin_internal_class_init,
529};
530
531static void unin_register_types(void)
532{
533 type_register_static(&unin_main_pci_host_info);
534 type_register_static(&u3_agp_pci_host_info);
535 type_register_static(&unin_agp_pci_host_info);
536 type_register_static(&unin_internal_pci_host_info);
537
538 type_register_static(&pci_unin_main_info);
539 type_register_static(&pci_u3_agp_info);
540 type_register_static(&pci_unin_agp_info);
541 type_register_static(&pci_unin_internal_info);
542}
543
544type_init(unin_register_types)
545