qemu/hw/nubus/nubus-device.c
<<
>>
Prefs
   1/*
   2 * QEMU Macintosh Nubus
   3 *
   4 * Copyright (c) 2013-2018 Laurent Vivier <laurent@vivier.eu>
   5 *
   6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
   7 * See the COPYING file in the top-level directory.
   8 *
   9 */
  10
  11#include "qemu/osdep.h"
  12#include "qemu/datadir.h"
  13#include "hw/irq.h"
  14#include "hw/loader.h"
  15#include "hw/nubus/nubus.h"
  16#include "qapi/error.h"
  17#include "qemu/error-report.h"
  18
  19
  20void nubus_set_irq(NubusDevice *nd, int level)
  21{
  22    NubusBus *nubus = NUBUS_BUS(qdev_get_parent_bus(DEVICE(nd)));
  23
  24    qemu_set_irq(nubus->irqs[nd->slot], level);
  25}
  26
  27static void nubus_device_realize(DeviceState *dev, Error **errp)
  28{
  29    NubusBus *nubus = NUBUS_BUS(qdev_get_parent_bus(dev));
  30    NubusDevice *nd = NUBUS_DEVICE(dev);
  31    char *name, *path;
  32    hwaddr slot_offset;
  33    int64_t size;
  34    int ret;
  35
  36    /* Super */
  37    slot_offset = nd->slot * NUBUS_SUPER_SLOT_SIZE;
  38
  39    name = g_strdup_printf("nubus-super-slot-%x", nd->slot);
  40    memory_region_init(&nd->super_slot_mem, OBJECT(dev), name,
  41                       NUBUS_SUPER_SLOT_SIZE);
  42    memory_region_add_subregion(&nubus->super_slot_io, slot_offset,
  43                                &nd->super_slot_mem);
  44    g_free(name);
  45
  46    /* Normal */
  47    slot_offset = nd->slot * NUBUS_SLOT_SIZE;
  48
  49    name = g_strdup_printf("nubus-slot-%x", nd->slot);
  50    memory_region_init(&nd->slot_mem, OBJECT(dev), name, NUBUS_SLOT_SIZE);
  51    memory_region_add_subregion(&nubus->slot_io, slot_offset,
  52                                &nd->slot_mem);
  53    g_free(name);
  54
  55    /* Declaration ROM */
  56    if (nd->romfile != NULL) {
  57        path = qemu_find_file(QEMU_FILE_TYPE_BIOS, nd->romfile);
  58        if (path == NULL) {
  59            path = g_strdup(nd->romfile);
  60        }
  61
  62        size = get_image_size(path);
  63        if (size < 0) {
  64            error_setg(errp, "failed to find romfile \"%s\"", nd->romfile);
  65            g_free(path);
  66            return;
  67        } else if (size == 0) {
  68            error_setg(errp, "romfile \"%s\" is empty", nd->romfile);
  69            g_free(path);
  70            return;
  71        } else if (size > NUBUS_DECL_ROM_MAX_SIZE) {
  72            error_setg(errp, "romfile \"%s\" too large (maximum size 128K)",
  73                       nd->romfile);
  74            g_free(path);
  75            return;
  76        }
  77
  78        name = g_strdup_printf("nubus-slot-%x-declaration-rom", nd->slot);
  79        memory_region_init_rom(&nd->decl_rom, OBJECT(dev), name, size,
  80                               &error_abort);
  81        ret = load_image_mr(path, &nd->decl_rom);
  82        g_free(path);
  83        if (ret < 0) {
  84            error_setg(errp, "could not load romfile \"%s\"", nd->romfile);
  85            return;
  86        }
  87        memory_region_add_subregion(&nd->slot_mem, NUBUS_SLOT_SIZE - size,
  88                                    &nd->decl_rom);
  89    }
  90}
  91
  92static Property nubus_device_properties[] = {
  93    DEFINE_PROP_INT32("slot", NubusDevice, slot, -1),
  94    DEFINE_PROP_STRING("romfile", NubusDevice, romfile),
  95    DEFINE_PROP_END_OF_LIST()
  96};
  97
  98static void nubus_device_class_init(ObjectClass *oc, void *data)
  99{
 100    DeviceClass *dc = DEVICE_CLASS(oc);
 101
 102    dc->realize = nubus_device_realize;
 103    dc->bus_type = TYPE_NUBUS_BUS;
 104    device_class_set_props(dc, nubus_device_properties);
 105}
 106
 107static const TypeInfo nubus_device_type_info = {
 108    .name = TYPE_NUBUS_DEVICE,
 109    .parent = TYPE_DEVICE,
 110    .abstract = true,
 111    .instance_size = sizeof(NubusDevice),
 112    .class_init = nubus_device_class_init,
 113};
 114
 115static void nubus_register_types(void)
 116{
 117    type_register_static(&nubus_device_type_info);
 118}
 119
 120type_init(nubus_register_types)
 121