int k7pnow_states(struct k7pnow_cpu_state *cstate, uint32_t cpusig, unsigned int fid, unsigned int vid) { int maxpst; struct psb_s *psb; struct pst_s *pst; uint8_t *p; /* * Look in the 0xe0000 - 0x100000 physical address * range for the pst tables; 16 byte blocks */ for (p = (u_int8_t *)ISA_HOLE_VADDR(BIOS_START); p < (u_int8_t *)ISA_HOLE_VADDR(BIOS_START + BIOS_LEN); p+= BIOS_STEP) { if (memcmp(p, "AMDK7PNOW!", 10) == 0) { psb = (struct psb_s *)p; if (psb->version != PN7_PSB_VERSION) return 0; cstate->sgtc = psb->ttime * cstate->fsb; if (cstate->sgtc < 100 * cstate->fsb) cstate->sgtc = 100 * cstate->fsb; if (psb->flags & 1) cstate->flags |= PN7_FLAG_DESKTOP_VRM; p += sizeof(struct psb_s); for (maxpst = 0; maxpst < psb->n_pst; maxpst++) { pst = (struct pst_s*) p; if (cpusig == pst->signature && fid == pst->fid && vid == pst->vid) { if (abs(cstate->fsb - pst->fsb) > 5) continue; cstate->n_states = pst->n_states; return (k7pnow_decode_pst(cstate, p + sizeof(struct pst_s), cstate->n_states)); } p += sizeof(struct pst_s) + (2 * pst->n_states); } } } return 0; }
int bus_space_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags, bus_space_handle_t *bshp) { int error; struct extent *ex; /* * Pick the appropriate extent map. */ if (t == X86_BUS_SPACE_IO) { ex = ioport_ex; if (flags & BUS_SPACE_MAP_LINEAR) return (EINVAL); } else if (t == X86_BUS_SPACE_MEM) ex = iomem_ex; else panic("bus_space_map: bad bus space tag"); /* * Before we go any further, let's make sure that this * region is available. */ error = extent_alloc_region(ex, bpa, size, EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0)); if (error) return (error); /* * For I/O space, that's all she wrote. */ if (t == X86_BUS_SPACE_IO) { *bshp = bpa; return (0); } if (bpa >= IOM_BEGIN && (bpa + size) <= IOM_END) { *bshp = (bus_space_handle_t)ISA_HOLE_VADDR(bpa); return(0); } /* * For memory space, map the bus physical address to * a kernel virtual address. */ error = x86_mem_add_mapping(bpa, size, flags, bshp); if (error) { if (extent_free(ex, bpa, size, EX_NOWAIT | (ioport_malloc_safe ? EX_MALLOCOK : 0))) { printf("bus_space_map: pa 0x%lx, size 0x%lx\n", bpa, size); printf("bus_space_map: can't free region\n"); } } return (error); }
int k8pnow_states(struct k8pnow_cpu_state *cstate, uint32_t cpusig, unsigned int fid, unsigned int vid) { struct psb_s *psb; struct pst_s *pst; uint8_t *p; int i; for (p = (u_int8_t *)ISA_HOLE_VADDR(BIOS_START); p < (u_int8_t *)ISA_HOLE_VADDR(BIOS_START + BIOS_LEN); p += BIOS_STEP) { if (memcmp(p, "AMDK7PNOW!", 10) == 0) { psb = (struct psb_s *)p; if (psb->version != PN8_PSB_VERSION) return 0; cstate->vst = psb->ttime; cstate->rvo = PN8_PSB_TO_RVO(psb->reserved); cstate->irt = PN8_PSB_TO_IRT(psb->reserved); cstate->mvs = PN8_PSB_TO_MVS(psb->reserved); cstate->low = PN8_PSB_TO_BATT(psb->reserved); p+= sizeof(struct psb_s); for (i = 0; i < psb->n_pst; ++i) { pst = (struct pst_s *) p; cstate->pll = pst->pll; cstate->n_states = pst->n_states; if (cpusig == pst->cpuid && pst->fid == fid && pst->vid == vid) { return (k8pnow_decode_pst(cstate, p+= sizeof (struct pst_s))); } p += sizeof(struct pst_s) + 2 * cstate->n_states; } } } return 0; }
/* * We can obtain the information about MCA bus presence via * GET CONFIGURATION BIOS call - int 0x15, function 0xc0. * The call returns a pointer to memory place with the configuration block * in es:bx (on AT-compatible, e.g. all we care about, computers). * * Configuration block contains block length (2 bytes), model * number (1 byte), submodel number (1 byte), BIOS revision * (1 byte) and up to 5 feature bytes. We only care about * first feature byte. */ void mca_busprobe(void) { struct bioscallregs regs; struct bios_config *scp; paddr_t paddr; char buf[80]; memset(®s, 0, sizeof(regs)); regs.AH = 0xc0; bioscall(0x15, ®s); if ((regs.EFLAGS & PSL_C) || regs.AH != 0) { aprint_verbose("BIOS CFG: Not supported. Not AT-compatible?\n"); return; } paddr = (regs.ES << 4) + regs.BX; scp = (struct bios_config *)ISA_HOLE_VADDR(paddr); bitmask_snprintf((scp->feature2 << 8) | scp->feature1, "\20" "\01MCA+ISA" "\02MCA" "\03EBDA" "\04WAITEV" "\05KBDINT" "\06RTC" "\07IC2" "\010DMA3B" "\011res" "\012DSTR" "\013n8042" "\014CPUF" "\015MMF" "\016GPDF" "\017KBDF" "\020DMA32\n", buf, sizeof(buf)); aprint_verbose("BIOS CFG: Model-SubM-Rev: %02x-%02x-%02x, 0x%s\n", scp->model, scp->submodel, scp->bios_rev, buf); MCA_system = (scp->feature1 & FEATURE_MCABUS) ? 1 : 0; }
static bool radeon_read_platform_bios(struct radeon_device *rdev) { #if defined(__amd64__) || defined(__i386__) || defined(__loongson__) uint8_t __iomem *bios; bus_size_t size = 256 * 1024; /* ??? */ uint8_t *found = NULL; int i; if (!(rdev->flags & RADEON_IS_IGP)) if (!radeon_card_posted(rdev)) return false; rdev->bios = NULL; #if defined(__loongson__) if (loongson_videobios == NULL) return false; bios = loongson_videobios; #else bios = (u8 *)ISA_HOLE_VADDR(0xc0000); #endif for (i = 0; i + 2 < size; i++) { if (bios[i] == 0x55 && bios[i + 1] == 0xaa) { found = bios + i; break; } } if (found == NULL) { DRM_ERROR("bios size zero or checksum mismatch\n"); return false; } rdev->bios = kmalloc(size, GFP_KERNEL); if (rdev->bios == NULL) return false; memcpy(rdev->bios, found, size); return true; #endif return false; }
/* * Attach the mainbus. */ void mainbus_attach(struct device *parent, struct device *self, void *aux) { union mainbus_attach_args mba; extern void (*setperf_setup)(struct cpu_info *); extern void (*cpusensors_setup)(struct cpu_info *); printf("\n"); #if NBIOS > 0 { mba.mba_bios.ba_name = "bios"; mba.mba_bios.ba_iot = I386_BUS_SPACE_IO; mba.mba_bios.ba_memt = I386_BUS_SPACE_MEM; config_found(self, &mba.mba_bios, mainbus_print); } #endif #if NIPMI > 0 { memset(&mba.mba_iaa, 0, sizeof(mba.mba_iaa)); mba.mba_iaa.iaa_name = "ipmi"; mba.mba_iaa.iaa_iot = I386_BUS_SPACE_IO; mba.mba_iaa.iaa_memt = I386_BUS_SPACE_MEM; if (ipmi_probe(&mba.mba_iaa)) config_found(self, &mba.mba_iaa, mainbus_print); } #endif #if NVMT > 0 if (vmt_probe()) { mba.mba_busname = "vmware"; config_found(self, &mba.mba_busname, mainbus_print); } #endif #if NMPBIOS > 0 if (mpbios_probe(self)) mpbios_scan(self); #endif if ((cpu_info_primary.ci_flags & CPUF_PRESENT) == 0) { struct cpu_attach_args caa; memset(&caa, 0, sizeof(caa)); caa.caa_name = "cpu"; caa.cpu_number = 0; caa.cpu_role = CPU_ROLE_SP; caa.cpu_func = 0; caa.cpu_signature = cpu_id; caa.feature_flags = cpu_feature; config_found(self, &caa, mainbus_print); } #if NAMDMSR > 0 if (amdmsr_probe()) { mba.mba_busname = "amdmsr"; config_found(self, &mba.mba_busname, mainbus_print); } #endif #if NACPI > 0 if (!acpi_hasprocfvs) #endif { if (setperf_setup != NULL) setperf_setup(&cpu_info_primary); } #ifdef MULTIPROCESSOR mp_setperf_init(); #endif if (cpusensors_setup != NULL) cpusensors_setup(&cpu_info_primary); #if NVESABIOS > 0 if (vbeprobe()) { mba.mba_busname = "vesabios"; config_found(self, &mba.mba_busname, NULL); } #endif #if NESM > 0 { memset(&mba.mba_eaa, 0, sizeof(mba.mba_eaa)); mba.mba_eaa.eaa_name = "esm"; mba.mba_eaa.eaa_iot = I386_BUS_SPACE_IO; mba.mba_eaa.eaa_memt = I386_BUS_SPACE_MEM; if (esm_probe(&mba.mba_eaa)) config_found(self, &mba.mba_eaa, mainbus_print); } #endif /* * XXX Note also that the presence of a PCI bus should * XXX _always_ be checked, and if present the bus should be * XXX 'found'. However, because of the structure of the code, * XXX that's not currently possible. */ #if NPCI > 0 if (pci_mode_detect() != 0) { mba.mba_pba.pba_busname = "pci"; mba.mba_pba.pba_iot = I386_BUS_SPACE_IO; mba.mba_pba.pba_memt = I386_BUS_SPACE_MEM; mba.mba_pba.pba_dmat = &pci_bus_dma_tag; mba.mba_pba.pba_domain = pci_ndomains++; mba.mba_pba.pba_bus = 0; mba.mba_pba.pba_bridgetag = NULL; config_found(self, &mba.mba_pba, mainbus_print); } #endif if (!bcmp(ISA_HOLE_VADDR(EISA_ID_PADDR), EISA_ID, EISA_ID_LEN)) { mba.mba_eba.eba_busname = "eisa"; mba.mba_eba.eba_iot = I386_BUS_SPACE_IO; mba.mba_eba.eba_memt = I386_BUS_SPACE_MEM; #if NEISA > 0 mba.mba_eba.eba_dmat = &eisa_bus_dma_tag; #endif config_found(self, &mba.mba_eba, mainbus_print); } if (isa_has_been_seen == 0) { mba.mba_iba.iba_busname = "isa"; mba.mba_iba.iba_iot = I386_BUS_SPACE_IO; mba.mba_iba.iba_memt = I386_BUS_SPACE_MEM; #if NISADMA > 0 mba.mba_iba.iba_dmat = &isa_bus_dma_tag; #endif config_found(self, &mba.mba_iba, mainbus_print); } }
/* * Initialize the BIOS32 interface. */ void bios32_init(void) { #if 0 /* XXXfvdl need to set up compatibility segment for this */ paddr_t entry = 0; void *p; unsigned char cksum; int i; for (p = (void *)ISA_HOLE_VADDR(BIOS32_START); p < (void *)ISA_HOLE_VADDR(BIOS32_END); p += 16) { if (*(int *)p != BIOS32_MAKESIG('_', '3', '2', '_')) continue; cksum = 0; for (i = 0; i < 16; i++) cksum += *(unsigned char *)(p + i); if (cksum != 0) continue; if (*(p + 9) != 1) continue; entry = *(uint32_t *)(p + 4); aprint_verbose("BIOS32 rev. %d found at 0x%lx\n", *(p + 8), entry); if (entry < BIOS32_START || entry >= BIOS32_END) { aprint_error("BIOS32 entry point outside " "allowable range\n"); entry = 0; } break; } if (entry != 0) { bios32_entry.offset = (void *)ISA_HOLE_VADDR(entry); bios32_entry.segment = GSEL(GCODE_SEL, SEL_KPL); } #endif uint8_t *p; int i; /* see if we have SMBIOS extentions */ for (p = ISA_HOLE_VADDR(SMBIOS_START); p < (uint8_t *)ISA_HOLE_VADDR(SMBIOS_END); p+= 16) { struct smbhdr * sh = (struct smbhdr *)p; uint8_t chksum; vaddr_t eva; paddr_t pa, end; if (sh->sig != BIOS32_MAKESIG('_', 'S', 'M', '_')) continue; i = sh->len; for (chksum = 0; i--; ) chksum += p[i]; if (chksum != 0) continue; p += 0x10; if (p[0] != '_' && p[1] != 'D' && p[2] != 'M' && p[3] != 'I' && p[4] != '_') continue; for (chksum = 0, i = 0xf; i--; ) chksum += p[i]; if (chksum != 0) continue; pa = trunc_page(sh->addr); end = round_page(sh->addr + sh->size); eva = uvm_km_alloc(kernel_map, end - pa, 0, UVM_KMF_VAONLY); if (eva == 0) break; smbios_entry.addr = (uint8_t *)(eva + (sh->addr & PGOFSET)); smbios_entry.len = sh->size; smbios_entry.mjr = sh->majrev; smbios_entry.min = sh->minrev; smbios_entry.count = sh->count; for (; pa < end; pa+= NBPG, eva+= NBPG) #ifdef XEN pmap_kenter_ma(eva, pa, VM_PROT_READ, 0); #else pmap_kenter_pa(eva, pa, VM_PROT_READ, 0); #endif pmap_update(pmap_kernel()); aprint_debug("SMBIOS rev. %d.%d @ 0x%lx (%d entries)\n", sh->majrev, sh->minrev, (u_long)sh->addr, sh->count); break; } }
return (0); /* service not found */ entry = ebx + edx; if (entry < BIOS32_START || entry >= BIOS32_END) { aprint_error( "bios32: entry point for service %c%c%c%c is outside " "allowable range\n", service & 0xff, (service >> 8) & 0xff, (service >> 16) & 0xff, (service >> 24) & 0xff); return (0); } e->offset = (void *)ISA_HOLE_VADDR(entry); e->segment = GSEL(GCODE_SEL, SEL_KPL); ei->bei_base = ebx; ei->bei_size = ecx; ei->bei_entry = entry; return (1); } /* * smbios_find_table() takes a caller supplied smbios struct type and * a pointer to a handle (struct smbtable) returning one if the structure * is sucessfully located and zero otherwise. Callers should take care * to initilize the cookie field of the smbtable structure to zero before * the first invocation of this function.