Merge tag 'efi-2022-01-rc3-2' of https://source.denx.de/u-boot/custodians/u-boot-efi

Pull request for efi-2022-01-rc3-2

Test:
* fix pylint warnings

UEFI:
* disable interrupts before removing devices in ExitBootServices()
* implement poweroff in efi_system_reset() on sandbox
* allow booting via EFI even if some block device fails
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index a74f5ec..13b0731 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -434,8 +434,10 @@
 		efi_status_t reset_status,
 		unsigned long data_size, void *reset_data)
 {
-	os_fd_restore();
-	os_relaunch(os_argv);
+	if (reset_type == EFI_RESET_SHUTDOWN)
+		sandbox_exit();
+	else
+		sandbox_reset();
 }
 
 void sandbox_reset(void)
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 6fdd0ef..8492b73 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -2167,6 +2167,7 @@
 	}
 
 	if (!efi_st_keep_devices) {
+		bootm_disable_interrupts();
 		if (IS_ENABLED(CONFIG_USB_DEVICE))
 			udc_disconnect();
 		board_quiesce_devices();
@@ -2179,9 +2180,6 @@
 	/* Fix up caches for EFI payloads if necessary */
 	efi_exit_caches();
 
-	/* This stops all lingering devices */
-	bootm_disable_interrupts();
-
 	/* Disable boot time services */
 	systab.con_in_handle = NULL;
 	systab.con_in = NULL;
diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
index 502bcfc..8301eed 100644
--- a/lib/efi_loader/efi_capsule.c
+++ b/lib/efi_loader/efi_capsule.c
@@ -1037,30 +1037,45 @@
 }
 
 /**
- * check_run_capsules - Check whether capsule update should run
+ * check_run_capsules() - check whether capsule update should run
  *
  * The spec says OsIndications must be set in order to run the capsule update
  * on-disk.  Since U-Boot doesn't support runtime SetVariable, allow capsules to
  * run explicitly if CONFIG_EFI_IGNORE_OSINDICATIONS is selected
+ *
+ * Return:	EFI_SUCCESS if update to run, EFI_NOT_FOUND otherwise
  */
-static bool check_run_capsules(void)
+static efi_status_t check_run_capsules(void)
 {
 	u64 os_indications;
 	efi_uintn_t size;
-	efi_status_t ret;
-
-	if (IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS))
-		return true;
+	efi_status_t r;
 
 	size = sizeof(os_indications);
-	ret = efi_get_variable_int(L"OsIndications", &efi_global_variable_guid,
-				   NULL, &size, &os_indications, NULL);
-	if (ret == EFI_SUCCESS &&
-	    (os_indications
-	      & EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED))
-		return true;
+	r = efi_get_variable_int(L"OsIndications", &efi_global_variable_guid,
+				 NULL, &size, &os_indications, NULL);
+	if (r != EFI_SUCCESS || size != sizeof(os_indications))
+		return EFI_NOT_FOUND;
 
