summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2014-10-10 20:47:23 +0000
committerjhb <jhb@FreeBSD.org>2014-10-10 20:47:23 +0000
commit5595ee40038c5126db4f066c82af2fb2883d2946 (patch)
treebac18b535c6d97ddc4590d6f4a27430cf891404b /sys/amd64
parent42c3399b2980b49ef41a9d63a49dd6bda51e2e9c (diff)
downloadFreeBSD-src-5595ee40038c5126db4f066c82af2fb2883d2946.zip
FreeBSD-src-5595ee40038c5126db4f066c82af2fb2883d2946.tar.gz
MFC 270828,271487,271495:
Add sysctls to export the BIOS SMAP and EFI memory maps along with handlers in the sysctl(8) binary to format them.
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/amd64/machdep.c56
-rw-r--r--sys/amd64/include/pc/bios.h8
2 files changed, 64 insertions, 0 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index ebf4b17..bb4d99d 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -2054,6 +2054,62 @@ cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
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");
+
+static int
+efi_map_sysctl_handler(SYSCTL_HANDLER_ARGS)
+{
+ struct efi_map_header *efihdr;
+ caddr_t kmdp;
+ uint32_t efisize;
+
+ kmdp = preload_search_by_type("elf kernel");
+ if (kmdp == NULL)
+ kmdp = preload_search_by_type("elf64 kernel");
+ efihdr = (struct efi_map_header *)preload_search_info(kmdp,
+ MODINFO_METADATA | MODINFOMD_EFI_MAP);
+ if (efihdr == NULL)
+ return (0);
+ efisize = *((uint32_t *)efihdr - 1);
+ return (SYSCTL_OUT(req, efihdr, efisize));
+}
+SYSCTL_PROC(_machdep, OID_AUTO, efi_map, CTLTYPE_OPAQUE|CTLFLAG_RD, NULL, 0,
+ efi_map_sysctl_handler, "S,efi_map_header", "Raw EFI Memory Map");
+
void
spinlock_enter(void)
{
diff --git a/sys/amd64/include/pc/bios.h b/sys/amd64/include/pc/bios.h
index e7d568e..ea509ea 100644
--- a/sys/amd64/include/pc/bios.h
+++ b/sys/amd64/include/pc/bios.h
@@ -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
*/
OpenPOWER on IntegriCloud