Module Name:    src
Committed By:   mrg
Date:           Sun Feb  5 22:42:39 UTC 2023

Modified Files:
        src/sys/arch/evbarm/evbarm: autoconf.c
        src/sys/arch/evbarm/fdt: fdt_machdep.c
        src/sys/arch/evbarm/include: types.h

Log Message:
fix root detection on evbarm when raid is involved

there are several problems solved in this change:
- lots of work was re-done when we already have determined the
  device booted from, so several new early returns introduced
  if booted_device has been set
- due to the lack of cpu_bootconf(), raidframe softroot would
  override "root=xxx" on the boot command line (note that
  platforms that use eg, device_register() to detect the boot
  device are not affected by this issue as they find the
  boot device much earlier.)
- in the new cpu_bootconf(), switch the order of the platform
  boot-config with the set_root_device() call.  this avoids a
  problem where "root=xxx" is checked after automated methods,
  and is thus ignored.
- in fdt_detect_root_device(), remove the code to add "root=xxx""
  string to the boot_args[] that would be later parsed by the
  set_root_device() call, and simply set booted_device and, for
  mbr installs, booted_partition directly.  also, for any
  successful call, perform an early return.
- define __HAVE_CPU_BOOTCONF so early boot calls cpu_bootconf().

tested on:
- rockpro64 booting from emmc, sata (big, and little endian)
- rockpro64 loading kernel from msdos partition
- rockpro64 booting from network (fails to auto-detect, with or
  without this change)
- quartz64 booting from nvme
- lx2k booting from nvme

XXX: pullup-10


To generate a diff of this commit:
cvs rdiff -u -r1.23 -r1.24 src/sys/arch/evbarm/evbarm/autoconf.c
cvs rdiff -u -r1.99 -r1.100 src/sys/arch/evbarm/fdt/fdt_machdep.c
cvs rdiff -u -r1.15 -r1.16 src/sys/arch/evbarm/include/types.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/evbarm/evbarm/autoconf.c
diff -u src/sys/arch/evbarm/evbarm/autoconf.c:1.23 src/sys/arch/evbarm/evbarm/autoconf.c:1.24
--- src/sys/arch/evbarm/evbarm/autoconf.c:1.23	Sat Dec 19 21:54:00 2020
+++ src/sys/arch/evbarm/evbarm/autoconf.c	Sun Feb  5 22:42:39 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: autoconf.c,v 1.23 2020/12/19 21:54:00 mrg Exp $	*/
+/*	$NetBSD: autoconf.c,v 1.24 2023/02/05 22:42:39 mrg Exp $	*/
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.23 2020/12/19 21:54:00 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.24 2023/02/05 22:42:39 mrg Exp $");
 
 #include "opt_md.h"
 #include "opt_ddb.h"
@@ -108,6 +108,9 @@ set_root_device(void)
 	char *ptr, *end, *buf;
 	size_t len;
 
+	if (booted_device)
+		return;
+
 	if (boot_args == NULL)
 		return;
 
@@ -118,7 +121,7 @@ set_root_device(void)
 		return;
 
 	/* NUL-terminate string, get_bootconf_option doesn't */
