Module Name:    src
Committed By:   martin
Date:           Fri Sep 15 13:25:34 UTC 2017

Modified Files:
        src/sys/arch/sparc/stand/ofwboot: Locore.c boot.c boot.h ofdev.c
            openfirm.h version
        src/sys/arch/sparc64/include: bootinfo.h

Log Message:
Add more details about the boot device as a new bootinfo record type.
>From within the bootloader, when we have readily accessible instance
handles of the boot device, it is easy to query more details like SCSI
LUN, target, and FC-AL wwn from the firmware.
The kernel later would have a hard time getting theses, but can make good
use to match the boot device.


To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.16 src/sys/arch/sparc/stand/ofwboot/Locore.c
cvs rdiff -u -r1.34 -r1.35 src/sys/arch/sparc/stand/ofwboot/boot.c
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/sparc/stand/ofwboot/boot.h
cvs rdiff -u -r1.36 -r1.37 src/sys/arch/sparc/stand/ofwboot/ofdev.c
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/sparc/stand/ofwboot/openfirm.h
cvs rdiff -u -r1.22 -r1.23 src/sys/arch/sparc/stand/ofwboot/version
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/sparc64/include/bootinfo.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/sparc/stand/ofwboot/Locore.c
diff -u src/sys/arch/sparc/stand/ofwboot/Locore.c:1.15 src/sys/arch/sparc/stand/ofwboot/Locore.c:1.16
--- src/sys/arch/sparc/stand/ofwboot/Locore.c:1.15	Sat Oct 10 06:50:25 2015
+++ src/sys/arch/sparc/stand/ofwboot/Locore.c	Fri Sep 15 13:25:34 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: Locore.c,v 1.15 2015/10/10 06:50:25 martin Exp $	*/
+/*	$NetBSD: Locore.c,v 1.16 2017/09/15 13:25:34 martin Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -35,6 +35,7 @@
 #include "openfirm.h"
 
 #include <machine/cpu.h>
+#include <machine/vmparam.h>
 
 /*
  * We are trying to boot a sparc v9 cpu, so openfirmware has to be 64bit,
@@ -154,6 +155,26 @@ OF_instance_to_path(int ihandle, char *b
 }
 
 int
+OF_parent(int phandle)
+{
+	struct {
+		cell_t name;
+		cell_t nargs;
+		cell_t nreturns;
+		cell_t phandle;
+		cell_t parent;
+	} args;
+
+	args.name = ADR2CELL("parent");
+	args.nargs = 1;
+	args.nreturns = 1;
+	args.phandle = HDL2CELL(phandle);
+	if (openfirmware(&args) == -1)
+		return 0;
+	return args.parent;
+}
+
+int
 OF_getprop(int handle, const char *prop, void *buf, int buflen)
 {
 	struct {
@@ -208,6 +229,66 @@ OF_setprop(u_int handle, char *prop, voi
 #endif
 
 int
+OF_interpret(const char *cmd, int nargs, int nreturns, ...)
+{
+	va_list ap;
+	struct {
+		cell_t name;
+		cell_t nargs;
+		cell_t nreturns;
+		cell_t slot[16];
+	} args;
+	cell_t status;
+	int i = 0;
+
+	args.name = ADR2CELL("interpret");
+	args.nargs = ++nargs;
+	args.nreturns = ++nreturns;
+	args.slot[i++] = ADR2CELL(cmd);
+	va_start(ap, nreturns);
+	while (i < nargs) {
+		args.slot[i++] = va_arg(ap, cell_t);
+	}
+	if (openfirmware(&args) == -1) {
+		va_end(ap);
+		return (-1);
+	}
+	status = args.slot[i++];
+	while (i < nargs+nreturns) {
+		*va_arg(ap, cell_t *) = args.slot[i++];
+	}
+	va_end(ap);
+
+	return status;
+}
+
+int
+OF_package_to_path(int phandle, char *buf, int buflen)
+{
+	struct {
+		cell_t name;
+		cell_t nargs;
+		cell_t nreturns;
+		cell_t phandle;
+		cell_t buf;
+		cell_t buflen;
+		cell_t length;
+	} args;
+
+	if (buflen > PAGE_SIZE)
+		return -1;
+	args.name = ADR2CELL("package-to-path");
+	args.nargs = 3;
+	args.nreturns = 1;
+	args.phandle = HDL2CELL(phandle);
+	args.buf = ADR2CELL(buf);
+	args.buflen = buflen;
+	if (openfirmware(&args) < 0)
+		return -1;
+	return args.length;
+}
+
+int
 OF_open(const char *dname)
 {
 	struct {

Index: src/sys/arch/sparc/stand/ofwboot/boot.c
diff -u src/sys/arch/sparc/stand/ofwboot/boot.c:1.34 src/sys/arch/sparc/stand/ofwboot/boot.c:1.35
--- src/sys/arch/sparc/stand/ofwboot/boot.c:1.34	Wed Aug 31 16:24:34 2016
+++ src/sys/arch/sparc/stand/ofwboot/boot.c	Fri Sep 15 13:25:34 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: boot.c,v 1.34 2016/08/31 16:24:34 martin Exp $	*/
+/*	$NetBSD: boot.c,v 1.35 2017/09/15 13:25:34 martin Exp $	*/
 
 /*
  * Copyright (c) 1997, 1999 Eduardo E. Horvath.  All rights reserved.
@@ -284,6 +284,9 @@ jump_to_kernel(u_long *marks, char *kern
 	bi_add(&bi_kend, BTINFO_KERNEND, sizeof(bi_kend));
 	bi_howto.boothowto = boothowto;
 	bi_add(&bi_howto, BTINFO_BOOTHOWTO, sizeof(bi_howto));
+	if (bootinfo_pass_bootunit)
+		bi_add(&bi_unit, BTINFO_BOOTDEV_UNIT,
+		    sizeof(bi_unit));
 	if (bootinfo_pass_bootdev) {
 		struct {
 			struct btinfo_common common;

Index: src/sys/arch/sparc/stand/ofwboot/boot.h
diff -u src/sys/arch/sparc/stand/ofwboot/boot.h:1.10 src/sys/arch/sparc/stand/ofwboot/boot.h:1.11
--- src/sys/arch/sparc/stand/ofwboot/boot.h:1.10	Thu Feb 20 14:50:39 2014
+++ src/sys/arch/sparc/stand/ofwboot/boot.h	Fri Sep 15 13:25:34 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: boot.h,v 1.10 2014/02/20 14:50:39 joerg Exp $	*/
+/*	$NetBSD: boot.h,v 1.11 2017/09/15 13:25:34 martin Exp $	*/
 
 /*-
  * Copyright (c) 2005 The NetBSD Foundation, Inc.
@@ -67,6 +67,9 @@ void	loadfile_set_allocator(int);
 void	freeall(void);
 
 /* ofdev.c */
