svn commit: r271495 - in head: sbin/sysctl sys/amd64/amd64
John Baldwin
jhb at FreeBSD.org
Sat Sep 13 03:10:03 UTC 2014
Author: jhb
Date: Sat Sep 13 03:10:02 2014
New Revision: 271495
URL: http://svnweb.freebsd.org/changeset/base/271495
Log:
Add a sysctl to export the EFI memory map along with a handler in the
sysctl(8) binary to format it.
Reviewed by: emaste
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D771
Modified:
head/sbin/sysctl/sysctl.c
head/sys/amd64/amd64/machdep.c
Modified: head/sbin/sysctl/sysctl.c
==============================================================================
--- head/sbin/sysctl/sysctl.c Sat Sep 13 02:18:54 2014 (r271494)
+++ head/sbin/sysctl/sysctl.c Sat Sep 13 03:10:02 2014 (r271495)
@@ -48,6 +48,11 @@ static const char rcsid[] =
#include <sys/sysctl.h>
#include <sys/vmmeter.h>
+#ifdef __amd64__
+#include <sys/efi.h>
+#include <machine/metadata.h>
+#endif
+
#if defined(__amd64__) || defined(__i386__)
#include <machine/pc/bios.h>
#endif
@@ -545,6 +550,91 @@ S_vmtotal(size_t l2, void *p)
return (0);
}
+#ifdef __amd64__
+#define efi_next_descriptor(ptr, size) \
+ ((struct efi_md *)(((uint8_t *) ptr) + size))
+
+static int
+S_efi_map(size_t l2, void *p)
+{
+ struct efi_map_header *efihdr;
+ struct efi_md *map;
+ const char *type;
+ size_t efisz;
+ int ndesc, i;
+
+ static const char *types[] = {
+ "Reserved",
+ "LoaderCode",
+ "LoaderData",
+ "BootServicesCode",
+ "BootServicesData",
+ "RuntimeServicesCode",
+ "RuntimeServicesData",
+ "ConventionalMemory",
+ "UnusableMemory",
+ "ACPIReclaimMemory",
+ "ACPIMemoryNVS",
+ "MemoryMappedIO",
+ "MemoryMappedIOPortSpace",
+ "PalCode"
+ };
+
+ /*
+ * Memory map data provided by UEFI via the GetMemoryMap
+ * Boot Services API.
+ */
+ if (l2 < sizeof(*efihdr)) {
+ warnx("S_efi_map length less than header");
+ return (1);
+ }
+ efihdr = p;
+ efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
+ map = (struct efi_md *)((uint8_t *)efihdr + efisz);
+
+ if (efihdr->descriptor_size == 0)
+ return (0);
+ if (l2 != efisz + efihdr->memory_size) {
+ warnx("S_efi_map length mismatch %zu vs %zu", l2, efisz +
+ efihdr->memory_size);
+ return (1);
+ }
+ ndesc = efihdr->memory_size / efihdr->descriptor_size;
+
+ printf("\n%23s %12s %12s %8s %4s",
+ "Type", "Physical", "Virtual", "#Pages", "Attr");
+
+ for (i = 0; i < ndesc; i++,
+ map = efi_next_descriptor(map, efihdr->descriptor_size)) {
+ if (map->md_type <= EFI_MD_TYPE_PALCODE)
+ type = types[map->md_type];
+ else
+ type = "<INVALID>";
+ printf("\n%23s %012lx %12p %08lx ", type, map->md_phys,
+ map->md_virt, map->md_pages);
+ if (map->md_attr & EFI_MD_ATTR_UC)
+ printf("UC ");
+ if (map->md_attr & EFI_MD_ATTR_WC)
+ printf("WC ");
+ if (map->md_attr & EFI_MD_ATTR_WT)
+ printf("WT ");
+ if (map->md_attr & EFI_MD_ATTR_WB)
+ printf("WB ");
+ if (map->md_attr & EFI_MD_ATTR_UCE)
+ printf("UCE ");
+ if (map->md_attr & EFI_MD_ATTR_WP)
+ printf("WP ");
+ if (map->md_attr & EFI_MD_ATTR_RP)
+ printf("RP ");
+ if (map->md_attr & EFI_MD_ATTR_XP)
+ printf("XP ");
+ if (map->md_attr & EFI_MD_ATTR_RT)
+ printf("RUNTIME");
+ }
+ return (0);
+}
+#endif
+
#if defined(__amd64__) || defined(__i386__)
static int
S_bios_smap_xattr(size_t l2, void *p)
@@ -818,6 +908,10 @@ show_var(int *oid, int nlen)
func = S_loadavg;
else if (strcmp(fmt, "S,vmtotal") == 0)
func = S_vmtotal;
+#ifdef __amd64__
+ else if (strcmp(fmt, "S,efi_map_header") == 0)
+ func = S_efi_map;
+#endif
#if defined(__amd64__) || defined(__i386__)
else if (strcmp(fmt, "S,bios_smap_xattr") == 0)
func = S_bios_smap_xattr;
Modified: head/sys/amd64/amd64/machdep.c
==============================================================================
--- head/sys/amd64/amd64/machdep.c Sat Sep 13 02:18:54 2014 (r271494)
+++ head/sys/amd64/amd64/machdep.c Sat Sep 13 03:10:02 2014 (r271495)
@@ -2124,6 +2124,26 @@ smap_sysctl_handler(SYSCTL_HANDLER_ARGS)
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)
{
More information about the svn-src-all
mailing list