Example #1
0
void
smbios_detect(void)
{
	char            buf[16];
	caddr_t         addr, dmi, smbios;
	size_t          count, length;
	uint32_t        paddr;
	int             i, major, minor, ver;
	
	/* Search signatures and validate checksums. */
	smbios = smbios_sigsearch(PTOV(SMBIOS_START), SMBIOS_LENGTH);
	if (smbios == NULL)
		return;
	
	length = SMBIOS_GET16(smbios, 0x16);    /* Structure Table Length */
	paddr = SMBIOS_GET32(smbios, 0x18);     /* Structure Table Address */
	count = SMBIOS_GET16(smbios, 0x1c);     /* No of SMBIOS Structures */
	ver = SMBIOS_GET8(smbios, 0x1e);        /* SMBIOS BCD Revision */
	
	if (ver != 0) {
		major = ver >> 4;
		minor = ver & 0x0f;
		if (major > 9 || minor > 9)
			ver = 0;
	}
Example #2
0
static void
smbios_probe(const caddr_t addr)
{
    caddr_t		saddr, info;
    uintptr_t	paddr;

    if (smbios.probed)
        return;
    smbios.probed = 1;

    /* Search signatures and validate checksums. */
    saddr = smbios_sigsearch(addr ? addr : PTOV(SMBIOS_START),
                             SMBIOS_LENGTH);
    if (saddr == NULL)
        return;

    smbios.length = SMBIOS_GET16(saddr, 0x16);	/* Structure Table Length */
    paddr = SMBIOS_GET32(saddr, 0x18);		/* Structure Table Address */
    smbios.count = SMBIOS_GET16(saddr, 0x1c);	/* No of SMBIOS Structures */
    smbios.ver = SMBIOS_GET8(saddr, 0x1e);		/* SMBIOS BCD Revision */

    if (smbios.ver != 0) {
        smbios.major = smbios.ver >> 4;
        smbios.minor = smbios.ver & 0x0f;
        if (smbios.major > 9 || smbios.minor > 9)
            smbios.ver = 0;
    }
Example #3
0
static void
smbios_setuuid(const char *name, const caddr_t addr, const int ver)
{
    char		uuid[37];
    int		byteorder, i, ones, zeros;
    UUID_TYPE	n;
    uint32_t	f1;
    uint16_t	f2, f3;

    for (i = 0, ones = 0, zeros = 0; i < UUID_SIZE; i += UUID_STEP) {
        n = UUID_GET(addr, i) + 1;
        if (zeros == 0 && n == 0)
            ones++;
        else if (ones == 0 && n == 1)
            zeros++;
        else
            break;
    }

    if (ones != UUID_ALL_BITS && zeros != UUID_ALL_BITS) {
        /*
         * 3.3.2.1 System UUID
         *
         * "Although RFC 4122 recommends network byte order for all
         * fields, the PC industry (including the ACPI, UEFI, and
         * Microsoft specifications) has consistently used
         * little-endian byte encoding for the first three fields:
         * time_low, time_mid, time_hi_and_version. The same encoding,
         * also known as wire format, should also be used for the
         * SMBIOS representation of the UUID."
         *
         * Note: We use network byte order for backward compatibility
         * unless SMBIOS version is 2.6+ or little-endian is forced.
         */
#if defined(SMBIOS_LITTLE_ENDIAN_UUID)
        byteorder = LITTLE_ENDIAN;
#elif defined(SMBIOS_NETWORK_ENDIAN_UUID)
        byteorder = BIG_ENDIAN;
#else
        byteorder = ver < 0x0206 ? BIG_ENDIAN : LITTLE_ENDIAN;
#endif
        if (byteorder != LITTLE_ENDIAN) {
            f1 = ntohl(SMBIOS_GET32(addr, 0));
            f2 = ntohs(SMBIOS_GET16(addr, 4));
            f3 = ntohs(SMBIOS_GET16(addr, 6));
        } else {
            f1 = le32toh(SMBIOS_GET32(addr, 0));
            f2 = le16toh(SMBIOS_GET16(addr, 4));
            f3 = le16toh(SMBIOS_GET16(addr, 6));
        }
        sprintf(uuid,
                "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
                f1, f2, f3, SMBIOS_GET8(addr, 8), SMBIOS_GET8(addr, 9),
                SMBIOS_GET8(addr, 10), SMBIOS_GET8(addr, 11),
                SMBIOS_GET8(addr, 12), SMBIOS_GET8(addr, 13),
                SMBIOS_GET8(addr, 14), SMBIOS_GET8(addr, 15));
        setenv(name, uuid, 1);
    }
}
Example #4
0
static caddr_t
smbios_find_struct(int type)
{
    caddr_t		dmi;
    size_t		i;

    if (smbios.addr == NULL)
        return (NULL);

    for (dmi = smbios.addr, i = 0;
            dmi < smbios.addr + smbios.length && i < smbios.count; i++) {
        if (SMBIOS_GET8(dmi, 0) == type)
            return dmi;
        /* Find structure terminator. */
        dmi = SMBIOS_GETSTR(dmi);
        while (SMBIOS_GET16(dmi, 0) != 0)
            dmi++;
        dmi += 2;
    }

    return (NULL);
}
Example #5
0
static caddr_t
smbios_parse_table(const caddr_t addr)
{
    caddr_t		cp;
    int		proc, size, osize, type;

    type = SMBIOS_GET8(addr, 0);	/* 3.1.2 Structure Header Format */
    switch(type) {
    case 0:		/* 3.3.1 BIOS Information (Type 0) */
        smbios_setenv("smbios.bios.vendor", addr, 0x04);
        smbios_setenv("smbios.bios.version", addr, 0x05);
        smbios_setenv("smbios.bios.reldate", addr, 0x08);
        break;

    case 1:		/* 3.3.2 System Information (Type 1) */
        smbios_setenv("smbios.system.maker", addr, 0x04);
        smbios_setenv("smbios.system.product", addr, 0x05);
        smbios_setenv("smbios.system.version", addr, 0x06);
#ifdef SMBIOS_SERIAL_NUMBERS
        smbios_setenv("smbios.system.serial", addr, 0x07);
        smbios_setuuid("smbios.system.uuid", addr + 0x08, smbios.ver);
#endif
        if (smbios.major > 2 ||
                (smbios.major == 2 && smbios.minor >= 4)) {
            smbios_setenv("smbios.system.sku", addr, 0x19);
            smbios_setenv("smbios.system.family", addr, 0x1a);
        }
        break;

    case 2:		/* 3.3.3 Base Board (or Module) Information (Type 2) */
        smbios_setenv("smbios.planar.maker", addr, 0x04);
        smbios_setenv("smbios.planar.product", addr, 0x05);
        smbios_setenv("smbios.planar.version", addr, 0x06);
#ifdef SMBIOS_SERIAL_NUMBERS
        smbios_setenv("smbios.planar.serial", addr, 0x07);
        smbios_setenv("smbios.planar.tag", addr, 0x08);
#endif
        smbios_setenv("smbios.planar.location", addr, 0x0a);
        break;

    case 3:		/* 3.3.4 System Enclosure or Chassis (Type 3) */
        smbios_setenv("smbios.chassis.maker", addr, 0x04);
        smbios_setenv("smbios.chassis.version", addr, 0x06);
#ifdef SMBIOS_SERIAL_NUMBERS
        smbios_setenv("smbios.chassis.serial", addr, 0x07);
        smbios_setenv("smbios.chassis.tag", addr, 0x08);
#endif
        break;

    case 4:		/* 3.3.5 Processor Information (Type 4) */
        /*
         * Offset 18h: Processor Status
         *
         * Bit 7	Reserved, must be 0
         * Bit 6	CPU Socket Populated
         *		1 - CPU Socket Populated
         *		0 - CPU Socket Unpopulated
         * Bit 5:3	Reserved, must be zero
         * Bit 2:0	CPU Status
         *		0h - Unknown
         *		1h - CPU Enabled
         *		2h - CPU Disabled by User via BIOS Setup
         *		3h - CPU Disabled by BIOS (POST Error)
         *		4h - CPU is Idle, waiting to be enabled
         *		5-6h - Reserved
         *		7h - Other
         */
        proc = SMBIOS_GET8(addr, 0x18);
        if ((proc & 0x07) == 1)
            smbios.enabled_sockets++;
        if ((proc & 0x40) != 0)
            smbios.populated_sockets++;
        break;

    case 6:		/* 3.3.7 Memory Module Information (Type 6, Obsolete) */
        /*
         * Offset 0Ah: Enabled Size
         *
         * Bit 7	Bank connection
         *		1 - Double-bank connection
         *		0 - Single-bank connection
         * Bit 6:0	Size (n), where 2**n is the size in MB
         *		7Dh - Not determinable (Installed Size only)
         *		7Eh - Module is installed, but no memory
         *		      has been enabled
         *		7Fh - Not installed
         */
        osize = SMBIOS_GET8(addr, 0x0a) & 0x7f;
        if (osize > 0 && osize < 22)
            smbios.old_enabled_memory += 1 << (osize + 10);
        break;

    case 17:	/* 3.3.18 Memory Device (Type 17) */
        /*
         * Offset 0Ch: Size
         *
         * Bit 15	Granularity
         *		1 - Value is in kilobytes units
         *		0 - Value is in megabytes units
         * Bit 14:0	Size
         */
        size = SMBIOS_GET16(addr, 0x0c);
        if (size != 0 && size != 0xffff)
            smbios.enabled_memory += (size & 0x8000) != 0 ?
                                     (size & 0x7fff) : (size << 10);
        break;

    default:	/* skip other types */
        break;
    }

    /* Find structure terminator. */
    cp = SMBIOS_GETSTR(addr);
    while (SMBIOS_GET16(cp, 0) != 0)
        cp++;

    return (cp + 2);
}