Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 20 Jul 2015 22:14:56 +0000 (UTC)
From:      Allan Jude <allanjude@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r285726 - in stable/10/sys/boot: amd64/efi i386/libi386 i386/loader
Message-ID:  <201507202214.t6KMEuYH086343@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: allanjude (doc committer)
Date: Mon Jul 20 22:14:55 2015
New Revision: 285726
URL: https://svnweb.freebsd.org/changeset/base/285726

Log:
  MFC: r277949:
  	New function smbios_match to detect BIOS versions during boot
  
  MFC: r277957:
  	Fix order of functions in smbios.c (corrects r277949)
  
  MFC: r281138:
  	SMBIOS support for EFI
  
  r281138 makes changes to the new unified EFI loader (r280950), which has not been merged to stable/10 (and likely won't be).
  These changes were manually applied to the amd64 EFI loader (sys/boot/amd64/efi).
  The changes to sys/boot/amd64/efi are a direct commit.
  
  Reviewed by:	stas
  Approved by:	re (gjb), marcel
  Sponsored by:	ScaleEngine Inc.
  Differential Revision:	https://reviews.freebsd.org/D3129

Added:
  stable/10/sys/boot/i386/libi386/smbios.h
     - copied unchanged from r281138, head/sys/boot/i386/libi386/smbios.h
Modified:
  stable/10/sys/boot/amd64/efi/Makefile
  stable/10/sys/boot/amd64/efi/main.c
  stable/10/sys/boot/i386/libi386/libi386.h
  stable/10/sys/boot/i386/libi386/smbios.c
  stable/10/sys/boot/i386/loader/main.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/boot/amd64/efi/Makefile
==============================================================================
--- stable/10/sys/boot/amd64/efi/Makefile	Mon Jul 20 21:52:05 2015	(r285725)
+++ stable/10/sys/boot/amd64/efi/Makefile	Mon Jul 20 22:14:55 2015	(r285726)
@@ -22,6 +22,7 @@ SRCS=	autoload.c \
 	framebuffer.c \
 	main.c \
 	reloc.c \
+	smbios.c \
 	vers.c
 SRCS+=	amd64_tramp.S \
 	start.S
@@ -32,6 +33,8 @@ CFLAGS+=	-I${.CURDIR}/../../efi/include
 CFLAGS+=	-I${.CURDIR}/../../efi/include/${MACHINE_CPUARCH}
 CFLAGS+=	-I${.CURDIR}/../../../contrib/dev/acpica/include
 CFLAGS+=	-I${.CURDIR}/../../..
+CFLAGS+=	-I${.CURDIR}/../../i386/libi386
+CFLAGS+=	-DNO_PCI -DEFI
 
 .if ${MK_FORTH} != "no"
 BOOT_FORTH=	yes
@@ -50,6 +53,8 @@ CFLAGS+=	-DEFI_STAGING_SIZE=${EFI_STAGIN
 
 # Always add MI sources 
 .PATH:		${.CURDIR}/../../common
+# For smbios.c
+.PATH:		${.CURDIR}/../../i386/libi386
 .include	"${.CURDIR}/../../common/Makefile.inc"
 CFLAGS+=	-I${.CURDIR}/../../common
 

Modified: stable/10/sys/boot/amd64/efi/main.c
==============================================================================
--- stable/10/sys/boot/amd64/efi/main.c	Mon Jul 20 21:52:05 2015	(r285725)
+++ stable/10/sys/boot/amd64/efi/main.c	Mon Jul 20 22:14:55 2015	(r285726)
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
 #include <efilib.h>
 
 #include <bootstrap.h>
+#include <smbios.h>
 #include "x86_efi.h"
 
 extern char bootprog_name[];
@@ -59,6 +60,7 @@ main(int argc, CHAR16 *argv[])
 {
 	char vendor[128];
 	EFI_LOADED_IMAGE *img;
+	EFI_GUID *guid;
 	int i;
 
 	/*
@@ -124,6 +126,14 @@ main(int argc, CHAR16 *argv[])
 	archsw.arch_copyout = x86_efi_copyout;
 	archsw.arch_readin = x86_efi_readin;
 
+	for (i = 0; i < ST->NumberOfTableEntries; i++) {
+		guid = &ST->ConfigurationTable[i].VendorGuid;
+		if (!memcmp(guid, &smbios, sizeof(EFI_GUID))) {
+			smbios_detect(ST->ConfigurationTable[i].VendorTable);
+			break;
+		}
+	}
+
 	interact();			/* doesn't return */
 
 	return (EFI_SUCCESS);		/* keep compiler happy */

Modified: stable/10/sys/boot/i386/libi386/libi386.h
==============================================================================
--- stable/10/sys/boot/i386/libi386/libi386.h	Mon Jul 20 21:52:05 2015	(r285725)
+++ stable/10/sys/boot/i386/libi386/libi386.h	Mon Jul 20 22:14:55 2015	(r285726)
@@ -110,8 +110,6 @@ uint32_t biospci_locator(int8_t bus, uin
 
 void	biosacpi_detect(void);
 
-void	smbios_detect(void);
-
 int	i386_autoload(void);
 
 int	bi_getboothowto(char *kargs);

Modified: stable/10/sys/boot/i386/libi386/smbios.c
==============================================================================
--- stable/10/sys/boot/i386/libi386/smbios.c	Mon Jul 20 21:52:05 2015	(r285725)
+++ stable/10/sys/boot/i386/libi386/smbios.c	Mon Jul 20 22:14:55 2015	(r285726)
@@ -31,8 +31,13 @@ __FBSDID("$FreeBSD$");
 #include <bootstrap.h>
 #include <sys/endian.h>
 
+#ifdef EFI
+/* In EFI, we don't need PTOV(). */
+#define PTOV(x)		(caddr_t)(x)
+#else
 #include "btxv86.h"
-#include "libi386.h"
+#endif
+#include "smbios.h"
 
 /*
  * Detect SMBIOS and export information about the SMBIOS into the
@@ -64,10 +69,24 @@ __FBSDID("$FreeBSD$");
 #define	SMBIOS_GETLEN(base)	SMBIOS_GET8(base, 0x01)
 #define	SMBIOS_GETSTR(base)	((base) + SMBIOS_GETLEN(base))
 
-static uint32_t	smbios_enabled_memory = 0;
-static uint32_t	smbios_old_enabled_memory = 0;
-static uint8_t	smbios_enabled_sockets = 0;
-static uint8_t	smbios_populated_sockets = 0;
+struct smbios_attr {
+	int		probed;
+	caddr_t 	addr;
+	size_t		length;
+	size_t		count;
+	int		major;
+	int		minor;
+	int		ver;
+	const char*	bios_vendor;
+	const char*	maker;
+	const char*	product;
+	uint32_t	enabled_memory;
+	uint32_t	old_enabled_memory;
+	uint8_t		enabled_sockets;
+	uint8_t		populated_sockets;
+};
+
+static struct smbios_attr smbios;
 
 static uint8_t
 smbios_checksum(const caddr_t addr, const uint8_t len)
@@ -95,8 +114,8 @@ smbios_sigsearch(const caddr_t addr, con
 	return (NULL);
 }
 
-static void
-smbios_setenv(const char *name, caddr_t addr, const int offset)
+static const char*
+smbios_getstring(caddr_t addr, const int offset)
 {
 	caddr_t		cp;
 	int		i, idx;
@@ -106,8 +125,19 @@ smbios_setenv(const char *name, caddr_t 
 		cp = SMBIOS_GETSTR(addr);
 		for (i = 1; i < idx; i++)
 			cp += strlen(cp) + 1;
-		setenv(name, cp, 1);
+		return cp;
 	}
+	return (NULL);
+}
+
+static void
+smbios_setenv(const char *name, caddr_t addr, const int offset)
+{
+	const char*	val;
+
+	val = smbios_getstring(addr, offset);
+	if (val != NULL)
+		setenv(name, val, 1);
 }
 
 #ifdef SMBIOS_SERIAL_NUMBERS
@@ -183,7 +213,7 @@ smbios_setuuid(const char *name, const c
 #endif
 
 static caddr_t
-smbios_parse_table(const caddr_t addr, const int ver)
+smbios_parse_table(const caddr_t addr)
 {
 	caddr_t		cp;
 	int		proc, size, osize, type;
@@ -202,7 +232,7 @@ smbios_parse_table(const caddr_t addr, c
 		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, ver);
+		smbios_setuuid("smbios.system.uuid", addr + 0x08, smbios.ver);
 #endif
 		break;
 
@@ -244,9 +274,9 @@ smbios_parse_table(const caddr_t addr, c
 		 */
 		proc = SMBIOS_GET8(addr, 0x18);
 		if ((proc & 0x07) == 1)
-			smbios_enabled_sockets++;
+			smbios.enabled_sockets++;
 		if ((proc & 0x40) != 0)
-			smbios_populated_sockets++;
+			smbios.populated_sockets++;
 		break;
 
 	case 6:		/* 3.3.7 Memory Module Information (Type 6, Obsolete) */
@@ -264,7 +294,7 @@ smbios_parse_table(const caddr_t addr, c
 		 */
 		osize = SMBIOS_GET8(addr, 0x0a) & 0x7f;
 		if (osize > 0 && osize < 22)
-			smbios_old_enabled_memory += 1 << (osize + 10);
+			smbios.old_enabled_memory += 1 << (osize + 10);
 		break;
 
 	case 17:	/* 3.3.18 Memory Device (Type 17) */
@@ -278,7 +308,7 @@ smbios_parse_table(const caddr_t addr, c
 		 */
 		size = SMBIOS_GET16(addr, 0x0c);
 		if (size != 0 && size != 0xffff)
-			smbios_enabled_memory += (size & 0x8000) != 0 ?
+			smbios.enabled_memory += (size & 0x8000) != 0 ?
 			    (size & 0x7fff) : (size << 10);
 		break;
 
@@ -294,54 +324,120 @@ smbios_parse_table(const caddr_t addr, c
 	return (cp + 2);
 }
 
+static caddr_t
+smbios_find_struct(int type)
+{
+	caddr_t		dmi;
+	int		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);
+}
+
+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;
+	}
+	if (smbios.ver == 0) {
+		smbios.major = SMBIOS_GET8(saddr, 0x06);/* SMBIOS Major Version */
+		smbios.minor = SMBIOS_GET8(saddr, 0x07);/* SMBIOS Minor Version */
+	}
+	smbios.ver = (smbios.major << 8) | smbios.minor;
+	smbios.addr = PTOV(paddr);
+
+	/* Get system information from SMBIOS */
+	info = smbios_find_struct(0x00);
+	if (info != NULL) {
+		smbios.bios_vendor = smbios_getstring(info, 0x04);
+	}
+	info = smbios_find_struct(0x01);
+	if (info != NULL) {
+		smbios.maker = smbios_getstring(info, 0x04);
+		smbios.product = smbios_getstring(info, 0x05);
+	}
+}
+
 void
-smbios_detect(void)
+smbios_detect(const caddr_t addr)
 {
 	char		buf[16];
-	caddr_t		addr, dmi, smbios;
-	size_t		count, length;
-	uint32_t	paddr;
-	int		i, major, minor, ver;
+	caddr_t		dmi;
+	int		i;
 
-	/* Search signatures and validate checksums. */
-	smbios = smbios_sigsearch(PTOV(SMBIOS_START), SMBIOS_LENGTH);
-	if (smbios == NULL)
+	smbios_probe(addr);
+	if (smbios.addr == 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;
-	}
-	if (ver == 0) {
-		major = SMBIOS_GET8(smbios, 0x06); /* SMBIOS Major Version */
-		minor = SMBIOS_GET8(smbios, 0x07); /* SMBIOS Minor Version */
-	}
-	ver = (major << 8) | minor;
-
-	addr = PTOV(paddr);
-	for (dmi = addr, i = 0; dmi < addr + length && i < count; i++)
-		dmi = smbios_parse_table(dmi, ver);
+	for (dmi = smbios.addr, i = 0;
+	     dmi < smbios.addr + smbios.length && i < smbios.count; i++)
+		dmi = smbios_parse_table(dmi);
 
-	sprintf(buf, "%d.%d", major, minor);
+	sprintf(buf, "%d.%d", smbios.major, smbios.minor);
 	setenv("smbios.version", buf, 1);
-	if (smbios_enabled_memory > 0 || smbios_old_enabled_memory > 0) {
-		sprintf(buf, "%u", smbios_enabled_memory > 0 ?
-		    smbios_enabled_memory : smbios_old_enabled_memory);
+	if (smbios.enabled_memory > 0 || smbios.old_enabled_memory > 0) {
+		sprintf(buf, "%u", smbios.enabled_memory > 0 ?
+		    smbios.enabled_memory : smbios.old_enabled_memory);
 		setenv("smbios.memory.enabled", buf, 1);
 	}
-	if (smbios_enabled_sockets > 0) {
-		sprintf(buf, "%u", smbios_enabled_sockets);
+	if (smbios.enabled_sockets > 0) {
+		sprintf(buf, "%u", smbios.enabled_sockets);
 		setenv("smbios.socket.enabled", buf, 1);
 	}
-	if (smbios_populated_sockets > 0) {
-		sprintf(buf, "%u", smbios_populated_sockets);
+	if (smbios.populated_sockets > 0) {
+		sprintf(buf, "%u", smbios.populated_sockets);
 		setenv("smbios.socket.populated", buf, 1);
 	}
 }
+
+static int
+smbios_match_str(const char* s1, const char* s2)
+{
+	return (s1 == NULL || (s2 != NULL && !strcmp(s1, s2)));
+}
+
+int
+smbios_match(const char* bios_vendor, const char* maker,
+    const char* product)
+{
+	/* XXXRP currently, only called from non-EFI. */
+	smbios_probe(NULL);
+	return (smbios_match_str(bios_vendor, smbios.bios_vendor) &&
+	    smbios_match_str(maker, smbios.maker) &&
+	    smbios_match_str(product, smbios.product));
+}

Copied: stable/10/sys/boot/i386/libi386/smbios.h (from r281138, head/sys/boot/i386/libi386/smbios.h)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/10/sys/boot/i386/libi386/smbios.h	Mon Jul 20 22:14:55 2015	(r285726, copy of r281138, head/sys/boot/i386/libi386/smbios.h)
@@ -0,0 +1,34 @@
+/*-
+ * Copyright (c) 2015 Rui Paulo <rpaulo@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifndef _SMBIOS_H_
+#define	_SMBIOS_H_
+
+void	smbios_detect(const caddr_t);
+int	smbios_match(const char *, const char *, const char *);
+
+#endif /* _SMBIOS_H_ */

Modified: stable/10/sys/boot/i386/loader/main.c
==============================================================================
--- stable/10/sys/boot/i386/loader/main.c	Mon Jul 20 21:52:05 2015	(r285725)
+++ stable/10/sys/boot/i386/loader/main.c	Mon Jul 20 22:14:55 2015	(r285726)
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
 #include "bootstrap.h"
 #include "common/bootargs.h"
 #include "libi386/libi386.h"
+#include "libi386/smbios.h"
 #include "btxv86.h"
 
 #ifdef LOADER_ZFS_SUPPORT
@@ -115,7 +116,7 @@ main(void)
     }
     setheap(heap_bottom, heap_top);
 
-    /* 
+    /*
      * XXX Chicken-and-egg problem; we want to have console output early, but some
      * console attributes may depend on reading from eg. the boot device, which we
      * can't do yet.
@@ -181,7 +182,7 @@ main(void)
     biosacpi_detect();
 
     /* detect SMBIOS for future reference */
-    smbios_detect();
+    smbios_detect(NULL);
 
     printf("\n");
     printf("%s, Revision %s\n", bootprog_name, bootprog_rev);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201507202214.t6KMEuYH086343>