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

Reply via email to