> Date: Fri, 9 Sep 2022 15:17:55 +0300
> From: Sergii Dmytruk <sergii.dmyt...@3mdeb.com>
> 
> Hi Mark,
> 
> Any news? I since setup gdb debugging of OVMF and figured out my EFI RT
> issues and it returns data fine now (was wrong calling ABI), but I'm not
> making /dev/efi as it sounds like you've done it already. Where are you
> at with this? Can I help to move this forward?

Hi Sergii,

Sorry, not much.  I've been a bit busy; some evil person put a lenovo
x13s on my desk ;).

I dug out the patch I was working on.  The goal of that patch was to
support rebooting machines using EFI runtime services, which makes the
Microsoft Surface Go 3 reboot correctly.  Unfortunately this breaks
other machines, which is why I parked the diff.

The diff is basically a port of the arm64 code, and I want to make an
effort to keep things in sync.  My plan is to get this bit in soon
after OpenBSD 7.2 is released.  That'll be a few weeks from now.  I
may use some of the time in between to make this a bit more robust
such that if we crash during an EFI runtime services call, the kernel
can recover.  This diff doesn't create dev/efi yet, but that will
follow soon after.

I did discuss the approach with Theo and some other OpenBSD developers
really.  I think this is very useful functionality, but there are some
concerns about making it too easy to set EFI variables from within
OpenBSD as this can have serious security implications.  Traditionally
we only allow this kind of thing when securelevel is -1 or 0.  See
https://man.openbsd.org/securelevel.7 for more information about
securelevel.  That would mean you can only run fwupd from single-user
mode.

Cheers, and thank you for your patience,

Mark


