Merge tag 'efi-2023-01-rc5-3' of https://source.denx.de/u-boot/custodians/u-boot-efi

Pull request for efi-2023-01-rc5-3

Documentation:

* Describe building documentation

UEFI:

* Add .data section to aarch64 EFI binaries and correct section flags
* Correct sorting of capsules when updating
* Populate console handles in system table

Other:

* Fix description of eth_env_[gs]et_enetaddr() return value
* Avoid endless loop in sound play command
diff --git a/arch/arm/lib/crt0_aarch64_efi.S b/arch/arm/lib/crt0_aarch64_efi.S
index b4fc263..3c2cef6 100644
--- a/arch/arm/lib/crt0_aarch64_efi.S
+++ b/arch/arm/lib/crt0_aarch64_efi.S
@@ -25,7 +25,7 @@
 	.long	IMAGE_NT_SIGNATURE		/* 'PE' */
 coff_header:
 	.short	IMAGE_FILE_MACHINE_ARM64	/* AArch64 */
-	.short	2				/* nr_sections */
+	.short	3				/* nr_sections */
 	.long	0				/* TimeDateStamp */
 	.long	0				/* PointerToSymbolTable */
 	.long	0				/* NumberOfSymbols */
@@ -40,7 +40,7 @@
 	.short	IMAGE_NT_OPTIONAL_HDR64_MAGIC	/* PE32+ format */
 	.byte	0x02				/* MajorLinkerVersion */
 	.byte	0x14				/* MinorLinkerVersion */
-	.long	_edata - _start			/* SizeOfCode */
+	.long	_etext - _start			/* SizeOfCode */
 	.long	0				/* SizeOfInitializedData */
 	.long	0				/* SizeOfUninitializedData */
 	.long	_start - ImageBase		/* AddressOfEntryPoint */
@@ -48,7 +48,7 @@
 
 extra_header_fields:
 	.quad	0				/* ImageBase */
-	.long	0x200				/* SectionAlignment */
+	.long	0x1000				/* SectionAlignment */
 	.long	0x200				/* FileAlignment */
 	.short	0				/* MajorOperatingSystemVersion */
 	.short	0				/* MinorOperatingSystemVersion */
@@ -100,25 +100,46 @@
 	.long	0			/* PointerToLineNumbers */
 	.short	0			/* NumberOfRelocations */
 	.short	0			/* NumberOfLineNumbers */
-	.long	0x42100040		/* Characteristics (section flags) */
-
+	/* Characteristics (section flags) */
+	.long	(IMAGE_SCN_MEM_READ | \
+		 IMAGE_SCN_MEM_DISCARDABLE | \
+		 IMAGE_SCN_CNT_INITIALIZED_DATA)
 
 	.ascii	".text"
 	.byte	0
 	.byte	0
 	.byte	0			/* end of 0 padding of section name */
-	.long	_edata - _start		/* VirtualSize */
+	.long	_etext - _start		/* VirtualSize */
 	.long	_start - ImageBase	/* VirtualAddress */
-	.long	_edata - _start		/* SizeOfRawData */
+	.long	_etext - _start		/* SizeOfRawData */
 	.long	_start - ImageBase	/* PointerToRawData */
+	.long	0			/* PointerToRelocations */
+	.long	0			/* PointerToLineNumbers */
+	.short	0			/* NumberOfRelocations */
+	.short	0			/* NumberOfLineNumbers */
+	/* Characteristics (section flags) */
+	.long	(IMAGE_SCN_MEM_READ | \
+		 IMAGE_SCN_MEM_EXECUTE | \
+		 IMAGE_SCN_CNT_CODE)
 
-	.long	0		/* PointerToRelocations (0 for executables) */
-	.long	0		/* PointerToLineNumbers (0 for executables) */
-	.short	0		/* NumberOfRelocations  (0 for executables) */
-	.short	0		/* NumberOfLineNumbers  (0 for executables) */
-	.long	0xe0500020	/* Characteristics (section flags) */
+	.ascii	".data"
+	.byte	0
+	.byte	0
+	.byte	0			/* end of 0 padding of section name */
+	.long	_data_size		/* VirtualSize */
+	.long	_data - ImageBase	/* VirtualAddress */
+	.long	_data_size		/* SizeOfRawData */
+	.long	_data - ImageBase	/* PointerToRawData */
+	.long	0			/* PointerToRelocations */
+	.long	0			/* PointerToLineNumbers */
+	.short	0			/* NumberOfRelocations */
+	.short	0			/* NumberOfLineNumbers */
+	/* Characteristics (section flags) */
+	.long	(IMAGE_SCN_MEM_WRITE | \
+		 IMAGE_SCN_MEM_READ | \
+		 IMAGE_SCN_CNT_INITIALIZED_DATA)
 
