]> git.proxmox.com Git - qemu.git/blobdiff - hw/display/tcx.c
sun4m: Add FCode ROM for TCX framebuffer
[qemu.git] / hw / display / tcx.c
index 995641c7452b48752a41048b0fdfca8c5190f166..873b82c8db81d0fa5fb6b0fc161fe9aa79bfade5 100644 (file)
 #include "qemu-common.h"
 #include "ui/console.h"
 #include "ui/pixel_ops.h"
+#include "hw/loader.h"
 #include "hw/sysbus.h"
 
+#define TCX_ROM_FILE "QEMU,tcx.bin"
+#define FCODE_MAX_ROM_SIZE 0x10000
+
 #define MAXX 1024
 #define MAXY 768
 #define TCX_DAC_NREGS 16
 #define TCX_THC_NREGS_24 0x1000
 #define TCX_TEC_NREGS    0x1000
 
+#define TYPE_TCX "SUNW,tcx"
+#define TCX(obj) OBJECT_CHECK(TCXState, (obj), TYPE_TCX)
+
 typedef struct TCXState {
-    SysBusDevice busdev;
+    SysBusDevice parent_obj;
+
     QemuConsole *con;
     uint8_t *vram;
     uint32_t *vram24, *cplane;
+    hwaddr prom_addr;
+    MemoryRegion rom;
     MemoryRegion vram_mem;
     MemoryRegion vram_8bit;
     MemoryRegion vram_24bit;
@@ -423,7 +433,7 @@ static const VMStateDescription vmstate_tcx = {
 
 static void tcx_reset(DeviceState *d)
 {
-    TCXState *s = container_of(d, TCXState, busdev.qdev);
+    TCXState *s = TCX(d);
 
     /* Initialize palette */
     memset(s->r, 0, 256);
@@ -523,34 +533,53 @@ static const GraphicHwOps tcx24_ops = {
 
 static int tcx_init1(SysBusDevice *dev)
 {
-    TCXState *s = FROM_SYSBUS(TCXState, dev);
+    TCXState *s = TCX(dev);
     ram_addr_t vram_offset = 0;
-    int size;
+    int size, ret;
     uint8_t *vram_base;
+    char *fcode_filename;
 
-    memory_region_init_ram(&s->vram_mem, "tcx.vram",
+    memory_region_init_ram(&s->vram_mem, OBJECT(s), "tcx.vram",
                            s->vram_size * (1 + 4 + 4));
     vmstate_register_ram_global(&s->vram_mem);
     vram_base = memory_region_get_ram_ptr(&s->vram_mem);
 
+    /* FCode ROM */
+    memory_region_init_ram(&s->rom, NULL, "tcx.prom", FCODE_MAX_ROM_SIZE);
+    vmstate_register_ram_global(&s->rom);
+    memory_region_set_readonly(&s->rom, true);
+    sysbus_init_mmio(dev, &s->rom);
+
+    fcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, TCX_ROM_FILE);
+    if (fcode_filename) {
+        ret = load_image_targphys(fcode_filename, s->prom_addr,
+                                  FCODE_MAX_ROM_SIZE);
+        if (ret < 0 || ret > FCODE_MAX_ROM_SIZE) {
+            fprintf(stderr, "tcx: could not load prom '%s'\n", TCX_ROM_FILE);
+            return -1;
+        }
+    }
+
     /* 8-bit plane */
     s->vram = vram_base;
     size = s->vram_size;
-    memory_region_init_alias(&s->vram_8bit, "tcx.vram.8bit",
+    memory_region_init_alias(&s->vram_8bit, OBJECT(s), "tcx.vram.8bit",
                              &s->vram_mem, vram_offset, size);
     sysbus_init_mmio(dev, &s->vram_8bit);
     vram_offset += size;
     vram_base += size;
 
     /* DAC */
-    memory_region_init_io(&s->dac, &tcx_dac_ops, s, "tcx.dac", TCX_DAC_NREGS);
+    memory_region_init_io(&s->dac, OBJECT(s), &tcx_dac_ops, s,
+                          "tcx.dac", TCX_DAC_NREGS);
     sysbus_init_mmio(dev, &s->dac);
 
     /* TEC (dummy) */
-    memory_region_init_io(&s->tec, &dummy_ops, s, "tcx.tec", TCX_TEC_NREGS);
+    memory_region_init_io(&s->tec, OBJECT(s), &dummy_ops, s,
+                          "tcx.tec", TCX_TEC_NREGS);
     sysbus_init_mmio(dev, &s->tec);
     /* THC: NetBSD writes here even with 8-bit display: dummy */
-    memory_region_init_io(&s->thc24, &dummy_ops, s, "tcx.thc24",
+    memory_region_init_io(&s->thc24, OBJECT(s), &dummy_ops, s, "tcx.thc24",
                           TCX_THC_NREGS_24);
     sysbus_init_mmio(dev, &s->thc24);
 
@@ -559,7 +588,7 @@ static int tcx_init1(SysBusDevice *dev)
         size = s->vram_size * 4;
         s->vram24 = (uint32_t *)vram_base;
         s->vram24_offset = vram_offset;
-        memory_region_init_alias(&s->vram_24bit, "tcx.vram.24bit",
+        memory_region_init_alias(&s->vram_24bit, OBJECT(s), "tcx.vram.24bit",
                                  &s->vram_mem, vram_offset, size);
         sysbus_init_mmio(dev, &s->vram_24bit);
         vram_offset += size;
@@ -569,14 +598,14 @@ static int tcx_init1(SysBusDevice *dev)
         size = s->vram_size * 4;
         s->cplane = (uint32_t *)vram_base;
         s->cplane_offset = vram_offset;
-        memory_region_init_alias(&s->vram_cplane, "tcx.vram.cplane",
+        memory_region_init_alias(&s->vram_cplane, OBJECT(s), "tcx.vram.cplane",
                                  &s->vram_mem, vram_offset, size);
         sysbus_init_mmio(dev, &s->vram_cplane);
 
         s->con = graphic_console_init(DEVICE(dev), &tcx24_ops, s);
     } else {
         /* THC 8 bit (dummy) */
-        memory_region_init_io(&s->thc8, &dummy_ops, s, "tcx.thc8",
+        memory_region_init_io(&s->thc8, OBJECT(s), &dummy_ops, s, "tcx.thc8",
                               TCX_THC_NREGS_8);
         sysbus_init_mmio(dev, &s->thc8);
 
@@ -592,6 +621,7 @@ static Property tcx_properties[] = {
     DEFINE_PROP_UINT16("width",    TCXState, width,     -1),
     DEFINE_PROP_UINT16("height",   TCXState, height,    -1),
     DEFINE_PROP_UINT16("depth",    TCXState, depth,     -1),
+    DEFINE_PROP_HEX64("prom_addr", TCXState, prom_addr, -1),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -607,7 +637,7 @@ static void tcx_class_init(ObjectClass *klass, void *data)
 }
 
 static const TypeInfo tcx_info = {
-    .name          = "SUNW,tcx",
+    .name          = TYPE_TCX,
     .parent        = TYPE_SYS_BUS_DEVICE,
     .instance_size = sizeof(TCXState),
     .class_init    = tcx_class_init,