summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/arm64/include/efivar.h7
-rw-r--r--sys/dev/efi/efi.c57
-rw-r--r--sys/dev/fdt/qcscm.c87
3 files changed, 128 insertions, 23 deletions
diff --git a/sys/arch/arm64/include/efivar.h b/sys/arch/arm64/include/efivar.h
index 190549a4a91..3bc3a8644a3 100644
--- a/sys/arch/arm64/include/efivar.h
+++ b/sys/arch/arm64/include/efivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: efivar.h,v 1.1 2023/01/14 12:11:11 kettenis Exp $ */
+/* $OpenBSD: efivar.h,v 1.2 2024/07/10 10:53:55 kettenis Exp $ */
/*
* Copyright (c) 2022 Mark Kettenis <kettenis@openbsd.org>
*
@@ -30,6 +30,11 @@ struct efi_softc {
struct todr_chip_handle sc_todr;
};
+
+extern EFI_GET_VARIABLE efi_get_variable;
+extern EFI_SET_VARIABLE efi_set_variable;
+extern EFI_GET_NEXT_VARIABLE_NAME efi_get_next_variable_name;
+
void efi_enter(struct efi_softc *);
void efi_leave(struct efi_softc *);
diff --git a/sys/dev/efi/efi.c b/sys/dev/efi/efi.c
index 6f8b37bb017..6be687645f8 100644
--- a/sys/dev/efi/efi.c
+++ b/sys/dev/efi/efi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: efi.c,v 1.1 2023/01/14 12:11:11 kettenis Exp $ */
+/* $OpenBSD: efi.c,v 1.2 2024/07/10 10:53:55 kettenis Exp $ */
/*
* Copyright (c) 2022 3mdeb <contact@3mdeb.com>
*
@@ -33,6 +33,10 @@ int efiioc_var_next(struct efi_softc *sc, void *);
int efiioc_var_set(struct efi_softc *sc, void *);
int efi_adapt_error(EFI_STATUS);
+EFI_GET_VARIABLE efi_get_variable;
+EFI_SET_VARIABLE efi_set_variable;
+EFI_GET_NEXT_VARIABLE_NAME efi_get_next_variable_name;
+
int
efiopen(dev_t dev, int flag, int mode, struct proc *p)
{
@@ -142,13 +146,18 @@ efiioc_var_get(struct efi_softc *sc, void *data)
goto leave;
}
- if (efi_enter_check(sc)) {
- error = ENOSYS;
- goto leave;
+ if (efi_get_variable) {
+ status = efi_get_variable(name, (EFI_GUID *)&ioc->vendor,
+ &ioc->attrib, &ioc->datasize, value);
+ } else {
+ if (efi_enter_check(sc)) {
+ error = ENOSYS;
+ goto leave;
+ }
+ status = sc->sc_rs->GetVariable(name, (EFI_GUID *)&ioc->vendor,
+ &ioc->attrib, &ioc->datasize, value);
+ efi_leave(sc);
}
- status = sc->sc_rs->GetVariable(name, (EFI_GUID *)&ioc->vendor,
- &ioc->attrib, &ioc->datasize, value);
- efi_leave(sc);
if (status == EFI_BUFFER_TOO_SMALL) {
/*
@@ -183,13 +192,18 @@ efiioc_var_next(struct efi_softc *sc, void *data)
if (error)
goto leave;
- if (efi_enter_check(sc)) {
- error = ENOSYS;
- goto leave;
+ if (efi_get_next_variable_name) {
+ status = efi_get_next_variable_name(&ioc->namesize,
+ name, (EFI_GUID *)&ioc->vendor);
+ } else {
+ if (efi_enter_check(sc)) {
+ error = ENOSYS;
+ goto leave;
+ }
+ status = sc->sc_rs->GetNextVariableName(&ioc->namesize,
+ name, (EFI_GUID *)&ioc->vendor);
+ efi_leave(sc);
}
- status = sc->sc_rs->GetNextVariableName(&ioc->namesize,
- name, (EFI_GUID *)&ioc->vendor);
- efi_leave(sc);
if (status == EFI_BUFFER_TOO_SMALL) {
/*
@@ -242,13 +256,18 @@ efiioc_var_set(struct efi_softc *sc, void *data)
goto leave;
}
- if (efi_enter_check(sc)) {
- error = ENOSYS;
- goto leave;
+ if (efi_set_variable) {
+ status = efi_set_variable(name, (EFI_GUID *)&ioc->vendor,
+ ioc->attrib, ioc->datasize, value);
+ } else {
+ if (efi_enter_check(sc)) {
+ error = ENOSYS;
+ goto leave;
+ }
+ status = sc->sc_rs->SetVariable(name, (EFI_GUID *)&ioc->vendor,
+ ioc->attrib, ioc->datasize, value);
+ efi_leave(sc);
}
- status = sc->sc_rs->SetVariable(name, (EFI_GUID *)&ioc->vendor,
- ioc->attrib, ioc->datasize, value);
- efi_leave(sc);
error = efi_adapt_error(status);
diff --git a/sys/dev/fdt/qcscm.c b/sys/dev/fdt/qcscm.c
index 50b9f9e0b23..cb7d9d466d4 100644
--- a/sys/dev/fdt/qcscm.c
+++ b/sys/dev/fdt/qcscm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: qcscm.c,v 1.7 2024/07/04 20:11:46 kettenis Exp $ */
+/* $OpenBSD: qcscm.c,v 1.8 2024/07/10 10:53:55 kettenis Exp $ */
/*
* Copyright (c) 2022 Patrick Wildt <patrick@blueri.se>
*
@@ -33,11 +33,14 @@
#include <machine/fdt.h>
#include <dev/efi/efi.h>
+#include <machine/efivar.h>
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_misc.h>
#include <dev/ofw/fdt.h>
+#include "efi.h"
+
/* #define QCSCM_DEBUG */
#define ARM_SMCCC_STD_CALL (0U << 31)
@@ -142,6 +145,12 @@ EFI_STATUS qcscm_uefi_set_variable(struct qcscm_softc *, CHAR16 *,
EFI_STATUS qcscm_uefi_get_next_variable(struct qcscm_softc *,
CHAR16 *, int *, EFI_GUID *);
+EFI_STATUS qcscm_efi_get_variable(CHAR16 *, EFI_GUID *, UINT32 *,
+ UINTN *, VOID *);
+EFI_STATUS qcscm_efi_set_variable(CHAR16 *, EFI_GUID *, UINT32,
+ UINTN, VOID *);
+EFI_STATUS qcscm_efi_get_next_variable_name(UINTN *, CHAR16 *, EFI_GUID *);
+
#ifdef QCSCM_DEBUG
void qcscm_uefi_dump_variables(struct qcscm_softc *);
void qcscm_uefi_dump_variable(struct qcscm_softc *, CHAR16 *, int,
@@ -188,6 +197,12 @@ qcscm_attach(struct device *parent, struct device *self, void *aux)
printf("\n");
qcscm_sc = sc;
+#if NEFI > 0
+ efi_get_variable = qcscm_efi_get_variable;
+ efi_set_variable = qcscm_efi_set_variable;
+ efi_get_next_variable_name = qcscm_efi_get_next_variable_name;
+#endif
+
#ifdef QCSCM_DEBUG
qcscm_uefi_dump_variables(sc);
qcscm_uefi_dump_variable(sc, u"RTCInfo", sizeof(u"RTCInfo"),
@@ -418,7 +433,7 @@ qcscm_uefi_get_variable(struct qcscm_softc *sc,
resp = QCSCM_DMA_KVA(qdm) + respoff;
if (resp->command_id != QCTEE_UEFI_GET_VARIABLE ||
- resp->length < sizeof(*resp) || resp->length > respsize) {
+ resp->length < sizeof(*resp)) {
qcscm_dmamem_free(sc, qdm);
return QCTEE_UEFI_DEVICE_ERROR;
}
@@ -433,7 +448,8 @@ qcscm_uefi_get_variable(struct qcscm_softc *sc,
return ret;
}
- if (resp->data_offset + resp->data_size > resp->length) {
+ if (resp->length > respsize ||
+ resp->data_offset + resp->data_size > resp->length) {
qcscm_dmamem_free(sc, qdm);
return QCTEE_UEFI_DEVICE_ERROR;
}
@@ -641,7 +657,71 @@ qcscm_uefi_get_next_variable(struct qcscm_softc *sc,
return QCTEE_UEFI_SUCCESS;
}
+#if NEFI > 0
+
+EFI_STATUS
+qcscm_efi_get_variable(CHAR16 *name, EFI_GUID *guid, UINT32 *attributes,
+ UINTN *data_size, VOID *data)
+{
+ struct qcscm_softc *sc = qcscm_sc;
+ EFI_STATUS status;
+ int name_size;
+ int size;
+
+ name_size = 0;
+ while (name[name_size])
+ name_size++;
+ name_size++;
+
+ size = *data_size;
+ status = qcscm_uefi_get_variable(sc, name, name_size * 2, guid,
+ attributes, data, &size);
+ *data_size = size;
+
+ /* Convert 32-bit status code to 64-bit. */
+ return ((status & 0xf0000000) << 32 | (status & 0x0fffffff));
+}
+
+EFI_STATUS
+qcscm_efi_set_variable(CHAR16 *name, EFI_GUID *guid, UINT32 attributes,
+ UINTN data_size, VOID *data)
+{
+ struct qcscm_softc *sc = qcscm_sc;
+ EFI_STATUS status;
+ int name_size;
+
+ name_size = 0;
+ while (name[name_size])
+ name_size++;
+ name_size++;
+
+ status = qcscm_uefi_set_variable(sc, name, name_size * 2, guid,
+ attributes, data, data_size);
+
+ /* Convert 32-bit status code to 64-bit. */
+ return ((status & 0xf0000000) << 32 | (status & 0x0fffffff));
+}
+
+EFI_STATUS
+qcscm_efi_get_next_variable_name(UINTN *name_size, CHAR16 *name,
+ EFI_GUID *guid)
+{
+ struct qcscm_softc *sc = qcscm_sc;
+ EFI_STATUS status;
+ int size;
+
+ size = *name_size;
+ status = qcscm_uefi_get_next_variable(sc, name, &size, guid);
+ *name_size = size;
+
+ /* Convert 32-bit status code to 64-bit. */
+ return ((status & 0xf0000000) << 32 | (status & 0x0fffffff));
+}
+
+#endif
+
#ifdef QCSCM_DEBUG
+
void
qcscm_uefi_dump_variables(struct qcscm_softc *sc)
{
@@ -699,6 +779,7 @@ qcscm_uefi_dump_variable(struct qcscm_softc *sc, CHAR16 *name, int namesize,
printf("%02x", data[i]);
printf("\n");
}
+
#endif
int