diff mbox series

[05/21] q800: add IOSB subsystem

Message ID 20230702154838.722809-6-mark.cave-ayland@ilande.co.uk
State New
Headers show
Series q800: add support for booting MacOS Classic - part 2 | expand

Commit Message

Mark Cave-Ayland July 2, 2023, 3:48 p.m. UTC
It is needed because it defines the BIOSConfig area.

Co-developed-by: Laurent Vivier <laurent@vivier.eu>
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
---
 MAINTAINERS            |   2 +
 hw/m68k/Kconfig        |   1 +
 hw/m68k/q800.c         |   9 +++
 hw/misc/Kconfig        |   3 +
 hw/misc/iosb.c         | 137 +++++++++++++++++++++++++++++++++++++++++
 hw/misc/meson.build    |   1 +
 hw/misc/trace-events   |   4 ++
 include/hw/m68k/q800.h |   2 +
 include/hw/misc/iosb.h |  25 ++++++++
 9 files changed, 184 insertions(+)
 create mode 100644 hw/misc/iosb.c
 create mode 100644 include/hw/misc/iosb.h

Comments

Philippe Mathieu-Daudé July 7, 2023, 8:25 a.m. UTC | #1
On 2/7/23 17:48, Mark Cave-Ayland wrote:
> It is needed because it defines the BIOSConfig area.
> 
> Co-developed-by: Laurent Vivier <laurent@vivier.eu>
> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
> ---
>   MAINTAINERS            |   2 +
>   hw/m68k/Kconfig        |   1 +
>   hw/m68k/q800.c         |   9 +++
>   hw/misc/Kconfig        |   3 +
>   hw/misc/iosb.c         | 137 +++++++++++++++++++++++++++++++++++++++++
>   hw/misc/meson.build    |   1 +
>   hw/misc/trace-events   |   4 ++
>   include/hw/m68k/q800.h |   2 +
>   include/hw/misc/iosb.h |  25 ++++++++
>   9 files changed, 184 insertions(+)
>   create mode 100644 hw/misc/iosb.c
>   create mode 100644 include/hw/misc/iosb.h


