2 * QEMU Macintosh Nubus Virtio MMIO card
4 * Copyright (c) 2024 Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
6 * SPDX-License-Identifier: GPL-2.0-or-later
9 #include "qemu/osdep.h"
10 #include "hw/nubus/nubus-virtio-mmio.h"
13 #define NUBUS_VIRTIO_MMIO_PIC_OFFSET 0
14 #define NUBUS_VIRTIO_MMIO_DEV_OFFSET 0x200
17 static void nubus_virtio_mmio_set_input_irq(void *opaque
, int n
, int level
)
19 NubusDevice
*nd
= NUBUS_DEVICE(opaque
);
21 nubus_set_irq(nd
, level
);
24 static void nubus_virtio_mmio_realize(DeviceState
*dev
, Error
**errp
)
26 NubusVirtioMMIODeviceClass
*nvmdc
= NUBUS_VIRTIO_MMIO_GET_CLASS(dev
);
27 NubusVirtioMMIO
*s
= NUBUS_VIRTIO_MMIO(dev
);
28 NubusDevice
*nd
= NUBUS_DEVICE(dev
);
32 nvmdc
->parent_realize(dev
, errp
);
38 sbd
= SYS_BUS_DEVICE(&s
->pic
);
39 if (!sysbus_realize(sbd
, errp
)) {
42 memory_region_add_subregion(&nd
->slot_mem
, NUBUS_VIRTIO_MMIO_PIC_OFFSET
,
43 sysbus_mmio_get_region(sbd
, 0));
44 sysbus_connect_irq(sbd
, 0,
45 qdev_get_gpio_in_named(dev
, "pic-input-irq", 0));
47 /* virtio-mmio devices */
48 offset
= NUBUS_VIRTIO_MMIO_DEV_OFFSET
;
49 for (i
= 0; i
< NUBUS_VIRTIO_MMIO_NUM_DEVICES
; i
++) {
50 sbd
= SYS_BUS_DEVICE(&s
->virtio_mmio
[i
]);
51 qdev_prop_set_bit(DEVICE(sbd
), "force-legacy", false);
52 if (!sysbus_realize_and_unref(sbd
, errp
)) {
56 memory_region_add_subregion(&nd
->slot_mem
, offset
,
57 sysbus_mmio_get_region(sbd
, 0));
60 sysbus_connect_irq(sbd
, 0, qdev_get_gpio_in(DEVICE(&s
->pic
), i
));
64 static void nubus_virtio_mmio_init(Object
*obj
)
66 NubusVirtioMMIO
*s
= NUBUS_VIRTIO_MMIO(obj
);
69 object_initialize_child(obj
, "pic", &s
->pic
, TYPE_GOLDFISH_PIC
);
70 for (i
= 0; i
< NUBUS_VIRTIO_MMIO_NUM_DEVICES
; i
++) {
71 char *name
= g_strdup_printf("virtio-mmio[%d]", i
);
72 object_initialize_child(obj
, name
, &s
->virtio_mmio
[i
],
77 /* Input from goldfish PIC */
78 qdev_init_gpio_in_named(DEVICE(obj
), nubus_virtio_mmio_set_input_irq
,
82 static void nubus_virtio_mmio_class_init(ObjectClass
*oc
, void *data
)
84 DeviceClass
*dc
= DEVICE_CLASS(oc
);
85 NubusVirtioMMIODeviceClass
*nvmdc
= NUBUS_VIRTIO_MMIO_CLASS(oc
);
87 device_class_set_parent_realize(dc
, nubus_virtio_mmio_realize
,
88 &nvmdc
->parent_realize
);
91 static const TypeInfo nubus_virtio_mmio_types
[] = {
93 .name
= TYPE_NUBUS_VIRTIO_MMIO
,
94 .parent
= TYPE_NUBUS_DEVICE
,
95 .instance_init
= nubus_virtio_mmio_init
,
96 .instance_size
= sizeof(NubusVirtioMMIO
),
97 .class_init
= nubus_virtio_mmio_class_init
,
98 .class_size
= sizeof(NubusVirtioMMIODeviceClass
),
102 DEFINE_TYPES(nubus_virtio_mmio_types
)