Index: arch/amd64/amd64/acpi_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/acpi_machdep.c,v
retrieving revision 1.104
diff -u -p -r1.104 acpi_machdep.c
--- arch/amd64/amd64/acpi_machdep.c     7 Aug 2022 23:56:06 -0000       1.104
+++ arch/amd64/amd64/acpi_machdep.c     14 Sep 2022 07:58:01 -0000
@@ -330,10 +330,14 @@ void
 acpi_attach_machdep(struct acpi_softc *sc)
 {
        extern void (*cpuresetfn)(void);
+       extern void (*powerdownfn)(void);
 
        sc->sc_interrupt = isa_intr_establish(NULL, sc->sc_fadt->sci_int,
            IST_LEVEL, IPL_BIO, acpi_interrupt, sc, sc->sc_dev.dv_xname);
-       cpuresetfn = acpi_reset;
+       if (!cpuresetfn)
+               cpuresetfn = acpi_reset;
+       if (!powerdownfn)
+               powerdownfn = acpi_powerdown;
 
 #ifndef SMALL_KERNEL
        /*
Index: arch/amd64/amd64/bios.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/bios.c,v
retrieving revision 1.45
diff -u -p -r1.45 bios.c
--- arch/amd64/amd64/bios.c     21 Feb 2022 11:03:39 -0000      1.45
+++ arch/amd64/amd64/bios.c     14 Sep 2022 07:58:01 -0000
@@ -30,6 +30,7 @@
 #include <amd64/include/isa_machdep.h>
 
 #include "acpi.h"
+#include "efi.h"
 #include "mpbios.h"
 #include "pci.h"
 
@@ -189,6 +190,18 @@ out:
                                break;
                        }
        }
+
+#if NEFI > 0
+       if (bios_efiinfo != NULL) {
+               struct bios_attach_args ba;
+
+               memset(&ba, 0, sizeof(ba));
+               ba.ba_name = "efi";
+               ba.ba_memt = X86_BUS_SPACE_MEM;
+
+               config_found(self, &ba, bios_print);
+       }
+#endif
 
 #if NACPI > 0
        {
Index: arch/amd64/amd64/efi.c
===================================================================
RCS file: arch/amd64/amd64/efi.c
diff -N arch/amd64/amd64/efi.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ arch/amd64/amd64/efi.c      14 Sep 2022 07:58:01 -0000
@@ -0,0 +1,315 @@
+/*     $OpenBSD$       */
+
+/*
+ * Copyright (c) 2022 Mark Kettenis <kette...@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/user.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <machine/biosvar.h>
+extern paddr_t cr3_reuse_pcid;
+extern void (*cpuresetfn)(void);
+extern void (*powerdownfn)(void);
+
+#include <dev/acpi/efi.h>
+
+#include <dev/clock_subr.h>
+
+extern todr_chip_handle_t todr_handle;
+
+extern EFI_MEMORY_DESCRIPTOR *mmap;
+
+struct efi_softc {
+       struct device   sc_dev;
+       struct pmap     *sc_pm;
+       EFI_RUNTIME_SERVICES *sc_rs;
+       u_long          sc_psw;
+       uint64_t        sc_cr3;
+
+       struct todr_chip_handle sc_todr;
+};
+
+int    efi_match(struct device *, void *, void *);
+void   efi_attach(struct device *, struct device *, void *);
+
+const struct cfattach efi_ca = {
+       sizeof(struct efi_softc), efi_match, efi_attach
+};
+
+struct cfdriver efi_cd = {
+       NULL, "efi", DV_DULL
+};
+
+void   efi_enter(struct efi_softc *);
+void   efi_leave(struct efi_softc *);
+int    efi_gettime(struct todr_chip_handle *, struct timeval *);
+int    efi_settime(struct todr_chip_handle *, struct timeval *);
+void   efi_reset(void);
+void   efi_powerdown(void);
+
+int
+efi_match(struct device *parent, void *match, void *aux)
+{
+       struct bios_attach_args *ba = aux;
+       struct cfdata *cf = match;
+
+       if (strcmp(ba->ba_name, cf->cf_driver->cd_name) == 0 &&
+           bios_efiinfo->system_table != 0)
+               return 1;
+
+       return 0;
+}
+
+void
+efi_attach(struct device *parent, struct device *self, void *aux)
+{
+       struct efi_softc *sc = (struct efi_softc *)self;
+       struct bios_attach_args *ba = aux;
+       uint64_t system_table;
+       bus_space_handle_t memh;
+       EFI_SYSTEM_TABLE *st;
+       EFI_RUNTIME_SERVICES *rs;
+       uint32_t mmap_size = bios_efiinfo->mmap_size;
+       uint32_t mmap_desc_size = bios_efiinfo->mmap_desc_size;
+       uint32_t mmap_desc_ver = bios_efiinfo->mmap_desc_ver;
+       EFI_MEMORY_DESCRIPTOR *desc;
+       EFI_TIME time;
+       EFI_STATUS status;
+       uint16_t major, minor;
+       int i;
+
+       if (mmap_desc_ver != EFI_MEMORY_DESCRIPTOR_VERSION) {
+               printf(": unsupported memory descriptor version %d\n",
+                   mmap_desc_ver);
+               return;
+       }
+
+       system_table = bios_efiinfo->system_table;
+       KASSERT(system_table);
+
+       if (bus_space_map(ba->ba_memt, system_table, sizeof(EFI_SYSTEM_TABLE),
+           BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE, &memh)) {
+               printf(": can't map system table\n");
+               return;
+       }
+
+       st = bus_space_vaddr(ba->ba_memt, memh);
+       rs = st->RuntimeServices;
+
+       major = st->Hdr.Revision >> 16;
+       minor = st->Hdr.Revision & 0xffff;
+       printf(": UEFI %d.%d", major, minor / 10);
+       if (minor % 10)
+               printf(".%d", minor % 10);
+       printf("\n");
+
+       if ((bios_efiinfo->flags & BEI_64BIT) == 0)
+               return;
+
+       /*
+        * We don't really want some random executable non-OpenBSD
+        * code lying around in kernel space.  So create a separate
+        * pmap and only activate it when we call runtime services.
+        */
+       sc->sc_pm = pmap_create();
+
+       desc = mmap;
+       for (i = 0; i < mmap_size / mmap_desc_size; i++) {
+               if (desc->Attribute & EFI_MEMORY_RUNTIME) {
+                       vaddr_t va = desc->PhysicalStart;
+                       paddr_t pa = desc->PhysicalStart;
+                       int npages = desc->NumberOfPages;
+                       vm_prot_t prot = PROT_READ | PROT_WRITE;
+
+#define EFI_DEBUG
+#ifdef EFI_DEBUG
+                       printf("type 0x%x pa 0x%llx va 0x%llx pages 0x%llx attr 
0x%llx\n",
+                           desc->Type, desc->PhysicalStart,
+                           desc->VirtualStart, desc->NumberOfPages,
+                           desc->Attribute);
+#endif
+
+                       /*
+                        * Normal memory is expected to be "write
+                        * back" cacheable.  Everything else is mapped
+                        * as device memory.
+                        */
+                       if ((desc->Attribute & EFI_MEMORY_WB) == 0)
+                               pa |= PMAP_NOCACHE;
+
+                       /*
+                        * Only make pages marked as runtime service code
+                        * executable.  This violates the standard but it
+                        * seems we can get away with it.
+                        */
+                       if (desc->Type == EfiRuntimeServicesCode)
+                               prot |= PROT_EXEC;
+
+                       if (desc->Attribute & EFI_MEMORY_RP)
+                               prot &= ~PROT_READ;
+                       if (desc->Attribute & EFI_MEMORY_XP)
+                               prot &= ~PROT_EXEC;
+                       if (desc->Attribute & EFI_MEMORY_RO)
+                               prot &= ~PROT_WRITE;
+
+                       while (npages--) {
+                               pmap_enter(sc->sc_pm, va, pa, prot,
+                                  prot | PMAP_WIRED | PMAP_EFI);
+                               va += PAGE_SIZE;
+                               pa += PAGE_SIZE;
+                       }
+               }
+               desc = NextMemoryDescriptor(desc, mmap_desc_size);
+       }
+
+       /*
+        * The FirmwareVendor and ConfigurationTable fields have been
+        * converted from a physical pointer to a virtual pointer, so
+        * we have to activate our pmap to access them.
+        */
+       efi_enter(sc);
+       if (st->FirmwareVendor) {
+               printf("%s: ", sc->sc_dev.dv_xname);
+               for (i = 0; st->FirmwareVendor[i]; i++)
+                       printf("%c", st->FirmwareVendor[i]);
+               printf(" rev 0x%x\n", st->FirmwareRevision);
+       }
+       efi_leave(sc);
+
+       if (rs == NULL)
+               return;
+       sc->sc_rs = rs;
+
+       cpuresetfn = efi_reset;
+       powerdownfn = efi_powerdown;
+
+       efi_enter(sc);
+       status = rs->GetTime(&time, NULL);
+       efi_leave(sc);
+       if (status != EFI_SUCCESS)
+               return;
+
+       sc->sc_todr.cookie = sc;
+       sc->sc_todr.todr_gettime = efi_gettime;
+       sc->sc_todr.todr_settime = efi_settime;
+       todr_handle = &sc->sc_todr;
+}
+
+void
+efi_enter(struct efi_softc *sc)
+{
+       sc->sc_psw = intr_disable();
+       sc->sc_cr3 = rcr3() | cr3_reuse_pcid;
+       lcr3(sc->sc_pm->pm_pdirpa | (pmap_use_pcid ? PCID_EFI : 0));
+
+       fpu_kernel_enter();
+}
+
+void
+efi_leave(struct efi_softc *sc)
+{
+       fpu_kernel_exit();
+
+       lcr3(sc->sc_cr3);
+       intr_restore(sc->sc_psw);
+}
+
+int
+efi_gettime(struct todr_chip_handle *handle, struct timeval *tv)
+{
+       struct efi_softc *sc = handle->cookie;
+       struct clock_ymdhms dt;
+       EFI_TIME time;
+       EFI_STATUS status;
+
+       efi_enter(sc);
+       status = sc->sc_rs->GetTime(&time, NULL);
+       efi_leave(sc);
+       if (status != EFI_SUCCESS)
+               return EIO;
+
+       dt.dt_year = time.Year;
+       dt.dt_mon = time.Month;
+       dt.dt_day = time.Day;
+       dt.dt_hour = time.Hour;
+       dt.dt_min = time.Minute;
+       dt.dt_sec = time.Second;
+
+       if (dt.dt_sec > 59 || dt.dt_min > 59 || dt.dt_hour > 23 ||
+           dt.dt_day > 31 || dt.dt_day == 0 ||
+           dt.dt_mon > 12 || dt.dt_mon == 0 ||
+           dt.dt_year < POSIX_BASE_YEAR)
+               return EINVAL;
+
+       tv->tv_sec = clock_ymdhms_to_secs(&dt);
+       tv->tv_usec = 0;
+       return 0;
+}
+
+int
+efi_settime(struct todr_chip_handle *handle, struct timeval *tv)
+{
+       struct efi_softc *sc = handle->cookie;
+       struct clock_ymdhms dt;
+       EFI_TIME time;
+       EFI_STATUS status;
+
+       clock_secs_to_ymdhms(tv->tv_sec, &dt);
+
+       time.Year = dt.dt_year;
+       time.Month = dt.dt_mon;
+       time.Day = dt.dt_day;
+       time.Hour = dt.dt_hour;
+       time.Minute = dt.dt_min;
+       time.Second = dt.dt_sec;
+       time.Nanosecond = 0;
+       time.TimeZone = 0;
+       time.Daylight = 0;
+
+       efi_enter(sc);
+       status = sc->sc_rs->SetTime(&time);
+       efi_leave(sc);
+       if (status != EFI_SUCCESS)
+               return EIO;
+       return 0;
+}
+
+void
+efi_reset(void)
+{
+       struct efi_softc *sc = efi_cd.cd_devs[0];
+
+       printf("%s\n", __func__);
+       efi_enter(sc);
+       sc->sc_rs->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
+       efi_leave(sc);
+}
+
+void
+efi_powerdown(void)
+{
+       struct efi_softc *sc = efi_cd.cd_devs[0];
+
+       printf("%s\n", __func__);
+       efi_enter(sc);
+       sc->sc_rs->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, NULL);
+       efi_leave(sc);
+}
Index: arch/amd64/amd64/machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/machdep.c,v
retrieving revision 1.280
diff -u -p -r1.280 machdep.c
--- arch/amd64/amd64/machdep.c  25 Aug 2022 17:25:25 -0000      1.280
+++ arch/amd64/amd64/machdep.c  14 Sep 2022 07:58:01 -0000
@@ -126,6 +126,11 @@ extern int db_console;
 #include <dev/ic/comreg.h>
 #endif
 
