> Date: Mon, 16 May 2022 00:13:12 +0200
> From: Harold Gutch <[email protected]>
>
> 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
Hi Harald,
Thanks for the diff. I've made some further adjustments, in
particular fixing the return type of the OF_map_phys() function. The
diff is currently in snapshots and will probably be committed soon.
Thanks again,
Mark
Index: arch/sparc64/sparc64/ofw_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/sparc64/ofw_machdep.c,v
retrieving revision 1.34
diff -u -p -r1.34 ofw_machdep.c
--- arch/sparc64/sparc64/ofw_machdep.c 28 Aug 2018 00:00:42 -0000 1.34
+++ arch/sparc64/sparc64/ofw_machdep.c 24 May 2022 20:42:41 -0000
@@ -350,8 +350,6 @@ prom_map_phys(paddr, size, vaddr, mode)
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 @@ prom_map_phys(paddr, size, vaddr, mode)
}
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;
@@ -368,12 +366,7 @@ prom_map_phys(paddr, size, vaddr, mode)
args.vaddr = ADR2CELL(vaddr);
args.phys_hi = HDQ2CELL_HI(paddr);
args.phys_lo = HDQ2CELL_LO(paddr);
-
- if (openfirmware(&args) == -1)
- return -1;
- if (args.status)
- return -1;
- return (int)args.retaddr;
+ return openfirmware(&args);
}
Index: arch/sparc64/stand/ofwboot/Locore.c
===================================================================
RCS file: /cvs/src/sys/arch/sparc64/stand/ofwboot/Locore.c,v
retrieving revision 1.16
diff -u -p -r1.16 Locore.c
--- arch/sparc64/stand/ofwboot/Locore.c 31 Dec 2018 11:44:57 -0000 1.16
+++ arch/sparc64/stand/ofwboot/Locore.c 24 May 2022 20:42:41 -0000
@@ -46,7 +46,7 @@
static vaddr_t OF_claim_virt(vaddr_t vaddr, int len);
static vaddr_t OF_alloc_virt(int len, int align);
static int OF_free_virt(vaddr_t vaddr, int len);
-static vaddr_t OF_map_phys(paddr_t paddr, off_t size, vaddr_t vaddr, int mode);
+static int OF_map_phys(paddr_t paddr, off_t size, vaddr_t vaddr, int mode);
static paddr_t OF_alloc_phys(int len, int align);
static int OF_free_phys(paddr_t paddr, int len);
@@ -438,7 +438,7 @@ OF_free_virt(vaddr_t vaddr, int len)
*
* Only works while the prom is actively mapping us.
*/
-static vaddr_t
+static int
OF_map_phys(paddr_t paddr, off_t size, vaddr_t vaddr, int mode)
{
struct {
@@ -452,13 +452,11 @@ OF_map_phys(paddr_t paddr, off_t size, v
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;
@@ -466,12 +464,7 @@ OF_map_phys(paddr_t paddr, off_t size, v
args.vaddr = ADR2CELL(vaddr);
args.paddr_hi = HDQ2CELL_HI(paddr);
args.paddr_lo = HDQ2CELL_LO(paddr);
-
- if (openfirmware(&args) == -1)
- return -1;
- if (args.status)
- return -1;
- return (vaddr_t)args.retaddr;
+ return openfirmware(&args);
}