> diff --git a/hw/misc/iosb.c b/hw/misc/iosb.c
> new file mode 100644
> index 0000000000..4fc10bcf9f
> --- /dev/null
> +++ b/hw/misc/iosb.c
> @@ -0,0 +1,137 @@
> +/*
> + * QEMU IOSB emulation
> + *
> + * Copyright (c) 2019 Laurent Vivier
> + * Copyright (c) 2022 Mark Cave-Ayland
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "migration/vmstate.h"
> +#include "hw/sysbus.h"
> +#include "hw/misc/iosb.h"
> +#include "trace.h"
> +
> +#define IOSB_SIZE          0x2000
> +
> +#define IOSB_CONFIG        0x0
> +#define IOSB_CONFIG2       0x100
> +#define IOSB_SONIC_SCSI    0x200
> +#define IOSB_REVISION      0x300
> +#define IOSB_SCSI_RESID    0x400
> +#define IOSB_BRIGHTNESS    0x500
> +#define IOSB_TIMEOUT       0x600
> +
> +
> +static uint64_t iosb_read(void *opaque, hwaddr addr,
> +                          unsigned size)
> +{
> +    IOSBState *s = IOSB(opaque);
> +    uint64_t val = 0;
> +
> +    switch (addr) {
> +    case IOSB_CONFIG:
> +    case IOSB_CONFIG2:
> +    case IOSB_SONIC_SCSI:
> +    case IOSB_REVISION:
> +    case IOSB_SCSI_RESID:
> +    case IOSB_BRIGHTNESS:
> +    case IOSB_TIMEOUT:
> +        val = s->regs[addr >> 8];
> +        break;
> +    default:
> +        qemu_log_mask(LOG_UNIMP, "IOSB: unimplemented read addr=0x%"PRIx64
> +                                 " val=0x%"PRIx64 " size=%d\n",
> +                                 addr, val, size);
> +    }
> +
> +    trace_iosb_read(addr, val, size);
> +    return val;
> +}
> +
> +static void iosb_write(void *opaque, hwaddr addr, uint64_t val,
> +                       unsigned size)
> +{
> +    IOSBState *s = IOSB(opaque);
> +
> +    switch (addr) {
> +    case IOSB_CONFIG:
> +    case IOSB_CONFIG2:
> +    case IOSB_SONIC_SCSI:
> +    case IOSB_REVISION:
> +    case IOSB_SCSI_RESID:
> +    case IOSB_BRIGHTNESS:
> +    case IOSB_TIMEOUT:
> +        s->regs[addr >> 8] = val;
> +        break;
> +    default:
> +        qemu_log_mask(LOG_UNIMP, "IOSB: unimplemented write addr=0x%"PRIx64
> +                                 " val=0x%"PRIx64 " size=%d\n",
> +                                 addr, val, size);
> +    }
> +
> +    trace_iosb_write(addr, val, size);
> +}
> +
> +static const MemoryRegionOps iosb_mmio_ops = {
> +    .read = iosb_read,
> +    .write = iosb_write,
> +    .endianness = DEVICE_BIG_ENDIAN,
> +    .impl = {
> +        .min_access_size = 1,

IIUC .impl.min_access_size = 4.

Do you mean .valid.min_access_size = 1?

Otherwise,
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>

> +        .max_access_size = 4,
> +    },
> +};
Mark Cave-Ayland Sept. 8, 2023, 6:50 a.m. UTC | #2
On 07/07/2023 09:25, Philippe Mathieu-Daudé wrote:

> On 2/7/23 17:48, Mark Cave-Ayland wrote:
>> It is needed because it defines the BIOSConfig area.
>>
>> Co-developed-by: Laurent Vivier <laurent@vivier.eu>
>> Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
>> ---
>>   MAINTAINERS            |   2 +
>>   hw/m68k/Kconfig        |   1 +
>>   hw/m68k/q800.c         |   9 +++
>>   hw/misc/Kconfig        |   3 +
>>   hw/misc/iosb.c         | 137 +++++++++++++++++++++++++++++++++++++++++
>>   hw/misc/meson.build    |   1 +
>>   hw/misc/trace-events   |   4 ++
>>   include/hw/m68k/q800.h |   2 +
>>   include/hw/misc/iosb.h |  25 ++++++++
>>   9 files changed, 184 insertions(+)
>>   create mode 100644 hw/misc/iosb.c
>>   create mode 100644 include/hw/misc/iosb.h
> 
> 
>> diff --git a/hw/misc/iosb.c b/hw/misc/iosb.c
>> new file mode 100644
>> index 0000000000..4fc10bcf9f
>> --- /dev/null
>> +++ b/hw/misc/iosb.c
>> @@ -0,0 +1,137 @@
>> +/*
>> + * QEMU IOSB emulation
>> + *
>> + * Copyright (c) 2019 Laurent Vivier
>> + * Copyright (c) 2022 Mark Cave-Ayland
>> + *
>> + * SPDX-License-Identifier: GPL-2.0-or-later
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "qemu/log.h"
>> +#include "migration/vmstate.h"
>> +#include "hw/sysbus.h"
>> +#include "hw/misc/iosb.h"
>> +#include "trace.h"
>> +
>> +#define IOSB_SIZE          0x2000
>> +
>> +#define IOSB_CONFIG        0x0
>> +#define IOSB_CONFIG2       0x100
>> +#define IOSB_SONIC_SCSI    0x200
>> +#define IOSB_REVISION      0x300
>> +#define IOSB_SCSI_RESID    0x400
>> +#define IOSB_BRIGHTNESS    0x500
>> +#define IOSB_TIMEOUT       0x600
>> +
>> +
>> +static uint64_t iosb_read(void *opaque, hwaddr addr,
>> +                          unsigned size)
>> +{
>> +    IOSBState *s = IOSB(opaque);
>> +    uint64_t val = 0;
>> +
>> +    switch (addr) {
>> +    case IOSB_CONFIG:
>> +    case IOSB_CONFIG2:
>> +    case IOSB_SONIC_SCSI:
>> +    case IOSB_REVISION:
>> +    case IOSB_SCSI_RESID:
>> +    case IOSB_BRIGHTNESS:
>> +    case IOSB_TIMEOUT:
>> +        val = s->regs[addr >> 8];
>> +        break;
>> +    default:
>> +        qemu_log_mask(LOG_UNIMP, "IOSB: unimplemented read addr=0x%"PRIx64
>> +                                 " val=0x%"PRIx64 " size=%d\n",
>> +                                 addr, val, size);
>> +    }
>> +
>> +    trace_iosb_read(addr, val, size);
>> +    return val;
>> +}
>> +
>> +static void iosb_write(void *opaque, hwaddr addr, uint64_t val,
>> +                       unsigned size)
>> +{
>> +    IOSBState *s = IOSB(opaque);
>> +
>> +    switch (addr) {
>> +    case IOSB_CONFIG:
>> +    case IOSB_CONFIG2:
>> +    case IOSB_SONIC_SCSI:
>> +    case IOSB_REVISION:
>> +    case IOSB_SCSI_RESID:
>> +    case IOSB_BRIGHTNESS:
>> +    case IOSB_TIMEOUT:
>> +        s->regs[addr >> 8] = val;
>> +        break;
>> +    default:
>> +        qemu_log_mask(LOG_UNIMP, "IOSB: unimplemented write addr=0x%"PRIx64
>> +                                 " val=0x%"PRIx64 " size=%d\n",
>> +                                 addr, val, size);
>> +    }
>> +
>> +    trace_iosb_write(addr, val, size);
>> +}
>> +
>> +static const MemoryRegionOps iosb_mmio_ops = {
>> +    .read = iosb_read,
>> +    .write = iosb_write,
>> +    .endianness = DEVICE_BIG_ENDIAN,
>> +    .impl = {
>> +        .min_access_size = 1,
> 
> IIUC .impl.min_access_size = 4.
> 
> Do you mean .valid.min_access_size = 1?

Hmmm I can't remember the exact origin of this, but indeed looking at the stride this 
doesn't make much sense. I've done some tests with .impl removed completely and 
haven't seen any issues, so I'll drop this from v2.

> Otherwise,
> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> 
>> +        .max_access_size = 4,
>> +    },
>> +};


ATB,

Mark.
diff mbox series

Patch

diff --git a/MAINTAINERS b/MAINTAINERS
index 2d85e8c28c..88db6540ae 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1232,6 +1232,7 @@  F: hw/nubus/*
 F: hw/display/macfb.c
 F: hw/block/swim.c
 F: hw/misc/djmemc.c
+F: hw/misc/iosb.c
 F: hw/m68k/bootinfo.h
 F: include/standard-headers/asm-m68k/bootinfo.h
 F: include/standard-headers/asm-m68k/bootinfo-mac.h
@@ -1242,6 +1243,7 @@  F: include/hw/block/swim.h
 F: include/hw/m68k/q800.h
 F: include/hw/m68k/q800-glue.h
 F: include/hw/misc/djmemc.h
+F: include/hw/misc/iosb.h
 
 virt
 M: Laurent Vivier <laurent@vivier.eu>
diff --git a/hw/m68k/Kconfig b/hw/m68k/Kconfig
index 330cfdfa2d..64fa70a0db 100644
--- a/hw/m68k/Kconfig
+++ b/hw/m68k/Kconfig
@@ -24,6 +24,7 @@  config Q800
     select DP8393X
     select OR_IRQ
     select DJMEMC
+    select IOSB
 
 config M68K_VIRT
     bool
diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index ac8509ba6f..081b95e9cf 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -41,6 +41,7 @@ 
 #include "hw/m68k/q800-glue.h"
 #include "hw/misc/mac_via.h"
 #include "hw/misc/djmemc.h"
+#include "hw/misc/iosb.h"
 #include "hw/input/adb.h"
 #include "hw/nubus/mac-nubus-bridge.h"
 #include "hw/display/macfb.h"
@@ -71,6 +72,7 @@ 
 #define ESP_BASE              (IO_BASE + 0x10000)
 #define ESP_PDMA              (IO_BASE + 0x10100)
 #define ASC_BASE              (IO_BASE + 0x14000)
+#define IOSB_BASE             (IO_BASE + 0x18000)
 #define SWIM_BASE             (IO_BASE + 0x1E000)
 
 #define SONIC_PROM_SIZE       0x1000
@@ -296,6 +298,13 @@  static void q800_machine_init(MachineState *machine)
     memory_region_add_subregion(&m->macio, DJMEMC_BASE - IO_BASE,
                                 sysbus_mmio_get_region(sysbus, 0));
 
+    /* IOSB subsystem */
+    object_initialize_child(OBJECT(machine), "iosb", &m->iosb, TYPE_IOSB);
+    sysbus = SYS_BUS_DEVICE(&m->iosb);
+    sysbus_realize_and_unref(sysbus, &error_fatal);
+    memory_region_add_subregion(&m->macio, IOSB_BASE - IO_BASE,
+                                sysbus_mmio_get_region(sysbus, 0));
+
     /* VIA 1 */
     object_initialize_child(OBJECT(machine), "via1", &m->via1,
                             TYPE_MOS6522_Q800_VIA1);
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 9576debc70..858742d8fc 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -186,4 +186,7 @@  config AXP2XX_PMU
 config DJMEMC
     bool
 
