xref: /openbmc/qemu/hw/nubus/nubus-virtio-mmio.c (revision 6410f877f5ed535acd01bbfaa4baec379e44d0ef)
131ae8bb1SMark Cave-Ayland /*
231ae8bb1SMark Cave-Ayland  * QEMU Macintosh Nubus Virtio MMIO card
331ae8bb1SMark Cave-Ayland  *
431ae8bb1SMark Cave-Ayland  * Copyright (c) 2024 Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
531ae8bb1SMark Cave-Ayland  *
631ae8bb1SMark Cave-Ayland  * SPDX-License-Identifier: GPL-2.0-or-later
731ae8bb1SMark Cave-Ayland  */
831ae8bb1SMark Cave-Ayland 
931ae8bb1SMark Cave-Ayland #include "qemu/osdep.h"
10*2f28f28eSZhao Liu #include "qapi/error.h"
1131ae8bb1SMark Cave-Ayland #include "hw/nubus/nubus-virtio-mmio.h"
1231ae8bb1SMark Cave-Ayland 
1331ae8bb1SMark Cave-Ayland 
1431ae8bb1SMark Cave-Ayland #define NUBUS_VIRTIO_MMIO_PIC_OFFSET   0
1531ae8bb1SMark Cave-Ayland #define NUBUS_VIRTIO_MMIO_DEV_OFFSET   0x200
1631ae8bb1SMark Cave-Ayland 
1731ae8bb1SMark Cave-Ayland 
nubus_virtio_mmio_set_input_irq(void * opaque,int n,int level)1831ae8bb1SMark Cave-Ayland static void nubus_virtio_mmio_set_input_irq(void *opaque, int n, int level)
1931ae8bb1SMark Cave-Ayland {
2031ae8bb1SMark Cave-Ayland     NubusDevice *nd = NUBUS_DEVICE(opaque);
2131ae8bb1SMark Cave-Ayland 
2231ae8bb1SMark Cave-Ayland     nubus_set_irq(nd, level);
2331ae8bb1SMark Cave-Ayland }
2431ae8bb1SMark Cave-Ayland 
nubus_virtio_mmio_realize(DeviceState * dev,Error ** errp)2531ae8bb1SMark Cave-Ayland static void nubus_virtio_mmio_realize(DeviceState *dev, Error **errp)
2631ae8bb1SMark Cave-Ayland {
27*2f28f28eSZhao Liu     ERRP_GUARD();
2831ae8bb1SMark Cave-Ayland     NubusVirtioMMIODeviceClass *nvmdc = NUBUS_VIRTIO_MMIO_GET_CLASS(dev);
2931ae8bb1SMark Cave-Ayland     NubusVirtioMMIO *s = NUBUS_VIRTIO_MMIO(dev);
3031ae8bb1SMark Cave-Ayland     NubusDevice *nd = NUBUS_DEVICE(dev);
3131ae8bb1SMark Cave-Ayland     SysBusDevice *sbd;
3231ae8bb1SMark Cave-Ayland     int i, offset;
3331ae8bb1SMark Cave-Ayland 
3431ae8bb1SMark Cave-Ayland     nvmdc->parent_realize(dev, errp);
3531ae8bb1SMark Cave-Ayland     if (*errp) {
3631ae8bb1SMark Cave-Ayland         return;
3731ae8bb1SMark Cave-Ayland     }
3831ae8bb1SMark Cave-Ayland 
3931ae8bb1SMark Cave-Ayland     /* Goldfish PIC */
4031ae8bb1SMark Cave-Ayland     sbd = SYS_BUS_DEVICE(&s->pic);
4131ae8bb1SMark Cave-Ayland     if (!sysbus_realize(sbd, errp)) {
4231ae8bb1SMark Cave-Ayland         return;
4331ae8bb1SMark Cave-Ayland     }
4431ae8bb1SMark Cave-Ayland     memory_region_add_subregion(&nd->slot_mem, NUBUS_VIRTIO_MMIO_PIC_OFFSET,
4531ae8bb1SMark Cave-Ayland                                 sysbus_mmio_get_region(sbd, 0));
4631ae8bb1SMark Cave-Ayland     sysbus_connect_irq(sbd, 0,
4731ae8bb1SMark Cave-Ayland                        qdev_get_gpio_in_named(dev, "pic-input-irq", 0));
4831ae8bb1SMark Cave-Ayland 
4931ae8bb1SMark Cave-Ayland     /* virtio-mmio devices */
5031ae8bb1SMark Cave-Ayland     offset = NUBUS_VIRTIO_MMIO_DEV_OFFSET;
5131ae8bb1SMark Cave-Ayland     for (i = 0; i < NUBUS_VIRTIO_MMIO_NUM_DEVICES; i++) {
5231ae8bb1SMark Cave-Ayland         sbd = SYS_BUS_DEVICE(&s->virtio_mmio[i]);
5331ae8bb1SMark Cave-Ayland         qdev_prop_set_bit(DEVICE(sbd), "force-legacy", false);
5431ae8bb1SMark Cave-Ayland         if (!sysbus_realize_and_unref(sbd, errp)) {
5531ae8bb1SMark Cave-Ayland             return;
5631ae8bb1SMark Cave-Ayland         }
5731ae8bb1SMark Cave-Ayland 
5831ae8bb1SMark Cave-Ayland         memory_region_add_subregion(&nd->slot_mem, offset,
5931ae8bb1SMark Cave-Ayland                                     sysbus_mmio_get_region(sbd, 0));
6031ae8bb1SMark Cave-Ayland         offset += 0x200;
6131ae8bb1SMark Cave-Ayland 
6231ae8bb1SMark Cave-Ayland         sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(DEVICE(&s->pic), i));
6331ae8bb1SMark Cave-Ayland     }
6431ae8bb1SMark Cave-Ayland }
6531ae8bb1SMark Cave-Ayland 
nubus_virtio_mmio_init(Object * obj)6631ae8bb1SMark Cave-Ayland static void nubus_virtio_mmio_init(Object *obj)
6731ae8bb1SMark Cave-Ayland {
6831ae8bb1SMark Cave-Ayland     NubusVirtioMMIO *s = NUBUS_VIRTIO_MMIO(obj);
6931ae8bb1SMark Cave-Ayland     int i;
7031ae8bb1SMark Cave-Ayland 
7131ae8bb1SMark Cave-Ayland     object_initialize_child(obj, "pic", &s->pic, TYPE_GOLDFISH_PIC);
7231ae8bb1SMark Cave-Ayland     for (i = 0; i < NUBUS_VIRTIO_MMIO_NUM_DEVICES; i++) {
7331ae8bb1SMark Cave-Ayland         char *name = g_strdup_printf("virtio-mmio[%d]", i);
7431ae8bb1SMark Cave-Ayland         object_initialize_child(obj, name, &s->virtio_mmio[i],
7531ae8bb1SMark Cave-Ayland                                 TYPE_VIRTIO_MMIO);
7631ae8bb1SMark Cave-Ayland         g_free(name);
7731ae8bb1SMark Cave-Ayland     }
7831ae8bb1SMark Cave-Ayland 
7931ae8bb1SMark Cave-Ayland     /* Input from goldfish PIC */
8031ae8bb1SMark Cave-Ayland     qdev_init_gpio_in_named(DEVICE(obj), nubus_virtio_mmio_set_input_irq,
8131ae8bb1SMark Cave-Ayland                             "pic-input-irq", 1);
8231ae8bb1SMark Cave-Ayland }
8331ae8bb1SMark Cave-Ayland 
nubus_virtio_mmio_class_init(ObjectClass * oc,void * data)8431ae8bb1SMark Cave-Ayland static void nubus_virtio_mmio_class_init(ObjectClass *oc, void *data)
8531ae8bb1SMark Cave-Ayland {
8631ae8bb1SMark Cave-Ayland     DeviceClass *dc = DEVICE_CLASS(oc);
8731ae8bb1SMark Cave-Ayland     NubusVirtioMMIODeviceClass *nvmdc = NUBUS_VIRTIO_MMIO_CLASS(oc);
8831ae8bb1SMark Cave-Ayland 
8931ae8bb1SMark Cave-Ayland     device_class_set_parent_realize(dc, nubus_virtio_mmio_realize,
9031ae8bb1SMark Cave-Ayland                                     &nvmdc->parent_realize);
9131ae8bb1SMark Cave-Ayland }
9231ae8bb1SMark Cave-Ayland 
9331ae8bb1SMark Cave-Ayland static const TypeInfo nubus_virtio_mmio_types[] = {
9431ae8bb1SMark Cave-Ayland     {
9531ae8bb1SMark Cave-Ayland         .name = TYPE_NUBUS_VIRTIO_MMIO,
9631ae8bb1SMark Cave-Ayland         .parent = TYPE_NUBUS_DEVICE,
9731ae8bb1SMark Cave-Ayland         .instance_init = nubus_virtio_mmio_init,
9831ae8bb1SMark Cave-Ayland         .instance_size = sizeof(NubusVirtioMMIO),
9931ae8bb1SMark Cave-Ayland         .class_init = nubus_virtio_mmio_class_init,
10031ae8bb1SMark Cave-Ayland         .class_size = sizeof(NubusVirtioMMIODeviceClass),
10131ae8bb1SMark Cave-Ayland     },
10231ae8bb1SMark Cave-Ayland };
10331ae8bb1SMark Cave-Ayland 
10431ae8bb1SMark Cave-Ayland DEFINE_TYPES(nubus_virtio_mmio_types)
105