Esempio n. 1
0
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;
}
Esempio n. 2
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);
}
Esempio n. 3
0
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;

}
Esempio n. 4
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(&regs, 0, sizeof(regs));
	regs.AH = 0xc0;
	bioscall(0x15, &regs);

	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;
}
Esempio n. 5
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;
}
Esempio n. 6
0
/*
 * 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);
	}
}
Esempio n. 7
0
/*
 * 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;
	}
}
Esempio n. 8
0
		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.