Beispiel #1
0
/* 
 * 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);
}
Beispiel #2
0
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;
}
Beispiel #3
0
// 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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
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);
}
Beispiel #7
0
/*
 * 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 {