Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 Aug 2014 21:25:48 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r270828 - in head: sbin/sysctl sys/amd64/amd64 sys/amd64/include/pc sys/i386/i386 sys/i386/include/pc
Message-ID:  <201408292125.s7TLPmtQ086899@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Fri Aug 29 21:25:47 2014
New Revision: 270828
URL: http://svnweb.freebsd.org/changeset/base/270828

Log:
  - Add a new structure type for the ACPI 3.0 SMAP entry that includes the
    optional attributes field.
  - Add a 'machdep.smap' sysctl that exports the SMAP table of the running
    system as an array of the ACPI 3.0 structure.  (On older systems, the
    attributes are given a value of zero.)  Note that the sysctl only
    exports the SMAP table if it is available via the metadata passed from
    the loader to the kernel.  If an SMAP is not available, an empty array
    is returned.
  - Add a format handler for the ACPI 3.0 SMAP structure to the sysctl(8)
    binary to format the SMAP structures in a readable format similar to
    the format found in boot messages.
  
  MFC after:	2 weeks

Modified:
  head/sbin/sysctl/sysctl.c
  head/sys/amd64/amd64/machdep.c
  head/sys/amd64/include/pc/bios.h
  head/sys/i386/i386/machdep.c
  head/sys/i386/include/pc/bios.h

Modified: head/sbin/sysctl/sysctl.c
==============================================================================
--- head/sbin/sysctl/sysctl.c	Fri Aug 29 21:20:36 2014	(r270827)
+++ head/sbin/sysctl/sysctl.c	Fri Aug 29 21:25:47 2014	(r270828)
@@ -48,6 +48,10 @@ static const char rcsid[] =
 #include <sys/sysctl.h>
 #include <sys/vmmeter.h>
 
+#if defined(__amd64__) || defined(__i386__)
+#include <machine/pc/bios.h>
+#endif
+
 #include <ctype.h>
 #include <err.h>
 #include <errno.h>
@@ -541,6 +545,27 @@ S_vmtotal(int l2, void *p)
 	return (0);
 }
 