-	return false;
+	if (os_indications &
+	    EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED) {
+		os_indications &=
+			~EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED;
+		r = efi_set_variable_int(L"OsIndications",
+					 &efi_global_variable_guid,
+					 EFI_VARIABLE_NON_VOLATILE |
+					 EFI_VARIABLE_BOOTSERVICE_ACCESS |
+					 EFI_VARIABLE_RUNTIME_ACCESS,
+					 sizeof(os_indications),
+					 &os_indications, false);
+		if (r != EFI_SUCCESS)
+			log_err("Setting %ls failed\n", L"OsIndications");
+		return EFI_SUCCESS;
+	} else if (IS_ENABLED(CONFIG_EFI_IGNORE_OSINDICATIONS)) {
+		return EFI_SUCCESS;
+	} else  {
+		return EFI_NOT_FOUND;
+	}
 }
 
 /**
@@ -1078,7 +1093,7 @@
 	unsigned int nfiles, index, i;
 	efi_status_t ret;
 
-	if (!check_run_capsules())
+	if (check_run_capsules() != EFI_SUCCESS)
 		return EFI_SUCCESS;
 
 	index = get_last_capsule();
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index ef8b5c8..45127d1 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -424,7 +424,7 @@
 			&efi_block_io_guid, &diskobj->ops,
 			guid, NULL, NULL));
 	if (ret != EFI_SUCCESS)
-		return ret;
+		goto error;
 
 	/*
 	 * On partitions or whole disks without partitions install the
@@ -573,7 +573,7 @@
 		if (ret) {
 			log_err("ERROR: failure to add disk device %s, r = %lu\n",
 				dev->name, ret & ~EFI_ERROR_MASK);
-			return ret;
+			continue;
 		}
 		disks++;
 
diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c
index a2338d7..1aba71c 100644
--- a/lib/efi_loader/efi_setup.c
+++ b/lib/efi_loader/efi_setup.c
@@ -176,43 +176,13 @@
 
 
 /**
- * efi_clear_os_indications() - clear OsIndications
- *
- * Clear EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED
- */
-static efi_status_t efi_clear_os_indications(void)
-{
-	efi_uintn_t size;
-	u64 os_indications;
-	efi_status_t ret;
-
-	size = sizeof(os_indications);
-	ret = efi_get_variable_int(L"OsIndications", &efi_global_variable_guid,
-				   NULL, &size, &os_indications, NULL);
-	if (ret != EFI_SUCCESS)
-		os_indications = 0;
-	else
-		os_indications &=
-			~EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED;
-	ret = efi_set_variable_int(L"OsIndications", &efi_global_variable_guid,
-				   EFI_VARIABLE_NON_VOLATILE |
-				   EFI_VARIABLE_BOOTSERVICE_ACCESS |
-				   EFI_VARIABLE_RUNTIME_ACCESS,
-				   sizeof(os_indications), &os_indications,
-				   false);
-	if (ret != EFI_SUCCESS)
-		log_err("Setting %ls failed\n", L"OsIndications");
-	return ret;
-}
-
-/**
  * efi_init_obj_list() - Initialize and populate EFI object list
  *
  * Return:	status code
  */
 efi_status_t efi_init_obj_list(void)
 {
-	efi_status_t r, ret = EFI_SUCCESS;
+	efi_status_t ret = EFI_SUCCESS;
 
 	/* Initialize once only */
 	if (efi_obj_list_initialized != OBJ_LIST_NOT_INITIALIZED)
@@ -331,11 +301,7 @@
 	if (IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK) &&
 	    !IS_ENABLED(CONFIG_EFI_CAPSULE_ON_DISK_EARLY))
 		ret = efi_launch_capsules();
-
 out:
-	r = efi_clear_os_indications();
-	if (ret == EFI_SUCCESS)
-		ret = r;
 	efi_obj_list_initialized = ret;
 	return ret;
 }
diff --git a/lib/efi_selftest/efi_selftest_fdt.c b/lib/efi_selftest/efi_selftest_fdt.c
index eae9820..412ba28 100644
--- a/lib/efi_selftest/efi_selftest_fdt.c
+++ b/lib/efi_selftest/efi_selftest_fdt.c
@@ -23,23 +23,24 @@
 static const efi_guid_t fdt_guid = EFI_FDT_GUID;
 static const efi_guid_t acpi_guid = EFI_ACPI_TABLE_GUID;
 
