26
#include "qemu/osdep.h"
27
#include "qapi/error.h"
28
#include "qemu/module.h"
29
#include "hw/misc/macio/cuda.h"
30
#include "hw/pci/pci.h"
31
#include "hw/ppc/mac_dbdma.h"
32
#include "hw/qdev-properties.h"
33
#include "migration/vmstate.h"
34
#include "hw/char/escc.h"
35
#include "hw/misc/macio/macio.h"
36
#include "hw/intc/heathrow_pic.h"
39
#define ESCC_CLOCK 3686400
54
static void macio_escc_legacy_setup(MacIOState *s)
56
SysBusDevice *sbd = SYS_BUS_DEVICE(&s->escc);
57
MemoryRegion *escc_legacy = g_new(MemoryRegion, 1);
59
static const int maps[] = {
72
memory_region_init(escc_legacy, OBJECT(s), "escc-legacy", 256);
73
for (i = 0; i < ARRAY_SIZE(maps); i += 2) {
74
MemoryRegion *port = g_new(MemoryRegion, 1);
75
memory_region_init_alias(port, OBJECT(s), "escc-legacy-port",
76
sysbus_mmio_get_region(sbd, 0),
78
memory_region_add_subregion(escc_legacy, maps[i], port);
81
memory_region_add_subregion(&s->bar, 0x12000, escc_legacy);
84
static void macio_bar_setup(MacIOState *s)
86
SysBusDevice *sbd = SYS_BUS_DEVICE(&s->escc);
87
MemoryRegion *bar = sysbus_mmio_get_region(sbd, 0);
89
memory_region_add_subregion(&s->bar, 0x13000, bar);
90
macio_escc_legacy_setup(s);
93
static bool macio_common_realize(PCIDevice *d, Error **errp)
95
MacIOState *s = MACIO(d);
98
if (!qdev_realize(DEVICE(&s->dbdma), BUS(&s->macio_bus), errp)) {
101
sbd = SYS_BUS_DEVICE(&s->dbdma);
102
memory_region_add_subregion(&s->bar, 0x08000,
103
sysbus_mmio_get_region(sbd, 0));
105
qdev_prop_set_uint32(DEVICE(&s->escc), "disabled", 0);
106
qdev_prop_set_uint32(DEVICE(&s->escc), "frequency", ESCC_CLOCK);
107
qdev_prop_set_uint32(DEVICE(&s->escc), "it_shift", 4);
108
qdev_prop_set_uint32(DEVICE(&s->escc), "chnBtype", escc_serial);
109
qdev_prop_set_uint32(DEVICE(&s->escc), "chnAtype", escc_serial);
110
if (!qdev_realize(DEVICE(&s->escc), BUS(&s->macio_bus), errp)) {
115
pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar);
120
static bool macio_realize_ide(MacIOState *s, MACIOIDEState *ide,
121
qemu_irq irq0, qemu_irq irq1, int dmaid,
124
SysBusDevice *sbd = SYS_BUS_DEVICE(ide);
126
qdev_prop_set_uint32(DEVICE(ide), "channel", dmaid);
127
object_property_set_link(OBJECT(ide), "dbdma", OBJECT(&s->dbdma),
129
macio_ide_register_dma(ide);
130
if (!qdev_realize(DEVICE(ide), BUS(&s->macio_bus), errp)) {
133
sysbus_connect_irq(sbd, 0, irq0);
134
sysbus_connect_irq(sbd, 1, irq1);
139
static void macio_oldworld_realize(PCIDevice *d, Error **errp)
141
MacIOState *s = MACIO(d);
142
OldWorldMacIOState *os = OLDWORLD_MACIO(d);
143
DeviceState *pic_dev = DEVICE(&os->pic);
146
if (!macio_common_realize(d, errp)) {
151
if (!qdev_realize(DEVICE(&os->pic), BUS(&s->macio_bus), errp)) {
154
sbd = SYS_BUS_DEVICE(&os->pic);
155
memory_region_add_subregion(&s->bar, 0x0,
156
sysbus_mmio_get_region(sbd, 0));
158
qdev_prop_set_uint64(DEVICE(&s->cuda), "timebase-frequency",
160
if (!qdev_realize(DEVICE(&s->cuda), BUS(&s->macio_bus), errp)) {
163
sbd = SYS_BUS_DEVICE(&s->cuda);
164
memory_region_add_subregion(&s->bar, 0x16000,
165
sysbus_mmio_get_region(sbd, 0));
166
sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(pic_dev, OLDWORLD_CUDA_IRQ));
168
sbd = SYS_BUS_DEVICE(&s->escc);
169
sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(pic_dev, OLDWORLD_ESCCB_IRQ));
170
sysbus_connect_irq(sbd, 1, qdev_get_gpio_in(pic_dev, OLDWORLD_ESCCA_IRQ));
172
if (!qdev_realize(DEVICE(&os->nvram), BUS(&s->macio_bus), errp)) {
175
sbd = SYS_BUS_DEVICE(&os->nvram);
176
memory_region_add_subregion(&s->bar, 0x60000,
177
sysbus_mmio_get_region(sbd, 0));
178
pmac_format_nvram_partition(&os->nvram, os->nvram.size);
181
if (!macio_realize_ide(s, &os->ide[0],
182
qdev_get_gpio_in(pic_dev, OLDWORLD_IDE0_IRQ),
183
qdev_get_gpio_in(pic_dev, OLDWORLD_IDE0_DMA_IRQ),
188
if (!macio_realize_ide(s, &os->ide[1],
189
qdev_get_gpio_in(pic_dev, OLDWORLD_IDE1_IRQ),
190
qdev_get_gpio_in(pic_dev, OLDWORLD_IDE1_DMA_IRQ),
196
static void macio_init_ide(MacIOState *s, MACIOIDEState *ide, int index)
198
gchar *name = g_strdup_printf("ide[%i]", index);
199
uint32_t addr = 0x1f000 + ((index + 1) * 0x1000);
201
object_initialize_child(OBJECT(s), name, ide, TYPE_MACIO_IDE);
202
qdev_prop_set_uint32(DEVICE(ide), "addr", addr);
203
memory_region_add_subregion(&s->bar, addr, &ide->mem);
207
static void macio_oldworld_init(Object *obj)
209
MacIOState *s = MACIO(obj);
210
OldWorldMacIOState *os = OLDWORLD_MACIO(obj);
214
object_initialize_child(obj, "pic", &os->pic, TYPE_HEATHROW);
216
object_initialize_child(obj, "cuda", &s->cuda, TYPE_CUDA);
218
object_initialize_child(obj, "nvram", &os->nvram, TYPE_MACIO_NVRAM);
219
dev = DEVICE(&os->nvram);
220
qdev_prop_set_uint32(dev, "size", MACIO_NVRAM_SIZE);
221
qdev_prop_set_uint32(dev, "it_shift", 4);
223
for (i = 0; i < 2; i++) {
224
macio_init_ide(s, &os->ide[i], i);
228
static void timer_write(void *opaque, hwaddr addr, uint64_t value,
231
trace_macio_timer_write(addr, size, value);
234
static uint64_t timer_read(void *opaque, hwaddr addr, unsigned size)
237
uint64_t systime = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
240
kltime = muldiv64(systime, 4194300, NANOSECONDS_PER_SECOND * 4);
241
kltime = muldiv64(kltime, 18432000, 1048575);
248
value = kltime >> 32;
252
trace_macio_timer_read(addr, size, value);
256
static const MemoryRegionOps timer_ops = {
258
.write = timer_write,
259
.endianness = DEVICE_LITTLE_ENDIAN,
262
static void macio_newworld_realize(PCIDevice *d, Error **errp)
264
MacIOState *s = MACIO(d);
265
NewWorldMacIOState *ns = NEWWORLD_MACIO(d);
266
DeviceState *pic_dev = DEVICE(&ns->pic);
268
MemoryRegion *timer_memory = NULL;
270
if (!macio_common_realize(d, errp)) {
275
qdev_prop_set_uint32(pic_dev, "model", OPENPIC_MODEL_KEYLARGO);
276
sbd = SYS_BUS_DEVICE(&ns->pic);
277
sysbus_realize_and_unref(sbd, &error_fatal);
278
memory_region_add_subregion(&s->bar, 0x40000,
279
sysbus_mmio_get_region(sbd, 0));
281
sbd = SYS_BUS_DEVICE(&s->escc);
282
sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(pic_dev, NEWWORLD_ESCCB_IRQ));
283
sysbus_connect_irq(sbd, 1, qdev_get_gpio_in(pic_dev, NEWWORLD_ESCCA_IRQ));
286
if (!macio_realize_ide(s, &ns->ide[0],
287
qdev_get_gpio_in(pic_dev, NEWWORLD_IDE0_IRQ),
288
qdev_get_gpio_in(pic_dev, NEWWORLD_IDE0_DMA_IRQ),
293
if (!macio_realize_ide(s, &ns->ide[1],
294
qdev_get_gpio_in(pic_dev, NEWWORLD_IDE1_IRQ),
295
qdev_get_gpio_in(pic_dev, NEWWORLD_IDE1_DMA_IRQ),
301
timer_memory = g_new(MemoryRegion, 1);
302
memory_region_init_io(timer_memory, OBJECT(s), &timer_ops, NULL, "timer",
304
memory_region_add_subregion(&s->bar, 0x15000, timer_memory);
308
if (!qdev_realize(DEVICE(&ns->gpio), BUS(&s->macio_bus), errp)) {
311
sbd = SYS_BUS_DEVICE(&ns->gpio);
312
sysbus_connect_irq(sbd, 1, qdev_get_gpio_in(pic_dev,
313
NEWWORLD_EXTING_GPIO1));
314
sysbus_connect_irq(sbd, 9, qdev_get_gpio_in(pic_dev,
315
NEWWORLD_EXTING_GPIO9));
316
memory_region_add_subregion(&s->bar, 0x50,
317
sysbus_mmio_get_region(sbd, 0));
320
object_initialize_child(OBJECT(s), "pmu", &s->pmu, TYPE_VIA_PMU);
321
object_property_set_link(OBJECT(&s->pmu), "gpio", OBJECT(sbd),
323
qdev_prop_set_bit(DEVICE(&s->pmu), "has-adb", ns->has_adb);
324
if (!qdev_realize(DEVICE(&s->pmu), BUS(&s->macio_bus), errp)) {
327
sbd = SYS_BUS_DEVICE(&s->pmu);
328
sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(pic_dev, NEWWORLD_PMU_IRQ));
329
memory_region_add_subregion(&s->bar, 0x16000,
330
sysbus_mmio_get_region(sbd, 0));
332
object_unparent(OBJECT(&ns->gpio));
335
object_initialize_child(OBJECT(s), "cuda", &s->cuda, TYPE_CUDA);
336
qdev_prop_set_uint64(DEVICE(&s->cuda), "timebase-frequency",
339
if (!qdev_realize(DEVICE(&s->cuda), BUS(&s->macio_bus), errp)) {
342
sbd = SYS_BUS_DEVICE(&s->cuda);
343
sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(pic_dev, NEWWORLD_CUDA_IRQ));
344
memory_region_add_subregion(&s->bar, 0x16000,
345
sysbus_mmio_get_region(sbd, 0));
349
static void macio_newworld_init(Object *obj)
351
MacIOState *s = MACIO(obj);
352
NewWorldMacIOState *ns = NEWWORLD_MACIO(obj);
355
object_initialize_child(obj, "pic", &ns->pic, TYPE_OPENPIC);
357
object_initialize_child(obj, "gpio", &ns->gpio, TYPE_MACIO_GPIO);
359
for (i = 0; i < 2; i++) {
360
macio_init_ide(s, &ns->ide[i], i);
364
static void macio_instance_init(Object *obj)
366
MacIOState *s = MACIO(obj);
368
memory_region_init(&s->bar, obj, "macio", 0x80000);
370
qbus_init(&s->macio_bus, sizeof(s->macio_bus), TYPE_MACIO_BUS,
371
DEVICE(obj), "macio.0");
373
object_initialize_child(obj, "dbdma", &s->dbdma, TYPE_MAC_DBDMA);
375
object_initialize_child(obj, "escc", &s->escc, TYPE_ESCC);
378
static const VMStateDescription vmstate_macio_oldworld = {
379
.name = "macio-oldworld",
381
.minimum_version_id = 0,
382
.fields = (const VMStateField[]) {
383
VMSTATE_PCI_DEVICE(parent_obj.parent, OldWorldMacIOState),
384
VMSTATE_END_OF_LIST()
388
static void macio_oldworld_class_init(ObjectClass *oc, void *data)
390
PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc);
391
DeviceClass *dc = DEVICE_CLASS(oc);
393
pdc->realize = macio_oldworld_realize;
394
pdc->device_id = PCI_DEVICE_ID_APPLE_343S1201;
395
dc->vmsd = &vmstate_macio_oldworld;
398
static const VMStateDescription vmstate_macio_newworld = {
399
.name = "macio-newworld",
401
.minimum_version_id = 0,
402
.fields = (const VMStateField[]) {
403
VMSTATE_PCI_DEVICE(parent_obj.parent, NewWorldMacIOState),
404
VMSTATE_END_OF_LIST()
408
static Property macio_newworld_properties[] = {
409
DEFINE_PROP_BOOL("has-pmu", NewWorldMacIOState, has_pmu, false),
410
DEFINE_PROP_BOOL("has-adb", NewWorldMacIOState, has_adb, false),
411
DEFINE_PROP_END_OF_LIST()
414
static void macio_newworld_class_init(ObjectClass *oc, void *data)
416
PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc);
417
DeviceClass *dc = DEVICE_CLASS(oc);
419
pdc->realize = macio_newworld_realize;
420
pdc->device_id = PCI_DEVICE_ID_APPLE_UNI_N_KEYL;
421
dc->vmsd = &vmstate_macio_newworld;
422
device_class_set_props(dc, macio_newworld_properties);
425
static Property macio_properties[] = {
426
DEFINE_PROP_UINT64("frequency", MacIOState, frequency, 0),
427
DEFINE_PROP_END_OF_LIST()
430
static void macio_class_init(ObjectClass *klass, void *data)
432
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
433
DeviceClass *dc = DEVICE_CLASS(klass);
435
k->vendor_id = PCI_VENDOR_ID_APPLE;
436
k->class_id = PCI_CLASS_OTHERS << 8;
437
device_class_set_props(dc, macio_properties);
438
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
441
static const TypeInfo macio_bus_info = {
442
.name = TYPE_MACIO_BUS,
443
.parent = TYPE_SYSTEM_BUS,
444
.instance_size = sizeof(MacIOBusState),
447
static const TypeInfo macio_oldworld_type_info = {
448
.name = TYPE_OLDWORLD_MACIO,
449
.parent = TYPE_MACIO,
450
.instance_size = sizeof(OldWorldMacIOState),
451
.instance_init = macio_oldworld_init,
452
.class_init = macio_oldworld_class_init,
455
static const TypeInfo macio_newworld_type_info = {
456
.name = TYPE_NEWWORLD_MACIO,
457
.parent = TYPE_MACIO,
458
.instance_size = sizeof(NewWorldMacIOState),
459
.instance_init = macio_newworld_init,
460
.class_init = macio_newworld_class_init,
463
static const TypeInfo macio_type_info = {
465
.parent = TYPE_PCI_DEVICE,
466
.instance_size = sizeof(MacIOState),
467
.instance_init = macio_instance_init,
469
.class_init = macio_class_init,
470
.interfaces = (InterfaceInfo[]) {
471
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
476
static void macio_register_types(void)
478
type_register_static(&macio_bus_info);
479
type_register_static(&macio_type_info);
480
type_register_static(&macio_oldworld_type_info);
481
type_register_static(&macio_newworld_type_info);
484
type_init(macio_register_types)