+#if defined(__amd64__) || defined(__i386__)
+static int
+S_bios_smap_xattr(int l2, void *p)
+{
+	struct bios_smap_xattr *smap, *end;
+
+	if (l2 % sizeof(*smap) != 0) {
+		warnx("S_bios_smap_xattr %d is not a multiple of %zu", l2,
+		    sizeof(*smap));
+		return (1);
+	}
+
+	end = (struct bios_smap_xattr *)((char *)p + l2);
+	for (smap = p; smap < end; smap++)
+		printf("\nSMAP type=%02x, xattr=%02x, base=%016jx, len=%016jx",
+		    smap->type, smap->xattr, (uintmax_t)smap->base,
+		    (uintmax_t)smap->length);
+	return (0);
+}
+#endif
+
 static int
 set_IK(const char *str, int *val)
 {
@@ -793,6 +818,10 @@ show_var(int *oid, int nlen)
 			func = S_loadavg;
 		else if (strcmp(fmt, "S,vmtotal") == 0)
 			func = S_vmtotal;
+#if defined(__amd64__) || defined(__i386__)
+		else if (strcmp(fmt, "S,bios_smap_xattr") == 0)
+			func = S_bios_smap_xattr;
+#endif
 		else
 			func = NULL;
 		if (func) {

Modified: head/sys/amd64/amd64/machdep.c
==============================================================================
--- head/sys/amd64/amd64/machdep.c	Fri Aug 29 21:20:36 2014	(r270827)
+++ head/sys/amd64/amd64/machdep.c	Fri Aug 29 21:25:47 2014	(r270828)
@@ -2090,6 +2090,42 @@ cpu_pcpu_init(struct pcpu *pcpu, int cpu
 	pcpu->pc_acpi_id = 0xffffffff;
 }
 
+static int
+smap_sysctl_handler(SYSCTL_HANDLER_ARGS)
+{
+	struct bios_smap *smapbase;
+	struct bios_smap_xattr smap;
+	caddr_t kmdp;
+	uint32_t *smapattr;
+	int count, error, i;
+
+	/* Retrieve the system memory map from the loader. */
+	kmdp = preload_search_by_type("elf kernel");
+	if (kmdp == NULL)
+		kmdp = preload_search_by_type("elf64 kernel");
+	smapbase = (struct bios_smap *)preload_search_info(kmdp,
+	    MODINFO_METADATA | MODINFOMD_SMAP);
+	if (smapbase == NULL)
+		return (0);
+	smapattr = (uint32_t *)preload_search_info(kmdp,
+	    MODINFO_METADATA | MODINFOMD_SMAP_XATTR);
+	count = *((uint32_t *)smapbase - 1) / sizeof(*smapbase);
+	error = 0;
+	for (i = 0; i < count; i++) {
+		smap.base = smapbase[i].base;
+		smap.length = smapbase[i].length;
+		smap.type = smapbase[i].type;
+		if (smapattr != NULL)
+			smap.xattr = smapattr[i];
+		else
+			smap.xattr = 0;
+		error = SYSCTL_OUT(req, &smap, sizeof(smap));
+	}
+	return (error);
+}
+SYSCTL_PROC(_machdep, OID_AUTO, smap, CTLTYPE_OPAQUE|CTLFLAG_RD, NULL, 0,
+    smap_sysctl_handler, "S,bios_smap_xattr", "Raw BIOS SMAP data");
+
 void
 spinlock_enter(void)
 {

Modified: head/sys/amd64/include/pc/bios.h
==============================================================================
--- head/sys/amd64/include/pc/bios.h	Fri Aug 29 21:20:36 2014	(r270827)
+++ head/sys/amd64/include/pc/bios.h	Fri Aug 29 21:25:47 2014	(r270828)
@@ -51,6 +51,14 @@ struct bios_smap {
     u_int32_t	type;
 } __packed;
 
+/* Structure extended to include extended attribute field in ACPI 3.0. */
+struct bios_smap_xattr {
+    u_int64_t	base;
+    u_int64_t	length;
+    u_int32_t	type;
+    u_int32_t	xattr;
+} __packed;
+	
 /*
  * System Management BIOS
  */

Modified: head/sys/i386/i386/machdep.c
==============================================================================
--- head/sys/i386/i386/machdep.c	Fri Aug 29 21:20:36 2014	(r270827)
+++ head/sys/i386/i386/machdep.c	Fri Aug 29 21:25:47 2014	(r270828)
@@ -3122,6 +3122,42 @@ cpu_pcpu_init(struct pcpu *pcpu, int cpu
 	pcpu->pc_acpi_id = 0xffffffff;
 }
 
+static int
+smap_sysctl_handler(SYSCTL_HANDLER_ARGS)
+{
+	struct bios_smap *smapbase;
+	struct bios_smap_xattr smap;
+	caddr_t kmdp;
+	uint32_t *smapattr;
+	int count, error, i;
+
+	/* Retrieve the system memory map from the loader. */
+	kmdp = preload_search_by_type("elf kernel");
+	if (kmdp == NULL)
+		kmdp = preload_search_by_type("elf32 kernel");
+	smapbase = (struct bios_smap *)preload_search_info(kmdp,
+	    MODINFO_METADATA | MODINFOMD_SMAP);
+	if (smapbase == NULL)
+		return (0);
+	smapattr = (uint32_t *)preload_search_info(kmdp,
+	    MODINFO_METADATA | MODINFOMD_SMAP_XATTR);
+	count = *((u_int32_t *)smapbase - 1) / sizeof(*smapbase);
+	error = 0;
+	for (i = 0; i < count; i++) {
+		smap.base = smapbase[i].base;
+		smap.length = smapbase[i].length;
+		smap.type = smapbase[i].type;
+		if (smapattr != NULL)
+			smap.xattr = smapattr[i];
+		else
+			smap.xattr = 0;
+		error = SYSCTL_OUT(req, &smap, sizeof(smap));
+	}
+	return (error);
+}
+SYSCTL_PROC(_machdep, OID_AUTO, smap, CTLTYPE_OPAQUE|CTLFLAG_RD, NULL, 0,
+    smap_sysctl_handler, "S,bios_smap_xattr", "Raw BIOS SMAP data");
+
 void
 spinlock_enter(void)
 {

Modified: head/sys/i386/include/pc/bios.h
==============================================================================
--- head/sys/i386/include/pc/bios.h	Fri Aug 29 21:20:36 2014	(r270827)
+++ head/sys/i386/include/pc/bios.h	Fri Aug 29 21:25:47 2014	(r270828)
@@ -221,6 +221,14 @@ struct bios_smap {
     u_int32_t	type;
 } __packed;
 
+/* Structure extended to include extended attribute field in ACPI 3.0. */
+struct bios_smap_xattr {
+    u_int64_t	base;
+    u_int64_t	length;
+    u_int32_t	type;
+    u_int32_t	xattr;
+} __packed;
+
 /*
  * System Management BIOS
  */



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