-/*
- * Convert FDT value to host endianness.
+/**
+ * f2h() - convert FDT value to host endianness.
  *
- * @val		FDT value
- * @return	converted value
+ * UEFI code is always low endian. The FDT is big endian.
+ *
+ * @val:	FDT value
+ * Return:	converted value
  */
 static uint32_t f2h(fdt32_t val)
 {
 	char *buf = (char *)&val;
 	char i;
 
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
 	/* Swap the bytes */
 	i = buf[0]; buf[0] = buf[3]; buf[3] = i;
 	i = buf[1]; buf[1] = buf[2]; buf[2] = i;
-#endif
-	return *(uint32_t *)buf;
+
+	return val;
 }
 
 /**
diff --git a/test/py/multiplexed_log.py b/test/py/multiplexed_log.py
index 545a774..442edad 100644
--- a/test/py/multiplexed_log.py
+++ b/test/py/multiplexed_log.py
@@ -2,8 +2,10 @@
 # Copyright (c) 2015 Stephen Warren
 # Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
 
-# Generate an HTML-formatted log file containing multiple streams of data,
-# each represented in a well-delineated/-structured fashion.
+"""
+Generate an HTML-formatted log file containing multiple streams of data,
+each represented in a well-delineated/-structured fashion.
+"""
 
 import datetime
 import html
@@ -178,7 +180,7 @@
             raise exception
         return output
 
-class SectionCtxMgr(object):
+class SectionCtxMgr:
     """A context manager for Python's "with" statement, which allows a certain
     portion of test code to be logged to a separate section of the log file.
     Objects of this type should be created by factory functions in the Logfile
@@ -206,7 +208,7 @@
     def __exit__(self, extype, value, traceback):
         self.log.end_section(self.marker)
 
-class Logfile(object):
+class Logfile:
     """Generates an HTML-formatted log file containing multiple streams of
     data, each represented in a well-delineated/-structured fashion."""
 
@@ -320,8 +322,8 @@
     # The set of characters that should be represented as hexadecimal codes in
     # the log file.
     _nonprint = {ord('%')}
-    _nonprint.update({c for c in range(0, 32) if c not in (9, 10)})
-    _nonprint.update({c for c in range(127, 256)})
+    _nonprint.update(c for c in range(0, 32) if c not in (9, 10))
+    _nonprint.update(range(127, 256))
 
     def _escape(self, data):
         """Render data format suitable for inclusion in an HTML document.
diff --git a/test/py/tests/test_efi_loader.py b/test/py/tests/test_efi_loader.py
index fc8d6b8..85473a9 100644
--- a/test/py/tests/test_efi_loader.py
+++ b/test/py/tests/test_efi_loader.py
@@ -6,9 +6,6 @@
 
 # Test efi loader implementation
 
-import pytest
-import u_boot_utils
-
 """
 Note: This test relies on boardenv_* containing configuration values to define
 which network environment is available for testing. Without this, the parts
@@ -50,6 +47,9 @@
 }
 """
 
+import pytest
+import u_boot_utils
+
 net_set_up = False
 
 def test_efi_pre_commands(u_boot_console):
@@ -80,7 +80,7 @@
         env_vars = u_boot_console.config.env.get('env__net_static_env_vars', None)
         if not env_vars:
             pytest.skip('No DHCP server available')
-        return None
+        return
 
     u_boot_console.run_command('setenv autoload no')
     output = u_boot_console.run_command('dhcp')
@@ -193,7 +193,7 @@
     check_smbios = u_boot_console.config.env.get('env__efi_loader_check_smbios', False)
     if check_smbios:
         u_boot_console.wait_for('grub>')
-        output = u_boot_console.run_command('lsefisystab', wait_for_prompt=False, wait_for_echo=False)
+        u_boot_console.run_command('lsefisystab', wait_for_prompt=False, wait_for_echo=False)
         u_boot_console.wait_for('SMBIOS')
 
     # Then exit cleanly
diff --git a/test/py/tests/test_efi_selftest.py b/test/py/tests/test_efi_selftest.py
index 63218ef..0161a6e 100644
--- a/test/py/tests/test_efi_selftest.py
+++ b/test/py/tests/test_efi_selftest.py
@@ -73,8 +73,7 @@
     This function calls the text input EFI selftest.
     """
     u_boot_console.run_command(cmd='setenv efi_selftest text input')
-    output = u_boot_console.run_command(cmd='bootefi selftest',
-                                        wait_for_prompt=False)
+    u_boot_console.run_command(cmd='bootefi selftest', wait_for_prompt=False)
     m = u_boot_console.p.expect([r'To terminate type \'x\''])
     if m != 0:
         raise Exception('No prompt for \'text input\' test')
@@ -143,8 +142,7 @@
     This function calls the extended text input EFI selftest.
     """
     u_boot_console.run_command(cmd='setenv efi_selftest extended text input')
-    output = u_boot_console.run_command(cmd='bootefi selftest',
-                                        wait_for_prompt=False)
+    u_boot_console.run_command(cmd='bootefi selftest', wait_for_prompt=False)
     m = u_boot_console.p.expect([r'To terminate type \'CTRL\+x\''])
     if m != 0:
         raise Exception('No prompt for \'text input\' test')
diff --git a/test/py/u_boot_console_exec_attach.py b/test/py/u_boot_console_exec_attach.py
index 27834b5..8dd8cc1 100644
--- a/test/py/u_boot_console_exec_attach.py
+++ b/test/py/u_boot_console_exec_attach.py
@@ -2,8 +2,10 @@
 # Copyright (c) 2015 Stephen Warren
 # Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
 
-# Logic to interact with U-Boot running on real hardware, typically via a
-# physical serial port.
+"""
+Logic to interact with U-Boot running on real hardware, typically via a
+physical serial port.
+"""
 
 import sys
 from u_boot_spawn import Spawn
diff --git a/test/py/u_boot_console_sandbox.py b/test/py/u_boot_console_sandbox.py
index 836f5a9..7e1eb0e 100644
--- a/test/py/u_boot_console_sandbox.py
+++ b/test/py/u_boot_console_sandbox.py
@@ -2,7 +2,9 @@
 # Copyright (c) 2015 Stephen Warren
 # Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
 
-# Logic to interact with the sandbox port of U-Boot, running as a sub-process.
+"""
+Logic to interact with the sandbox port of U-Boot, running as a sub-process.
+"""
 
 import time
 from u_boot_spawn import Spawn
diff --git a/test/py/u_boot_spawn.py b/test/py/u_boot_spawn.py
index e34cb21..7c48d96 100644
--- a/test/py/u_boot_spawn.py
+++ b/test/py/u_boot_spawn.py
@@ -1,7 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0
 # Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
 
-# Logic to spawn a sub-process and interact with its stdio.
+"""
+Logic to spawn a sub-process and interact with its stdio.
+"""
 
 import os
 import re
@@ -9,12 +11,12 @@
 import signal
 import select
 import time
+import traceback
 
 class Timeout(Exception):
     """An exception sub-class that indicates that a timeout occurred."""
-    pass
 
-class Spawn(object):
+class Spawn:
     """Represents the stdio of a freshly created sub-process. Commands may be
     sent to the process, and responses waited for.
 
@@ -58,14 +60,14 @@
                 os.execvp(args[0], args)
             except:
                 print('CHILD EXECEPTION:')
-                import traceback
                 traceback.print_exc()
             finally:
                 os._exit(255)
 
         try:
             self.poll = select.poll()
-            self.poll.register(self.fd, select.POLLIN | select.POLLPRI | select.POLLERR | select.POLLHUP | select.POLLNVAL)
+            self.poll.register(self.fd, select.POLLIN | select.POLLPRI | select.POLLERR |
+                               select.POLLHUP | select.POLLNVAL)
         except:
             self.close()
             raise
@@ -106,7 +108,7 @@
         elif os.WIFSIGNALED(status):
             signum = os.WTERMSIG(status)
             self.exit_code = -signum
-            self.exit_info = 'signal %d (%s)' % (signum, signal.Signals(signum))
+            self.exit_info = 'signal %d (%s)' % (signum, signal.Signals(signum).name)
         self.waited = True
         return False, self.exit_code, self.exit_info
 
@@ -196,13 +198,11 @@
                     # shouldn't and explain why. This is much more friendly than
                     # just dying with an I/O error
                     if err.errno == 5:  # Input/output error
-                        alive, exit_code, info = self.checkalive()
+                        alive, _, info = self.checkalive()
                         if alive:
-                            raise
-                        else:
-                            raise ValueError('U-Boot exited with %s' % info)
-                    else:
-                        raise
+                            raise err
+                        raise ValueError('U-Boot exited with %s' % info)
+                    raise err
                 if self.logfile_read:
                     self.logfile_read.write(c)
                 self.buf += c
@@ -227,7 +227,7 @@
         """
 
         os.close(self.fd)
-        for i in range(100):
+        for _ in range(100):
             if not self.isalive():
                 break
             time.sleep(0.1)
diff --git a/test/py/u_boot_utils.py b/test/py/u_boot_utils.py
index e816c7f..089eda5 100644
--- a/test/py/u_boot_utils.py
+++ b/test/py/u_boot_utils.py
@@ -1,17 +1,20 @@
 # SPDX-License-Identifier: GPL-2.0
 # Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
 
-# Utility code shared across multiple tests.
+"""
+Utility code shared across multiple tests.
+"""
 
 import hashlib
 import inspect
 import os
 import os.path
-import pytest
+import pathlib
 import signal
 import sys
 import time
 import re
+import pytest
 
 def md5sum_data(data):
     """Calculate the MD5 hash of some data.
@@ -48,7 +51,7 @@
         data = fh.read(*params)
     return md5sum_data(data)
 
-class PersistentRandomFile(object):
+class PersistentRandomFile:
     """Generate and store information about a persistent file containing
     random data."""
 
@@ -144,7 +147,7 @@
         Nothing.
     """
 
-    for i in range(100):
+    for _ in range(100):
         fh = attempt_to_open_file(fn)
         if not fh:
             return
@@ -192,9 +195,9 @@
     try:
         runner = u_boot_console.log.get_runner(cmd[0], sys.stdout)
         runner.run(cmd)
-    except Exception as e:
-        assert(retcode == runner.exit_status)
-        assert(msg in runner.output)
+    except Exception:
+        assert retcode == runner.exit_status
+        assert msg in runner.output
     else:
         raise Exception("Expected an exception with retcode %d message '%s',"
                         "but it was not raised" % (retcode, msg))
@@ -279,17 +282,17 @@
             if filename_timestamp < self.module_timestamp:
                 self.log.action('Removing stale generated file ' +
                     self.filename)
-                os.unlink(self.filename)
+                pathlib.Path(self.filename).unlink()
 
     def __exit__(self, extype, value, traceback):
         if extype:
             try:
-                os.path.unlink(self.filename)
-            except:
+                pathlib.Path(self.filename).unlink()
+            except Exception:
                 pass
             return
         logged = False
-        for i in range(20):
+        for _ in range(20):
             filename_timestamp = os.path.getmtime(self.filename)
             if filename_timestamp > self.module_timestamp:
                 break