Using this patch stacked on Steven Noonan's I was able to make BootX from Mac OS X 10.4 load XNU successfully in qemu-system-ppc.
Unfortunately, most of this patch is nothing but a mere hack to find out what we really need to get this working.
Also I didn't manage to get anything but 10.4 running. Other versions broke in the partition table interpretation.
I would not feel good taking the patch as is, because it would be better to implement the correct Forth magic to make the real callbacks work. Here is what I found to be broken:
- unselect-dev is missing - local variables don't work ({ ... }) - I ran into an endless loop, getting isi and dsi faults on the same 2 addresses all the time
Also, Qemu's only usable Desktop PPC target is a G3 Beige which is only supported up to 10.2.8 IIRC. So even getting the bootloader running for 10.4 didn't exactly buy me much.
Don't apply the patch as is! It'd be great to see someone build on this! --- arch/ppc/qemu/ofmem.c | 4 ++-- modules/client.c | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/arch/ppc/qemu/ofmem.c b/arch/ppc/qemu/ofmem.c index a1a8fb1..32642e2 100644 --- a/arch/ppc/qemu/ofmem.c +++ b/arch/ppc/qemu/ofmem.c @@ -716,8 +716,8 @@ hash_page_32( ulong ea, ulong phys, int mode )
/* out of slots, just evict one */ if( !found ) { - i = next_grab_slot + 1; - next_grab_slot = (next_grab_slot + 1) % 8; + i = next_grab_slot + 3; + next_grab_slot = (next_grab_slot + 3) % 8; } i--; upte[i*2] = cmp; diff --git a/modules/client.c b/modules/client.c index a2e8405..a8c89ff 100644 --- a/modules/client.c +++ b/modules/client.c @@ -49,6 +49,46 @@ handle_calls( prom_args_t *pb ) pb->nargs, pb->nret); #endif
+#if 1 + if (!strcmp(pb->service, "interpret")) + { + char *ns; + + ns = strstr((char*)pb->args[0], "{ ; dpth }"); + if (ns) return 0; + + ns = strstr((char*)pb->args[0], "dev /chosen "); + if (ns) memcpy(ns, " " /chosen"", 11); + } + else if (!strcmp(pb->service, "call-method")) + { + if (!strncmp((char*)pb->args[0], "slw_init_keymap", 15)) { + + char *a = (char*)malloc(20); + memset(a, 0x00, 20); + pb->args[4] = (uint32_t)a; + pb->args[3] = 0; + + return 0; + } + if (!strncmp((char*)pb->args[0], "slw_emit", strlen("slw_emit"))) { + PUSH( (char)pb->args[2] ); + fword("emit"); + + return 0; + } + if (!strncmp((char*)pb->args[0], "slw_cr", strlen("slw_cr"))) { + PUSH( '\n' ); + fword("emit"); + return 0; + } + if (!strncmp((char*)pb->args[0], "slw_update_keymap", strlen("slw_update_keymap"))) return 0; + if (!strncmp((char*)pb->args[0], "slw_set_output_level", strlen("slw_set_output_level"))) return 0; + if (!strncmp((char*)pb->args[0], "slw_spin_init", strlen("slw_spin_init"))) return 0; + if (!strncmp((char*)pb->args[0], "slw_spin", strlen("slw_spin"))) return 0; + } +#endif + for( i=pb->nargs-1; i>=0; i-- ) PUSH( pb->args[i] );