14a5d661aSToomas Soome /*-
24a5d661aSToomas Soome * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
34a5d661aSToomas Soome * All rights reserved.
44a5d661aSToomas Soome *
54a5d661aSToomas Soome * Redistribution and use in source and binary forms, with or without
64a5d661aSToomas Soome * modification, are permitted provided that the following conditions
74a5d661aSToomas Soome * are met:
84a5d661aSToomas Soome * 1. Redistributions of source code must retain the above copyright
94a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer.
104a5d661aSToomas Soome * 2. Redistributions in binary form must reproduce the above copyright
114a5d661aSToomas Soome * notice, this list of conditions and the following disclaimer in the
124a5d661aSToomas Soome * documentation and/or other materials provided with the distribution.
134a5d661aSToomas Soome *
144a5d661aSToomas Soome * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
154a5d661aSToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
164a5d661aSToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
174a5d661aSToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
184a5d661aSToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
194a5d661aSToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
204a5d661aSToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
214a5d661aSToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
224a5d661aSToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
234a5d661aSToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
244a5d661aSToomas Soome * SUCH DAMAGE.
254a5d661aSToomas Soome */
264a5d661aSToomas Soome
274a5d661aSToomas Soome #include <sys/cdefs.h>
284a5d661aSToomas Soome
294a5d661aSToomas Soome /*
304a5d661aSToomas Soome * MD bootstrap main() and assorted miscellaneous
314a5d661aSToomas Soome * commands.
324a5d661aSToomas Soome */
334a5d661aSToomas Soome
344a5d661aSToomas Soome #include <stand.h>
354a5d661aSToomas Soome #include <stddef.h>
364a5d661aSToomas Soome #include <string.h>
374a5d661aSToomas Soome #include <machine/bootinfo.h>
384a5d661aSToomas Soome #include <machine/cpufunc.h>
394a5d661aSToomas Soome #include <machine/psl.h>
409ab3b382SToomas Soome #include <sys/disk.h>
41*6feb9af9SToomas Soome #include <sys/param.h>
424a5d661aSToomas Soome #include <sys/reboot.h>
434a5d661aSToomas Soome
444a5d661aSToomas Soome #include "bootstrap.h"
454a5d661aSToomas Soome #include "common/bootargs.h"
464a5d661aSToomas Soome #include "libi386/libi386.h"
474a5d661aSToomas Soome #include "libi386/smbios.h"
484a5d661aSToomas Soome #include "btxv86.h"
494a5d661aSToomas Soome
504a5d661aSToomas Soome #ifdef LOADER_ZFS_SUPPORT
514a5d661aSToomas Soome #include "../zfs/libzfs.h"
524a5d661aSToomas Soome #endif
534a5d661aSToomas Soome
544a5d661aSToomas Soome CTASSERT(sizeof(struct bootargs) == BOOTARGS_SIZE);
554a5d661aSToomas Soome CTASSERT(offsetof(struct bootargs, bootinfo) == BA_BOOTINFO);
564a5d661aSToomas Soome CTASSERT(offsetof(struct bootargs, bootflags) == BA_BOOTFLAGS);
574a5d661aSToomas Soome CTASSERT(offsetof(struct bootinfo, bi_size) == BI_SIZE);
584a5d661aSToomas Soome
594a5d661aSToomas Soome /* Arguments passed in from the boot1/boot2 loader */
604a5d661aSToomas Soome static struct bootargs *kargs;
614a5d661aSToomas Soome
624a5d661aSToomas Soome static u_int32_t initial_howto;
634a5d661aSToomas Soome static u_int32_t initial_bootdev;
644a5d661aSToomas Soome static struct bootinfo *initial_bootinfo;
654a5d661aSToomas Soome
664a5d661aSToomas Soome struct arch_switch archsw; /* MI/MD interface boundary */
674a5d661aSToomas Soome
684a5d661aSToomas Soome static void extract_currdev(void);
694a5d661aSToomas Soome static int isa_inb(int port);
704a5d661aSToomas Soome static void isa_outb(int port, int value);
714a5d661aSToomas Soome void exit(int code);
724a5d661aSToomas Soome #ifdef LOADER_ZFS_SUPPORT
734a5d661aSToomas Soome static void i386_zfs_probe(void);
744a5d661aSToomas Soome #endif
754a5d661aSToomas Soome
764a5d661aSToomas Soome /* from vers.c */
77c8951589SToomas Soome extern char bootprog_info[];
784a5d661aSToomas Soome
794a5d661aSToomas Soome /* XXX debugging */
804a5d661aSToomas Soome extern char end[];
814a5d661aSToomas Soome
824a5d661aSToomas Soome static void *heap_top;
834a5d661aSToomas Soome static void *heap_bottom;
844a5d661aSToomas Soome
854a5d661aSToomas Soome int
main(void)864a5d661aSToomas Soome main(void)
874a5d661aSToomas Soome {
884a5d661aSToomas Soome int i;
894a5d661aSToomas Soome
904a5d661aSToomas Soome /* Pick up arguments */
914a5d661aSToomas Soome kargs = (void *)__args;
924a5d661aSToomas Soome initial_howto = kargs->howto;
934a5d661aSToomas Soome initial_bootdev = kargs->bootdev;
944a5d661aSToomas Soome initial_bootinfo = kargs->bootinfo ? (struct bootinfo *)PTOV(kargs->bootinfo) : NULL;
954a5d661aSToomas Soome
964a5d661aSToomas Soome /* Initialize the v86 register set to a known-good state. */
974a5d661aSToomas Soome bzero(&v86, sizeof(v86));
984a5d661aSToomas Soome v86.efl = PSL_RESERVED_DEFAULT | PSL_I;
994a5d661aSToomas Soome
1004a5d661aSToomas Soome /*
1014a5d661aSToomas Soome * Initialise the heap as early as possible. Once this is done, malloc() is usable.
1024a5d661aSToomas Soome */
1034a5d661aSToomas Soome bios_getmem();
1044a5d661aSToomas Soome
1054a5d661aSToomas Soome #if defined(LOADER_BZIP2_SUPPORT) || defined(LOADER_FIREWIRE_SUPPORT) || \
1064a5d661aSToomas Soome defined(LOADER_GPT_SUPPORT) || defined(LOADER_ZFS_SUPPORT)
1074a5d661aSToomas Soome if (high_heap_size > 0) {
1084a5d661aSToomas Soome heap_top = PTOV(high_heap_base + high_heap_size);
1094a5d661aSToomas Soome heap_bottom = PTOV(high_heap_base);
1104a5d661aSToomas Soome if (high_heap_base < memtop_copyin)
1114a5d661aSToomas Soome memtop_copyin = high_heap_base;
1124a5d661aSToomas Soome } else
1134a5d661aSToomas Soome #endif
1144a5d661aSToomas Soome {
1154a5d661aSToomas Soome heap_top = (void *)PTOV(bios_basemem);
1164a5d661aSToomas Soome heap_bottom = (void *)end;
1174a5d661aSToomas Soome }
1184a5d661aSToomas Soome setheap(heap_bottom, heap_top);
1194a5d661aSToomas Soome
1204a5d661aSToomas Soome /*
1214a5d661aSToomas Soome * XXX Chicken-and-egg problem; we want to have console output early, but some
1224a5d661aSToomas Soome * console attributes may depend on reading from eg. the boot device, which we
1234a5d661aSToomas Soome * can't do yet.
1244a5d661aSToomas Soome *
1254a5d661aSToomas Soome * We can use printf() etc. once this is done.
1264a5d661aSToomas Soome * If the previous boot stage has requested a serial console, prefer that.
1274a5d661aSToomas Soome */
1284a5d661aSToomas Soome bi_setboothowto(initial_howto);
1294a5d661aSToomas Soome if (initial_howto & RB_MULTIPLE) {
1304a5d661aSToomas Soome if (initial_howto & RB_SERIAL)
1314a5d661aSToomas Soome setenv("console", "ttya text", 1);
1324a5d661aSToomas Soome else
1334a5d661aSToomas Soome setenv("console", "text ttya", 1);
1344a5d661aSToomas Soome } else if (initial_howto & RB_SERIAL)
1354a5d661aSToomas Soome setenv("console", "ttya", 1);
1364a5d661aSToomas Soome else if (initial_howto & RB_MUTE)
1374a5d661aSToomas Soome setenv("console", "null", 1);
1384a5d661aSToomas Soome cons_probe();
1394a5d661aSToomas Soome
1404a5d661aSToomas Soome /*
1414a5d661aSToomas Soome * Initialise the block cache. Set the upper limit.
1424a5d661aSToomas Soome */
1434a5d661aSToomas Soome bcache_init(32768, 512);
1444a5d661aSToomas Soome
1454a5d661aSToomas Soome /*
1464a5d661aSToomas Soome * Special handling for PXE and CD booting.
1474a5d661aSToomas Soome */
1484a5d661aSToomas Soome if (kargs->bootinfo == 0) {
1494a5d661aSToomas Soome /*
1504a5d661aSToomas Soome * We only want the PXE disk to try to init itself in the below
1514a5d661aSToomas Soome * walk through devsw if we actually booted off of PXE.
1524a5d661aSToomas Soome */
1534a5d661aSToomas Soome if (kargs->bootflags & KARGS_FLAGS_PXE)
1544a5d661aSToomas Soome pxe_enable(kargs->pxeinfo ? PTOV(kargs->pxeinfo) : NULL);
1554a5d661aSToomas Soome else if (kargs->bootflags & KARGS_FLAGS_CD)
1564a5d661aSToomas Soome bc_add(initial_bootdev);
1574a5d661aSToomas Soome }
1584a5d661aSToomas Soome
1594a5d661aSToomas Soome archsw.arch_autoload = i386_autoload;
1604a5d661aSToomas Soome archsw.arch_getdev = i386_getdev;
1614a5d661aSToomas Soome archsw.arch_copyin = i386_copyin;
1624a5d661aSToomas Soome archsw.arch_copyout = i386_copyout;
1634a5d661aSToomas Soome archsw.arch_readin = i386_readin;
1644a5d661aSToomas Soome archsw.arch_isainb = isa_inb;
1654a5d661aSToomas Soome archsw.arch_isaoutb = isa_outb;
166*6feb9af9SToomas Soome archsw.arch_loadaddr = i386_loadaddr;
1674a5d661aSToomas Soome #ifdef LOADER_ZFS_SUPPORT
1684a5d661aSToomas Soome archsw.arch_zfs_probe = i386_zfs_probe;
1694a5d661aSToomas Soome #endif
1704a5d661aSToomas Soome
1714a5d661aSToomas Soome /*
1724a5d661aSToomas Soome * March through the device switch probing for things.
1734a5d661aSToomas Soome */
1744a5d661aSToomas Soome for (i = 0; devsw[i] != NULL; i++)
1754a5d661aSToomas Soome if (devsw[i]->dv_init != NULL)
1764a5d661aSToomas Soome (devsw[i]->dv_init)();
1774a5d661aSToomas Soome printf("BIOS %dkB/%dkB available memory\n", bios_basemem / 1024, bios_extmem / 1024);
1784a5d661aSToomas Soome if (initial_bootinfo != NULL) {
1794a5d661aSToomas Soome initial_bootinfo->bi_basemem = bios_basemem / 1024;
1804a5d661aSToomas Soome initial_bootinfo->bi_extmem = bios_extmem / 1024;
1814a5d661aSToomas Soome }
1824a5d661aSToomas Soome
1834a5d661aSToomas Soome /* detect ACPI for future reference */
1844a5d661aSToomas Soome biosacpi_detect();
1854a5d661aSToomas Soome
1864a5d661aSToomas Soome /* detect SMBIOS for future reference */
1874a5d661aSToomas Soome smbios_detect(NULL);
1884a5d661aSToomas Soome
1894a5d661aSToomas Soome /* detect PCI BIOS for future reference */
1904a5d661aSToomas Soome biospci_detect();
1914a5d661aSToomas Soome
192c8951589SToomas Soome printf("\n%s", bootprog_info);
1934a5d661aSToomas Soome
1944a5d661aSToomas Soome extract_currdev(); /* set $currdev and $loaddev */
1954a5d661aSToomas Soome setenv("LINES", "24", 1); /* optional */
1964a5d661aSToomas Soome setenv("COLUMNS", "80", 1); /* optional */
1974a5d661aSToomas Soome
1984a5d661aSToomas Soome if (bi_checkcpu())
1994a5d661aSToomas Soome setenv("ISADIR", "amd64", 1);
2004a5d661aSToomas Soome else
2014a5d661aSToomas Soome setenv("ISADIR", "", 1);
2024a5d661aSToomas Soome
2034a5d661aSToomas Soome bios_getsmap();
2044a5d661aSToomas Soome
2054a5d661aSToomas Soome interact(NULL);
2064a5d661aSToomas Soome
2074a5d661aSToomas Soome /* if we ever get here, it is an error */
2084a5d661aSToomas Soome return (1);
2094a5d661aSToomas Soome }
2104a5d661aSToomas Soome
2114a5d661aSToomas Soome /*
2124a5d661aSToomas Soome * Set the 'current device' by (if possible) recovering the boot device as
2134a5d661aSToomas Soome * supplied by the initial bootstrap.
2144a5d661aSToomas Soome *
2154a5d661aSToomas Soome * XXX should be extended for netbooting.
2164a5d661aSToomas Soome */
2174a5d661aSToomas Soome static void
extract_currdev(void)2184a5d661aSToomas Soome extract_currdev(void)
2194a5d661aSToomas Soome {
2204a5d661aSToomas Soome struct i386_devdesc new_currdev;
2214a5d661aSToomas Soome #ifdef LOADER_ZFS_SUPPORT
2224a5d661aSToomas Soome char buf[20];
2234a5d661aSToomas Soome struct zfs_boot_args *zargs;
2244a5d661aSToomas Soome #endif
2254a5d661aSToomas Soome int biosdev = -1;
2264a5d661aSToomas Soome
2274a5d661aSToomas Soome /* Assume we are booting from a BIOS disk by default */
2284a5d661aSToomas Soome new_currdev.d_dev = &biosdisk;
2294a5d661aSToomas Soome
2304a5d661aSToomas Soome /* new-style boot loaders such as pxeldr and cdldr */
2314a5d661aSToomas Soome if (kargs->bootinfo == 0) {
2324a5d661aSToomas Soome if ((kargs->bootflags & KARGS_FLAGS_CD) != 0) {
2334a5d661aSToomas Soome /* we are booting from a CD with cdboot */
2344a5d661aSToomas Soome new_currdev.d_dev = &bioscd;
2354a5d661aSToomas Soome new_currdev.d_unit = bc_bios2unit(initial_bootdev);
2364a5d661aSToomas Soome } else if ((kargs->bootflags & KARGS_FLAGS_PXE) != 0) {
2374a5d661aSToomas Soome /* we are booting from pxeldr */
2384a5d661aSToomas Soome new_currdev.d_dev = &pxedisk;
2394a5d661aSToomas Soome new_currdev.d_unit = 0;
2404a5d661aSToomas Soome } else {
2414a5d661aSToomas Soome /* we don't know what our boot device is */
2424a5d661aSToomas Soome new_currdev.d_kind.biosdisk.slice = -1;
2434a5d661aSToomas Soome new_currdev.d_kind.biosdisk.partition = 0;
2444a5d661aSToomas Soome biosdev = -1;
2454a5d661aSToomas Soome }
2464a5d661aSToomas Soome #ifdef LOADER_ZFS_SUPPORT
2474a5d661aSToomas Soome } else if ((kargs->bootflags & KARGS_FLAGS_ZFS) != 0) {
2484a5d661aSToomas Soome zargs = NULL;
2494a5d661aSToomas Soome /* check for new style extended argument */
2504a5d661aSToomas Soome if ((kargs->bootflags & KARGS_FLAGS_EXTARG) != 0)
2514a5d661aSToomas Soome zargs = (struct zfs_boot_args *)(kargs + 1);
2524a5d661aSToomas Soome
2534a5d661aSToomas Soome if (zargs != NULL &&
2544a5d661aSToomas Soome zargs->size >= offsetof(struct zfs_boot_args, primary_pool)) {
2554a5d661aSToomas Soome /* sufficient data is provided */
2564a5d661aSToomas Soome new_currdev.d_kind.zfs.pool_guid = zargs->pool;
2574a5d661aSToomas Soome new_currdev.d_kind.zfs.root_guid = zargs->root;
2584a5d661aSToomas Soome if (zargs->size >= sizeof(*zargs) && zargs->primary_vdev != 0) {
2594a5d661aSToomas Soome sprintf(buf, "%llu", zargs->primary_pool);
2604a5d661aSToomas Soome setenv("vfs.zfs.boot.primary_pool", buf, 1);
2614a5d661aSToomas Soome sprintf(buf, "%llu", zargs->primary_vdev);
2624a5d661aSToomas Soome setenv("vfs.zfs.boot.primary_vdev", buf, 1);
2634a5d661aSToomas Soome }
2644a5d661aSToomas Soome } else {
2654a5d661aSToomas Soome /* old style zfsboot block */
2664a5d661aSToomas Soome new_currdev.d_kind.zfs.pool_guid = kargs->zfspool;
2674a5d661aSToomas Soome new_currdev.d_kind.zfs.root_guid = 0;
2684a5d661aSToomas Soome }
2694a5d661aSToomas Soome new_currdev.d_dev = &zfs_dev;
2704a5d661aSToomas Soome #endif
2714a5d661aSToomas Soome } else if ((initial_bootdev & B_MAGICMASK) != B_DEVMAGIC) {
2724a5d661aSToomas Soome /* The passed-in boot device is bad */
2734a5d661aSToomas Soome new_currdev.d_kind.biosdisk.slice = -1;
2744a5d661aSToomas Soome new_currdev.d_kind.biosdisk.partition = 0;
2754a5d661aSToomas Soome biosdev = -1;
2764a5d661aSToomas Soome } else {
2774a5d661aSToomas Soome new_currdev.d_kind.biosdisk.slice = B_SLICE(initial_bootdev) - 1;
2784a5d661aSToomas Soome new_currdev.d_kind.biosdisk.partition = B_PARTITION(initial_bootdev);
2794a5d661aSToomas Soome biosdev = initial_bootinfo->bi_bios_dev;
2804a5d661aSToomas Soome
2814a5d661aSToomas Soome /*
2824a5d661aSToomas Soome * If we are booted by an old bootstrap, we have to guess at the BIOS
2834a5d661aSToomas Soome * unit number. We will lose if there is more than one disk type
2844a5d661aSToomas Soome * and we are not booting from the lowest-numbered disk type
2854a5d661aSToomas Soome * (ie. SCSI when IDE also exists).
2864a5d661aSToomas Soome */
2874a5d661aSToomas Soome if ((biosdev == 0) && (B_TYPE(initial_bootdev) != 2)) /* biosdev doesn't match major */
2884a5d661aSToomas Soome biosdev = 0x80 + B_UNIT(initial_bootdev); /* assume harddisk */
2894a5d661aSToomas Soome }
2904a5d661aSToomas Soome new_currdev.d_type = new_currdev.d_dev->dv_type;
2914a5d661aSToomas Soome
2924a5d661aSToomas Soome /*
2934a5d661aSToomas Soome * If we are booting off of a BIOS disk and we didn't succeed in determining
2944a5d661aSToomas Soome * which one we booted off of, just use disk0: as a reasonable default.
2954a5d661aSToomas Soome */
2964a5d661aSToomas Soome if ((new_currdev.d_type == biosdisk.dv_type) &&
2974a5d661aSToomas Soome ((new_currdev.d_unit = bd_bios2unit(biosdev)) == -1)) {
2984a5d661aSToomas Soome printf("Can't work out which disk we are booting from.\n"
2994a5d661aSToomas Soome "Guessed BIOS device 0x%x not found by probes, defaulting to disk0:\n", biosdev);
3004a5d661aSToomas Soome new_currdev.d_unit = 0;
3014a5d661aSToomas Soome }
3024a5d661aSToomas Soome
3034a5d661aSToomas Soome #ifdef LOADER_ZFS_SUPPORT
3044a5d661aSToomas Soome #ifdef __FreeBSD__
3054a5d661aSToomas Soome if (new_currdev.d_type == DEVT_ZFS)
3064a5d661aSToomas Soome init_zfs_bootenv(zfs_fmtdev(&new_currdev));
3074a5d661aSToomas Soome #endif
3084a5d661aSToomas Soome #endif
3094a5d661aSToomas Soome
3104a5d661aSToomas Soome env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&new_currdev),
3114a5d661aSToomas Soome i386_setcurrdev, env_nounset);
3124a5d661aSToomas Soome env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&new_currdev), env_noset,
3134a5d661aSToomas Soome env_nounset);
3144a5d661aSToomas Soome }
3154a5d661aSToomas Soome
3164a5d661aSToomas Soome COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
3174a5d661aSToomas Soome
3184a5d661aSToomas Soome static int
command_reboot(int argc,char * argv[])3194a5d661aSToomas Soome command_reboot(int argc, char *argv[])
3204a5d661aSToomas Soome {
3214a5d661aSToomas Soome int i;
3224a5d661aSToomas Soome
3234a5d661aSToomas Soome for (i = 0; devsw[i] != NULL; ++i)
3244a5d661aSToomas Soome if (devsw[i]->dv_cleanup != NULL)
3254a5d661aSToomas Soome (devsw[i]->dv_cleanup)();
3264a5d661aSToomas Soome
3274a5d661aSToomas Soome printf("Rebooting...\n");
3284a5d661aSToomas Soome delay(1000000);
3294a5d661aSToomas Soome __exit(0);
3304a5d661aSToomas Soome }
3314a5d661aSToomas Soome
3324a5d661aSToomas Soome /* provide this for panic, as it's not in the startup code */
3334a5d661aSToomas Soome void
exit(int code)3344a5d661aSToomas Soome exit(int code)
3354a5d661aSToomas Soome {
3364a5d661aSToomas Soome __exit(code);
3374a5d661aSToomas Soome }
3384a5d661aSToomas Soome
3394a5d661aSToomas Soome COMMAND_SET(heap, "heap", "show heap usage", command_heap);
3404a5d661aSToomas Soome
3414a5d661aSToomas Soome static int
command_heap(int argc,char * argv[])3424a5d661aSToomas Soome command_heap(int argc, char *argv[])
3434a5d661aSToomas Soome {
3444a5d661aSToomas Soome mallocstats();
3454a5d661aSToomas Soome printf("heap base at %p, top at %p, upper limit at %p\n", heap_bottom,
3464a5d661aSToomas Soome sbrk(0), heap_top);
3474a5d661aSToomas Soome return(CMD_OK);
3484a5d661aSToomas Soome }
3494a5d661aSToomas Soome
3504a5d661aSToomas Soome #ifdef LOADER_ZFS_SUPPORT
3514a5d661aSToomas Soome COMMAND_SET(lszfs, "lszfs", "list child datasets of a zfs dataset",
3524a5d661aSToomas Soome command_lszfs);
3534a5d661aSToomas Soome
3544a5d661aSToomas Soome static int
command_lszfs(int argc,char * argv[])3554a5d661aSToomas Soome command_lszfs(int argc, char *argv[])
3564a5d661aSToomas Soome {
3574a5d661aSToomas Soome int err;
3584a5d661aSToomas Soome
3594a5d661aSToomas Soome if (argc != 2) {
3604a5d661aSToomas Soome command_errmsg = "wrong number of arguments";
3614a5d661aSToomas Soome return (CMD_ERROR);
3624a5d661aSToomas Soome }
3634a5d661aSToomas Soome
3644a5d661aSToomas Soome err = zfs_list(argv[1]);
3654a5d661aSToomas Soome if (err != 0) {
3664a5d661aSToomas Soome command_errmsg = strerror(err);
3674a5d661aSToomas Soome return (CMD_ERROR);
3684a5d661aSToomas Soome }
3694a5d661aSToomas Soome
3704a5d661aSToomas Soome return (CMD_OK);
3714a5d661aSToomas Soome }
3724a5d661aSToomas Soome
3734a5d661aSToomas Soome #ifdef __FreeBSD__
3744a5d661aSToomas Soome COMMAND_SET(reloadbe, "reloadbe", "refresh the list of ZFS Boot Environments",
3754a5d661aSToomas Soome command_reloadbe);
3764a5d661aSToomas Soome
3774a5d661aSToomas Soome static int
command_reloadbe(int argc,char * argv[])3784a5d661aSToomas Soome command_reloadbe(int argc, char *argv[])
3794a5d661aSToomas Soome {
3804a5d661aSToomas Soome int err;
3814a5d661aSToomas Soome char *root;
3824a5d661aSToomas Soome
3834a5d661aSToomas Soome if (argc > 2) {
3844a5d661aSToomas Soome command_errmsg = "wrong number of arguments";
3854a5d661aSToomas Soome return (CMD_ERROR);
3864a5d661aSToomas Soome }
3874a5d661aSToomas Soome
3884a5d661aSToomas Soome if (argc == 2) {
3894a5d661aSToomas Soome err = zfs_bootenv(argv[1]);
3904a5d661aSToomas Soome } else {
3914a5d661aSToomas Soome root = getenv("zfs_be_root");
3924a5d661aSToomas Soome if (root == NULL) {
3934a5d661aSToomas Soome /* There does not appear to be a ZFS pool here, exit without error */
3944a5d661aSToomas Soome return (CMD_OK);
3954a5d661aSToomas Soome }
3964a5d661aSToomas Soome err = zfs_bootenv(getenv("zfs_be_root"));
3974a5d661aSToomas Soome }
3984a5d661aSToomas Soome
3994a5d661aSToomas Soome if (err != 0) {
4004a5d661aSToomas Soome command_errmsg = strerror(err);
4014a5d661aSToomas Soome return (CMD_ERROR);
4024a5d661aSToomas Soome }
4034a5d661aSToomas Soome
4044a5d661aSToomas Soome return (CMD_OK);
4054a5d661aSToomas Soome }
4064a5d661aSToomas Soome #endif /* __FreeBSD__ */
4074a5d661aSToomas Soome #endif
4084a5d661aSToomas Soome
4094a5d661aSToomas Soome /* ISA bus access functions for PnP. */
4104a5d661aSToomas Soome static int
isa_inb(int port)4114a5d661aSToomas Soome isa_inb(int port)
4124a5d661aSToomas Soome {
4134a5d661aSToomas Soome
4144a5d661aSToomas Soome return (inb(port));
4154a5d661aSToomas Soome }
4164a5d661aSToomas Soome
4174a5d661aSToomas Soome static void
isa_outb(int port,int value)4184a5d661aSToomas Soome isa_outb(int port, int value)
4194a5d661aSToomas Soome {
4204a5d661aSToomas Soome
4214a5d661aSToomas Soome outb(port, value);
4224a5d661aSToomas Soome }
4234a5d661aSToomas Soome
4244a5d661aSToomas Soome #ifdef LOADER_ZFS_SUPPORT
4254a5d661aSToomas Soome static void
i386_zfs_probe(void)4264a5d661aSToomas Soome i386_zfs_probe(void)
4274a5d661aSToomas Soome {
4284a5d661aSToomas Soome char devname[32];
4294a5d661aSToomas Soome int unit;
4304a5d661aSToomas Soome
4314a5d661aSToomas Soome /*
4324a5d661aSToomas Soome * Open all the disks we can find and see if we can reconstruct
4334a5d661aSToomas Soome * ZFS pools from them.
4344a5d661aSToomas Soome */
4354a5d661aSToomas Soome for (unit = 0; unit < MAXBDDEV; unit++) {
4364a5d661aSToomas Soome if (bd_unit2bios(unit) == -1)
4374a5d661aSToomas Soome break;
4384a5d661aSToomas Soome sprintf(devname, "disk%d:", unit);
4394a5d661aSToomas Soome zfs_probe_dev(devname, NULL);
4404a5d661aSToomas Soome }
4414a5d661aSToomas Soome }
4429ab3b382SToomas Soome
4439ab3b382SToomas Soome uint64_t
ldi_get_size(void * priv)4449ab3b382SToomas Soome ldi_get_size(void *priv)
4459ab3b382SToomas Soome {
4469ab3b382SToomas Soome int fd = (uintptr_t) priv;
4479ab3b382SToomas Soome uint64_t size;
4489ab3b382SToomas Soome
4499ab3b382SToomas Soome ioctl(fd, DIOCGMEDIASIZE, &size);
4509ab3b382SToomas Soome return (size);
4519ab3b382SToomas Soome }
4524a5d661aSToomas Soome #endif
453