From 296cb5dff06f595c2590ca32bcbf365ed75f9d99 Mon Sep 17 00:00:00 2001 From: kettenis Date: Fri, 14 Jun 2024 19:49:17 +0000 Subject: [PATCH] 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 patrick@, jca@ --- sys/arch/arm64/stand/efiboot/conf.c | 4 +-- sys/arch/arm64/stand/efiboot/efiboot.c | 26 ++++++++++++--- sys/arch/arm64/stand/efiboot/efidt.h | 44 ++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 sys/arch/arm64/stand/efiboot/efidt.h diff --git a/sys/arch/arm64/stand/efiboot/conf.c b/sys/arch/arm64/stand/efiboot/conf.c index 770bf2e1a5d..a1174dc8b57 100644 --- a/sys/arch/arm64/stand/efiboot/conf.c +++ b/sys/arch/arm64/stand/efiboot/conf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: conf.c,v 1.47 2023/10/26 14:13:37 jsg Exp $ */ +/* $OpenBSD: conf.c,v 1.48 2024/06/14 19:49:17 kettenis Exp $ */ /* * Copyright (c) 1996 Michael Shalayeff @@ -47,7 +47,7 @@ #include "efipxe.h" #include "softraid_arm64.h" -const char version[] = "1.18"; +const char version[] = "1.19"; int debug = 0; struct fs_ops file_system[] = { diff --git a/sys/arch/arm64/stand/efiboot/efiboot.c b/sys/arch/arm64/stand/efiboot/efiboot.c index 7d1c1b7ca4e..0bae1402657 100644 --- a/sys/arch/arm64/stand/efiboot/efiboot.c +++ b/sys/arch/arm64/stand/efiboot/efiboot.c @@ -1,4 +1,4 @@ -/* $OpenBSD: efiboot.c,v 1.50 2024/02/23 21:52:12 kettenis Exp $ */ +/* $OpenBSD: efiboot.c,v 1.51 2024/06/14 19:49:17 kettenis Exp $ */ /* * Copyright (c) 2015 YASUOKA Masahiko @@ -41,6 +41,7 @@ #include "efidev.h" #include "efiboot.h" +#include "efidt.h" #include "fdt.h" EFI_SYSTEM_TABLE *ST; @@ -67,6 +68,7 @@ static EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; static EFI_GUID fdt_guid = FDT_TABLE_GUID; static EFI_GUID smbios_guid = SMBIOS_TABLE_GUID; static EFI_GUID smbios3_guid = SMBIOS3_TABLE_GUID; +static EFI_GUID dt_fixup_guid = EFI_DT_FIXUP_PROTOCOL_GUID; #define efi_guidcmp(_a, _b) memcmp((_a), (_b), sizeof(EFI_GUID)) @@ -1134,12 +1136,18 @@ efi_fdt(void) return fdt_override ? fdt_override : 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) { @@ -1157,7 +1165,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; @@ -1167,9 +1176,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; } @@ -1180,7 +1198,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/arm64/stand/efiboot/efidt.h b/sys/arch/arm64/stand/efiboot/efidt.h new file mode 100644 index 00000000000..537c08c85c6 --- /dev/null +++ b/sys/arch/arm64/stand/efiboot/efidt.h @@ -0,0 +1,44 @@ +/* $OpenBSD: efidt.h,v 1.1 2024/06/14 19:49:17 kettenis Exp $ */ + +/* + * Copyright (c) 2024 Mark Kettenis + * + * 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 + +#include +#include + +#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; -- 2.20.1