-	for (end=ptr; *end != '\0'; ++end) {
+	for (end = ptr; *end != '\0'; ++end) {
 		if (*end == ' ' || *end == '\t') {
 			break;
 		}
@@ -144,16 +147,25 @@ set_root_device(void)
 #endif
 
 /*
- * Set up the root device from the boot args
+ * Set up the root device from the boot args.
+ *
+ * cpu_bootconf() is called before RAIDframe root detection,
+ * and cpu_rootconf() is called after.
  */
 void
-cpu_rootconf(void)
+cpu_bootconf(void)
 {
 #ifndef MEMORY_DISK_IS_ROOT
+	set_root_device();
 	if (evbarm_cpu_rootconf)
 		(*evbarm_cpu_rootconf)();
-	set_root_device();
 #endif
+}
+
+void
+cpu_rootconf(void)
+{
+	cpu_bootconf();
 	aprint_normal("boot device: %s\n",
 	    booted_device != NULL ? device_xname(booted_device) : "<unknown>");
 	rootconf();

Index: src/sys/arch/evbarm/fdt/fdt_machdep.c
diff -u src/sys/arch/evbarm/fdt/fdt_machdep.c:1.99 src/sys/arch/evbarm/fdt/fdt_machdep.c:1.100
--- src/sys/arch/evbarm/fdt/fdt_machdep.c:1.99	Fri Nov  4 10:51:17 2022
+++ src/sys/arch/evbarm/fdt/fdt_machdep.c	Sun Feb  5 22:42:39 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: fdt_machdep.c,v 1.99 2022/11/04 10:51:17 jmcneill Exp $ */
+/* $NetBSD: fdt_machdep.c,v 1.100 2023/02/05 22:42:39 mrg Exp $ */
 
 /*-
  * Copyright (c) 2015-2017 Jared McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.99 2022/11/04 10:51:17 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fdt_machdep.c,v 1.100 2023/02/05 22:42:39 mrg Exp $");
 
 #include "opt_arm_debug.h"
 #include "opt_bootconfig.h"
@@ -741,16 +741,10 @@ delay(u_int us)
 static void
 fdt_detect_root_device(device_t dev)
 {
-	struct mbr_sector mbr;
-	uint8_t buf[DEV_BSIZE];
-	uint8_t hash[16];
-	const uint8_t *rhash;
-	char rootarg[64];
-	struct vnode *vp;
-	MD5_CTX md5ctx;
 	int error, len;
-	size_t resid;
-	u_int part;
+
+	if (booted_device)
+		return;
 
 	const int chosen = OF_finddevice("/chosen");
 	if (chosen < 0)
@@ -758,6 +752,14 @@ fdt_detect_root_device(device_t dev)
 
 	if (of_hasprop(chosen, "netbsd,mbr") &&
 	    of_hasprop(chosen, "netbsd,partition")) {
+		struct mbr_sector mbr;
+		uint8_t buf[DEV_BSIZE];
+		uint8_t hash[16];
+		const uint8_t *rhash;
+		struct vnode *vp;
+		MD5_CTX md5ctx;
+		size_t resid;
+		u_int part;
 
 		/*
 		 * The bootloader has passed in a partition index and MD5 hash
@@ -787,22 +789,22 @@ fdt_detect_root_device(device_t dev)
 		MD5Update(&md5ctx, (void *)&mbr, sizeof(mbr));
 		MD5Final(hash, &md5ctx);
 
-		if (memcmp(rhash, hash, 16) != 0)
-			return;
+		if (memcmp(rhash, hash, 16) == 0) {
+			booted_device = dev;
+			booted_partition = part;
+		}
 
-		snprintf(rootarg, sizeof(rootarg), " root=%s%c", device_xname(dev), part + 'a');
-		strcat(boot_args, rootarg);
+		return;
 	}
 
 	if (of_hasprop(chosen, "netbsd,gpt-guid")) {
-		char guidbuf[UUID_STR_LEN];
-		const struct uuid *guid = fdtbus_get_prop(chosen, "netbsd,gpt-guid", &len);
-		if (guid == NULL || len != 16)
-			return;
+		const struct uuid *guid =
+		    fdtbus_get_prop(chosen, "netbsd,gpt-guid", &len);
+
+		if (guid != NULL && len == 16)
+			booted_device = dev;
 
-		uuid_snprintf(guidbuf, sizeof(guidbuf), guid);
-		snprintf(rootarg, sizeof(rootarg), " root=wedge:%s", guidbuf);
-		strcat(boot_args, rootarg);
+		return;
 	}
 
 	if (of_hasprop(chosen, "netbsd,gpt-label")) {
@@ -813,14 +815,19 @@ fdt_detect_root_device(device_t dev)
 		device_t dv = dkwedge_find_by_wname(label);
 		if (dv != NULL)
 			booted_device = dv;
+
+		return;
 	}
 
 	if (of_hasprop(chosen, "netbsd,booted-mac-address")) {
-		const uint8_t *macaddr = fdtbus_get_prop(chosen, "netbsd,booted-mac-address", &len);
+		const uint8_t *macaddr =
+		    fdtbus_get_prop(chosen, "netbsd,booted-mac-address", &len);
+		struct ifnet *ifp;
+
 		if (macaddr == NULL || len != 6)
 			return;
+
 		int s = pserialize_read_enter();
-		struct ifnet *ifp;
 		IFNET_READER_FOREACH(ifp) {
 			if (memcmp(macaddr, CLLADDR(ifp->if_sadl), len) == 0) {
 				device_t dv = device_find_by_xname(ifp->if_xname);
@@ -830,6 +837,8 @@ fdt_detect_root_device(device_t dev)
 			}
 		}
 		pserialize_read_exit(s);
+
+		return;
 	}
 }
 
@@ -878,7 +887,6 @@ fdt_cpu_rootconf(void)
 {
 	device_t dev;
 	deviter_t di;
-	char *ptr;
 
 	if (booted_device != NULL)
 		return;
@@ -887,11 +895,11 @@ fdt_cpu_rootconf(void)
 		if (device_class(dev) != DV_DISK)
 			continue;
 
-		if (get_bootconf_option(boot_args, "root", BOOTOPT_TYPE_STRING, &ptr) != 0)
-			break;
-
 		if (device_is_a(dev, "ld") || device_is_a(dev, "sd") || device_is_a(dev, "wd"))
 			fdt_detect_root_device(dev);
+
+		if (booted_device != NULL)
+			break;
 	}
 	deviter_release(&di);
 }

Index: src/sys/arch/evbarm/include/types.h
diff -u src/sys/arch/evbarm/include/types.h:1.15 src/sys/arch/evbarm/include/types.h:1.16
--- src/sys/arch/evbarm/include/types.h:1.15	Thu Apr  1 04:35:45 2021
+++ src/sys/arch/evbarm/include/types.h	Sun Feb  5 22:42:39 2023
@@ -1,8 +1,10 @@
-/*	$NetBSD: types.h,v 1.15 2021/04/01 04:35:45 simonb Exp $	*/
+/*	$NetBSD: types.h,v 1.16 2023/02/05 22:42:39 mrg Exp $	*/
 
 #ifndef _EVBARM_TYPES_H_
 #define	_EVBARM_TYPES_H_
 
+#define	__HAVE_CPU_BOOTCONF
+
 #ifdef __aarch64__
 #include <aarch64/types.h>
 

Reply via email to