Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch Add more details about the boot device as a new boo...
details: https://anonhg.NetBSD.org/src/rev/9697aeea9033
branches: trunk
changeset: 356282:9697aeea9033
user: martin <martin%NetBSD.org@localhost>
date: Fri Sep 15 13:25:34 2017 +0000
description:
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.
diffstat:
sys/arch/sparc/stand/ofwboot/Locore.c | 83 ++++++++++++++++++++++++++++++++-
sys/arch/sparc/stand/ofwboot/boot.c | 5 +-
sys/arch/sparc/stand/ofwboot/boot.h | 5 +-
sys/arch/sparc/stand/ofwboot/ofdev.c | 76 +++++++++++++++++++++++++++++-
sys/arch/sparc/stand/ofwboot/openfirm.h | 3 +-
sys/arch/sparc/stand/ofwboot/version | 3 +-
sys/arch/sparc64/include/bootinfo.h | 12 ++++-
7 files changed, 180 insertions(+), 7 deletions(-)
diffs (truncated from 327 to 300 lines):
diff -r 030c3f80e046 -r 9697aeea9033 sys/arch/sparc/stand/ofwboot/Locore.c
--- a/sys/arch/sparc/stand/ofwboot/Locore.c Fri Sep 15 12:02:00 2017 +0000
+++ b/sys/arch/sparc/stand/ofwboot/Locore.c Fri Sep 15 13:25:34 2017 +0000
@@ -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 @@
}
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 @@
#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 {
diff -r 030c3f80e046 -r 9697aeea9033 sys/arch/sparc/stand/ofwboot/boot.c
--- a/sys/arch/sparc/stand/ofwboot/boot.c Fri Sep 15 12:02:00 2017 +0000
+++ b/sys/arch/sparc/stand/ofwboot/boot.c Fri Sep 15 13:25:34 2017 +0000
@@ -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 @@
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;
diff -r 030c3f80e046 -r 9697aeea9033 sys/arch/sparc/stand/ofwboot/boot.h
--- a/sys/arch/sparc/stand/ofwboot/boot.h Fri Sep 15 12:02:00 2017 +0000
+++ b/sys/arch/sparc/stand/ofwboot/boot.h Fri Sep 15 13:25:34 2017 +0000
@@ -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 freeall(void);
/* ofdev.c */
+extern struct btinfo_bootdev_unit bi_unit;
+extern bool bootinfo_pass_bootunit;
+
char *filename(char *, char *);
/* boot.c */
diff -r 030c3f80e046 -r 9697aeea9033 sys/arch/sparc/stand/ofwboot/ofdev.c
--- a/sys/arch/sparc/stand/ofwboot/ofdev.c Fri Sep 15 12:02:00 2017 +0000
+++ b/sys/arch/sparc/stand/ofwboot/ofdev.c Fri Sep 15 13:25:34 2017 +0000
@@ -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 @@
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 @@
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 @@
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 @@
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) {
diff -r 030c3f80e046 -r 9697aeea9033 sys/arch/sparc/stand/ofwboot/openfirm.h
--- a/sys/arch/sparc/stand/ofwboot/openfirm.h Fri Sep 15 12:02:00 2017 +0000
+++ b/sys/arch/sparc/stand/ofwboot/openfirm.h Fri Sep 15 13:25:34 2017 +0000
@@ -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 @@
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);
diff -r 030c3f80e046 -r 9697aeea9033 sys/arch/sparc/stand/ofwboot/version
--- a/sys/arch/sparc/stand/ofwboot/version Fri Sep 15 12:02:00 2017 +0000
+++ b/sys/arch/sparc/stand/ofwboot/version Fri Sep 15 13:25:34 2017 +0000
@@ -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 @@
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
diff -r 030c3f80e046 -r 9697aeea9033 sys/arch/sparc64/include/bootinfo.h
--- a/sys/arch/sparc64/include/bootinfo.h Fri Sep 15 12:02:00 2017 +0000
+++ b/sys/arch/sparc64/include/bootinfo.h Fri Sep 15 13:25:34 2017 +0000
@@ -1,4 +1,4 @@
Home |
Main Index |
Thread Index |
Old Index