+extern struct btinfo_bootdev_unit bi_unit;
+extern bool bootinfo_pass_bootunit;
+
 char *filename(char *, char *);
 
 /* boot.c */

Index: src/sys/arch/sparc/stand/ofwboot/ofdev.c
diff -u src/sys/arch/sparc/stand/ofwboot/ofdev.c:1.36 src/sys/arch/sparc/stand/ofwboot/ofdev.c:1.37
--- src/sys/arch/sparc/stand/ofwboot/ofdev.c:1.36	Sat Mar 25 09:21:21 2017
+++ src/sys/arch/sparc/stand/ofwboot/ofdev.c	Fri Sep 15 13:25:34 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ofdev.c,v 1.36 2017/03/25 09:21:21 martin Exp $	*/
+/*	$NetBSD: ofdev.c,v 1.37 2017/09/15 13:25:34 martin Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -61,6 +61,9 @@
 extern char bootdev[];
 extern bool root_fs_quickseekable;
 
+struct btinfo_bootdev_unit bi_unit;
+bool bootinfo_pass_bootunit = false;
+
 /*
  * This is ugly.  A path on a sparc machine is something like this:
  *
@@ -358,6 +361,69 @@ search_label(struct of_dev *devp, u_long
 	return ("no disk label");
 }
 
+static void
+device_target_unit(const char *dev, int ihandle)
+{
+	cell_t units[4], phandle, myself, depth = 0, odepth = 0, cnt;
+	char buf[256];
+
+	/* init the data passed to the kernel */
+	bootinfo_pass_bootunit = false;
+	memset(&bi_unit, 0, sizeof(bi_unit));
+
+	/* save old my-self value */
+	OF_interpret("my-self", 0, 1, &myself);
+	/* set our device as my-self */
+	OF_interpret("to my-self", 1, 0, HDL2CELL(ihandle));
+
+	/*
+	 * my-unit delivers a variable number of cells, we could
+	 * walk up the path and find a #address-cells value that
+	 * describes it, but it seems to just work this simple
+	 * way.
+	 */
+	OF_interpret("depth", 0, 1, &odepth);	
+	OF_interpret("my-unit depth", 0, 5, &depth,
+	    &units[0], &units[1], &units[2], &units[3]);
+	cnt = depth-odepth;
+
+	/*
+	 * Old versions of QEMU's OpenBIOS have a bug in the
+	 * CIF implementation for instance_to_package, test
+	 * for that explicitly here and work around it if needed.
+	 */
+	phandle = OF_instance_to_package(ihandle);	
+	OF_package_to_path(phandle, buf, sizeof(buf));
+	buf[sizeof(buf)-1] = 0;
+	if (strlen(buf) > 2 && strlen(dev) > 2 &&
+	    strncmp(buf, dev, strlen(buf)) != 0) {
+		DPRINTF(("OpenBIOS workaround: phandle %" PRIx32 "is %s, "
+		    "does not match %s\n", (uint32_t)phandle, buf, dev));
+		OF_interpret("my-self ihandle>non-interposed-phandle",
+		     0, 1, &phandle);
+		OF_package_to_path(phandle, buf, sizeof(buf));
+		DPRINTF(("new phandle %" PRIx32 " is %s\n",
+		    (uint32_t)phandle, buf));
+	}
+
+	bi_unit.phandle = phandle;
+	bi_unit.parent = OF_parent(phandle);
+	bi_unit.lun = units[cnt > 2 ? 3 : 1];
+	bi_unit.target = units[cnt > 2 ? 2 : 0];
+	if (cnt >= 4)
+		bi_unit.wwn = (uint64_t)units[0] << 32 | (uint32_t)units[1];
+	DPRINTF(("boot device package: %" PRIx32 ", parent: %" PRIx32 
+	    ", lun: %" PRIu32 ", target: %" PRIu32 ", wwn: %" PRIx64 "\n",
+	    bi_unit.phandle, bi_unit.parent, bi_unit.lun, bi_unit.target,
+	    bi_unit.wwn));
+
+	/* restore my-self */
+	OF_interpret("to my-self", 1, 0, myself);
+
+	/* now that we have gatherd all the details, pass them to the kernel */
+	bootinfo_pass_bootunit = true;
+}
+
 int
 devopen(struct open_file *of, const char *name, char **file)
 {
@@ -373,6 +439,7 @@ devopen(struct open_file *of, const char
 	size_t readsize;
 	char *errmsg = NULL, *pp = NULL, savedpart = 0;
 	int error = 0;
+	bool get_target_unit = false;
 
 	if (ofdev.handle != -1)
 		panic("devopen: ofdev already in use");
@@ -412,6 +479,9 @@ devopen(struct open_file *of, const char
 		return ENXIO;
 	DPRINTF(("devopen: %s is a %s device\n", fname, b.buf));
 	if (strcmp(b.buf, "block") == 0 || strcmp(b.buf, "scsi") == 0) {
+
+		get_target_unit = true;
+
 		pp = strrchr(fname, ':');
 		if (pp && pp[1] >= 'a' && pp[1] <= 'f' && pp[2] == 0) {
 			savedpart = pp[1];
@@ -458,6 +528,10 @@ open_again:
 		return ENXIO;
 	}
 	DPRINTF(("devopen: %s is now open\n", fname));
+
+	if (get_target_unit)
+		device_target_unit(fname, handle);
+
 	memset(&ofdev, 0, sizeof ofdev);
 	ofdev.handle = handle;
 	if (strcmp(b.buf, "block") == 0 || strcmp(b.buf, "scsi") == 0) {

Index: src/sys/arch/sparc/stand/ofwboot/openfirm.h
diff -u src/sys/arch/sparc/stand/ofwboot/openfirm.h:1.5 src/sys/arch/sparc/stand/ofwboot/openfirm.h:1.6
--- src/sys/arch/sparc/stand/ofwboot/openfirm.h:1.5	Sat May 21 15:50:42 2011
+++ src/sys/arch/sparc/stand/ofwboot/openfirm.h	Fri Sep 15 13:25:34 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: openfirm.h,v 1.5 2011/05/21 15:50:42 tsutsui Exp $	*/
+/*	$NetBSD: openfirm.h,v 1.6 2017/09/15 13:25:34 martin Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -70,4 +70,5 @@ vaddr_t	OF_map_phys(paddr_t, off_t, vadd
 paddr_t	OF_alloc_phys(int, int);
 paddr_t	OF_claim_phys(paddr_t, int);
 int	OF_free_phys(paddr_t, int);
+int	OF_interpret(const char *, int, int, ...);
 void	OF_initialize(void);

Index: src/sys/arch/sparc/stand/ofwboot/version
diff -u src/sys/arch/sparc/stand/ofwboot/version:1.22 src/sys/arch/sparc/stand/ofwboot/version:1.23
--- src/sys/arch/sparc/stand/ofwboot/version:1.22	Sat Mar 25 09:22:02 2017
+++ src/sys/arch/sparc/stand/ofwboot/version	Fri Sep 15 13:25:34 2017
@@ -1,4 +1,4 @@
-$NetBSD: version,v 1.22 2017/03/25 09:22:02 martin Exp $
+$NetBSD: version,v 1.23 2017/09/15 13:25:34 martin Exp $
 
 NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE.  The format of this
 file is important - make sure the entries are appended on end, last item
@@ -23,3 +23,4 @@ is taken as the current.
 1.17:	Add support for sun4v architecture
 1.18:	Fix loading of kernels with huge .bss
 1.19:	Support booting from virtio devices
+1.20:	Provide more boot device details

Index: src/sys/arch/sparc64/include/bootinfo.h
diff -u src/sys/arch/sparc64/include/bootinfo.h:1.7 src/sys/arch/sparc64/include/bootinfo.h:1.8
--- src/sys/arch/sparc64/include/bootinfo.h:1.7	Mon May 28 21:09:52 2012
+++ src/sys/arch/sparc64/include/bootinfo.h	Fri Sep 15 13:25:34 2017
@@ -1,4 +1,4 @@
-/*       $NetBSD: bootinfo.h,v 1.7 2012/05/28 21:09:52 martin Exp $        */
+/*       $NetBSD: bootinfo.h,v 1.8 2017/09/15 13:25:34 martin Exp $        */
 
 /*-
  * Copyright (c) 2005 The NetBSD Foundation, Inc.
@@ -98,6 +98,7 @@
 #define BTINFO_ITLB			103
 #define BTINFO_KERNEND			104
 #define BTINFO_BOOTDEV			105
+#define BTINFO_BOOTDEV_UNIT		106
 
 #define LOOKUP_BOOTINFO(btp, info) \
 do { \
@@ -131,4 +132,13 @@ struct btinfo_bootdev {
 	char name[1];
 };
 
+struct btinfo_bootdev_unit {
+	struct btinfo_common common;
+	uint32_t phandle;	/* the boot path package handle */
+	uint32_t parent;	/* the controller handle */
+	uint32_t lun;		/* scsi address details */
+	uint32_t target;	/* or primary/secondary channel for IDE */
+	uint64_t wwn;		/* zero for non FC-AL drives */
+};
+
 #endif /* _BOOTINFO_H_ */

Reply via email to