- 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
This commit is contained in:
John Baldwin 2014-08-29 21:25:47 +00:00
parent 1a83a822d2
commit 89871cdeb6
5 changed files with 117 additions and 0 deletions

View File

@ -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) {

View File

@ -2090,6 +2090,42 @@ 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");
void
spinlock_enter(void)
{

View File

@ -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
*/

View File

@ -3122,6 +3122,42 @@ 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("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)
{

View File

@ -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
*/