diff options
author | peter <peter@FreeBSD.org> | 2004-09-24 00:42:36 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2004-09-24 00:42:36 +0000 |
commit | 09b56c9832dac675750896f41018db6609e38529 (patch) | |
tree | 62ea625b75642fab67c77ed285a00becff5b43c0 /sys/amd64 | |
parent | 7b666b4137707dee58b6dde684884e3355a5d894 (diff) | |
download | FreeBSD-src-09b56c9832dac675750896f41018db6609e38529.zip FreeBSD-src-09b56c9832dac675750896f41018db6609e38529.tar.gz |
Severely strip down the repocopied i386/bios.c and bios.h files. It turns
out that bios_sigsearch() etc is useful for finding tables in roms.
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/amd64/bios.c | 593 | ||||
-rw-r--r-- | sys/amd64/include/pc/bios.h | 233 |
2 files changed, 3 insertions, 823 deletions
diff --git a/sys/amd64/amd64/bios.c b/sys/amd64/amd64/bios.c index 3bee94f..b34da4d 100644 --- a/sys/amd64/amd64/bios.c +++ b/sys/amd64/amd64/bios.c @@ -29,164 +29,19 @@ __FBSDID("$FreeBSD$"); /* - * Code for dealing with the BIOS in x86 PC systems. + * Subset of the i386 bios support code. We cannot make bios16 nor bios32 + * calls, so we can leave that out. However, searching for bios rom + * signatures can be useful for locating tables, eg: powernow settings. */ -#include "opt_isa.h" - #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/module.h> -#include <sys/bus.h> -#include <sys/pcpu.h> -#include <vm/vm.h> -#include <vm/pmap.h> -#include <machine/md_var.h> -#include <machine/segments.h> -#include <machine/stdarg.h> -#include <machine/vmparam.h> #include <machine/pc/bios.h> -#ifdef DEV_ISA -#include <isa/isavar.h> -#include <isa/pnpreg.h> -#include <isa/pnpvar.h> -#endif #define BIOS_START 0xe0000 #define BIOS_SIZE 0x20000 -/* exported lookup results */ -struct bios32_SDentry PCIbios; - -static struct PnPBIOS_table *PnPBIOStable; - -static u_int bios32_SDCI; - -/* start fairly early */ -static void bios32_init(void *junk); -SYSINIT(bios32, SI_SUB_CPU, SI_ORDER_ANY, bios32_init, NULL); - -/* - * bios32_init - * - * Locate various bios32 entities. - */ -static void -bios32_init(void *junk) -{ - u_long sigaddr; - struct bios32_SDheader *sdh; - struct PnPBIOS_table *pt; - u_int8_t ck, *cv; - int i; - char *p; - - /* - * BIOS32 Service Directory, PCI BIOS - */ - - /* look for the signature */ - if ((sigaddr = bios_sigsearch(0, "_32_", 4, 16, 0)) != 0) { - - /* get a virtual pointer to the structure */ - sdh = (struct bios32_SDheader *)(uintptr_t)BIOS_PADDRTOVADDR(sigaddr); - for (cv = (u_int8_t *)sdh, ck = 0, i = 0; i < (sdh->len * 16); i++) { - ck += cv[i]; - } - /* If checksum is OK, enable use of the entrypoint */ - if ((ck == 0) && (BIOS_START <= sdh->entry ) && - (sdh->entry < (BIOS_START + BIOS_SIZE))) { - bios32_SDCI = BIOS_PADDRTOVADDR(sdh->entry); - if (bootverbose) { - printf("bios32: Found BIOS32 Service Directory header at %p\n", sdh); - printf("bios32: Entry = 0x%x (%x) Rev = %d Len = %d\n", - sdh->entry, bios32_SDCI, sdh->revision, sdh->len); - } - - /* Allow user override of PCI BIOS search */ - if (((p = getenv("machdep.bios.pci")) == NULL) || strcmp(p, "disable")) { - - /* See if there's a PCI BIOS entrypoint here */ - PCIbios.ident.id = 0x49435024; /* PCI systems should have this */ - if (!bios32_SDlookup(&PCIbios) && bootverbose) - printf("pcibios: PCI BIOS entry at 0x%x+0x%x\n", PCIbios.base, PCIbios.entry); - } - if (p != NULL) - freeenv(p); - } else { - printf("bios32: Bad BIOS32 Service Directory\n"); - } - } - - /* - * PnP BIOS - * - * Allow user override of PnP BIOS search - */ - if ((((p = getenv("machdep.bios.pnp")) == NULL) || strcmp(p, "disable")) && - ((sigaddr = bios_sigsearch(0, "$PnP", 4, 16, 0)) != 0)) { - - /* get a virtual pointer to the structure */ - pt = (struct PnPBIOS_table *)(uintptr_t)BIOS_PADDRTOVADDR(sigaddr); - for (cv = (u_int8_t *)pt, ck = 0, i = 0; i < pt->len; i++) { - ck += cv[i]; - } - /* If checksum is OK, enable use of the entrypoint */ - if (ck == 0) { - PnPBIOStable = pt; - if (bootverbose) { - printf("pnpbios: Found PnP BIOS data at %p\n", pt); - printf("pnpbios: Entry = %x:%x Rev = %d.%d\n", - pt->pmentrybase, pt->pmentryoffset, pt->version >> 4, pt->version & 0xf); - if ((pt->control & 0x3) == 0x01) - printf("pnpbios: Event flag at %x\n", pt->evflagaddr); - if (pt->oemdevid != 0) - printf("pnpbios: OEM ID %x\n", pt->oemdevid); - - } - } else { - printf("pnpbios: Bad PnP BIOS data checksum\n"); - } - } - if (p != NULL) - freeenv(p); - if (bootverbose) { - /* look for other know signatures */ - printf("Other BIOS signatures found:\n"); - } -} - -/* - * bios32_SDlookup - * - * Query the BIOS32 Service Directory for the service named in (ent), - * returns nonzero if the lookup fails. The caller must fill in - * (ent->ident), the remainder are populated on a successful lookup. - */ -int -bios32_SDlookup(struct bios32_SDentry *ent) -{ - struct bios_regs args; - - if (bios32_SDCI == 0) - return (1); - - args.eax = ent->ident.id; /* set up arguments */ - args.ebx = args.ecx = args.edx = 0; - bios32(&args, bios32_SDCI, GSEL(GCODE_SEL, SEL_KPL)); - if ((args.eax & 0xff) == 0) { /* success? */ - ent->base = args.ebx; - ent->len = args.ecx; - ent->entry = args.edx; - ent->ventry = BIOS_PADDRTOVADDR(ent->base + ent->entry); - return (0); /* all OK */ - } - return (1); /* failed */ -} - - /* * bios_sigsearch * @@ -236,245 +91,6 @@ bios_sigsearch(u_int32_t start, u_char *sig, int siglen, int paralen, int sigofs return(0); } -/* - * do not staticize, used by bioscall.s - */ -union { - struct { - u_short offset; - u_short segment; - } vec16; - struct { - u_int offset; - u_short segment; - } vec32; -} bioscall_vector; /* bios jump vector */ - -void -set_bios_selectors(struct bios_segments *seg, int flags) -{ - struct soft_segment_descriptor ssd = { - 0, /* segment base address (overwritten) */ - 0, /* length (overwritten) */ - SDT_MEMERA, /* segment type (overwritten) */ - 0, /* priority level */ - 1, /* descriptor present */ - 0, 0, - 1, /* descriptor size (overwritten) */ - 0 /* granularity == byte units */ - }; - union descriptor *p_gdt; - -#ifdef SMP - p_gdt = &gdt[PCPU_GET(cpuid) * NGDT]; -#else - p_gdt = gdt; -#endif - - ssd.ssd_base = seg->code32.base; - ssd.ssd_limit = seg->code32.limit; - ssdtosd(&ssd, &p_gdt[GBIOSCODE32_SEL].sd); - - ssd.ssd_def32 = 0; - if (flags & BIOSCODE_FLAG) { - ssd.ssd_base = seg->code16.base; - ssd.ssd_limit = seg->code16.limit; - ssdtosd(&ssd, &p_gdt[GBIOSCODE16_SEL].sd); - } - - ssd.ssd_type = SDT_MEMRWA; - if (flags & BIOSDATA_FLAG) { - ssd.ssd_base = seg->data.base; - ssd.ssd_limit = seg->data.limit; - ssdtosd(&ssd, &p_gdt[GBIOSDATA_SEL].sd); - } - - if (flags & BIOSUTIL_FLAG) { - ssd.ssd_base = seg->util.base; - ssd.ssd_limit = seg->util.limit; - ssdtosd(&ssd, &p_gdt[GBIOSUTIL_SEL].sd); - } - - if (flags & BIOSARGS_FLAG) { - ssd.ssd_base = seg->args.base; - ssd.ssd_limit = seg->args.limit; - ssdtosd(&ssd, &p_gdt[GBIOSARGS_SEL].sd); - } -} - -extern int vm86pa; -extern void bios16_jmp(void); - -/* - * this routine is really greedy with selectors, and uses 5: - * - * 32-bit code selector: to return to kernel - * 16-bit code selector: for running code - * data selector: for 16-bit data - * util selector: extra utility selector - * args selector: to handle pointers - * - * the util selector is set from the util16 entry in bios16_args, if a - * "U" specifier is seen. - * - * See <machine/pc/bios.h> for description of format specifiers - */ -int -bios16(struct bios_args *args, char *fmt, ...) -{ - char *p, *stack, *stack_top; - va_list ap; - int flags = BIOSCODE_FLAG | BIOSDATA_FLAG; - u_int i, arg_start, arg_end; - pt_entry_t *pte; - pd_entry_t *ptd; - - arg_start = 0xffffffff; - arg_end = 0; - - /* - * Some BIOS entrypoints attempt to copy the largest-case - * argument frame (in order to generalise handling for - * different entry types). If our argument frame is - * smaller than this, the BIOS will reach off the top of - * our constructed stack segment. Pad the top of the stack - * with some garbage to avoid this. - */ - stack = (caddr_t)PAGE_SIZE - 32; - - va_start(ap, fmt); - for (p = fmt; p && *p; p++) { - switch (*p) { - case 'p': /* 32-bit pointer */ - i = va_arg(ap, u_int); - arg_start = min(arg_start, i); - arg_end = max(arg_end, i); - flags |= BIOSARGS_FLAG; - stack -= 4; - break; - - case 'i': /* 32-bit integer */ - i = va_arg(ap, u_int); - stack -= 4; - break; - - case 'U': /* 16-bit selector */ - flags |= BIOSUTIL_FLAG; - /* FALLTHROUGH */ - case 'D': /* 16-bit selector */ - case 'C': /* 16-bit selector */ - stack -= 2; - break; - - case 's': /* 16-bit integer passed as an int */ - i = va_arg(ap, int); - stack -= 2; - break; - - default: - return (EINVAL); - } - } - - if (flags & BIOSARGS_FLAG) { - if (arg_end - arg_start > ctob(16)) - return (EACCES); - args->seg.args.base = arg_start; - args->seg.args.limit = 0xffff; - } - - args->seg.code32.base = (u_int)&bios16_jmp & PG_FRAME; - args->seg.code32.limit = 0xffff; - - ptd = (pd_entry_t *)rcr3(); -#ifdef PAE - if (ptd == IdlePDPT) -#else - if (ptd == IdlePTD) -#endif - { - /* - * no page table, so create one and install it. - */ - pte = (pt_entry_t *)malloc(PAGE_SIZE, M_TEMP, M_WAITOK); - ptd = (pd_entry_t *)((u_int)IdlePTD + KERNBASE); - *pte = (vm86pa - PAGE_SIZE) | PG_RW | PG_V; - *ptd = vtophys(pte) | PG_RW | PG_V; - } else { - /* - * this is a user-level page table - */ - pte = PTmap; - *pte = (vm86pa - PAGE_SIZE) | PG_RW | PG_V; - } - pmap_invalidate_all(kernel_pmap); /* XXX insurance for now */ - - stack_top = stack; - va_start(ap, fmt); - for (p = fmt; p && *p; p++) { - switch (*p) { - case 'p': /* 32-bit pointer */ - i = va_arg(ap, u_int); - *(u_int *)stack = (i - arg_start) | - (GSEL(GBIOSARGS_SEL, SEL_KPL) << 16); - stack += 4; - break; - - case 'i': /* 32-bit integer */ - i = va_arg(ap, u_int); - *(u_int *)stack = i; - stack += 4; - break; - - case 'U': /* 16-bit selector */ - *(u_short *)stack = GSEL(GBIOSUTIL_SEL, SEL_KPL); - stack += 2; - break; - - case 'D': /* 16-bit selector */ - *(u_short *)stack = GSEL(GBIOSDATA_SEL, SEL_KPL); - stack += 2; - break; - - case 'C': /* 16-bit selector */ - *(u_short *)stack = GSEL(GBIOSCODE16_SEL, SEL_KPL); - stack += 2; - break; - - case 's': /* 16-bit integer passed as an int */ - i = va_arg(ap, int); - *(u_short *)stack = i; - stack += 2; - break; - - default: - return (EINVAL); - } - } - - set_bios_selectors(&args->seg, flags); - bioscall_vector.vec16.offset = (u_short)args->entry; - bioscall_vector.vec16.segment = GSEL(GBIOSCODE16_SEL, SEL_KPL); - - i = bios16_call(&args->r, stack_top); - - if (pte == PTmap) { - *pte = 0; /* remove entry */ - /* - * XXX only needs to be invlpg(0) but that doesn't work on the 386 - */ - pmap_invalidate_all(kernel_pmap); - } else { - *ptd = 0; /* remove page table */ - /* - * XXX only needs to be invlpg(0) but that doesn't work on the 386 - */ - pmap_invalidate_all(kernel_pmap); - free(pte, M_TEMP); /* ... and free it */ - } - return (i); -} - const u_char * bios_string(u_int from, u_int to, const u_char *string, int len) { @@ -489,206 +105,3 @@ bios_string(u_int from, u_int to, const u_char *string, int len) return (t); return (NULL); } - -#ifdef DEV_ISA -/* - * PnP BIOS interface; enumerate devices only known to the system - * BIOS and save information about them for later use. - */ - -struct pnp_sysdev -{ - u_int16_t size; - u_int8_t handle; - u_int32_t devid; - u_int8_t type[3]; - u_int16_t attrib; -#define PNPATTR_NODISABLE (1<<0) /* can't be disabled */ -#define PNPATTR_NOCONFIG (1<<1) /* can't be configured */ -#define PNPATTR_OUTPUT (1<<2) /* can be primary output */ -#define PNPATTR_INPUT (1<<3) /* can be primary input */ -#define PNPATTR_BOOTABLE (1<<4) /* can be booted from */ -#define PNPATTR_DOCK (1<<5) /* is a docking station */ -#define PNPATTR_REMOVEABLE (1<<6) /* device is removeable */ -#define PNPATTR_CONFIG_STATIC (0) -#define PNPATTR_CONFIG_DYNAMIC (1) -#define PNPATTR_CONFIG_DYNONLY (3) -#define PNPATTR_CONFIG(a) (((a) >> 7) & 0x3) - /* device-specific data comes here */ - u_int8_t devdata[0]; -} __packed; - -/* We have to cluster arguments within a 64k range for the bios16 call */ -struct pnp_sysdevargs -{ - u_int16_t next; - struct pnp_sysdev node; -}; - -/* - * This function is called after the bus has assigned resource - * locations for a logical device. - */ -static void -pnpbios_set_config(void *arg, struct isa_config *config, int enable) -{ -} - -/* - * Quiz the PnP BIOS, build a list of PNP IDs and resource data. - */ -static void -pnpbios_identify(driver_t *driver, device_t parent) -{ - struct PnPBIOS_table *pt = PnPBIOStable; - struct bios_args args; - struct pnp_sysdev *pd; - struct pnp_sysdevargs *pda; - u_int16_t ndevs, bigdev; - int error, currdev; - u_int8_t *devnodebuf, tag; - u_int32_t *devid, *compid; - int idx, left; - device_t dev; - - /* no PnP BIOS information */ - if (pt == NULL) - return; - - /* Check to see if ACPI is already active. */ - dev = devclass_get_device(devclass_find("acpi"), 0); - if (dev != NULL && device_is_attached(dev)) - return; - - /* get count of PnP devices */ - bzero(&args, sizeof(args)); - args.seg.code16.base = BIOS_PADDRTOVADDR(pt->pmentrybase); - args.seg.code16.limit = 0xffff; /* XXX ? */ - args.seg.data.base = BIOS_PADDRTOVADDR(pt->pmdataseg); - args.seg.data.limit = 0xffff; - args.entry = pt->pmentryoffset; - - if ((error = bios16(&args, PNP_COUNT_DEVNODES, &ndevs, &bigdev)) || (args.r.eax & 0xff)) - printf("pnpbios: error %d/%x getting device count/size limit\n", error, args.r.eax); - ndevs &= 0xff; /* clear high byte garbage */ - if (bootverbose) - printf("pnpbios: %d devices, largest %d bytes\n", ndevs, bigdev); - - devnodebuf = malloc(bigdev + (sizeof(struct pnp_sysdevargs) - sizeof(struct pnp_sysdev)), - M_DEVBUF, M_NOWAIT); - pda = (struct pnp_sysdevargs *)devnodebuf; - pd = &pda->node; - - for (currdev = 0, left = ndevs; (currdev != 0xff) && (left > 0); left--) { - - bzero(pd, bigdev); - pda->next = currdev; - /* get current configuration */ - if ((error = bios16(&args, PNP_GET_DEVNODE, &pda->next, &pda->node, 1))) { - printf("pnpbios: error %d making BIOS16 call\n", error); - break; - } - if ((error = (args.r.eax & 0xff))) { - if (bootverbose) - printf("pnpbios: %s 0x%x fetching node %d\n", error & 0x80 ? "error" : "warning", error, currdev); - if (error & 0x80) - break; - } - currdev = pda->next; - if (pd->size < sizeof(struct pnp_sysdev)) { - printf("pnpbios: bogus system node data, aborting scan\n"); - break; - } - - /* - * Ignore PICs so that we don't have to worry about the PICs - * claiming IRQs to prevent their use. The PIC drivers - * already ensure that invalid IRQs are not used. - */ - if (!strcmp(pnp_eisaformat(pd->devid), "PNP0000")) /* ISA PIC */ - continue; - if (!strcmp(pnp_eisaformat(pd->devid), "PNP0003")) /* APIC */ - continue; - - /* Add the device and parse its resources */ - dev = BUS_ADD_CHILD(parent, ISA_ORDER_PNP, NULL, -1); - isa_set_vendorid(dev, pd->devid); - isa_set_logicalid(dev, pd->devid); - /* - * It appears that some PnP BIOS doesn't allow us to re-enable - * the embedded system device once it is disabled. We shall - * mark all system device nodes as "cannot be disabled", regardless - * of actual settings in the device attribute byte. - * XXX - isa_set_configattr(dev, - ((pd->attrib & PNPATTR_NODISABLE) ? 0 : ISACFGATTR_CANDISABLE) | - ((!(pd->attrib & PNPATTR_NOCONFIG) && - PNPATTR_CONFIG(pd->attrib) != PNPATTR_CONFIG_STATIC) - ? ISACFGATTR_DYNAMIC : 0)); - */ - isa_set_configattr(dev, - (!(pd->attrib & PNPATTR_NOCONFIG) && - PNPATTR_CONFIG(pd->attrib) != PNPATTR_CONFIG_STATIC) - ? ISACFGATTR_DYNAMIC : 0); - ISA_SET_CONFIG_CALLBACK(parent, dev, pnpbios_set_config, 0); - pnp_parse_resources(dev, &pd->devdata[0], - pd->size - sizeof(struct pnp_sysdev), 0); - if (!device_get_desc(dev)) - device_set_desc_copy(dev, pnp_eisaformat(pd->devid)); - - /* Find device IDs */ - devid = &pd->devid; - compid = NULL; - - /* look for a compatible device ID too */ - left = pd->size - sizeof(struct pnp_sysdev); - idx = 0; - while (idx < left) { - tag = pd->devdata[idx++]; - if (PNP_RES_TYPE(tag) == 0) { - /* Small resource */ - switch (PNP_SRES_NUM(tag)) { - case PNP_TAG_COMPAT_DEVICE: - compid = (u_int32_t *)(pd->devdata + idx); - if (bootverbose) - printf("pnpbios: node %d compat ID 0x%08x\n", pd->handle, *compid); - /* FALLTHROUGH */ - case PNP_TAG_END: - idx = left; - break; - default: - idx += PNP_SRES_LEN(tag); - break; - } - } else - /* Large resource, skip it */ - idx += *(u_int16_t *)(pd->devdata + idx) + 2; - } - if (bootverbose) { - printf("pnpbios: handle %d device ID %s (%08x)", - pd->handle, pnp_eisaformat(*devid), *devid); - if (compid != NULL) - printf(" compat ID %s (%08x)", - pnp_eisaformat(*compid), *compid); - printf("\n"); - } - } -} - -static device_method_t pnpbios_methods[] = { - /* Device interface */ - DEVMETHOD(device_identify, pnpbios_identify), - - { 0, 0 } -}; - -static driver_t pnpbios_driver = { - "pnpbios", - pnpbios_methods, - 1, /* no softc */ -}; - -static devclass_t pnpbios_devclass; - -DRIVER_MODULE(pnpbios, isa, pnpbios_driver, pnpbios_devclass, 0, 0); -#endif /* DEV_ISA */ diff --git a/sys/amd64/include/pc/bios.h b/sys/amd64/include/pc/bios.h index c7362a9..8727972 100644 --- a/sys/amd64/include/pc/bios.h +++ b/sys/amd64/include/pc/bios.h @@ -30,245 +30,12 @@ #ifndef _MACHINE_PC_BIOS_H_ #define _MACHINE_PC_BIOS_H_ -/* - * Signature structure for the BIOS32 Service Directory header - */ -struct bios32_SDheader -{ - u_int8_t sig[4]; - u_int32_t entry; - u_int8_t revision; - u_int8_t len; - u_int8_t cksum; - u_int8_t pad[5]; -}; - -/* - * BIOS32 Service Directory entry. Caller supplies name, bios32_SDlookup - * fills in the rest of the details. - */ -struct bios32_SDentry -{ - union - { - u_int8_t name[4]; /* service identifier */ - u_int32_t id; /* as a 32-bit value */ - } ident; - u_int32_t base; /* base of service */ - u_int32_t len; /* service length */ - u_int32_t entry; /* entrypoint offset from base */ - vm_offset_t ventry; /* entrypoint in kernel virtual segment */ -}; - -extern int bios32_SDlookup(struct bios32_SDentry *ent); extern u_int32_t bios_sigsearch(u_int32_t start, u_char *sig, int siglen, int paralen, int sigofs); #define BIOS_PADDRTOVADDR(x) ((x) + KERNBASE) #define BIOS_VADDRTOPADDR(x) ((x) - KERNBASE) - -/* - * PnP BIOS presence structure - */ -struct PnPBIOS_table -{ - u_int8_t sig[4]; /* "$PnP */ - u_int8_t version; /* should be 0x10 */ - u_int8_t len; /* total structure length */ - u_int16_t control; /* BIOS feature flags */ - u_int8_t cksum; /* checksum */ - u_int32_t evflagaddr; /* address of event notificaton flag */ - u_int16_t rmentryoffset; /* real-mode entry offset */ - u_int16_t rmentryseg; /* segment */ - u_int16_t pmentryoffset; /* protected-mode entry offset */ - u_int32_t pmentrybase; /* segment base */ - u_int32_t oemdevid; /* motherboard EISA ID */ - u_int16_t rmbiosseg; /* real-mode BIOS segment */ - u_int32_t pmdataseg; /* protected-mode data segment */ -} __packed; - - -/* - * Exported lookup results - */ -extern struct bios32_SDentry PCIbios; - -struct segment_info { - u_int base; - u_int limit; -}; - -#define BIOSCODE_FLAG 0x01 -#define BIOSDATA_FLAG 0x02 -#define BIOSUTIL_FLAG 0x04 -#define BIOSARGS_FLAG 0x08 - -struct bios_segments { - struct segment_info code32; /* 32-bit code (mandatory) */ - struct segment_info code16; /* 16-bit code */ - struct segment_info data; /* 16-bit data */ - struct segment_info util; /* 16-bit utility */ - struct segment_info args; /* 16-bit args */ -}; - -struct bios_regs { - u_int eax; - u_int ebx; - u_int ecx; - u_int edx; - u_int esi; - u_int edi; -}; - -struct bios_args { - u_int entry; /* entry point of routine */ - struct bios_regs r; - struct bios_segments seg; -}; - -/* - * PnP BIOS return codes - */ -#define PNP_SUCCESS 0x00 -#define PNP_NOT_SET_STATICALLY 0x7f -#define PNP_UNKNOWN_FUNCTION 0x81 -#define PNP_FUNTION_NOT_SUPPORTED 0x82 -#define PNP_INVALID_HANDLE 0x83 -#define PNP_BAD_PARAMETER 0x84 -#define PNP_SET_FAILED 0x85 -#define PNP_EVENTS_NOT_PENDING 0x86 -#define PNP_SYSTEM_NOT_DOCKED 0x87 -#define PNP_NO_ISA_PNP_CARDS 0x88 -#define PNP_UNABLE_TO_DETERMINE_DOCK_CAPABILITIES 0x89 -#define PNP_CONFIG_CHANGE_FAILED_NO_BATTERY 0x8a -#define PNP_CONFIG_CHANGE_FAILED_RESOURCE_CONFLICT 0x8b -#define PNP_BUFFER_TOO_SMALL 0x8c -#define PNP_USE_ESCD_SUPPORT 0x8d -#define PNP_MESSAGE_NOT_SUPPORTED 0x8e -#define PNP_HARDWARE_ERROR 0x8f - -/* - * DMI return codes - */ -#define DMI_SUCCESS 0x00 -#define DMI_UNKNOWN_FUNCTION 0x81 -#define DMI_FUNCTION_NOT_SUPPORTED 0x82 -#define DMI_INVALID_HANDLE 0x83 -#define DMI_BAD_PARAMETER 0x84 -#define DMI_INVALID_SUBFUNCTION 0x85 -#define DMI_NO_CHANGE 0x86 -#define DMI_ADD_STRUCTURE_FAILED 0x87 -#define DMI_READ_ONLY 0x8d -#define DMI_LOCK_NOT_SUPPORTED 0x90 -#define DMI_CURRENTLY_LOCKED 0x91 -#define DMI_INVALID_LOCK 0x92 - -/* - * format specifiers and defines for bios16() - * s = short (16 bits) - * i = int (32 bits) - * p = pointer (converted to seg:offset) - * C,D,U = selector (corresponding to code/data/utility segment) - */ -#define PNP_COUNT_DEVNODES "sppD", 0x00 -#define PNP_GET_DEVNODE "sppsD", 0x01 -#define PNP_SET_DEVNODE "sspsD", 0x02 -#define PNP_GET_EVENT "spD", 0x03 -#define PNP_SEND_MSG "ssD", 0x04 -#define PNP_GET_DOCK_INFO "spD", 0x05 - -#define PNP_SEL_PRIBOOT "ssiiisspD", 0x07 -#define PNP_GET_PRIBOOT "sspppppD", 0x08 -#define PNP_SET_RESINFO "spD", 0x09 -#define PNP_GET_RESINFO "spD", 0x0A -#define PNP_GET_APM_ID "sppD", 0x0B - -#define PNP_GET_ISA_INFO "spD", 0x40 -#define PNP_GET_ECSD_INFO "spppD", 0x41 -#define PNP_READ_ESCD "spUD", 0x42 -#define PNP_WRITE_ESCD "spUD", 0x43 - -#define PNP_GET_DMI_INFO "spppppD", 0x50 -#define PNP_GET_DMI_STRUCTURE "sppUD", 0x51 -#define PNP_SET_DMI_STRUCTURE "sppsUD" 0x52 -#define PNP_GET_DMI_CHANGE "spUD" 0x53 -#define PNP_DMI_CONTROL "sspsUD" 0x54 -#define PNP_GET_GPNV_INFO "sppppD" 0x55 -#define PNP_READ_GPNV_DATA "ssppUD" 0x56 -#define PNP_WRITE_GPNV_DATA "sspsUD" 0x57 - -#define PNP_BOOT_CHECK "sp", 0x60 -#define PNP_COUNT_IPL "sppp", 0x61 -#define PNP_GET_BOOTPRI "spp", 0x62 -#define PNP_SET_BOOTPRI "sp", 0x63 -#define PNP_GET_LASTBOOT "sp", 0x64 -#define PNP_GET_BOOTFIRST "sp", 0x65 -#define PNP_SET_BOOTFIRST "sp", 0x66 - -/* - * PCI BIOS functions - */ -#define PCIBIOS_BIOS_PRESENT 0xb101 -#define PCIBIOS_READ_CONFIG_BYTE 0xb108 -#define PCIBIOS_READ_CONFIG_WORD 0xb109 -#define PCIBIOS_READ_CONFIG_DWORD 0xb10a -#define PCIBIOS_WRITE_CONFIG_BYTE 0xb10b -#define PCIBIOS_WRITE_CONFIG_WORD 0xb10c -#define PCIBIOS_WRITE_CONFIG_DWORD 0xb10d -#define PCIBIOS_GET_IRQ_ROUTING 0xb10e -#define PCIBIOS_ROUTE_INTERRUPT 0xb10f - -extern int bios16(struct bios_args *, char *, ...); -extern int bios16_call(struct bios_regs *, char *); -extern int bios32(struct bios_regs *, u_int, u_short); -extern void set_bios_selectors(struct bios_segments *, int); - -/* - * PCI interrupt routing table. - * - * $PIR in the BIOS segment contains a PIR_table - * int 1a:b106 returns PIR_table in buffer at es:(e)di - * int 1a:b18e returns PIR_table in buffer at es:(e)di - * int 1a:b406 returns es:di pointing to the BIOS PIR_table - */ -struct PIR_header -{ - int8_t ph_signature[4]; - u_int16_t ph_version; - u_int16_t ph_length; - u_int8_t ph_router_bus; - u_int8_t ph_router_dev_fn; - u_int16_t ph_pci_irqs; - u_int16_t ph_router_vendor; - u_int16_t ph_router_device; - u_int32_t ph_miniport; - u_int8_t ph_res[11]; - u_int8_t ph_checksum; -} __packed; - -struct PIR_intpin -{ - u_int8_t link; - u_int16_t irqs; -} __packed; - -struct PIR_entry -{ - u_int8_t pe_bus; - u_int8_t pe_res1:3; - u_int8_t pe_device:5; - struct PIR_intpin pe_intpin[4]; - u_int8_t pe_slot; - u_int8_t pe_res3; -} __packed; - -struct PIR_table -{ - struct PIR_header pt_header; - struct PIR_entry pt_entry[0]; -} __packed; - /* * Int 15:E820 'SMAP' structure * |