diff options
| author | Yoshihiro Takahashi <nyan@FreeBSD.org> | 2000-01-03 15:31:17 +0000 |
|---|---|---|
| committer | Yoshihiro Takahashi <nyan@FreeBSD.org> | 2000-01-03 15:31:17 +0000 |
| commit | 996a586a167c42fbbb87d48882b64c6868753c7e (patch) | |
| tree | 745bde50adc4f2cc0acdcf77a1869a9d98d107b2 | |
| parent | 4911007aaed7d7c3d938bebc87af464b9c2d3996 (diff) | |
Notes
| -rw-r--r-- | sys/boot/pc98/libpc98/biosdisk.c | 67 | ||||
| -rw-r--r-- | sys/boot/pc98/libpc98/bootinfo.c | 331 | ||||
| -rw-r--r-- | sys/boot/pc98/loader/main.c | 4 |
3 files changed, 62 insertions, 340 deletions
diff --git a/sys/boot/pc98/libpc98/biosdisk.c b/sys/boot/pc98/libpc98/biosdisk.c index 27c86d6dcaca..31ddbb4855c6 100644 --- a/sys/boot/pc98/libpc98/biosdisk.c +++ b/sys/boot/pc98/libpc98/biosdisk.c @@ -95,7 +95,7 @@ static struct bdinfo int bd_flags; int bd_type; /* BIOS 'drive type' (floppy only) */ #ifdef PC98 - int bd_da_unit; /* kernel unit number for da */ + int bd_da_unit; /* kernel unit number for da */ #endif } bdinfo [MAXBDDEV]; static int nbdinfo = 0; @@ -228,6 +228,7 @@ bd_init(void) static int bd_int13probe(struct bdinfo *bd) { + #ifdef PC98 int addr; if (bd->bd_flags & BD_FLOPPY){ @@ -536,6 +537,7 @@ bd_opendisk(struct open_disk **odp, struct i386_devdesc *dev) od->od_boff = sector; /* no partition, must be after the slice */ DEBUG("opening raw slice"); } else { + if (bd_read(od, sector + LABELSECTOR, 1, buf)) { DEBUG("error reading disklabel"); error = EIO; @@ -597,7 +599,7 @@ bd_bestslice(struct dos_partition *dptr) int i; int preflevel, pref; - + #ifndef PC98 /* * Check for the historically bogus MBR found on true dedicated disks @@ -901,12 +903,12 @@ bd_getgeom(struct open_disk *od) #ifdef PC98 if (od->od_flags & BD_FLOPPY) { - od->od_cyl = 79; + od->od_cyl = 79; od->od_hds = 2; od->od_sec = (od->od_unit & 0xf0) == 0x30 ? 18 : 15; } else { - v86.ctl = V86_FLAGS; + v86.ctl = V86_FLAGS; v86.addr = 0x1b; v86.eax = 0x8400 | od->od_unit; v86int(); @@ -940,6 +942,60 @@ bd_getgeom(struct open_disk *od) } /* + * Return the BIOS geometry of a given "fixed drive" in a format + * suitable for the legacy bootinfo structure. Since the kernel is + * expecting raw int 0x13/0x8 values for N_BIOS_GEOM drives, we + * prefer to get the information directly, rather than rely on being + * able to put it together from information already maintained for + * different purposes and for a probably different number of drives. + * + * For valid drives, the geometry is expected in the format (31..0) + * "000000cc cccccccc hhhhhhhh 00ssssss"; and invalid drives are + * indicated by returning the geometry of a "1.2M" PC-format floppy + * disk. And, incidentally, what is returned is not the geometry as + * such but the highest valid cylinder, head, and sector numbers. + */ +u_int32_t +bd_getbigeom(int bunit) +{ + +#ifdef PC98 + int hds = 0; + int unit = 0x80; /* IDE HDD */ + u_int addr = 0xA155d; + + while (unit < 0xa7) { + if (*(u_char *)PTOV(addr) & (1 << (unit & 0x0f))) + if (hds++ == bunit) + break; + if (++unit == 0x84) { + unit = 0xa0; /* SCSI HDD */ + addr = 0xA1482; + } + } + if (unit == 0xa7) + return 0x4f010f; + v86.ctl = V86_FLAGS; + v86.addr = 0x1b; + v86.eax = 0x8400 | unit; + v86int(); + if (v86.efl & 0x1) + return 0x4f010f; + return ((v86.ecx & 0xffff) << 16) | (v86.edx & 0xffff); +#else + v86.ctl = V86_FLAGS; + v86.addr = 0x13; + v86.eax = 0x800; + v86.edx = 0x80 + bunit; + v86int(); + if (v86.efl & 0x1) + return 0x4f010f; + return ((v86.ecx & 0xc0) << 18) | ((v86.ecx & 0xff00) << 8) | + (v86.edx & 0xff00) | (v86.ecx & 0x3f); +#endif +} + +/* * Return a suitable dev_t value for (dev). * * In the case where it looks like (dev) is a SCSI disk, we allow the number of @@ -1008,7 +1064,8 @@ bd_getdev(struct i386_devdesc *dev) else unit = biosdev & 0xf; #else - unit = (biosdev & 0x7f) - unitofs; /* allow for #wd compenstation in da case */ +/* allow for #wd compenstation in da case */ + unit = (biosdev & 0x7f) - unitofs; #endif } diff --git a/sys/boot/pc98/libpc98/bootinfo.c b/sys/boot/pc98/libpc98/bootinfo.c deleted file mode 100644 index 03d949e01aa5..000000000000 --- a/sys/boot/pc98/libpc98/bootinfo.c +++ /dev/null @@ -1,331 +0,0 @@ -/*- - * Copyright (c) 1998 Michael Smith <msmith@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. - * - * $FreeBSD$ - */ - -#include <stand.h> -#include <sys/param.h> -#include <sys/reboot.h> -#include <sys/linker.h> -#include <machine/bootinfo.h> -#include "bootstrap.h" -#include "libi386.h" -#include "btxv86.h" - -static struct bootinfo bi; -#ifdef PC98 -extern struct bootinfo *initial_bootinfo; -#endif - -/* - * Return a 'boothowto' value corresponding to the kernel arguments in - * (kargs) and any relevant environment variables. - */ -static struct -{ - char *ev; - int mask; -} howto_names[] = { - {"boot_askname", RB_ASKNAME}, - {"boot_userconfig", RB_CONFIG}, - {"boot_ddb", RB_KDB}, - {"boot_gdb", RB_GDB}, - {"boot_single", RB_SINGLE}, - {"boot_verbose", RB_VERBOSE}, - {NULL, 0} -}; - -int -bi_getboothowto(char *kargs) -{ - char *cp; - int howto; - int active; - int i; - - /* Parse kargs */ - howto = 0; - if (kargs != NULL) { - cp = kargs; - active = 0; - while (*cp != 0) { - if (!active && (*cp == '-')) { - active = 1; - } else if (active) - switch (*cp) { - case 'a': - howto |= RB_ASKNAME; - break; - case 'c': - howto |= RB_CONFIG; - break; - case 'd': - howto |= RB_KDB; - break; - case 'g': - howto |= RB_GDB; - break; - case 'h': - howto |= RB_SERIAL; - break; - case 'r': - howto |= RB_DFLTROOT; - break; - case 's': - howto |= RB_SINGLE; - break; - case 'v': - howto |= RB_VERBOSE; - break; - default: - active = 0; - break; - } - cp++; - } - } - /* get equivalents from the environment */ - for (i = 0; howto_names[i].ev != NULL; i++) - if (getenv(howto_names[i].ev) != NULL) - howto |= howto_names[i].mask; - if (!strcmp(getenv("console"), "comconsole")) - howto |= RB_SERIAL; - return(howto); -} - -/* - * Copy the environment into the load area starting at (addr). - * Each variable is formatted as <name>=<value>, with a single nul - * separating each variable, and a double nul terminating the environment. - */ -vm_offset_t -bi_copyenv(vm_offset_t addr) -{ - struct env_var *ep; - - /* traverse the environment */ - for (ep = environ; ep != NULL; ep = ep->ev_next) { - i386_copyin(ep->ev_name, addr, strlen(ep->ev_name)); - addr += strlen(ep->ev_name); - i386_copyin("=", addr, 1); - addr++; - if (ep->ev_value != NULL) { - i386_copyin(ep->ev_value, addr, strlen(ep->ev_value)); - addr += strlen(ep->ev_value); - } - i386_copyin("", addr, 1); - addr++; - } - i386_copyin("", addr, 1); - addr++; - return(addr); -} - -/* - * Copy module-related data into the load area, where it can be - * used as a directory for loaded modules. - * - * Module data is presented in a self-describing format. Each datum - * is preceeded by a 32-bit identifier and a 32-bit size field. - * - * Currently, the following data are saved: - * - * MOD_NAME (variable) module name (string) - * MOD_TYPE (variable) module type (string) - * MOD_ADDR sizeof(vm_offset_t) module load address - * MOD_SIZE sizeof(size_t) module size - * MOD_METADATA (variable) type-specific metadata - */ -#define COPY32(v, a) { \ - u_int32_t x = (v); \ - i386_copyin(&x, a, sizeof(x)); \ - a += sizeof(x); \ -} - -#define MOD_STR(t, a, s) { \ - COPY32(t, a); \ - COPY32(strlen(s) + 1, a); \ - i386_copyin(s, a, strlen(s) + 1); \ - a += roundup(strlen(s) + 1, sizeof(u_long));\ -} - -#define MOD_NAME(a, s) MOD_STR(MODINFO_NAME, a, s) -#define MOD_TYPE(a, s) MOD_STR(MODINFO_TYPE, a, s) - -#define MOD_VAR(t, a, s) { \ - COPY32(t, a); \ - COPY32(sizeof(s), a); \ - i386_copyin(&s, a, sizeof(s)); \ - a += roundup(sizeof(s), sizeof(u_long)); \ -} - -#define MOD_ADDR(a, s) MOD_VAR(MODINFO_ADDR, a, s) -#define MOD_SIZE(a, s) MOD_VAR(MODINFO_SIZE, a, s) - -#define MOD_METADATA(a, mm) { \ - COPY32(MODINFO_METADATA | mm->md_type, a); \ - COPY32(mm->md_size, a); \ - i386_copyin(mm->md_data, a, mm->md_size); \ - a += roundup(mm->md_size, sizeof(u_long));\ -} - -#define MOD_END(a) { \ - COPY32(MODINFO_END, a); \ - COPY32(0, a); \ -} - -vm_offset_t -bi_copymodules(vm_offset_t addr) -{ - struct loaded_module *mp; - struct module_metadata *md; - - /* start with the first module on the list, should be the kernel */ - for (mp = mod_findmodule(NULL, NULL); mp != NULL; mp = mp->m_next) { - - MOD_NAME(addr, mp->m_name); /* this field must come first */ - MOD_TYPE(addr, mp->m_type); - MOD_ADDR(addr, mp->m_addr); - MOD_SIZE(addr, mp->m_size); - for (md = mp->m_metadata; md != NULL; md = md->md_next) - if (!(md->md_type & MODINFOMD_NOCOPY)) - MOD_METADATA(addr, md); - } - MOD_END(addr); - return(addr); -} - -/* - * Load the information expected by an i386 kernel. - * - * - The 'boothowto' argument is constructed - * - The 'botdev' argument is constructed - * - The 'bootinfo' struct is constructed, and copied into the kernel space. - * - The kernel environment is copied into kernel space. - * - Module metadata are formatted and placed in kernel space. - */ -int -bi_load(char *args, int *howtop, int *bootdevp, vm_offset_t *bip) -{ - struct loaded_module *xp; - struct i386_devdesc *rootdev; - vm_offset_t addr, bootinfo_addr; - char *rootdevname; - int bootdevnr; - u_int pad; - char *kernelname; - const char *kernelpath; -#ifdef PC98 - int i; -#endif - - *howtop = bi_getboothowto(args); - - /* - * Allow the environment variable 'rootdev' to override the supplied device - * This should perhaps go to MI code and/or have $rootdev tested/set by - * MI code before launching the kernel. - */ - rootdevname = getenv("rootdev"); - i386_getdev((void **)(&rootdev), rootdevname, NULL); - if (rootdev == NULL) { /* bad $rootdev/$currdev */ - printf("can't determine root device\n"); - return(EINVAL); - } - - switch(rootdev->d_type) { - case DEVT_DISK: - /* pass in the BIOS device number of the current disk */ - bi.bi_bios_dev = bd_unit2bios(rootdev->d_kind.biosdisk.unit); - bootdevnr = bd_getdev(rootdev); - if (bootdevnr != -1) - break; - printf("root device %s invalid\n", i386_fmtdev(rootdev)); - return(EINVAL); - - default: - printf("aout_exec: WARNING - don't know how to boot from device type %d\n", rootdev->d_type); - } - free(rootdev); - *bootdevp = bootdevnr; - - /* legacy bootinfo structure */ - bi.bi_version = BOOTINFO_VERSION; - bi.bi_kernelname = 0; /* XXX char * -> kernel name */ - bi.bi_nfs_diskless = 0; /* struct nfs_diskless * */ - bi.bi_n_bios_used = 0; /* XXX would have to hook biosdisk driver for these */ - /* bi.bi_bios_geom[] */ -#ifdef PC98 - for(i = 0; i < N_BIOS_GEOM; i++) - bi.bi_bios_geom[i] = initial_bootinfo->bi_bios_geom[i]; -#endif - bi.bi_size = sizeof(bi); - bi.bi_memsizes_valid = 1; - bi.bi_basemem = getbasemem(); - bi.bi_extmem = getextmem(); - - /* find the last module in the chain */ - addr = 0; - for (xp = mod_findmodule(NULL, NULL); xp != NULL; xp = xp->m_next) { - if (addr < (xp->m_addr + xp->m_size)) - addr = xp->m_addr + xp->m_size; - } - /* pad to a page boundary */ - pad = (u_int)addr & PAGE_MASK; - if (pad != 0) { - pad = PAGE_SIZE - pad; - addr += pad; - } - - /* copy our environment */ - bi.bi_envp = addr; - addr = bi_copyenv(addr); - - /* pad to a page boundary */ - pad = (u_int)addr & PAGE_MASK; - if (pad != 0) { - pad = PAGE_SIZE - pad; - addr += pad; - } - /* copy module list and metadata */ - bi.bi_modulep = addr; - addr = bi_copymodules(addr); - - /* all done copying stuff in, save end of loaded object space */ - bi.bi_kernend = addr; - - *howtop |= RB_BOOTINFO; /* it's there now */ - - /* - * Get the kernel name, strip off any device prefix. - */ - kernelname = getenv("kernelname"); - i386_getdev(NULL, kernelname, &kernelpath); - bi.bi_kernelname = VTOP(kernelpath); - *bip = VTOP(&bi); - - return(0); -} diff --git a/sys/boot/pc98/loader/main.c b/sys/boot/pc98/loader/main.c index 0fabadfe5b8e..b9978ca85c28 100644 --- a/sys/boot/pc98/loader/main.c +++ b/sys/boot/pc98/loader/main.c @@ -53,11 +53,7 @@ static struct static u_int32_t initial_howto; static u_int32_t initial_bootdev; -#ifdef PC98 -struct bootinfo *initial_bootinfo; -#else static struct bootinfo *initial_bootinfo; -#endif struct arch_switch archsw; /* MI/MD interface boundary */ |
