aboutsummaryrefslogtreecommitdiff
path: root/stand
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-12-09 11:39:45 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-12-09 11:39:45 +0000
commit67350cb56a69468c118bd4ccf6e361b7ebfa9eb4 (patch)
tree093815c5d75ba2f601c6ba4d487fff29ab62f3ad /stand
parent0b9890fcbf4bd3cb118afc215675503889b63fb9 (diff)
parent25b4f9ad69e65a688f77df35062c81ac65a71f8d (diff)
downloadsrc-67350cb56a69468c118bd4ccf6e361b7ebfa9eb4.tar.gz
src-67350cb56a69468c118bd4ccf6e361b7ebfa9eb4.zip
Merge ^/head r340918 through r341763.
Notes
Notes: svn path=/projects/clang700-import/; revision=341764
Diffstat (limited to 'stand')
-rw-r--r--stand/common/bcache.c12
-rw-r--r--stand/common/interp_forth.c3
-rw-r--r--stand/defs.mk17
-rw-r--r--stand/efi/libefi/efi_console.c140
-rw-r--r--stand/i386/btx/lib/Makefile2
-rw-r--r--stand/i386/btx/lib/btxsys.S (renamed from stand/i386/btx/lib/btxsys.s)0
-rw-r--r--stand/i386/btx/lib/btxv86.S (renamed from stand/i386/btx/lib/btxv86.s)0
-rw-r--r--stand/i386/common/bootargs.h78
-rw-r--r--stand/i386/gptboot/gptboot.c31
-rw-r--r--stand/i386/kgzldr/Makefile4
-rw-r--r--stand/i386/kgzldr/crt.S (renamed from stand/i386/kgzldr/crt.s)0
-rw-r--r--stand/i386/kgzldr/sio.S (renamed from stand/i386/kgzldr/sio.s)0
-rw-r--r--stand/i386/kgzldr/start.S (renamed from stand/i386/kgzldr/start.s)0
-rw-r--r--stand/i386/libi386/Makefile4
-rw-r--r--stand/i386/libi386/bioscd.c432
-rw-r--r--stand/i386/libi386/biosdisk.c670
-rw-r--r--stand/i386/libi386/bootinfo32.c7
-rw-r--r--stand/i386/libi386/libi386.h8
-rw-r--r--stand/i386/libi386/pxetramp.S (renamed from stand/i386/libi386/pxetramp.s)0
-rw-r--r--stand/i386/loader/chain.c2
-rw-r--r--stand/i386/loader/conf.c3
-rw-r--r--stand/i386/loader/main.c85
-rw-r--r--stand/i386/mbr/Makefile4
-rw-r--r--stand/i386/mbr/mbr.S (renamed from stand/i386/mbr/mbr.s)0
-rw-r--r--stand/i386/pmbr/Makefile6
-rw-r--r--stand/i386/pmbr/pmbr.S (renamed from stand/i386/pmbr/pmbr.s)0
-rw-r--r--stand/i386/pxeldr/pxeboot.82
-rw-r--r--stand/i386/zfsboot/zfsboot.c14
-rw-r--r--stand/libsa/arp.c2
-rw-r--r--stand/libsa/assert.c4
-rw-r--r--stand/libsa/bzipfs.c2
-rw-r--r--stand/libsa/netif.c8
-rw-r--r--stand/libsa/sbrk.c2
-rw-r--r--stand/libsa/ufs.c8
-rw-r--r--stand/libsa/zfs/libzfs.h25
-rw-r--r--stand/uboot/common/main.c3
-rw-r--r--stand/uboot/lib/copy.c2
-rw-r--r--stand/uboot/lib/net.c4
38 files changed, 799 insertions, 785 deletions
diff --git a/stand/common/bcache.c b/stand/common/bcache.c
index 39e8e35a559d..5affaf5f0fd9 100644
--- a/stand/common/bcache.c
+++ b/stand/common/bcache.c
@@ -476,12 +476,12 @@ command_bcache(int argc, char *argv[])
return(CMD_ERROR);
}
- printf("\ncache blocks: %d\n", bcache_total_nblks);
- printf("cache blocksz: %d\n", bcache_blksize);
- printf("cache readahead: %d\n", bcache_rablks);
- printf("unit cache blocks: %d\n", bcache_unit_nblks);
- printf("cached units: %d\n", bcache_units);
- printf("%d ops %d bypasses %d hits %d misses\n", bcache_ops,
+ printf("\ncache blocks: %u\n", bcache_total_nblks);
+ printf("cache blocksz: %u\n", bcache_blksize);
+ printf("cache readahead: %u\n", bcache_rablks);
+ printf("unit cache blocks: %u\n", bcache_unit_nblks);
+ printf("cached units: %u\n", bcache_units);
+ printf("%u ops %d bypasses %u hits %u misses\n", bcache_ops,
bcache_bypasses, bcache_hits, bcache_misses);
return(CMD_OK);
}
diff --git a/stand/common/interp_forth.c b/stand/common/interp_forth.c
index 31ba1f7c2967..19d66cdf3f4d 100644
--- a/stand/common/interp_forth.c
+++ b/stand/common/interp_forth.c
@@ -142,9 +142,10 @@ bf_command(FICL_VM *vm)
switch (result) {
case CMD_CRIT:
printf("%s\n", command_errmsg);
+ command_errmsg = NULL;
break;
case CMD_FATAL:
- panic("%s\n", command_errmsg);
+ panic("%s", command_errmsg);
}
free(line);
diff --git a/stand/defs.mk b/stand/defs.mk
index 7ee0922858b9..0d66fba0cf69 100644
--- a/stand/defs.mk
+++ b/stand/defs.mk
@@ -1,12 +1,12 @@
# $FreeBSD$
-.include <src.opts.mk>
-
-WARNS?=1
-
.if !defined(__BOOT_DEFS_MK__)
__BOOT_DEFS_MK__=${MFILE}
+# We need to define all the MK_ options before including src.opts.mk
+# because it includes bsd.own.mk which needs the right MK_ values,
+# espeically MK_CTF.
+
MK_CTF= no
MK_SSP= no
MK_PROFILE= no
@@ -16,6 +16,10 @@ NO_PIC=
INTERNALLIB=
.endif
+.include <src.opts.mk>
+
+WARNS?= 1
+
BOOTSRC= ${SRCTOP}/stand
EFISRC= ${BOOTSRC}/efi
EFIINC= ${EFISRC}/include
@@ -115,6 +119,11 @@ CFLAGS+= -march=rv64imac -mabi=lp64
CFLAGS+= -msoft-float
.endif
+# -msoft-float seems to be insufficient for powerpcspe
+.if ${MACHINE_ARCH} == "powerpcspe"
+CFLAGS+= -mno-spe
+.endif
+
.if ${MACHINE_CPUARCH} == "i386" || (${MACHINE_CPUARCH} == "amd64" && ${DO32:U0} == 1)
CFLAGS+= -march=i386
CFLAGS.gcc+= -mpreferred-stack-boundary=2
diff --git a/stand/efi/libefi/efi_console.c b/stand/efi/libefi/efi_console.c
index c8275030a2a6..de1e3a711649 100644
--- a/stand/efi/libefi/efi_console.c
+++ b/stand/efi/libefi/efi_console.c
@@ -51,7 +51,8 @@ void HO(void);
void end_term(void);
#endif
-static EFI_INPUT_KEY key_cur;
+#define KEYBUFSZ 10
+static unsigned keybuf[KEYBUFSZ]; /* keybuf for extended codes */
static int key_pending;
static void efi_cons_probe(struct console *);
@@ -438,55 +439,120 @@ efi_cons_putchar(int c)
#endif
}
-int
-efi_cons_getchar()
+static int
+keybuf_getchar(void)
{
- EFI_INPUT_KEY key;
- EFI_STATUS status;
- UINTN junk;
-
- if (key_pending) {
- key = key_cur;
- key_pending = 0;
- } else {
- /* Try to read a key stroke. We wait for one if none is pending. */
- status = conin->ReadKeyStroke(conin, &key);
- while (status == EFI_NOT_READY) {
- /* Some EFI implementation (u-boot for example) do not support WaitForKey */
- if (conin->WaitForKey != NULL)
- BS->WaitForEvent(1, &conin->WaitForKey, &junk);
- status = conin->ReadKeyStroke(conin, &key);
+ int i, c = 0;
+
+ for (i = 0; i < KEYBUFSZ; i++) {
+ if (keybuf[i] != 0) {
+ c = keybuf[i];
+ keybuf[i] = 0;
+ break;
}
}
- switch (key.ScanCode) {
- case 0x17: /* ESC */
- return (0x1b); /* esc */
+ return (c);
+}
+
+static bool
+keybuf_ischar(void)
+{
+ int i;
+
+ for (i = 0; i < KEYBUFSZ; i++) {
+ if (keybuf[i] != 0)
+ return (true);
}
+ return (false);
+}
- /* this can return */
- return (key.UnicodeChar);
+/*
+ * We are not reading input before keybuf is empty, so we are safe
+ * just to fill keybuf from the beginning.
+ */
+static void
+keybuf_inschar(EFI_INPUT_KEY *key)
+{
+
+ switch (key->ScanCode) {
+ case 0x1: /* UP */
+ keybuf[0] = 0x1b; /* esc */
+ keybuf[1] = '[';
+ keybuf[2] = 'A';
+ break;
+ case 0x2: /* DOWN */
+ keybuf[0] = 0x1b; /* esc */
+ keybuf[1] = '[';
+ keybuf[2] = 'B';
+ break;
+ case 0x3: /* RIGHT */
+ keybuf[0] = 0x1b; /* esc */
+ keybuf[1] = '[';
+ keybuf[2] = 'C';
+ break;
+ case 0x4: /* LEFT */
+ keybuf[0] = 0x1b; /* esc */
+ keybuf[1] = '[';
+ keybuf[2] = 'D';
+ break;
+ case 0x17:
+ keybuf[0] = 0x1b; /* esc */
+ break;
+ default:
+ keybuf[0] = key->UnicodeChar;
+ break;
+ }
}
-int
-efi_cons_poll()
+static bool
+efi_readkey(void)
{
- EFI_INPUT_KEY key;
EFI_STATUS status;
+ EFI_INPUT_KEY key;
- if (conin->WaitForKey == NULL) {
- if (key_pending)
- return (1);
- status = conin->ReadKeyStroke(conin, &key);
- if (status == EFI_SUCCESS) {
- key_cur = key;
- key_pending = 1;
- }
- return (key_pending);
+ status = conin->ReadKeyStroke(conin, &key);
+ if (status == EFI_SUCCESS) {
+ keybuf_inschar(&key);
+ return (true);
}
+ return (false);
+}
+
+int
+efi_cons_getchar(void)
+{
+ int c;
+
+ if ((c = keybuf_getchar()) != 0)
+ return (c);
+
+ key_pending = 0;
+
+ if (efi_readkey())
+ return (keybuf_getchar());
+
+ return (-1);
+}
+
+int
+efi_cons_poll(void)
+{
+
+ if (keybuf_ischar() || key_pending)
+ return (1);
+
+ /*
+ * Some EFI implementation (u-boot for example) do not support
+ * WaitForKey().
+ * CheckEvent() can clear the signaled state.
+ */
+ if (conin->WaitForKey == NULL)
+ key_pending = efi_readkey();
+ else
+ key_pending = BS->CheckEvent(conin->WaitForKey) == EFI_SUCCESS;
- /* This can clear the signaled state. */
- return (BS->CheckEvent(conin->WaitForKey) == EFI_SUCCESS);
+ return (key_pending);
}
/* Plain direct access to EFI OutputString(). */
diff --git a/stand/i386/btx/lib/Makefile b/stand/i386/btx/lib/Makefile
index 2988f4297660..a9e2e4350a55 100644
--- a/stand/i386/btx/lib/Makefile
+++ b/stand/i386/btx/lib/Makefile
@@ -4,7 +4,7 @@
PROG= crt0.o
INTERNALPROG=
-SRCS= btxcsu.S btxsys.s btxv86.s
+SRCS= btxcsu.S btxsys.S btxv86.S
CFLAGS+=-I${BOOTSRC}/i386/common
LDFLAGS+=-Wl,-r
diff --git a/stand/i386/btx/lib/btxsys.s b/stand/i386/btx/lib/btxsys.S
index 9c77b4295e7c..9c77b4295e7c 100644
--- a/stand/i386/btx/lib/btxsys.s
+++ b/stand/i386/btx/lib/btxsys.S
diff --git a/stand/i386/btx/lib/btxv86.s b/stand/i386/btx/lib/btxv86.S
index 0d7d1116322d..0d7d1116322d 100644
--- a/stand/i386/btx/lib/btxv86.s
+++ b/stand/i386/btx/lib/btxv86.S
diff --git a/stand/i386/common/bootargs.h b/stand/i386/common/bootargs.h
index df558072f37f..5a6fef85a8c8 100644
--- a/stand/i386/common/bootargs.h
+++ b/stand/i386/common/bootargs.h
@@ -18,10 +18,11 @@
#ifndef _BOOT_I386_ARGS_H_
#define _BOOT_I386_ARGS_H_
-#define KARGS_FLAGS_CD 0x1
-#define KARGS_FLAGS_PXE 0x2
-#define KARGS_FLAGS_ZFS 0x4
-#define KARGS_FLAGS_EXTARG 0x8 /* variably sized extended argument */
+#define KARGS_FLAGS_CD 0x0001 /* .bootdev is a bios CD dev */
+#define KARGS_FLAGS_PXE 0x0002 /* .pxeinfo is valid */
+#define KARGS_FLAGS_ZFS 0x0004 /* .zfspool is valid, EXTARG is zfs_boot_args */
+#define KARGS_FLAGS_EXTARG 0x0008 /* variably sized extended argument */
+#define KARGS_FLAGS_GELI 0x0010 /* EXTARG is geli_boot_args */
#define BOOTARGS_SIZE 24 /* sizeof(struct bootargs) */
#define BA_BOOTFLAGS 8 /* offsetof(struct bootargs, bootflags) */
@@ -43,6 +44,24 @@
#ifndef __ASSEMBLER__
+/*
+ * This struct describes the contents of the stack on entry to btxldr.S. This
+ * is the data that follows the return address, so it begins at 4(%esp). On
+ * the sending side, this data is passed as individual args to __exec(). On the
+ * receiving side, code in btxldr.S copies the data from the entry stack to a
+ * known fixed location in the new address space. Then, btxcsu.S sets the
+ * global variable __args to point to that known fixed location before calling
+ * main(), which casts __args to a struct bootargs pointer to access the data.
+ * The btxldr.S code is aware of KARGS_FLAGS_EXTARG, and if it's set, the extra
+ * args data is copied along with the other bootargs from the entry stack to the
+ * fixed location in the new address space.
+ *
+ * The bootinfo field is actually a pointer to a bootinfo struct that has been
+ * converted to uint32_t using VTOP(). On the receiving side it must be
+ * converted back to a pointer using PTOV(). Code in btxldr.S is aware of this
+ * field and if it's non-NULL it copies the data it points to into another known
+ * fixed location, and adjusts the bootinfo field to point to that new location.
+ */
struct bootargs
{
uint32_t howto;
@@ -66,11 +85,15 @@ struct bootargs
#ifdef LOADER_GELI_SUPPORT
#include <crypto/intake.h>
+#include "geliboot.h"
#endif
-struct geli_boot_args
+/*
+ * geli_boot_data is embedded in geli_boot_args (passed from gptboot to loader)
+ * and in zfs_boot_args (passed from zfsboot and gptzfsboot to loader).
+ */
+struct geli_boot_data
{
- uint32_t size;
union {
char gelipw[256];
struct {
@@ -88,6 +111,49 @@ struct geli_boot_args
};
};
+#ifdef LOADER_GELI_SUPPORT
+
+static inline void
+export_geli_boot_data(struct geli_boot_data *gbdata)
+{
+
+ gbdata->notapw = '\0';
+ gbdata->keybuf_sentinel = KEYBUF_SENTINEL;
+ gbdata->keybuf = malloc(sizeof(struct keybuf) +
+ (GELI_MAX_KEYS * sizeof(struct keybuf_ent)));
+ geli_export_key_buffer(gbdata->keybuf);
+}
+
+static inline void
+import_geli_boot_data(struct geli_boot_data *gbdata)
+{
+
+ if (gbdata->gelipw[0] != '\0') {
+ setenv("kern.geom.eli.passphrase", gbdata->gelipw, 1);
+ explicit_bzero(gbdata->gelipw, sizeof(gbdata->gelipw));
+ } else if (gbdata->keybuf_sentinel == KEYBUF_SENTINEL) {
+ geli_import_key_buffer(gbdata->keybuf);
+ }
+}
+#endif /* LOADER_GELI_SUPPORT */
+
+struct geli_boot_args
+{
+ uint32_t size;
+ struct geli_boot_data gelidata;
+};
+
+struct zfs_boot_args
+{
+ uint32_t size;
+ uint32_t reserved;
+ uint64_t pool;
+ uint64_t root;
+ uint64_t primary_pool;
+ uint64_t primary_vdev;
+ struct geli_boot_data gelidata;
+};
+
#endif /*__ASSEMBLER__*/
#endif /* !_BOOT_I386_ARGS_H_ */
diff --git a/stand/i386/gptboot/gptboot.c b/stand/i386/gptboot/gptboot.c
index 5553364090f1..d9e11864c0a4 100644
--- a/stand/i386/gptboot/gptboot.c
+++ b/stand/i386/gptboot/gptboot.c
@@ -81,7 +81,6 @@ uint32_t opts;
static const char *const dev_nm[NDEV] = {"ad", "da", "fd"};
static const unsigned char dev_maj[NDEV] = {30, 4, 2};
-static struct dsk dsk;
static char kname[1024];
static int comspeed = SIOSPD;
static struct bootinfo bootinfo;
@@ -115,7 +114,6 @@ static int vdev_read(void *vdev __unused, void *priv, off_t off, void *buf,
#ifdef LOADER_GELI_SUPPORT
#include "geliboot.h"
static char gelipw[GELI_PW_MAXLEN];
-static struct keybuf *gelibuf;
#endif
struct gptdsk {
@@ -481,17 +479,18 @@ load(void)
#ifdef LOADER_GELI_SUPPORT
geliargs.size = sizeof(geliargs);
explicit_bzero(gelipw, sizeof(gelipw));
- gelibuf = malloc(sizeof(struct keybuf) +
- (GELI_MAX_KEYS * sizeof(struct keybuf_ent)));
- geli_export_key_buffer(gelibuf);
- geliargs.notapw = '\0';
- geliargs.keybuf_sentinel = KEYBUF_SENTINEL;
- geliargs.keybuf = gelibuf;
+ export_geli_boot_data(&geliargs.gelidata);
#endif
+ /*
+ * Note that the geliargs struct is passed by value, not by pointer.
+ * Code in btxldr.S copies the values from the entry stack to a fixed
+ * location within loader(8) at startup due to the presence of the
+ * KARGS_FLAGS_EXTARG flag.
+ */
__exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK),
MAKEBOOTDEV(dev_maj[gdsk.dsk.type], gdsk.dsk.part + 1, gdsk.dsk.unit, 0xff),
#ifdef LOADER_GELI_SUPPORT
- KARGS_FLAGS_EXTARG, 0, 0, VTOP(&bootinfo), geliargs
+ KARGS_FLAGS_GELI | KARGS_FLAGS_EXTARG, 0, 0, VTOP(&bootinfo), geliargs
#else
0, 0, 0, VTOP(&bootinfo)
#endif
@@ -569,22 +568,22 @@ parse_cmds(char *cmdstr, int *dskupdated)
arg[1] != dev_nm[i][1]; i++)
if (i == NDEV - 1)
return (-1);
- dsk.type = i;
+ gdsk.dsk.type = i;
arg += 3;
- dsk.unit = *arg - '0';
- if (arg[1] != 'p' || dsk.unit > 9)
+ gdsk.dsk.unit = *arg - '0';
+ if (arg[1] != 'p' || gdsk.dsk.unit > 9)
return (-1);
arg += 2;
- dsk.part = *arg - '0';
- if (dsk.part < 1 || dsk.part > 9)
+ gdsk.dsk.part = *arg - '0';
+ if (gdsk.dsk.part < 1 || gdsk.dsk.part > 9)
return (-1);
arg++;
if (arg[0] != ')')
return (-1);
arg++;
if (drv == -1)
- drv = dsk.unit;
- dsk.drive = (dsk.type <= TYPE_MAXHARD
+ drv = gdsk.dsk.unit;
+ gdsk.dsk.drive = (gdsk.dsk.type <= TYPE_MAXHARD
? DRV_HARD : 0) + drv;
*dskupdated = 1;
}
diff --git a/stand/i386/kgzldr/Makefile b/stand/i386/kgzldr/Makefile
index 281f1c9f1ba0..96ba94ee535f 100644
--- a/stand/i386/kgzldr/Makefile
+++ b/stand/i386/kgzldr/Makefile
@@ -7,7 +7,7 @@ STRIP=
BINMODE=${LIBMODE}
BINDIR= ${LIBDIR}
-SRCS= start.s boot.c subr_inflate.c lib.c crt.s sio.s
+SRCS= start.S boot.c subr_inflate.c lib.c crt.S sio.S
CFLAGS= -Os
CFLAGS+=-DKZIP
NO_SHARED=
@@ -15,6 +15,6 @@ LDFLAGS+=-Wl,-r
.PATH: ${SYSDIR}/kern
BOOT_COMCONSOLE_PORT?= 0x3f8
-AFLAGS+=--defsym SIO_PRT=${BOOT_COMCONSOLE_PORT}
+ACFLAGS+=-Wa,-defsym,SIO_PRT=${BOOT_COMCONSOLE_PORT}
.include <bsd.prog.mk>
diff --git a/stand/i386/kgzldr/crt.s b/stand/i386/kgzldr/crt.S
index cfb479fd2d84..cfb479fd2d84 100644
--- a/stand/i386/kgzldr/crt.s
+++ b/stand/i386/kgzldr/crt.S
diff --git a/stand/i386/kgzldr/sio.s b/stand/i386/kgzldr/sio.S
index ff174eb0b71b..ff174eb0b71b 100644
--- a/stand/i386/kgzldr/sio.s
+++ b/stand/i386/kgzldr/sio.S
diff --git a/stand/i386/kgzldr/start.s b/stand/i386/kgzldr/start.S
index 550fa526d946..550fa526d946 100644
--- a/stand/i386/kgzldr/start.s
+++ b/stand/i386/kgzldr/start.S
diff --git a/stand/i386/libi386/Makefile b/stand/i386/libi386/Makefile
index f92558edae3a..21f821f281d0 100644
--- a/stand/i386/libi386/Makefile
+++ b/stand/i386/libi386/Makefile
@@ -4,11 +4,11 @@
LIB= i386
-SRCS= biosacpi.c bioscd.c biosdisk.c biosmem.c biospnp.c \
+SRCS= biosacpi.c biosdisk.c biosmem.c biospnp.c \
biospci.c biossmap.c bootinfo.c bootinfo32.c bootinfo64.c \
comconsole.c devicename.c elf32_freebsd.c \
elf64_freebsd.c multiboot.c multiboot_tramp.S relocater_tramp.S \
- i386_copy.c i386_module.c nullconsole.c pxe.c pxetramp.s \
+ i386_copy.c i386_module.c nullconsole.c pxe.c pxetramp.S \
smbios.c time.c vidconsole.c amd64_tramp.S spinconsole.c
.PATH: ${ZFSSRC}
SRCS+= devicename_stubs.c
diff --git a/stand/i386/libi386/bioscd.c b/stand/i386/libi386/bioscd.c
deleted file mode 100644
index b1ad44597263..000000000000
--- a/stand/i386/libi386/bioscd.c
+++ /dev/null
@@ -1,432 +0,0 @@
-/*-
- * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
- * Copyright (c) 2001 John H. Baldwin <jhb@FreeBSD.org>
- * 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 THE AUTHOR AND CONTRIBUTORS ``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 THE AUTHOR OR CONTRIBUTORS 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * BIOS CD device handling for CD's that have been booted off of via no
- * emulation booting as defined in the El Torito standard.
- *
- * Ideas and algorithms from:
- *
- * - FreeBSD libi386/biosdisk.c
- *
- */
-
-#include <stand.h>
-
-#include <sys/param.h>
-#include <machine/bootinfo.h>
-
-#include <stdarg.h>
-
-#include <bootstrap.h>
-#include <btxv86.h>
-#include <edd.h>
-#include "libi386.h"
-
-#define BIOSCD_SECSIZE 2048
-#define BUFSIZE (1 * BIOSCD_SECSIZE)
-#define MAXBCDEV 1
-
-/* Major numbers for devices we frontend for. */
-#define ACDMAJOR 117
-#define CDMAJOR 15
-
-#ifdef DISK_DEBUG
-# define DEBUG(fmt, args...) printf("%s: " fmt "\n" , __func__ , ## args)
-#else
-# define DEBUG(fmt, args...)
-#endif
-
-struct specification_packet {
- u_char sp_size;
- u_char sp_bootmedia;
- u_char sp_drive;
- u_char sp_controller;
- u_int sp_lba;
- u_short sp_devicespec;
- u_short sp_buffersegment;
- u_short sp_loadsegment;
- u_short sp_sectorcount;
- u_short sp_cylsec;
- u_char sp_head;
-};
-
-/*
- * List of BIOS devices, translation from disk unit number to
- * BIOS unit number.
- */
-static struct bcinfo {
- int bc_unit; /* BIOS unit number */
- struct specification_packet bc_sp;
- int bc_open; /* reference counter */
- void *bc_bcache; /* buffer cache data */
-} bcinfo [MAXBCDEV];
-static int nbcinfo = 0;
-
-#define BC(dev) (bcinfo[(dev)->dd.d_unit])
-
-static int bc_read(int unit, daddr_t dblk, int blks, caddr_t dest);
-static int bc_init(void);
-static int bc_strategy(void *devdata, int flag, daddr_t dblk,
- size_t size, char *buf, size_t *rsize);
-static int bc_realstrategy(void *devdata, int flag, daddr_t dblk,
- size_t size, char *buf, size_t *rsize);
-static int bc_open(struct open_file *f, ...);
-static int bc_close(struct open_file *f);
-static int bc_print(int verbose);
-
-struct devsw bioscd = {
- "cd",
- DEVT_CD,
- bc_init,
- bc_strategy,
- bc_open,
- bc_close,
- noioctl,
- bc_print,
- NULL
-};
-
-/*
- * Translate between BIOS device numbers and our private unit numbers.
- */
-int
-bc_bios2unit(int biosdev)
-{
- int i;
-
- DEBUG("looking for bios device 0x%x", biosdev);
- for (i = 0; i < nbcinfo; i++) {
- DEBUG("bc unit %d is BIOS device 0x%x", i, bcinfo[i].bc_unit);
- if (bcinfo[i].bc_unit == biosdev)
- return(i);
- }
- return(-1);
-}
-
-int
-bc_unit2bios(int unit)
-{
- if ((unit >= 0) && (unit < nbcinfo))
- return(bcinfo[unit].bc_unit);
- return(-1);
-}
-
-/*
- * We can't quiz, we have to be told what device to use, so this functoin
- * doesn't do anything. Instead, the loader calls bc_add() with the BIOS
- * device number to add.
- */
-static int
-bc_init(void)
-{
-
- return (0);
-}
-
-int
-bc_add(int biosdev)
-{
-
- if (nbcinfo >= MAXBCDEV)
- return (-1);
- bcinfo[nbcinfo].bc_unit = biosdev;
- v86.ctl = V86_FLAGS;
- v86.addr = 0x13;
- v86.eax = 0x4b01;
- v86.edx = biosdev;
- v86.ds = VTOPSEG(&bcinfo[nbcinfo].bc_sp);
- v86.esi = VTOPOFF(&bcinfo[nbcinfo].bc_sp);
- v86int();
- if ((v86.eax & 0xff00) != 0)
- return (-1);
-
- printf("BIOS CD is cd%d\n", nbcinfo);
- nbcinfo++;
- bcache_add_dev(nbcinfo); /* register cd device in bcache */
- return(0);
-}
-
-/*
- * Print information about disks
- */
-static int
-bc_print(int verbose)
-{
- char line[80];
- int i, ret = 0;
-
- if (nbcinfo == 0)
- return (0);
-
- printf("%s devices:", bioscd.dv_name);
- if ((ret = pager_output("\n")) != 0)
- return (ret);
-
- for (i = 0; i < nbcinfo; i++) {
- snprintf(line, sizeof(line), " cd%d: Device 0x%x\n", i,
- bcinfo[i].bc_sp.sp_devicespec);
- if ((ret = pager_output(line)) != 0)
- break;
- }
- return (ret);
-}
-
-/*
- * Attempt to open the disk described by (dev) for use by (f).
- */
-static int
-bc_open(struct open_file *f, ...)
-{
- va_list ap;
- struct i386_devdesc *dev;
-
- va_start(ap, f);
- dev = va_arg(ap, struct i386_devdesc *);
- va_end(ap);
- if (dev->dd.d_unit >= nbcinfo) {
- DEBUG("attempt to open nonexistent disk");
- return(ENXIO);
- }
-
- BC(dev).bc_open++;
- if (BC(dev).bc_bcache == NULL)
- BC(dev).bc_bcache = bcache_allocate();
- return(0);
-}
-
-static int
-bc_close(struct open_file *f)
-{
- struct i386_devdesc *dev;
-
- dev = (struct i386_devdesc *)f->f_devdata;
- BC(dev).bc_open--;
- if (BC(dev).bc_open == 0) {
- bcache_free(BC(dev).bc_bcache);
- BC(dev).bc_bcache = NULL;
- }
- return(0);
-}
-
-static int
-bc_strategy(void *devdata, int rw, daddr_t dblk, size_t size,
- char *buf, size_t *rsize)
-{
- struct bcache_devdata bcd;
- struct i386_devdesc *dev;
-
- dev = (struct i386_devdesc *)devdata;
- bcd.dv_strategy = bc_realstrategy;
- bcd.dv_devdata = devdata;
- bcd.dv_cache = BC(dev).bc_bcache;
-
- return (bcache_strategy(&bcd, rw, dblk, size, buf, rsize));
-}
-
-static int
-bc_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size,
- char *buf, size_t *rsize)
-{
- struct i386_devdesc *dev;
- int unit;
- int blks;
-
- if (size % BIOSCD_SECSIZE)
- return (EINVAL);
-
- if ((rw & F_MASK) != F_READ)
- return(EROFS);
- dev = (struct i386_devdesc *)devdata;
- unit = dev->dd.d_unit;
- blks = size / BIOSCD_SECSIZE;
- if (dblk % (BIOSCD_SECSIZE / DEV_BSIZE) != 0)
- return (EINVAL);
- dblk /= (BIOSCD_SECSIZE / DEV_BSIZE);
- DEBUG("read %d from %lld to %p", blks, dblk, buf);
-
- if (rsize)
- *rsize = 0;
- if ((blks = bc_read(unit, dblk, blks, buf)) < 0) {
- DEBUG("read error");
- return (EIO);
- } else {
- if (size / BIOSCD_SECSIZE > blks) {
- if (rsize)
- *rsize = blks * BIOSCD_SECSIZE;
- return (0);
- }
- }
- if (rsize)
- *rsize = size;
- return (0);
-}
-
-/* return negative value for an error, otherwise blocks read */
-static int
-bc_read(int unit, daddr_t dblk, int blks, caddr_t dest)
-{
- u_int maxfer, resid, result, retry, x;
- caddr_t bbuf, p, xp;
- static struct edd_packet packet;
- int biosdev;
-#ifdef DISK_DEBUG
- int error;
-#endif
-
- /* Just in case some idiot actually tries to read -1 blocks... */
- if (blks < 0)
- return (-1);
-
- /* If nothing to do, just return succcess. */
- if (blks == 0)
- return (0);
-
- /* Decide whether we have to bounce */
- if (VTOP(dest) >> 20 != 0) {
- /*
- * The destination buffer is above first 1MB of
- * physical memory so we have to arrange a suitable
- * bounce buffer.
- */
- x = V86_IO_BUFFER_SIZE / BIOSCD_SECSIZE;
- x = min(x, (unsigned)blks);
- bbuf = PTOV(V86_IO_BUFFER);
- maxfer = x;
- } else {
- bbuf = NULL;
- maxfer = 0;
- }
-
- biosdev = bc_unit2bios(unit);
- resid = blks;
- p = dest;
-
- while (resid > 0) {
- if (bbuf)
- xp = bbuf;
- else
- xp = p;
- x = resid;
- if (maxfer > 0)
- x = min(x, maxfer);
-
- /*
- * Loop retrying the operation a couple of times. The BIOS
- * may also retry.
- */
- for (retry = 0; retry < 3; retry++) {
- /* If retrying, reset the drive */
- if (retry > 0) {
- v86.ctl = V86_FLAGS;
- v86.addr = 0x13;
- v86.eax = 0;
- v86.edx = biosdev;
- v86int();
- }
-
- packet.len = sizeof(struct edd_packet);
- packet.count = x;
- packet.off = VTOPOFF(xp);
- packet.seg = VTOPSEG(xp);
- packet.lba = dblk;
- v86.ctl = V86_FLAGS;
- v86.addr = 0x13;
- v86.eax = 0x4200;
- v86.edx = biosdev;
- v86.ds = VTOPSEG(&packet);
- v86.esi = VTOPOFF(&packet);
- v86int();
- result = V86_CY(v86.efl);
- if (result == 0)
- break;
- /* fall back to 1 sector read */
- x = 1;
- }
-
-#ifdef DISK_DEBUG
- error = (v86.eax >> 8) & 0xff;
-#endif
- DEBUG("%d sectors from %lld to %p (0x%x) %s", x, dblk, p,
- VTOP(p), result ? "failed" : "ok");
- DEBUG("unit %d status 0x%x", unit, error);
-
- /* still an error? break off */
- if (result != 0)
- break;
-
- if (bbuf != NULL)
- bcopy(bbuf, p, x * BIOSCD_SECSIZE);
- p += (x * BIOSCD_SECSIZE);
- dblk += x;
- resid -= x;
- }
-
-/* hexdump(dest, (blks * BIOSCD_SECSIZE)); */
-
- if (blks - resid == 0)
- return (-1); /* read failed */
-
- return (blks - resid);
-}
-
-/*
- * Return a suitable dev_t value for (dev).
- */
-int
-bc_getdev(struct i386_devdesc *dev)
-{
- int biosdev, unit;
- int major;
- int rootdev;
-
- unit = dev->dd.d_unit;
- biosdev = bc_unit2bios(unit);
- DEBUG("unit %d BIOS device %d", unit, biosdev);
- if (biosdev == -1) /* not a BIOS device */
- return(-1);
-
- /*
- * XXX: Need to examine device spec here to figure out if SCSI or
- * ATAPI. No idea on how to figure out device number. All we can
- * really pass to the kernel is what bus and device on which bus we
- * were booted from, which dev_t isn't well suited to since those
- * number don't match to unit numbers very well. We may just need
- * to engage in a hack where we pass -C to the boot args if we are
- * the boot device.
- */
- major = ACDMAJOR;
- unit = 0; /* XXX */
-
- /* XXX: Assume partition 'a'. */
- rootdev = MAKEBOOTDEV(major, 0, unit, 0);
- DEBUG("dev is 0x%x\n", rootdev);
- return(rootdev);
-}
diff --git a/stand/i386/libi386/biosdisk.c b/stand/i386/libi386/biosdisk.c
index ef2e3fb56e39..3deba27e9faa 100644
--- a/stand/i386/libi386/biosdisk.c
+++ b/stand/i386/libi386/biosdisk.c
@@ -40,9 +40,11 @@ __FBSDID("$FreeBSD$");
#include <sys/disk.h>
#include <sys/limits.h>
+#include <sys/queue.h>
#include <stand.h>
#include <machine/bootinfo.h>
#include <stdarg.h>
+#include <stdbool.h>
#include <bootstrap.h>
#include <btxv86.h>
@@ -59,6 +61,8 @@ __FBSDID("$FreeBSD$");
#define WFDMAJOR 1
#define FDMAJOR 2
#define DAMAJOR 4
+#define ACDMAJOR 117
+#define CDMAJOR 15
#ifdef DISK_DEBUG
#define DEBUG(fmt, args...) printf("%s: " fmt "\n", __func__, ## args)
@@ -66,12 +70,27 @@ __FBSDID("$FreeBSD$");
#define DEBUG(fmt, args...)
#endif
+struct specification_packet {
+ uint8_t sp_size;
+ uint8_t sp_bootmedia;
+ uint8_t sp_drive;
+ uint8_t sp_controller;
+ uint32_t sp_lba;
+ uint16_t sp_devicespec;
+ uint16_t sp_buffersegment;
+ uint16_t sp_loadsegment;
+ uint16_t sp_sectorcount;
+ uint16_t sp_cylsec;
+ uint8_t sp_head;
+};
+
/*
* List of BIOS devices, translation from disk unit number to
* BIOS unit number.
*/
-static struct bdinfo
+typedef struct bdinfo
{
+ STAILQ_ENTRY(bdinfo) bd_link; /* link in device list */
int bd_unit; /* BIOS unit number */
int bd_cyl; /* BIOS geometry */
int bd_hds;
@@ -83,25 +102,30 @@ static struct bdinfo
#define BD_MODEEDD (BD_MODEEDD1 | BD_MODEEDD3)
#define BD_MODEMASK 0x0003
#define BD_FLOPPY 0x0004
-#define BD_NO_MEDIA 0x0008
+#define BD_CDROM 0x0008
+#define BD_NO_MEDIA 0x0010
int bd_type; /* BIOS 'drive type' (floppy only) */
uint16_t bd_sectorsize; /* Sector size */
uint64_t bd_sectors; /* Disk size */
int bd_open; /* reference counter */
void *bd_bcache; /* buffer cache data */
-} bdinfo [MAXBDDEV];
-static int nbdinfo = 0;
+} bdinfo_t;
-#define BD(dev) (bdinfo[(dev)->dd.d_unit])
#define BD_RD 0
#define BD_WR 1
-static void bd_io_workaround(struct disk_devdesc *dev);
+typedef STAILQ_HEAD(bdinfo_list, bdinfo) bdinfo_list_t;
+static bdinfo_list_t fdinfo = STAILQ_HEAD_INITIALIZER(fdinfo);
+static bdinfo_list_t cdinfo = STAILQ_HEAD_INITIALIZER(cdinfo);
+static bdinfo_list_t hdinfo = STAILQ_HEAD_INITIALIZER(hdinfo);
-static int bd_io(struct disk_devdesc *, daddr_t, int, caddr_t, int);
-static int bd_int13probe(struct bdinfo *bd);
+static void bd_io_workaround(bdinfo_t *);
+static int bd_io(struct disk_devdesc *, bdinfo_t *, daddr_t, int, caddr_t, int);
+static bool bd_int13probe(bdinfo_t *);
static int bd_init(void);
+static int cd_init(void);
+static int fd_init(void);
static int bd_strategy(void *devdata, int flag, daddr_t dblk, size_t size,
char *buf, size_t *rsize);
static int bd_realstrategy(void *devdata, int flag, daddr_t dblk, size_t size,
@@ -110,42 +134,120 @@ static int bd_open(struct open_file *f, ...);
static int bd_close(struct open_file *f);
static int bd_ioctl(struct open_file *f, u_long cmd, void *data);
static int bd_print(int verbose);
+static int cd_print(int verbose);
+static int fd_print(int verbose);
+
+struct devsw biosfd = {
+ .dv_name = "fd",
+ .dv_type = DEVT_FD,
+ .dv_init = fd_init,
+ .dv_strategy = bd_strategy,
+ .dv_open = bd_open,
+ .dv_close = bd_close,
+ .dv_ioctl = bd_ioctl,
+ .dv_print = fd_print,
+ .dv_cleanup = NULL
+};
+
+struct devsw bioscd = {
+ .dv_name = "cd",
+ .dv_type = DEVT_CD,
+ .dv_init = cd_init,
+ .dv_strategy = bd_strategy,
+ .dv_open = bd_open,
+ .dv_close = bd_close,
+ .dv_ioctl = bd_ioctl,
+ .dv_print = cd_print,
+ .dv_cleanup = NULL
+};
-struct devsw biosdisk = {
- "disk",
- DEVT_DISK,
- bd_init,
- bd_strategy,
- bd_open,
- bd_close,
- bd_ioctl,
- bd_print,
- NULL
+struct devsw bioshd = {
+ .dv_name = "disk",
+ .dv_type = DEVT_DISK,
+ .dv_init = bd_init,
+ .dv_strategy = bd_strategy,
+ .dv_open = bd_open,
+ .dv_close = bd_close,
+ .dv_ioctl = bd_ioctl,
+ .dv_print = bd_print,
+ .dv_cleanup = NULL
};
+static bdinfo_list_t *
+bd_get_bdinfo_list(struct devsw *dev)
+{
+ if (dev->dv_type == DEVT_DISK)
+ return (&hdinfo);
+ if (dev->dv_type == DEVT_CD)
+ return (&cdinfo);
+ if (dev->dv_type == DEVT_FD)
+ return (&fdinfo);
+ return (NULL);
+}
+
+/* XXX this gets called way way too often, investigate */
+static bdinfo_t *
+bd_get_bdinfo(struct devdesc *dev)
+{
+ bdinfo_list_t *bdi;
+ bdinfo_t *bd = NULL;
+ int unit;
+
+ bdi = bd_get_bdinfo_list(dev->d_dev);
+ if (bdi == NULL)
+ return (bd);
+
+ unit = 0;
+ STAILQ_FOREACH(bd, bdi, bd_link) {
+ if (unit == dev->d_unit)
+ return (bd);
+ unit++;
+ }
+ return (bd);
+}
+
/*
* Translate between BIOS device numbers and our private unit numbers.
*/
int
bd_bios2unit(int biosdev)
{
- int i;
+ bdinfo_list_t *bdi[] = { &fdinfo, &cdinfo, &hdinfo, NULL };
+ bdinfo_t *bd;
+ int i, unit;
DEBUG("looking for bios device 0x%x", biosdev);
- for (i = 0; i < nbdinfo; i++) {
- DEBUG("bd unit %d is BIOS device 0x%x", i, bdinfo[i].bd_unit);
- if (bdinfo[i].bd_unit == biosdev)
- return (i);
+ for (i = 0; bdi[i] != NULL; i++) {
+ unit = 0;
+ STAILQ_FOREACH(bd, bdi[i], bd_link) {
+ if (bd->bd_unit == biosdev) {
+ DEBUG("bd unit %d is BIOS device 0x%x", unit,
+ bd->bd_unit);
+ return (unit);
+ }
+ unit++;
+ }
}
return (-1);
}
int
-bd_unit2bios(int unit)
+bd_unit2bios(struct i386_devdesc *dev)
{
+ bdinfo_list_t *bdi;
+ bdinfo_t *bd;
+ int unit;
+
+ bdi = bd_get_bdinfo_list(dev->dd.d_dev);
+ if (bdi == NULL)
+ return (-1);
- if ((unit >= 0) && (unit < nbdinfo))
- return (bdinfo[unit].bd_unit);
+ unit = 0;
+ STAILQ_FOREACH(bd, bdi, bd_link) {
+ if (unit == dev->dd.d_unit)
+ return (bd->bd_unit);
+ unit++;
+ }
return (-1);
}
@@ -153,42 +255,128 @@ bd_unit2bios(int unit)
* Quiz the BIOS for disk devices, save a little info about them.
*/
static int
-bd_init(void)
+fd_init(void)
{
- int base, unit, nfd = 0;
+ int unit;
+ bdinfo_t *bd;
- /* sequence 0, 0x80 */
- for (base = 0; base <= 0x80; base += 0x80) {
- for (unit = base; (nbdinfo < MAXBDDEV); unit++) {
-#ifndef VIRTUALBOX
- /*
- * Check the BIOS equipment list for number
- * of fixed disks.
- */
- if (base == 0x80 &&
- (nfd >= *(unsigned char *)PTOV(BIOS_NUMDRIVES)))
- break;
-#endif
- bdinfo[nbdinfo].bd_open = 0;
- bdinfo[nbdinfo].bd_bcache = NULL;
- bdinfo[nbdinfo].bd_unit = unit;
- bdinfo[nbdinfo].bd_flags = unit < 0x80 ? BD_FLOPPY: 0;
- if (!bd_int13probe(&bdinfo[nbdinfo]))
- break;
+ for (unit = 0; unit < MAXBDDEV; unit++) {
+ if ((bd = calloc(1, sizeof(*bd))) == NULL)
+ break;
+ bd->bd_flags = BD_FLOPPY;
+ bd->bd_unit = unit;
+ if (!bd_int13probe(bd)) {
+ free(bd);
+ break;
+ }
+ if (bd->bd_sectors == 0)
+ bd->bd_flags |= BD_NO_MEDIA;
+
+ printf("BIOS drive %c: is %s%d\n", ('A' + unit),
+ biosfd.dv_name, unit);
+
+ STAILQ_INSERT_TAIL(&fdinfo, bd, bd_link);
+ }
+
+ bcache_add_dev(unit);
+ return (0);
+}
- /* XXX we need "disk aliases" to make this simpler */
- printf("BIOS drive %c: is disk%d\n", (unit < 0x80) ?
- ('A' + unit): ('C' + unit - 0x80), nbdinfo);
- nbdinfo++;
- if (base == 0x80)
- nfd++;
+static int
+bd_init(void)
+{
+ int base, unit;
+ bdinfo_t *bd;
+
+ base = 0x80;
+ for (unit = 0; unit < *(unsigned char *)PTOV(BIOS_NUMDRIVES); unit++) {
+ /*
+ * Check the BIOS equipment list for number of fixed disks.
+ */
+ if ((bd = calloc(1, sizeof(*bd))) == NULL)
+ break;
+ bd->bd_unit = base + unit;
+ if (!bd_int13probe(bd)) {
+ free(bd);
+ break;
}
+
+ printf("BIOS drive %c: is %s%d\n", ('C' + unit),
+ bioshd.dv_name, unit);
+
+ STAILQ_INSERT_TAIL(&hdinfo, bd, bd_link);
}
- bcache_add_dev(nbdinfo);
+ bcache_add_dev(unit);
return (0);
}
/*
+ * We can't quiz, we have to be told what device to use, so this function
+ * doesn't do anything. Instead, the loader calls bc_add() with the BIOS
+ * device number to add.
+ */
+static int
+cd_init(void)
+{
+
+ return (0);
+}
+
+int
+bc_add(int biosdev)
+{
+ bdinfo_t *bd;
+ struct specification_packet bc_sp;
+ int nbcinfo = 0;
+
+ if (!STAILQ_EMPTY(&cdinfo))
+ return (-1);
+
+ v86.ctl = V86_FLAGS;
+ v86.addr = 0x13;
+ v86.eax = 0x4b01;
+ v86.edx = biosdev;
+ v86.ds = VTOPSEG(&bc_sp);
+ v86.esi = VTOPOFF(&bc_sp);
+ v86int();
+ if ((v86.eax & 0xff00) != 0)
+ return (-1);
+
+ if ((bd = calloc(1, sizeof(*bd))) == NULL)
+ return (-1);
+
+ bd->bd_flags = BD_CDROM;
+ bd->bd_unit = biosdev;
+
+ /*
+ * Ignore result from bd_int13probe(), we will use local
+ * workaround below.
+ */
+ (void)bd_int13probe(bd);
+
+ if (bd->bd_cyl == 0) {
+ bd->bd_cyl = ((bc_sp.sp_cylsec & 0xc0) << 2) +
+ ((bc_sp.sp_cylsec & 0xff00) >> 8) + 1;
+ }
+ if (bd->bd_hds == 0)
+ bd->bd_hds = bc_sp.sp_head + 1;
+ if (bd->bd_sec == 0)
+ bd->bd_sec = bc_sp.sp_cylsec & 0x3f;
+ if (bd->bd_sectors == 0)
+ bd->bd_sectors = (uint64_t)bd->bd_cyl * bd->bd_hds * bd->bd_sec;
+
+ /* Still no size? use 7.961GB */
+ if (bd->bd_sectors == 0)
+ bd->bd_sectors = 4173824;
+
+ STAILQ_INSERT_TAIL(&cdinfo, bd, bd_link);
+ printf("BIOS CD is cd%d\n", nbcinfo);
+ nbcinfo++;
+ bcache_add_dev(nbcinfo); /* register cd device in bcache */
+ return(0);
+}
+
+/*
* Return EDD version or 0 if EDD is not supported on this drive.
*/
static int
@@ -306,11 +494,10 @@ bd_get_diskinfo_ext(struct bdinfo *bd)
/*
* Try to detect a device supported by the legacy int13 BIOS
*/
-static int
-bd_int13probe(struct bdinfo *bd)
+static bool
+bd_int13probe(bdinfo_t *bd)
{
- int edd;
- int ret;
+ int edd, ret;
bd->bd_flags &= ~BD_NO_MEDIA;
@@ -340,7 +527,7 @@ bd_int13probe(struct bdinfo *bd)
v86.edx = bd->bd_unit;
v86int();
if (V86_CY(v86.efl) || (v86.eax & 0x300) == 0)
- return (0);
+ return (false);
}
ret = 1;
@@ -354,7 +541,6 @@ bd_int13probe(struct bdinfo *bd)
bd->bd_cyl = 80;
bd->bd_hds = 2;
bd->bd_sec = 18;
- bd->bd_type = 4;
bd->bd_sectors = 2880;
/* Since we are there, there most likely is no media */
bd->bd_flags |= BD_NO_MEDIA;
@@ -362,6 +548,10 @@ bd_int13probe(struct bdinfo *bd)
}
if (ret != 0) {
+ /* CD is special case, bc_add() has its own fallback. */
+ if ((bd->bd_flags & BD_CDROM) != 0)
+ return (true);
+
if (bd->bd_sectors != 0 && edd != 0) {
bd->bd_sec = 63;
bd->bd_hds = 255;
@@ -369,9 +559,18 @@ bd_int13probe(struct bdinfo *bd)
(bd->bd_sectors + bd->bd_sec * bd->bd_hds - 1) /
bd->bd_sec * bd->bd_hds;
} else {
+ const char *dv_name;
+
+ if ((bd->bd_flags & BD_FLOPPY) != 0)
+ dv_name = biosfd.dv_name;
+ else if ((bd->bd_flags & BD_CDROM) != 0)
+ dv_name = bioscd.dv_name;
+ else
+ dv_name = bioshd.dv_name;
+
printf("Can not get information about %s unit %#x\n",
- biosdisk.dv_name, bd->bd_unit);
- return (0);
+ dv_name, bd->bd_unit);
+ return (false);
}
}
@@ -383,54 +582,86 @@ bd_int13probe(struct bdinfo *bd)
if (bd->bd_sectors == 0)
bd->bd_sectors = (uint64_t)bd->bd_cyl * bd->bd_hds * bd->bd_sec;
- DEBUG("unit 0x%x geometry %d/%d/%d", bd->bd_unit, bd->bd_cyl,
+ DEBUG("unit 0x%x geometry %d/%d/%d\n", bd->bd_unit, bd->bd_cyl,
bd->bd_hds, bd->bd_sec);
- return (1);
+ return (true);
+}
+
+static int
+bd_count(bdinfo_list_t *bdi)
+{
+ bdinfo_t *bd;
+ int i;
+
+ i = 0;
+ STAILQ_FOREACH(bd, bdi, bd_link)
+ i++;
+ return (i);
}
/*
* Print information about disks
*/
static int
-bd_print(int verbose)
+bd_print_common(struct devsw *dev, bdinfo_list_t *bdi, int verbose)
{
- static char line[80];
- struct disk_devdesc dev;
+ char line[80];
+ struct disk_devdesc devd;
+ bdinfo_t *bd;
int i, ret = 0;
+ char drive;
- if (nbdinfo == 0)
+ if (STAILQ_EMPTY(bdi))
return (0);
- printf("%s devices:", biosdisk.dv_name);
+ printf("%s devices:", dev->dv_name);
if ((ret = pager_output("\n")) != 0)
return (ret);
- for (i = 0; i < nbdinfo; i++) {
+ i = -1;
+ STAILQ_FOREACH(bd, bdi, bd_link) {
+ i++;
+
+ switch (dev->dv_type) {
+ case DEVT_FD:
+ drive = 'A';
+ break;
+ case DEVT_CD:
+ drive = 'C' + bd_count(&hdinfo);
+ break;
+ default:
+ drive = 'C';
+ break;
+ }
+
snprintf(line, sizeof(line),
- " disk%d: BIOS drive %c (%s%ju X %u):\n", i,
- (bdinfo[i].bd_unit < 0x80) ? ('A' + bdinfo[i].bd_unit):
- ('C' + bdinfo[i].bd_unit - 0x80),
- (bdinfo[i].bd_flags & BD_NO_MEDIA) == BD_NO_MEDIA ?
+ " %s%d: BIOS drive %c (%s%ju X %u):\n",
+ dev->dv_name, i, drive + i,
+ (bd->bd_flags & BD_NO_MEDIA) == BD_NO_MEDIA ?
"no media, " : "",
- (uintmax_t)bdinfo[i].bd_sectors,
- bdinfo[i].bd_sectorsize);
+ (uintmax_t)bd->bd_sectors,
+ bd->bd_sectorsize);
if ((ret = pager_output(line)) != 0)
break;
- if ((bdinfo[i].bd_flags & BD_NO_MEDIA) == BD_NO_MEDIA)
+ if ((bd->bd_flags & BD_NO_MEDIA) == BD_NO_MEDIA)
continue;
- dev.dd.d_dev = &biosdisk;
- dev.dd.d_unit = i;
- dev.d_slice = -1;
- dev.d_partition = -1;
- if (disk_open(&dev,
- bdinfo[i].bd_sectorsize * bdinfo[i].bd_sectors,
- bdinfo[i].bd_sectorsize) == 0) {
- snprintf(line, sizeof(line), " disk%d", i);
- ret = disk_print(&dev, line, verbose);
- disk_close(&dev);
+ if (dev->dv_type != DEVT_DISK)
+ continue;
+
+ devd.dd.d_dev = dev;
+ devd.dd.d_unit = i;
+ devd.d_slice = -1;
+ devd.d_partition = -1;
+ if (disk_open(&devd,
+ bd->bd_sectorsize * bd->bd_sectors,
+ bd->bd_sectorsize) == 0) {
+ snprintf(line, sizeof(line), " %s%d",
+ dev->dv_name, i);
+ ret = disk_print(&devd, line, verbose);
+ disk_close(&devd);
if (ret != 0)
break;
}
@@ -438,6 +669,24 @@ bd_print(int verbose)
return (ret);
}
+static int
+fd_print(int verbose)
+{
+ return (bd_print_common(&biosfd, &fdinfo, verbose));
+}
+
+static int
+bd_print(int verbose)
+{
+ return (bd_print_common(&bioshd, &hdinfo, verbose));
+}
+
+static int
+cd_print(int verbose)
+{
+ return (bd_print_common(&bioscd, &cdinfo, verbose));
+}
+
/*
* Read disk size from partition.
* This is needed to work around buggy BIOS systems returning
@@ -448,21 +697,26 @@ bd_print(int verbose)
static uint64_t
bd_disk_get_sectors(struct disk_devdesc *dev)
{
+ bdinfo_t *bd;
struct disk_devdesc disk;
uint64_t size;
+ bd = bd_get_bdinfo(&dev->dd);
+ if (bd == NULL)
+ return (0);
+
disk.dd.d_dev = dev->dd.d_dev;
disk.dd.d_unit = dev->dd.d_unit;
disk.d_slice = -1;
disk.d_partition = -1;
disk.d_offset = 0;
- size = BD(dev).bd_sectors * BD(dev).bd_sectorsize;
- if (disk_open(&disk, size, BD(dev).bd_sectorsize) == 0) {
+ size = bd->bd_sectors * bd->bd_sectorsize;
+ if (disk_open(&disk, size, bd->bd_sectorsize) == 0) {
(void) disk_ioctl(&disk, DIOCGMEDIASIZE, &size);
disk_close(&disk);
}
- return (size / BD(dev).bd_sectorsize);
+ return (size / bd->bd_sectorsize);
}
/*
@@ -478,6 +732,7 @@ bd_disk_get_sectors(struct disk_devdesc *dev)
static int
bd_open(struct open_file *f, ...)
{
+ bdinfo_t *bd;
struct disk_devdesc *dev;
va_list ap;
int rc;
@@ -486,29 +741,33 @@ bd_open(struct open_file *f, ...)
dev = va_arg(ap, struct disk_devdesc *);
va_end(ap);
- if (dev->dd.d_unit < 0 || dev->dd.d_unit >= nbdinfo)
+ bd = bd_get_bdinfo(&dev->dd);
+ if (bd == NULL)
return (EIO);
- if ((BD(dev).bd_flags & BD_NO_MEDIA) == BD_NO_MEDIA) {
- if (!bd_int13probe(&BD(dev)))
+ if ((bd->bd_flags & BD_NO_MEDIA) == BD_NO_MEDIA) {
+ if (!bd_int13probe(bd))
return (EIO);
- if ((BD(dev).bd_flags & BD_NO_MEDIA) == BD_NO_MEDIA)
+ if ((bd->bd_flags & BD_NO_MEDIA) == BD_NO_MEDIA)
return (EIO);
}
- if (BD(dev).bd_bcache == NULL)
- BD(dev).bd_bcache = bcache_allocate();
-
- if (BD(dev).bd_open == 0)
- BD(dev).bd_sectors = bd_disk_get_sectors(dev);
- BD(dev).bd_open++;
-
- rc = disk_open(dev, BD(dev).bd_sectors * BD(dev).bd_sectorsize,
- BD(dev).bd_sectorsize);
- if (rc != 0) {
- BD(dev).bd_open--;
- if (BD(dev).bd_open == 0) {
- bcache_free(BD(dev).bd_bcache);
- BD(dev).bd_bcache = NULL;
+ if (bd->bd_bcache == NULL)
+ bd->bd_bcache = bcache_allocate();
+
+ if (bd->bd_open == 0)
+ bd->bd_sectors = bd_disk_get_sectors(dev);
+ bd->bd_open++;
+
+ rc = 0;
+ if (dev->dd.d_dev->dv_type == DEVT_DISK) {
+ rc = disk_open(dev, bd->bd_sectors * bd->bd_sectorsize,
+ bd->bd_sectorsize);
+ if (rc != 0) {
+ bd->bd_open--;
+ if (bd->bd_open == 0) {
+ bcache_free(bd->bd_bcache);
+ bd->bd_bcache = NULL;
+ }
}
}
return (rc);
@@ -518,34 +777,48 @@ static int
bd_close(struct open_file *f)
{
struct disk_devdesc *dev;
+ bdinfo_t *bd;
+ int rc = 0;
dev = (struct disk_devdesc *)f->f_devdata;
- BD(dev).bd_open--;
- if (BD(dev).bd_open == 0) {
- bcache_free(BD(dev).bd_bcache);
- BD(dev).bd_bcache = NULL;
+ bd = bd_get_bdinfo(&dev->dd);
+ if (bd == NULL)
+ return (EIO);
+
+ bd->bd_open--;
+ if (bd->bd_open == 0) {
+ bcache_free(bd->bd_bcache);
+ bd->bd_bcache = NULL;
}
- return (disk_close(dev));
+ if (dev->dd.d_dev->dv_type == DEVT_DISK)
+ rc = disk_close(dev);
+ return (rc);
}
static int
bd_ioctl(struct open_file *f, u_long cmd, void *data)
{
+ bdinfo_t *bd;
struct disk_devdesc *dev;
int rc;
dev = (struct disk_devdesc *)f->f_devdata;
+ bd = bd_get_bdinfo(&dev->dd);
+ if (bd == NULL)
+ return (EIO);
- rc = disk_ioctl(dev, cmd, data);
- if (rc != ENOTTY)
- return (rc);
+ if (dev->dd.d_dev->dv_type == DEVT_DISK) {
+ rc = disk_ioctl(dev, cmd, data);
+ if (rc != ENOTTY)
+ return (rc);
+ }
switch (cmd) {
case DIOCGSECTORSIZE:
- *(uint32_t *)data = BD(dev).bd_sectorsize;
+ *(uint32_t *)data = bd->bd_sectorsize;
break;
case DIOCGMEDIASIZE:
- *(uint64_t *)data = BD(dev).bd_sectors * BD(dev).bd_sectorsize;
+ *(uint64_t *)data = bd->bd_sectors * bd->bd_sectorsize;
break;
default:
return (ENOTTY);
@@ -557,14 +830,27 @@ static int
bd_strategy(void *devdata, int rw, daddr_t dblk, size_t size,
char *buf, size_t *rsize)
{
+ bdinfo_t *bd;
struct bcache_devdata bcd;
struct disk_devdesc *dev;
+ daddr_t offset;
dev = (struct disk_devdesc *)devdata;
+ bd = bd_get_bdinfo(&dev->dd);
+ if (bd == NULL)
+ return (EINVAL);
+
bcd.dv_strategy = bd_realstrategy;
bcd.dv_devdata = devdata;
- bcd.dv_cache = BD(dev).bd_bcache;
- return (bcache_strategy(&bcd, rw, dblk + dev->d_offset, size,
+ bcd.dv_cache = bd->bd_bcache;
+
+ offset = 0;
+ if (dev->dd.d_dev->dv_type == DEVT_DISK) {
+
+ offset = dev->d_offset * bd->bd_sectorsize;
+ offset /= BIOSDISK_SECSIZE;
+ }
+ return (bcache_strategy(&bcd, rw, dblk + offset, size,
buf, rsize));
}
@@ -573,12 +859,14 @@ bd_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size,
char *buf, size_t *rsize)
{
struct disk_devdesc *dev = (struct disk_devdesc *)devdata;
- uint64_t disk_blocks, offset;
+ bdinfo_t *bd;
+ uint64_t disk_blocks, offset, d_offset;
size_t blks, blkoff, bsize, rest;
caddr_t bbuf;
int rc;
- if ((BD(dev).bd_flags & BD_NO_MEDIA) == BD_NO_MEDIA)
+ bd = bd_get_bdinfo(&dev->dd);
+ if (bd == NULL || (bd->bd_flags & BD_NO_MEDIA) == BD_NO_MEDIA)
return (EIO);
/*
@@ -596,8 +884,8 @@ bd_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size,
DEBUG("open_disk %p", dev);
offset = dblk * BIOSDISK_SECSIZE;
- dblk = offset / BD(dev).bd_sectorsize;
- blkoff = offset % BD(dev).bd_sectorsize;
+ dblk = offset / bd->bd_sectorsize;
+ blkoff = offset % bd->bd_sectorsize;
/*
* Check the value of the size argument. We do have quite small
@@ -610,8 +898,8 @@ bd_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size,
return (EIO);
}
- blks = size / BD(dev).bd_sectorsize;
- if (blks == 0 || (size % BD(dev).bd_sectorsize) != 0)
+ blks = size / bd->bd_sectorsize;
+ if (blks == 0 || (size % bd->bd_sectorsize) != 0)
blks++;
if (dblk > dblk + blks)
@@ -624,44 +912,48 @@ bd_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size,
* Get disk blocks, this value is either for whole disk or for
* partition.
*/
- if (disk_ioctl(dev, DIOCGMEDIASIZE, &disk_blocks) == 0) {
- /* DIOCGMEDIASIZE does return bytes. */
- disk_blocks /= BD(dev).bd_sectorsize;
- } else {
- /* We should not get here. Just try to survive. */
- disk_blocks = BD(dev).bd_sectors - dev->d_offset;
+ d_offset = 0;
+ disk_blocks = 0;
+ if (dev->dd.d_dev->dv_type == DEVT_DISK) {
+ if (disk_ioctl(dev, DIOCGMEDIASIZE, &disk_blocks) == 0) {
+ /* DIOCGMEDIASIZE does return bytes. */
+ disk_blocks /= bd->bd_sectorsize;
+ }
+ d_offset = dev->d_offset;
}
+ if (disk_blocks == 0)
+ disk_blocks = bd->bd_sectors - d_offset;
/* Validate source block address. */
- if (dblk < dev->d_offset || dblk >= dev->d_offset + disk_blocks)
+ if (dblk < d_offset || dblk >= d_offset + disk_blocks)
return (EIO);
/*
* Truncate if we are crossing disk or partition end.
*/
- if (dblk + blks >= dev->d_offset + disk_blocks) {
- blks = dev->d_offset + disk_blocks - dblk;
- size = blks * BD(dev).bd_sectorsize;
+ if (dblk + blks >= d_offset + disk_blocks) {
+ blks = d_offset + disk_blocks - dblk;
+ size = blks * bd->bd_sectorsize;
DEBUG("short I/O %d", blks);
}
- if (V86_IO_BUFFER_SIZE / BD(dev).bd_sectorsize == 0)
- panic("BUG: Real mode buffer is too small\n");
+ if (V86_IO_BUFFER_SIZE / bd->bd_sectorsize == 0)
+ panic("BUG: Real mode buffer is too small");
bbuf = PTOV(V86_IO_BUFFER);
rest = size;
while (blks > 0) {
- int x = min(blks, V86_IO_BUFFER_SIZE / BD(dev).bd_sectorsize);
+ int x = min(blks, V86_IO_BUFFER_SIZE / bd->bd_sectorsize);
switch (rw & F_MASK) {
case F_READ:
DEBUG("read %d from %lld to %p", x, dblk, buf);
- bsize = BD(dev).bd_sectorsize * x - blkoff;
+ bsize = bd->bd_sectorsize * x - blkoff;
if (rest < bsize)
bsize = rest;
- if ((rc = bd_io(dev, dblk, x, bbuf, BD_RD)) != 0)
+ if ((rc = bd_io(dev, bd, dblk, x, bbuf, BD_RD)) != 0)
return (EIO);
bcopy(bbuf + blkoff, buf, bsize);
@@ -674,27 +966,27 @@ bd_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size,
* bbuf.
*/
x = 1;
- bsize = BD(dev).bd_sectorsize - blkoff;
+ bsize = bd->bd_sectorsize - blkoff;
bsize = min(bsize, rest);
- rc = bd_io(dev, dblk, x, bbuf, BD_RD);
- } else if (rest < BD(dev).bd_sectorsize) {
+ rc = bd_io(dev, bd, dblk, x, bbuf, BD_RD);
+ } else if (rest < bd->bd_sectorsize) {
/*
* The remaining block is not full
* sector. Read 1 sector to bbuf.
*/
x = 1;
bsize = rest;
- rc = bd_io(dev, dblk, x, bbuf, BD_RD);
+ rc = bd_io(dev, bd, dblk, x, bbuf, BD_RD);
} else {
/* We can write full sector(s). */
- bsize = BD(dev).bd_sectorsize * x;
+ bsize = bd->bd_sectorsize * x;
}
/*
* Put your Data In, Put your Data out,
* Put your Data In, and shake it all about
*/
bcopy(buf, bbuf + blkoff, bsize);
- if ((rc = bd_io(dev, dblk, x, bbuf, BD_WR)) != 0)
+ if ((rc = bd_io(dev, bd, dblk, x, bbuf, BD_WR)) != 0)
return (EIO);
break;
@@ -716,7 +1008,7 @@ bd_realstrategy(void *devdata, int rw, daddr_t dblk, size_t size,
}
static int
-bd_edd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest,
+bd_edd_io(bdinfo_t *bd, daddr_t dblk, int blks, caddr_t dest,
int dowrite)
{
static struct edd_packet packet;
@@ -733,7 +1025,7 @@ bd_edd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest,
v86.eax = 0x4300;
else
v86.eax = 0x4200;
- v86.edx = BD(dev).bd_unit;
+ v86.edx = bd->bd_unit;
v86.ds = VTOPSEG(&packet);
v86.esi = VTOPOFF(&packet);
v86int();
@@ -743,17 +1035,17 @@ bd_edd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest,
}
static int
-bd_chs_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest,
+bd_chs_io(bdinfo_t *bd, daddr_t dblk, int blks, caddr_t dest,
int dowrite)
{
uint32_t x, bpc, cyl, hd, sec;
- bpc = BD(dev).bd_sec * BD(dev).bd_hds; /* blocks per cylinder */
+ bpc = bd->bd_sec * bd->bd_hds; /* blocks per cylinder */
x = dblk;
cyl = x / bpc; /* block # / blocks per cylinder */
x %= bpc; /* block offset into cylinder */
- hd = x / BD(dev).bd_sec; /* offset / blocks per track */
- sec = x % BD(dev).bd_sec; /* offset into track */
+ hd = x / bd->bd_sec; /* offset / blocks per track */
+ sec = x % bd->bd_sec; /* offset into track */
/* correct sector number for 1-based BIOS numbering */
sec++;
@@ -770,7 +1062,7 @@ bd_chs_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest,
else
v86.eax = 0x200 | blks;
v86.ecx = ((cyl & 0xff) << 8) | ((cyl & 0x300) >> 2) | sec;
- v86.edx = (hd << 8) | BD(dev).bd_unit;
+ v86.edx = (hd << 8) | bd->bd_unit;
v86.es = VTOPSEG(dest);
v86.ebx = VTOPOFF(dest);
v86int();
@@ -780,16 +1072,16 @@ bd_chs_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest,
}
static void
-bd_io_workaround(struct disk_devdesc *dev)
+bd_io_workaround(bdinfo_t *bd)
{
uint8_t buf[8 * 1024];
- bd_edd_io(dev, 0xffffffff, 1, (caddr_t)buf, BD_RD);
+ bd_edd_io(bd, 0xffffffff, 1, (caddr_t)buf, BD_RD);
}
static int
-bd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest,
- int dowrite)
+bd_io(struct disk_devdesc *dev, bdinfo_t *bd, daddr_t dblk, int blks,
+ caddr_t dest, int dowrite)
{
int result, retry;
@@ -809,20 +1101,20 @@ bd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest,
* may also retry.
*/
if (dowrite == BD_RD && dblk >= 0x100000000)
- bd_io_workaround(dev);
+ bd_io_workaround(bd);
for (retry = 0; retry < 3; retry++) {
- if (BD(dev).bd_flags & BD_MODEEDD)
- result = bd_edd_io(dev, dblk, blks, dest, dowrite);
+ if (bd->bd_flags & BD_MODEEDD)
+ result = bd_edd_io(bd, dblk, blks, dest, dowrite);
else
- result = bd_chs_io(dev, dblk, blks, dest, dowrite);
+ result = bd_chs_io(bd, dblk, blks, dest, dowrite);
if (result == 0) {
- if (BD(dev).bd_flags & BD_NO_MEDIA)
- BD(dev).bd_flags &= ~BD_NO_MEDIA;
+ if (bd->bd_flags & BD_NO_MEDIA)
+ bd->bd_flags &= ~BD_NO_MEDIA;
break;
}
- bd_reset_disk(BD(dev).bd_unit);
+ bd_reset_disk(bd->bd_unit);
/*
* Error codes:
@@ -832,12 +1124,12 @@ bd_io(struct disk_devdesc *dev, daddr_t dblk, int blks, caddr_t dest,
* There is no reason to repeat the IO with errors above.
*/
if (result == 0x20 || result == 0x31 || result == 0x80) {
- BD(dev).bd_flags |= BD_NO_MEDIA;
+ bd->bd_flags |= BD_NO_MEDIA;
break;
}
}
- if (result != 0 && (BD(dev).bd_flags & BD_NO_MEDIA) == 0) {
+ if (result != 0 && (bd->bd_flags & BD_NO_MEDIA) == 0) {
if (dowrite == BD_WR) {
printf("%s%d: Write %d sector(s) from %p (0x%x) "
"to %lld: 0x%x\n", dev->dd.d_dev->dv_name,
@@ -893,26 +1185,40 @@ int
bd_getdev(struct i386_devdesc *d)
{
struct disk_devdesc *dev;
+ bdinfo_t *bd;
int biosdev;
int major;
int rootdev;
char *nip, *cp;
- int i, unit;
+ int i, unit, slice, partition;
+
+ /* XXX: Assume partition 'a'. */
+ slice = 0;
+ partition = 0;
dev = (struct disk_devdesc *)d;
- biosdev = bd_unit2bios(dev->dd.d_unit);
+ bd = bd_get_bdinfo(&dev->dd);
+ if (bd == NULL)
+ return (-1);
+
+ biosdev = bd_unit2bios(d);
DEBUG("unit %d BIOS device %d", dev->dd.d_unit, biosdev);
if (biosdev == -1) /* not a BIOS device */
return (-1);
- if (disk_open(dev, BD(dev).bd_sectors * BD(dev).bd_sectorsize,
- BD(dev).bd_sectorsize) != 0) /* oops, not a viable device */
- return (-1);
- else
- disk_close(dev);
+
+ if (dev->dd.d_dev->dv_type == DEVT_DISK) {
+ if (disk_open(dev, bd->bd_sectors * bd->bd_sectorsize,
+ bd->bd_sectorsize) != 0) /* oops, not a viable device */
+ return (-1);
+ else
+ disk_close(dev);
+ slice = dev->d_slice + 1;
+ partition = dev->d_partition;
+ }
if (biosdev < 0x80) {
/* floppy (or emulated floppy) or ATAPI device */
- if (bdinfo[dev->dd.d_unit].bd_type == DT_ATAPI) {
+ if (bd->bd_type == DT_ATAPI) {
/* is an ATAPI disk */
major = WFDMAJOR;
} else {
@@ -926,6 +1232,20 @@ bd_getdev(struct i386_devdesc *d)
/* default root disk unit number */
unit = biosdev & 0x7f;
+ if (dev->dd.d_dev->dv_type == DEVT_CD) {
+ /*
+ * XXX: Need to examine device spec here to figure out if
+ * SCSI or ATAPI. No idea on how to figure out device number.
+ * All we can really pass to the kernel is what bus and device
+ * on which bus we were booted from, which dev_t isn't well
+ * suited to since those number don't match to unit numbers
+ * very well. We may just need to engage in a hack where
+ * we pass -C to the boot args if we are the boot device.
+ */
+ major = ACDMAJOR;
+ unit = 0; /* XXX */
+ }
+
/* XXX a better kludge to set the root disk unit number */
if ((nip = getenv("root_disk_unit")) != NULL) {
i = strtol(nip, &cp, 0);
@@ -934,7 +1254,7 @@ bd_getdev(struct i386_devdesc *d)
unit = i;
}
- rootdev = MAKEBOOTDEV(major, dev->d_slice + 1, unit, dev->d_partition);
+ rootdev = MAKEBOOTDEV(major, slice, unit, partition);
DEBUG("dev is 0x%x\n", rootdev);
return (rootdev);
}
diff --git a/stand/i386/libi386/bootinfo32.c b/stand/i386/libi386/bootinfo32.c
index 58881b705f9e..e6a92a2164d7 100644
--- a/stand/i386/libi386/bootinfo32.c
+++ b/stand/i386/libi386/bootinfo32.c
@@ -176,14 +176,9 @@ bi_load32(char *args, int *howtop, int *bootdevp, vm_offset_t *bip, vm_offset_t
switch(rootdev->dd.d_dev->dv_type) {
case DEVT_CD:
- /* Pass in BIOS device number. */
- bi.bi_bios_dev = bc_unit2bios(rootdev->dd.d_unit);
- bootdevnr = bc_getdev(rootdev);
- break;
-
case DEVT_DISK:
/* pass in the BIOS device number of the current disk */
- bi.bi_bios_dev = bd_unit2bios(rootdev->dd.d_unit);
+ bi.bi_bios_dev = bd_unit2bios(rootdev);
bootdevnr = bd_getdev(rootdev);
break;
diff --git a/stand/i386/libi386/libi386.h b/stand/i386/libi386/libi386.h
index 8fcb3e37a66b..561460c17590 100644
--- a/stand/i386/libi386/libi386.h
+++ b/stand/i386/libi386/libi386.h
@@ -91,17 +91,15 @@ extern struct devdesc currdev; /* our current device */
/* exported devices XXX rename? */
extern struct devsw bioscd;
-extern struct devsw biosdisk;
+extern struct devsw biosfd;
+extern struct devsw bioshd;
extern struct devsw pxedisk;
extern struct fs_ops pxe_fsops;
int bc_add(int biosdev); /* Register CD booted from. */
-int bc_getdev(struct i386_devdesc *dev); /* return dev_t for (dev) */
-int bc_bios2unit(int biosdev); /* xlate BIOS device -> bioscd unit */
-int bc_unit2bios(int unit); /* xlate bioscd unit -> BIOS device */
uint32_t bd_getbigeom(int bunit); /* return geometry in bootinfo format */
int bd_bios2unit(int biosdev); /* xlate BIOS device -> biosdisk unit */
-int bd_unit2bios(int unit); /* xlate biosdisk unit -> BIOS device */
+int bd_unit2bios(struct i386_devdesc *); /* xlate biosdisk -> BIOS device */
int bd_getdev(struct i386_devdesc *dev); /* return dev_t for (dev) */
ssize_t i386_copyin(const void *src, vm_offset_t dest, const size_t len);
diff --git a/stand/i386/libi386/pxetramp.s b/stand/i386/libi386/pxetramp.S
index dcf1441aeb24..dcf1441aeb24 100644
--- a/stand/i386/libi386/pxetramp.s
+++ b/stand/i386/libi386/pxetramp.S
diff --git a/stand/i386/loader/chain.c b/stand/i386/loader/chain.c
index 4e04cc4a23fc..43ba2697e938 100644
--- a/stand/i386/loader/chain.c
+++ b/stand/i386/loader/chain.c
@@ -113,7 +113,7 @@ command_chain(int argc, char *argv[])
relocater_data[0].dest = 0x7C00;
relocater_data[0].size = size;
- relocator_edx = bd_unit2bios(rootdev->dd.d_unit);
+ relocator_edx = bd_unit2bios(rootdev);
relocator_esi = relocater_size;
relocator_ds = 0;
relocator_es = 0;
diff --git a/stand/i386/loader/conf.c b/stand/i386/loader/conf.c
index 1e62e401793d..a3c676a6b549 100644
--- a/stand/i386/loader/conf.c
+++ b/stand/i386/loader/conf.c
@@ -51,8 +51,9 @@ extern struct devsw fwohci;
/* Exported for libstand */
struct devsw *devsw[] = {
+ &biosfd,
&bioscd,
- &biosdisk,
+ &bioshd,
#if defined(LOADER_NFS_SUPPORT) || defined(LOADER_TFTP_SUPPORT)
&pxedisk,
#endif
diff --git a/stand/i386/loader/main.c b/stand/i386/loader/main.c
index fd6507da9b6a..a7d1e82fd488 100644
--- a/stand/i386/loader/main.c
+++ b/stand/i386/loader/main.c
@@ -73,6 +73,7 @@ void exit(int code);
#ifdef LOADER_GELI_SUPPORT
#include "geliboot.h"
struct geli_boot_args *gargs;
+struct geli_boot_data *gbdata;
#endif
#ifdef LOADER_ZFS_SUPPORT
struct zfs_boot_args *zargs;
@@ -169,37 +170,49 @@ main(void)
#ifdef LOADER_ZFS_SUPPORT
archsw.arch_zfs_probe = i386_zfs_probe;
-#ifdef LOADER_GELI_SUPPORT
- if ((kargs->bootflags & KARGS_FLAGS_EXTARG) != 0) {
+ /*
+ * zfsboot and gptzfsboot have always passed KARGS_FLAGS_ZFS, so if that is
+ * set along with KARGS_FLAGS_EXTARG we know we can interpret the extarg
+ * data as a struct zfs_boot_args.
+ */
+#define KARGS_EXTARGS_ZFS (KARGS_FLAGS_EXTARG | KARGS_FLAGS_ZFS)
+
+ if ((kargs->bootflags & KARGS_EXTARGS_ZFS) == KARGS_EXTARGS_ZFS) {
zargs = (struct zfs_boot_args *)(kargs + 1);
- if (zargs != NULL && zargs->size >= offsetof(struct zfs_boot_args, gelipw)) {
- if (zargs->size >= offsetof(struct zfs_boot_args, keybuf_sentinel) &&
- zargs->keybuf_sentinel == KEYBUF_SENTINEL) {
- geli_import_key_buffer(zargs->keybuf);
- }
- if (zargs->gelipw[0] != '\0') {
- setenv("kern.geom.eli.passphrase", zargs->gelipw, 1);
- explicit_bzero(zargs->gelipw, sizeof(zargs->gelipw));
- }
- }
}
-#endif /* LOADER_GELI_SUPPORT */
-#else /* !LOADER_ZFS_SUPPORT */
+#endif /* LOADER_ZFS_SUPPORT */
+
#ifdef LOADER_GELI_SUPPORT
- if ((kargs->bootflags & KARGS_FLAGS_EXTARG) != 0) {
+ /*
+ * If we decided earlier that we have zfs_boot_args extarg data, and it is
+ * big enough to contain the embedded geli data (the early zfs_boot_args
+ * structs weren't), then init the gbdata pointer accordingly. If there is
+ * extarg data which isn't zfs_boot_args data, determine whether it is
+ * geli_boot_args data. Recent versions of gptboot set KARGS_FLAGS_GELI to
+ * indicate that. Earlier versions didn't, but we presume that's what we
+ * have if the extarg size exactly matches the size of the geli_boot_args
+ * struct during that pre-flag era.
+ */
+#define LEGACY_GELI_ARGS_SIZE 260 /* This can never change */
+
+#ifdef LOADER_ZFS_SUPPORT
+ if (zargs != NULL) {
+ if (zargs->size > offsetof(struct zfs_boot_args, gelidata)) {
+ gbdata = &zargs->gelidata;
+ }
+ } else
+#endif /* LOADER_ZFS_SUPPORT */
+ if ((kargs->bootflags & KARGS_FLAGS_EXTARG) != 0) {
gargs = (struct geli_boot_args *)(kargs + 1);
- if (gargs != NULL && gargs->size >= offsetof(struct geli_boot_args, gelipw)) {
- if (gargs->keybuf_sentinel == KEYBUF_SENTINEL) {
- geli_import_key_buffer(gargs->keybuf);
- }
- if (gargs->gelipw[0] != '\0') {
- setenv("kern.geom.eli.passphrase", gargs->gelipw, 1);
- explicit_bzero(gargs->gelipw, sizeof(gargs->gelipw));
- }
+ if ((kargs->bootflags & KARGS_FLAGS_GELI) ||
+ gargs->size == LEGACY_GELI_ARGS_SIZE) {
+ gbdata = &gargs->gelidata;
}
}
+
+ if (gbdata != NULL)
+ import_geli_boot_data(gbdata);
#endif /* LOADER_GELI_SUPPORT */
-#endif /* LOADER_ZFS_SUPPORT */
/*
* March through the device switch probing for things.
@@ -251,14 +264,14 @@ extract_currdev(void)
int biosdev = -1;
/* Assume we are booting from a BIOS disk by default */
- new_currdev.dd.d_dev = &biosdisk;
+ new_currdev.dd.d_dev = &bioshd;
/* new-style boot loaders such as pxeldr and cdldr */
if (kargs->bootinfo == 0) {
if ((kargs->bootflags & KARGS_FLAGS_CD) != 0) {
/* we are booting from a CD with cdboot */
new_currdev.dd.d_dev = &bioscd;
- new_currdev.dd.d_unit = bc_bios2unit(initial_bootdev);
+ new_currdev.dd.d_unit = bd_bios2unit(initial_bootdev);
} else if ((kargs->bootflags & KARGS_FLAGS_PXE) != 0) {
/* we are booting from pxeldr */
new_currdev.dd.d_dev = &pxedisk;
@@ -271,11 +284,7 @@ extract_currdev(void)
}
#ifdef LOADER_ZFS_SUPPORT
} else if ((kargs->bootflags & KARGS_FLAGS_ZFS) != 0) {
- zargs = NULL;
- /* check for new style extended argument */
- if ((kargs->bootflags & KARGS_FLAGS_EXTARG) != 0)
- zargs = (struct zfs_boot_args *)(kargs + 1);
-
+ /* zargs was set in main() if we have new style extended argument */
if (zargs != NULL &&
zargs->size >= offsetof(struct zfs_boot_args, primary_pool)) {
/* sufficient data is provided */
@@ -318,7 +327,7 @@ extract_currdev(void)
* If we are booting off of a BIOS disk and we didn't succeed in determining
* which one we booted off of, just use disk0: as a reasonable default.
*/
- if ((new_currdev.dd.d_dev->dv_type == biosdisk.dv_type) &&
+ if ((new_currdev.dd.d_dev->dv_type == bioshd.dv_type) &&
((new_currdev.dd.d_unit = bd_bios2unit(biosdev)) == -1)) {
printf("Can't work out which disk we are booting from.\n"
"Guessed BIOS device 0x%x not found by probes, defaulting to disk0:\n", biosdev);
@@ -390,18 +399,16 @@ static void
i386_zfs_probe(void)
{
char devname[32];
- int unit;
+ struct i386_devdesc dev;
/*
* Open all the disks we can find and see if we can reconstruct
* ZFS pools from them.
*/
- for (unit = 0; unit < MAXBDDEV; unit++) {
- if (bd_unit2bios(unit) == -1)
- break;
- if (bd_unit2bios(unit) < 0x80)
- continue;
- sprintf(devname, "disk%d:", unit);
+ dev.dd.d_dev = &bioshd;
+ for (dev.dd.d_unit = 0; bd_unit2bios(&dev) >= 0; dev.dd.d_unit++) {
+ snprintf(devname, sizeof(devname), "%s%d:", bioshd.dv_name,
+ dev.dd.d_unit);
zfs_probe_dev(devname, NULL);
}
}
diff --git a/stand/i386/mbr/Makefile b/stand/i386/mbr/Makefile
index 26018ffb1378..dca202cb815b 100644
--- a/stand/i386/mbr/Makefile
+++ b/stand/i386/mbr/Makefile
@@ -3,14 +3,14 @@
PROG= mbr
STRIP=
BINMODE=${NOBINMODE}
-SRCS= ${PROG}.s
+SRCS= ${PROG}.S
# MBR flags: 0x80 -- try packet interface (also known as EDD or LBA)
BOOT_MBR_FLAGS?= 0x80
ORG= 0x600
-AFLAGS+=--defsym FLAGS=${BOOT_MBR_FLAGS}
+ACFLAGS+=-Wa,-defsym,FLAGS=${BOOT_MBR_FLAGS}
LDFLAGS+=${LDFLAGS_BIN}
.include <bsd.prog.mk>
diff --git a/stand/i386/mbr/mbr.s b/stand/i386/mbr/mbr.S
index 3cfc20dd58e1..3cfc20dd58e1 100644
--- a/stand/i386/mbr/mbr.s
+++ b/stand/i386/mbr/mbr.S
diff --git a/stand/i386/pmbr/Makefile b/stand/i386/pmbr/Makefile
index bfd6209f0406..e09bb610fc18 100644
--- a/stand/i386/pmbr/Makefile
+++ b/stand/i386/pmbr/Makefile
@@ -3,11 +3,13 @@
PROG= pmbr
STRIP=
BINMODE=${NOBINMODE}
-SRCS= ${PROG}.s
+SRCS= ${PROG}.S
+
+BOOT_MBR_FLAGS?= 0
ORG= 0x600
-AFLAGS+=--defsym FLAGS=${BOOT_MBR_FLAGS}
+ACFLAGS+=-Wa,-defsym,FLAGS=${BOOT_MBR_FLAGS}
LDFLAGS+=${LDFLAGS_BIN}
.include <bsd.prog.mk>
diff --git a/stand/i386/pmbr/pmbr.s b/stand/i386/pmbr/pmbr.S
index 1a758812edd3..1a758812edd3 100644
--- a/stand/i386/pmbr/pmbr.s
+++ b/stand/i386/pmbr/pmbr.S
diff --git a/stand/i386/pxeldr/pxeboot.8 b/stand/i386/pxeldr/pxeboot.8
index 7d7d65ccaaad..c9fa434b3028 100644
--- a/stand/i386/pxeldr/pxeboot.8
+++ b/stand/i386/pxeldr/pxeboot.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 27, 2017
+.Dd November 25, 2018
.Dt PXEBOOT 8
.Os
.Sh NAME
diff --git a/stand/i386/zfsboot/zfsboot.c b/stand/i386/zfsboot/zfsboot.c
index e88527757158..28a9e9a39760 100644
--- a/stand/i386/zfsboot/zfsboot.c
+++ b/stand/i386/zfsboot/zfsboot.c
@@ -129,7 +129,6 @@ int main(void);
#ifdef LOADER_GELI_SUPPORT
#include "geliboot.h"
static char gelipw[GELI_PW_MAXLEN];
-static struct keybuf *gelibuf;
#endif
struct zfsdsk {
@@ -993,18 +992,17 @@ load(void)
zfsargs.primary_pool = primary_spa->spa_guid;
#ifdef LOADER_GELI_SUPPORT
explicit_bzero(gelipw, sizeof(gelipw));
- gelibuf = malloc(sizeof(struct keybuf) + (GELI_MAX_KEYS * sizeof(struct keybuf_ent)));
- geli_export_key_buffer(gelibuf);
- zfsargs.notapw = '\0';
- zfsargs.keybuf_sentinel = KEYBUF_SENTINEL;
- zfsargs.keybuf = gelibuf;
-#else
- zfsargs.gelipw[0] = '\0';
+ export_geli_boot_data(&zfsargs.gelidata);
#endif
if (primary_vdev != NULL)
zfsargs.primary_vdev = primary_vdev->v_guid;
else
printf("failed to detect primary vdev\n");
+ /*
+ * Note that the zfsargs struct is passed by value, not by pointer. Code in
+ * btxldr.S copies the values from the entry stack to a fixed location
+ * within loader(8) at startup due to the presence of KARGS_FLAGS_EXTARG.
+ */
__exec((caddr_t)addr, RB_BOOTINFO | (opts & RBX_MASK),
bootdev,
KARGS_FLAGS_ZFS | KARGS_FLAGS_EXTARG,
diff --git a/stand/libsa/arp.c b/stand/libsa/arp.c
index 3d298fff2058..7d49559b4e04 100644
--- a/stand/libsa/arp.c
+++ b/stand/libsa/arp.c
@@ -120,7 +120,7 @@ arpwhohas(struct iodesc *d, struct in_addr addr)
arpsend, &wbuf.data, sizeof(wbuf.data),
arprecv, &pkt, (void **)&ah, NULL);
if (i == -1) {
- panic("arp: no response for %s\n",
+ panic("arp: no response for %s",
inet_ntoa(addr));
}
diff --git a/stand/libsa/assert.c b/stand/libsa/assert.c
index 8eec63a4729a..74b9fb4bacbf 100644
--- a/stand/libsa/assert.c
+++ b/stand/libsa/assert.c
@@ -35,10 +35,10 @@ void
__assert(const char *func, const char *file, int line, const char *expression)
{
if (func == NULL)
- panic("Assertion failed: (%s), file %s, line %d.\n",
+ panic("Assertion failed: (%s), file %s, line %d.",
expression, file, line);
else
panic(
- "Assertion failed: (%s), function %s, file %s, line %d.\n",
+ "Assertion failed: (%s), function %s, file %s, line %d.",
expression, func, file, line);
}
diff --git a/stand/libsa/bzipfs.c b/stand/libsa/bzipfs.c
index ff1514efeed3..47380ae72e5e 100644
--- a/stand/libsa/bzipfs.c
+++ b/stand/libsa/bzipfs.c
@@ -360,7 +360,7 @@ bzf_stat(struct open_file *f, struct stat *sb)
void
bz_internal_error(int errorcode)
{
- panic("bzipfs: critical error %d in bzip2 library occured\n", errorcode);
+ panic("bzipfs: critical error %d in bzip2 library occured", errorcode);
}
#ifdef REGRESSION
diff --git a/stand/libsa/netif.c b/stand/libsa/netif.c
index 105f9a31ab5d..d255cc663d5a 100644
--- a/stand/libsa/netif.c
+++ b/stand/libsa/netif.c
@@ -182,7 +182,7 @@ netif_attach(struct netif *nif, struct iodesc *desc, void *machdep_hint)
desc->io_netif = nif;
#ifdef PARANOID
if (drv->netif_init == NULL)
- panic("%s%d: no netif_init support\n", drv->netif_bname,
+ panic("%s%d: no netif_init support", drv->netif_bname,
nif->nif_unit);
#endif
drv->netif_init(desc, machdep_hint);
@@ -201,7 +201,7 @@ netif_detach(struct netif *nif)
#endif
#ifdef PARANOID
if (drv->netif_end == NULL)
- panic("%s%d: no netif_end support\n", drv->netif_bname,
+ panic("%s%d: no netif_end support", drv->netif_bname,
nif->nif_unit);
#endif
drv->netif_end(nif);
@@ -222,7 +222,7 @@ netif_get(struct iodesc *desc, void **pkt, time_t timo)
#endif
#ifdef PARANOID
if (drv->netif_get == NULL)
- panic("%s%d: no netif_get support\n", drv->netif_bname,
+ panic("%s%d: no netif_get support", drv->netif_bname,
nif->nif_unit);
#endif
rv = drv->netif_get(desc, pkt, timo);
@@ -249,7 +249,7 @@ netif_put(struct iodesc *desc, void *pkt, size_t len)
#endif
#ifdef PARANOID
if (drv->netif_put == NULL)
- panic("%s%d: no netif_put support\n", drv->netif_bname,
+ panic("%s%d: no netif_put support", drv->netif_bname,
nif->nif_unit);
#endif
rv = drv->netif_put(desc, pkt, len);
diff --git a/stand/libsa/sbrk.c b/stand/libsa/sbrk.c
index 00787fc54945..2f169ea60f66 100644
--- a/stand/libsa/sbrk.c
+++ b/stand/libsa/sbrk.c
@@ -53,7 +53,7 @@ sbrk(int incr)
char *ret;
if (heapbase == 0)
- panic("No heap setup\n");
+ panic("No heap setup");
if ((heapsize + incr) <= maxheap) {
ret = (char *)heapbase + heapsize;
diff --git a/stand/libsa/ufs.c b/stand/libsa/ufs.c
index 204bc969f968..317d6e9fdb1c 100644
--- a/stand/libsa/ufs.c
+++ b/stand/libsa/ufs.c
@@ -140,6 +140,11 @@ static int ufs_use_sa_read(void *, off_t, void **, int);
/* from ffs_subr.c */
int ffs_sbget(void *, struct fs **, off_t, char *,
int (*)(void *, off_t, void **, int));
+/*
+ * Request standard superblock location in ffs_sbget
+ */
+#define STDSB -1 /* Fail if check-hash is bad */
+#define STDSB_NOHASHFAIL -2 /* Ignore check-hash failure */
/*
* Read a new inode into a file structure.
@@ -519,7 +524,8 @@ ufs_open(upath, f)
/* read super block */
twiddle(1);
- if ((rc = ffs_sbget(f, &fs, -1, "stand", ufs_use_sa_read)) != 0)
+ if ((rc = ffs_sbget(f, &fs, STDSB_NOHASHFAIL, "stand",
+ ufs_use_sa_read)) != 0)
goto out;
fp->f_fs = fs;
/*
diff --git a/stand/libsa/zfs/libzfs.h b/stand/libsa/zfs/libzfs.h
index dcbab89fa441..fef59e1bb13a 100644
--- a/stand/libsa/zfs/libzfs.h
+++ b/stand/libsa/zfs/libzfs.h
@@ -44,31 +44,6 @@ struct zfs_devdesc {
#include <crypto/intake.h>
#endif
-struct zfs_boot_args
-{
- uint32_t size;
- uint32_t reserved;
- uint64_t pool;
- uint64_t root;
- uint64_t primary_pool;
- uint64_t primary_vdev;
- union {
- char gelipw[256];
- struct {
- char notapw; /*
- * single null byte to stop keybuf
- * being interpreted as a password
- */
- uint32_t keybuf_sentinel;
-#ifdef LOADER_GELI_SUPPORT
- struct keybuf *keybuf;
-#else
- void *keybuf;
-#endif
- };
- };
-};
-
int zfs_parsedev(struct zfs_devdesc *dev, const char *devspec,
const char **path);
char *zfs_fmtdev(void *vdev);
diff --git a/stand/uboot/common/main.c b/stand/uboot/common/main.c
index c7ca501c7a45..50a12cd425fb 100644
--- a/stand/uboot/common/main.c
+++ b/stand/uboot/common/main.c
@@ -497,6 +497,9 @@ main(int argc, char **argv)
do_interact:
setenv("LINES", "24", 1); /* optional */
setenv("prompt", "loader>", 1);
+#ifdef __powerpc__
+ setenv("usefdt", "1", 1);
+#endif
archsw.arch_loadaddr = uboot_loadaddr;
archsw.arch_getdev = uboot_getdev;
diff --git a/stand/uboot/lib/copy.c b/stand/uboot/lib/copy.c
index 131b88d85861..7fd5fd671c02 100644
--- a/stand/uboot/lib/copy.c
+++ b/stand/uboot/lib/copy.c
@@ -133,7 +133,7 @@ uboot_loadaddr(u_int type, void *data, uint64_t addr)
}
}
if (biggest_size == 0)
- panic("Not enough DRAM to load kernel\n");
+ panic("Not enough DRAM to load kernel");
#if 0
printf("Loading kernel into region 0x%08jx-0x%08jx (%ju MiB)\n",
(uintmax_t)biggest_block,
diff --git a/stand/uboot/lib/net.c b/stand/uboot/lib/net.c
index a0d1cb4f4583..2e1b9ab4caa4 100644
--- a/stand/uboot/lib/net.c
+++ b/stand/uboot/lib/net.c
@@ -324,7 +324,7 @@ net_init(struct iodesc *desc, void *machdep_hint)
sc = nif->nif_devdata = &uboot_softc;
if ((err = ub_dev_open(sc->sc_handle)) != 0)
- panic("%s%d: initialisation failed with error %d\n",
+ panic("%s%d: initialisation failed with error %d",
nif->nif_driver->netif_bname, nif->nif_unit, err);
/* Get MAC address */
@@ -359,6 +359,6 @@ net_end(struct netif *nif)
int err;
if ((err = ub_dev_close(sc->sc_handle)) != 0)
- panic("%s%d: net_end failed with error %d\n",
+ panic("%s%d: net_end failed with error %d",
nif->nif_driver->netif_bname, nif->nif_unit, err);
}