diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2024-06-17 09:12:46 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2024-06-17 09:12:46 +0000 |
commit | 84de9ae8600167f54ef1831620a35c4a7057a6ba (patch) | |
tree | cca10f2285db4845908eec4ddaac3069f3a4e86e /sys/arch/armv7 | |
parent | fc7ebe6f53f705c9e33e7a1f151664bd515543f4 (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.c | 4 | ||||
-rw-r--r-- | sys/arch/armv7/stand/efiboot/efiboot.c | 26 | ||||
-rw-r--r-- | sys/arch/armv7/stand/efiboot/efidt.h | 44 |
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; |