This diff makes BOOTAA64.EFI pass the address of the EFI system table
and information about the EFI memory map to the kernel. This is done
by adding several properties to the /chosen node. This matches what
Linux does (see Documentation/arm/uefi.txt) except that the properties
have an "openbsd," prefix instead of "linux,".
This is a first step towards adding support for EFI runtime services
(to access the RTC on the Overdrive machines) and (shudder) ACPI.
ok?
Index: sys/arch/arm64/stand/efiboot/conf.c
===================================================================
RCS file: /cvs/src/sys/arch/arm64/stand/efiboot/conf.c,v
retrieving revision 1.2
diff -u -p -r1.2 conf.c
--- sys/arch/arm64/stand/efiboot/conf.c 8 Feb 2017 09:18:24 -0000 1.2
+++ sys/arch/arm64/stand/efiboot/conf.c 6 May 2017 21:09:29 -0000
@@ -35,7 +35,7 @@
#include "efiboot.h"
#include "efidev.h"
-const char version[] = "0.2";
+const char version[] = "0.3";
int debug = 0;
struct fs_ops file_system[] = {
Index: sys/arch/arm64/stand/efiboot/efiboot.c
===================================================================
RCS file: /cvs/src/sys/arch/arm64/stand/efiboot/efiboot.c,v
retrieving revision 1.6
diff -u -p -r1.6 efiboot.c
--- sys/arch/arm64/stand/efiboot/efiboot.c 11 Mar 2017 09:09:14 -0000
1.6
+++ sys/arch/arm64/stand/efiboot/efiboot.c 6 May 2017 21:09:29 -0000
@@ -46,6 +46,7 @@ EFI_MEMORY_DESCRIPTOR *mmap = NULL;
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;
@@ -233,8 +234,9 @@ void *
efi_makebootargs(char *bootargs)
{
void *fdt = NULL;
- char bootduid[8];
- u_char zero[8];
+ u_char bootduid[8];
+ u_char zero[8] = { 0 };
+ uint64_t uefi_system_table = htobe64((uintptr_t)ST);
void *node;
size_t len;
int i;
@@ -256,18 +258,53 @@ efi_makebootargs(char *bootargs)
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();
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
@@ -303,6 +340,7 @@ efi_cleanup(void)
/* 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;
@@ -512,6 +550,7 @@ efi_memprobe_internal(void)
mmap_key = mapkey;
mmap_ndesc = n;
mmap_descsiz = mmsiz;
+ mmap_version = mmver;
}
/*
Index: sys/arch/arm64/stand/efiboot/fdt.c
===================================================================
RCS file: /cvs/src/sys/arch/arm64/stand/efiboot/fdt.c,v
retrieving revision 1.1
diff -u -p -r1.1 fdt.c
--- sys/arch/arm64/stand/efiboot/fdt.c 17 Dec 2016 23:38:33 -0000 1.1
+++ sys/arch/arm64/stand/efiboot/fdt.c 6 May 2017 21:09:29 -0000
@@ -219,7 +219,7 @@ fdt_node_property(void *node, char *name
}
int
-fdt_node_set_property(void *node, char *name, char *data, int len)
+fdt_node_set_property(void *node, char *name, void *data, int len)
{
uint32_t *ptr, *next;
uint32_t nameid;
@@ -263,7 +263,7 @@ fdt_node_set_property(void *node, char *
}
int
-fdt_node_add_property(void *node, char *name, char *data, int len)
+fdt_node_add_property(void *node, char *name, void *data, int len)
{
char *dummy;
Index: sys/arch/arm64/stand/efiboot/fdt.h
===================================================================
RCS file: /cvs/src/sys/arch/arm64/stand/efiboot/fdt.h,v
retrieving revision 1.1
diff -u -p -r1.1 fdt.h
--- sys/arch/arm64/stand/efiboot/fdt.h 17 Dec 2016 23:38:33 -0000 1.1
+++ sys/arch/arm64/stand/efiboot/fdt.h 6 May 2017 21:09:29 -0000
@@ -57,8 +57,8 @@ void *fdt_child_node(void *);
char *fdt_node_name(void *);
void *fdt_find_node(char *);
int fdt_node_property(void *, char *, char **);
-int fdt_node_set_property(void *, char *, char *, int);
-int fdt_node_add_property(void *, char *, char *, int);
+int fdt_node_set_property(void *, char *, void *, int);
+int fdt_node_add_property(void *, char *, void *, int);
void *fdt_parent_node(void *);
int fdt_node_is_compatible(void *, const char *);
#ifdef DEBUG