summaryrefslogtreecommitdiff
path: root/sys/arch/armv7
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2024-06-17 09:12:46 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2024-06-17 09:12:46 +0000
commit84de9ae8600167f54ef1831620a35c4a7057a6ba (patch)
treecca10f2285db4845908eec4ddaac3069f3a4e86e /sys/arch/armv7
parentfc7ebe6f53f705c9e33e7a1f151664bd515543f4 (diff)
When loading a device tree using the "mach dtb" command, give firmware
a chance to make modifications (such as applying memory reservations) by using the EFI devicetree fixup protocol. ok jca@
Diffstat (limited to 'sys/arch/armv7')
-rw-r--r--sys/arch/armv7/stand/efiboot/conf.c4
-rw-r--r--sys/arch/armv7/stand/efiboot/efiboot.c26
-rw-r--r--sys/arch/armv7/stand/efiboot/efidt.h44
3 files changed, 68 insertions, 6 deletions
diff --git a/sys/arch/armv7/stand/efiboot/conf.c b/sys/arch/armv7/stand/efiboot/conf.c
index de536fb9620..4143b4f5c46 100644
--- a/sys/arch/armv7/stand/efiboot/conf.c
+++ b/sys/arch/armv7/stand/efiboot/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.35 2024/03/10 15:37:54 kettenis Exp $ */
+/* $OpenBSD: conf.c,v 1.36 2024/06/17 09:12:45 kettenis Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff
@@ -42,7 +42,7 @@
#include "efidev.h"
#include "efipxe.h"
-const char version[] = "1.22";
+const char version[] = "1.23";
int debug = 0;
struct fs_ops file_system[] = {
diff --git a/sys/arch/armv7/stand/efiboot/efiboot.c b/sys/arch/armv7/stand/efiboot/efiboot.c
index c6bf9501ebd..0e5ac7dcaa5 100644
--- a/sys/arch/armv7/stand/efiboot/efiboot.c
+++ b/sys/arch/armv7/stand/efiboot/efiboot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: efiboot.c,v 1.40 2022/12/22 15:44:02 kettenis Exp $ */
+/* $OpenBSD: efiboot.c,v 1.41 2024/06/17 09:12:45 kettenis Exp $ */
/*
* Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
@@ -36,6 +36,7 @@
#include "efidev.h"
#include "efiboot.h"
+#include "efidt.h"
#include "fdt.h"
EFI_SYSTEM_TABLE *ST;
@@ -59,6 +60,7 @@ static EFI_GUID blkio_guid = BLOCK_IO_PROTOCOL;
static EFI_GUID devp_guid = DEVICE_PATH_PROTOCOL;
static EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
static EFI_GUID fdt_guid = FDT_TABLE_GUID;
+static EFI_GUID dt_fixup_guid = EFI_DT_FIXUP_PROTOCOL_GUID;
#define efi_guidcmp(_a, _b) memcmp((_a), (_b), sizeof(EFI_GUID))
@@ -1004,12 +1006,18 @@ efi_fdt(void)
return fdt_sys;
}
+#define EXTRA_DT_SPACE (32 * 1024)
+
int
fdt_load_override(char *file)
{
+ EFI_DT_FIXUP_PROTOCOL *dt_fixup;
EFI_PHYSICAL_ADDRESS addr;
char path[MAXPATHLEN];
+ EFI_STATUS status;
struct stat sb;
+ size_t dt_size;
+ UINTN sz;
int fd;
if (file == NULL && fdt_override) {
@@ -1027,7 +1035,8 @@ fdt_load_override(char *file)
printf("cannot open %s\n", path);
return 0;
}
- if (efi_memprobe_find(EFI_SIZE_TO_PAGES(sb.st_size),
+ dt_size = sb.st_size + EXTRA_DT_SPACE;
+ if (efi_memprobe_find(EFI_SIZE_TO_PAGES(dt_size),
PAGE_SIZE, EfiLoaderData, &addr) != EFI_SUCCESS) {
printf("cannot allocate memory for %s\n", path);
return 0;
@@ -1037,9 +1046,18 @@ fdt_load_override(char *file)
return 0;
}
+ status = BS->LocateProtocol(&dt_fixup_guid, NULL, (void **)&dt_fixup);
+ if (status == EFI_SUCCESS) {
+ sz = dt_size;
+ status = dt_fixup->Fixup(dt_fixup, (void *)addr, &sz,
+ EFI_DT_APPLY_FIXUPS | EFI_DT_RESERVE_MEMORY);
+ if (status != EFI_SUCCESS)
+ panic("DT fixup failed: 0x%lx", status);
+ }
+
if (!fdt_init((void *)addr)) {
printf("invalid device tree\n");
- BS->FreePages(addr, EFI_SIZE_TO_PAGES(sb.st_size));
+ BS->FreePages(addr, EFI_SIZE_TO_PAGES(dt_size));
return 0;
}
@@ -1050,7 +1068,7 @@ fdt_load_override(char *file)
}
fdt_override = (void *)addr;
- fdt_override_size = sb.st_size;
+ fdt_override_size = dt_size;
return 0;
}
diff --git a/sys/arch/armv7/stand/efiboot/efidt.h b/sys/arch/armv7/stand/efiboot/efidt.h
new file mode 100644
index 00000000000..8a2ab0d2c34
--- /dev/null
+++ b/sys/arch/armv7/stand/efiboot/efidt.h
@@ -0,0 +1,44 @@
+/* $OpenBSD: efidt.h,v 1.1 2024/06/17 09:12:45 kettenis Exp $ */
+
+/*
+ * Copyright (c) 2024 Mark Kettenis <kettenis@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 <efi.h>
+#include <efiapi.h>
+
+#define EFI_DT_FIXUP_PROTOCOL_GUID \
+ { 0xe617d64c, 0xfe08, 0x46da, \
+ { 0xf4, 0xdc, 0xbb, 0xd5, 0x87, 0x0c, 0x73, 0x00 } }
+
+INTERFACE_DECL(_EFI_DT_FIXUP_PROTOCOL);
+
+typedef EFI_STATUS
+(EFIAPI *EFI_DT_FIXUP) (
+ IN struct _EFI_DT_FIXUP_PROTOCOL *This,
+ IN VOID *Fdt,
+ IN OUT UINTN *BufferSize,
+ IN UINT32 Flags
+ );
+
+#define EFI_DT_APPLY_FIXUPS 0x00000001
+#define EFI_DT_RESERVE_MEMORY 0x00000002
+
+typedef struct _EFI_DT_FIXUP_PROTOCOL {
+ UINT64 Revision;
+ EFI_DT_FIXUP Fixup;
+} EFI_DT_FIXUP_PROTOCOL;