summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2017-08-21 20:05:33 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2017-08-21 20:05:33 +0000
commit267989b4b7db6c523237dbb06a91a07717467423 (patch)
treedfbb7a6a286f7e56aa9ddeac63a9859fafdf2a00 /sys
parent1670b0f2cd363c6a5c19785ee1b99a42feb3b939 (diff)
Pass the address of the EFI system table and the EFI memory map through
properties in the /chosen node of the FDT. The properties match the ones used by Linux (see Documentation/arm/uefi.txt in the Linux kernel source tree) but with the "linux," prefix replaced by "openbsd,". While there, reduce the diffs to the arm64 efiboot. ok tom@, jsg@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/armv7/stand/efiboot/conf.c4
-rw-r--r--sys/arch/armv7/stand/efiboot/efiboot.c99
2 files changed, 92 insertions, 11 deletions
diff --git a/sys/arch/armv7/stand/efiboot/conf.c b/sys/arch/armv7/stand/efiboot/conf.c
index b8391d4bee0..da04d738e19 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.10 2017/08/07 19:34:53 kettenis Exp $ */
+/* $OpenBSD: conf.c,v 1.11 2017/08/21 20:05:32 kettenis Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff
@@ -35,7 +35,7 @@
#include "efiboot.h"
#include "efidev.h"
-const char version[] = "0.9";
+const char version[] = "1.0";
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 d3209715da4..dbc434da7bf 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.18 2017/08/07 19:34:53 kettenis Exp $ */
+/* $OpenBSD: efiboot.c,v 1.19 2017/08/21 20:05:32 kettenis Exp $ */
/*
* Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
@@ -38,9 +38,15 @@
EFI_SYSTEM_TABLE *ST;
EFI_BOOT_SERVICES *BS;
EFI_RUNTIME_SERVICES *RS;
-EFI_HANDLE IH;
+EFI_HANDLE IH, efi_bootdp;
-EFI_HANDLE efi_bootdp;
+EFI_PHYSICAL_ADDRESS heap;
+UINTN heapsiz = 1 * 1024 * 1024;
+EFI_MEMORY_DESCRIPTOR *mmap;
+UINTN mmap_key;
+UINTN mmap_ndesc;
+UINTN mmap_descsiz;
+UINT32 mmap_version;
static EFI_GUID imgp_guid = LOADED_IMAGE_PROTOCOL;
static EFI_GUID blkio_guid = BLOCK_IO_PROTOCOL;
@@ -48,6 +54,8 @@ static EFI_GUID devp_guid = DEVICE_PATH_PROTOCOL;
static int efi_device_path_depth(EFI_DEVICE_PATH *dp, int);
static int efi_device_path_ncmp(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *, int);
+static void efi_heap_init(void);
+static void efi_memprobe_internal(void);
static void efi_timer_init(void);
static void efi_timer_cleanup(void);
@@ -146,9 +154,6 @@ efi_cons_putc(dev_t dev, int c)
conout->OutputString(conout, buf);
}
-EFI_PHYSICAL_ADDRESS heap;
-UINTN heapsiz = 1 * 1024 * 1024;
-
static void
efi_heap_init(void)
{
@@ -284,7 +289,8 @@ efi_makebootargs(char *bootargs, uint32_t *board_id)
{
void *fdt = NULL;
u_char bootduid[8];
- u_char zero[8];
+ u_char zero[8] = { 0 };
+ uint64_t uefi_system_table = htobe64((uintptr_t)ST);
void *node;
size_t len;
int i;
@@ -306,13 +312,22 @@ efi_makebootargs(char *bootargs, uint32_t *board_id)
fdt_node_add_property(node, "bootargs", bootargs, len);
/* Pass DUID of the boot disk. */
- memset(&zero, 0, sizeof(zero));
memcpy(&bootduid, diskinfo.disklabel.d_uid, sizeof(bootduid));
if (memcmp(bootduid, zero, sizeof(bootduid)) != 0) {
fdt_node_add_property(node, "openbsd,bootduid", bootduid,
sizeof(bootduid));
}
+ /* Pass EFI system table. */
+ fdt_node_add_property(node, "openbsd,uefi-system-table",
+ &uefi_system_table, sizeof(uefi_system_table));
+
+ /* Placeholders for EFI memory map. */
+ fdt_node_add_property(node, "openbsd,uefi-mmap-start", zero, 8);
+ fdt_node_add_property(node, "openbsd,uefi-mmap-size", zero, 4);
+ fdt_node_add_property(node, "openbsd,uefi-mmap-desc-size", zero, 4);
+ fdt_node_add_property(node, "openbsd,uefi-mmap-desc-ver", zero, 4);
+
fdt_finalize();
node = fdt_find_node("/");
@@ -326,6 +341,32 @@ efi_makebootargs(char *bootargs, uint32_t *board_id)
return fdt;
}
+void
+efi_updatefdt(void)
+{
+ uint64_t uefi_mmap_start = htobe64((uintptr_t)mmap);
+ uint32_t uefi_mmap_size = htobe32(mmap_ndesc * mmap_descsiz);
+ uint32_t uefi_mmap_desc_size = htobe32(mmap_descsiz);
+ uint32_t uefi_mmap_desc_ver = htobe32(mmap_version);
+ void *node;
+
+ node = fdt_find_node("/chosen");
+ if (!node)
+ return;
+
+ /* Pass EFI memory map. */
+ fdt_node_set_property(node, "openbsd,uefi-mmap-start",
+ &uefi_mmap_start, sizeof(uefi_mmap_start));
+ fdt_node_set_property(node, "openbsd,uefi-mmap-size",
+ &uefi_mmap_size, sizeof(uefi_mmap_size));
+ fdt_node_set_property(node, "openbsd,uefi-mmap-desc-size",
+ &uefi_mmap_desc_size, sizeof(uefi_mmap_desc_size));
+ fdt_node_set_property(node, "openbsd,uefi-mmap-desc-ver",
+ &uefi_mmap_desc_ver, sizeof(uefi_mmap_desc_ver));
+
+ fdt_finalize();
+}
+
u_long efi_loadaddr;
void
@@ -361,9 +402,21 @@ machdep(void)
void
efi_cleanup(void)
{
+ int retry;
+ EFI_STATUS status;
+
efi_timer_cleanup();
- BS->ExitBootServices(NULL, 0);
+ /* retry once in case of failure */
+ for (retry = 1; retry >= 0; retry--) {
+ efi_memprobe_internal(); /* sync the current map */
+ efi_updatefdt();
+ status = EFI_CALL(BS->ExitBootServices, IH, mmap_key);
+ if (status == EFI_SUCCESS)
+ break;
+ if (retry == 0)
+ panic("ExitBootServices failed (%d)", status);
+ }
}
void
@@ -543,6 +596,34 @@ devopen(struct open_file *f, const char *fname, char **file)
return (*dp->dv_open)(f, unit, part);
}
+static void
+efi_memprobe_internal(void)
+{
+ EFI_STATUS status;
+ UINTN mapkey, mmsiz, siz;
+ UINT32 mmver;
+ EFI_MEMORY_DESCRIPTOR *mm;
+ int n;
+
+ free(mmap, mmap_ndesc * mmap_descsiz);
+
+ siz = 0;
+ status = EFI_CALL(BS->GetMemoryMap, &siz, NULL, &mapkey, &mmsiz,
+ &mmver);
+ if (status != EFI_BUFFER_TOO_SMALL)
+ panic("cannot get the size of memory map");
+ mm = alloc(siz);
+ status = EFI_CALL(BS->GetMemoryMap, &siz, mm, &mapkey, &mmsiz, &mmver);
+ if (status != EFI_SUCCESS)
+ panic("cannot get the memory map");
+ n = siz / mmsiz;
+ mmap = mm;
+ mmap_key = mapkey;
+ mmap_ndesc = n;
+ mmap_descsiz = mmsiz;
+ mmap_version = mmver;
+}
+
/*
* Commands
*/