From: kettenis Date: Thu, 22 Dec 2022 15:44:02 +0000 (+0000) Subject: Bring over various changes from the arm64 version of this code. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=864fc787256cef1209c4fef6ff6231dc2997f6a5;p=openbsd Bring over various changes from the arm64 version of this code. ok patrick@ --- diff --git a/sys/arch/armv7/stand/efiboot/conf.c b/sys/arch/armv7/stand/efiboot/conf.c index 9968136184a..78a416f81ce 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.32 2021/10/06 12:50:10 visa Exp $ */ +/* $OpenBSD: conf.c,v 1.33 2022/12/22 15:44:02 kettenis Exp $ */ /* * Copyright (c) 1996 Michael Shalayeff @@ -42,7 +42,7 @@ #include "efidev.h" #include "efipxe.h" -const char version[] = "1.19"; +const char version[] = "1.20"; int debug = 0; struct fs_ops file_system[] = { @@ -65,7 +65,8 @@ int ndevs = nitems(devsw); struct consdev constab[] = { { efi_cons_probe, efi_cons_init, efi_cons_getc, efi_cons_putc }, - { efi_fb_probe, efi_fb_init, efi_cons_getc, efi_cons_putc }, + { efi_com_probe, efi_com_init, efi_com_getc, efi_com_putc }, + { efi_fb_probe, efi_fb_init, efi_fb_getc, efi_fb_putc }, { NULL } }; struct consdev *cn_tab; diff --git a/sys/arch/armv7/stand/efiboot/efiboot.c b/sys/arch/armv7/stand/efiboot/efiboot.c index 134c021169c..c6bf9501ebd 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.39 2022/03/22 10:32:10 kettenis Exp $ */ +/* $OpenBSD: efiboot.c,v 1.40 2022/12/22 15:44:02 kettenis Exp $ */ /* * Copyright (c) 2015 YASUOKA Masahiko @@ -42,6 +42,9 @@ EFI_SYSTEM_TABLE *ST; EFI_BOOT_SERVICES *BS; EFI_RUNTIME_SERVICES *RS; EFI_HANDLE IH, efi_bootdp; +void *fdt_sys = NULL; +void *fdt_override = NULL; +size_t fdt_override_size; EFI_PHYSICAL_ADDRESS heap; UINTN heapsiz = 1 * 1024 * 1024; @@ -55,6 +58,9 @@ static EFI_GUID imgp_guid = LOADED_IMAGE_PROTOCOL; 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; + +#define efi_guidcmp(_a, _b) memcmp((_a), (_b), sizeof(EFI_GUID)) int efi_device_path_depth(EFI_DEVICE_PATH *dp, int); int efi_device_path_ncmp(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *, int); @@ -62,7 +68,10 @@ static void efi_heap_init(void); static void efi_memprobe_internal(void); static void efi_timer_init(void); static void efi_timer_cleanup(void); -static EFI_STATUS efi_memprobe_find(UINTN, UINTN, EFI_PHYSICAL_ADDRESS *); +static EFI_STATUS efi_memprobe_find(UINTN, UINTN, EFI_MEMORY_TYPE, + EFI_PHYSICAL_ADDRESS *); +void *efi_fdt(void); +int fdt_load_override(char *); EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) @@ -71,6 +80,7 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) EFI_LOADED_IMAGE *imgp; EFI_DEVICE_PATH *dp = NULL; EFI_STATUS status; + int i; ST = systab; BS = ST->BootServices; @@ -87,6 +97,13 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) if (status == EFI_SUCCESS) efi_bootdp = dp; + for (i = 0; i < ST->NumberOfTableEntries; i++) { + if (efi_guidcmp(&fdt_guid, + &ST->ConfigurationTable[i].VendorGuid) == 0) + fdt_sys = ST->ConfigurationTable[i].VendorTable; + } + fdt_init(fdt_sys); + progname = "BOOTARM"; boot(0); @@ -102,8 +119,8 @@ static SIMPLE_INPUT_INTERFACE *conin; * kernel. That's fine. They're just used as an index into the cdevs * array and never passed on to the kernel. */ -static dev_t serial = makedev(0, 0); -static dev_t framebuffer = makedev(1, 0); +static dev_t serial = makedev(1, 0); +static dev_t framebuffer = makedev(2, 0); static char framebuffer_path[128]; @@ -111,7 +128,7 @@ void efi_cons_probe(struct consdev *cn) { cn->cn_pri = CN_MIDPRI; - cn->cn_dev = serial; + cn->cn_dev = makedev(0, 0); } void @@ -172,6 +189,32 @@ efi_cons_putc(dev_t dev, int c) conout->OutputString(conout, buf); } +void +efi_com_probe(struct consdev *cn) +{ + cn->cn_pri = CN_LOWPRI; + cn->cn_dev = serial; +} + +void +efi_com_init(struct consdev *cn) +{ + conin = ST->ConIn; + conout = ST->ConOut; +} + +int +efi_com_getc(dev_t dev) +{ + return efi_cons_getc(dev); +} + +void +efi_com_putc(dev_t dev, int c) +{ + efi_cons_putc(dev, c); +} + void efi_fb_probe(struct consdev *cn) { @@ -435,6 +478,39 @@ efi_framebuffer(void) sizeof(framebuffer_path)); } +void +efi_console(void) +{ + void *node; + + if (major(cn_tab->cn_dev) == major(serial)) { + char *serial_path; + char alias[16]; + int len; + + /* Construct alias and resolve it. */ + snprintf(alias, sizeof(alias), "serial%d", + minor(cn_tab->cn_dev)); + node = fdt_find_node("/aliases"); + len = fdt_node_property(node, alias, &serial_path); + if (len <= 0) + return; + + /* Point stdout-path at the serial node. */ + node = fdt_find_node("/chosen"); + fdt_node_add_property(node, "stdout-path", + serial_path, strlen(serial_path) + 1); + } else if (major(cn_tab->cn_dev) == major(framebuffer)) { + if (strlen(framebuffer_path) == 0) + return; + + /* Point stdout-path at the framebuffer node. */ + node = fdt_find_node("/chosen"); + fdt_node_add_property(node, "stdout-path", + framebuffer_path, strlen(framebuffer_path) + 1); + } +} + uint64_t dma_constraint[2] = { 0, -1 }; void @@ -457,28 +533,7 @@ efi_dma_constraint(void) dma_constraint, sizeof(dma_constraint)); } -void -efi_console(void) -{ - void *node; - - if (cn_tab->cn_dev != framebuffer) - return; - - if (strlen(framebuffer_path) == 0) - return; - - /* Point stdout-path at the framebuffer node. */ - node = fdt_find_node("/chosen"); - fdt_node_add_property(node, "stdout-path", - framebuffer_path, strlen(framebuffer_path) + 1); -} - -void *fdt = NULL; char *bootmac = NULL; -static EFI_GUID fdt_guid = FDT_TABLE_GUID; - -#define efi_guidcmp(_a, _b) memcmp((_a), (_b), sizeof(EFI_GUID)) void * efi_makebootargs(char *bootargs, int howto) @@ -488,17 +543,12 @@ efi_makebootargs(char *bootargs, int howto) uint64_t uefi_system_table = htobe64((uintptr_t)ST); uint32_t boothowto = htobe32(howto); EFI_PHYSICAL_ADDRESS addr; - void *node; + void *node, *fdt; size_t len; - int i; - 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; - } - } + fdt = efi_fdt(); + if (fdt == NULL) + return NULL; if (!fdt_get_size(fdt)) return NULL; @@ -514,10 +564,15 @@ efi_makebootargs(char *bootargs, int howto) if (!fdt_init(fdt)) return NULL; + /* Create common nodes which might not exist when using mach dtb */ + node = fdt_find_node("/aliases"); + if (node == NULL) + fdt_node_add_node(fdt_find_node("/"), "aliases", &node); node = fdt_find_node("/chosen"); - if (!node) - return NULL; + if (node == NULL) + fdt_node_add_node(fdt_find_node("/"), "chosen", &node); + node = fdt_find_node("/chosen"); len = strlen(bootargs) + 1; fdt_node_add_property(node, "bootargs", bootargs, len); fdt_node_add_property(node, "openbsd,boothowto", @@ -591,6 +646,7 @@ machdep(void) EFI_STATUS status; cninit(); + efi_heap_init(); /* * The kernel expects to be loaded at offset 0x00300000 into a @@ -609,7 +665,6 @@ machdep(void) if (efi_loadaddr == 0) printf("Can't allocate memory\n"); - efi_heap_init(); efi_timer_init(); efi_diskprobe(); efi_pxeprobe(); @@ -714,7 +769,7 @@ devboot(dev_t dev, char *p) p[2] = '0' + sd_boot_vol; } -const char cdevs[][4] = { "com", "fb" }; +const char cdevs[][4] = { "cons", "com", "fb" }; const int ncdevs = nitems(cdevs); int @@ -872,7 +927,8 @@ efi_memprobe_internal(void) } static EFI_STATUS -efi_memprobe_find(UINTN pages, UINTN align, EFI_PHYSICAL_ADDRESS *addr) +efi_memprobe_find(UINTN pages, UINTN align, EFI_MEMORY_TYPE type, + EFI_PHYSICAL_ADDRESS *addr) { EFI_MEMORY_DESCRIPTOR *mm; int i, j; @@ -900,7 +956,7 @@ efi_memprobe_find(UINTN pages, UINTN align, EFI_PHYSICAL_ADDRESS *addr) if (paddr & (align - 1)) continue; - if (BS->AllocatePages(AllocateAddress, EfiLoaderData, + if (BS->AllocatePages(AllocateAddress, type, pages, &paddr) == EFI_SUCCESS) { *addr = paddr; return EFI_SUCCESS; @@ -910,51 +966,123 @@ efi_memprobe_find(UINTN pages, UINTN align, EFI_PHYSICAL_ADDRESS *addr) return EFI_OUT_OF_RESOURCES; } -/* - * Commands - */ +int +mdrandom(char *buf, size_t buflen) +{ + char *random; + void *node; + int i, len, ret = -1; -int Xdtb_efi(void); -int Xexit_efi(void); -int Xpoweroff_efi(void); + node = fdt_find_node("/chosen"); + if (!node) + return -1; -const struct cmd_table cmd_machine[] = { - { "dtb", CMDT_CMD, Xdtb_efi }, - { "exit", CMDT_CMD, Xexit_efi }, - { "poweroff", CMDT_CMD, Xpoweroff_efi }, - { NULL, 0 } -}; + len = fdt_node_property(node, "rng-seed", &random); + if (len > 0) { + for (i = 0; i < buflen; i++) + buf[i] ^= random[i % len]; + ret = 0; + } + + len = fdt_node_property(node, "kaslr-seed", &random); + if (len > 0) { + for (i = 0; i < buflen; i++) + buf[i] ^= random[i % len]; + ret = 0; + } + + return ret; +} + +void * +efi_fdt(void) +{ + /* 'mach dtb' has precedence */ + if (fdt_override != NULL) + return fdt_override; + + return fdt_sys; +} int -Xdtb_efi(void) +fdt_load_override(char *file) { EFI_PHYSICAL_ADDRESS addr; char path[MAXPATHLEN]; struct stat sb; int fd; - if (cmd.argc != 2) - return (1); + if (file == NULL && fdt_override) { + BS->FreePages((uint64_t)fdt_override, + EFI_SIZE_TO_PAGES(fdt_override_size)); + fdt_override = NULL; + fdt_init(fdt_sys); + return 0; + } - snprintf(path, sizeof(path), "%s:%s", cmd.bootdev, cmd.argv[1]); + snprintf(path, sizeof(path), "%s:%s", cmd.bootdev, file); fd = open(path, O_RDONLY); if (fd < 0 || fstat(fd, &sb) == -1) { printf("cannot open %s\n", path); - return (1); + return 0; } if (efi_memprobe_find(EFI_SIZE_TO_PAGES(sb.st_size), - 0x1000, &addr) != EFI_SUCCESS) { + PAGE_SIZE, EfiLoaderData, &addr) != EFI_SUCCESS) { printf("cannot allocate memory for %s\n", path); - return (1); + return 0; } if (read(fd, (void *)addr, sb.st_size) != sb.st_size) { printf("cannot read from %s\n", path); - return (1); + return 0; } - fdt = (void *)addr; - return (0); + if (!fdt_init((void *)addr)) { + printf("invalid device tree\n"); + BS->FreePages(addr, EFI_SIZE_TO_PAGES(sb.st_size)); + return 0; + } + + if (fdt_override) { + BS->FreePages((uint64_t)fdt_override, + EFI_SIZE_TO_PAGES(fdt_override_size)); + fdt_override = NULL; + } + + fdt_override = (void *)addr; + fdt_override_size = sb.st_size; + return 0; +} + +/* + * Commands + */ + +int Xdtb_efi(void); +int Xexit_efi(void); +int Xpoweroff_efi(void); + +const struct cmd_table cmd_machine[] = { + { "dtb", CMDT_CMD, Xdtb_efi }, + { "exit", CMDT_CMD, Xexit_efi }, + { "poweroff", CMDT_CMD, Xpoweroff_efi }, + { NULL, 0 } +}; + +int +Xdtb_efi(void) +{ + if (cmd.argc == 1) { + fdt_load_override(NULL); + return (0); + } + + if (cmd.argc != 2) { + printf("dtb file\n"); + return (0); + } + + return fdt_load_override(cmd.argv[1]); } int diff --git a/sys/arch/armv7/stand/efiboot/efiboot.h b/sys/arch/armv7/stand/efiboot/efiboot.h index 8ec6783f574..67dddde51ce 100644 --- a/sys/arch/armv7/stand/efiboot/efiboot.h +++ b/sys/arch/armv7/stand/efiboot/efiboot.h @@ -1,4 +1,4 @@ -/* $OpenBSD: efiboot.h,v 1.7 2020/05/17 14:32:12 kettenis Exp $ */ +/* $OpenBSD: efiboot.h,v 1.8 2022/12/22 15:44:02 kettenis Exp $ */ /* * Copyright (c) 2015 YASUOKA Masahiko @@ -24,6 +24,10 @@ void efi_cons_probe(struct consdev *); void efi_cons_init(struct consdev *); int efi_cons_getc(dev_t); void efi_cons_putc(dev_t, int); +void efi_com_probe(struct consdev *); +void efi_com_init(struct consdev *); +int efi_com_getc(dev_t); +void efi_com_putc(dev_t, int); void efi_fb_probe(struct consdev *); void efi_fb_init(struct consdev *); int efi_fb_getc(dev_t);