-	.align		9
+	.align		12
 _start:
 	stp		x29, x30, [sp, #-32]!
 	mov		x29, sp
diff --git a/arch/arm/lib/elf_aarch64_efi.lds b/arch/arm/lib/elf_aarch64_efi.lds
index c0604da..ffc6f6e 100644
--- a/arch/arm/lib/elf_aarch64_efi.lds
+++ b/arch/arm/lib/elf_aarch64_efi.lds
@@ -18,11 +18,13 @@
 		*(.gnu.linkonce.t.*)
 		*(.srodata)
 		*(.rodata*)
+		. = ALIGN(16);
+		*(.dynamic);
 		. = ALIGN(512);
 	}
 	_etext = .;
 	_text_size = . - _text;
-	.dynamic  : { *(.dynamic) }
+	. = ALIGN(4096);
 	.data : {
 		_data = .;
 		*(.sdata)
@@ -48,11 +50,11 @@
 		_bss_end = .;
 		_edata = .;
 	}
+	_data_size = _edata - _data;
 	.rela.dyn : { *(.rela.dyn) }
 	.rela.plt : { *(.rela.plt) }
 	.rela.got : { *(.rela.got) }
 	.rela.data : { *(.rela.data) *(.rela.data*) }
-	_data_size = . - _etext;
 
 	. = ALIGN(4096);
 	.dynsym   : { *(.dynsym) }
