The branch main has been updated by aokblast:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=f840492b5b0d5c9e7d6d7d7dc25c260bc4d63ba2

commit f840492b5b0d5c9e7d6d7d7dc25c260bc4d63ba2
Author:     ShengYi Hung <aokbl...@freebsd.org>
AuthorDate: 2025-07-19 17:07:27 +0000
Commit:     ShengYi Hung <aokbl...@freebsd.org>
CommitDate: 2025-07-22 04:45:29 +0000

    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
---
 sys/dev/efidev/efirt.c       | 42 +++++++++++++++++++++++++++++++++++--
 sys/modules/efirt/Makefile   |  2 +-
 sys/sys/efi.h                | 18 ++++++++++++++++
 usr.sbin/efitable/efitable.8 |  2 ++
 usr.sbin/efitable/efitable.c | 50 +++++++++++++++++++++++++++++++++++++++++++-
 5 files changed, 110 insertions(+), 4 deletions(-)

diff --git a/sys/dev/efidev/efirt.c b/sys/dev/efidev/efirt.c
index b0fa33daeca7..b55c1c191077 100644
--- a/sys/dev/efidev/efirt.c
+++ b/sys/dev/efidev/efirt.c
@@ -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;
diff --git a/sys/modules/efirt/Makefile b/sys/modules/efirt/Makefile
index 4738996fd4e6..c46484465b68 100644
--- a/sys/modules/efirt/Makefile
+++ b/sys/modules/efirt/Makefile
@@ -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
diff --git a/sys/sys/efi.h b/sys/sys/efi.h
index 95a433a950db..89c8b15519de 100644
--- a/sys/sys/efi.h
+++ b/sys/sys/efi.h
@@ -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
diff --git a/usr.sbin/efitable/efitable.8 b/usr.sbin/efitable/efitable.8
index bb8a9cc3d0e1..4d174b7d9514 100644
--- a/usr.sbin/efitable/efitable.8
+++ b/usr.sbin/efitable/efitable.8
@@ -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
diff --git a/usr.sbin/efitable/efitable.c b/usr.sbin/efitable/efitable.c
index 0eee72801592..a506b4dea311 100644
--- a/usr.sbin/efitable/efitable.c
+++ b/usr.sbin/efitable/efitable.c
@@ -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");

Reply via email to