Module Name:    src
Committed By:   martin
Date:           Tue Aug  1 16:05:12 UTC 2023

Modified Files:
        src/sys/arch/arm/arm [netbsd-10]: efi_runtime.c
        src/sys/arch/x86/x86 [netbsd-10]: efi_machdep.c
        src/sys/dev [netbsd-10]: efi.c efivar.h
        src/sys/dev/efi [netbsd-10]: efi.h
        src/sys/sys [netbsd-10]: efiio.h

Log Message:
Pull up following revision(s) (requested by riastradh in ticket #292):

        sys/arch/arm/arm/efi_runtime.c: revision 1.11
        sys/dev/efi/efi.h: revision 1.3
        sys/arch/x86/x86/efi_machdep.c: revision 1.5
        sys/arch/x86/x86/efi_machdep.c: revision 1.6
        sys/dev/efi.c: revision 1.5
        sys/dev/efi.c: revision 1.6
        sys/dev/efi.c: revision 1.7
        sys/dev/efi.c: revision 1.8
        sys/dev/efi.c: revision 1.9
        sys/dev/efivar.h: revision 1.2
        sys/sys/efiio.h: revision 1.3

efi(4): Parenthesize EFIERR argument out of paranoia.
PR kern/57076

efi(4): Move error macros to efi.h.
PR kern/57076

efi(4): Implement MI parts of EFIIOC_GET_TABLE.
Intended to be compatible with FreeBSD.
Not yet supported on any architectures.
PR kern/57076

efi(4): Implement EFIIOC_GET_TABLE on x86.
PR kern/57076

efi(4): Translate between size_t and unsigned long.
Fixes i386 build.
PR kern/57076

efi(4): Fix logic to handle buffer sizing.

Can't KASSERT(datasize <= databufsize) because the caller is allowed
to pass in a too-small size and get ERR_BUFFER_TOO_SMALL back, with
the actual size returned so it can resize its buffer.  So just clamp
the size to the smaller of what the caller provided and what the
firwmare provided, instead of asserting anything.

PR kern/57076


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.10.2.1 src/sys/arch/arm/arm/efi_runtime.c
cvs rdiff -u -r1.3 -r1.3.4.1 src/sys/arch/x86/x86/efi_machdep.c
cvs rdiff -u -r1.4 -r1.4.4.1 src/sys/dev/efi.c
cvs rdiff -u -r1.1 -r1.1.4.1 src/sys/dev/efivar.h
cvs rdiff -u -r1.2 -r1.2.4.1 src/sys/dev/efi/efi.h
cvs rdiff -u -r1.2 -r1.2.4.1 src/sys/sys/efiio.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/arm/efi_runtime.c
diff -u src/sys/arch/arm/arm/efi_runtime.c:1.10 src/sys/arch/arm/arm/efi_runtime.c:1.10.2.1
--- src/sys/arch/arm/arm/efi_runtime.c:1.10	Sat Oct 15 11:19:23 2022
+++ src/sys/arch/arm/arm/efi_runtime.c	Tue Aug  1 16:05:11 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: efi_runtime.c,v 1.10 2022/10/15 11:19:23 jmcneill Exp $ */
+/* $NetBSD: efi_runtime.c,v 1.10.2.1 2023/08/01 16:05:11 martin Exp $ */
 
 /*-
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
 #include "efi.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: efi_runtime.c,v 1.10 2022/10/15 11:19:23 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: efi_runtime.c,v 1.10.2.1 2023/08/01 16:05:11 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/mutex.h>
@@ -45,15 +45,6 @@ __KERNEL_RCSID(0, "$NetBSD: efi_runtime.
 #include <arm/arm/efi_runtime.h>
 #include <arm/bootconfig.h>
 
-#ifdef _LP64
-#define	EFIERR(x)	(0x8000000000000000 | x)
-#else
-#define	EFIERR(x)	(0x80000000 | x)
-#endif
-
-#define	EFI_UNSUPPORTED		EFIERR(3)
-#define	EFI_DEVICE_ERROR	EFIERR(7)
-
 static kmutex_t efi_lock;
 static struct efi_rt *RT;
 #if BYTE_ORDER == LITTLE_ENDIAN

Index: src/sys/arch/x86/x86/efi_machdep.c
diff -u src/sys/arch/x86/x86/efi_machdep.c:1.3 src/sys/arch/x86/x86/efi_machdep.c:1.3.4.1
--- src/sys/arch/x86/x86/efi_machdep.c:1.3	Sat Sep 24 15:01:54 2022
+++ src/sys/arch/x86/x86/efi_machdep.c	Tue Aug  1 16:05:12 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: efi_machdep.c,v 1.3 2022/09/24 15:01:54 riastradh Exp $	*/
+/*	$NetBSD: efi_machdep.c,v 1.3.4.1 2023/08/01 16:05:12 martin Exp $	*/
 
 /*-
  * Copyright (c) 2016 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: efi_machdep.c,v 1.3 2022/09/24 15:01:54 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: efi_machdep.c,v 1.3.4.1 2023/08/01 16:05:12 martin Exp $");
 
 #include "efi.h"
 #include "opt_efi.h"
@@ -582,18 +582,6 @@ efi_get_e820memmap(void)
 #ifdef EFI_RUNTIME
 
 /*
- * XXX move to sys/dev/efi/efi.h
- */
-#ifdef _LP64
-#define	EFIERR(x)	(0x8000000000000000ul | (x))
-#else
-#define	EFIERR(x)	(0x80000000ul | (x))
-#endif
-
-#define	EFI_UNSUPPORTED		EFIERR(3)
-#define	EFI_DEVICE_ERROR	EFIERR(7)
-
-/*
  * efi_runtime_init()
  *
  *	Set up kernel access to EFI runtime services:
@@ -985,12 +973,29 @@ efi_runtime_setvar(efi_char *name, struc
 	return status;
 }
 
+static efi_status
+efi_runtime_gettab(const struct uuid *vendor, uint64_t *addrp)
+{
+	struct efi_cfgtbl *cfgtbl = efi_getcfgtblhead();
+	paddr_t pa;
+
+	if (cfgtbl == NULL)
+		return EFI_UNSUPPORTED;
+
+	pa = efi_getcfgtblpa(vendor);
+	if (pa == 0)
+		return EFI_NOT_FOUND;
+	*addrp = pa;
+	return EFI_SUCCESS;
+}
+
 static struct efi_ops efi_runtime_ops = {
 	.efi_gettime = efi_runtime_gettime,
 	.efi_settime = efi_runtime_settime,
 	.efi_getvar = efi_runtime_getvar,
 	.efi_setvar = efi_runtime_setvar,
 	.efi_nextvar = efi_runtime_nextvar,
+	.efi_gettab = efi_runtime_gettab,
 };
 
 #endif	/* EFI_RUNTIME */

Index: src/sys/dev/efi.c
diff -u src/sys/dev/efi.c:1.4 src/sys/dev/efi.c:1.4.4.1
--- src/sys/dev/efi.c:1.4	Sat Sep 24 11:06:03 2022
+++ src/sys/dev/efi.c	Tue Aug  1 16:05:12 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: efi.c,v 1.4 2022/09/24 11:06:03 riastradh Exp $ */
+/* $NetBSD: efi.c,v 1.4.4.1 2023/08/01 16:05:12 martin Exp $ */
 
 /*-
  * Copyright (c) 2021 Jared McNeill <jmcne...@invisible.ca>
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: efi.c,v 1.4 2022/09/24 11:06:03 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: efi.c,v 1.4.4.1 2023/08/01 16:05:12 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -40,23 +40,10 @@ __KERNEL_RCSID(0, "$NetBSD: efi.c,v 1.4 
 #include <sys/atomic.h>
 #include <sys/efiio.h>
 
-#include <dev/efivar.h>
-
-#ifdef _LP64
-#define	EFIERR(x)		(0x8000000000000000 | x)
-#else
-#define	EFIERR(x)		(0x80000000 | x)
-#endif
+#include <uvm/uvm_extern.h>
 
-#define	EFI_SUCCESS		0
-#define	EFI_INVALID_PARAMETER	EFIERR(2)
-#define	EFI_UNSUPPORTED		EFIERR(3)
-#define	EFI_BUFFER_TOO_SMALL	EFIERR(5)
-#define	EFI_DEVICE_ERROR	EFIERR(7)
-#define	EFI_WRITE_PROTECTED	EFIERR(8)
-#define	EFI_OUT_OF_RESOURCES	EFIERR(9)
-#define	EFI_NOT_FOUND		EFIERR(14)
-#define	EFI_SECURITY_VIOLATION	EFIERR(26)
+#include <dev/efivar.h>
+#include <dev/mm.h>
 
 #include "ioconf.h"
 
@@ -149,12 +136,208 @@ efi_status_to_error(efi_status status)
 	}
 }
 
+/* XXX move to efi.h */
+#define	EFI_SYSTEM_RESOURCE_TABLE_GUID					      \
+	{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_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION	1
+
+struct EFI_SYSTEM_RESOURCE_ENTRY {
+	struct uuid	FwClass;
+	uint32_t	FwType;
+	uint32_t	FwVersion;
+	uint32_t	LowestSupportedFwVersion;
+	uint32_t	CapsuleFlags;
+	uint32_t	LastAttemptVersion;
+	uint32_t	LastAttemptStatus;
+};
+
+struct EFI_SYSTEM_RESOURCE_TABLE {
+	uint32_t	FwResourceCount;
+	uint32_t	FwResourceCountMax;
+	uint64_t	FwResourceVersion;
+	struct EFI_SYSTEM_RESOURCE_ENTRY	Entries[];
+};
+
+static void *
+efi_map_pa(uint64_t addr, bool *directp)
+{
+	paddr_t pa = addr;
+	vaddr_t va;
+
+	/*
+	 * Verify the address is not truncated by conversion to
+	 * paddr_t.  This might happen with a 64-bit EFI booting a
+	 * 32-bit OS.
+	 */
+	if (pa != addr)
+		return NULL;
+
+	/*
+	 * Try direct-map if we have it.  If it works, note that it was
+	 * direct-mapped for efi_unmap.
+	 */
+#ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS
+	if (mm_md_direct_mapped_phys(pa, &va)) {
+		*directp = true;
+		return (void *)va;
+	}
+#endif
+
+	/*
+	 * No direct map.  Reserve a page of kernel virtual address
+	 * space, with no backing, to map to the physical address.
+	 */
+	va = uvm_km_alloc(kernel_map, PAGE_SIZE, 0,
+	    UVM_KMF_VAONLY|UVM_KMF_WAITVA);
+	KASSERT(va != 0);
+
+	/*
+	 * Map the kva page to the physical address and update the
+	 * kernel pmap so we can use it.
+	 */
+	pmap_kenter_pa(va, pa, VM_PROT_READ, 0);
+	pmap_update(pmap_kernel());
+
+	/*
+	 * Success!  Return the VA and note that it was not
+	 * direct-mapped for efi_unmap.
+	 */
+	*directp = false;
+	return (void *)va;
+}
+
+static void
+efi_unmap(void *ptr, bool direct)
+{
+	vaddr_t va = (vaddr_t)ptr;
+
+	/*
+	 * If it was direct-mapped, nothing to do here.
+	 */
+	if (direct)
+		return;
+
+	/*
+	 * First remove the mapping from the kernel pmap so that it can
+	 * be reused, before we free the kva and let anyone else reuse
+	 * it.
+	 */
+	pmap_kremove(va, PAGE_SIZE);
+	pmap_update(pmap_kernel());
+
+	/*
+	 * Next free the kva so it can be reused by someone else.
+	 */
+	uvm_km_free(kernel_map, va, PAGE_SIZE, UVM_KMF_VAONLY);
+}
+
+static int
+efi_ioctl_got_table(struct efi_get_table_ioc *ioc, void *ptr, size_t len)
+{
+
+	/*
+	 * Return the actual table length.
+	 */
+	ioc->table_len = len;
+
+	/*
+	 * Copy out as much as we can into the user's allocated buffer.
+	 */
+	return copyout(ptr, ioc->buf, MIN(ioc->buf_len, len));
+}
+
+static int
+efi_ioctl_get_esrt(struct efi_get_table_ioc *ioc,
+    struct EFI_SYSTEM_RESOURCE_TABLE *tab)
+{
+
+	/*
+	 * Verify the firmware resource version is one we understand.
+	 */
+	if (tab->FwResourceVersion !=
+	    EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION)
+		return ENOENT;
+
+	/*
+	 * Verify the resource count fits within the single page we
+	 * have mapped.
+	 *
+	 * XXX What happens if it doesn't?  Are we expected to map more
+	 * than one page, according to the table header?  The UEFI spec
+	 * is unclear on this.
+	 */
+	const size_t entry_space = PAGE_SIZE -
+	    offsetof(struct EFI_SYSTEM_RESOURCE_TABLE, Entries);
+	if (tab->FwResourceCount > entry_space/sizeof(tab->Entries[0]))
+		return ENOENT;
+
+	/*
+	 * Success!  Return everything through the last table entry.
+	 */
+	const size_t len = offsetof(struct EFI_SYSTEM_RESOURCE_TABLE,
+	    Entries[tab->FwResourceCount]);
+	return efi_ioctl_got_table(ioc, tab, len);
+}
+
+static int
+efi_ioctl_get_table(struct efi_get_table_ioc *ioc)
+{
+	uint64_t addr;
+	bool direct;
+	efi_status status;
+	int error;
+
+	/*
+	 * If the platform doesn't support it yet, fail now.
+	 */
+	if (efi_ops->efi_gettab == NULL)
+		return ENODEV;
+
+	/*
+	 * Get the address of the requested table out of the EFI
+	 * configuration table.
+	 */
+	status = efi_ops->efi_gettab(&ioc->uuid, &addr);
+	if (status != EFI_SUCCESS)
+		return efi_status_to_error(status);
+
+	/*
+	 * UEFI provides no generic way to identify the size of the
+	 * table, so we have to bake knowledge of every vendor GUID
+	 * into this code to safely expose the right amount of data to
+	 * userland.
+	 *
+	 * We even have to bake knowledge of which ones are physically
+	 * addressed and which ones might be virtually addressed
+	 * according to the vendor GUID into this code, although for
+	 * the moment we never use RT->SetVirtualAddressMap so we only
+	 * ever have to deal with physical addressing.
+	 */
+	if (memcmp(&ioc->uuid, &(struct uuid)EFI_SYSTEM_RESOURCE_TABLE_GUID,
+		sizeof(ioc->uuid)) == 0) {
+		struct EFI_SYSTEM_RESOURCE_TABLE *tab;
+
+		if ((tab = efi_map_pa(addr, &direct)) == NULL)
+			return ENOENT;
+		error = efi_ioctl_get_esrt(ioc, tab);
+		efi_unmap(tab, direct);
+	} else {
+		error = ENOENT;
+	}
+
+	return error;
+}
+
 static int
 efi_ioctl_var_get(struct efi_var_ioc *var)
 {
 	uint16_t *namebuf;
 	void *databuf = NULL;
-	size_t datasize;
+	size_t databufsize;
+	unsigned long datasize;
 	efi_status status;
 	int error;
 
@@ -165,6 +348,9 @@ efi_ioctl_var_get(struct efi_var_ioc *va
 	if (var->namesize > EFI_VARNAME_MAXLENGTH) {
 		return ENOMEM;
 	}
+	if (var->datasize > ULONG_MAX) { /* XXX stricter limit */
+		return ENOMEM;
+	}
 
 	namebuf = kmem_alloc(var->namesize, KM_SLEEP);
 	error = copyin(var->name, namebuf, var->namesize);
@@ -175,23 +361,26 @@ efi_ioctl_var_get(struct efi_var_ioc *va
 		error = EINVAL;
 		goto done;
 	}
-	datasize = var->datasize;
-	if (datasize != 0) {
-		databuf = kmem_alloc(datasize, KM_SLEEP);
-		error = copyin(var->data, databuf, datasize);
+	databufsize = var->datasize;
+	if (databufsize != 0) {
+		databuf = kmem_alloc(databufsize, KM_SLEEP);
+		error = copyin(var->data, databuf, databufsize);
 		if (error != 0) {
 			goto done;
 		}
 	}
 
+	datasize = databufsize;
 	status = efi_ops->efi_getvar(namebuf, &var->vendor, &var->attrib,
-	    &var->datasize, databuf);
+	    &datasize, databuf);
 	if (status != EFI_SUCCESS && status != EFI_BUFFER_TOO_SMALL) {
 		error = efi_status_to_error(status);
 		goto done;
 	}
-	if (status == EFI_SUCCESS && databuf != NULL) {
-		error = copyout(databuf, var->data, var->datasize);
+	var->datasize = datasize;
+	if (status == EFI_SUCCESS && databufsize != 0) {
+		error = copyout(databuf, var->data,
+		    MIN(datasize, databufsize));
 	} else {
 		var->data = NULL;
 	}
@@ -199,7 +388,7 @@ efi_ioctl_var_get(struct efi_var_ioc *va
 done:
 	kmem_free(namebuf, var->namesize);
 	if (databuf != NULL) {
-		kmem_free(databuf, datasize);
+		kmem_free(databuf, databufsize);
 	}
 	return error;
 }
@@ -209,7 +398,8 @@ efi_ioctl_var_next(struct efi_var_ioc *v
 {
 	efi_status status;
 	uint16_t *namebuf;
-	size_t namesize;
+	size_t namebufsize;
+	unsigned long namesize;
 	int error;
 
 	if (var->name == NULL || var->namesize == 0) {
@@ -219,26 +409,30 @@ efi_ioctl_var_next(struct efi_var_ioc *v
 		return ENOMEM;
 	}
 
-	namesize = var->namesize;
-	namebuf = kmem_alloc(namesize, KM_SLEEP);
-	error = copyin(var->name, namebuf, namesize);
+	namebufsize = var->namesize;
+	namebuf = kmem_alloc(namebufsize, KM_SLEEP);
+	error = copyin(var->name, namebuf, namebufsize);
 	if (error != 0) {
 		goto done;
 	}
 
-	status = efi_ops->efi_nextvar(&var->namesize, namebuf, &var->vendor);
+	CTASSERT(EFI_VARNAME_MAXLENGTH <= ULONG_MAX);
+	namesize = namebufsize;
+	status = efi_ops->efi_nextvar(&namesize, namebuf, &var->vendor);
 	if (status != EFI_SUCCESS && status != EFI_BUFFER_TOO_SMALL) {
 		error = efi_status_to_error(status);
 		goto done;
 	}
+	var->namesize = namesize;
 	if (status == EFI_SUCCESS) {
-		error = copyout(namebuf, var->name, var->namesize);
+		error = copyout(namebuf, var->name,
+		    MIN(namesize, namebufsize));
 	} else {
 		var->name = NULL;
 	}
 
 done:
-	kmem_free(namebuf, namesize);
+	kmem_free(namebuf, namebufsize);
 	return error;
 }
 
@@ -289,6 +483,8 @@ efi_ioctl(dev_t dev, u_long cmd, void *d
 	KASSERT(efi_ops != NULL);
 
 	switch (cmd) {
+	case EFIIOC_GET_TABLE:
+		return efi_ioctl_get_table(data);
 	case EFIIOC_VAR_GET:
 		return efi_ioctl_var_get(data);
 	case EFIIOC_VAR_NEXT:

Index: src/sys/dev/efivar.h
diff -u src/sys/dev/efivar.h:1.1 src/sys/dev/efivar.h:1.1.4.1
--- src/sys/dev/efivar.h:1.1	Sun Oct 10 13:03:09 2021
+++ src/sys/dev/efivar.h	Tue Aug  1 16:05:12 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: efivar.h,v 1.1 2021/10/10 13:03:09 jmcneill Exp $ */
+/* $NetBSD: efivar.h,v 1.1.4.1 2023/08/01 16:05:12 martin Exp $ */
 
 /*-
  * Copyright (c) 2021 Jared McNeill <jmcne...@invisible.ca>
@@ -29,16 +29,20 @@
 #ifndef _DEV_EFIVAR_H
 #define _DEV_EFIVAR_H
 
+#include <sys/uuid.h>
+#include <sys/types.h>
+
 #include <machine/efi.h>
 
 struct efi_ops {
 	efi_status	(*efi_gettime)(struct efi_tm *, struct efi_tmcap *);
 	efi_status	(*efi_settime)(struct efi_tm *);
 	efi_status	(*efi_getvar)(uint16_t *, struct uuid *, uint32_t *,
-				      u_long *, void *);
+			    u_long *, void *);
 	efi_status	(*efi_setvar)(uint16_t *, struct uuid *, uint32_t,
-				      u_long, void *);
+			    u_long, void *);
 	efi_status	(*efi_nextvar)(u_long *, uint16_t *, struct uuid *);
+	efi_status	(*efi_gettab)(const struct uuid *, uint64_t *);
 };
 
 void	efi_register_ops(const struct efi_ops *);

Index: src/sys/dev/efi/efi.h
diff -u src/sys/dev/efi/efi.h:1.2 src/sys/dev/efi/efi.h:1.2.4.1
--- src/sys/dev/efi/efi.h:1.2	Thu Sep 22 14:46:37 2022
+++ src/sys/dev/efi/efi.h	Tue Aug  1 16:05:12 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: efi.h,v 1.2 2022/09/22 14:46:37 riastradh Exp $	*/
+/*	$NetBSD: efi.h,v 1.2.4.1 2023/08/01 16:05:12 martin Exp $	*/
 
 /*-
  * Copyright (c) 2004 Marcel Moolenaar
@@ -44,6 +44,22 @@
 #define	EFIAPI	/* empty */
 #endif
 
+#ifdef _LP64
+#define	EFIERR(x)		(0x8000000000000000 | (x))
+#else
+#define	EFIERR(x)		(0x80000000 | (x))
+#endif
+
+#define	EFI_SUCCESS		0
+#define	EFI_INVALID_PARAMETER	EFIERR(2)
+#define	EFI_UNSUPPORTED		EFIERR(3)
+#define	EFI_BUFFER_TOO_SMALL	EFIERR(5)
+#define	EFI_DEVICE_ERROR	EFIERR(7)
+#define	EFI_WRITE_PROTECTED	EFIERR(8)
+#define	EFI_OUT_OF_RESOURCES	EFIERR(9)
+#define	EFI_NOT_FOUND		EFIERR(14)
+#define	EFI_SECURITY_VIOLATION	EFIERR(26)
+
 enum efi_reset {
 	EFI_RESET_COLD,
 	EFI_RESET_WARM,

Index: src/sys/sys/efiio.h
diff -u src/sys/sys/efiio.h:1.2 src/sys/sys/efiio.h:1.2.4.1
--- src/sys/sys/efiio.h:1.2	Mon Oct 11 10:23:02 2021
+++ src/sys/sys/efiio.h	Tue Aug  1 16:05:12 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: efiio.h,v 1.2 2021/10/11 10:23:02 jmcneill Exp $ */
+/* $NetBSD: efiio.h,v 1.2.4.1 2023/08/01 16:05:12 martin Exp $ */
 
 /*-
  * Copyright (c) 2021 The NetBSD Foundation, Inc.
@@ -48,6 +48,13 @@
 #define	EFI_VARIABLE_APPEND_WRITE				0x00000040
 #define	EFI_VARIABLE_ENHANCED_AUTHENTICATED_ACCESS		0x00000080
 
+struct efi_get_table_ioc {
+	void *		buf;
+	struct uuid	uuid;
+	size_t		table_len;
+	size_t		buf_len;
+};
+
 struct efi_var_ioc {
 	uint16_t *	name;		/* vendor's variable name */
 	size_t		namesize;	/* size in bytes of the name buffer */
@@ -57,6 +64,7 @@ struct efi_var_ioc {
 	size_t		datasize;	/* size in bytes of the data buffer */
 };
 
+#define	EFIIOC_GET_TABLE	_IOWR('e', 1, struct efi_get_table_ioc)
 #define	EFIIOC_VAR_GET		_IOWR('e', 4, struct efi_var_ioc)
 #define	EFIIOC_VAR_NEXT		_IOWR('e', 5, struct efi_var_ioc)
 #define	EFIIOC_VAR_SET		_IOWR('e', 7, struct efi_var_ioc)

Reply via email to