diff --git a/cmd/sound.c b/cmd/sound.c
index cef71be..0b7f959 100644
--- a/cmd/sound.c
+++ b/cmd/sound.c
@@ -48,12 +48,12 @@
 	++argv;
 	while (argc || first) {
 		first = false;
-		if (argc && *argv[0] != '-') {
+		if (argc) {
 			msec = dectoul(argv[0], NULL);
 			--argc;
 			++argv;
 		}
-		if (argc && *argv[0] != '-') {
+		if (argc) {
 			freq = dectoul(argv[0], NULL);
 			--argc;
 			++argv;
diff --git a/doc/build/documentation.rst b/doc/build/documentation.rst
new file mode 100644
index 0000000..896264d
--- /dev/null
+++ b/doc/build/documentation.rst
@@ -0,0 +1,90 @@
+.. SPDX-License-Identifier: GPL-2.0+:
+
+Building documentation
+======================
+
+The U-Boot documentation is based on the Sphinx documentation generator.
+
+HTML documentation
+------------------
+
+The *htmldocs* target is used to build the HTML documentation. It uses the
+`Read the Docs Sphinx theme <https://sphinx-rtd-theme.readthedocs.io/en/stable/>`_.
+
+.. code-block:: bash
+
+    # Create Python environment 'myenv'
+    python3 -m venv myenv
+    # Activate the Python environment
+    . myenv/bin/activate
+    # Install build requirements
+    python3 -m pip install -r doc/sphinx/requirements.txt
+    # Build the documentation
+    make htmldocs
+    # Deactivate the Python environment
+    deactivate
+    # Display the documentation in a graphical web browser
+    x-www-browser doc/output/index.html
+
+Infodoc documentation
+---------------------
+
+The *infodocs* target builds both a texinfo and an info file:
+
+.. code-block:: bash
+
+    # Create Python environment 'myenv'
+    python3 -m venv myenv
+    # Activate the Python environment
+    . myenv/bin/activate
+    # Install build requirements
+    python3 -m pip install -r doc/sphinx/requirements.txt
+    # Build the documentation
+    make infodocs
+    # Deactivate the Python environment
+    deactivate
+    # Display the documentation
+    info doc/output/texinfo/u-boot.info
+
+PDF documentation
+-----------------
+
+The *pdfdocs* target is meant to be used to build PDF documenation.
+As v2023.01 it fails with 'LaTeX Error: Too deeply nested'.
+
+We can use texi2pdf instead:
+
+.. code-block:: bash
+
+    # Create Python environment 'myenv'
+    python3 -m venv myenv
+    # Activate the Python environment
+    . myenv/bin/activate
+    # Install build requirements
+    python3 -m pip install -r doc/sphinx/requirements.txt
+    # Build the documentation
+    make texinfodocs
+    # Deactivate the Python environment
+    deactivate
+    # Convert to PDF
+    texi2pdf doc/output/texinfo/u-boot.texi
+
+Texinfo documentation
+---------------------
+
+To build only the texinfo documentation the *texinfodocs* target is used:
+
+.. code-block:: bash
+
+    # Create Python environment 'myenv'
+    python3 -m venv myenv
+    # Activate the Python environment
+    . myenv/bin/activate
+    # Install build requirements
+    python3 -m pip install -r doc/sphinx/requirements.txt
+    # Build the documentation
+    make texinfodocs
+    # Deactivate the Python environment
+    deactivate
+
+The output is in file *doc/output/texinfo/u-boot.texi*.
diff --git a/doc/build/index.rst b/doc/build/index.rst
index 9a8105d..dc9cde4 100644
--- a/doc/build/index.rst
+++ b/doc/build/index.rst
@@ -12,3 +12,4 @@
    docker
    tools
    buildman
+   documentation
diff --git a/include/asm-generic/pe.h b/include/asm-generic/pe.h
index a1df747..b9d674b 100644
--- a/include/asm-generic/pe.h
+++ b/include/asm-generic/pe.h
@@ -51,6 +51,19 @@
 #define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER	12
 #define IMAGE_SUBSYSTEM_EFI_ROM			13
 
+/* Section flags */
+#define IMAGE_SCN_CNT_CODE			0x00000020
+#define IMAGE_SCN_CNT_INITIALIZED_DATA		0x00000040
+#define IMAGE_SCN_CNT_UNINITIALIZED_ DATA	0x00000080
+#define IMAGE_SCN_LNK_NRELOC_OVFL		0x01000000
+#define IMAGE_SCN_MEM_DISCARDABLE		0x02000000
+#define IMAGE_SCN_MEM_NOT_CACHED		0x04000000
+#define IMAGE_SCN_MEM_NOT_PAGED			0x08000000
+#define IMAGE_SCN_MEM_SHARED			0x10000000
+#define IMAGE_SCN_MEM_EXECUTE			0x20000000
+#define IMAGE_SCN_MEM_READ			0x40000000
+#define IMAGE_SCN_MEM_WRITE			0x80000000
+
 #define LINUX_ARM64_MAGIC			0x644d5241
 
 #endif /* _ASM_PE_H */
diff --git a/include/charset.h b/include/charset.h
index e900fd7..6e79d71 100644
--- a/include/charset.h
+++ b/include/charset.h
@@ -174,6 +174,19 @@
 s32 utf_to_upper(const s32 code);
 
 /**
+ * u16_strcasecmp() - compare two u16 strings case insensitively
+ *
+ * @s1:		first string to compare
+ * @s2:		second string to compare
+ * @n:		maximum number of u16 to compare
+ * Return:	0  if the first n u16 are the same in s1 and s2
+ *		< 0 if the first different u16 in s1 is less than the
+ *		corresponding u16 in s2
+ *		> 0 if the first different u16 in s1 is greater than the
+ */
+int u16_strcasecmp(const u16 *s1, const u16 *s2);
+
+/**
  * u16_strncmp() - compare two u16 string
  *
  * @s1:		first string to compare
diff --git a/include/env.h b/include/env.h
index 60acb54..1480efa 100644
--- a/include/env.h
+++ b/include/env.h
@@ -226,7 +226,7 @@
  *
  * @name: Environment variable to get (e.g. "ethaddr")
  * @enetaddr: Place to put MAC address (6 bytes)
- * Return: 0 if OK, 1 on error
+ * Return: 1 if OK, 0 on error
  */
 int eth_env_get_enetaddr(const char *name, uint8_t *enetaddr);
 
@@ -235,7 +235,7 @@
  *
  * @name: Environment variable to set (e.g. "ethaddr")
  * @enetaddr: Pointer to MAC address to put into the variable (6 bytes)
- * Return: 0 if OK, 1 on error
+ * Return: 0 if OK, non-zero otherwise
  */
 int eth_env_set_enetaddr(const char *name, const uint8_t *enetaddr);
 
diff --git a/lib/charset.c b/lib/charset.c
index bece498..b184275 100644
--- a/lib/charset.c
+++ b/lib/charset.c
@@ -351,6 +351,32 @@
 }
 
 /*
+ * u16_strcasecmp() - compare two u16 strings case insensitively
+ *
+ * @s1:		first string to compare
+ * @s2:		second string to compare
+ * @n:		maximum number of u16 to compare
+ * Return:	0  if the first n u16 are the same in s1 and s2
+ *		< 0 if the first different u16 in s1 is less than the
+ *		corresponding u16 in s2
+ *		> 0 if the first different u16 in s1 is greater than the
+ */
+int u16_strcasecmp(const u16 *s1, const u16 *s2)
+{
+	int ret = 0;
+	s32 c1, c2;
+
+	for (;;) {
+		c1 = utf_to_upper(utf16_get(&s1));
+		c2 = utf_to_upper(utf16_get(&s2));
+		ret = c1 - c2;
+		if (ret || !c1 || c1 == -1 || c2 == -1)
+			break;
+	}
+	return ret;
+}
+
+/*
  * u16_strncmp() - compare two u16 string
  *
  * @s1:		first string to compare
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 253f9f7..e65ca6a 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -3956,8 +3956,11 @@
 	 * These entries will be set to NULL in ExitBootServices(). To avoid
 	 * relocation in SetVirtualAddressMap(), set them dynamically.
 	 */
+	systab.con_in_handle = efi_root;
 	systab.con_in = &efi_con_in;
+	systab.con_out_handle = efi_root;
 	systab.con_out = &efi_con_out;
+	systab.stderr_handle = efi_root;
 	systab.std_err = &efi_con_out;
 	systab.boottime = &efi_boot_services;
 
diff --git a/lib/efi_loader/efi_capsule.c b/lib/efi_loader/efi_capsule.c
index 1163a2e..0997cd2 100644
--- a/lib/efi_loader/efi_capsule.c
+++ b/lib/efi_loader/efi_capsule.c
@@ -1108,10 +1108,13 @@
 	/* ignore an error */
 	EFI_CALL((*dirh->close)(dirh));
 
-	/* in ascii order */
-	/* FIXME: u16 version of strcasecmp */
+	/*
+	 * Capsule files are applied in case insensitive alphabetic order
+	 *
+	 * TODO: special handling of rightmost period
+	 */
 	qsort(tmp_files, count, sizeof(*tmp_files),
-	      (int (*)(const void *, const void *))strcasecmp);
+	      (int (*)(const void *, const void *))u16_strcasecmp);
 	*files = tmp_files;
 	*num = count;
 	ret = EFI_SUCCESS;
diff --git a/test/unicode_ut.c b/test/unicode_ut.c
index 3547aef..382b796 100644
--- a/test/unicode_ut.c
+++ b/test/unicode_ut.c
@@ -624,6 +624,31 @@
 }
 UNICODE_TEST(unicode_test_utf_to_upper);
 
+static int unicode_test_u16_strcasecmp(struct unit_test_state *uts)
+{
+	ut_assert(u16_strcasecmp(u"abcd", u"abcd") == 0);
+	ut_assert(u16_strcasecmp(u"aBcd", u"abcd") == 0);
+	ut_assert(u16_strcasecmp(u"abcd", u"abCd") == 0);
+	ut_assert(u16_strcasecmp(u"abcdE", u"abcd") > 0);
+	ut_assert(u16_strcasecmp(u"abcd", u"abcdE") < 0);
+	ut_assert(u16_strcasecmp(u"abcE", u"abcd") > 0);
+	ut_assert(u16_strcasecmp(u"abcd", u"abcE") < 0);
+	ut_assert(u16_strcasecmp(u"abcd", u"abcd") == 0);
+	ut_assert(u16_strcasecmp(u"abcd", u"abcd") == 0);
+	if (CONFIG_IS_ENABLED(EFI_UNICODE_CAPITALIZATION)) {
+		/* Cyrillic letters */
+		ut_assert(u16_strcasecmp(u"\x043a\x043d\x0438\x0433\x0430",
+					 u"\x041a\x041d\x0418\x0413\x0410") == 0);
+		ut_assert(u16_strcasecmp(u"\x043a\x043d\x0438\x0433\x0430",
+					 u"\x041a\x041d\x0418\x0413\x0411") < 0);
+		ut_assert(u16_strcasecmp(u"\x043a\x043d\x0438\x0433\x0431",
+					 u"\x041a\x041d\x0418\x0413\x0410") > 0);
+	}
+
+	return 0;
+}
+UNICODE_TEST(unicode_test_u16_strcasecmp);
+
 static int unicode_test_u16_strncmp(struct unit_test_state *uts)
 {
 	ut_assert(u16_strncmp(u"abc", u"abc", 3) == 0);