diff options
Diffstat (limited to 'sys/arch/i386/i386/bios.c')
-rw-r--r-- | sys/arch/i386/i386/bios.c | 229 |
1 files changed, 126 insertions, 103 deletions
diff --git a/sys/arch/i386/i386/bios.c b/sys/arch/i386/i386/bios.c index c54f332a49d..3d3bc4ac556 100644 --- a/sys/arch/i386/i386/bios.c +++ b/sys/arch/i386/i386/bios.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bios.c,v 1.10 1997/10/19 06:34:21 mickey Exp $ */ +/* $OpenBSD: bios.c,v 1.11 1997/10/22 23:37:11 mickey Exp $ */ /* * Copyright (c) 1997 Michael Shalayeff @@ -32,17 +32,22 @@ * */ +/* #define BIOS_DEBUG */ + #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/device.h> #include <sys/errno.h> #include <sys/proc.h> +#include <sys/malloc.h> +#include <sys/reboot.h> #include <vm/vm.h> #include <sys/sysctl.h> #include <dev/cons.h> +#include <stand/boot/bootarg.h> #include <machine/cpu.h> #include <machine/pio.h> @@ -58,22 +63,13 @@ #include "apm.h" -#define LMVAS (1024*1024-NBPG) -#define LMVOF NBPG - -int gdt_get_slot __P((void)); - struct bios_softc { struct device sc_dev; - - bus_space_handle_t bt; }; int biosprobe __P((struct device *, void *, void *)); void biosattach __P((struct device *, struct device *, void *)); -void bios_init __P((bus_space_handle_t)); int bios_print __P((void *, const char *)); -static __inline int bios_call __P((u_int cmd, u_int arg)); struct cfattach bios_ca = { sizeof(struct bios_softc), biosprobe, biosattach @@ -83,57 +79,14 @@ struct cfdriver bios_cd = { NULL, "bios", DV_DULL }; -int bios_initted = 0; -int bios_ds, bios_cs16; -bus_space_handle_t bios_lmva; -struct { - u_int32_t ip; - u_int16_t cs; -} bios_kentry; -struct BIOS_vars BIOS_vars; - -static __inline int -bios_call(cmd, arg) - u_int cmd; - u_int arg; -{ - int rv; - __asm volatile ("pushl %1\n\t" - "pushl %2\n\t" - "pushl %%ds\n\t" - "movl %4, %%ds\n\t" - "movl %4, %%es\n\t" - "movl %4, %%gs\n\t" - "movl %4, %%fs\n\t" - "lcall %%cs:(%3)\n\t" - "popl %%ds\n\t" - "addl $8, %%esp" - : "=a" (rv) - : "id" (cmd), "r" (arg), - "r" (&bios_kentry), "r" (bios_ds)); - return rv; -} - -void -bios_init(bt) - bus_space_handle_t bt; -{ - if (bios_initted) - return; - - if (bus_space_map(bt, LMVOF, LMVAS, 0, &bios_lmva) == 0) { - extern union descriptor *dynamic_gdt; +extern bus_addr_t bootargv; +extern int bootargc; +extern u_int bootapiver; /* locore.s */ +extern dev_t bootdev; - setsegment(&dynamic_gdt[bios_kentry.cs = gdt_get_slot()].sd, - (void*)bios_lmva, LMVAS, SDT_MEMERA, SEL_KPL, 1, 0); - setsegment(&dynamic_gdt[bios_ds = gdt_get_slot()].sd, - (void*)bios_lmva, LMVAS, SDT_MEMRWA, SEL_KPL, 1, 0); - setsegment(&dynamic_gdt[bios_cs16 = gdt_get_slot()].sd, - (void*)bios_lmva, LMVAS, SDT_MEMERA, SEL_KPL, 0, 0); +bios_diskinfo_t *bios_diskinfo; - bios_initted++; - } -} +bios_diskinfo_t *bios_getdiskinfo __P((dev_t)); int biosprobe(parent, match, aux) @@ -141,21 +94,31 @@ biosprobe(parent, match, aux) void *match, *aux; { struct bios_attach_args *bia = aux; - extern u_int bootapiver; /* locore.s */ + bus_space_handle_t hsp; + int error; - if (bootapiver == 0) +#ifdef BIOS_DEBUG + printf("%s%d: boot API ver %x, %x; args %p[%d]\n", + bia->bios_dev, bios_cd.cd_ndevs, + bootapiver, BOOT_APIVER, bootargv, bootargc); +#endif + /* there could be only one */ + if (bios_cd.cd_ndevs || strcmp(bia->bios_dev, bios_cd.cd_name)) return 0; -#if 0 - if (!bios_initted) { - bus_space_handle_t hsp; + if (bootapiver < BOOT_APIVER || bootargv == NULL) + return 0; - if (bus_space_map(bia->bios_memt, LMVOF, LMVAS, 0, &hsp) != 0) - return 0; - bus_space_unmap(bia->bios_memt, hsp, LMVAS); - } + if ((error = bus_space_map(bia->bios_memt, + bootargv, bootargc, 1, &hsp)) != 0) { +#ifdef DEBUG + printf("bios0: bus_space_map() == %d\n", error); #endif - return !bios_cd.cd_ndevs && !strcmp(bia->bios_dev, "bios"); + return 0; + } + bus_space_unmap(bia->bios_memt, hsp, bootargc); + + return 1; } void @@ -165,44 +128,69 @@ biosattach(parent, self, aux) { struct bios_softc *sc = (void *) self; struct bios_attach_args *bia = aux; - +#if NAPM > 0 || defined(DEBUG) + bios_apminfo_t *apm; +#endif u_int8_t *va = ISA_HOLE_VADDR(0xffff0); - char *p; + char *str; + bus_space_handle_t hsp; + bootarg_t *p, *q; + + if (bus_space_map(bia->bios_memt, bootargv, bootargc, 1, &hsp) != 0) { +#ifdef DEBUG + panic("getbootargs: can't map low memory"); +#endif + return; + } - sc->bt = bia->bios_memt; - /* bios_init(sc->bt); */ switch (va[14]) { default: - case 0xff: p = "PC"; break; - case 0xfe: p = "PC/XT"; break; - case 0xfd: p = "PCjr"; break; - case 0xfc: p = "AT/286+"; break; - case 0xfb: p = "PC/XT+"; break; - case 0xfa: p = "PS/2 25/30"; break; - case 0xf9: p = "PC Convertible";break; - case 0xf8: p = "PS/2 386+"; break; + case 0xff: str = "PC"; break; + case 0xfe: str = "PC/XT"; break; + case 0xfd: str = "PCjr"; break; + case 0xfc: str = "AT/286+"; break; + case 0xfb: str = "PC/XT+"; break; + case 0xfa: str = "PS/2 25/30"; break; + case 0xf9: str = "PC Convertible";break; + case 0xf8: str = "PS/2 386+"; break; } printf(": %s(%02x) BIOS, date %c%c/%c%c/%c%c\n", - p, va[15], va[5], va[6], va[8], va[9], va[11], va[12]); + str, va[15], va[5], va[6], va[8], va[9], va[11], va[12]); + + printf("%s:", sc->sc_dev.dv_xname); + p = (bootarg_t *)hsp; + for(q = p; q->ba_type != BOOTARG_END; q = q->ba_next) { + q->ba_next = (bootarg_t *)((caddr_t)q + q->ba_size); + switch (q->ba_type) { + case BOOTARG_MEMMAP: + printf(" memmap"); + break; + case BOOTARG_DISKINFO: + printf(" diskinfo"); + bios_diskinfo = (bios_diskinfo_t *)q->ba_arg; + break; + case BOOTARG_APMINFO: + printf(" apminfo"); + apm = (bios_apminfo_t *)q->ba_arg; + break; + default: + } + } + printf("\n"); + #ifdef DEBUG printf("apminfo: %x, code %x/%x[%x], data %x[%x], entry %x\n", - BIOS_vars.bios_apm_detail, BIOS_vars.bios_apm_code32_base, - BIOS_vars.bios_apm_code16_base, BIOS_vars.bios_apm_code_len, - BIOS_vars.bios_apm_data_base, BIOS_vars.bios_apm_data_len, - BIOS_vars.bios_apm_entry); + apm->apm_detail, apm->apm_code32_base, + apm->apm_code16_base, apm->apm_code_len, + apm->apm_data_base, apm->apm_data_len, apm->apm_entry); #endif #if NAPM > 0 { struct bios_attach_args ba; - ba.apm_detail = BIOS_vars.bios_apm_detail; - ba.apm_code32_base = BIOS_vars.bios_apm_code32_base; - ba.apm_code16_base = BIOS_vars.bios_apm_code16_base; - ba.apm_code_len = BIOS_vars.bios_apm_code_len; - ba.apm_data_base = BIOS_vars.bios_apm_data_base; - ba.apm_data_len = BIOS_vars.bios_apm_data_len; - ba.apm_entry = BIOS_vars.bios_apm_entry; + ba.bios_apmp = apm; ba.bios_dev = "apm"; + ba.bios_func = 0x15; config_found(self, &ba, bios_print); } #endif @@ -216,7 +204,8 @@ bios_print(aux, pnp) struct bios_attach_args *ba = aux; if (pnp) - printf("%s at %s", ba->bios_dev, pnp); + printf("%s at %s function 0x%x", + ba->bios_dev, pnp, ba->bios_func); return (UNCONF); } @@ -281,7 +270,7 @@ bioscnprobe(cn) { #if 0 bios_init(I386_BUS_SPACE_MEM); /* XXX */ - if (!bios_initted) + if (!bios_cd.cd_ndevs) return; if (0 && bios_call(BOOTC_CHECK, NULL)) @@ -331,20 +320,31 @@ bios_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) size_t newlen; struct proc *p; { - extern u_int cnvmem, extmem, bootapiver; /* locore.s */ + extern u_int cnvmem, extmem; /* locore.s */ + bios_diskinfo_t *pdi; + int biosdev; /* all sysctl names at this level are terminal */ - if (namelen != 1) + if (namelen != 1 && name[0] != BIOS_DISKINFO) return (ENOTDIR); /* overloaded */ - if (bootapiver == 0) - return EOPNOTSUPP; - switch (name[0]) { case BIOS_DEV: - return sysctl_rdint(oldp, oldlenp, newp, BIOS_vars.bios_dev); - case BIOS_GEOMETRY: - return sysctl_rdint(oldp, oldlenp, newp, BIOS_vars.bios_geometry); + if (bootapiver < BOOT_APIVER) + return EOPNOTSUPP; + if ((pdi = bios_getdiskinfo(bootdev)) == NULL) + return ENXIO; + biosdev = pdi->bios_number; + return sysctl_rdint(oldp, oldlenp, newp, biosdev); + case BIOS_DISKINFO: + if (namelen != 2) + return ENOTDIR; + if (bootapiver < BOOT_APIVER) + return EOPNOTSUPP; + if ((pdi = bios_getdiskinfo(name[1])) == NULL) + return ENXIO; + return sysctl_rdstruct(oldp, oldlenp, newp, + pdi, sizeof(*bios_diskinfo)); case BIOS_CNVMEM: return sysctl_rdint(oldp, oldlenp, newp, cnvmem); case BIOS_EXTMEM: @@ -354,3 +354,26 @@ bios_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) } /* NOTREACHED */ } + +bios_diskinfo_t * +bios_getdiskinfo(dev) + dev_t dev; +{ + bios_diskinfo_t *pdi; + + for (pdi = bios_diskinfo; pdi->bios_number != -1; pdi++) { + if ((dev & B_MAGICMASK) == B_DEVMAGIC) { /* search by bootdev */ + if (pdi->bsd_dev == dev) + break; + } else { + if (pdi->bios_number == dev) + break; + } + } + + if (pdi->bios_number == -1) + return NULL; + else + return pdi; +} + |