199767f8919635c4928607450d9e0abb932109ceToomas Soome/*-
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
199767f8919635c4928607450d9e0abb932109ceToomas Soome * All rights reserved.
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Redistribution and use in source and binary forms, with or without
199767f8919635c4928607450d9e0abb932109ceToomas Soome * modification, are permitted provided that the following conditions
199767f8919635c4928607450d9e0abb932109ceToomas Soome * are met:
199767f8919635c4928607450d9e0abb932109ceToomas Soome * 1. Redistributions of source code must retain the above copyright
199767f8919635c4928607450d9e0abb932109ceToomas Soome * notice, this list of conditions and the following disclaimer.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * 2. Redistributions in binary form must reproduce the above copyright
199767f8919635c4928607450d9e0abb932109ceToomas Soome * notice, this list of conditions and the following disclaimer in the
199767f8919635c4928607450d9e0abb932109ceToomas Soome * documentation and/or other materials provided with the distribution.
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
199767f8919635c4928607450d9e0abb932109ceToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
199767f8919635c4928607450d9e0abb932109ceToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
199767f8919635c4928607450d9e0abb932109ceToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
199767f8919635c4928607450d9e0abb932109ceToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
199767f8919635c4928607450d9e0abb932109ceToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
199767f8919635c4928607450d9e0abb932109ceToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
199767f8919635c4928607450d9e0abb932109ceToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
199767f8919635c4928607450d9e0abb932109ceToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
199767f8919635c4928607450d9e0abb932109ceToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
199767f8919635c4928607450d9e0abb932109ceToomas Soome * SUCH DAMAGE.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <sys/cdefs.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome__FBSDID("$FreeBSD$");
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * MD bootstrap main() and assorted miscellaneous
199767f8919635c4928607450d9e0abb932109ceToomas Soome * commands.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <stand.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <stddef.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <string.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <machine/bootinfo.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <machine/cpufunc.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <machine/psl.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include <sys/reboot.h>
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include "bootstrap.h"
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include "common/bootargs.h"
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include "libi386/libi386.h"
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include "libi386/smbios.h"
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include "btxv86.h"
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef LOADER_ZFS_SUPPORT
199767f8919635c4928607450d9e0abb932109ceToomas Soome#include "../zfs/libzfs.h"
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas SoomeCTASSERT(sizeof(struct bootargs) == BOOTARGS_SIZE);
199767f8919635c4928607450d9e0abb932109ceToomas SoomeCTASSERT(offsetof(struct bootargs, bootinfo) == BA_BOOTINFO);
199767f8919635c4928607450d9e0abb932109ceToomas SoomeCTASSERT(offsetof(struct bootargs, bootflags) == BA_BOOTFLAGS);
199767f8919635c4928607450d9e0abb932109ceToomas SoomeCTASSERT(offsetof(struct bootinfo, bi_size) == BI_SIZE);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* Arguments passed in from the boot1/boot2 loader */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic struct bootargs *kargs;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic u_int32_t initial_howto;
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic u_int32_t initial_bootdev;
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic struct bootinfo *initial_bootinfo;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestruct arch_switch archsw; /* MI/MD interface boundary */
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void extract_currdev(void);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int isa_inb(int port);
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void isa_outb(int port, int value);
199767f8919635c4928607450d9e0abb932109ceToomas Soomevoid exit(int code);
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef LOADER_ZFS_SUPPORT
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void i386_zfs_probe(void);
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* from vers.c */
199767f8919635c4928607450d9e0abb932109ceToomas Soomeextern char bootprog_name[], bootprog_rev[], bootprog_date[], bootprog_maker[];
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* XXX debugging */
199767f8919635c4928607450d9e0abb932109ceToomas Soomeextern char end[];
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void *heap_top;
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void *heap_bottom;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomeint
199767f8919635c4928607450d9e0abb932109ceToomas Soomemain(void)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int i;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Pick up arguments */
199767f8919635c4928607450d9e0abb932109ceToomas Soome kargs = (void *)__args;
199767f8919635c4928607450d9e0abb932109ceToomas Soome initial_howto = kargs->howto;
199767f8919635c4928607450d9e0abb932109ceToomas Soome initial_bootdev = kargs->bootdev;
199767f8919635c4928607450d9e0abb932109ceToomas Soome initial_bootinfo = kargs->bootinfo ? (struct bootinfo *)PTOV(kargs->bootinfo) : NULL;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Initialize the v86 register set to a known-good state. */
199767f8919635c4928607450d9e0abb932109ceToomas Soome bzero(&v86, sizeof(v86));
199767f8919635c4928607450d9e0abb932109ceToomas Soome v86.efl = PSL_RESERVED_DEFAULT | PSL_I;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Initialise the heap as early as possible. Once this is done, malloc() is usable.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome bios_getmem();
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#if defined(LOADER_BZIP2_SUPPORT) || defined(LOADER_FIREWIRE_SUPPORT) || \
199767f8919635c4928607450d9e0abb932109ceToomas Soome defined(LOADER_GPT_SUPPORT) || defined(LOADER_ZFS_SUPPORT)
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (high_heap_size > 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome heap_top = PTOV(high_heap_base + high_heap_size);
199767f8919635c4928607450d9e0abb932109ceToomas Soome heap_bottom = PTOV(high_heap_base);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (high_heap_base < memtop_copyin)
199767f8919635c4928607450d9e0abb932109ceToomas Soome memtop_copyin = high_heap_base;
199767f8919635c4928607450d9e0abb932109ceToomas Soome } else
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome {
199767f8919635c4928607450d9e0abb932109ceToomas Soome heap_top = (void *)PTOV(bios_basemem);
199767f8919635c4928607450d9e0abb932109ceToomas Soome heap_bottom = (void *)end;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome setheap(heap_bottom, heap_top);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * XXX Chicken-and-egg problem; we want to have console output early, but some
199767f8919635c4928607450d9e0abb932109ceToomas Soome * console attributes may depend on reading from eg. the boot device, which we
199767f8919635c4928607450d9e0abb932109ceToomas Soome * can't do yet.
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * We can use printf() etc. once this is done.
199767f8919635c4928607450d9e0abb932109ceToomas Soome * If the previous boot stage has requested a serial console, prefer that.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome bi_setboothowto(initial_howto);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (initial_howto & RB_MULTIPLE) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (initial_howto & RB_SERIAL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome setenv("console", "ttya text", 1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome else
199767f8919635c4928607450d9e0abb932109ceToomas Soome setenv("console", "text ttya", 1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome } else if (initial_howto & RB_SERIAL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome setenv("console", "ttya", 1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome else if (initial_howto & RB_MUTE)
199767f8919635c4928607450d9e0abb932109ceToomas Soome setenv("console", "null", 1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome cons_probe();
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Initialise the block cache. Set the upper limit.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome bcache_init(32768, 512);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Special handling for PXE and CD booting.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (kargs->bootinfo == 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * We only want the PXE disk to try to init itself in the below
199767f8919635c4928607450d9e0abb932109ceToomas Soome * walk through devsw if we actually booted off of PXE.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (kargs->bootflags & KARGS_FLAGS_PXE)
199767f8919635c4928607450d9e0abb932109ceToomas Soome pxe_enable(kargs->pxeinfo ? PTOV(kargs->pxeinfo) : NULL);
199767f8919635c4928607450d9e0abb932109ceToomas Soome else if (kargs->bootflags & KARGS_FLAGS_CD)
199767f8919635c4928607450d9e0abb932109ceToomas Soome bc_add(initial_bootdev);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome archsw.arch_autoload = i386_autoload;
199767f8919635c4928607450d9e0abb932109ceToomas Soome archsw.arch_getdev = i386_getdev;
199767f8919635c4928607450d9e0abb932109ceToomas Soome archsw.arch_copyin = i386_copyin;
199767f8919635c4928607450d9e0abb932109ceToomas Soome archsw.arch_copyout = i386_copyout;
199767f8919635c4928607450d9e0abb932109ceToomas Soome archsw.arch_readin = i386_readin;
199767f8919635c4928607450d9e0abb932109ceToomas Soome archsw.arch_isainb = isa_inb;
199767f8919635c4928607450d9e0abb932109ceToomas Soome archsw.arch_isaoutb = isa_outb;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef LOADER_ZFS_SUPPORT
199767f8919635c4928607450d9e0abb932109ceToomas Soome archsw.arch_zfs_probe = i386_zfs_probe;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * March through the device switch probing for things.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0; devsw[i] != NULL; i++)
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (devsw[i]->dv_init != NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome (devsw[i]->dv_init)();
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("BIOS %dkB/%dkB available memory\n", bios_basemem / 1024, bios_extmem / 1024);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (initial_bootinfo != NULL) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome initial_bootinfo->bi_basemem = bios_basemem / 1024;
199767f8919635c4928607450d9e0abb932109ceToomas Soome initial_bootinfo->bi_extmem = bios_extmem / 1024;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* detect ACPI for future reference */
199767f8919635c4928607450d9e0abb932109ceToomas Soome biosacpi_detect();
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* detect SMBIOS for future reference */
199767f8919635c4928607450d9e0abb932109ceToomas Soome smbios_detect(NULL);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* detect PCI BIOS for future reference */
199767f8919635c4928607450d9e0abb932109ceToomas Soome biospci_detect();
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("\n");
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("%s, Revision %s\n", bootprog_name, bootprog_rev);
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("(%s, %s)\n", bootprog_maker, bootprog_date);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome extract_currdev(); /* set $currdev and $loaddev */
199767f8919635c4928607450d9e0abb932109ceToomas Soome setenv("LINES", "24", 1); /* optional */
199767f8919635c4928607450d9e0abb932109ceToomas Soome setenv("COLUMNS", "80", 1); /* optional */
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (bi_checkcpu())
199767f8919635c4928607450d9e0abb932109ceToomas Soome setenv("ISADIR", "amd64", 1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome else
199767f8919635c4928607450d9e0abb932109ceToomas Soome setenv("ISADIR", "", 1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome bios_getsmap();
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome interact(NULL);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* if we ever get here, it is an error */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Set the 'current device' by (if possible) recovering the boot device as
199767f8919635c4928607450d9e0abb932109ceToomas Soome * supplied by the initial bootstrap.
199767f8919635c4928607450d9e0abb932109ceToomas Soome *
199767f8919635c4928607450d9e0abb932109ceToomas Soome * XXX should be extended for netbooting.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void
199767f8919635c4928607450d9e0abb932109ceToomas Soomeextract_currdev(void)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome struct i386_devdesc new_currdev;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef LOADER_ZFS_SUPPORT
199767f8919635c4928607450d9e0abb932109ceToomas Soome char buf[20];
199767f8919635c4928607450d9e0abb932109ceToomas Soome struct zfs_boot_args *zargs;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome int biosdev = -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* Assume we are booting from a BIOS disk by default */
199767f8919635c4928607450d9e0abb932109ceToomas Soome new_currdev.d_dev = &biosdisk;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* new-style boot loaders such as pxeldr and cdldr */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (kargs->bootinfo == 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((kargs->bootflags & KARGS_FLAGS_CD) != 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* we are booting from a CD with cdboot */
199767f8919635c4928607450d9e0abb932109ceToomas Soome new_currdev.d_dev = &bioscd;
199767f8919635c4928607450d9e0abb932109ceToomas Soome new_currdev.d_unit = bc_bios2unit(initial_bootdev);
199767f8919635c4928607450d9e0abb932109ceToomas Soome } else if ((kargs->bootflags & KARGS_FLAGS_PXE) != 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* we are booting from pxeldr */
199767f8919635c4928607450d9e0abb932109ceToomas Soome new_currdev.d_dev = &pxedisk;
199767f8919635c4928607450d9e0abb932109ceToomas Soome new_currdev.d_unit = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome } else {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* we don't know what our boot device is */
199767f8919635c4928607450d9e0abb932109ceToomas Soome new_currdev.d_kind.biosdisk.slice = -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome new_currdev.d_kind.biosdisk.partition = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome biosdev = -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef LOADER_ZFS_SUPPORT
199767f8919635c4928607450d9e0abb932109ceToomas Soome } else if ((kargs->bootflags & KARGS_FLAGS_ZFS) != 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome zargs = NULL;
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* check for new style extended argument */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((kargs->bootflags & KARGS_FLAGS_EXTARG) != 0)
199767f8919635c4928607450d9e0abb932109ceToomas Soome zargs = (struct zfs_boot_args *)(kargs + 1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (zargs != NULL &&
199767f8919635c4928607450d9e0abb932109ceToomas Soome zargs->size >= offsetof(struct zfs_boot_args, primary_pool)) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* sufficient data is provided */
199767f8919635c4928607450d9e0abb932109ceToomas Soome new_currdev.d_kind.zfs.pool_guid = zargs->pool;
199767f8919635c4928607450d9e0abb932109ceToomas Soome new_currdev.d_kind.zfs.root_guid = zargs->root;
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (zargs->size >= sizeof(*zargs) && zargs->primary_vdev != 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome sprintf(buf, "%llu", zargs->primary_pool);
199767f8919635c4928607450d9e0abb932109ceToomas Soome setenv("vfs.zfs.boot.primary_pool", buf, 1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome sprintf(buf, "%llu", zargs->primary_vdev);
199767f8919635c4928607450d9e0abb932109ceToomas Soome setenv("vfs.zfs.boot.primary_vdev", buf, 1);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome } else {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* old style zfsboot block */
199767f8919635c4928607450d9e0abb932109ceToomas Soome new_currdev.d_kind.zfs.pool_guid = kargs->zfspool;
199767f8919635c4928607450d9e0abb932109ceToomas Soome new_currdev.d_kind.zfs.root_guid = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome new_currdev.d_dev = &zfs_dev;
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome } else if ((initial_bootdev & B_MAGICMASK) != B_DEVMAGIC) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* The passed-in boot device is bad */
199767f8919635c4928607450d9e0abb932109ceToomas Soome new_currdev.d_kind.biosdisk.slice = -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome new_currdev.d_kind.biosdisk.partition = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome biosdev = -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome } else {
199767f8919635c4928607450d9e0abb932109ceToomas Soome new_currdev.d_kind.biosdisk.slice = B_SLICE(initial_bootdev) - 1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome new_currdev.d_kind.biosdisk.partition = B_PARTITION(initial_bootdev);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (new_currdev.d_kind.biosdisk.partition == 0xff)
199767f8919635c4928607450d9e0abb932109ceToomas Soome new_currdev.d_kind.biosdisk.partition = -1;
199767f8919635c4928607450d9e0abb932109ceToomas Soome biosdev = initial_bootinfo->bi_bios_dev;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * If we are booted by an old bootstrap, we have to guess at the BIOS
199767f8919635c4928607450d9e0abb932109ceToomas Soome * unit number. We will lose if there is more than one disk type
199767f8919635c4928607450d9e0abb932109ceToomas Soome * and we are not booting from the lowest-numbered disk type
199767f8919635c4928607450d9e0abb932109ceToomas Soome * (ie. SCSI when IDE also exists).
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((biosdev == 0) && (B_TYPE(initial_bootdev) != 2)) /* biosdev doesn't match major */
199767f8919635c4928607450d9e0abb932109ceToomas Soome biosdev = 0x80 + B_UNIT(initial_bootdev); /* assume harddisk */
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome new_currdev.d_type = new_currdev.d_dev->dv_type;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * If we are booting off of a BIOS disk and we didn't succeed in determining
199767f8919635c4928607450d9e0abb932109ceToomas Soome * which one we booted off of, just use disk0: as a reasonable default.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome if ((new_currdev.d_type == biosdisk.dv_type) &&
199767f8919635c4928607450d9e0abb932109ceToomas Soome ((new_currdev.d_unit = bd_bios2unit(biosdev)) == -1)) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("Can't work out which disk we are booting from.\n"
199767f8919635c4928607450d9e0abb932109ceToomas Soome "Guessed BIOS device 0x%x not found by probes, defaulting to disk0:\n", biosdev);
199767f8919635c4928607450d9e0abb932109ceToomas Soome new_currdev.d_unit = 0;
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef LOADER_ZFS_SUPPORT
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef __FreeBSD__
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (new_currdev.d_type == DEVT_ZFS)
199767f8919635c4928607450d9e0abb932109ceToomas Soome init_zfs_bootenv(zfs_fmtdev(&new_currdev));
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome env_setenv("currdev", EV_VOLATILE, i386_fmtdev(&new_currdev),
199767f8919635c4928607450d9e0abb932109ceToomas Soome i386_setcurrdev, env_nounset);
199767f8919635c4928607450d9e0abb932109ceToomas Soome env_setenv("loaddev", EV_VOLATILE, i386_fmtdev(&new_currdev), env_noset,
199767f8919635c4928607450d9e0abb932109ceToomas Soome env_nounset);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas SoomeCOMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int
199767f8919635c4928607450d9e0abb932109ceToomas Soomecommand_reboot(int argc, char *argv[])
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int i;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (i = 0; devsw[i] != NULL; ++i)
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (devsw[i]->dv_cleanup != NULL)
199767f8919635c4928607450d9e0abb932109ceToomas Soome (devsw[i]->dv_cleanup)();
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("Rebooting...\n");
199767f8919635c4928607450d9e0abb932109ceToomas Soome delay(1000000);
199767f8919635c4928607450d9e0abb932109ceToomas Soome __exit(0);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* provide this for panic, as it's not in the startup code */
199767f8919635c4928607450d9e0abb932109ceToomas Soomevoid
199767f8919635c4928607450d9e0abb932109ceToomas Soomeexit(int code)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome __exit(code);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas SoomeCOMMAND_SET(heap, "heap", "show heap usage", command_heap);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int
199767f8919635c4928607450d9e0abb932109ceToomas Soomecommand_heap(int argc, char *argv[])
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome mallocstats();
199767f8919635c4928607450d9e0abb932109ceToomas Soome printf("heap base at %p, top at %p, upper limit at %p\n", heap_bottom,
199767f8919635c4928607450d9e0abb932109ceToomas Soome sbrk(0), heap_top);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return(CMD_OK);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef LOADER_ZFS_SUPPORT
199767f8919635c4928607450d9e0abb932109ceToomas SoomeCOMMAND_SET(lszfs, "lszfs", "list child datasets of a zfs dataset",
199767f8919635c4928607450d9e0abb932109ceToomas Soome command_lszfs);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int
199767f8919635c4928607450d9e0abb932109ceToomas Soomecommand_lszfs(int argc, char *argv[])
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int err;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (argc != 2) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome command_errmsg = "wrong number of arguments";
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (CMD_ERROR);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome err = zfs_list(argv[1]);
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (err != 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome command_errmsg = strerror(err);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (CMD_ERROR);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (CMD_OK);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef __FreeBSD__
199767f8919635c4928607450d9e0abb932109ceToomas SoomeCOMMAND_SET(reloadbe, "reloadbe", "refresh the list of ZFS Boot Environments",
199767f8919635c4928607450d9e0abb932109ceToomas Soome command_reloadbe);
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int
199767f8919635c4928607450d9e0abb932109ceToomas Soomecommand_reloadbe(int argc, char *argv[])
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome int err;
199767f8919635c4928607450d9e0abb932109ceToomas Soome char *root;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (argc > 2) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome command_errmsg = "wrong number of arguments";
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (CMD_ERROR);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (argc == 2) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome err = zfs_bootenv(argv[1]);
199767f8919635c4928607450d9e0abb932109ceToomas Soome } else {
199767f8919635c4928607450d9e0abb932109ceToomas Soome root = getenv("zfs_be_root");
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (root == NULL) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome /* There does not appear to be a ZFS pool here, exit without error */
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (CMD_OK);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome err = zfs_bootenv(getenv("zfs_be_root"));
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (err != 0) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome command_errmsg = strerror(err);
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (CMD_ERROR);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (CMD_OK);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif /* __FreeBSD__ */
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome/* ISA bus access functions for PnP. */
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic int
199767f8919635c4928607450d9e0abb932109ceToomas Soomeisa_inb(int port)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome return (inb(port));
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void
199767f8919635c4928607450d9e0abb932109ceToomas Soomeisa_outb(int port, int value)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome outb(port, value);
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome#ifdef LOADER_ZFS_SUPPORT
199767f8919635c4928607450d9e0abb932109ceToomas Soomestatic void
199767f8919635c4928607450d9e0abb932109ceToomas Soomei386_zfs_probe(void)
199767f8919635c4928607450d9e0abb932109ceToomas Soome{
199767f8919635c4928607450d9e0abb932109ceToomas Soome char devname[32];
199767f8919635c4928607450d9e0abb932109ceToomas Soome int unit;
199767f8919635c4928607450d9e0abb932109ceToomas Soome
199767f8919635c4928607450d9e0abb932109ceToomas Soome /*
199767f8919635c4928607450d9e0abb932109ceToomas Soome * Open all the disks we can find and see if we can reconstruct
199767f8919635c4928607450d9e0abb932109ceToomas Soome * ZFS pools from them.
199767f8919635c4928607450d9e0abb932109ceToomas Soome */
199767f8919635c4928607450d9e0abb932109ceToomas Soome for (unit = 0; unit < MAXBDDEV; unit++) {
199767f8919635c4928607450d9e0abb932109ceToomas Soome if (bd_unit2bios(unit) == -1)
199767f8919635c4928607450d9e0abb932109ceToomas Soome break;
199767f8919635c4928607450d9e0abb932109ceToomas Soome sprintf(devname, "disk%d:", unit);
199767f8919635c4928607450d9e0abb932109ceToomas Soome zfs_probe_dev(devname, NULL);
199767f8919635c4928607450d9e0abb932109ceToomas Soome }
199767f8919635c4928607450d9e0abb932109ceToomas Soome}
199767f8919635c4928607450d9e0abb932109ceToomas Soome#endif