+config IOSB
+    bool
+
 source macio/Kconfig
diff --git a/hw/misc/iosb.c b/hw/misc/iosb.c
new file mode 100644
index 0000000000..4fc10bcf9f
--- /dev/null
+++ b/hw/misc/iosb.c
@@ -0,0 +1,137 @@ 
+/*
+ * QEMU IOSB emulation
+ *
+ * Copyright (c) 2019 Laurent Vivier
+ * Copyright (c) 2022 Mark Cave-Ayland
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "migration/vmstate.h"
+#include "hw/sysbus.h"
+#include "hw/misc/iosb.h"
+#include "trace.h"
+
+#define IOSB_SIZE          0x2000
+
+#define IOSB_CONFIG        0x0
+#define IOSB_CONFIG2       0x100
+#define IOSB_SONIC_SCSI    0x200
+#define IOSB_REVISION      0x300
+#define IOSB_SCSI_RESID    0x400
+#define IOSB_BRIGHTNESS    0x500
+#define IOSB_TIMEOUT       0x600
+
+
+static uint64_t iosb_read(void *opaque, hwaddr addr,
+                          unsigned size)
+{
+    IOSBState *s = IOSB(opaque);
+    uint64_t val = 0;
+
+    switch (addr) {
+    case IOSB_CONFIG:
+    case IOSB_CONFIG2:
+    case IOSB_SONIC_SCSI:
+    case IOSB_REVISION:
+    case IOSB_SCSI_RESID:
+    case IOSB_BRIGHTNESS:
+    case IOSB_TIMEOUT:
+        val = s->regs[addr >> 8];
+        break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "IOSB: unimplemented read addr=0x%"PRIx64
+                                 " val=0x%"PRIx64 " size=%d\n",
+                                 addr, val, size);
+    }
+
+    trace_iosb_read(addr, val, size);
+    return val;
+}
+
+static void iosb_write(void *opaque, hwaddr addr, uint64_t val,
+                       unsigned size)
+{
+    IOSBState *s = IOSB(opaque);
+
+    switch (addr) {
+    case IOSB_CONFIG:
+    case IOSB_CONFIG2:
+    case IOSB_SONIC_SCSI:
+    case IOSB_REVISION:
+    case IOSB_SCSI_RESID:
+    case IOSB_BRIGHTNESS:
+    case IOSB_TIMEOUT:
+        s->regs[addr >> 8] = val;
+        break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "IOSB: unimplemented write addr=0x%"PRIx64
+                                 " val=0x%"PRIx64 " size=%d\n",
+                                 addr, val, size);
+    }
+
+    trace_iosb_write(addr, val, size);
+}
+
+static const MemoryRegionOps iosb_mmio_ops = {
+    .read = iosb_read,
+    .write = iosb_write,
+    .endianness = DEVICE_BIG_ENDIAN,
+    .impl = {
+        .min_access_size = 1,
+        .max_access_size = 4,
+    },
+};
+
+static void iosb_reset_hold(Object *obj)
+{
+    IOSBState *s = IOSB(obj);
+
+    memset(s->regs, 0, sizeof(s->regs));
+
+    /* BCLK 33 MHz */
+    s->regs[IOSB_CONFIG >> 8] = 1;
+}
+
+static void iosb_init(Object *obj)
+{
+    IOSBState *s = IOSB(obj);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+
+    memory_region_init_io(&s->mem_regs, obj, &iosb_mmio_ops, s, "IOSB",
+                          IOSB_SIZE);
+    sysbus_init_mmio(sbd, &s->mem_regs);
+}
+
+static const VMStateDescription vmstate_iosb = {
+    .name = "IOSB",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(regs, IOSBState, IOSB_REGS),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void iosb_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+    ResettableClass *rc = RESETTABLE_CLASS(oc);
+
+    dc->vmsd = &vmstate_iosb;
+    rc->phases.hold = iosb_reset_hold;
+}
+
+static const TypeInfo iosb_info_types[] = {
+    {
+        .name          = TYPE_IOSB,
+        .parent        = TYPE_SYS_BUS_DEVICE,
+        .instance_size = sizeof(IOSBState),
+        .instance_init = iosb_init,
+        .class_init    = iosb_class_init,
+    },
+};
+
+DEFINE_TYPES(iosb_info_types)
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index c68f30e630..dc7d90ff3e 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -21,6 +21,7 @@  system_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_ras.c'))
 # Mac devices
 system_ss.add(when: 'CONFIG_MOS6522', if_true: files('mos6522.c'))
 system_ss.add(when: 'CONFIG_DJMEMC', if_true: files('djmemc.c'))
