diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2018-08-19 14:09:42 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2018-08-19 14:09:42 +0000 |
commit | 2a6634e5fa59f84fb12339bd9428350db1c522f3 (patch) | |
tree | 0676a40df906f4b09df7948aab2db478209589c5 /sys/arch/arm64 | |
parent | c47a81e3448ee7f0cef25f2467b3720e9fb71a70 (diff) |
Implement "mach dtb <filename.dtb>" in efiboot(8). This way we can
provide our own FDT if the BIOS doesn't supply one, or even override
the supplied one.
Idea from and ok kettenis@
Diffstat (limited to 'sys/arch/arm64')
-rw-r--r-- | sys/arch/arm64/stand/efiboot/efiboot.c | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/sys/arch/arm64/stand/efiboot/efiboot.c b/sys/arch/arm64/stand/efiboot/efiboot.c index df21ad22758..fa8fefb75bc 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.18 2018/07/10 13:05:37 kettenis Exp $ */ +/* $OpenBSD: efiboot.c,v 1.19 2018/08/19 14:09:41 patrick Exp $ */ /* * Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net> @@ -19,6 +19,7 @@ #include <sys/param.h> #include <sys/queue.h> +#include <sys/stat.h> #include <dev/cons.h> #include <sys/disklabel.h> @@ -359,6 +360,7 @@ efi_framebuffer(void) } int acpi = 0; +void *fdt = NULL; char *bootmac = NULL; static EFI_GUID fdt_guid = FDT_TABLE_GUID; @@ -367,7 +369,6 @@ static EFI_GUID fdt_guid = FDT_TABLE_GUID; void * efi_makebootargs(char *bootargs) { - void *fdt = NULL; u_char bootduid[8]; u_char zero[8] = { 0 }; uint64_t uefi_system_table = htobe64((uintptr_t)ST); @@ -375,10 +376,12 @@ efi_makebootargs(char *bootargs) size_t len; int i; - for (i = 0; i < ST->NumberOfTableEntries; i++) { - if (efi_guidcmp(&fdt_guid, - &ST->ConfigurationTable[i].VendorGuid) == 0) - fdt = ST->ConfigurationTable[i].VendorTable; + if (fdt == NULL) { + for (i = 0; i < ST->NumberOfTableEntries; i++) { + if (efi_guidcmp(&fdt_guid, + &ST->ConfigurationTable[i].VendorGuid) == 0) + fdt = ST->ConfigurationTable[i].VendorTable; + } } if (fdt == NULL || acpi) @@ -741,11 +744,13 @@ efi_memprobe_find(UINTN pages, UINTN align, EFI_PHYSICAL_ADDRESS *addr) */ int Xacpi_efi(void); +int Xdtb_efi(void); int Xexit_efi(void); int Xpoweroff_efi(void); const struct cmd_table cmd_machine[] = { { "acpi", CMDT_CMD, Xacpi_efi }, + { "dtb", CMDT_CMD, Xdtb_efi }, { "exit", CMDT_CMD, Xexit_efi }, { "poweroff", CMDT_CMD, Xpoweroff_efi }, { NULL, 0 } @@ -759,6 +764,40 @@ Xacpi_efi(void) } int +Xdtb_efi(void) +{ + EFI_PHYSICAL_ADDRESS addr; + char path[MAXPATHLEN]; + struct stat sb; + int fd; + +#define O_RDONLY 0 + + if (cmd.argc != 2) + return (1); + + snprintf(path, sizeof(path), "%s:%s", cmd.bootdev, cmd.argv[1]); + + fd = open(path, O_RDONLY); + if (fd < 0 || fstat(fd, &sb) == -1) { + printf("cannot open %s\n", path); + return (1); + } + if (efi_memprobe_find(EFI_SIZE_TO_PAGES(sb.st_size), + 0x1000, &addr) != EFI_SUCCESS) { + printf("cannot allocate memory for %s\n", path); + return (1); + } + if (read(fd, (void *)addr, sb.st_size) != sb.st_size) { + printf("cannot read from %s\n", path); + return (1); + } + + fdt = (void *)addr; + return (0); +} + +int Xexit_efi(void) { EFI_CALL(BS->Exit, IH, 0, 0, NULL); |