Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
q800: reimplement mac-io region aliasing using IO memory region
The current use of aliased memory regions causes us 2 problems: firstly the
output of "info qom-tree" is absolutely huge and difficult to read, and
secondly we have already reached the internal limit for memory regions as
adding any new memory region into the mac-io region causes QEMU to assert
with "phys_section_add: Assertion `map->sections_nb < TARGET_PAGE_SIZE'
failed".

Resolve this issue by implementing the aliasing using a single new IO memory
region that forwards the memory accesses onto the mac-io memory region.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
  • Loading branch information
mcayland committed Apr 18, 2021
1 parent 9eeef03 commit 56f8639
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 20 deletions.
87 changes: 67 additions & 20 deletions hw/m68k/q800.c
Expand Up @@ -60,6 +60,7 @@

#define IO_BASE 0x50000000
#define IO_SLICE 0x00040000
#define IO_SLICE_MASK (IO_SLICE - 1)
#define IO_SIZE 0x04000000

#define VIA_BASE (IO_BASE + 0x00000)
Expand Down Expand Up @@ -156,6 +157,54 @@ static const TypeInfo glue_info = {
.class_init = glue_class_init,
};


static MemTxResult macio_alias_read(void *opaque, hwaddr addr, uint64_t *data,
unsigned size, MemTxAttrs attrs)
{
MemoryRegion *mr = opaque;
MemoryRegionSection mrs;

addr &= IO_SLICE_MASK;
mrs = memory_region_find(mr, addr, size);

if (mrs.mr) {
return memory_region_dispatch_read(mrs.mr, mrs.offset_within_region,
data, size_memop(size) | MO_BE,
attrs);
} else {
return MEMTX_DECODE_ERROR;
}
}

static MemTxResult macio_alias_write(void *opaque, hwaddr addr, uint64_t value,
unsigned size, MemTxAttrs attrs)
{
MemoryRegion *mr = opaque;
MemoryRegionSection mrs;

addr &= IO_SLICE_MASK;
mrs = memory_region_find(mr, addr, size);

if (mrs.mr) {
return memory_region_dispatch_write(mrs.mr, mrs.offset_within_region,
value, size_memop(size) | MO_BE,
attrs);
} else {
return MEMTX_DECODE_ERROR;
}
}

static const MemoryRegionOps macio_alias_ops = {
.read_with_attrs = macio_alias_read,
.write_with_attrs = macio_alias_write,
.endianness = DEVICE_BIG_ENDIAN,
.valid = {
.min_access_size = 1,
.max_access_size = 4,
},
};


static void main_cpu_reset(void *opaque)
{
M68kCPU *cpu = opaque;
Expand Down Expand Up @@ -197,9 +246,6 @@ static void q800_init(MachineState *machine)
int bios_size;
ram_addr_t initrd_base;
int32_t initrd_size;
MemoryRegion *io;
const int io_slice_nb = (IO_SIZE / IO_SLICE) - 1;
int i;
ram_addr_t ram_size = machine->ram_size;
const char *kernel_filename = machine->kernel_filename;
const char *initrd_filename = machine->initrd_filename;
Expand Down Expand Up @@ -242,16 +288,10 @@ static void q800_init(MachineState *machine)
* Memory from IO_BASE to IO_BASE + IO_SLICE is repeated
* from IO_BASE + IO_SLICE to IO_BASE + IO_SIZE
*/
io = g_new(MemoryRegion, io_slice_nb);
for (i = 0; i < io_slice_nb; i++) {
char *name = g_strdup_printf("mac_m68k.io[%d]", i + 1);

memory_region_init_alias(&io[i], NULL, name, get_system_memory(),
IO_BASE, IO_SLICE);
memory_region_add_subregion(get_system_memory(),
IO_BASE + (i + 1) * IO_SLICE, &io[i]);
g_free(name);
}
memory_region_init_io(&m->macio_alias, NULL, &macio_alias_ops, &m->macio,
"mac-io.alias", IO_SIZE - IO_SLICE);
memory_region_add_subregion(get_system_memory(), IO_BASE + IO_SLICE,
&m->macio_alias);

/* IRQ Glue */
m->glue = qdev_new(TYPE_GLUE);
Expand All @@ -267,7 +307,8 @@ static void q800_init(MachineState *machine)
}
sysbus = SYS_BUS_DEVICE(via_dev);
sysbus_realize_and_unref(sysbus, &error_fatal);
sysbus_mmio_map(sysbus, 0, VIA_BASE);
memory_region_add_subregion(&m->macio, VIA_BASE - IO_BASE,
sysbus_mmio_get_region(sysbus, 0));
qdev_connect_gpio_out_named(DEVICE(sysbus), "irq", 0,
qdev_get_gpio_in(m->glue, 0));
qdev_connect_gpio_out_named(DEVICE(sysbus), "irq", 1,
Expand Down Expand Up @@ -310,8 +351,10 @@ static void q800_init(MachineState *machine)
OBJECT(get_system_memory()), &error_abort);
sysbus = SYS_BUS_DEVICE(dev);
sysbus_realize_and_unref(sysbus, &error_fatal);
sysbus_mmio_map(sysbus, 0, SONIC_BASE);
sysbus_mmio_map(sysbus, 1, SONIC_PROM_BASE);
memory_region_add_subregion(&m->macio, SONIC_BASE - IO_BASE,
sysbus_mmio_get_region(sysbus, 0));
memory_region_add_subregion(&m->macio, SONIC_PROM_BASE - IO_BASE,
sysbus_mmio_get_region(sysbus, 1));
sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(m->glue, 2));

/* SCC */
Expand All @@ -335,7 +378,8 @@ static void q800_init(MachineState *machine)
sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(escc_orgate, 0));
sysbus_connect_irq(sysbus, 1, qdev_get_gpio_in(escc_orgate, 1));
qdev_connect_gpio_out(DEVICE(escc_orgate), 0, qdev_get_gpio_in(m->glue, 3));
sysbus_mmio_map(sysbus, 0, SCC_BASE);
memory_region_add_subregion(&m->macio, SCC_BASE - IO_BASE,
sysbus_mmio_get_region(sysbus, 0));

/* SCSI */

Expand All @@ -356,16 +400,19 @@ static void q800_init(MachineState *machine)
sysbus_connect_irq(sysbus, 1,
qdev_get_gpio_in_named(via_dev, "via2-irq",
VIA2_IRQ_SCSI_DATA_BIT));
sysbus_mmio_map(sysbus, 0, ESP_BASE);
sysbus_mmio_map(sysbus, 1, ESP_PDMA);
memory_region_add_subregion(&m->macio, ESP_BASE - IO_BASE,
sysbus_mmio_get_region(sysbus, 0));
memory_region_add_subregion(&m->macio, ESP_PDMA - IO_BASE,
sysbus_mmio_get_region(sysbus, 1));

scsi_bus_legacy_handle_cmdline(&esp->bus);

/* SWIM floppy controller */

dev = qdev_new(TYPE_SWIM);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, SWIM_BASE);
memory_region_add_subregion(&m->macio, SWIM_BASE - IO_BASE,
sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0));

/* NuBus */

Expand Down
1 change: 1 addition & 0 deletions include/hw/m68k/q800.h
Expand Up @@ -53,6 +53,7 @@ typedef struct Q800MachineState {
DeviceState *glue;

MemoryRegion macio;
MemoryRegion macio_alias;
} Q800MachineState;

#define TYPE_Q800_MACHINE MACHINE_TYPE_NAME("q800")
Expand Down

0 comments on commit 56f8639

Please sign in to comment.