Le 17/09/2021 à 09:50, Mark Cave-Ayland a écrit :
> 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 <mark.cave-ayland@ilande.co.uk>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> ---
> hw/nubus/nubus-bus.c | 34 ++++++++++++++++++----------------
> 1 file changed, 18 insertions(+), 16 deletions(-)
>
> diff --git a/hw/nubus/nubus-bus.c b/hw/nubus/nubus-bus.c
> index 39182db065..a617459a4f 100644
> --- a/hw/nubus/nubus-bus.c
> +++ b/hw/nubus/nubus-bus.c
> @@ -20,23 +20,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,
> @@ -44,23 +44,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,
>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>