summaryrefslogtreecommitdiffstats
path: root/sbin
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 /sbin
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 'sbin')
-rw-r--r--sbin/sysctl/sysctl.c143
1 files changed, 133 insertions, 10 deletions
diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c
index 1359645..20d5952 100644
--- a/sbin/sysctl/sysctl.c
+++ b/sbin/sysctl/sysctl.c
@@ -48,6 +48,15 @@ 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
+
#include <ctype.h>
#include <err.h>
#include <errno.h>
@@ -454,12 +463,12 @@ parsefile(const char *filename)
/* These functions will dump out various interesting structures. */
static int
-S_clockinfo(int l2, void *p)
+S_clockinfo(size_t l2, void *p)
{
struct clockinfo *ci = (struct clockinfo*)p;
if (l2 != sizeof(*ci)) {
- warnx("S_clockinfo %d != %zu", l2, sizeof(*ci));
+ warnx("S_clockinfo %zu != %zu", l2, sizeof(*ci));
return (1);
}
printf(hflag ? "{ hz = %'d, tick = %'d, profhz = %'d, stathz = %'d }" :
@@ -469,12 +478,12 @@ S_clockinfo(int l2, void *p)
}
static int
-S_loadavg(int l2, void *p)
+S_loadavg(size_t l2, void *p)
{
struct loadavg *tv = (struct loadavg*)p;
if (l2 != sizeof(*tv)) {
- warnx("S_loadavg %d != %zu", l2, sizeof(*tv));
+ warnx("S_loadavg %zu != %zu", l2, sizeof(*tv));
return (1);
}
printf(hflag ? "{ %'.2f %'.2f %'.2f }" : "{ %.2f %.2f %.2f }",
@@ -485,14 +494,14 @@ S_loadavg(int l2, void *p)
}
static int
-S_timeval(int l2, void *p)
+S_timeval(size_t l2, void *p)
{
struct timeval *tv = (struct timeval*)p;
time_t tv_sec;
char *p1, *p2;
if (l2 != sizeof(*tv)) {
- warnx("S_timeval %d != %zu", l2, sizeof(*tv));
+ warnx("S_timeval %zu != %zu", l2, sizeof(*tv));
return (1);
}
printf(hflag ? "{ sec = %'jd, usec = %'ld } " :
@@ -509,13 +518,13 @@ S_timeval(int l2, void *p)
}
static int
-S_vmtotal(int l2, void *p)
+S_vmtotal(size_t l2, void *p)
{
struct vmtotal *v = (struct vmtotal *)p;
int pageKilo = getpagesize() / 1024;
if (l2 != sizeof(*v)) {
- warnx("S_vmtotal %d != %zu", l2, sizeof(*v));
+ warnx("S_vmtotal %zu != %zu", l2, sizeof(*v));
return (1);
}
@@ -536,10 +545,116 @@ S_vmtotal(int l2, void *p)
v->t_vmshr * pageKilo, v->t_avmshr * pageKilo);
printf("Shared Real Memory:\t(Total: %dK Active: %dK)\n",
v->t_rmshr * pageKilo, v->t_armshr * pageKilo);
- printf("Free Memory:\t%dK\n", v->t_free * pageKilo);
+ printf("Free Memory:\t%dK", v->t_free * pageKilo);
+
+ 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)
+{
+ struct bios_smap_xattr *smap, *end;
+
+ if (l2 % sizeof(*smap) != 0) {
+ warnx("S_bios_smap_xattr %zu 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)
@@ -655,7 +770,7 @@ show_var(int *oid, int nlen)
size_t intlen;
size_t j, len;
u_int kind;
- int (*func)(int, void *);
+ int (*func)(size_t, void *);
/* Silence GCC. */
umv = mv = intlen = 0;
@@ -793,6 +908,14 @@ 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;
+#endif
else
func = NULL;
if (func) {
OpenPOWER on IntegriCloud