Hi,
over the last months there have been multiple reports of sparc64 not
booting with OF_map_phys() calls failing, see, e.g., the thread
https://marc.info/?t=164371993700001&r=1&w=2 .
In early December 2021, writing to disk from Open Firmware was disabled,
but at least in Qemu I still get this error when booting the most
recent miniroot snapshot,
https://cdn.openbsd.org/pub/OpenBSD/snapshots/sparc64/miniroot71.img .
I believe the actual reason is a bug in the OF_map_phys() function of
ofwboot (in Locore.c) which does not correspond to the Open Firmware
documentation. As a result, the Open Firmware stack is garbled, and
some images just happen to have the right values where OF_map_phys()
reads something it believes to be a return value and end up
successfully booting nonetheless.
The attached patch fixes that (and makes the according change to the
kernel call in ofw_machdep.c). After rebuilding ofwboot with it and
injecting that in miniroot71.img, it successfully boots in Qemu.
I don't have sparc64 hardware readily available and was thus unable to
verify this on hardware. The bug was inherited from NetBSD where this
started showing up with a compiler change roughly 1 year ago, and
there the patch helped for both Qemu and hardware, see also
https://gnats.netbsd.org/56829 .
cheers,
Harold
--- src/sys/arch/sparc64/stand/ofwboot/Locore.c.orig Mon Dec 31 12:44:57 2018
+++ src/sys/arch/sparc64/stand/ofwboot/Locore.c Sun May 15 23:26:52 2022
@@ -452,13 +452,11 @@
cell_t vaddr;
cell_t paddr_hi;
cell_t paddr_lo;
- cell_t status;
- cell_t retaddr;
} args;
args.name = ADR2CELL("call-method");
args.nargs = 7;
- args.nreturns = 1;
+ args.nreturns = 0;
args.method = ADR2CELL("map");
args.ihandle = HDL2CELL(mmuh);
args.mode = mode;
@@ -469,9 +467,7 @@
if (openfirmware(&args) == -1)
return -1;
- if (args.status)
- return -1;
- return (vaddr_t)args.retaddr;
+ return 0;
}
--- src/sys/arch/sparc64/sparc64/ofw_machdep.c.orig Tue Aug 28 02:00:42 2018
+++ src/sys/arch/sparc64/sparc64/ofw_machdep.c Sun May 15 23:45:43 2022
@@ -350,8 +350,6 @@
cell_t vaddr;
cell_t phys_hi;
cell_t phys_lo;
- cell_t status;
- cell_t retaddr;
} args;
if (mmuh == -1 && ((mmuh = get_mmu_handle()) == -1)) {
@@ -360,7 +358,7 @@
}
args.name = ADR2CELL("call-method");
args.nargs = 7;
- args.nreturns = 1;
+ args.nreturns = 0;
args.method = ADR2CELL("map");
args.ihandle = HDL2CELL(mmuh);
args.mode = mode;
@@ -371,9 +369,7 @@
if (openfirmware(&args) == -1)
return -1;
- if (args.status)
- return -1;
- return (int)args.retaddr;
+ return 0;
}