diff mbox series

[5/6] efi_selftest: Modify self-tests for initrd loading

Message ID 20201228122440.316403-6-ilias.apalodimas@linaro.org
State Superseded
Headers show
Series Change logic of EFI LoadFile2 protocol for initrd loading | expand

Commit Message

Ilias Apalodimas Dec. 28, 2020, 12:24 p.m. UTC
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 <ilias.apalodimas@linaro.org>

---
 lib/efi_selftest/efi_selftest_load_initrd.c | 90 ++++++++++++++++++++-
 1 file changed, 88 insertions(+), 2 deletions(-)

-- 
2.30.0.rc2
diff mbox series

Patch

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);