+system_ss.add(when: 'CONFIG_IOSB', if_true: files('iosb.c'))
 
 # virt devices
 system_ss.add(when: 'CONFIG_VIRT_CTRL', if_true: files('virt_ctrl.c'))
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index 341adbf24c..d5711dcff2 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -301,3 +301,7 @@  lasi_chip_write(uint64_t addr, uint32_t val) "addr 0x%"PRIx64" val 0x%08x"
 # djmemc.c
 djmemc_read(int reg, uint64_t value, unsigned int size) "reg=0x%x value=0x%"PRIx64" size=%u"
 djmemc_write(int reg, uint64_t value, unsigned int size) "reg=0x%x value=0x%"PRIx64" size=%u"
+
+# iosb.c
+iosb_read(int reg, uint64_t value, unsigned int size) "reg=0x%x value=0x%"PRIx64" size=%u"
+iosb_write(int reg, uint64_t value, unsigned int size) "reg=0x%x value=0x%"PRIx64" size=%u"
diff --git a/include/hw/m68k/q800.h b/include/hw/m68k/q800.h
index dd7d7a6f2c..98097165d9 100644
--- a/include/hw/m68k/q800.h
+++ b/include/hw/m68k/q800.h
@@ -37,6 +37,7 @@ 
 #include "hw/nubus/mac-nubus-bridge.h"
 #include "hw/display/macfb.h"
 #include "hw/misc/djmemc.h"
