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/8781230d57c1
branches:  trunk
changeset: 826583:8781230d57c1
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 2a200a372204 -r 8781230d57c1 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 2a200a372204 -r 8781230d57c1 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 2a200a372204 -r 8781230d57c1 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 2a200a372204 -r 8781230d57c1 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 2a200a372204 -r 8781230d57c1 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 2a200a372204 -r 8781230d57c1 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 2a200a372204 -r 8781230d57c1 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