diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2024-06-14 19:49:18 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2024-06-14 19:49:18 +0000 |
commit | cc707ac10543c81baebe12b11d94dc40c9f018b3 (patch) | |
tree | 5e3f140625025a627300e94a45e847f502f6d483 /sys | |
parent | db2cd38622913ac7598f6fcebbc3b98e380278cc (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 patrick@, jca@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/arm64/stand/efiboot/conf.c | 4 | ||||
-rw-r--r-- | sys/arch/arm64/stand/efiboot/efiboot.c | 26 | ||||
-rw-r--r-- | sys/arch/arm64/stand/efiboot/efidt.h | 44 |
3 files changed, 68 insertions, 6 deletions
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 <yasuoka@yasuoka.net> @@ -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 <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; |