+#include "efi.h"
+#if NEFI > 0
+#include <dev/acpi/efi.h>
+#endif
+
 #include "softraid.h"
 #if NSOFTRAID > 0
 #include <dev/softraidvar.h>
@@ -244,6 +249,10 @@ u_int32_t  bios_cksumlen;
 bios_efiinfo_t *bios_efiinfo;
 bios_ucode_t   *bios_ucode;
 
+#if NEFI > 0
+EFI_MEMORY_DESCRIPTOR *mmap;
+#endif
+
 /*
  * Size of memory segments, before any memory is stolen.
  */
@@ -258,6 +267,7 @@ void        cpu_init_extents(void);
 void   map_tramps(void);
 void   init_x86_64(paddr_t);
 void   (*cpuresetfn)(void);
+void   (*powerdownfn)(void);
 void   enter_shared_special_pages(void);
 
 #ifdef APERTURE
@@ -850,15 +860,13 @@ haltsys:
 #endif
 
        if ((howto & RB_HALT) != 0) {
-#if NACPI > 0 && !defined(SMALL_KERNEL)
-               extern int acpi_enabled;
-
-               if (acpi_enabled) {
+               if ((howto & RB_POWERDOWN) != 0) {
+                       printf("\nAttempting to power down...\n");
                        delay(500000);
-                       if ((howto & RB_POWERDOWN) != 0)
-                               acpi_powerdown();
+                       if (powerdownfn)
+                               (*powerdownfn)();
                }
-#endif
+
                printf("\n");
                printf("The operating system has halted.\n");
                printf("Please press any key to reboot.\n\n");
@@ -1537,6 +1545,16 @@ init_x86_64(paddr_t first_avail)
         * We must do this before loading pages into the VM system.
         */
        first_avail = pmap_bootstrap(first_avail, trunc_page(avail_end));
+
+#if NEFI > 0
+       /* Relocate the EFI memory map. */
+       if (bios_efiinfo && bios_efiinfo->mmap_start) {
+               mmap = (EFI_MEMORY_DESCRIPTOR *)PMAP_DIRECT_MAP(first_avail);
+               memcpy(mmap, (void *)PMAP_DIRECT_MAP(bios_efiinfo->mmap_start),
+                   bios_efiinfo->mmap_size);
+               first_avail += round_page(bios_efiinfo->mmap_size);
+       }
+#endif
 
        /* Allocate these out of the 640KB base memory */
        if (avail_start != PAGE_SIZE)
Index: arch/amd64/amd64/pmap.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/pmap.c,v
retrieving revision 1.154
diff -u -p -r1.154 pmap.c
--- arch/amd64/amd64/pmap.c     10 Sep 2022 20:35:28 -0000      1.154
+++ arch/amd64/amd64/pmap.c     14 Sep 2022 07:58:01 -0000
@@ -2834,7 +2834,7 @@ enter_now:
        if (nocache)
                npte |= PG_N;
        if (va < VM_MAXUSER_ADDRESS)
-               npte |= PG_u;
+               npte |= ((flags & PMAP_EFI) ? 0 : PG_u);
        else if (va < VM_MAX_ADDRESS)
                npte |= (PG_u | PG_RW); /* XXXCDC: no longer needed? */
        if (pmap == pmap_kernel())
Index: arch/amd64/conf/GENERIC
===================================================================
RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v
retrieving revision 1.512
diff -u -p -r1.512 GENERIC
--- arch/amd64/conf/GENERIC     8 Mar 2022 15:08:01 -0000       1.512
+++ arch/amd64/conf/GENERIC     14 Sep 2022 07:58:01 -0000
@@ -86,6 +86,8 @@ ipmi0         at acpi? disable
 ccpmic*                at iic?
 tipmic*                at iic?
 
+efi0           at bios0
+
 mpbios0                at bios0
 
 ipmi0  at mainbus? disable     # IPMI
Index: arch/amd64/conf/files.amd64
===================================================================
RCS file: /cvs/src/sys/arch/amd64/conf/files.amd64,v
retrieving revision 1.105
diff -u -p -r1.105 files.amd64
--- arch/amd64/conf/files.amd64 9 Feb 2022 23:54:34 -0000       1.105
+++ arch/amd64/conf/files.amd64 14 Sep 2022 07:58:01 -0000
@@ -243,6 +243,13 @@ attach     acpipci at acpi
 file   arch/amd64/pci/acpipci.c                acpipci
 
 #
+# EFI
+#
+device efi
+attach efi at bios
+file   arch/amd64/amd64/efi.c                  efi needs-flag
+
+#
 # VMM
 #
 device vmm {}
Index: arch/amd64/include/pmap.h
===================================================================
RCS file: /cvs/src/sys/arch/amd64/include/pmap.h,v
retrieving revision 1.81
diff -u -p -r1.81 pmap.h
--- arch/amd64/include/pmap.h   29 Aug 2022 02:58:13 -0000      1.81
+++ arch/amd64/include/pmap.h   14 Sep 2022 07:58:01 -0000
@@ -256,6 +256,7 @@
 #define PCID_PROC      1       /* non-pmap_kernel(), U+K */
 #define PCID_PROC_INTEL        2       /* non-pmap_kernel(), U-K (meltdown) */
 #define PCID_TEMP      3       /* temp mapping of another non-pmap_kernel() */
+#define PCID_EFI       4       /* EFI runtime services */ 
 
 extern int pmap_use_pcid;      /* non-zero if PCID support is enabled */
 
@@ -316,6 +317,8 @@ struct pmap {
        int pm_type;                    /* Type of pmap this is (PMAP_TYPE_x) */
        uint64_t eptp;                  /* cached EPTP (used by vmm) */
 };
+
+#define PMAP_EFI       PMAP_MD0
 
 /*
  * MD flags that we use for pmap_enter (in the pa):
Index: dev/acpi/efi.h
===================================================================
RCS file: /cvs/src/sys/dev/acpi/efi.h,v
retrieving revision 1.4
diff -u -p -r1.4 efi.h
--- dev/acpi/efi.h      4 Aug 2019 09:27:09 -0000       1.4
+++ dev/acpi/efi.h      14 Sep 2022 07:58:01 -0000
@@ -5,6 +5,12 @@
 #ifndef _MACHINE_EFI_H_
 #define _MACHINE_EFI_H_
 
+#ifdef __amd64__
+#define EFIAPI         __attribute__((ms_abi))
+#else
+#define EFIAPI
+#endif
+
 typedef uint8_t                UINT8;
 typedef int16_t                INT16;
 typedef uint16_t       UINT16;
@@ -41,6 +47,10 @@ typedef struct {
   { 0xf2fd1544, 0x9794, 0x4a2c, \
     { 0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94 } }
 
+#define EFI_GLOBAL_VARIABLE \
+  { 0x8be4df61, 0x93ca, 0x11d2, \
+    { 0xaa,0x0d,0x00,0xe0,0x98,0x03,0x2b,0x8c } }
+
 typedef enum {
        EfiReservedMemoryType,
        EfiLoaderCode,
@@ -87,6 +97,13 @@ typedef struct {
 #define NextMemoryDescriptor(Ptr, Size) \
        ((EFI_MEMORY_DESCRIPTOR *)(((UINT8 *)Ptr) + Size))
 
+typedef enum {
+       EfiResetCold,
+       EfiResetWarm,
+       EfiResetShutdown,
+       EfiResetPlatformSpecific
+} EFI_RESET_TYPE;
+
 typedef struct {
        UINT64                          Signature;
        UINT32                          Revision;
@@ -111,9 +128,13 @@ typedef struct {
 
 typedef VOID           *EFI_TIME_CAPABILITIES;
 
-typedef EFI_STATUS (*EFI_GET_TIME)(EFI_TIME *, EFI_TIME_CAPABILITIES *);
-typedef EFI_STATUS (*EFI_SET_TIME)(EFI_TIME *);
-typedef EFI_STATUS (*EFI_SET_VIRTUAL_ADDRESS_MAP)(UINTN, UINTN, UINT32, 
EFI_MEMORY_DESCRIPTOR *);
+typedef EFI_STATUS (EFIAPI *EFI_GET_TIME)(EFI_TIME *, EFI_TIME_CAPABILITIES *);
+typedef EFI_STATUS (EFIAPI *EFI_SET_TIME)(EFI_TIME *);
+typedef EFI_STATUS (EFIAPI *EFI_SET_VIRTUAL_ADDRESS_MAP)(UINTN, UINTN, UINT32, 
EFI_MEMORY_DESCRIPTOR *);
+typedef EFI_STATUS (EFIAPI *EFI_GET_VARIABLE)(CHAR16 *, EFI_GUID *, UINT32 *, 
UINTN *, VOID *);
+typedef EFI_STATUS (EFIAPI *EFI_GET_NEXT_VARIABLE_NAME)(UINTN *, CHAR16 *, 
EFI_GUID *);
+typedef EFI_STATUS (EFIAPI *EFI_SET_VARIABLE)(CHAR16 *, EFI_GUID *, UINT32, 
UINTN, VOID *);
+typedef VOID (EFIAPI *EFI_RESET_SYSTEM)(EFI_RESET_TYPE, EFI_STATUS, UINTN, 
VOID *);
 
 typedef struct {
        EFI_TABLE_HEADER                Hdr;
@@ -123,6 +144,14 @@ typedef struct {
        VOID                            *SetWakeupTime;
 
        EFI_SET_VIRTUAL_ADDRESS_MAP     SetVirtualAddressMap;
+       VOID                            *ConvertPointer;
+
+       EFI_GET_VARIABLE                GetVariable;
+       EFI_GET_NEXT_VARIABLE_NAME      GetNextVariableName;
+       EFI_SET_VARIABLE                SetVariable;
+
+       VOID                            *GetNextHighMonotonicCount;
+       EFI_RESET_SYSTEM                ResetSystem;
 } EFI_RUNTIME_SERVICES;
 
 typedef struct {

Reply via email to