--- sun4m.c.orig 2022-07-28 11:01:13.750981000 -0700 +++ sun4m.c 2022-07-28 11:16:34.912020000 -0700 @@ -658,6 +658,87 @@ .class_init = afx_class_init, }; +#define TYPE_DBRI "SUNW,DBRIe" +#define DBRI(obj) OBJECT_CHECK(DBRIState, (obj), TYPE_DBRI) + +typedef struct DBRIState { + SysBusDevice parent_obj; + + qemu_irq irq; + MemoryRegion rom; + MemoryRegion r1; +} DBRIState; + +static uint64_t dbri_readl(void *opaque, hwaddr addr, + unsigned size) +{ + return (0); +} + +static void dbri_writel(void *opaque, hwaddr addr, + uint64_t val, unsigned size) +{ + return; +} + +static const MemoryRegionOps dbri_ops = { + .read = dbri_readl, + .write = dbri_writel, + .endianness = DEVICE_NATIVE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, +}; + +static void dbri_realize(DeviceState *ds, Error **errp) +{ + DBRIState *s = DBRI(ds); + SysBusDevice *dev = SYS_BUS_DEVICE(ds); + Error *local_err = NULL; + + memory_region_init_ram_nomigrate(&s->rom, OBJECT(ds), "dbri.rom", + 0x1000, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + vmstate_register_ram_global(&s->rom); + memory_region_set_readonly(&s->rom, true); + + sysbus_init_mmio(dev, &s->rom); + + memory_region_init_io(&s->r1, OBJECT(ds), &dbri_ops, s, "dbri", 0x100); + + sysbus_init_mmio(dev, &s->r1); + + sysbus_init_irq(dev, &s->irq); + + return; +} + +static Property dbri_properties[] = { + {/* end of property list */}, +}; + +static void dbri_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + device_class_set_props (dc, dbri_properties); + dc->realize = dbri_realize; + + return; +} + +static const TypeInfo dbri_info = { + .name = TYPE_DBRI, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(DBRIState), + .class_init = dbri_class_init, +}; + #define TYPE_OPENPROM "openprom" typedef struct PROMState PROMState; DECLARE_INSTANCE_CHECKER(PROMState, OPENPROM, @@ -1029,13 +1110,30 @@ } if (hwdef->dbri_base) { + char *filename; + /* ISDN chip with attached CS4215 audio codec */ - /* prom space */ - create_unimplemented_device("sun-DBRI.prom", - hwdef->dbri_base + 0x1000, 0x30); + + dev = qdev_new(TYPE_DBRI); + s = SYS_BUS_DEVICE(dev); + sysbus_realize_and_unref(s, &error_fatal); + + /* + * prom space + * I'm a little confused by this. Supposedly the FCode should + * be at offset 0 from the device's base address, but for the + * DBRI device it seems we need to actually map the FCode at + * offset 0x1000. + */ + sysbus_mmio_map(s, 0, hwdef->dbri_base + 0x1000); /* reg space */ - create_unimplemented_device("sun-DBRI", - hwdef->dbri_base + 0x10000, 0x100); + sysbus_mmio_map(s, 1, hwdef->dbri_base + 0x10000); + + sysbus_connect_irq(s, 0, slavio_irq[11]); + + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "QEMU,dbri.bin"); + (void)rom_add_file_fixed (filename, hwdef->dbri_base + 0x1000, -1); + g_free(filename); } if (hwdef->bpp_base) { @@ -1487,6 +1585,7 @@ { type_register_static(&idreg_info); type_register_static(&afx_info); + type_register_static(&dbri_info); type_register_static(&prom_info); type_register_static(&ram_info); }