From 5d1fa7e412cb34b97ca924018ca8f357df9e7b29 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Sep 2021 08:37:49 +0100 Subject: nubus: add comment indicating reference documents MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Reviewed-by: Laurent Vivier Message-Id: <20210924073808.1041-2-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- hw/nubus/nubus-bus.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'hw') diff --git a/hw/nubus/nubus-bus.c b/hw/nubus/nubus-bus.c index 5c13452..f441080 100644 --- a/hw/nubus/nubus-bus.c +++ b/hw/nubus/nubus-bus.c @@ -8,6 +8,14 @@ * */ +/* + * References: + * Nubus Specification (TI) + * http://www.bitsavers.org/pdf/ti/nubus/2242825-0001_NuBus_Spec1983.pdf + * + * Designing Cards and Drivers for the Macintosh Family (Apple) + */ + #include "qemu/osdep.h" #include "hw/nubus/nubus.h" #include "qapi/error.h" -- cgit v1.1 From e2c49c0515f5995b267a9795d88733865d2d0ced Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Sep 2021 08:37:50 +0100 Subject: nubus-device: rename slot_nb variable to slot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is in preparation for creating a qdev property of the same name. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Laurent Vivier Message-Id: <20210924073808.1041-3-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- hw/nubus/nubus-device.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'hw') diff --git a/hw/nubus/nubus-device.c b/hw/nubus/nubus-device.c index ffe78a8..be01269 100644 --- a/hw/nubus/nubus-device.c +++ b/hw/nubus/nubus-device.c @@ -87,7 +87,7 @@ static void nubus_register_format_block(NubusDevice *dev) char *fblock_name; fblock_name = g_strdup_printf("nubus-slot-%d-format-block", - dev->slot_nb); + dev->slot); hwaddr fblock_offset = memory_region_size(&dev->slot_mem) - FBLOCK_SIZE; memory_region_init_io(&dev->fblock_io, NULL, &nubus_format_block_ops, @@ -142,7 +142,7 @@ void nubus_register_rom(NubusDevice *dev, const uint8_t *rom, uint32_t size, /* ROM */ dev->rom = rom; - rom_name = g_strdup_printf("nubus-slot-%d-rom", dev->slot_nb); + rom_name = g_strdup_printf("nubus-slot-%d-rom", dev->slot); memory_region_init_io(&dev->rom_io, NULL, &mac_nubus_rom_ops, dev, rom_name, size); memory_region_set_readonly(&dev->rom_io, true); @@ -167,12 +167,12 @@ static void nubus_device_realize(DeviceState *dev, Error **errp) return; } - nd->slot_nb = nubus->current_slot++; - name = g_strdup_printf("nubus-slot-%d", nd->slot_nb); + nd->slot = nubus->current_slot++; + name = g_strdup_printf("nubus-slot-%d", nd->slot); - if (nd->slot_nb < NUBUS_FIRST_SLOT) { + if (nd->slot < NUBUS_FIRST_SLOT) { /* Super */ - slot_offset = (nd->slot_nb - 6) * NUBUS_SUPER_SLOT_SIZE; + slot_offset = (nd->slot - 6) * NUBUS_SUPER_SLOT_SIZE; memory_region_init(&nd->slot_mem, OBJECT(dev), name, NUBUS_SUPER_SLOT_SIZE); @@ -180,7 +180,7 @@ static void nubus_device_realize(DeviceState *dev, Error **errp) &nd->slot_mem); } else { /* Normal */ - slot_offset = nd->slot_nb * NUBUS_SLOT_SIZE; + slot_offset = nd->slot * NUBUS_SLOT_SIZE; memory_region_init(&nd->slot_mem, OBJECT(dev), name, NUBUS_SLOT_SIZE); memory_region_add_subregion(&nubus->slot_io, slot_offset, -- cgit v1.1 From 90be1dea5017e518076f2a0d3ad26e158b92a1da Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Sep 2021 08:37:51 +0100 Subject: nubus-device: expose separate super slot memory region MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to "Designing Cards and Drivers for the Macintosh Family" each physical nubus slot can access 2 separate address ranges: a super slot memory region which is 256MB and a standard slot memory region which is 16MB. Currently a Nubus device uses the physical slot number to determine whether it is using a standard slot memory region or a super slot memory region rather than exposing both memory regions for use as required. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Laurent Vivier Message-Id: <20210924073808.1041-4-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- hw/nubus/nubus-device.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'hw') diff --git a/hw/nubus/nubus-device.c b/hw/nubus/nubus-device.c index be01269..4e23df1 100644 --- a/hw/nubus/nubus-device.c +++ b/hw/nubus/nubus-device.c @@ -168,26 +168,26 @@ static void nubus_device_realize(DeviceState *dev, Error **errp) } nd->slot = nubus->current_slot++; - name = g_strdup_printf("nubus-slot-%d", nd->slot); - - if (nd->slot < NUBUS_FIRST_SLOT) { - /* Super */ - slot_offset = (nd->slot - 6) * NUBUS_SUPER_SLOT_SIZE; - - memory_region_init(&nd->slot_mem, OBJECT(dev), name, - NUBUS_SUPER_SLOT_SIZE); - memory_region_add_subregion(&nubus->super_slot_io, slot_offset, - &nd->slot_mem); - } else { - /* Normal */ - slot_offset = nd->slot * NUBUS_SLOT_SIZE; - - memory_region_init(&nd->slot_mem, OBJECT(dev), name, NUBUS_SLOT_SIZE); - memory_region_add_subregion(&nubus->slot_io, slot_offset, - &nd->slot_mem); - } + /* Super */ + slot_offset = nd->slot * NUBUS_SUPER_SLOT_SIZE; + + name = g_strdup_printf("nubus-super-slot-%x", nd->slot); + memory_region_init(&nd->super_slot_mem, OBJECT(dev), name, + NUBUS_SUPER_SLOT_SIZE); + memory_region_add_subregion(&nubus->super_slot_io, slot_offset, + &nd->super_slot_mem); + g_free(name); + + /* Normal */ + slot_offset = nd->slot * NUBUS_SLOT_SIZE; + + name = g_strdup_printf("nubus-slot-%x", nd->slot); + memory_region_init(&nd->slot_mem, OBJECT(dev), name, NUBUS_SLOT_SIZE); + memory_region_add_subregion(&nubus->slot_io, slot_offset, + &nd->slot_mem); g_free(name); + nubus_register_format_block(nd); } -- cgit v1.1 From 03deab99401a57332d8f3bdba319a41eebc1d666 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Sep 2021 08:37:52 +0100 Subject: nubus: use bitmap to manage available slots MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Convert nubus_device_realize() to use a bitmap to manage available slots to allow for future Nubus devices to be plugged into arbitrary slots from the command line using a new qdev "slot" parameter for nubus devices. Update mac_nubus_bridge_init() to only allow slots 0x9 to 0xe on Macintosh machines as documented in "Designing Cards and Drivers for the Macintosh Family". Signed-off-by: Mark Cave-Ayland Reviewed-by: Laurent Vivier Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20210924073808.1041-5-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- hw/nubus/mac-nubus-bridge.c | 4 ++++ hw/nubus/nubus-bus.c | 5 +++-- hw/nubus/nubus-device.c | 29 ++++++++++++++++++++++++----- 3 files changed, 31 insertions(+), 7 deletions(-) (limited to 'hw') diff --git a/hw/nubus/mac-nubus-bridge.c b/hw/nubus/mac-nubus-bridge.c index 7c32930..3f07578 100644 --- a/hw/nubus/mac-nubus-bridge.c +++ b/hw/nubus/mac-nubus-bridge.c @@ -18,6 +18,10 @@ static void mac_nubus_bridge_init(Object *obj) s->bus = NUBUS_BUS(qbus_create(TYPE_NUBUS_BUS, DEVICE(s), NULL)); + /* Macintosh only has slots 0x9 to 0xe available */ + s->bus->slot_available_mask = MAKE_64BIT_MASK(MAC_NUBUS_FIRST_SLOT, + MAC_NUBUS_SLOT_NB); + sysbus_init_mmio(sbd, &s->bus->super_slot_io); sysbus_init_mmio(sbd, &s->bus->slot_io); } diff --git a/hw/nubus/nubus-bus.c b/hw/nubus/nubus-bus.c index f441080..3cd7534 100644 --- a/hw/nubus/nubus-bus.c +++ b/hw/nubus/nubus-bus.c @@ -86,13 +86,14 @@ static void nubus_init(Object *obj) memory_region_init_io(&nubus->super_slot_io, obj, &nubus_super_slot_ops, nubus, "nubus-super-slots", - NUBUS_SUPER_SLOT_NB * NUBUS_SUPER_SLOT_SIZE); + (NUBUS_SUPER_SLOT_NB + 1) * NUBUS_SUPER_SLOT_SIZE); memory_region_init_io(&nubus->slot_io, obj, &nubus_slot_ops, nubus, "nubus-slots", NUBUS_SLOT_NB * NUBUS_SLOT_SIZE); - nubus->current_slot = NUBUS_FIRST_SLOT; + nubus->slot_available_mask = MAKE_64BIT_MASK(NUBUS_FIRST_SLOT, + NUBUS_SLOT_NB); } static void nubus_class_init(ObjectClass *oc, void *data) diff --git a/hw/nubus/nubus-device.c b/hw/nubus/nubus-device.c index 4e23df1..2e96d6b 100644 --- a/hw/nubus/nubus-device.c +++ b/hw/nubus/nubus-device.c @@ -161,13 +161,26 @@ static void nubus_device_realize(DeviceState *dev, Error **errp) char *name; hwaddr slot_offset; - if (nubus->current_slot < NUBUS_FIRST_SLOT || - nubus->current_slot > NUBUS_LAST_SLOT) { - error_setg(errp, "Cannot register nubus card, not enough slots"); - return; + if (nd->slot == -1) { + /* No slot specified, find first available free slot */ + int s = ctz32(nubus->slot_available_mask); + if (s != 32) { + nd->slot = s; + } else { + error_setg(errp, "Cannot register nubus card, no free slot " + "available"); + return; + } + } else { + /* Slot specified, make sure the slot is available */ + if (!(nubus->slot_available_mask & BIT(nd->slot))) { + error_setg(errp, "Cannot register nubus card, slot %d is " + "unavailable or already occupied", nd->slot); + return; + } } - nd->slot = nubus->current_slot++; + nubus->slot_available_mask &= ~BIT(nd->slot); /* Super */ slot_offset = nd->slot * NUBUS_SUPER_SLOT_SIZE; @@ -191,12 +204,18 @@ static void nubus_device_realize(DeviceState *dev, Error **errp) nubus_register_format_block(nd); } +static Property nubus_device_properties[] = { + DEFINE_PROP_INT32("slot", NubusDevice, slot, -1), + DEFINE_PROP_END_OF_LIST() +}; + static void nubus_device_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); dc->realize = nubus_device_realize; dc->bus_type = TYPE_NUBUS_BUS; + device_class_set_props(dc, nubus_device_properties); } static const TypeInfo nubus_device_type_info = { -- cgit v1.1 From c10a576c19665a617ce00cb93afd115142b6a7af Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Sep 2021 08:37:53 +0100 Subject: nubus: move slot bitmap checks from NubusDevice realize() to BusClass check_address() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allow Nubus to manage the slot allocations itself using the BusClass check_address() virtual function rather than managing this during NubusDevice realize(). Signed-off-by: Mark Cave-Ayland Reviewed-by: Laurent Vivier Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20210924073808.1041-6-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- hw/nubus/nubus-bus.c | 29 +++++++++++++++++++++++++++++ hw/nubus/nubus-device.c | 21 --------------------- 2 files changed, 29 insertions(+), 21 deletions(-) (limited to 'hw') diff --git a/hw/nubus/nubus-bus.c b/hw/nubus/nubus-bus.c index 3cd7534..96ef027 100644 --- a/hw/nubus/nubus-bus.c +++ b/hw/nubus/nubus-bus.c @@ -96,11 +96,40 @@ static void nubus_init(Object *obj) NUBUS_SLOT_NB); } +static bool nubus_check_address(BusState *bus, DeviceState *dev, Error **errp) +{ + NubusDevice *nd = NUBUS_DEVICE(dev); + NubusBus *nubus = NUBUS_BUS(bus); + + if (nd->slot == -1) { + /* No slot specified, find first available free slot */ + int s = ctz32(nubus->slot_available_mask); + if (s != 32) { + nd->slot = s; + } else { + error_setg(errp, "Cannot register nubus card, no free slot " + "available"); + return false; + } + } else { + /* Slot specified, make sure the slot is available */ + if (!(nubus->slot_available_mask & BIT(nd->slot))) { + error_setg(errp, "Cannot register nubus card, slot %d is " + "unavailable or already occupied", nd->slot); + return false; + } + } + + nubus->slot_available_mask &= ~BIT(nd->slot); + return true; +} + static void nubus_class_init(ObjectClass *oc, void *data) { BusClass *bc = BUS_CLASS(oc); bc->realize = nubus_realize; + bc->check_address = nubus_check_address; } static const TypeInfo nubus_bus_info = { diff --git a/hw/nubus/nubus-device.c b/hw/nubus/nubus-device.c index 2e96d6b..516b13d 100644 --- a/hw/nubus/nubus-device.c +++ b/hw/nubus/nubus-device.c @@ -161,27 +161,6 @@ static void nubus_device_realize(DeviceState *dev, Error **errp) char *name; hwaddr slot_offset; - if (nd->slot == -1) { - /* No slot specified, find first available free slot */ - int s = ctz32(nubus->slot_available_mask); - if (s != 32) { - nd->slot = s; - } else { - error_setg(errp, "Cannot register nubus card, no free slot " - "available"); - return; - } - } else { - /* Slot specified, make sure the slot is available */ - if (!(nubus->slot_available_mask & BIT(nd->slot))) { - error_setg(errp, "Cannot register nubus card, slot %d is " - "unavailable or already occupied", nd->slot); - return; - } - } - - nubus->slot_available_mask &= ~BIT(nd->slot); - /* Super */ slot_offset = nd->slot * NUBUS_SUPER_SLOT_SIZE; -- cgit v1.1 From c0ad4eaf44d9aea4c2872e00bab5b36d05c9e0d6 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Sep 2021 08:37:54 +0100 Subject: nubus: implement BusClass get_dev_path() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Laurent Vivier Message-Id: <20210924073808.1041-7-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- hw/nubus/nubus-bus.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'hw') diff --git a/hw/nubus/nubus-bus.c b/hw/nubus/nubus-bus.c index 96ef027..04f11ed 100644 --- a/hw/nubus/nubus-bus.c +++ b/hw/nubus/nubus-bus.c @@ -96,6 +96,21 @@ static void nubus_init(Object *obj) NUBUS_SLOT_NB); } +static char *nubus_get_dev_path(DeviceState *dev) +{ + NubusDevice *nd = NUBUS_DEVICE(dev); + BusState *bus = qdev_get_parent_bus(dev); + char *p = qdev_get_dev_path(bus->parent); + + if (p) { + char *ret = g_strdup_printf("%s/%s/%02x", p, bus->name, nd->slot); + g_free(p); + return ret; + } else { + return g_strdup_printf("%s/%02x", bus->name, nd->slot); + } +} + static bool nubus_check_address(BusState *bus, DeviceState *dev, Error **errp) { NubusDevice *nd = NUBUS_DEVICE(dev); @@ -130,6 +145,7 @@ static void nubus_class_init(ObjectClass *oc, void *data) bc->realize = nubus_realize; bc->check_address = nubus_check_address; + bc->get_dev_path = nubus_get_dev_path; } static const TypeInfo nubus_bus_info = { -- cgit v1.1 From ce0e6a2c55b13c16de4a7985c0ca41835420430a Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Sep 2021 08:37:55 +0100 Subject: nubus: add trace-events for empty slot accesses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Increase the max_access_size to 4 bytes for empty Nubus slot and super slot accesses to allow tracing of the Nubus enumeration process by the guest OS. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Laurent Vivier Message-Id: <20210924073808.1041-8-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- hw/nubus/nubus-bus.c | 10 +++++++--- hw/nubus/trace-events | 7 +++++++ hw/nubus/trace.h | 1 + 3 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 hw/nubus/trace-events create mode 100644 hw/nubus/trace.h (limited to 'hw') diff --git a/hw/nubus/nubus-bus.c b/hw/nubus/nubus-bus.c index 04f11ed..a9fb6de 100644 --- a/hw/nubus/nubus-bus.c +++ b/hw/nubus/nubus-bus.c @@ -19,6 +19,7 @@ #include "qemu/osdep.h" #include "hw/nubus/nubus.h" #include "qapi/error.h" +#include "trace.h" static NubusBus *nubus_find(void) @@ -31,12 +32,13 @@ static void nubus_slot_write(void *opaque, hwaddr addr, uint64_t val, unsigned int size) { /* read only */ + trace_nubus_slot_write(addr, val, size); } - static uint64_t nubus_slot_read(void *opaque, hwaddr addr, unsigned int size) { + trace_nubus_slot_read(addr, size); return 0; } @@ -46,7 +48,7 @@ static const MemoryRegionOps nubus_slot_ops = { .endianness = DEVICE_BIG_ENDIAN, .valid = { .min_access_size = 1, - .max_access_size = 1, + .max_access_size = 4, }, }; @@ -54,11 +56,13 @@ static void nubus_super_slot_write(void *opaque, hwaddr addr, uint64_t val, unsigned int size) { /* read only */ + trace_nubus_super_slot_write(addr, val, size); } static uint64_t nubus_super_slot_read(void *opaque, hwaddr addr, unsigned int size) { + trace_nubus_super_slot_read(addr, size); return 0; } @@ -68,7 +72,7 @@ static const MemoryRegionOps nubus_super_slot_ops = { .endianness = DEVICE_BIG_ENDIAN, .valid = { .min_access_size = 1, - .max_access_size = 1, + .max_access_size = 4, }, }; diff --git a/hw/nubus/trace-events b/hw/nubus/trace-events new file mode 100644 index 0000000..e31833d --- /dev/null +++ b/hw/nubus/trace-events @@ -0,0 +1,7 @@ +# See docs/devel/tracing.txt for syntax documentation. + +# nubus-bus.c +nubus_slot_read(uint64_t addr, int size) "reading unassigned addr 0x%"PRIx64 " size %d" +nubus_slot_write(uint64_t addr, uint64_t val, int size) "writing unassigned addr 0x%"PRIx64 " value 0x%"PRIx64 " size %d" +nubus_super_slot_read(uint64_t addr, int size) "reading unassigned addr 0x%"PRIx64 " size %d" +nubus_super_slot_write(uint64_t addr, uint64_t val, int size) "writing unassigned addr 0x%"PRIx64 " value 0x%"PRIx64 " size %d" diff --git a/hw/nubus/trace.h b/hw/nubus/trace.h new file mode 100644 index 0000000..3749420 --- /dev/null +++ b/hw/nubus/trace.h @@ -0,0 +1 @@ +#include "trace/trace-hw_nubus.h" -- cgit v1.1 From 1d3d62dff8f069c379123690a30817d7aa575cae Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Sep 2021 08:37:56 +0100 Subject: nubus: generate bus error when attempting to access empty slots MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to "Designing Cards and Drivers for the Macintosh Family" any attempt to access an unimplemented address location on Nubus generates a bus error. MacOS uses a custom bus error handler to detect empty Nubus slots, and with the current implementation assumes that all slots are occupied as the Nubus transactions never fail. Switch nubus_slot_ops and nubus_super_slot_ops over to use {read,write}_with_attrs and hard-code them to return MEMTX_DECODE_ERROR so that unoccupied Nubus slots will generate the expected bus error. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Laurent Vivier Message-Id: <20210924073808.1041-9-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- hw/nubus/nubus-bus.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'hw') diff --git a/hw/nubus/nubus-bus.c b/hw/nubus/nubus-bus.c index a9fb6de..215fdb6 100644 --- a/hw/nubus/nubus-bus.c +++ b/hw/nubus/nubus-bus.c @@ -28,23 +28,23 @@ static NubusBus *nubus_find(void) return NUBUS_BUS(object_resolve_path_type("", TYPE_NUBUS_BUS, NULL)); } -static void nubus_slot_write(void *opaque, hwaddr addr, uint64_t val, - unsigned int size) +static MemTxResult nubus_slot_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size, MemTxAttrs attrs) { - /* read only */ trace_nubus_slot_write(addr, val, size); + return MEMTX_DECODE_ERROR; } -static uint64_t nubus_slot_read(void *opaque, hwaddr addr, - unsigned int size) +static MemTxResult nubus_slot_read(void *opaque, hwaddr addr, uint64_t *data, + unsigned size, MemTxAttrs attrs) { trace_nubus_slot_read(addr, size); - return 0; + return MEMTX_DECODE_ERROR; } static const MemoryRegionOps nubus_slot_ops = { - .read = nubus_slot_read, - .write = nubus_slot_write, + .read_with_attrs = nubus_slot_read, + .write_with_attrs = nubus_slot_write, .endianness = DEVICE_BIG_ENDIAN, .valid = { .min_access_size = 1, @@ -52,23 +52,25 @@ static const MemoryRegionOps nubus_slot_ops = { }, }; -static void nubus_super_slot_write(void *opaque, hwaddr addr, uint64_t val, - unsigned int size) +static MemTxResult nubus_super_slot_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size, + MemTxAttrs attrs) { - /* read only */ trace_nubus_super_slot_write(addr, val, size); + return MEMTX_DECODE_ERROR; } -static uint64_t nubus_super_slot_read(void *opaque, hwaddr addr, - unsigned int size) +static MemTxResult nubus_super_slot_read(void *opaque, hwaddr addr, + uint64_t *data, unsigned size, + MemTxAttrs attrs) { trace_nubus_super_slot_read(addr, size); - return 0; + return MEMTX_DECODE_ERROR; } static const MemoryRegionOps nubus_super_slot_ops = { - .read = nubus_super_slot_read, - .write = nubus_super_slot_write, + .read_with_attrs = nubus_super_slot_read, + .write_with_attrs = nubus_super_slot_write, .endianness = DEVICE_BIG_ENDIAN, .valid = { .min_access_size = 1, -- cgit v1.1 From e0591bf1a56fa59b787870fbdd4e5d7ca8d745d2 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Sep 2021 08:37:57 +0100 Subject: macfb: don't register declaration ROM The macfb device is an on-board framebuffer and so is initialised by the system declaration ROM included within the MacOS toolbox ROM. Signed-off-by: Mark Cave-Ayland Reviewed-by: Laurent Vivier Message-Id: <20210924073808.1041-10-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- hw/display/macfb.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'hw') diff --git a/hw/display/macfb.c b/hw/display/macfb.c index d8183b9..76808b6 100644 --- a/hw/display/macfb.c +++ b/hw/display/macfb.c @@ -383,10 +383,6 @@ static void macfb_sysbus_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(SYS_BUS_DEVICE(s), &ms->mem_vram); } -const uint8_t macfb_rom[] = { - 255, 0, 0, 0, -}; - static void macfb_nubus_realize(DeviceState *dev, Error **errp) { NubusDevice *nd = NUBUS_DEVICE(dev); @@ -399,8 +395,6 @@ static void macfb_nubus_realize(DeviceState *dev, Error **errp) macfb_common_realize(dev, ms, errp); memory_region_add_subregion(&nd->slot_mem, DAFB_BASE, &ms->mem_ctrl); memory_region_add_subregion(&nd->slot_mem, VIDEO_BASE, &ms->mem_vram); - - nubus_register_rom(nd, macfb_rom, sizeof(macfb_rom), 1, 9, 0xf); } static void macfb_sysbus_reset(DeviceState *d) -- cgit v1.1 From 2469dc1dda596b13b4a8c7ed7f03d5991fa61b43 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Sep 2021 08:37:58 +0100 Subject: nubus-device: remove nubus_register_rom() and nubus_register_format_block() Since there is no need to generate a dummy declaration ROM, remove both nubus_register_rom() and nubus_register_format_block(). These will shortly be replaced with a mechanism to optionally load a declaration ROM from disk to allow real images to be used within QEMU. Signed-off-by: Mark Cave-Ayland Reviewed-by: Laurent Vivier Message-Id: <20210924073808.1041-11-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- hw/nubus/nubus-device.c | 143 ------------------------------------------------ 1 file changed, 143 deletions(-) (limited to 'hw') diff --git a/hw/nubus/nubus-device.c b/hw/nubus/nubus-device.c index 516b13d..d4932d6 100644 --- a/hw/nubus/nubus-device.c +++ b/hw/nubus/nubus-device.c @@ -13,147 +13,6 @@ #include "qapi/error.h" -/* The Format Block Structure */ - -#define FBLOCK_DIRECTORY_OFFSET 0 -#define FBLOCK_LENGTH 4 -#define FBLOCK_CRC 8 -#define FBLOCK_REVISION_LEVEL 12 -#define FBLOCK_FORMAT 13 -#define FBLOCK_TEST_PATTERN 14 -#define FBLOCK_RESERVED 18 -#define FBLOCK_BYTE_LANES 19 - -#define FBLOCK_SIZE 20 -#define FBLOCK_PATTERN_VAL 0x5a932bc7 - -static uint64_t nubus_fblock_read(void *opaque, hwaddr addr, unsigned int size) -{ - NubusDevice *dev = opaque; - uint64_t val; - -#define BYTE(v, b) (((v) >> (24 - 8 * (b))) & 0xff) - switch (addr) { - case FBLOCK_BYTE_LANES: - val = dev->byte_lanes; - val |= (val ^ 0xf) << 4; - break; - case FBLOCK_RESERVED: - val = 0x00; - break; - case FBLOCK_TEST_PATTERN...FBLOCK_TEST_PATTERN + 3: - val = BYTE(FBLOCK_PATTERN_VAL, addr - FBLOCK_TEST_PATTERN); - break; - case FBLOCK_FORMAT: - val = dev->rom_format; - break; - case FBLOCK_REVISION_LEVEL: - val = dev->rom_rev; - break; - case FBLOCK_CRC...FBLOCK_CRC + 3: - val = BYTE(dev->rom_crc, addr - FBLOCK_CRC); - break; - case FBLOCK_LENGTH...FBLOCK_LENGTH + 3: - val = BYTE(dev->rom_length, addr - FBLOCK_LENGTH); - break; - case FBLOCK_DIRECTORY_OFFSET...FBLOCK_DIRECTORY_OFFSET + 3: - val = BYTE(dev->directory_offset, addr - FBLOCK_DIRECTORY_OFFSET); - break; - default: - val = 0; - break; - } - return val; -} - -static void nubus_fblock_write(void *opaque, hwaddr addr, uint64_t val, - unsigned int size) -{ - /* read only */ -} - -static const MemoryRegionOps nubus_format_block_ops = { - .read = nubus_fblock_read, - .write = nubus_fblock_write, - .endianness = DEVICE_BIG_ENDIAN, - .valid = { - .min_access_size = 1, - .max_access_size = 1, - } -}; - -static void nubus_register_format_block(NubusDevice *dev) -{ - char *fblock_name; - - fblock_name = g_strdup_printf("nubus-slot-%d-format-block", - dev->slot); - - hwaddr fblock_offset = memory_region_size(&dev->slot_mem) - FBLOCK_SIZE; - memory_region_init_io(&dev->fblock_io, NULL, &nubus_format_block_ops, - dev, fblock_name, FBLOCK_SIZE); - memory_region_add_subregion(&dev->slot_mem, fblock_offset, - &dev->fblock_io); - - g_free(fblock_name); -} - -static void mac_nubus_rom_write(void *opaque, hwaddr addr, uint64_t val, - unsigned int size) -{ - /* read only */ -} - -static uint64_t mac_nubus_rom_read(void *opaque, hwaddr addr, - unsigned int size) -{ - NubusDevice *dev = opaque; - - return dev->rom[addr]; -} - -static const MemoryRegionOps mac_nubus_rom_ops = { - .read = mac_nubus_rom_read, - .write = mac_nubus_rom_write, - .endianness = DEVICE_BIG_ENDIAN, - .valid = { - .min_access_size = 1, - .max_access_size = 1, - }, -}; - - -void nubus_register_rom(NubusDevice *dev, const uint8_t *rom, uint32_t size, - int revision, int format, uint8_t byte_lanes) -{ - hwaddr rom_offset; - char *rom_name; - - /* FIXME : really compute CRC */ - dev->rom_length = 0; - dev->rom_crc = 0; - - dev->rom_rev = revision; - dev->rom_format = format; - - dev->byte_lanes = byte_lanes; - dev->directory_offset = -size; - - /* ROM */ - - dev->rom = rom; - rom_name = g_strdup_printf("nubus-slot-%d-rom", dev->slot); - memory_region_init_io(&dev->rom_io, NULL, &mac_nubus_rom_ops, - dev, rom_name, size); - memory_region_set_readonly(&dev->rom_io, true); - - rom_offset = memory_region_size(&dev->slot_mem) - FBLOCK_SIZE + - dev->directory_offset; - memory_region_add_subregion(&dev->slot_mem, rom_offset, &dev->rom_io); - - g_free(rom_name); -} - static void nubus_device_realize(DeviceState *dev, Error **errp) { NubusBus *nubus = NUBUS_BUS(qdev_get_parent_bus(dev)); @@ -179,8 +38,6 @@ static void nubus_device_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(&nubus->slot_io, slot_offset, &nd->slot_mem); g_free(name); - - nubus_register_format_block(nd); } static Property nubus_device_properties[] = { -- cgit v1.1 From 3616f424c911f1b52629cea1fec6ef99e9da07ad Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Sep 2021 08:37:59 +0100 Subject: nubus-device: add romfile property for loading declaration ROMs The declaration ROM is located at the top-most address of the standard slot space. Signed-off-by: Mark Cave-Ayland Reviewed-by: Laurent Vivier Message-Id: <20210924073808.1041-12-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- hw/nubus/nubus-device.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'hw') diff --git a/hw/nubus/nubus-device.c b/hw/nubus/nubus-device.c index d4932d6..280f40e 100644 --- a/hw/nubus/nubus-device.c +++ b/hw/nubus/nubus-device.c @@ -9,16 +9,21 @@ */ #include "qemu/osdep.h" +#include "qemu/datadir.h" +#include "hw/loader.h" #include "hw/nubus/nubus.h" #include "qapi/error.h" +#include "qemu/error-report.h" static void nubus_device_realize(DeviceState *dev, Error **errp) { NubusBus *nubus = NUBUS_BUS(qdev_get_parent_bus(dev)); NubusDevice *nd = NUBUS_DEVICE(dev); - char *name; + char *name, *path; hwaddr slot_offset; + int64_t size; + int ret; /* Super */ slot_offset = nd->slot * NUBUS_SUPER_SLOT_SIZE; @@ -38,10 +43,47 @@ static void nubus_device_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(&nubus->slot_io, slot_offset, &nd->slot_mem); g_free(name); + + /* Declaration ROM */ + if (nd->romfile != NULL) { + path = qemu_find_file(QEMU_FILE_TYPE_BIOS, nd->romfile); + if (path == NULL) { + path = g_strdup(nd->romfile); + } + + size = get_image_size(path); + if (size < 0) { + error_setg(errp, "failed to find romfile \"%s\"", nd->romfile); + g_free(path); + return; + } else if (size == 0) { + error_setg(errp, "romfile \"%s\" is empty", nd->romfile); + g_free(path); + return; + } else if (size > NUBUS_DECL_ROM_MAX_SIZE) { + error_setg(errp, "romfile \"%s\" too large (maximum size 128K)", + nd->romfile); + g_free(path); + return; + } + + name = g_strdup_printf("nubus-slot-%x-declaration-rom", nd->slot); + memory_region_init_rom(&nd->decl_rom, OBJECT(dev), name, size, + &error_abort); + ret = load_image_mr(path, &nd->decl_rom); + g_free(path); + if (ret < 0) { + error_setg(errp, "could not load romfile \"%s\"", nd->romfile); + return; + } + memory_region_add_subregion(&nd->slot_mem, NUBUS_SLOT_SIZE - size, + &nd->decl_rom); + } } static Property nubus_device_properties[] = { DEFINE_PROP_INT32("slot", NubusDevice, slot, -1), + DEFINE_PROP_STRING("romfile", NubusDevice, romfile), DEFINE_PROP_END_OF_LIST() }; -- cgit v1.1 From 62437f90cf90d1a0fda855f17ca6d9e7c0204f92 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Sep 2021 08:38:00 +0100 Subject: nubus: move nubus to its own 32-bit address space MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to "Designing Cards and Drivers for the Macintosh Family" the Nubus has its own 32-bit address space based upon physical slot addressing. Move Nubus to its own 32-bit address space and then use memory region aliases to map available slot and super slot ranges into the q800 system address space via the Macintosh Nubus bridge. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Laurent Vivier Message-Id: <20210924073808.1041-13-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- hw/m68k/q800.c | 9 ++++----- hw/nubus/mac-nubus-bridge.c | 16 ++++++++++++++-- hw/nubus/nubus-bus.c | 18 ++++++++++++++++++ 3 files changed, 36 insertions(+), 7 deletions(-) (limited to 'hw') diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index 5ba87f7..a07912b 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -67,9 +67,6 @@ #define ASC_BASE (IO_BASE + 0x14000) #define SWIM_BASE (IO_BASE + 0x1E000) -#define NUBUS_SUPER_SLOT_BASE 0x60000000 -#define NUBUS_SLOT_BASE 0xf0000000 - #define SONIC_PROM_SIZE 0x1000 /* @@ -396,8 +393,10 @@ static void q800_init(MachineState *machine) dev = qdev_new(TYPE_MAC_NUBUS_BRIDGE); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, NUBUS_SUPER_SLOT_BASE); - sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, NUBUS_SLOT_BASE); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, + MAC_NUBUS_FIRST_SLOT * NUBUS_SUPER_SLOT_SIZE); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, NUBUS_SLOT_BASE + + MAC_NUBUS_FIRST_SLOT * NUBUS_SLOT_SIZE); nubus = MAC_NUBUS_BRIDGE(dev)->bus; diff --git a/hw/nubus/mac-nubus-bridge.c b/hw/nubus/mac-nubus-bridge.c index 3f07578..3af4f5d 100644 --- a/hw/nubus/mac-nubus-bridge.c +++ b/hw/nubus/mac-nubus-bridge.c @@ -22,8 +22,20 @@ static void mac_nubus_bridge_init(Object *obj) s->bus->slot_available_mask = MAKE_64BIT_MASK(MAC_NUBUS_FIRST_SLOT, MAC_NUBUS_SLOT_NB); - sysbus_init_mmio(sbd, &s->bus->super_slot_io); - sysbus_init_mmio(sbd, &s->bus->slot_io); + /* Aliases for slots 0x9 to 0xe */ + memory_region_init_alias(&s->super_slot_alias, obj, "super-slot-alias", + &s->bus->nubus_mr, + MAC_NUBUS_FIRST_SLOT * NUBUS_SUPER_SLOT_SIZE, + MAC_NUBUS_SLOT_NB * NUBUS_SUPER_SLOT_SIZE); + + memory_region_init_alias(&s->slot_alias, obj, "slot-alias", + &s->bus->nubus_mr, + NUBUS_SLOT_BASE + + MAC_NUBUS_FIRST_SLOT * NUBUS_SLOT_SIZE, + MAC_NUBUS_SLOT_NB * NUBUS_SLOT_SIZE); + + sysbus_init_mmio(sbd, &s->super_slot_alias); + sysbus_init_mmio(sbd, &s->slot_alias); } static void mac_nubus_bridge_class_init(ObjectClass *klass, void *data) diff --git a/hw/nubus/nubus-bus.c b/hw/nubus/nubus-bus.c index 215fdb6..07c279b 100644 --- a/hw/nubus/nubus-bus.c +++ b/hw/nubus/nubus-bus.c @@ -78,25 +78,42 @@ static const MemoryRegionOps nubus_super_slot_ops = { }, }; +static void nubus_unrealize(BusState *bus) +{ + NubusBus *nubus = NUBUS_BUS(bus); + + address_space_destroy(&nubus->nubus_as); +} + static void nubus_realize(BusState *bus, Error **errp) { + NubusBus *nubus = NUBUS_BUS(bus); + if (!nubus_find()) { error_setg(errp, "at most one %s device is permitted", TYPE_NUBUS_BUS); return; } + + address_space_init(&nubus->nubus_as, &nubus->nubus_mr, "nubus"); } static void nubus_init(Object *obj) { NubusBus *nubus = NUBUS_BUS(obj); + memory_region_init(&nubus->nubus_mr, obj, "nubus", 0x100000000); + memory_region_init_io(&nubus->super_slot_io, obj, &nubus_super_slot_ops, nubus, "nubus-super-slots", (NUBUS_SUPER_SLOT_NB + 1) * NUBUS_SUPER_SLOT_SIZE); + memory_region_add_subregion(&nubus->nubus_mr, 0x0, &nubus->super_slot_io); memory_region_init_io(&nubus->slot_io, obj, &nubus_slot_ops, nubus, "nubus-slots", NUBUS_SLOT_NB * NUBUS_SLOT_SIZE); + memory_region_add_subregion(&nubus->nubus_mr, + (NUBUS_SUPER_SLOT_NB + 1) * + NUBUS_SUPER_SLOT_SIZE, &nubus->slot_io); nubus->slot_available_mask = MAKE_64BIT_MASK(NUBUS_FIRST_SLOT, NUBUS_SLOT_NB); @@ -150,6 +167,7 @@ static void nubus_class_init(ObjectClass *oc, void *data) BusClass *bc = BUS_CLASS(oc); bc->realize = nubus_realize; + bc->unrealize = nubus_unrealize; bc->check_address = nubus_check_address; bc->get_dev_path = nubus_get_dev_path; } -- cgit v1.1 From 9bf674bc71d972426d4659e0b7769f4e45219cf7 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Sep 2021 08:38:01 +0100 Subject: nubus-bridge: introduce separate NubusBridge structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is to allow the Nubus bridge to store its own additional state. Also update the comment in the file header to reflect that nubus-bridge is not specific to the Macintosh. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Laurent Vivier Message-Id: <20210924073808.1041-14-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- hw/nubus/nubus-bridge.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'hw') diff --git a/hw/nubus/nubus-bridge.c b/hw/nubus/nubus-bridge.c index cd8c6a9..9566256 100644 --- a/hw/nubus/nubus-bridge.c +++ b/hw/nubus/nubus-bridge.c @@ -1,5 +1,5 @@ /* - * QEMU Macintosh Nubus + * QEMU Nubus * * Copyright (c) 2013-2018 Laurent Vivier * @@ -22,7 +22,7 @@ static void nubus_bridge_class_init(ObjectClass *klass, void *data) static const TypeInfo nubus_bridge_info = { .name = TYPE_NUBUS_BRIDGE, .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(SysBusDevice), + .instance_size = sizeof(NubusBridge), .class_init = nubus_bridge_class_init, }; -- cgit v1.1 From f48d613484bb8969469c9edcfc0bbe410c88d645 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Sep 2021 08:38:02 +0100 Subject: mac-nubus-bridge: rename MacNubusState to MacNubusBridge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This better reflects that the mac-nubus-bridge device is derived from the nubus-bridge device, and that the structure represents the state of the bridge device and not the Nubus itself. Also update the comment in the file header to reflect that mac-nubus-bridge is specific to the Macintosh. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Laurent Vivier Message-Id: <20210924073808.1041-15-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- hw/nubus/mac-nubus-bridge.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'hw') diff --git a/hw/nubus/mac-nubus-bridge.c b/hw/nubus/mac-nubus-bridge.c index 3af4f5d..e241c58 100644 --- a/hw/nubus/mac-nubus-bridge.c +++ b/hw/nubus/mac-nubus-bridge.c @@ -1,5 +1,7 @@ /* - * Copyright (c) 2013-2018 Laurent Vivier + * QEMU Macintosh Nubus + * + * Copyright (c) 2013-2018 Laurent Vivier * * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. @@ -13,7 +15,7 @@ static void mac_nubus_bridge_init(Object *obj) { - MacNubusState *s = MAC_NUBUS_BRIDGE(obj); + MacNubusBridge *s = MAC_NUBUS_BRIDGE(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); s->bus = NUBUS_BUS(qbus_create(TYPE_NUBUS_BUS, DEVICE(s), NULL)); @@ -49,7 +51,7 @@ static const TypeInfo mac_nubus_bridge_info = { .name = TYPE_MAC_NUBUS_BRIDGE, .parent = TYPE_NUBUS_BRIDGE, .instance_init = mac_nubus_bridge_init, - .instance_size = sizeof(MacNubusState), + .instance_size = sizeof(MacNubusBridge), .class_init = mac_nubus_bridge_class_init, }; -- cgit v1.1 From 1fa04232db5946d9648ffc03718aad9b6de87c38 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Sep 2021 08:38:03 +0100 Subject: nubus: move NubusBus from mac-nubus-bridge to nubus-bridge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that Nubus has its own address space rather than mapping directly into the system bus, move the Nubus reference from MacNubusBridge to NubusBridge. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Laurent Vivier Message-Id: <20210924073808.1041-16-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- hw/m68k/q800.c | 2 +- hw/nubus/mac-nubus-bridge.c | 11 +++++------ hw/nubus/nubus-bridge.c | 9 +++++++++ 3 files changed, 15 insertions(+), 7 deletions(-) (limited to 'hw') diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index a07912b..9bdea1a 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -398,7 +398,7 @@ static void q800_init(MachineState *machine) sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, NUBUS_SLOT_BASE + MAC_NUBUS_FIRST_SLOT * NUBUS_SLOT_SIZE); - nubus = MAC_NUBUS_BRIDGE(dev)->bus; + nubus = NUBUS_BRIDGE(dev)->bus; /* framebuffer in nubus slot #9 */ diff --git a/hw/nubus/mac-nubus-bridge.c b/hw/nubus/mac-nubus-bridge.c index e241c58..db8640e 100644 --- a/hw/nubus/mac-nubus-bridge.c +++ b/hw/nubus/mac-nubus-bridge.c @@ -16,22 +16,21 @@ static void mac_nubus_bridge_init(Object *obj) { MacNubusBridge *s = MAC_NUBUS_BRIDGE(obj); + NubusBridge *nb = NUBUS_BRIDGE(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); - s->bus = NUBUS_BUS(qbus_create(TYPE_NUBUS_BUS, DEVICE(s), NULL)); - /* Macintosh only has slots 0x9 to 0xe available */ - s->bus->slot_available_mask = MAKE_64BIT_MASK(MAC_NUBUS_FIRST_SLOT, - MAC_NUBUS_SLOT_NB); + nb->bus->slot_available_mask = MAKE_64BIT_MASK(MAC_NUBUS_FIRST_SLOT, + MAC_NUBUS_SLOT_NB); /* Aliases for slots 0x9 to 0xe */ memory_region_init_alias(&s->super_slot_alias, obj, "super-slot-alias", - &s->bus->nubus_mr, + &nb->bus->nubus_mr, MAC_NUBUS_FIRST_SLOT * NUBUS_SUPER_SLOT_SIZE, MAC_NUBUS_SLOT_NB * NUBUS_SUPER_SLOT_SIZE); memory_region_init_alias(&s->slot_alias, obj, "slot-alias", - &s->bus->nubus_mr, + &nb->bus->nubus_mr, NUBUS_SLOT_BASE + MAC_NUBUS_FIRST_SLOT * NUBUS_SLOT_SIZE, MAC_NUBUS_SLOT_NB * NUBUS_SLOT_SIZE); diff --git a/hw/nubus/nubus-bridge.c b/hw/nubus/nubus-bridge.c index 9566256..3b68d44 100644 --- a/hw/nubus/nubus-bridge.c +++ b/hw/nubus/nubus-bridge.c @@ -12,6 +12,14 @@ #include "hw/sysbus.h" #include "hw/nubus/nubus.h" + +static void nubus_bridge_init(Object *obj) +{ + NubusBridge *s = NUBUS_BRIDGE(obj); + + s->bus = NUBUS_BUS(qbus_create(TYPE_NUBUS_BUS, DEVICE(s), NULL)); +} + static void nubus_bridge_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -22,6 +30,7 @@ static void nubus_bridge_class_init(ObjectClass *klass, void *data) static const TypeInfo nubus_bridge_info = { .name = TYPE_NUBUS_BRIDGE, .parent = TYPE_SYS_BUS_DEVICE, + .instance_init = nubus_bridge_init, .instance_size = sizeof(NubusBridge), .class_init = nubus_bridge_class_init, }; -- cgit v1.1 From d585d89de172bbfaa4a2331c882c46ed186ede2a Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Sep 2021 08:38:04 +0100 Subject: nubus-bridge: embed the NubusBus object directly within nubus-bridge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since nubus-bridge is a container for NubusBus then it should be embedded directly within the bridge device using qbus_create_inplace(). Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Laurent Vivier Message-Id: <20210924073808.1041-17-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- hw/m68k/q800.c | 2 +- hw/nubus/mac-nubus-bridge.c | 9 +++++---- hw/nubus/nubus-bridge.c | 3 ++- 3 files changed, 8 insertions(+), 6 deletions(-) (limited to 'hw') diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index 9bdea1a..074acf4 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -398,7 +398,7 @@ static void q800_init(MachineState *machine) sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, NUBUS_SLOT_BASE + MAC_NUBUS_FIRST_SLOT * NUBUS_SLOT_SIZE); - nubus = NUBUS_BRIDGE(dev)->bus; + nubus = &NUBUS_BRIDGE(dev)->bus; /* framebuffer in nubus slot #9 */ diff --git a/hw/nubus/mac-nubus-bridge.c b/hw/nubus/mac-nubus-bridge.c index db8640e..a0da5a8 100644 --- a/hw/nubus/mac-nubus-bridge.c +++ b/hw/nubus/mac-nubus-bridge.c @@ -18,19 +18,20 @@ static void mac_nubus_bridge_init(Object *obj) MacNubusBridge *s = MAC_NUBUS_BRIDGE(obj); NubusBridge *nb = NUBUS_BRIDGE(obj); SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + NubusBus *bus = &nb->bus; /* Macintosh only has slots 0x9 to 0xe available */ - nb->bus->slot_available_mask = MAKE_64BIT_MASK(MAC_NUBUS_FIRST_SLOT, - MAC_NUBUS_SLOT_NB); + bus->slot_available_mask = MAKE_64BIT_MASK(MAC_NUBUS_FIRST_SLOT, + MAC_NUBUS_SLOT_NB); /* Aliases for slots 0x9 to 0xe */ memory_region_init_alias(&s->super_slot_alias, obj, "super-slot-alias", - &nb->bus->nubus_mr, + &bus->nubus_mr, MAC_NUBUS_FIRST_SLOT * NUBUS_SUPER_SLOT_SIZE, MAC_NUBUS_SLOT_NB * NUBUS_SUPER_SLOT_SIZE); memory_region_init_alias(&s->slot_alias, obj, "slot-alias", - &nb->bus->nubus_mr, + &bus->nubus_mr, NUBUS_SLOT_BASE + MAC_NUBUS_FIRST_SLOT * NUBUS_SLOT_SIZE, MAC_NUBUS_SLOT_NB * NUBUS_SLOT_SIZE); diff --git a/hw/nubus/nubus-bridge.c b/hw/nubus/nubus-bridge.c index 3b68d44..1adda7f 100644 --- a/hw/nubus/nubus-bridge.c +++ b/hw/nubus/nubus-bridge.c @@ -16,8 +16,9 @@ static void nubus_bridge_init(Object *obj) { NubusBridge *s = NUBUS_BRIDGE(obj); + NubusBus *bus = &s->bus; - s->bus = NUBUS_BUS(qbus_create(TYPE_NUBUS_BUS, DEVICE(s), NULL)); + qbus_create_inplace(bus, sizeof(s->bus), TYPE_NUBUS_BUS, DEVICE(s), NULL); } static void nubus_bridge_class_init(ObjectClass *klass, void *data) -- cgit v1.1 From 094f5b2b09d46c57a2afbbbd6aa9d4a5213e4648 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Sep 2021 08:38:05 +0100 Subject: nubus-bridge: make slot_available_mask a qdev property MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is to allow Macintosh machines to further specify which slots are available since the number of addressable slots may not match the number of physical slots present in the machine. Signed-off-by: Mark Cave-Ayland Reviewed-by: Laurent Vivier Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20210924073808.1041-18-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- hw/nubus/nubus-bridge.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'hw') diff --git a/hw/nubus/nubus-bridge.c b/hw/nubus/nubus-bridge.c index 1adda7f..7b51722 100644 --- a/hw/nubus/nubus-bridge.c +++ b/hw/nubus/nubus-bridge.c @@ -21,11 +21,18 @@ static void nubus_bridge_init(Object *obj) qbus_create_inplace(bus, sizeof(s->bus), TYPE_NUBUS_BUS, DEVICE(s), NULL); } +static Property nubus_bridge_properties[] = { + DEFINE_PROP_UINT16("slot-available-mask", NubusBridge, + bus.slot_available_mask, 0xffff), + DEFINE_PROP_END_OF_LIST() +}; + static void nubus_bridge_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->fw_name = "nubus"; + device_class_set_props(dc, nubus_bridge_properties); } static const TypeInfo nubus_bridge_info = { -- cgit v1.1 From d2cf28a0c6bcfba9d95e83ac628476e0f9cc178f Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Sep 2021 08:38:06 +0100 Subject: nubus: add support for slot IRQs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each Nubus slot has an IRQ line that can be used to request service from the CPU. Connect the IRQs to the Nubus bridge so that they can be wired up using qdev gpios accordingly, and introduce a new nubus_set_irq() function that can be used by Nubus devices to control the slot IRQ. Signed-off-by: Mark Cave-Ayland Reviewed-by: Laurent Vivier Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20210924073808.1041-19-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- hw/nubus/nubus-bridge.c | 2 ++ hw/nubus/nubus-device.c | 8 ++++++++ 2 files changed, 10 insertions(+) (limited to 'hw') diff --git a/hw/nubus/nubus-bridge.c b/hw/nubus/nubus-bridge.c index 7b51722..c517a8a 100644 --- a/hw/nubus/nubus-bridge.c +++ b/hw/nubus/nubus-bridge.c @@ -19,6 +19,8 @@ static void nubus_bridge_init(Object *obj) NubusBus *bus = &s->bus; qbus_create_inplace(bus, sizeof(s->bus), TYPE_NUBUS_BUS, DEVICE(s), NULL); + + qdev_init_gpio_out(DEVICE(s), bus->irqs, NUBUS_IRQS); } static Property nubus_bridge_properties[] = { diff --git a/hw/nubus/nubus-device.c b/hw/nubus/nubus-device.c index 280f40e..0f1852f 100644 --- a/hw/nubus/nubus-device.c +++ b/hw/nubus/nubus-device.c @@ -10,12 +10,20 @@ #include "qemu/osdep.h" #include "qemu/datadir.h" +#include "hw/irq.h" #include "hw/loader.h" #include "hw/nubus/nubus.h" #include "qapi/error.h" #include "qemu/error-report.h" +void nubus_set_irq(NubusDevice *nd, int level) +{ + NubusBus *nubus = NUBUS_BUS(qdev_get_parent_bus(DEVICE(nd))); + + qemu_set_irq(nubus->irqs[nd->slot], level); +} + static void nubus_device_realize(DeviceState *dev, Error **errp) { NubusBus *nubus = NUBUS_BUS(qdev_get_parent_bus(dev)); -- cgit v1.1 From b297843ef5666c094c153a2a7d78c6b010dd9154 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Sep 2021 08:38:07 +0100 Subject: q800: wire up nubus IRQs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nubus IRQs are routed to the CPU through the VIA2 device so wire up the IRQs using gpios accordingly. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Laurent Vivier Message-Id: <20210924073808.1041-20-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- hw/m68k/q800.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'hw') diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index 074acf4..5bc9df5 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -398,6 +398,12 @@ static void q800_init(MachineState *machine) sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, NUBUS_SLOT_BASE + MAC_NUBUS_FIRST_SLOT * NUBUS_SLOT_SIZE); + for (i = 0; i < VIA2_NUBUS_IRQ_NB; i++) { + qdev_connect_gpio_out(dev, 9 + i, + qdev_get_gpio_in_named(via2_dev, "nubus-irq", + VIA2_NUBUS_IRQ_9 + i)); + } + nubus = &NUBUS_BRIDGE(dev)->bus; /* framebuffer in nubus slot #9 */ -- cgit v1.1 From 5ef251416b5116bbf7723f31ddf8a6949a2ac271 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Fri, 24 Sep 2021 08:38:08 +0100 Subject: q800: configure nubus available slots for Quadra 800 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Slot 0x9 is reserved for use by the in-built framebuffer whilst only slots 0xc, 0xd and 0xe physically exist on the Quadra 800. Signed-off-by: Mark Cave-Ayland Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Laurent Vivier Message-Id: <20210924073808.1041-21-mark.cave-ayland@ilande.co.uk> Signed-off-by: Laurent Vivier --- hw/m68k/q800.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'hw') diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index 5bc9df5..09b3366 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -79,6 +79,13 @@ #define MAC_CLOCK 3686418 /* + * Slot 0x9 is reserved for use by the in-built framebuffer whilst only + * slots 0xc, 0xd and 0xe physically exist on the Quadra 800 + */ +#define Q800_NUBUS_SLOTS_AVAILABLE (BIT(0x9) | BIT(0xc) | BIT(0xd) | \ + BIT(0xe)) + +/* * The GLUE (General Logic Unit) is an Apple custom integrated circuit chip * that performs a variety of functions (RAM management, clock generation, ...). * The GLUE chip receives interrupt requests from various devices, @@ -392,6 +399,8 @@ static void q800_init(MachineState *machine) /* NuBus */ dev = qdev_new(TYPE_MAC_NUBUS_BRIDGE); + qdev_prop_set_uint32(dev, "slot-available-mask", + Q800_NUBUS_SLOTS_AVAILABLE); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, MAC_NUBUS_FIRST_SLOT * NUBUS_SUPER_SLOT_SIZE); -- cgit v1.1