/* * Initialise access to PCI configuration space */ int pci_cfgregopen(void) { static int opened = 0; u_long sigaddr; static struct PIR_table *pt; u_int8_t ck, *cv; int i; if (opened) return(1); if (pcibios_cfgopen() != 0) usebios = 1; else if (pcireg_cfgopen() != 0) usebios = 0; else return(0); /* * Look for the interrupt routing table. * * We use PCI BIOS's PIR table if it's available $PIR is the * standard way to do this. Sadly, some machines are not * standards conforming and have _PIR instead. We shrug and cope * by looking for both. */ if (pcibios_get_version() >= 0x0210 && pt == NULL) { sigaddr = bios_sigsearch(0, "$PIR", 4, 16, 0); if (sigaddr == 0) sigaddr = bios_sigsearch(0, "_PIR", 4, 16, 0); if (sigaddr != 0) { pt = (struct PIR_table *)(uintptr_t) BIOS_PADDRTOVADDR(sigaddr); for (cv = (u_int8_t *)pt, ck = 0, i = 0; i < (pt->pt_header.ph_length); i++) { ck += cv[i]; } if (ck == 0 && pt->pt_header.ph_length > sizeof(struct PIR_header)) { pci_route_table = pt; pci_route_count = (pt->pt_header.ph_length - sizeof(struct PIR_header)) / sizeof(struct PIR_entry); printf("Using $PIR table, %d entries at %p\n", pci_route_count, pci_route_table); if (bootverbose) pci_print_route_table(pci_route_table, pci_route_count); } } } opened = 1; return(1); }
static void smapi_identify (driver_t *driver, device_t parent) { device_t child; u_int32_t addr; int length; int rid; if (!device_is_alive(parent)) return; addr = bios_sigsearch(SMAPI_START, SMAPI_SIG, SMAPI_LEN, SMAPI_STEP, SMAPI_OFF); if (addr != 0) { rid = 0; length = ADDR2HDR(addr)->length; child = BUS_ADD_CHILD(parent, 5, "smapi", -1); device_set_driver(child, driver); bus_set_resource(child, SYS_RES_MEMORY, rid, addr, length); device_set_desc(child, "SMAPI BIOS"); } return; }
// Returns 0 or virtual adress of smbios static struct smbios_eps * smbios_identify() { u_int32_t addr; int length; int rid; addr = bios_sigsearch(SMBIOS_START, (unsigned char *)SMBIOS_SIG, SMBIOS_LEN, SMBIOS_STEP, SMBIOS_OFF); if (addr == 0) return 0; rid = 0; struct smbios_eps *ep = ADDR2EPS(addr); length = ep->Length; if (length != 0x1f) { u_int8_t major, minor; major = ep->SMBIOS_Major; minor = ep->SMBIOS_Minor; /* SMBIOS v2.1 implementation might use 0x1e. */ if (length == 0x1e && major == 2 && minor == 1) length = 0x1f; else return 0; } /* child = BUS_ADD_CHILD(parent, 5, "smbios", -1); device_set_driver(child, driver); bus_set_resource(child, SYS_RES_MEMORY, rid, addr, length); device_set_desc(child, "System Management BIOS"); */ return ep; }
static void vpd_identify (driver_t *driver, device_t parent) { device_t child; u_int32_t addr; int length; int rid; if (!device_is_alive(parent)) return; addr = bios_sigsearch(VPD_START, VPD_SIG, VPD_LEN, VPD_STEP, VPD_OFF); if (addr != 0) { rid = 0; length = ADDR2VPD(addr)->Length; child = BUS_ADD_CHILD(parent, 5, "vpd", -1); device_set_driver(child, driver); bus_set_resource(child, SYS_RES_MEMORY, rid, addr, length); device_set_desc(child, "Vital Product Data Area"); } return; }
static int smbios_find_eps(void) { uintptr_t addr; u_int8_t major, minor; if (smbios_eps == 0xffff) return 0; /* already set */ if (smbios_eps > 0) return 1; addr = bios_sigsearch(SMBIOS_START, SMBIOS_SIG, SMBIOS_LEN, SMBIOS_STEP, SMBIOS_OFF); if (addr != 0) { smbios_eps = BIOS_PADDRTOVADDR(addr); if (smbios_cksum(smbios_eps)) { printf("SMBIOS checksum failed.\n"); smbios_eps = 0xffff; return 0; } else { printf("SMBIOS found\n"); major = *((u_int8_t *)(smbios_eps + 0x6)); minor = *((u_int8_t *)(smbios_eps + 0x7)); printf("SMBIOS %i.%i found\n", major, minor); return 1; } } printf("SMBIOS Signature not found\n"); smbios_eps = 0xffff; return 0; }
static int pn_decode_pst(device_t dev) { int maxpst; struct pn_softc *sc; u_int cpuid, maxfid, startvid; u_long sig; struct psb_header *psb; uint8_t *p; u_int regs[4]; uint64_t status; sc = device_get_softc(dev); do_cpuid(0x80000001, regs); cpuid = regs[0]; if ((cpuid & 0xfff) == 0x760) sc->errata |= A0_ERRATA; status = rdmsr(MSR_AMDK7_FIDVID_STATUS); switch (sc->pn_type) { case PN7_TYPE: maxfid = PN7_STA_MFID(status); startvid = PN7_STA_SVID(status); break; case PN8_TYPE: maxfid = PN8_STA_MFID(status); /* * we should actually use a variable named 'maxvid' if K8, * but why introducing a new variable for that? */ startvid = PN8_STA_MVID(status); break; default: return (ENODEV); } if (bootverbose) { device_printf(dev, "STATUS: 0x%jx\n", status); device_printf(dev, "STATUS: maxfid: 0x%02x\n", maxfid); device_printf(dev, "STATUS: %s: 0x%02x\n", sc->pn_type == PN7_TYPE ? "startvid" : "maxvid", startvid); } sig = bios_sigsearch(PSB_START, PSB_SIG, PSB_LEN, PSB_STEP, PSB_OFF); if (sig) { struct pst_header *pst; psb = (struct psb_header*)(uintptr_t)BIOS_PADDRTOVADDR(sig); switch (psb->version) { default: return (ENODEV); case 0x14: /* * We can't be picky about numpst since at least * some systems have a value of 1 and some have 2. * We trust that cpuid_is_k7() will be better at * catching that we're on a K8 anyway. */ if (sc->pn_type != PN8_TYPE) return (EINVAL); sc->vst = psb->settlingtime; sc->rvo = PN8_PSB_TO_RVO(psb->res1), sc->irt = PN8_PSB_TO_IRT(psb->res1), sc->mvs = PN8_PSB_TO_MVS(psb->res1), sc->low = PN8_PSB_TO_BATT(psb->res1); if (bootverbose) { device_printf(dev, "PSB: VST: %d\n", psb->settlingtime); device_printf(dev, "PSB: RVO %x IRT %d " "MVS %d BATT %d\n", sc->rvo, sc->irt, sc->mvs, sc->low); } break; case 0x12: if (sc->pn_type != PN7_TYPE) return (EINVAL); sc->sgtc = psb->settlingtime * sc->fsb; if (sc->sgtc < 100 * sc->fsb) sc->sgtc = 100 * sc->fsb; break; } p = ((uint8_t *) psb) + sizeof(struct psb_header); pst = (struct pst_header*) p; maxpst = 200; do { struct pst_header *pst = (struct pst_header*) p; if (cpuid == pst->cpuid && maxfid == pst->maxfid && startvid == pst->startvid) { sc->powernow_max_states = pst->numpstates; switch (sc->pn_type) { case PN7_TYPE: if (abs(sc->fsb - pst->fsb) > 5) continue; break; case PN8_TYPE: break; } return (decode_pst(sc, p + sizeof(struct pst_header), sc->powernow_max_states)); } p += sizeof(struct pst_header) + (2 * pst->numpstates); } while (cpuid_is_k7(pst->cpuid) && maxpst--); device_printf(dev, "no match for extended cpuid %.3x\n", cpuid); } return (ENODEV); }
/* * 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 {