From: Ted Bullock Subject: Re: Booting 8.0 on qemu-system-sparc64 fails Unimplemented service set-symbol-lookup To: David Stanaway Cc: sparc@openbsd.org, tech@openbsd.org Date: Tue, 03 Nov 2026 23:19:04 -0600 Hi David and tech@ Ok, so the OpenBSD kernel and bootloader have a defect according to the open firmware specification that stops openbsd from booting with sparc on qemu with its bundled firmware. We’re requesting zero return values and leaving no space for the catch result and ending up clobbered with overwritten memory. The openboot firmware is more graceful for our request than openbios which is why we don't see this on physical sun machines. Anyway, this shows up a few times for the call-method firmware operation, it's supposed to be able to return the extra value and we are getting hit by that. The following patch fixes the kernel and the bootloader so they follow the Open Firmware Client Interface Developer’s Guide. Page 26 has the rule: The arguments N_args and N_returns specify the number of calling arguments and return values; they must agree with the number of arguments and return values expected by the particular service. and Page 30 describes "call-method" OUT: catch-result, stack-result1, ... , stack-resultQ Pops the result returned by catch into catch-result. If that result is zero, pops up to N_returns-1 items from the Forth data stack into the returned values portion of the argument array, with stack_result1 corresponding to the top of the stack. Anyway, my Sun Blade boots without this patch. With the patch, QEMU boots with its shipped BIOS. --- a/sys/arch/sparc64/sparc64/ofw_machdep.c +++ b/sys/arch/sparc64/sparc64/ofw_machdep.c @@ -260,6 +260,7 @@ cell_t ihandle; cell_t len; cell_t vaddr; + cell_t status; } args; if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) { @@ -268,7 +269,7 @@ } args.name = ADR2CELL("call-method"); args.nargs = 4; - args.nreturns = 0; + args.nreturns = 1; args.method = ADR2CELL("release"); args.ihandle = HDL2CELL(mmuh); args.vaddr = ADR2CELL(vaddr); @@ -293,6 +294,7 @@ cell_t ihandle; cell_t len; cell_t vaddr; + cell_t status; } args; if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) { @@ -301,7 +303,7 @@ } args.name = ADR2CELL("call-method"); args.nargs = 4; - args.nreturns = 0; + args.nreturns = 1; args.method = ADR2CELL("unmap"); args.ihandle = HDL2CELL(mmuh); args.vaddr = ADR2CELL(vaddr); @@ -328,6 +330,7 @@ cell_t vaddr; cell_t phys_hi; cell_t phys_lo; + cell_t status; } args; if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) { @@ -336,7 +339,7 @@ } args.name = ADR2CELL("call-method"); args.nargs = 7; - args.nreturns = 0; + args.nreturns = 1; args.method = ADR2CELL("map"); args.ihandle = HDL2CELL(mmuh); args.mode = mode; @@ -443,6 +446,7 @@ cell_t len; cell_t phys_hi; cell_t phys_lo; + cell_t status; } args; if (memh == -1 && ((memh = get_memory_handle()) == -1)) { @@ -451,7 +455,7 @@ } args.name = ADR2CELL("call-method"); args.nargs = 5; - args.nreturns = 0; + args.nreturns = 1; args.method = ADR2CELL("release"); args.ihandle = HDL2CELL(memh); args.len = len; --- a/sys/arch/sparc64/stand/ofwboot/Locore.c +++ b/sys/arch/sparc64/stand/ofwboot/Locore.c @@ -420,11 +420,12 @@ cell_t ihandle; cell_t len; cell_t vaddr; + cell_t status; } args; args.name = ADR2CELL("call-method"); args.nargs = 4; - args.nreturns = 0; + args.nreturns = 1; args.method = ADR2CELL("release"); args.ihandle = HDL2CELL(mmuh); args.vaddr = ADR2CELL(vaddr); @@ -452,11 +453,12 @@ cell_t vaddr; cell_t paddr_hi; cell_t paddr_lo; + cell_t status; } args; args.name = ADR2CELL("call-method"); args.nargs = 7; - args.nreturns = 0; + args.nreturns = 1; args.method = ADR2CELL("map"); args.ihandle = HDL2CELL(mmuh); args.mode = mode; @@ -519,11 +521,12 @@ cell_t len; cell_t phys_hi; cell_t phys_lo; + cell_t status; } args; args.name = ADR2CELL("call-method"); args.nargs = 5; - args.nreturns = 0; + args.nreturns = 1; args.method = ADR2CELL("release"); args.ihandle = HDL2CELL(memh); args.len = len;