summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjake <jake@FreeBSD.org>2002-11-10 19:17:36 +0000
committerjake <jake@FreeBSD.org>2002-11-10 19:17:36 +0000
commit73d398d702d8489985977353b7f67aaabb9d840c (patch)
treeafef4c9c5cb095c3438e4a1874a05286c64fec0e
parent1ff96af1eab5b5285540c2bb95862f1687e10252 (diff)
downloadFreeBSD-src-73d398d702d8489985977353b7f67aaabb9d840c.zip
FreeBSD-src-73d398d702d8489985977353b7f67aaabb9d840c.tar.gz
Change the device path representation in libofw to use the full firmware
path, instead of an internal i386 specific one. Don't try to interpret a disklabel in ofw_disk.c, open the partition's device node directly and let the firmware do it. This fixes booting from a partition other than 'a' on sparc64, which is needed to support more installation methods. No objection: ppc
-rw-r--r--sys/boot/ofw/common/main.c37
-rw-r--r--sys/boot/ofw/libofw/Makefile4
-rw-r--r--sys/boot/ofw/libofw/devicename.c204
-rw-r--r--sys/boot/ofw/libofw/libofw.h43
-rw-r--r--sys/boot/ofw/libofw/ofw_devsearch.c135
-rw-r--r--sys/boot/ofw/libofw/ofw_disk.c218
-rw-r--r--sys/boot/powerpc/loader/metadata.c13
-rw-r--r--sys/boot/powerpc/ofw/metadata.c13
-rw-r--r--sys/boot/sparc64/loader/Makefile6
-rw-r--r--sys/boot/sparc64/loader/main.c52
-rw-r--r--sys/boot/sparc64/loader/metadata.c15
11 files changed, 93 insertions, 647 deletions
diff --git a/sys/boot/ofw/common/main.c b/sys/boot/ofw/common/main.c
index 9348135..8e201b3 100644
--- a/sys/boot/ofw/common/main.c
+++ b/sys/boot/ofw/common/main.c
@@ -32,7 +32,6 @@
#include "libofw.h"
#include "bootstrap.h"
-struct ofw_devdesc currdev; /* our current device */
struct arch_switch archsw; /* MI/MD interface boundary */
extern char end[];
@@ -123,41 +122,9 @@ main(int (*openfirm)(void *))
printf("\n");
- switch (ofw_devicetype(bootpath)) {
- case DEVT_DISK:
- currdev.d_dev = &ofwdisk;
- currdev.d_type = DEVT_DISK;
- strncpy(currdev.d_kind.ofwdisk.path, bootpath, 64);
- currdev.d_kind.ofwdisk.unit = ofwd_getunit(bootpath);
-
- if (currdev.d_kind.ofwdisk.unit == -1) {
- printf("Could not locate boot device.\n");
- OF_exit();
- }
-
- break;
-
- case DEVT_NET:
- currdev.d_dev = &netdev;
- currdev.d_type = DEVT_NET;
- strncpy(currdev.d_kind.netif.path, bootpath, 64);
- /* XXX Only works when we only look for one net device */
- currdev.d_kind.netif.unit = 0;
-
- break;
-
- case DEVT_NONE:
- default:
- printf("\n");
- printf("Could not establish type of boot device.\n");
- OF_exit();
- /* NOTREACHED */
- break;
- }
-
- env_setenv("currdev", EV_VOLATILE, ofw_fmtdev(&currdev),
+ env_setenv("currdev", EV_VOLATILE, bootpath,
ofw_setcurrdev, env_nounset);
- env_setenv("loaddev", EV_VOLATILE, ofw_fmtdev(&currdev), env_noset,
+ env_setenv("loaddev", EV_VOLATILE, bootpath, env_noset,
env_nounset);
setenv("LINES", "24", 1); /* optional */
diff --git a/sys/boot/ofw/libofw/Makefile b/sys/boot/ofw/libofw/Makefile
index 87c0535..a153f4f 100644
--- a/sys/boot/ofw/libofw/Makefile
+++ b/sys/boot/ofw/libofw/Makefile
@@ -3,8 +3,8 @@
LIB= ofw
INTERNALLIB= true
-SRCS= devicename.c elf_freebsd.c ofw_console.c ofw_copy.c ofw_devsearch.c \
- ofw_disk.c ofw_memory.c ofw_module.c ofw_net.c ofw_reboot.c \
+SRCS= devicename.c elf_freebsd.c ofw_console.c ofw_copy.c ofw_disk.c \
+ ofw_memory.c ofw_module.c ofw_net.c ofw_reboot.c \
ofw_time.c openfirm.c
CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/
diff --git a/sys/boot/ofw/libofw/devicename.c b/sys/boot/ofw/libofw/devicename.c
index 6eb08fa..c2c5f36 100644
--- a/sys/boot/ofw/libofw/devicename.c
+++ b/sys/boot/ofw/libofw/devicename.c
@@ -30,7 +30,7 @@
#include <sys/disklabel.h>
#include "libofw.h"
-static int ofw_parsedev(struct ofw_devdesc **, const char *, const char **);
+static int ofw_parsedev(struct ofw_devdesc **, const char *, const char **);
/*
* Point (dev) at an allocated device specifier for the device matching the
@@ -42,14 +42,13 @@ ofw_getdev(void **vdev, const char *devspec, const char **path)
{
struct ofw_devdesc **dev = (struct ofw_devdesc **)vdev;
int rv;
-
+
/*
* If it looks like this is just a path and no
* device, go with the current device.
*/
if ((devspec == NULL) ||
- (devspec[0] == '/') ||
- (strchr(devspec, ':') == NULL)) {
+ (strchr(devspec, '@') == NULL)) {
if (((rv = ofw_parsedev(dev, getenv("currdev"), NULL)) == 0) &&
(path != NULL))
@@ -67,110 +66,42 @@ ofw_getdev(void **vdev, const char *devspec, const char **path)
* Point (dev) at an allocated device specifier matching the string version
* at the beginning of (devspec). Return a pointer to the remaining
* text in (path).
- *
- * In all cases, the beginning of (devspec) is compared to the names
- * of known devices in the device switch, and then any following text
- * is parsed according to the rules applied to the device type.
- *
- * For disk-type devices, the syntax is:
- *
- * disk<unit>[s<slice>][<partition>]:
- *
*/
static int
ofw_parsedev(struct ofw_devdesc **dev, const char *devspec, const char **path)
{
- struct ofw_devdesc *idev;
+ struct ofw_devdesc *idev;
struct devsw *dv;
- int i, unit, slice, partition, err;
- char *cp;
- const char *np;
-
- /* minimum length check */
- if (strlen(devspec) < 2)
- return(EINVAL);
-
- /* look for a device that matches */
- for (i = 0, dv = NULL; devsw[i] != NULL; i++) {
- if (!strncmp(devspec, devsw[i]->dv_name, strlen(devsw[i]->dv_name))) {
- dv = devsw[i];
+ phandle_t handle;
+ const char *p;
+ const char *s;
+ char name[256];
+ char type[64];
+ int len;
+ int i;
+
+ for (p = s = devspec; *s != '\0'; p = s) {
+ if ((s = strchr(p + 1, '/')) == NULL)
+ s = strchr(p, '\0');
+ len = s - devspec;
+ bcopy(devspec, name, len);
+ name[len] = '\0';
+ if ((handle = OF_finddevice(name)) == -1)
break;
+ if (OF_getprop(handle, "device_type", type, sizeof(type)) == -1)
+ continue;
+ for (i = 0; (dv = devsw[i]) != NULL; i++) {
+ if (strncmp(dv->dv_name, type, strlen(type)) == 0)
+ goto found;
}
}
+ return(ENOENT);
- if (dv == NULL)
- return(ENOENT);
+found:
+ if (*s != '\0')
+ *path = s;
idev = malloc(sizeof(struct ofw_devdesc));
- err = 0;
- np = (devspec + strlen(dv->dv_name));
-
- switch(dv->dv_type) {
- case DEVT_NONE: /* XXX what to do here? Do we care? */
- break;
-
- case DEVT_DISK:
- unit = -1;
- slice = -1;
- partition = -1;
- if (*np && (*np != ':')) {
- unit = strtol(np, &cp, 10); /* next comes the unit number */
- if (cp == np) {
- err = EUNIT;
- goto fail;
- }
- if (*cp == 's') { /* got a slice number */
- np = cp + 1;
- slice = strtol(np, &cp, 10);
- if (cp == np) {
- err = ESLICE;
- goto fail;
- }
- }
- if (*cp && (*cp != ':')) {
- partition = *cp - 'a'; /* get a partition number */
- if ((partition < 0) || (partition >= MAXPARTITIONS)) {
- err = EPART;
- goto fail;
- }
- cp++;
- }
- }
- if (*cp && (*cp != ':')) {
- err = EINVAL;
- goto fail;
- }
-
- idev->d_kind.ofwdisk.unit = unit;
- idev->d_kind.ofwdisk.slice = slice;
- idev->d_kind.ofwdisk.partition = partition;
- if (path != NULL)
- *path = (*cp == 0) ? cp : cp + 1;
- break;
-
- case DEVT_NET:
- unit = 0;
-
- if (*np && (*np != ':')) {
- unit = strtol(np, &cp, 0); /* get unit number if present */
- if (cp == np) {
- err = EUNIT;
- goto fail;
- }
- }
- if (*cp && (*cp != ':')) {
- err = EINVAL;
- goto fail;
- }
-
- idev->d_kind.netif.unit = unit;
- if (path != NULL)
- *path = (*cp == 0) ? cp : cp + 1;
- break;
-
- default:
- err = EINVAL;
- goto fail;
- }
+ strcpy(idev->d_path, name);
idev->d_dev = dv;
idev->d_type = dv->dv_type;
if (dev == NULL) {
@@ -179,81 +110,18 @@ ofw_parsedev(struct ofw_devdesc **dev, const char *devspec, const char **path)
*dev = idev;
}
return(0);
-
- fail:
- free(idev);
- return(err);
-}
-
-/*
- * Hack to correctly parse bootpath for currdev. Also, enter the device into
- * the device array in the case of lazy probing (i.e. on sparc64). This has the
- * effect that the disk the loader was loaded from will always be the first
- * in the list, but it saves lots of time.
- */
-int
-ofw_parseofwdev(struct ofw_devdesc *dev, const char *devspec)
-{
- char *cp, *ep;
- int i;
- struct devsw *dv;
-
-#ifdef __sparc64__
- ofwd_enter_dev(devspec);
-#endif
- if ((dev->d_kind.ofwdisk.unit = ofwd_getunit(devspec)) == -1)
- return EUNIT;
- if ((cp = strrchr(devspec, ',')) == 0)
- return EINVAL;
- cp++;
- if (*cp != ',')
- return ESLICE;
- ep = ++cp;
- dev->d_kind.ofwdisk.slice = strtol(cp, &cp, 10) + 1;
- if (cp == ep)
- return ESLICE;
- if (*cp != ':')
- return EPART;
- dev->d_kind.ofwdisk.partition = *++cp - 'a';
-}
-
-char *
-ofw_fmtdev(void *vdev)
-{
- struct ofw_devdesc *dev = (struct ofw_devdesc *)vdev;
- static char buf[128];
- char *cp;
-
- switch(dev->d_type) {
- case DEVT_NONE:
- strcpy(buf, "(no device)");
- break;
-
- case DEVT_DISK:
- sprintf(buf, "%s%ds%d%c:", dev->d_dev->dv_name,
- dev->d_kind.ofwdisk.unit, dev->d_kind.ofwdisk.slice,
- dev->d_kind.ofwdisk.partition + 'a');
- break;
-
- case DEVT_NET:
- sprintf(buf, "%s%d:", dev->d_dev->dv_name,
- dev->d_kind.netif.unit);
- break;
- }
-
- return buf;
}
int
ofw_setcurrdev(struct env_var *ev, int flags, void *value)
{
- struct ofw_devdesc *ncurr;
- int rv;
+ struct ofw_devdesc *ncurr;
+ int rv;
- if ((rv = ofw_parsedev(&ncurr, value, NULL)) != 0)
- return rv;
+ if ((rv = ofw_parsedev(&ncurr, value, NULL)) != 0)
+ return rv;
- free(ncurr);
- env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
- return 0;
+ free(ncurr);
+ env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
+ return 0;
}
diff --git a/sys/boot/ofw/libofw/libofw.h b/sys/boot/ofw/libofw/libofw.h
index c65c84a..a7d73e6 100644
--- a/sys/boot/ofw/libofw/libofw.h
+++ b/sys/boot/ofw/libofw/libofw.h
@@ -31,57 +31,22 @@
struct ofw_devdesc {
struct devsw *d_dev;
int d_type;
- union {
- struct {
- phandle_t handle; /* OFW handle */
- unsigned long partoff; /* sector offset */
- int unit; /* disk number */
- char path[64]; /* OFW path */
- int slice; /* slice# */
- int partition; /* partition in slice */
- int bsize; /* block size */
- } ofwdisk;
- struct {
- int unit;
- char path[64];
- void *dmabuf;
- } netif;
- } d_kind;
-/*
- * Keeping this around so I know what came from the NetBSD stuff.
- * I've made a wild guess as to what goes where, but I have no idea if it's
- * right.
- *
- * void *dmabuf;
- */
+ phandle_t d_handle;
+ char d_path[256];
};
-#define MAXDEV 31 /* Maximum number of devices. */
-
-/* Known types. Use the same as alpha for consistancy. */
-#define DEVT_NONE 0
-#define DEVT_DISK 1
-#define DEVT_NET 2
-
extern int ofw_getdev(void **vdev, const char *devspec, const char **path);
-extern char *ofw_fmtdev(void *vdev);
-extern int ofw_parseofwdev(struct ofw_devdesc *, const char *devspec);
extern int ofw_setcurrdev(struct env_var *ev, int flags, void *value);
extern struct devsw ofwdisk;
extern struct netif_driver ofwnet;
-void ofwd_enter_dev(const char *);
int ofwn_getunit(const char *);
ssize_t ofw_copyin(const void *src, vm_offset_t dest, const size_t len);
ssize_t ofw_copyout(const vm_offset_t src, void *dest, const size_t len);
ssize_t ofw_readin(const int fd, vm_offset_t dest, const size_t len);
-void ofw_devsearch_init(void);
-int ofw_devsearch(const char *, char *);
-int ofw_devicetype(char *);
-
extern int ofw_boot(void);
extern int ofw_autoload(void);
@@ -99,10 +64,10 @@ extern struct file_format ofw_elf;
extern void reboot(void);
-extern int main(int (*openfirm)(void *));
-
struct ofw_reg
{
cell_t base;
cell_t size;
};
+
+extern int (*openfirmware)(void *);
diff --git a/sys/boot/ofw/libofw/ofw_devsearch.c b/sys/boot/ofw/libofw/ofw_devsearch.c
deleted file mode 100644
index 6a195dd..0000000
--- a/sys/boot/ofw/libofw/ofw_devsearch.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2000 Benno Rice
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#include <stand.h>
-
-#include "libofw.h"
-
-static phandle_t curnode;
-
-/*
- * Initialise a device tree search. We do this by setting curpackage to point
- * to the root node.
- */
-void
-ofw_devsearch_init(void)
-{
- curnode = OF_peer(0);
-}
-
-static phandle_t
-nextnode(phandle_t current)
-{
- phandle_t node;
-
- node = OF_child(current);
-
- if (node == -1)
- return(-1);
-
- if (node == 0) {
- node = OF_peer(current);
-
- if (node == -1)
- return(-1);
-
- if (node == 0) {
- phandle_t newnode;
-
- newnode = current;
- node = 0;
-
- while (node == 0) {
- node = OF_parent(newnode);
-
- if (node == -1 || node == 0)
- return ((int)node);
-
- newnode = node;
- node = OF_peer(newnode);
- }
- }
- }
-
- return(node);
-}
-
-/*
- * Search for devices in the device tree with a certain device_type.
- * Return their paths.
- */
-int
-ofw_devsearch(const char *type, char *path)
-{
- phandle_t new;
- char str[32];
- int i;
-
- for (;;) {
- new = nextnode(curnode);
- if (new == 0 || new == -1) {
- return((int)new);
- }
-
- curnode = new;
-
- if ((i = OF_getprop(curnode, "device_type", str, 31)) != -1) {
-
- if (strncmp(str, type, 32) == 0) {
- if ((i = OF_package_to_path(curnode, path, 254)) == -1)
- return(-1);
-
- path[i] = '\0';
- return(1);
- }
- }
- }
-}
-
-/*
- * Get the device_type of a node.
- * Return DEVT_DISK, DEVT_NET or DEVT_NONE.
- */
-int
-ofw_devicetype(char *path)
-{
- phandle_t node;
- char type[16];
-
- node = OF_finddevice(path);
- if (node == -1)
- return DEVT_NONE;
-
- OF_getprop(node, "device_type", type, 16);
-
- if (strncmp(type, "block", 16) == 0)
- return DEVT_DISK;
- else if (strncmp(type, "network", 16) == 0)
- return DEVT_NET;
- else
- return DEVT_NONE;
-}
diff --git a/sys/boot/ofw/libofw/ofw_disk.c b/sys/boot/ofw/libofw/ofw_disk.c
index 1327f18..c1d01ab 100644
--- a/sys/boot/ofw/libofw/ofw_disk.c
+++ b/sys/boot/ofw/libofw/ofw_disk.c
@@ -41,147 +41,28 @@
#include "bootstrap.h"
#include "libofw.h"
-#define DISKSECSZ 512
-
static int ofwd_init(void);
static int ofwd_strategy(void *devdata, int flag, daddr_t dblk,
size_t size, char *buf, size_t *rsize);
static int ofwd_open(struct open_file *f, ...);
static int ofwd_close(struct open_file *f);
+static int ofwd_ioctl(struct open_file *f, u_long cmd, void *data);
static void ofwd_print(int verbose);
-static char * ofwd_getdevpath(int unit);
-int readdisklabel(struct ofw_devdesc *);
struct devsw ofwdisk = {
- "disk",
+ "block",
DEVT_DISK,
ofwd_init,
ofwd_strategy,
ofwd_open,
ofwd_close,
- noioctl,
+ ofwd_ioctl,
ofwd_print
};
-static struct ofwdinfo {
- int ofwd_unit;
- char ofwd_path[255];
-} ofwdinfo[MAXDEV];
-static int nofwdinfo = 0;
-static int probed;
-
-#define OFDP_FOUND 0
-#define OFDP_NOTFOUND 1
-#define OFDP_TERMINATE 2
-
-#define MAXDEV_IDE 4
-#define MAXDEV_DEFAULT 16 /* SCSI etc. */
-
-void
-ofwd_enter_dev(const char *devpath)
-{
- char *p;
- int n;
-
- if (ofwd_getunit(devpath) != -1)
- return;
- if ((p = strrchr(devpath, ',')) != NULL)
- n = p - devpath;
- else
- n = strlen(devpath);
- ofwdinfo[nofwdinfo].ofwd_unit = nofwdinfo;
- strncpy(ofwdinfo[nofwdinfo].ofwd_path, devpath, n);
- ofwdinfo[nofwdinfo].ofwd_path[n] = '\0';
- printf("disk%d is %s\n", nofwdinfo, ofwdinfo[nofwdinfo].ofwd_path);
- nofwdinfo++;
-}
-
-static int
-ofwd_probe_dev(char *devpath)
-{
- ihandle_t instance;
- int rv;
-
- /* Is the device already in the list? */
- if (ofwd_getunit(devpath) != -1)
- return OFDP_FOUND;
- instance = OF_open(devpath);
- if (instance != -1) {
- ofwd_enter_dev(devpath);
- OF_close(instance);
- } else
- return OFDP_NOTFOUND;
- if (nofwdinfo > MAXDEV) {
- printf("Hit MAXDEV probing disks.\n");
- return OFDP_TERMINATE;
- }
- return OFDP_FOUND;
-}
-
-static int
-ofwd_probe_devs(void)
-{
- int ret;
- char devpath[255];
-#ifdef __sparc64__
- int i, n;
- char cdevpath[255];
-#endif
-
- probed = 1;
- ofw_devsearch_init();
- while ((ret = ofw_devsearch("block", devpath)) != 0) {
- devpath[sizeof devpath - 1] = 0;
- if (ret == -1)
- return 1;
-#ifdef DEBUG
- printf("devpath=\"%s\" ret=%d\n", devpath, ret);
-#endif
-
- if (strstr(devpath, "cdrom") != 0)
- continue;
-
-#ifdef __sparc64__
- /*
- * sparc64 machines usually only have a single disk node as
- * child of the controller (in the ATA case, there may exist
- * an additional cdrom node, which we ignore above, since
- * booting from it is special, and it can also be used as a
- * disk node).
- * Devices are accessed by using disk@unit; when no unit
- * number is given, 0 is assumed.
- * There is no way we can enumerate the existing disks except
- * trying to open them, which unfortunately creates some deleays
- * and spurioius warnings printed by the prom, which we can't
- * do much about. The search may not stop on the first
- * unsuccessful attempt, because that would cause disks that
- * follow one with an invalid label (like CD-ROMS) would not
- * be detected this way.
- * Try to at least be a bit smart and only probe 4 devices in
- * the IDE case.
- */
- if (strstr(devpath, "/ide@") != NULL)
- n = MAXDEV_IDE;
- else
- n = MAXDEV_DEFAULT;
- for (i = 0; i < n; i++) {
- sprintf(cdevpath, "%s@%d", devpath, i);
- if (ofwd_probe_dev(cdevpath) == OFDP_TERMINATE)
- return 1;
- }
-#else
- if (ofwd_probe_dev(devpath) == OFDP_TERMINATE)
- return 1;
-#endif
- }
-
- return 0;
-}
-
static int
ofwd_init(void)
{
- /* Short-circuit the device probing, since it takes too long. */
return 0;
}
@@ -194,18 +75,14 @@ ofwd_strategy(void *devdata, int flag, daddr_t dblk, size_t size, char *buf,
int n;
int i, j;
- pos = (dp->d_kind.ofwdisk.partoff + dblk) * dp->d_kind.ofwdisk.bsize;
-
+ pos = dblk * 512;
do {
- if (OF_seek(dp->d_kind.ofwdisk.handle, pos) < 0) {
+ if (OF_seek(dp->d_handle, pos) < 0)
return EIO;
- }
- n = OF_read(dp->d_kind.ofwdisk.handle, buf, size);
- if (n < 0 && n != -2) {
+ n = OF_read(dp->d_handle, buf, size);
+ if (n < 0 && n != -2)
return EIO;
- }
} while (n == -2);
-
*rsize = size;
return 0;
}
@@ -213,55 +90,18 @@ ofwd_strategy(void *devdata, int flag, daddr_t dblk, size_t size, char *buf,
static int
ofwd_open(struct open_file *f, ...)
{
- va_list vl;
struct ofw_devdesc *dp;
- char *devpath;
- phandle_t diskh;
- char buf[256];
- int i, j;
+ phandle_t handle;
+ va_list vl;
va_start(vl, f);
dp = va_arg(vl, struct ofw_devdesc *);
va_end(vl);
-
- /*
- * The unit number is really an index into our device array.
- * If it is not in the list, we may need to probe now.
- */
- if (!probed && dp->d_kind.ofwdisk.unit >= nofwdinfo)
- ofwd_probe_devs();
- if (dp->d_kind.ofwdisk.unit >= nofwdinfo)
- return 1;
- devpath = ofwdinfo[dp->d_kind.ofwdisk.unit].ofwd_path;
- sprintf(buf, "%s,%d:%c", devpath, dp->d_kind.ofwdisk.slice,
- 'a' + dp->d_kind.ofwdisk.partition);
- if ((diskh = OF_open(buf)) == -1) {
- printf("ofwd_open: Could not open %s\n", buf);
+ if ((handle = OF_open(dp->d_path)) == -1) {
+ printf("ofwd_open: Could not open %s\n", dp->d_path);
return 1;
}
- dp->d_kind.ofwdisk.bsize = DISKSECSZ;
- dp->d_kind.ofwdisk.handle = diskh;
- readdisklabel(dp);
-
- return 0;
-}
-
-int
-readdisklabel(struct ofw_devdesc *dp)
-{
- char buf[DISKSECSZ];
- struct disklabel *lp;
- size_t size;
- int i;
-
- dp->d_kind.ofwdisk.partoff = 0;
- dp->d_dev->dv_strategy(dp, 0, LABELSECTOR, sizeof(buf), buf, &size);
- i = dp->d_kind.ofwdisk.partition;
- if (i >= MAXPARTITIONS)
- return 1;
-
- lp = (struct disklabel *)(buf + LABELOFFSET);
- dp->d_kind.ofwdisk.partoff = lp->d_partitions[i].p_offset;
+ dp->d_handle = handle;
return 0;
}
@@ -269,41 +109,19 @@ static int
ofwd_close(struct open_file *f)
{
struct ofw_devdesc *dev = f->f_devdata;
- OF_close(dev->d_kind.ofwdisk.handle);
+ OF_close(dev->d_handle);
return 0;
}
-static void
-ofwd_print(int verbose)
+static int
+ofwd_ioctl(struct open_file *f, u_long cmd, void *data)
{
- int i;
- char line[80];
- if (!probed)
- ofwd_probe_devs();
- for (i = 0; i < nofwdinfo; i++) {
- sprintf(line, " disk%d: %s", i, ofwdinfo[i].ofwd_path);
- pager_output(line);
- pager_output("\n");
- }
- return;
+ return (EINVAL);
}
-int
-ofwd_getunit(const char *path)
+static void
+ofwd_print(int verbose)
{
- char *p;
- int i, n;
-
- if ((p = strrchr(path, ',')) != NULL)
- n = p - path;
- else
- n = strlen(path);
- for (i = 0; i < nofwdinfo; i++) {
- if (strncmp(path, ofwdinfo[i].ofwd_path, n) == 0)
- return i;
- }
-
- return -1;
}
diff --git a/sys/boot/powerpc/loader/metadata.c b/sys/boot/powerpc/loader/metadata.c
index be86c6c..0ef06a9 100644
--- a/sys/boot/powerpc/loader/metadata.c
+++ b/sys/boot/powerpc/loader/metadata.c
@@ -255,7 +255,6 @@ md_load(char *args, vm_offset_t *modulep)
struct preloaded_file *kfp;
struct preloaded_file *xp;
struct file_metadata *md;
- struct ofw_devdesc *rootdev;
vm_offset_t kernend;
vm_offset_t addr;
vm_offset_t envp;
@@ -273,16 +272,10 @@ md_load(char *args, vm_offset_t *modulep)
* MI code before launching the kernel.
*/
rootdevname = getenv("rootdev");
- ofw_getdev((void **)(&rootdev), rootdevname, NULL);
- if (rootdev == NULL) { /* bad $rootdev/$currdev */
- printf("can't determine root device\n");
- return(EINVAL);
- }
-
+ if (rootdevname == NULL)
+ rootdevname = getenv("currdev");
/* Try reading the /etc/fstab file to select the root device */
- getrootmount(ofw_fmtdev((void *)rootdev));
-
- free(rootdev);
+ getrootmount(rootdevname);
/* find the last module in the chain */
addr = 0;
diff --git a/sys/boot/powerpc/ofw/metadata.c b/sys/boot/powerpc/ofw/metadata.c
index be86c6c..0ef06a9 100644
--- a/sys/boot/powerpc/ofw/metadata.c
+++ b/sys/boot/powerpc/ofw/metadata.c
@@ -255,7 +255,6 @@ md_load(char *args, vm_offset_t *modulep)
struct preloaded_file *kfp;
struct preloaded_file *xp;
struct file_metadata *md;
- struct ofw_devdesc *rootdev;
vm_offset_t kernend;
vm_offset_t addr;
vm_offset_t envp;
@@ -273,16 +272,10 @@ md_load(char *args, vm_offset_t *modulep)
* MI code before launching the kernel.
*/
rootdevname = getenv("rootdev");
- ofw_getdev((void **)(&rootdev), rootdevname, NULL);
- if (rootdev == NULL) { /* bad $rootdev/$currdev */
- printf("can't determine root device\n");
- return(EINVAL);
- }
-
+ if (rootdevname == NULL)
+ rootdevname = getenv("currdev");
/* Try reading the /etc/fstab file to select the root device */
- getrootmount(ofw_fmtdev((void *)rootdev));
-
- free(rootdev);
+ getrootmount(rootdevname);
/* find the last module in the chain */
addr = 0;
diff --git a/sys/boot/sparc64/loader/Makefile b/sys/boot/sparc64/loader/Makefile
index cb7a8fa..0d77ee7 100644
--- a/sys/boot/sparc64/loader/Makefile
+++ b/sys/boot/sparc64/loader/Makefile
@@ -16,6 +16,7 @@ LOADER_CD9660_SUPPORT?= yes
LOADER_NET_SUPPORT?= yes
LOADER_NFS_SUPPORT?= yes
LOADER_TFTP_SUPPORT?= yes
+LOADER_ZIP_SUPPORT?= yes
LOADER_GZIP_SUPPORT?= yes
LOADER_BZIP2_SUPPORT?= no
@@ -28,6 +29,9 @@ CFLAGS+= -DLOADER_UFS_SUPPORT
.if ${LOADER_CD9660_SUPPORT} == "yes"
CFLAGS+= -DLOADER_CD9660_SUPPORT
.endif
+.if ${LOADER_ZIP_SUPPORT} == "yes"
+CFLAGS+= -DLOADER_ZIP_SUPPORT
+.endif
.if ${LOADER_GZIP_SUPPORT} == "yes"
CFLAGS+= -DLOADER_GZIP_SUPPORT
.endif
@@ -81,7 +85,7 @@ LIBSTAND= -lstand
.endif
CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/
-LDADD= ${LIBFICL} ${LIBSTAND} ${LIBOFW}
+LDADD= ${LIBFICL} ${LIBOFW} ${LIBSTAND}
vers.c: ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version
sh ${.CURDIR}/../../common/newvers.sh ${.CURDIR}/version ${NEWVERSWHAT}
diff --git a/sys/boot/sparc64/loader/main.c b/sys/boot/sparc64/loader/main.c
index 43e3c77..3354bc2 100644
--- a/sys/boot/sparc64/loader/main.c
+++ b/sys/boot/sparc64/loader/main.c
@@ -75,7 +75,6 @@ vm_offset_t heapva;
phandle_t pmemh; /* OFW memory handle */
struct memory_slice memslices[18];
-struct ofw_devdesc bootdev;
/*
* Machine dependent structures that the machine independent
@@ -368,9 +367,6 @@ main(int (*openfirm)(void *))
archsw.arch_copyout = ofw_copyout;
archsw.arch_readin = sparc64_readin;
archsw.arch_autoload = sparc64_autoload;
-#ifdef ELF_CRC32
- archsw.arch_crc32 = sparc64_crc32;
-#endif
init_heap();
setheap((void *)heapva, (void *)(heapva + HEAPSZ));
@@ -398,46 +394,32 @@ main(int (*openfirm)(void *))
chosenh = OF_finddevice("/chosen");
OF_getprop(chosenh, "bootpath", bootpath, sizeof(bootpath));
- bootdev.d_type = ofw_devicetype(bootpath);
- switch (bootdev.d_type) {
- case DEVT_DISK:
- bootdev.d_dev = &ofwdisk;
- /*
- * Sun compatible bootable CD-ROMs have a disk label placed
- * before the cd9660 data, with the actual filesystem being
- * in the first partition, while the other partitions contain
- * pseudo disk labels with embedded boot blocks for different
- * architectures, which may be followed by UFS filesystems.
- * The firmware will set the boot path to the partition it
- * boots from ('f' in the sun4u case), but we want the kernel
- * to be loaded from the cd9660 fs ('a'), so the boot path
- * needs to be altered.
- */
- if (strstr(bootpath, "cdrom") != NULL &&
- bootpath[strlen(bootpath) - 2] == ':') {
- bootpath[strlen(bootpath) - 1] = 'a';
- printf("Boot path set to %s\n", bootpath);
- }
- strncpy(bootdev.d_kind.ofwdisk.path, bootpath, 64);
- ofw_parseofwdev(&bootdev, bootpath);
- break;
- case DEVT_NET:
- bootdev.d_dev = &netdev;
- strncpy(bootdev.d_kind.netif.path, bootpath, 64);
- bootdev.d_kind.netif.unit = 0;
- break;
+ /*
+ * Sun compatible bootable CD-ROMs have a disk label placed
+ * before the cd9660 data, with the actual filesystem being
+ * in the first partition, while the other partitions contain
+ * pseudo disk labels with embedded boot blocks for different
+ * architectures, which may be followed by UFS filesystems.
+ * The firmware will set the boot path to the partition it
+ * boots from ('f' in the sun4u case), but we want the kernel
+ * to be loaded from the cd9660 fs ('a'), so the boot path
+ * needs to be altered.
+ */
+ if (bootpath[strlen(bootpath) - 2] == ':' &&
+ bootpath[strlen(bootpath) - 1] == 'f') {
+ bootpath[strlen(bootpath) - 1] = 'a';
+ printf("Boot path set to %s\n", bootpath);
}
- env_setenv("currdev", EV_VOLATILE, ofw_fmtdev(&bootdev),
+ env_setenv("currdev", EV_VOLATILE, bootpath,
ofw_setcurrdev, env_nounset);
- env_setenv("loaddev", EV_VOLATILE, ofw_fmtdev(&bootdev),
+ env_setenv("loaddev", EV_VOLATILE, bootpath,
env_noset, env_nounset);
printf("\n");
printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
printf("(%s, %s)\n", bootprog_maker, bootprog_date);
printf("bootpath=\"%s\"\n", bootpath);
- printf("loaddev=%s\n", getenv("loaddev"));
/* Give control to the machine independent loader code. */
interact();
diff --git a/sys/boot/sparc64/loader/metadata.c b/sys/boot/sparc64/loader/metadata.c
index 7f0b873..5de7e7d 100644
--- a/sys/boot/sparc64/loader/metadata.c
+++ b/sys/boot/sparc64/loader/metadata.c
@@ -261,7 +261,6 @@ md_load(char *args, vm_offset_t *modulep)
struct preloaded_file *kfp;
struct preloaded_file *xp;
struct file_metadata *md;
- struct ofw_devdesc *rootdev;
vm_offset_t kernend;
vm_offset_t addr;
vm_offset_t envp;
@@ -276,17 +275,9 @@ md_load(char *args, vm_offset_t *modulep)
* This should perhaps go to MI code and/or have $rootdev tested/set by
* MI code before launching the kernel.
*/
- rootdevname = getenv("rootdev");
- ofw_getdev((void **)(&rootdev), rootdevname, NULL);
- if (rootdev == NULL) { /* bad $rootdev/$currdev */
- printf("can't determine root device\n");
- return(EINVAL);
- }
-
- /* Try reading the /etc/fstab file to select the root device */
- getrootmount(ofw_fmtdev((void *)rootdev));
-
- free(rootdev);
+ if ((rootdevname = getenv("rootdev")) == NULL)
+ rootdevname = getenv("currdev");
+ getrootmount(rootdevname);
/* find the last module in the chain */
addr = 0;
OpenPOWER on IntegriCloud