[PATCH v2] q800: implement mac rom reset function for BIOS-less mode

Jason A. Donenfeld posted 1 patch 4 years, 4 months ago
Test asan failed
Test checkpatch failed
Test FreeBSD failed
Test docker-mingw@fedora failed
Test docker-clang@ubuntu failed
Test docker-quick@centos7 failed
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20200102120150.281082-1-Jason@zx2c4.com
Maintainers: Laurent Vivier <laurent@vivier.eu>
hw/m68k/q800.c | 29 ++++++++++++++++++++++++++++-
1 file changed, 28 insertions(+), 1 deletion(-)
[PATCH v2] q800: implement mac rom reset function for BIOS-less mode
Posted by Jason A. Donenfeld 4 years, 4 months ago
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. We also correct the value of ROMBASE while we're at it.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
---
 hw/m68k/q800.c | 29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
index 4ca8678007..f03679e24c 100644
--- a/hw/m68k/q800.c
+++ b/hw/m68k/q800.c
@@ -47,7 +47,7 @@
 #include "sysemu/runstate.h"
 #include "sysemu/reset.h"
 
-#define MACROM_ADDR     0x40000000
+#define MACROM_ADDR     0x40800000
 #define MACROM_SIZE     0x00100000
 
 #define MACROM_FILENAME "MacROM.bin"
@@ -128,6 +128,27 @@ 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 */
+
+    /* via2[vDirB] |= VIA2B_vPower */
+    0x20, 0x7C, 0x50, 0xF0, 0x24, 0x00, /* moveal VIA2_BASE+vDirB,%a0 */
+    0x10, 0x10,                         /* moveb %a0@,%d0 */
+    0x00, 0x00, 0x00, 0x04,             /* orib #4,%d0 */
+    0x10, 0x80,                         /* moveb %d0,%a0@ */
+
+    /* via2[vBufB] &= ~VIA2B_vPower */
+    0x20, 0x7C, 0x50, 0xF0, 0x20, 0x00, /* moveal VIA2_BASE+vBufB,%a0 */
+    0x10, 0x10,                         /* moveb %a0@,%d0 */
+    0x02, 0x00, 0xFF, 0xFB,             /* andib #-5,%d0 */
+    0x10, 0x80,                         /* moveb %d0,%a0@ */
+
+    /* while (true) ; */
+    0x60, 0xFE                          /* bras [self] */
+};
+
 static void q800_init(MachineState *machine)
 {
     M68kCPU *cpu = NULL;
@@ -340,6 +361,12 @@ static void q800_init(MachineState *machine)
                   (graphic_width * graphic_depth + 7) / 8);
         BOOTINFO1(cs->as, parameters_base, BI_MAC_SCCBASE, SCC_BASE);
 
+        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,
                         kernel_cmdline);
-- 
2.24.1


Re: [PATCH v2] q800: implement mac rom reset function for BIOS-less mode
Posted by Laurent Vivier 4 years, 4 months ago
Le 02/01/2020 à 13:01, Jason A. Donenfeld a écrit :
> 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. We also correct the value of ROMBASE while we're at it.
> 
> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
> ---
>  hw/m68k/q800.c | 29 ++++++++++++++++++++++++++++-
>  1 file changed, 28 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
> index 4ca8678007..f03679e24c 100644
> --- a/hw/m68k/q800.c
> +++ b/hw/m68k/q800.c
> @@ -47,7 +47,7 @@
>  #include "sysemu/runstate.h"
>  #include "sysemu/reset.h"
>  
> -#define MACROM_ADDR     0x40000000
> +#define MACROM_ADDR     0x40800000
>  #define MACROM_SIZE     0x00100000
>  
>  #define MACROM_FILENAME "MacROM.bin"
> @@ -128,6 +128,27 @@ 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 */
> +
> +    /* via2[vDirB] |= VIA2B_vPower */
> +    0x20, 0x7C, 0x50, 0xF0, 0x24, 0x00, /* moveal VIA2_BASE+vDirB,%a0 */
> +    0x10, 0x10,                         /* moveb %a0@,%d0 */
> +    0x00, 0x00, 0x00, 0x04,             /* orib #4,%d0 */
> +    0x10, 0x80,                         /* moveb %d0,%a0@ */
> +
> +    /* via2[vBufB] &= ~VIA2B_vPower */
> +    0x20, 0x7C, 0x50, 0xF0, 0x20, 0x00, /* moveal VIA2_BASE+vBufB,%a0 */
> +    0x10, 0x10,                         /* moveb %a0@,%d0 */
> +    0x02, 0x00, 0xFF, 0xFB,             /* andib #-5,%d0 */
> +    0x10, 0x80,                         /* moveb %d0,%a0@ */
> +
> +    /* while (true) ; */
> +    0x60, 0xFE                          /* bras [self] */
> +};
> +
>  static void q800_init(MachineState *machine)
>  {
>      M68kCPU *cpu = NULL;
> @@ -340,6 +361,12 @@ static void q800_init(MachineState *machine)
>                    (graphic_width * graphic_depth + 7) / 8);
>          BOOTINFO1(cs->as, parameters_base, BI_MAC_SCCBASE, SCC_BASE);
>  
> +        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,
>                          kernel_cmdline);
> 

Reviewed-by: Laurent Vivier <laurent@vivier.eu>