Merge tag 'efi-next-20230325' of https://source.denx.de/u-boot/custodians/u-boot-efi into next

Pull request for efi-next-20230325

Documenation:

* add man-page for efi command

UEFI:

* Let EFI app call ExitBootServices() before legacy booting kernel
* Support zboot and bootm in the EFI app
* Let efi command show configuration tables
* Support booting a 64-bit kernel from 64-bit EFI app
* Allocate device-tree copy from high memory
* simplify efi_str_to_u16()
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig
index b19ed2c..54027cc 100644
--- a/arch/arm/mach-kirkwood/Kconfig
+++ b/arch/arm/mach-kirkwood/Kconfig
@@ -5,9 +5,11 @@
 
 config KW88F6192
 	bool
+	select ARCH_VERY_EARLY_INIT
 
 config KW88F6281
 	bool
+	select ARCH_VERY_EARLY_INIT
 
 config SHEEVA_88SV131
 	bool
diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile
index 3b2eef8..0fb5a23 100644
--- a/arch/arm/mach-kirkwood/Makefile
+++ b/arch/arm/mach-kirkwood/Makefile
@@ -6,6 +6,7 @@
 
 obj-y	= cpu.o
 obj-y	+= cache.o
+obj-y	+= lowlevel.o
 obj-y	+= mpp.o
 
 # cpu.o and cache.o contain CP15 instructions which cannot be run in
diff --git a/arch/arm/mach-kirkwood/cpu.c b/arch/arm/mach-kirkwood/cpu.c
index df3e8f1..2b493b3 100644
--- a/arch/arm/mach-kirkwood/cpu.c
+++ b/arch/arm/mach-kirkwood/cpu.c
@@ -189,9 +189,6 @@
 	struct kwcpu_registers *cpureg =
 		(struct kwcpu_registers *)KW_CPU_REG_BASE;
 
-	/* Linux expects the internal registers to be at 0xf1000000 */
-	writel(KW_REGS_PHY_BASE, KW_OFFSET_REG);
-
 	/* Enable and invalidate L2 cache in write through mode */
 	writel(readl(&cpureg->l2_cfg) | 0x18, &cpureg->l2_cfg);
 	invalidate_l2_cache();
diff --git a/arch/arm/mach-kirkwood/lowlevel.S b/arch/arm/mach-kirkwood/lowlevel.S
new file mode 100644
index 0000000..6810384
--- /dev/null
+++ b/arch/arm/mach-kirkwood/lowlevel.S
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+
+ENTRY(arch_very_early_init)
+	/* Move internal registers from KW_OFFSET_REG to KW_REGS_PHY_BASE */
+	ldr	r0, =KW_REGS_PHY_BASE
+	ldr	r1, =KW_OFFSET_REG
+	str	r0, [r1]
+	bx	lr
+ENDPROC(arch_very_early_init)
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index fb3cff4..1f0dbef 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -423,6 +423,16 @@
 	default 0
 	depends on SECURED_MODE_IMAGE
 
+config SF_DEFAULT_SPEED
+	int "Default speed for SPI flash in Hz"
+	default 10000000
+	depends on MVEBU_SPL_BOOT_DEVICE_SPI
+
+config SF_DEFAULT_MODE
+	hex "Default mode for SPI flash"
+	default 0x0
+	depends on MVEBU_SPL_BOOT_DEVICE_SPI
+
 source "board/solidrun/clearfog/Kconfig"
 source "board/kobol/helios4/Kconfig"
 
diff --git a/configs/n2350_defconfig b/configs/n2350_defconfig
index b85ef0d..247533e 100644
--- a/configs/n2350_defconfig
+++ b/configs/n2350_defconfig
@@ -69,6 +69,9 @@
 CONFIG_DM_I2C=y
 CONFIG_SYS_I2C_MVTWSI=y
 CONFIG_MTD=y
+CONFIG_MTD_RAW_NAND=y
+CONFIG_NAND_PXA3XX=y
+CONFIG_SYS_NAND_ONFI_DETECTION=y
 CONFIG_SF_DEFAULT_SPEED=50000000
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_STMICRO=y
diff --git a/configs/nsa310s_defconfig b/configs/nsa310s_defconfig
index 76839e6..b936ae1 100644
--- a/configs/nsa310s_defconfig
+++ b/configs/nsa310s_defconfig
@@ -15,8 +15,11 @@
 CONFIG_ENV_OFFSET=0xE0000
 CONFIG_DEFAULT_DEVICE_TREE="kirkwood-nsa310s"
 CONFIG_SYS_PROMPT="NSA310s> "
