On Linux, calling `reboot(RB_AUTOBOOT);` will result in arch/m68k/mac/misc.c's mac_reset function being called. That in turn looks at the rombase (or uses 0x40800000 is there's no rombase), adds 0xa, and jumps to that address. At the moment, there's nothing there, so the kernel just crashes when trying to reboot. So, this commit adds a very simple implementation at that location, which just writes to via2 to power down.
Signed-off-by: Jason A. Donenfeld <ja...@zx2c4.com> --- hw/m68k/q800.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index 4ca8678007..491ba11200 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -128,6 +128,20 @@ static void main_cpu_reset(void *opaque) cpu->env.pc = ldl_phys(cs->as, 4); } +static uint8_t fake_mac_rom[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* offset: 0xa - mac_reset */ + 0x20, 0x7C, 0x50, 0xF0, 0x24, 0x00, /* moveal #1357915136,%a0 */ + 0x10, 0x10, /* moveb %a0@,%d0 */ + 0x00, 0x00, 0x00, 0x04, /* orib #4,%d0 */ + 0x10, 0x80, /* moveb %d0,%a0@ */ + 0x20, 0x7C, 0x50, 0xF0, 0x20, 0x00, /* moveal #1357914112,%a0 */ + 0x10, 0x10, /* moveb %a0@,%d0 */ + 0x02, 0x00, 0xFF, 0xFB, /* andib #-5,%d0 */ + 0x10, 0x80, /* moveb %d0,%a0@ */ + 0x60, 0xFE /* bras [self] */ +}; + static void q800_init(MachineState *machine) { M68kCPU *cpu = NULL; @@ -339,6 +353,13 @@ static void q800_init(MachineState *machine) BOOTINFO1(cs->as, parameters_base, BI_MAC_VROW, (graphic_width * graphic_depth + 7) / 8); BOOTINFO1(cs->as, parameters_base, BI_MAC_SCCBASE, SCC_BASE); + BOOTINFO1(cs->as, parameters_base, BI_MAC_ROMBASE, MACROM_ADDR); + + rom = g_malloc(sizeof(*rom)); + memory_region_init_ram_ptr(rom, NULL, "m68k_fake_mac.rom", + sizeof(fake_mac_rom), fake_mac_rom); + memory_region_set_readonly(rom, true); + memory_region_add_subregion(get_system_memory(), MACROM_ADDR, rom); if (kernel_cmdline) { BOOTINFOSTR(cs->as, parameters_base, BI_COMMAND_LINE, -- 2.24.1