2 * QEMU Uninorth PCI host (for all Mac99 and newer machines)
4 * Copyright (c) 2006 Fabrice Bellard
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
25 #include "qemu/osdep.h"
27 #include "hw/ppc/mac.h"
28 #include "hw/qdev-properties.h"
29 #include "qemu/module.h"
30 #include "hw/pci/pci.h"
31 #include "hw/pci/pci_host.h"
32 #include "hw/pci-host/uninorth.h"
35 static int pci_unin_map_irq(PCIDevice
*pci_dev
, int irq_num
)
37 return (irq_num
+ (pci_dev
->devfn
>> 3)) & 3;
40 static void pci_unin_set_irq(void *opaque
, int irq_num
, int level
)
42 UNINHostState
*s
= opaque
;
44 trace_unin_set_irq(irq_num
, level
);
45 qemu_set_irq(s
->irqs
[irq_num
], level
);
48 static uint32_t unin_get_config_reg(uint32_t reg
, uint32_t addr
)
52 if (reg
& (1u << 31)) {
53 /* XXX OpenBIOS compatibility hack */
54 retval
= reg
| (addr
& 3);
57 retval
= (reg
& ~7u) | (addr
& 7);
61 /* Grab CFA0 style values */
62 slot
= ctz32(reg
& 0xfffff800);
64 slot
= -1; /* XXX: should this be 0? */
66 func
= PCI_FUNC(reg
>> 8);
68 /* ... and then convert them to x86 format */
70 retval
= (reg
& (0xff - 7)) | (addr
& 7);
72 retval
|= PCI_DEVFN(slot
, func
) << 8;
75 trace_unin_get_config_reg(reg
, addr
, retval
);
80 static void unin_data_write(void *opaque
, hwaddr addr
,
81 uint64_t val
, unsigned len
)
83 UNINHostState
*s
= opaque
;
84 PCIHostState
*phb
= PCI_HOST_BRIDGE(s
);
85 trace_unin_data_write(addr
, len
, val
);
86 pci_data_write(phb
->bus
,
87 unin_get_config_reg(phb
->config_reg
, addr
),
91 static uint64_t unin_data_read(void *opaque
, hwaddr addr
,
94 UNINHostState
*s
= opaque
;
95 PCIHostState
*phb
= PCI_HOST_BRIDGE(s
);
98 val
= pci_data_read(phb
->bus
,
99 unin_get_config_reg(phb
->config_reg
, addr
),
101 trace_unin_data_read(addr
, len
, val
);
105 static const MemoryRegionOps unin_data_ops
= {
106 .read
= unin_data_read
,
107 .write
= unin_data_write
,
108 .endianness
= DEVICE_LITTLE_ENDIAN
,
111 static char *pci_unin_main_ofw_unit_address(const SysBusDevice
*dev
)
113 UNINHostState
*s
= UNI_NORTH_PCI_HOST_BRIDGE(dev
);
115 return g_strdup_printf("%x", s
->ofw_addr
);
118 static void pci_unin_main_realize(DeviceState
*dev
, Error
**errp
)
120 UNINHostState
*s
= UNI_NORTH_PCI_HOST_BRIDGE(dev
);
121 PCIHostState
*h
= PCI_HOST_BRIDGE(dev
);
123 h
->bus
= pci_register_root_bus(dev
, NULL
,
124 pci_unin_set_irq
, pci_unin_map_irq
,
128 PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS
);
130 pci_create_simple(h
->bus
, PCI_DEVFN(11, 0), "uni-north-pci");
132 /* DEC 21154 bridge */
134 /* XXX: not activated as PPC BIOS doesn't handle multiple buses properly */
135 pci_create_simple(h
->bus
, PCI_DEVFN(12, 0), "dec-21154");
139 static void pci_unin_main_init(Object
*obj
)
141 UNINHostState
*s
= UNI_NORTH_PCI_HOST_BRIDGE(obj
);
142 SysBusDevice
*sbd
= SYS_BUS_DEVICE(obj
);
143 PCIHostState
*h
= PCI_HOST_BRIDGE(obj
);
145 /* Use values found on a real PowerMac */
146 /* Uninorth main bus */
147 memory_region_init_io(&h
->conf_mem
, OBJECT(h
), &pci_host_conf_le_ops
,
148 obj
, "unin-pci-conf-idx", 0x1000);
149 memory_region_init_io(&h
->data_mem
, OBJECT(h
), &unin_data_ops
, obj
,
150 "unin-pci-conf-data", 0x1000);
152 memory_region_init(&s
->pci_mmio
, OBJECT(s
), "unin-pci-mmio",
154 memory_region_init_io(&s
->pci_io
, OBJECT(s
), &unassigned_io_ops
, obj
,
155 "unin-pci-isa-mmio", 0x00800000);
157 memory_region_init_alias(&s
->pci_hole
, OBJECT(s
),
158 "unin-pci-hole", &s
->pci_mmio
,
159 0x80000000ULL
, 0x10000000ULL
);
161 sysbus_init_mmio(sbd
, &h
->conf_mem
);
162 sysbus_init_mmio(sbd
, &h
->data_mem
);
163 sysbus_init_mmio(sbd
, &s
->pci_hole
);
164 sysbus_init_mmio(sbd
, &s
->pci_io
);
166 qdev_init_gpio_out(DEVICE(obj
), s
->irqs
, ARRAY_SIZE(s
->irqs
));
169 static void pci_u3_agp_realize(DeviceState
*dev
, Error
**errp
)
171 UNINHostState
*s
= U3_AGP_HOST_BRIDGE(dev
);
172 PCIHostState
*h
= PCI_HOST_BRIDGE(dev
);
174 h
->bus
= pci_register_root_bus(dev
, NULL
,
175 pci_unin_set_irq
, pci_unin_map_irq
,
179 PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS
);
181 pci_create_simple(h
->bus
, PCI_DEVFN(11, 0), "u3-agp");
184 static void pci_u3_agp_init(Object
*obj
)
186 UNINHostState
*s
= U3_AGP_HOST_BRIDGE(obj
);
187 SysBusDevice
*sbd
= SYS_BUS_DEVICE(obj
);
188 PCIHostState
*h
= PCI_HOST_BRIDGE(obj
);
190 /* Uninorth U3 AGP bus */
191 memory_region_init_io(&h
->conf_mem
, OBJECT(h
), &pci_host_conf_le_ops
,
192 obj
, "unin-pci-conf-idx", 0x1000);
193 memory_region_init_io(&h
->data_mem
, OBJECT(h
), &unin_data_ops
, obj
,
194 "unin-pci-conf-data", 0x1000);
196 memory_region_init(&s
->pci_mmio
, OBJECT(s
), "unin-pci-mmio",
198 memory_region_init_io(&s
->pci_io
, OBJECT(s
), &unassigned_io_ops
, obj
,
199 "unin-pci-isa-mmio", 0x00800000);
201 memory_region_init_alias(&s
->pci_hole
, OBJECT(s
),
202 "unin-pci-hole", &s
->pci_mmio
,
203 0x80000000ULL
, 0x70000000ULL
);
205 sysbus_init_mmio(sbd
, &h
->conf_mem
);
206 sysbus_init_mmio(sbd
, &h
->data_mem
);
207 sysbus_init_mmio(sbd
, &s
->pci_hole
);
208 sysbus_init_mmio(sbd
, &s
->pci_io
);
210 qdev_init_gpio_out(DEVICE(obj
), s
->irqs
, ARRAY_SIZE(s
->irqs
));
213 static void pci_unin_agp_realize(DeviceState
*dev
, Error
**errp
)
215 UNINHostState
*s
= UNI_NORTH_AGP_HOST_BRIDGE(dev
);
216 PCIHostState
*h
= PCI_HOST_BRIDGE(dev
);
218 h
->bus
= pci_register_root_bus(dev
, NULL
,
219 pci_unin_set_irq
, pci_unin_map_irq
,
223 PCI_DEVFN(11, 0), 4, TYPE_PCI_BUS
);
225 pci_create_simple(h
->bus
, PCI_DEVFN(11, 0), "uni-north-agp");
228 static void pci_unin_agp_init(Object
*obj
)
230 UNINHostState
*s
= UNI_NORTH_AGP_HOST_BRIDGE(obj
);
231 SysBusDevice
*sbd
= SYS_BUS_DEVICE(obj
);
232 PCIHostState
*h
= PCI_HOST_BRIDGE(obj
);
234 /* Uninorth AGP bus */
235 memory_region_init_io(&h
->conf_mem
, OBJECT(h
), &pci_host_conf_le_ops
,
236 obj
, "unin-agp-conf-idx", 0x1000);
237 memory_region_init_io(&h
->data_mem
, OBJECT(h
), &pci_host_data_le_ops
,
238 obj
, "unin-agp-conf-data", 0x1000);
240 sysbus_init_mmio(sbd
, &h
->conf_mem
);
241 sysbus_init_mmio(sbd
, &h
->data_mem
);
243 qdev_init_gpio_out(DEVICE(obj
), s
->irqs
, ARRAY_SIZE(s
->irqs
));
246 static void pci_unin_internal_realize(DeviceState
*dev
, Error
**errp
)
248 UNINHostState
*s
= UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE(dev
);
249 PCIHostState
*h
= PCI_HOST_BRIDGE(dev
);
251 h
->bus
= pci_register_root_bus(dev
, NULL
,
252 pci_unin_set_irq
, pci_unin_map_irq
,
256 PCI_DEVFN(14, 0), 4, TYPE_PCI_BUS
);
258 pci_create_simple(h
->bus
, PCI_DEVFN(14, 0), "uni-north-internal-pci");
261 static void pci_unin_internal_init(Object
*obj
)
263 UNINHostState
*s
= UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE(obj
);
264 SysBusDevice
*sbd
= SYS_BUS_DEVICE(obj
);
265 PCIHostState
*h
= PCI_HOST_BRIDGE(obj
);
267 /* Uninorth internal bus */
268 memory_region_init_io(&h
->conf_mem
, OBJECT(h
), &pci_host_conf_le_ops
,
269 obj
, "unin-pci-conf-idx", 0x1000);
270 memory_region_init_io(&h
->data_mem
, OBJECT(h
), &pci_host_data_le_ops
,
271 obj
, "unin-pci-conf-data", 0x1000);
273 sysbus_init_mmio(sbd
, &h
->conf_mem
);
274 sysbus_init_mmio(sbd
, &h
->data_mem
);
276 qdev_init_gpio_out(DEVICE(obj
), s
->irqs
, ARRAY_SIZE(s
->irqs
));
279 static void unin_main_pci_host_realize(PCIDevice
*d
, Error
**errp
)
281 /* cache_line_size */
282 d
->config
[0x0C] = 0x08;
284 d
->config
[0x0D] = 0x10;
285 /* capabilities_pointer */
286 d
->config
[0x34] = 0x00;
289 * Set kMacRISCPCIAddressSelect (0x48) register to indicate PCI
290 * memory space with base 0x80000000, size 0x10000000 for Apple's
291 * AppleMacRiscPCI driver
293 d
->config
[0x48] = 0x0;
294 d
->config
[0x49] = 0x0;
295 d
->config
[0x4a] = 0x0;
296 d
->config
[0x4b] = 0x1;
299 static void unin_agp_pci_host_realize(PCIDevice
*d
, Error
**errp
)
301 /* cache_line_size */
302 d
->config
[0x0C] = 0x08;
304 d
->config
[0x0D] = 0x10;
305 /* capabilities_pointer
306 d->config[0x34] = 0x80; */
309 static void u3_agp_pci_host_realize(PCIDevice
*d
, Error
**errp
)
311 /* cache line size */
312 d
->config
[0x0C] = 0x08;
314 d
->config
[0x0D] = 0x10;
317 static void unin_internal_pci_host_realize(PCIDevice
*d
, Error
**errp
)
319 /* cache_line_size */
320 d
->config
[0x0C] = 0x08;
322 d
->config
[0x0D] = 0x10;
323 /* capabilities_pointer */
324 d
->config
[0x34] = 0x00;
327 static void unin_main_pci_host_class_init(ObjectClass
*klass
, void *data
)
329 PCIDeviceClass
*k
= PCI_DEVICE_CLASS(klass
);
330 DeviceClass
*dc
= DEVICE_CLASS(klass
);
332 k
->realize
= unin_main_pci_host_realize
;
333 k
->vendor_id
= PCI_VENDOR_ID_APPLE
;
334 k
->device_id
= PCI_DEVICE_ID_APPLE_UNI_N_PCI
;
336 k
->class_id
= PCI_CLASS_BRIDGE_HOST
;
338 * PCI-facing part of the host bridge, not usable without the
339 * host-facing part, which can't be device_add'ed, yet.
341 dc
->user_creatable
= false;
344 static const TypeInfo unin_main_pci_host_info
= {
345 .name
= "uni-north-pci",
346 .parent
= TYPE_PCI_DEVICE
,
347 .instance_size
= sizeof(PCIDevice
),
348 .class_init
= unin_main_pci_host_class_init
,
349 .interfaces
= (InterfaceInfo
[]) {
350 { INTERFACE_CONVENTIONAL_PCI_DEVICE
},
355 static void u3_agp_pci_host_class_init(ObjectClass
*klass
, void *data
)
357 PCIDeviceClass
*k
= PCI_DEVICE_CLASS(klass
);
358 DeviceClass
*dc
= DEVICE_CLASS(klass
);
360 k
->realize
= u3_agp_pci_host_realize
;
361 k
->vendor_id
= PCI_VENDOR_ID_APPLE
;
362 k
->device_id
= PCI_DEVICE_ID_APPLE_U3_AGP
;
364 k
->class_id
= PCI_CLASS_BRIDGE_HOST
;
366 * PCI-facing part of the host bridge, not usable without the
367 * host-facing part, which can't be device_add'ed, yet.
369 dc
->user_creatable
= false;
372 static const TypeInfo u3_agp_pci_host_info
= {
374 .parent
= TYPE_PCI_DEVICE
,
375 .instance_size
= sizeof(PCIDevice
),
376 .class_init
= u3_agp_pci_host_class_init
,
377 .interfaces
= (InterfaceInfo
[]) {
378 { INTERFACE_CONVENTIONAL_PCI_DEVICE
},
383 static void unin_agp_pci_host_class_init(ObjectClass
*klass
, void *data
)
385 PCIDeviceClass
*k
= PCI_DEVICE_CLASS(klass
);
386 DeviceClass
*dc
= DEVICE_CLASS(klass
);
388 k
->realize
= unin_agp_pci_host_realize
;
389 k
->vendor_id
= PCI_VENDOR_ID_APPLE
;
390 k
->device_id
= PCI_DEVICE_ID_APPLE_UNI_N_AGP
;
392 k
->class_id
= PCI_CLASS_BRIDGE_HOST
;
394 * PCI-facing part of the host bridge, not usable without the
395 * host-facing part, which can't be device_add'ed, yet.
397 dc
->user_creatable
= false;
400 static const TypeInfo unin_agp_pci_host_info
= {
401 .name
= "uni-north-agp",
402 .parent
= TYPE_PCI_DEVICE
,
403 .instance_size
= sizeof(PCIDevice
),
404 .class_init
= unin_agp_pci_host_class_init
,
405 .interfaces
= (InterfaceInfo
[]) {
406 { INTERFACE_CONVENTIONAL_PCI_DEVICE
},
411 static void unin_internal_pci_host_class_init(ObjectClass
*klass
, void *data
)
413 PCIDeviceClass
*k
= PCI_DEVICE_CLASS(klass
);
414 DeviceClass
*dc
= DEVICE_CLASS(klass
);
416 k
->realize
= unin_internal_pci_host_realize
;
417 k
->vendor_id
= PCI_VENDOR_ID_APPLE
;
418 k
->device_id
= PCI_DEVICE_ID_APPLE_UNI_N_I_PCI
;
420 k
->class_id
= PCI_CLASS_BRIDGE_HOST
;
422 * PCI-facing part of the host bridge, not usable without the
423 * host-facing part, which can't be device_add'ed, yet.
425 dc
->user_creatable
= false;
428 static const TypeInfo unin_internal_pci_host_info
= {
429 .name
= "uni-north-internal-pci",
430 .parent
= TYPE_PCI_DEVICE
,
431 .instance_size
= sizeof(PCIDevice
),
432 .class_init
= unin_internal_pci_host_class_init
,
433 .interfaces
= (InterfaceInfo
[]) {
434 { INTERFACE_CONVENTIONAL_PCI_DEVICE
},
439 static Property pci_unin_main_pci_host_props
[] = {
440 DEFINE_PROP_UINT32("ofw-addr", UNINHostState
, ofw_addr
, -1),
441 DEFINE_PROP_END_OF_LIST()
444 static void pci_unin_main_class_init(ObjectClass
*klass
, void *data
)
446 DeviceClass
*dc
= DEVICE_CLASS(klass
);
447 SysBusDeviceClass
*sbc
= SYS_BUS_DEVICE_CLASS(klass
);
449 dc
->realize
= pci_unin_main_realize
;
450 device_class_set_props(dc
, pci_unin_main_pci_host_props
);
451 set_bit(DEVICE_CATEGORY_BRIDGE
, dc
->categories
);
453 sbc
->explicit_ofw_unit_address
= pci_unin_main_ofw_unit_address
;
456 static const TypeInfo pci_unin_main_info
= {
457 .name
= TYPE_UNI_NORTH_PCI_HOST_BRIDGE
,
458 .parent
= TYPE_PCI_HOST_BRIDGE
,
459 .instance_size
= sizeof(UNINHostState
),
460 .instance_init
= pci_unin_main_init
,
461 .class_init
= pci_unin_main_class_init
,
464 static void pci_u3_agp_class_init(ObjectClass
*klass
, void *data
)
466 DeviceClass
*dc
= DEVICE_CLASS(klass
);
468 dc
->realize
= pci_u3_agp_realize
;
469 set_bit(DEVICE_CATEGORY_BRIDGE
, dc
->categories
);
472 static const TypeInfo pci_u3_agp_info
= {
473 .name
= TYPE_U3_AGP_HOST_BRIDGE
,
474 .parent
= TYPE_PCI_HOST_BRIDGE
,
475 .instance_size
= sizeof(UNINHostState
),
476 .instance_init
= pci_u3_agp_init
,
477 .class_init
= pci_u3_agp_class_init
,
480 static void pci_unin_agp_class_init(ObjectClass
*klass
, void *data
)
482 DeviceClass
*dc
= DEVICE_CLASS(klass
);
484 dc
->realize
= pci_unin_agp_realize
;
485 set_bit(DEVICE_CATEGORY_BRIDGE
, dc
->categories
);
488 static const TypeInfo pci_unin_agp_info
= {
489 .name
= TYPE_UNI_NORTH_AGP_HOST_BRIDGE
,
490 .parent
= TYPE_PCI_HOST_BRIDGE
,
491 .instance_size
= sizeof(UNINHostState
),
492 .instance_init
= pci_unin_agp_init
,
493 .class_init
= pci_unin_agp_class_init
,
496 static void pci_unin_internal_class_init(ObjectClass
*klass
, void *data
)
498 DeviceClass
*dc
= DEVICE_CLASS(klass
);
500 dc
->realize
= pci_unin_internal_realize
;
501 set_bit(DEVICE_CATEGORY_BRIDGE
, dc
->categories
);
504 static const TypeInfo pci_unin_internal_info
= {
505 .name
= TYPE_UNI_NORTH_INTERNAL_PCI_HOST_BRIDGE
,
506 .parent
= TYPE_PCI_HOST_BRIDGE
,
507 .instance_size
= sizeof(UNINHostState
),
508 .instance_init
= pci_unin_internal_init
,
509 .class_init
= pci_unin_internal_class_init
,
513 static void unin_write(void *opaque
, hwaddr addr
, uint64_t value
,
516 trace_unin_write(addr
, value
);
519 static uint64_t unin_read(void *opaque
, hwaddr addr
, unsigned size
)
525 value
= UNINORTH_VERSION_10A
;
531 trace_unin_read(addr
, value
);
536 static const MemoryRegionOps unin_ops
= {
539 .endianness
= DEVICE_BIG_ENDIAN
,
542 static void unin_init(Object
*obj
)
544 UNINState
*s
= UNI_NORTH(obj
);
545 SysBusDevice
*sbd
= SYS_BUS_DEVICE(obj
);
547 memory_region_init_io(&s
->mem
, obj
, &unin_ops
, s
, "unin", 0x1000);
549 sysbus_init_mmio(sbd
, &s
->mem
);
552 static void unin_class_init(ObjectClass
*klass
, void *data
)
554 DeviceClass
*dc
= DEVICE_CLASS(klass
);
556 set_bit(DEVICE_CATEGORY_BRIDGE
, dc
->categories
);
559 static const TypeInfo unin_info
= {
560 .name
= TYPE_UNI_NORTH
,
561 .parent
= TYPE_SYS_BUS_DEVICE
,
562 .instance_size
= sizeof(UNINState
),
563 .instance_init
= unin_init
,
564 .class_init
= unin_class_init
,
567 static void unin_register_types(void)
569 type_register_static(&unin_main_pci_host_info
);
570 type_register_static(&u3_agp_pci_host_info
);
571 type_register_static(&unin_agp_pci_host_info
);
572 type_register_static(&unin_internal_pci_host_info
);
574 type_register_static(&pci_unin_main_info
);
575 type_register_static(&pci_u3_agp_info
);
576 type_register_static(&pci_unin_agp_info
);
577 type_register_static(&pci_unin_internal_info
);
579 type_register_static(&unin_info
);
582 type_init(unin_register_types
)