+#include "hw/misc/iosb.h"
 
 /*
  * The main Q800 machine
@@ -58,6 +59,7 @@  struct Q800MachineState {
     MacNubusBridge mac_nubus_bridge;
     MacfbNubusState macfb;
     DJMEMCState djmemc;
+    IOSBState iosb;
     MemoryRegion macio;
     MemoryRegion macio_alias;
     MemoryRegion machine_id;
diff --git a/include/hw/misc/iosb.h b/include/hw/misc/iosb.h
new file mode 100644
index 0000000000..377f8ca7e2
--- /dev/null
+++ b/include/hw/misc/iosb.h
@@ -0,0 +1,25 @@ 
+/*
+ * QEMU IOSB emulation
+ *
+ * Copyright (c) 2019 Laurent Vivier
+ * Copyright (c) 2022 Mark Cave-Ayland
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_MEM_IOSB_H
+#define HW_MEM_IOSB_H
+
+#define IOSB_REGS 7
+
+struct IOSBState {
+    SysBusDevice parent_obj;
+
+    MemoryRegion mem_regs;
+    uint32_t regs[IOSB_REGS];
+};
+
+#define TYPE_IOSB "IOSB"
+OBJECT_DECLARE_SIMPLE_TYPE(IOSBState, IOSB);
+
+#endif