+CONFIG_DEBUG_UART_BASE=0xf1012000
+CONFIG_DEBUG_UART_CLOCK=166666667
 CONFIG_IDENT_STRING="\nZyXEL NSA310S/320S 1/2-Bay Power Media Server"
 CONFIG_SYS_LOAD_ADDR=0x800000
+CONFIG_DEBUG_UART=y
 CONFIG_DISTRO_DEFAULTS=y
 CONFIG_BOOTDELAY=3
 CONFIG_USE_PREBOOT=y
@@ -50,6 +53,7 @@
 CONFIG_PHY_MARVELL=y
 CONFIG_MVGBE=y
 CONFIG_MII=y
+CONFIG_DEBUG_UART_SHIFT=2
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_UBIFS_SILENCE_MSG=y
diff --git a/doc/kwboot.1 b/doc/kwboot.1
index 5cda3b4..32d324f 100644
--- a/doc/kwboot.1
+++ b/doc/kwboot.1
@@ -69,7 +69,7 @@
 .IP
 
 Armada 38x BootROM has a bug which cause that BootROM's standard output
-is turned off on UART when SPI-NOR contains valid boot image. Nevertheless
+is turned off on UART when default boot source location contains valid boot image. Nevertheless
 BootROM's standard input and BootROM's terminal echo are active and working
 fine. To workaround this BootROM bug with standard output, it is possible
 to manually overwrite BootROM variables stored in SRAM which BootROM use
diff --git a/drivers/ddr/marvell/a38x/ddr3_init.h b/drivers/ddr/marvell/a38x/ddr3_init.h
index ba9f788..6854bb4 100644
--- a/drivers/ddr/marvell/a38x/ddr3_init.h
+++ b/drivers/ddr/marvell/a38x/ddr3_init.h
@@ -9,7 +9,6 @@
 #include "ddr_ml_wrapper.h"
 #include "mv_ddr_plat.h"
 
-#include "seq_exec.h"
 #include "ddr3_logging_def.h"
 #include "ddr3_training_hw_algo.h"
 #include "ddr3_training_ip.h"
diff --git a/drivers/ddr/marvell/a38x/seq_exec.h b/drivers/ddr/marvell/a38x/seq_exec.h
deleted file mode 100644
index fe0cb8f..0000000
--- a/drivers/ddr/marvell/a38x/seq_exec.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) Marvell International Ltd. and its affiliates
- */
-
-#ifndef _SEQ_EXEC_H
-#define _SEQ_EXEC_H
-
-#define NA			0xff
-#define DEFAULT_PARAM		0
-#define MV_BOARD_TCLK_ERROR	0xffffffff
-
-#define NO_DATA			0xffffffff
-#define MAX_DATA_ARRAY		5
-#define FIRST_CELL		0
-
-/* Operation types */
-enum mv_op {
-	WRITE_OP,
-	DELAY_OP,
-	POLL_OP,
-};
-
-/* Operation parameters */
-struct op_params {
-	u32 unit_base_reg;
-	u32 unit_offset;
-	u32 mask;
-	u32 data[MAX_DATA_ARRAY];	/* data array */
-	u8 wait_time;			/* msec */
-	u16 num_of_loops;		/* for polling only */
-};
-
-/*
- * Sequence parameters. Each sequence contains:
- * 1. Sequence id.
- * 2. Sequence size (total amount of operations during the sequence)
- * 3. a series of operations. operations can be write, poll or delay
- * 4. index in the data array (the entry where the relevant data sits)
- */
-struct cfg_seq {
-	struct op_params *op_params_ptr;
-	u8 cfg_seq_size;
-	u8 data_arr_idx;
-};
-
-extern struct cfg_seq serdes_seq_db[];
-
-/*
- * A generic function type for executing an operation (write, poll or delay)
- */
-typedef int (*op_execute_func_ptr)(u32 serdes_num, struct op_params *params,
-				   u32 data_arr_idx);
-
-/* Specific functions for executing each operation */
-int write_op_execute(u32 serdes_num, struct op_params *params,
-		     u32 data_arr_idx);
-int delay_op_execute(u32 serdes_num, struct op_params *params,
-		     u32 data_arr_idx);
-int poll_op_execute(u32 serdes_num, struct op_params *params, u32 data_arr_idx);
-enum mv_op get_cfg_seq_op(struct op_params *params);
-int mv_seq_exec(u32 serdes_num, u32 seq_id);
-
-#endif /*_SEQ_EXEC_H*/
diff --git a/tools/kwbimage.c b/tools/kwbimage.c
index 309657a..177084a 100644
--- a/tools/kwbimage.c
+++ b/tools/kwbimage.c
@@ -1231,6 +1231,16 @@
 	if (count > 0)
 		headersz += sizeof(struct register_set_hdr_v1) + 8 * count + 4;
 
