efidev: add support for memory attribute
The EFI_PROPERTIES_TABLE has been deprecated in the UEFI specification. It is now replaced by the EFI_MEMORY_ATTRIBUTES_TABLE, which provides a new header and data format for describing memory region attributes. Reviewed by: imp Approved by: markj (mentor) Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D49998
This commit is contained in:
+40
-2
@@ -107,7 +107,8 @@ static int efi_status2err[25] = {
|
||||
|
||||
enum efi_table_type {
|
||||
TYPE_ESRT = 0,
|
||||
TYPE_PROP
|
||||
TYPE_PROP,
|
||||
TYPE_MEMORY_ATTR
|
||||
};
|
||||
|
||||
static int efi_enter(void);
|
||||
@@ -445,6 +446,42 @@ get_table_length(enum efi_table_type type, size_t *table_len, void **taddr)
|
||||
free(buf, M_TEMP);
|
||||
return (0);
|
||||
}
|
||||
case TYPE_MEMORY_ATTR:
|
||||
{
|
||||
efi_guid_t guid = EFI_MEMORY_ATTRIBUTES_TABLE;
|
||||
struct efi_memory_attribute_table *tbl_addr, *mem_addr;
|
||||
int error;
|
||||
void *buf;
|
||||
size_t len = sizeof(struct efi_memory_attribute_table);
|
||||
|
||||
error = efi_get_table(&guid, (void **)&tbl_addr);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
buf = malloc(len, M_TEMP, M_WAITOK);
|
||||
error = physcopyout((vm_paddr_t)tbl_addr, buf, len);
|
||||
if (error) {
|
||||
free(buf, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
|
||||
mem_addr = (struct efi_memory_attribute_table *)buf;
|
||||
if (mem_addr->version != 2) {
|
||||
free(buf, M_TEMP);
|
||||
return (EINVAL);
|
||||
}
|
||||
len += mem_addr->descriptor_size * mem_addr->num_ents;
|
||||
if (len > EFI_TABLE_ALLOC_MAX) {
|
||||
free(buf, M_TEMP);
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
*table_len = len;
|
||||
if (taddr != NULL)
|
||||
*taddr = tbl_addr;
|
||||
free(buf, M_TEMP);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
return (ENOENT);
|
||||
}
|
||||
@@ -457,7 +494,8 @@ copy_table(efi_guid_t *guid, void **buf, size_t buf_len, size_t *table_len)
|
||||
enum efi_table_type type;
|
||||
} tables[] = {
|
||||
{ EFI_TABLE_ESRT, TYPE_ESRT },
|
||||
{ EFI_PROPERTIES_TABLE, TYPE_PROP }
|
||||
{ EFI_PROPERTIES_TABLE, TYPE_PROP },
|
||||
{ EFI_MEMORY_ATTRIBUTES_TABLE, TYPE_MEMORY_ATTR }
|
||||
};
|
||||
size_t table_idx;
|
||||
void *taddr;
|
||||
|
||||
@@ -9,7 +9,7 @@ SRCS+= device_if.h bus_if.h clock_if.h
|
||||
DPSRCS+= assym.inc
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "amd64"
|
||||
SRCS+= opt_hwpmc_hooks.h opt_kstack_pages.h
|
||||
SRCS+= opt_acpi.h opt_hwpmc_hooks.h opt_kstack_pages.h
|
||||
.endif
|
||||
|
||||
efirt_support.o: efirt_support.S assym.inc
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
{0xb122a263,0x3661,0x4f68,{0x99,0x29,0x78,0xf8,0xb0,0xd6,0x21,0x80}}
|
||||
#define EFI_PROPERTIES_TABLE \
|
||||
{0x880aaca3,0x4adc,0x4a04,{0x90,0x79,0xb7,0x47,0x34,0x08,0x25,0xe5}}
|
||||
#define EFI_MEMORY_ATTRIBUTES_TABLE \
|
||||
{0xdcfa911d,0x26eb,0x469f,{0xa2,0x20,0x38,0xb7,0xdc,0x46,0x12,0x20}}
|
||||
#define LINUX_EFI_MEMRESERVE_TABLE \
|
||||
{0x888eb0c6,0x8ede,0x4ff5,{0xa8,0xf0,0x9a,0xee,0x5c,0xb9,0x77,0xc2}}
|
||||
|
||||
@@ -166,6 +168,22 @@ struct efi_prop_table {
|
||||
uint64_t memory_protection_attribute;
|
||||
};
|
||||
|
||||
struct efi_memory_descriptor {
|
||||
uint32_t type;
|
||||
caddr_t phy_addr;
|
||||
caddr_t virt_addr;
|
||||
uint64_t pages;
|
||||
uint64_t attrs;
|
||||
};
|
||||
|
||||
struct efi_memory_attribute_table {
|
||||
uint32_t version;
|
||||
uint32_t num_ents;
|
||||
uint32_t descriptor_size;
|
||||
uint32_t flags;
|
||||
struct efi_memory_descriptor tables[];
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#ifdef EFIABI_ATTR
|
||||
|
||||
@@ -54,6 +54,8 @@ Currently supported tables:
|
||||
.Bl -tag -width indent -compact
|
||||
.It Cm esrt
|
||||
EFI System Resource Table
|
||||
.It Cm memory
|
||||
EFI Memory Attributes Table
|
||||
.It Cm prop
|
||||
EFI Properties Table
|
||||
.El
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
|
||||
static void efi_table_print_esrt(const void *data);
|
||||
static void efi_table_print_prop(const void *data);
|
||||
static void efi_table_print_memory(const void *data);
|
||||
static void usage(void) __dead2;
|
||||
|
||||
struct efi_table_op {
|
||||
@@ -56,7 +57,9 @@ static const struct efi_table_op efi_table_ops[] = {
|
||||
{ .name = "esrt", .parse = efi_table_print_esrt,
|
||||
.guid = EFI_TABLE_ESRT },
|
||||
{ .name = "prop", .parse = efi_table_print_prop,
|
||||
.guid = EFI_PROPERTIES_TABLE }
|
||||
.guid = EFI_PROPERTIES_TABLE },
|
||||
{ .name = "memory", .parse = efi_table_print_memory,
|
||||
.guid = EFI_MEMORY_ATTRIBUTES_TABLE }
|
||||
};
|
||||
|
||||
int
|
||||
@@ -239,6 +242,51 @@ efi_table_print_prop(const void *data)
|
||||
xo_err(EX_IOERR, "stdout");
|
||||
}
|
||||
|
||||
static void
|
||||
efi_table_print_memory(const void *data)
|
||||
{
|
||||
const struct efi_memory_attribute_table *attr =
|
||||
(const struct efi_memory_attribute_table *)data;
|
||||
const struct efi_memory_descriptor *desc;
|
||||
int i, nentries;
|
||||
|
||||
nentries = attr->num_ents;
|
||||
desc = attr->tables;
|
||||
|
||||
xo_set_version(EFITABLE_XO_VERSION);
|
||||
|
||||
xo_open_container("memory");
|
||||
xo_emit("{Lwc:Version}{:version/%#x}\n", attr->version);
|
||||
xo_emit("{Lwc:Length}{:length/%u}\n", attr->descriptor_size);
|
||||
xo_emit("{Lwc:Entries}{:entries/%u}\n", attr->num_ents);
|
||||
|
||||
xo_open_container("attributes");
|
||||
|
||||
/*
|
||||
* According to https://forum.osdev.org/viewtopic.php?t=32953, the size
|
||||
* of records into the attribute table never equals to
|
||||
* sizeof(efi_memory_descriptor). The correct one for indexing the array
|
||||
* resides in the attributet table.
|
||||
*/
|
||||
for (i = 0; i < nentries; i++) {
|
||||
xo_emit("{Lwc:ID}{:id/%#x}\n", i);
|
||||
xo_emit("{Lwc:Attributes}{:attributes/%#x}\n", desc->attrs);
|
||||
xo_emit("{Lwc:Type}{:type/%#x}\n", desc->type);
|
||||
xo_emit("{Lwc:Pages}{:pages/%#x}\n", desc->pages);
|
||||
xo_emit("{Lwc:Phyaddr}{:phyaddr/%#p}\n", desc->phy_addr);
|
||||
xo_emit("{Lwc:Virtaddr}{:virtaddr/%#p}\n", desc->virt_addr);
|
||||
desc = (const struct efi_memory_descriptor *)(const void *)
|
||||
((const char *)desc + attr->descriptor_size);
|
||||
}
|
||||
|
||||
xo_close_container("attributes");
|
||||
|
||||
xo_close_container("memory");
|
||||
|
||||
if (xo_finish() < 0)
|
||||
xo_err(EX_IOERR, "stdout");
|
||||
}
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
xo_error("usage: efitable [-g guid | -t name] [--libxo]\n");
|
||||
|
||||
Reference in New Issue
Block a user