Previous patches change the logic of the initrd discovery and the
registration of the protocol.
Instead of a config now option it now resides in an EFI variable. Adjust
the instructions of execution accordingly and add new self-tests which
will cover the new functionality.

Signed-off-by: Ilias Apalodimas <[email protected]>
---
 lib/efi_selftest/efi_selftest_load_initrd.c | 90 ++++++++++++++++++++-
 1 file changed, 88 insertions(+), 2 deletions(-)

diff --git a/lib/efi_selftest/efi_selftest_load_initrd.c 
b/lib/efi_selftest/efi_selftest_load_initrd.c
index fe060a664402..85afed55425f 100644
--- a/lib/efi_selftest/efi_selftest_load_initrd.c
+++ b/lib/efi_selftest/efi_selftest_load_initrd.c
@@ -14,10 +14,12 @@
  *
  *   CONFIG_EFI_SELFTEST=y
  *   CONFIG_EFI_LOAD_FILE2_INITRD=y
- *   CONFIG_EFI_INITRD_FILESPEC="host 0:1 initrd"
  *
- * * Run ./u-boot and execute
+ * * Create files
+ *   mkdir init_test && cp initrd init_test/
+ *   virt-make-fs -t ext4 init_test test.img
  *
+ * * Run ./u-boot and execute
  *   host bind 0 image
  *   setenv efi_selftest load initrd
  *   bootefi selftest
@@ -43,6 +45,7 @@
 #include <efi_load_initrd.h>
 
 static struct efi_boot_services *boottime;
+static struct efi_runtime_services *runtime;
 
 static struct efi_initrd_dp dp = {
        .vendor = {
@@ -80,6 +83,7 @@ static int setup(const efi_handle_t handle,
                 const struct efi_system_table *systable)
 {
        boottime = systable->boottime;
+       runtime = systable->runtime;
 
        return EFI_ST_SUCCESS;
 }
@@ -87,6 +91,7 @@ static int setup(const efi_handle_t handle,
 static int execute(void)
 {
        efi_guid_t lf2_proto_guid = EFI_LOAD_FILE2_PROTOCOL_GUID;
+       efi_guid_t efi_global_variable_guid = EFI_GLOBAL_VARIABLE_GUID;
        struct efi_load_file_protocol *lf2;
        struct efi_device_path *dp2, *dp2_invalid;
        efi_status_t status;
@@ -95,8 +100,89 @@ static int execute(void)
        efi_uintn_t buffer_size;
        void *buf;
        u32 crc32;
+       u16 boot_current = 0;
+       efi_uintn_t boot_current_size = sizeof(boot_current);
+       char path[] = "host 0 initrd";
+       char invalid_path[] = "host 1 initrd";
+       efi_uintn_t path_size = sizeof(path);
+       efi_uintn_t invalid_path_size = sizeof(invalid_path);
+       u32 attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | 
EFI_VARIABLE_RUNTIME_ACCESS;
 
        memset(buffer, 0, sizeof(buffer));
+       /* Set variable BootCurrent and Initrd#### to a wrong value */
+       status = runtime->set_variable(L"BootCurrent", 
&efi_global_variable_guid,
+                                      attrs, boot_current_size, &boot_current);
+       if (status != EFI_SUCCESS) {
+               efi_st_error("SetVariable for BootCurrent failed\n");
+               return EFI_ST_FAILURE;
+       }
+
+       /*
+        * We don't need NV for Initrd here.
+        * Set the file to an invalid file path
+        */
+       status = runtime->set_variable(L"Initrd0010", &efi_global_variable_guid,
+                                      attrs, invalid_path_size, invalid_path);
+       if (status != EFI_SUCCESS) {
+               efi_st_error("SetVariable for Initrd failed\n");
+               return EFI_ST_FAILURE;
+       }
+
+       /* We only register the protocol during efibootmgr */
+       status = efi_initrd_register();
+       if (status != EFI_SUCCESS) {
+               efi_st_error("Failed to register initrd protocol\n");
+               return EFI_ST_FAILURE;
+       }
+
+       /*
+        * We should only register the protocol if the file's found
+        * Right now both BootCurrent and file path are invalid
+        */
+       dp2 = (struct efi_device_path *)&dp;
+       status = boottime->locate_device_path(&lf2_proto_guid, &dp2, &handle);
+       if (status != EFI_NOT_FOUND) {
+               efi_st_error("Initrd protocol should't be registered\n");
+               return EFI_ST_FAILURE;
+       }
+
+       /* Update BootCurrent to the correct value */
+       boot_current = 0x0010;
+       status = runtime->set_variable(L"BootCurrent", 
&efi_global_variable_guid,
+                                      attrs, boot_current_size, &boot_current);
+       if (status != EFI_SUCCESS) {
+               efi_st_error("SetVariable for BootCurrent failed\n");
+               return EFI_ST_FAILURE;
+       }
+
+       /* re-register with invalid file path */
+       status = efi_initrd_register();
+       if (status != EFI_SUCCESS) {
+               efi_st_error("Failed to register initrd protocol\n");
+               return EFI_ST_FAILURE;
+       }
+
+       /* file path is invalid */
+       dp2 = (struct efi_device_path *)&dp;
+       status = boottime->locate_device_path(&lf2_proto_guid, &dp2, &handle);
+       if (status != EFI_NOT_FOUND) {
+               efi_st_error("Initrd protocol should't be registered\n");
+               return EFI_ST_FAILURE;
+       }
+
+       /* re-register with correct values now */
+       status = runtime->set_variable(L"Initrd0010", &efi_global_variable_guid,
+                                      attrs, path_size, path);
+       if (status != EFI_SUCCESS) {
+               efi_st_error("SetVariable for Initrd failed\n");
+               return EFI_ST_FAILURE;
+       }
+
+       status = efi_initrd_register();
+       if (status != EFI_SUCCESS) {
+               efi_st_error("Failed to register initrd protocol\n");
+               return EFI_ST_FAILURE;
+       }
 
        dp2 = (struct efi_device_path *)&dp;
        status = boottime->locate_device_path(&lf2_proto_guid, &dp2, &handle);
-- 
2.30.0.rc2

Reply via email to