+	/*
+	 * For all images except UART, headersz stored in header itself should
+	 * contains header size without padding. For UART image BootROM rounds
+	 * down headersz to multiply of 128 bytes. Therefore align UART headersz
+	 * to multiply of 128 bytes to ensure that remaining UART header bytes
+	 * are not ignored by BootROM.
+	 */
+	if (image_get_bootfrom() == IBR_HDR_UART_ID)
+		headersz = ALIGN(headersz, 128);
+
 	return headersz;
 }
 
diff --git a/tools/kwboot.c b/tools/kwboot.c
index 7c66648..348a320 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -61,7 +61,9 @@
  *   SPI-NOR or parallel-NOR. Despite the type name it really can be stored on
  *   parallel-NOR and cannot be stored on other SPI devices, like SPI-NAND.
  *   So it should have been named NOR image, not SPI image. This image type
- *   supports XIP - Execute In Place directly from NOR memory.
+ *   supports XIP - Execute In Place directly from NOR memory. Destination
+ *   address of the XIP image is set to 0xFFFFFFFF and execute address to the
+ *   absolute offset in bytes from the beginning of NOR memory.
  *
  * - IBR_HDR_NAND_ID (0x8B):
  *   NAND image can be stored either at any 2 MB aligned offset in the first
@@ -78,6 +80,17 @@
  *
  * - IBR_HDR_UART_ID (0x69):
  *   UART image can be transfered via xmodem protocol over first UART.
+ *   Unlike all other image types, header size stored in the image must be
+ *   multiply of the 128 bytes (for all other image types it can be any size)
+ *   and data part of the image does not have to contain 32-bit checksum
+ *   (all other image types must have valid 32-bit checksum in its data part).
+ *   And data size stored in the image is ignored. A38x BootROM determinates
+ *   size of the data part implicitly by the end of the xmodem transfer.
+ *   A38x BootROM has a bug which cause that BootROM loads data part of UART
+ *   image into RAM target address increased by one byte when source address
+ *   and header size stored in the image header are not same. So UART image
+ *   should be constructed in a way that there is no gap between header and
+ *   data part.
  *
  * - IBR_HDR_I2C_ID (0x4D):
  *   It is unknown for what kind of storage is used this image. It is not
@@ -1455,6 +1468,8 @@
 	 * followed by the header. So align header size to xmodem block size.
 	 */
 	hdrsz += (KWBOOT_XM_BLKSZ - hdrsz % KWBOOT_XM_BLKSZ) % KWBOOT_XM_BLKSZ;
+	if (hdrsz > size)
+		hdrsz = size;
 
 	pnum = 1;
 
@@ -2079,6 +2094,8 @@
 			goto err;
 		}
 		kwboot_img_grow_data_right(img, size, sizeof(uint32_t));
+		/* Update the 32-bit data checksum */
+		*kwboot_img_csum32_ptr(img) = kwboot_img_csum32(img);
 	}
 
 	if (!kwboot_img_has_ddr_init(img) &&
@@ -2168,6 +2185,29 @@
 
 		kwboot_printv("Aligning image header to Xmodem block size\n");
 		kwboot_img_grow_hdr(img, size, grow);
+		hdrsz += grow;
+
+		/*
+		 * kwbimage v1 contains header size field and for UART type it
+		 * must be set to the aligned xmodem header size because BootROM
+		 * rounds header size down to xmodem block size.
+		 */
+		if (kwbimage_version(img) == 1) {
+			hdr->headersz_msb = hdrsz >> 16;
+			hdr->headersz_lsb = cpu_to_le16(hdrsz & 0xffff);
+		}
+	}
+
+	/* Header size and source address must be same for UART type due to A38x BootROM bug */
+	if (hdrsz != le32_to_cpu(hdr->srcaddr)) {
+		if (is_secure) {
+			fprintf(stderr, "Cannot align image with secure header\n");
+			goto err;
+		}
+
+		kwboot_printv("Removing gap between image header and data\n");
+		memmove(img + hdrsz, img + le32_to_cpu(hdr->srcaddr), le32_to_cpu(hdr->blocksize));
+		hdr->srcaddr = cpu_to_le32(hdrsz);
 	}
 
 	hdr->checksum = kwboot_hdr_csum8(hdr) - csum;