summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--arch/arm/dts/sunxi-u-boot.dtsi4
-rw-r--r--arch/arm/include/asm/arch-sunxi/cpu_sun4i.h11
-rw-r--r--arch/arm/mach-mvebu/Kconfig26
-rw-r--r--arch/arm/mach-mvebu/include/mach/cpu.h2
-rw-r--r--arch/arm/mach-mvebu/lowlevel_spl.S3
-rw-r--r--arch/arm/mach-mvebu/spl.c248
-rw-r--r--arch/sandbox/cpu/start.c9
-rw-r--r--arch/sandbox/cpu/state.c18
-rw-r--r--arch/sandbox/dts/sandbox.dtsi2
-rw-r--r--arch/sandbox/include/asm/state.h1
-rw-r--r--board/Marvell/dreamplug/dreamplug.c62
-rw-r--r--board/gdsys/a38x/Makefile2
-rw-r--r--board/gdsys/a38x/spl.c20
-rw-r--r--board/kobol/helios4/Kconfig5
-rw-r--r--board/solidrun/clearfog/Kconfig5
-rw-r--r--board/sunxi/board.c14
-rw-r--r--cmd/fdt.c42
-rw-r--r--common/autoboot.c6
-rw-r--r--common/board_r.c8
-rw-r--r--common/spl/Kconfig4
-rw-r--r--common/spl/spl.c9
-rw-r--r--common/spl/spl_mmc.c16
-rw-r--r--common/spl/spl_sata.c12
-rw-r--r--common/spl/spl_spi.c2
-rw-r--r--configs/clearfog_defconfig1
-rw-r--r--configs/controlcenterdc_defconfig2
-rw-r--r--configs/db-88f6720_defconfig1
-rw-r--r--configs/db-88f6820-amc_defconfig1
-rw-r--r--configs/db-88f6820-gp_defconfig2
-rw-r--r--configs/db-mv784mp-gp_defconfig1
-rw-r--r--configs/dreamplug_defconfig4
-rw-r--r--configs/ds414_defconfig1
-rw-r--r--configs/helios4_defconfig1
-rw-r--r--configs/maxbcm_defconfig1
-rw-r--r--configs/theadorable_debug_defconfig1
-rw-r--r--configs/turris_omnia_defconfig1
-rw-r--r--configs/x530_defconfig1
-rw-r--r--doc/develop/index.rst10
-rw-r--r--doc/develop/moveconfig.rst282
-rw-r--r--doc/develop/testing.rst6
-rw-r--r--doc/device-tree-bindings/pinctrl/marvell,armada-37xx-pinctrl.txt8
-rw-r--r--drivers/pinctrl/mvebu/pinctrl-armada-37xx.c17
-rw-r--r--drivers/serial/serial_mvebu_a3700.c9
-rw-r--r--drivers/tpm/Makefile4
-rw-r--r--drivers/tpm/sandbox_common.c77
-rw-r--r--drivers/tpm/sandbox_common.h108
-rw-r--r--drivers/tpm/tpm2_tis_sandbox.c283
-rw-r--r--drivers/tpm/tpm_tis_sandbox.c171
-rw-r--r--env/Kconfig3
-rw-r--r--include/autoboot.h36
-rw-r--r--include/configs/clearfog.h7
-rw-r--r--include/configs/controlcenterdc.h9
-rw-r--r--include/configs/db-88f6720.h3
-rw-r--r--include/configs/db-88f6820-amc.h5
-rw-r--r--include/configs/db-88f6820-gp.h7
-rw-r--r--include/configs/db-mv784mp-gp.h3
-rw-r--r--include/configs/dreamplug.h12
-rw-r--r--include/configs/ds414.h5
-rw-r--r--include/configs/helios4.h7
-rw-r--r--include/configs/sun8i.h10
-rw-r--r--include/configs/theadorable.h3
-rw-r--r--include/configs/turris_omnia.h7
-rw-r--r--include/configs/x530.h3
-rw-r--r--include/spl.h1
-rw-r--r--include/tpm-v2.h2
-rw-r--r--scripts/config_whitelist.txt1
-rw-r--r--test/common/test_autoboot.c6
-rw-r--r--test/dm/of_platdata.c7
-rw-r--r--test/py/tests/test_tpm2.py18
-rw-r--r--tools/Makefile8
-rw-r--r--tools/dtoc/fdt.py40
-rw-r--r--tools/dtoc/test/dtoc_test_simple.dts2
-rwxr-xr-xtools/dtoc/test_dtoc.py9
-rwxr-xr-xtools/dtoc/test_fdt.py29
-rw-r--r--tools/kwbimage.c437
-rw-r--r--tools/kwbimage.h54
-rw-r--r--tools/kwboot.c24
-rwxr-xr-xtools/moveconfig.py315
-rw-r--r--tools/patman/func_test.py11
-rw-r--r--tools/patman/patchstream.py9
81 files changed, 1765 insertions, 854 deletions
diff --git a/Makefile b/Makefile
index 8c84c22b722..269e353a28a 100644
--- a/Makefile
+++ b/Makefile
@@ -1440,7 +1440,7 @@ u-boot.itb: u-boot-nodtb.bin \
$(BOARD_SIZE_CHECK)
endif
-u-boot-spl.kwb: u-boot.img spl/u-boot-spl.bin FORCE
+u-boot-spl.kwb: u-boot.bin spl/u-boot-spl.bin FORCE
$(call if_changed,mkimage)
u-boot.sha1: u-boot.bin
diff --git a/arch/arm/dts/sunxi-u-boot.dtsi b/arch/arm/dts/sunxi-u-boot.dtsi
index 06da009fa28..4a6ed3a7dd5 100644
--- a/arch/arm/dts/sunxi-u-boot.dtsi
+++ b/arch/arm/dts/sunxi-u-boot.dtsi
@@ -64,7 +64,7 @@
};
};
-#ifndef CONFIG_MACH_SUN50I_H616
+#ifdef SCP_ADDR
scp {
description = "SCP firmware";
type = "firmware";
@@ -92,7 +92,7 @@
@config-SEQ {
description = "NAME";
firmware = "atf";
-#ifdef CONFIG_MACH_SUN50I_H616
+#ifndef SCP_ADDR
loadables = "uboot";
#else
loadables = "scp", "uboot";
diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
index 02ce73954db..d4c795d89cb 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h
@@ -11,7 +11,18 @@
#define SUNXI_SRAM_A1_BASE 0x00000000
#define SUNXI_SRAM_A1_SIZE (16 * 1024) /* 16 kiB */
+#if defined(CONFIG_SUNXI_GEN_SUN6I) && \
+ !defined(CONFIG_MACH_SUN8I_R40) && \
+ !defined(CONFIG_MACH_SUN8I_V3S)
+#define SUNXI_SRAM_A2_BASE 0x00040000
+#ifdef CONFIG_MACH_SUN8I_H3
+#define SUNXI_SRAM_A2_SIZE (48 * 1024) /* 16+32 kiB */
+#else
+#define SUNXI_SRAM_A2_SIZE (80 * 1024) /* 16+64 kiB */
+#endif
+#else
#define SUNXI_SRAM_A2_BASE 0x00004000 /* 16 kiB */
+#endif
#define SUNXI_SRAM_A3_BASE 0x00008000 /* 13 kiB */
#define SUNXI_SRAM_A4_BASE 0x0000b400 /* 3 kiB */
#define SUNXI_SRAM_D_BASE 0x00010000 /* 4 kiB */
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 27d227d54a3..89737a37ad9 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -253,28 +253,32 @@ choice
config MVEBU_SPL_BOOT_DEVICE_SPI
bool "SPI NOR flash"
imply ENV_IS_IN_SPI_FLASH
- select SPL_DM_SPI
- select SPL_SPI_FLASH_SUPPORT
- select SPL_SPI_LOAD
- select SPL_SPI_SUPPORT
+ imply SPL_DM_SPI
+ imply SPL_SPI_FLASH_SUPPORT
+ imply SPL_SPI_LOAD
+ imply SPL_SPI_SUPPORT
+ select SPL_BOOTROM_SUPPORT
config MVEBU_SPL_BOOT_DEVICE_MMC
bool "SDIO/MMC card"
imply ENV_IS_IN_MMC
# GPIO needed for eMMC/SD card presence detection
- select SPL_DM_GPIO
- select SPL_DM_MMC
- select SPL_GPIO
- select SPL_LIBDISK_SUPPORT
- select SPL_MMC_SUPPORT
+ imply SPL_DM_GPIO
+ imply SPL_DM_MMC
+ imply SPL_GPIO
+ imply SPL_LIBDISK_SUPPORT
+ imply SPL_MMC_SUPPORT
+ select SPL_BOOTROM_SUPPORT
config MVEBU_SPL_BOOT_DEVICE_SATA
bool "SATA"
- select SPL_SATA_SUPPORT
- select SPL_LIBDISK_SUPPORT
+ imply SPL_SATA_SUPPORT
+ imply SPL_LIBDISK_SUPPORT
+ select SPL_BOOTROM_SUPPORT
config MVEBU_SPL_BOOT_DEVICE_UART
bool "UART"
+ select SPL_BOOTROM_SUPPORT
endchoice
diff --git a/arch/arm/mach-mvebu/include/mach/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h
index 52473ade7a7..79858858c25 100644
--- a/arch/arm/mach-mvebu/include/mach/cpu.h
+++ b/arch/arm/mach-mvebu/include/mach/cpu.h
@@ -142,7 +142,7 @@ int mvebu_mbus_probe(struct mbus_win windows[], int count);
int mvebu_soc_family(void);
u32 mvebu_get_nand_clock(void);
-void return_to_bootrom(void);
+void __noreturn return_to_bootrom(void);
#ifndef CONFIG_DM_MMC
int mv_sdh_init(unsigned long regbase, u32 max_clk, u32 min_clk, u32 quirks);
diff --git a/arch/arm/mach-mvebu/lowlevel_spl.S b/arch/arm/mach-mvebu/lowlevel_spl.S
index 8718d7a43e1..dde77b76521 100644
--- a/arch/arm/mach-mvebu/lowlevel_spl.S
+++ b/arch/arm/mach-mvebu/lowlevel_spl.S
@@ -13,8 +13,9 @@ ENDPROC(save_boot_params)
ENTRY(return_to_bootrom)
ldr r12, =CONFIG_SPL_BOOTROM_SAVE
ldr sp, [r12]
+ ldmfd sp!, {r0 - r12, lr} /* @ restore registers from stack */
mov r0, #0x0 /* @ return value: 0x0 NO_ERR */
- ldmfd sp!, {r0 - r12, pc} /* @ restore regs and return */
+ bx lr /* @ return to bootrom */
ENDPROC(return_to_bootrom)
/*
diff --git a/arch/arm/mach-mvebu/spl.c b/arch/arm/mach-mvebu/spl.c
index 16ebb7a59e5..3b6bc389709 100644
--- a/arch/arm/mach-mvebu/spl.c
+++ b/arch/arm/mach-mvebu/spl.c
@@ -8,6 +8,7 @@
#include <debug_uart.h>
#include <fdtdec.h>
#include <hang.h>
+#include <image.h>
#include <init.h>
#include <log.h>
#include <spl.h>
@@ -16,6 +17,160 @@
#include <asm/arch/cpu.h>
#include <asm/arch/soc.h>
+#if defined(CONFIG_SPL_SPI_FLASH_SUPPORT) || defined(CONFIG_SPL_MMC_SUPPORT) || defined(CONFIG_SPL_SATA_SUPPORT)
+
+/*
+ * When loading U-Boot via SPL from SPI NOR, CONFIG_SYS_SPI_U_BOOT_OFFS must
+ * point to the offset of kwbimage main header which is always at offset zero
+ * (defined by BootROM). Therefore other values of CONFIG_SYS_SPI_U_BOOT_OFFS
+ * makes U-Boot non-bootable.
+ */
+#ifdef CONFIG_SPL_SPI_FLASH_SUPPORT
+#if defined(CONFIG_SYS_SPI_U_BOOT_OFFS) && CONFIG_SYS_SPI_U_BOOT_OFFS != 0
+#error CONFIG_SYS_SPI_U_BOOT_OFFS must be set to 0
+#endif
+#endif
+
+/*
+ * When loading U-Boot via SPL from eMMC (in Marvell terminology SDIO), the
+ * kwbimage main header is stored at sector 0. U-Boot SPL needs to parse this
+ * header and figure out at which sector the U-Boot proper binary is stored.
+ * Partition booting is therefore not supported and CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
+ * and CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET need to point to the
+ * kwbimage main header.
+ */
+#ifdef CONFIG_SPL_MMC_SUPPORT
+#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
+#error CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION is unsupported
+#endif
+#if defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR) && CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR != 0
+#error CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR must be set to 0
+#endif
+#if defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET) && CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET != 0
+#error CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET must be set to 0
+#endif
+#endif
+
+/*
+ * When loading U-Boot via SPL from SATA disk, the kwbimage main header is
+ * stored at sector 1. Therefore CONFIG_SPL_SATA_RAW_U_BOOT_SECTOR must be
+ * set to 1. Otherwise U-Boot SPL would not be able to load U-Boot proper.
+ */
+#ifdef CONFIG_SPL_SATA_SUPPORT
+#if !defined(CONFIG_SPL_SATA_RAW_U_BOOT_USE_SECTOR) || !defined(CONFIG_SPL_SATA_RAW_U_BOOT_SECTOR) || CONFIG_SPL_SATA_RAW_U_BOOT_SECTOR != 1
+#error CONFIG_SPL_SATA_RAW_U_BOOT_SECTOR must be set to 1
+#endif
+#endif
+
+/* Boot Type - block ID */
+#define IBR_HDR_I2C_ID 0x4D
+#define IBR_HDR_SPI_ID 0x5A
+#define IBR_HDR_NAND_ID 0x8B
+#define IBR_HDR_SATA_ID 0x78
+#define IBR_HDR_PEX_ID 0x9C
+#define IBR_HDR_UART_ID 0x69
+#define IBR_HDR_SDIO_ID 0xAE
+
+/* Structure of the main header, version 1 (Armada 370/38x/XP) */
+struct kwbimage_main_hdr_v1 {
+ uint8_t blockid; /* 0x0 */
+ uint8_t flags; /* 0x1 */
+ uint16_t reserved2; /* 0x2-0x3 */
+ uint32_t blocksize; /* 0x4-0x7 */
+ uint8_t version; /* 0x8 */
+ uint8_t headersz_msb; /* 0x9 */
+ uint16_t headersz_lsb; /* 0xA-0xB */
+ uint32_t srcaddr; /* 0xC-0xF */
+ uint32_t destaddr; /* 0x10-0x13 */
+ uint32_t execaddr; /* 0x14-0x17 */
+ uint8_t options; /* 0x18 */
+ uint8_t nandblocksize; /* 0x19 */
+ uint8_t nandbadblklocation; /* 0x1A */
+ uint8_t reserved4; /* 0x1B */
+ uint16_t reserved5; /* 0x1C-0x1D */
+ uint8_t ext; /* 0x1E */
+ uint8_t checksum; /* 0x1F */
+} __packed;
+
+#ifdef CONFIG_SPL_MMC_SUPPORT
+u32 spl_mmc_boot_mode(const u32 boot_device)
+{
+ return MMCSD_MODE_RAW;
+}
+#endif
+
+int spl_parse_board_header(struct spl_image_info *spl_image,
+ const void *image_header, size_t size)
+{
+ const struct kwbimage_main_hdr_v1 *mhdr = image_header;
+
+ if (size < sizeof(*mhdr)) {
+ /* This should be compile time assert */
+ printf("FATAL ERROR: Image header size is too small\n");
+ hang();
+ }
+
+ /*
+ * Very basic check for image validity. We cannot check mhdr->checksum
+ * as it is calculated also from variable length extended headers
+ * (including SPL content) which is not included in U-Boot image_header.
+ */
+ if (mhdr->version != 1 ||
+ ((mhdr->headersz_msb << 16) | mhdr->headersz_lsb) < sizeof(*mhdr) ||
+ (
+#ifdef CONFIG_SPL_SPI_FLASH_SUPPORT
+ mhdr->blockid != IBR_HDR_SPI_ID &&
+#endif
+#ifdef CONFIG_SPL_SATA_SUPPORT
+ mhdr->blockid != IBR_HDR_SATA_ID &&
+#endif
+#ifdef CONFIG_SPL_MMC_SUPPORT
+ mhdr->blockid != IBR_HDR_SDIO_ID &&
+#endif
+ 1
+ )) {
+ printf("ERROR: Not valid SPI/NAND/SATA/SDIO kwbimage v1\n");
+ return -EINVAL;
+ }
+
+ spl_image->offset = mhdr->srcaddr;
+
+#ifdef CONFIG_SPL_SATA_SUPPORT
+ /*
+ * For SATA srcaddr is specified in number of sectors.
+ * The main header is must be stored at sector number 1.
+ * This expects that sector size is 512 bytes and recalculates
+ * data offset to bytes relative to the main header.
+ */
+ if (mhdr->blockid == IBR_HDR_SATA_ID) {
+ if (spl_image->offset < 1) {
+ printf("ERROR: Wrong SATA srcaddr in kwbimage\n");
+ return -EINVAL;
+ }
+ spl_image->offset -= 1;
+ spl_image->offset *= 512;
+ }
+#endif
+
+#ifdef CONFIG_SPL_MMC_SUPPORT
+ /*
+ * For SDIO (eMMC) srcaddr is specified in number of sectors.
+ * This expects that sector size is 512 bytes and recalculates
+ * data offset to bytes.
+ */
+ if (mhdr->blockid == IBR_HDR_SDIO_ID)
+ spl_image->offset *= 512;
+#endif
+
+ spl_image->size = mhdr->blocksize;
+ spl_image->entry_point = mhdr->execaddr;
+ spl_image->load_addr = mhdr->destaddr;
+ spl_image->os = IH_OS_U_BOOT;
+ spl_image->name = "U-Boot";
+
+ return 0;
+}
+
static u32 get_boot_device(void)
{
u32 val;
@@ -49,11 +204,11 @@ static u32 get_boot_device(void)
boot_device = (val & BOOT_DEV_SEL_MASK) >> BOOT_DEV_SEL_OFFS;
debug("SAR_REG=0x%08x boot_device=0x%x\n", val, boot_device);
switch (boot_device) {
-#if defined(CONFIG_ARMADA_38X)
+#ifdef BOOT_FROM_NAND
case BOOT_FROM_NAND:
return BOOT_DEVICE_NAND;
#endif
-#ifdef CONFIG_SPL_MMC_SUPPORT
+#ifdef BOOT_FROM_MMC
case BOOT_FROM_MMC:
case BOOT_FROM_MMC_ALT:
return BOOT_DEVICE_MMC1;
@@ -69,14 +224,77 @@ static u32 get_boot_device(void)
return BOOT_DEVICE_SATA;
#endif
case BOOT_FROM_SPI:
- default:
return BOOT_DEVICE_SPI;
+ default:
+ return BOOT_DEVICE_BOOTROM;
};
}
+#else
+
+static u32 get_boot_device(void)
+{
+ return BOOT_DEVICE_BOOTROM;
+}
+
+#endif
+
u32 spl_boot_device(void)
{
- return get_boot_device();
+ u32 boot_device = get_boot_device();
+
+ switch (boot_device) {
+ /*
+ * Return to the BootROM to continue the Marvell xmodem
+ * UART boot protocol. As initiated by the kwboot tool.
+ *
+ * This can only be done by the BootROM since the beginning
+ * of the image is already read and interpreted by the BootROM.
+ * SPL has no chance to receive this information. So we
+ * need to return to the BootROM to enable this xmodem
+ * UART download. Use SPL infrastructure to return to BootROM.
+ */
+ case BOOT_DEVICE_UART:
+ return BOOT_DEVICE_BOOTROM;
+
+ /*
+ * If SPL is compiled with chosen boot_device support
+ * then use SPL driver for loading U-Boot proper.
+ */
+#ifdef CONFIG_SPL_MMC_SUPPORT
+ case BOOT_DEVICE_MMC1:
+ return BOOT_DEVICE_MMC1;
+#endif
+#ifdef CONFIG_SPL_SATA_SUPPORT
+ case BOOT_FROM_SATA:
+ return BOOT_FROM_SATA;
+#endif
+#ifdef CONFIG_SPL_SPI_FLASH_SUPPORT
+ case BOOT_DEVICE_SPI:
+ return BOOT_DEVICE_SPI;
+#endif
+
+ /*
+ * If SPL is not compiled with chosen boot_device support
+ * then return to the BootROM. BootROM supports loading
+ * U-Boot proper from any valid boot_device present in SAR
+ * register.
+ */
+ default:
+ return BOOT_DEVICE_BOOTROM;
+ }
+}
+
+int board_return_to_bootrom(struct spl_image_info *spl_image,
+ struct spl_boot_device *bootdev)
+{
+ u32 *regs = *(u32 **)CONFIG_SPL_BOOTROM_SAVE;
+
+ printf("Returning to BootROM (return address 0x%08x)...\n", regs[13]);
+ return_to_bootrom();
+
+ /* NOTREACHED - return_to_bootrom() does not return */
+ hang();
}
void board_init_f(ulong dummy)
@@ -135,26 +353,4 @@ void board_init_f(ulong dummy)
/* Update read timing control for PCIe */
mv_rtc_config();
-
- /*
- * Return to the BootROM to continue the Marvell xmodem
- * UART boot protocol. As initiated by the kwboot tool.
- *
- * This can only be done by the BootROM and not by the
- * U-Boot SPL infrastructure, since the beginning of the
- * image is already read and interpreted by the BootROM.
- * SPL has no chance to receive this information. So we
- * need to return to the BootROM to enable this xmodem
- * UART download.
- *
- * If booting from NAND lets let the BootROM load the
- * rest of the bootloader.
- */
- switch (get_boot_device()) {
- case BOOT_DEVICE_UART:
-#if defined(CONFIG_ARMADA_38X)
- case BOOT_DEVICE_NAND:
-#endif
- return_to_bootrom();
- }
}
diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c
index 777db4e9522..a74f5ec7ba0 100644
--- a/arch/sandbox/cpu/start.c
+++ b/arch/sandbox/cpu/start.c
@@ -400,6 +400,15 @@ static int sandbox_cmdline_cb_signals(struct sandbox_state *state,
SANDBOX_CMDLINE_OPT_SHORT(signals, 'S', 0,
"Handle signals (such as SIGSEGV) in sandbox");
+static int sandbox_cmdline_cb_autoboot_keyed(struct sandbox_state *state,
+ const char *arg)
+{
+ state->autoboot_keyed = true;
+
+ return 0;
+}
+SANDBOX_CMDLINE_OPT(autoboot_keyed, 0, "Allow keyed autoboot");
+
static void setup_ram_buf(struct sandbox_state *state)
{
/* Zero the RAM buffer if we didn't read it, to keep valgrind happy */
diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c
index a4d99bade41..4e822538baf 100644
--- a/arch/sandbox/cpu/state.c
+++ b/arch/sandbox/cpu/state.c
@@ -4,6 +4,7 @@
*/
#include <common.h>
+#include <autoboot.h>
#include <bloblist.h>
#include <errno.h>
#include <fdtdec.h>
@@ -378,6 +379,23 @@ void state_reset_for_test(struct sandbox_state *state)
state->next_tag = state->ram_size;
}
+bool autoboot_keyed(void)
+{
+ struct sandbox_state *state = state_get_current();
+
+ return IS_ENABLED(CONFIG_AUTOBOOT_KEYED) && state->autoboot_keyed;
+}
+
+bool autoboot_set_keyed(bool autoboot_keyed)
+{
+ struct sandbox_state *state = state_get_current();
+ bool old_val = state->autoboot_keyed;
+
+ state->autoboot_keyed = autoboot_keyed;
+
+ return old_val;
+}
+
int state_init(void)
{
state = &main_state;
diff --git a/arch/sandbox/dts/sandbox.dtsi b/arch/sandbox/dts/sandbox.dtsi
index 31db50db352..200fcab6a41 100644
--- a/arch/sandbox/dts/sandbox.dtsi
+++ b/arch/sandbox/dts/sandbox.dtsi
@@ -231,6 +231,7 @@
boolval;
intval = <1>;
intarray = <2 3 4>;
+ maybe-empty-int = <>;
byteval = [05];
bytearray = [06];
longbytearray = [09 0a 0b 0c 0d 0e 0f 10 11];
@@ -254,6 +255,7 @@
u-boot,dm-pre-reloc;
compatible = "sandbox,spl-test";
stringarray = "one";
+ maybe-empty-int = <1>;
};
spl-test5 {
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index 1c4c571e28d..10352a587e4 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -94,6 +94,7 @@ struct sandbox_state {
bool run_unittests; /* Run unit tests */
const char *select_unittests; /* Unit test to run */
bool handle_signals; /* Handle signals within sandbox */
+ bool autoboot_keyed; /* Use keyed-autoboot feature */
/* Pointer to information for each SPI bus/cs */
struct sandbox_spi_info spi[CONFIG_SANDBOX_SPI_MAX_BUS]
diff --git a/board/Marvell/dreamplug/dreamplug.c b/board/Marvell/dreamplug/dreamplug.c
index e1c64b52246..d5b6b22ddfb 100644
--- a/board/Marvell/dreamplug/dreamplug.c
+++ b/board/Marvell/dreamplug/dreamplug.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0+
/*
+ * Copyright (C) 2021 Tony Dinh <mibodhi@gmail.com>
* (C) Copyright 2011
* Jason Cooper <u-boot@lakedaemon.net>
*
@@ -97,42 +98,75 @@ int board_init(void)
return 0;
}
+static int fdt_get_phy_addr(const char *path)
+{
+ const void *fdt = gd->fdt_blob;
+ const u32 *reg;
+ const u32 *val;
+ int node, phandle, addr;
+
+ /* Find the node by its full path */
+ node = fdt_path_offset(fdt, path);
+ if (node >= 0) {
+ /* Look up phy-handle */
+ val = fdt_getprop(fdt, node, "phy-handle", NULL);
+ if (val) {
+ phandle = fdt32_to_cpu(*val);
+ if (!phandle)
+ return -1;
+ /* Follow it to its node */
+ node = fdt_node_offset_by_phandle(fdt, phandle);
+ if (node) {
+ /* Look up reg */
+ reg = fdt_getprop(fdt, node, "reg", NULL);
+ if (reg) {
+ addr = fdt32_to_cpu(*reg);
+ return addr;
+ }
+ }
+ }
+ }
+ return -1;
+}
+
#ifdef CONFIG_RESET_PHY_R
-void mv_phy_88e1116_init(char *name)
+void mv_phy_88e1116_init(const char *name, const char *path)
{
u16 reg;
- u16 devadr;
+ int phyaddr;
if (miiphy_set_current_dev(name))
return;
- /* command to read PHY dev address */
- if (miiphy_read(name, 0xEE, 0xEE, (u16 *) &devadr)) {
- printf("Err..%s could not read PHY dev address\n",
- __func__);
+ phyaddr = fdt_get_phy_addr(path);
+ if (phyaddr < 0)
return;
- }
/*
* Enable RGMII delay on Tx and Rx for CPU port
* Ref: sec 4.7.2 of chip datasheet
*/
- miiphy_write(name, devadr, MV88E1116_PGADR_REG, 2);
- miiphy_read(name, devadr, MV88E1116_MAC_CTRL2_REG, &reg);
+ miiphy_write(name, phyaddr, MV88E1116_PGADR_REG, 2);
+ miiphy_read(name, phyaddr, MV88E1116_MAC_CTRL2_REG, &reg);
reg |= (MV88E1116_RGMII_RXTM_CTRL | MV88E1116_RGMII_TXTM_CTRL);
- miiphy_write(name, devadr, MV88E1116_MAC_CTRL2_REG, reg);
- miiphy_write(name, devadr, MV88E1116_PGADR_REG, 0);
+ miiphy_write(name, phyaddr, MV88E1116_MAC_CTRL2_REG, reg);
+ miiphy_write(name, phyaddr, MV88E1116_PGADR_REG, 0);
/* reset the phy */
- miiphy_reset(name, devadr);
+ miiphy_reset(name, phyaddr);
printf("88E1116 Initialized on %s\n", name);
}
void reset_phy(void)
{
+ char *eth0_name = "ethernet-controller@72000";
+ char *eth0_path = "/ocp@f1000000/ethernet-controller@72000/ethernet0-port@0";
+ char *eth1_name = "ethernet-controller@76000";
+ char *eth1_path = "/ocp@f1000000/ethernet-controller@72000/ethernet1-port@0";
+
/* configure and initialize both PHY's */
- mv_phy_88e1116_init("egiga0");
- mv_phy_88e1116_init("egiga1");
+ mv_phy_88e1116_init(eth0_name, eth0_path);
+ mv_phy_88e1116_init(eth1_name, eth1_path);
}
#endif /* CONFIG_RESET_PHY_R */
diff --git a/board/gdsys/a38x/Makefile b/board/gdsys/a38x/Makefile
index 32fffab467b..4b13859fed1 100644
--- a/board/gdsys/a38x/Makefile
+++ b/board/gdsys/a38x/Makefile
@@ -4,7 +4,7 @@
# Copyright (C) 2015 Reinhard Pfau <reinhard.pfau@gdsys.cc>
# Copyright (C) 2016 Mario Six <mario.six@gdsys.cc>
-obj-$(CONFIG_TARGET_CONTROLCENTERDC) += controlcenterdc.o hre.o spl.o keyprogram.o dt_helpers.o
+obj-$(CONFIG_TARGET_CONTROLCENTERDC) += controlcenterdc.o hre.o keyprogram.o dt_helpers.o
ifeq ($(CONFIG_SPL_BUILD),)
obj-$(CONFIG_TARGET_CONTROLCENTERDC) += hydra.o ihs_phys.o
diff --git a/board/gdsys/a38x/spl.c b/board/gdsys/a38x/spl.c
deleted file mode 100644
index 84864d19746..00000000000
--- a/board/gdsys/a38x/spl.c
+++ /dev/null
@@ -1,20 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * (C) Copyright 2016
- * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
- */
-
-#include <common.h>
-#include <config.h>
-#include <asm/arch/cpu.h>
-
-void spl_board_init(void)
-{
-#if CONFIG_SPL_BOOT_DEVICE == SPL_BOOT_SPI_NOR_FLASH
- u32 *bootrom_save = (u32 *)CONFIG_SPL_BOOTROM_SAVE;
- u32 *regs = (u32 *)(*bootrom_save);
-
- printf("Returning to BootROM (return address %08x)...\n", regs[13]);
- return_to_bootrom();
-#endif
-}
diff --git a/board/kobol/helios4/Kconfig b/board/kobol/helios4/Kconfig
index cad51c1cf02..81a2199ae5f 100644
--- a/board/kobol/helios4/Kconfig
+++ b/board/kobol/helios4/Kconfig
@@ -16,9 +16,4 @@ config ENV_SECT_SIZE
# Use optimistic 64 KiB erase block, will vary between actual media
default 0x10000 if MVEBU_SPL_BOOT_DEVICE_MMC || MVEBU_SPL_BOOT_DEVICE_UART
-config SYS_SPI_U_BOOT_OFFS
- hex "address of u-boot payload in SPI flash"
- default 0x20000
- depends on MVEBU_SPL_BOOT_DEVICE_SPI
-
endmenu
diff --git a/board/solidrun/clearfog/Kconfig b/board/solidrun/clearfog/Kconfig
index cf952580906..60d39213073 100644
--- a/board/solidrun/clearfog/Kconfig
+++ b/board/solidrun/clearfog/Kconfig
@@ -54,9 +54,4 @@ config ENV_SECT_SIZE
# Use optimistic 64 KiB erase block, will vary between actual media
default 0x10000 if MVEBU_SPL_BOOT_DEVICE_MMC || MVEBU_SPL_BOOT_DEVICE_UART
-config SYS_SPI_U_BOOT_OFFS
- hex "address of u-boot payload in SPI flash"
- default 0x20000
- depends on MVEBU_SPL_BOOT_DEVICE_SPI
-
endmenu
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 67acc01d83a..1a46100e408 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -636,6 +636,20 @@ int board_mmc_init(struct bd_info *bis)
return 0;
}
+
+#if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
+int mmc_get_env_dev(void)
+{
+ switch (sunxi_get_boot_device()) {
+ case BOOT_DEVICE_MMC1:
+ return 0;
+ case BOOT_DEVICE_MMC2:
+ return 1;
+ default:
+ return CONFIG_SYS_MMC_ENV_DEV;
+ }
+}
+#endif
#endif
#ifdef CONFIG_SPL_BUILD
diff --git a/cmd/fdt.c b/cmd/fdt.c
index f1e2fc2fd8b..baec05529ad 100644
--- a/cmd/fdt.c
+++ b/cmd/fdt.c
@@ -115,26 +115,20 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
if (argc < 2)
return CMD_RET_USAGE;
- /*
- * Set the address of the fdt
- */
+ /* fdt addr: Set the address of the fdt */
if (strncmp(argv[1], "ad", 2) == 0) {
unsigned long addr;
int control = 0;
struct fdt_header *blob;
- /*
- * Set the address [and length] of the fdt.
- */
+
+ /* Set the address [and length] of the fdt */
argc -= 2;
argv += 2;
-/* Temporary #ifdef - some archs don't have fdt_blob yet */
-#ifdef CONFIG_OF_CONTROL
if (argc && !strcmp(*argv, "-c")) {
control = 1;
argc--;
argv++;
}
-#endif
if (argc == 0) {
if (control)
blob = (struct fdt_header *)gd->fdt_blob;
@@ -142,9 +136,10 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
blob = working_fdt;
if (!blob || !fdt_valid(&blob))
return 1;
- printf("The address of the fdt is %#08lx\n",
+ printf("%s fdt: %08lx\n",
+ control ? "Control" : "Working",
control ? (ulong)map_to_sysmem(blob) :
- env_get_hex("fdtaddr", 0));
+ env_get_hex("fdtaddr", 0));
return 0;
}
@@ -160,22 +155,18 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
if (argc >= 2) {
int len;
int err;
- /*
- * Optional new length
- */
+
+ /* Optional new length */
len = simple_strtoul(argv[1], NULL, 16);
if (len < fdt_totalsize(blob)) {
- printf ("New length %d < existing length %d, "
- "ignoring.\n",
- len, fdt_totalsize(blob));
+ printf("New length %d < existing length %d, ignoring\n",
+ len, fdt_totalsize(blob));
} else {
- /*
- * Open in place with a new length.
- */
+ /* Open in place with a new length */
err = fdt_open_into(blob, blob, len);
if (err != 0) {
- printf ("libfdt fdt_open_into(): %s\n",
- fdt_strerror(err));
+ printf("libfdt fdt_open_into(): %s\n",
+ fdt_strerror(err));
}
}
}
@@ -184,10 +175,9 @@ static int do_fdt(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
}
if (!working_fdt) {
- puts(
- "No FDT memory address configured. Please configure\n"
- "the FDT address via \"fdt addr <address>\" command.\n"
- "Aborting!\n");
+ puts("No FDT memory address configured. Please configure\n"
+ "the FDT address via \"fdt addr <address>\" command.\n"
+ "Aborting!\n");
return CMD_RET_FAILURE;
}
diff --git a/common/autoboot.c b/common/autoboot.c
index 8b9e9aa8785..5bb2e190895 100644
--- a/common/autoboot.c
+++ b/common/autoboot.c
@@ -406,7 +406,7 @@ static int abortboot(int bootdelay)
int abort = 0;
if (bootdelay >= 0) {
- if (IS_ENABLED(CONFIG_AUTOBOOT_KEYED))
+ if (autoboot_keyed())
abort = abortboot_key_sequence(bootdelay);
else
abort = abortboot_single_key(bootdelay);
@@ -481,7 +481,7 @@ void autoboot_command(const char *s)
bool lock;
int prev;
- lock = IS_ENABLED(CONFIG_AUTOBOOT_KEYED) &&
+ lock = autoboot_keyed() &&
!IS_ENABLED(CONFIG_AUTOBOOT_KEYED_CTRLC);
if (lock)
prev = disable_ctrlc(1); /* disable Ctrl-C checking */
@@ -498,4 +498,4 @@ void autoboot_command(const char *s)
if (s)
run_command_list(s, -1, 0);
}
-} \ No newline at end of file
+}
diff --git a/common/board_r.c b/common/board_r.c
index 3f824047727..e3e6248a1fd 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -323,10 +323,16 @@ static int initr_manual_reloc_cmdtable(void)
static int initr_binman(void)
{
+ int ret;
+
if (!CONFIG_IS_ENABLED(BINMAN_FDT))
return 0;
- return binman_init();
+ ret = binman_init();
+ if (ret)
+ printf("binman_init failed:%d\n", ret);
+
+ return ret;
}
#if defined(CONFIG_MTD_NOR_FLASH)
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 9552ed49117..c155a3b5fcc 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -344,7 +344,7 @@ config SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
default 0x75 if ARCH_DAVINCI
default 0x8a if ARCH_MX6 || ARCH_MX7
default 0x100 if ARCH_UNIPHIER
- default 0x140 if ARCH_MVEBU
+ default 0x0 if ARCH_MVEBU
default 0x200 if ARCH_SOCFPGA || ARCH_AT91
default 0x300 if ARCH_ZYNQ || ARCH_KEYSTONE || OMAP34XX || OMAP44XX || \
OMAP54XX || AM33XX || AM43XX || ARCH_K3
@@ -1099,6 +1099,7 @@ config SPL_SATA_SUPPORT
config SPL_SATA_RAW_U_BOOT_USE_SECTOR
bool "SATA raw mode: by sector"
depends on SPL_SATA_SUPPORT
+ default y if ARCH_MVEBU
help
Use sector number for specifying U-Boot location on SATA disk in
raw mode.
@@ -1106,6 +1107,7 @@ config SPL_SATA_RAW_U_BOOT_USE_SECTOR
config SPL_SATA_RAW_U_BOOT_SECTOR
hex "Sector on the SATA disk to load U-Boot from"
depends on SPL_SATA_RAW_U_BOOT_USE_SECTOR
+ default 0x1 if ARCH_MVEBU
help
Sector on the SATA disk to load U-Boot from, when the SATA disk is being
used in raw mode. Units: SATA disk sectors (1 sector = 512 bytes).
diff --git a/common/spl/spl.c b/common/spl/spl.c
index f6375b06a19..d55d3c28485 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -300,6 +300,12 @@ static int spl_load_fit_image(struct spl_image_info *spl_image,
}
#endif
+__weak int spl_parse_board_header(struct spl_image_info *spl_image,
+ const void *image_header, size_t size)
+{
+ return -EINVAL;
+}
+
__weak int spl_parse_legacy_header(struct spl_image_info *spl_image,
const struct image_header *header)
{
@@ -352,6 +358,9 @@ int spl_parse_image_header(struct spl_image_info *spl_image,
}
#endif
+ if (!spl_parse_board_header(spl_image, (const void *)header, sizeof(*header)))
+ return 0;
+
#ifdef CONFIG_SPL_RAW_IMAGE_SUPPORT
/* Signature not found - assume u-boot.bin */
debug("mkimage signature not found - ih_magic = %x\n",
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index 4dff9bfd6e8..212a2b09928 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -20,26 +20,40 @@
static int mmc_load_legacy(struct spl_image_info *spl_image, struct mmc *mmc,
ulong sector, struct image_header *header)
{
+ u32 image_offset_sectors;
u32 image_size_sectors;
unsigned long count;
+ u32 image_offset;
int ret;
ret = spl_parse_image_header(spl_image, header);
if (ret)
return ret;
+ /* convert offset to sectors - round down */
+ image_offset_sectors = spl_image->offset / mmc->read_bl_len;
+ /* calculate remaining offset */
+ image_offset = spl_image->offset % mmc->read_bl_len;
+
/* convert size to sectors - round up */
image_size_sectors = (spl_image->size + mmc->read_bl_len - 1) /
mmc->read_bl_len;
/* Read the header too to avoid extra memcpy */
- count = blk_dread(mmc_get_blk_desc(mmc), sector, image_size_sectors,
+ count = blk_dread(mmc_get_blk_desc(mmc),
+ sector + image_offset_sectors,
+ image_size_sectors,
(void *)(ulong)spl_image->load_addr);
debug("read %x sectors to %lx\n", image_size_sectors,
spl_image->load_addr);
if (count != image_size_sectors)
return -EIO;
+ if (image_offset)
+ memmove((void *)(ulong)spl_image->load_addr,
+ (void *)(ulong)spl_image->load_addr + image_offset,
+ spl_image->size);
+
return 0;
}
diff --git a/common/spl/spl_sata.c b/common/spl/spl_sata.c
index e108af0576a..535a9219efa 100644
--- a/common/spl/spl_sata.c
+++ b/common/spl/spl_sata.c
@@ -36,6 +36,8 @@ static int spl_sata_load_image_raw(struct spl_image_info *spl_image,
struct image_header *header;
unsigned long count;
u32 image_size_sectors;
+ u32 image_offset_sectors;
+ u32 image_offset;
int ret;
header = spl_get_load_buffer(-sizeof(*header), stor_dev->blksz);
@@ -48,11 +50,19 @@ static int spl_sata_load_image_raw(struct spl_image_info *spl_image,
return ret;
image_size_sectors = DIV_ROUND_UP(spl_image->size, stor_dev->blksz);
- count = blk_dread(stor_dev, sector, image_size_sectors,
+ image_offset_sectors = spl_image->offset / stor_dev->blksz;
+ image_offset = spl_image->offset % stor_dev->blksz;
+ count = blk_dread(stor_dev, sector + image_offset_sectors,
+ image_size_sectors,
(void *)spl_image->load_addr);
if (count != image_size_sectors)
return -EIO;
+ if (image_offset)
+ memmove((void *)spl_image->load_addr,
+ (void *)spl_image->load_addr + image_offset,
+ spl_image->size);
+
return 0;
}
diff --git a/common/spl/spl_spi.c b/common/spl/spl_spi.c
index 6a4e0332870..9884e7c1850 100644
--- a/common/spl/spl_spi.c
+++ b/common/spl/spl_spi.c
@@ -159,7 +159,7 @@ static int spl_spi_load_image(struct spl_image_info *spl_image,
err = spl_parse_image_header(spl_image, header);
if (err)
return err;
- err = spi_flash_read(flash, payload_offs,
+ err = spi_flash_read(flash, payload_offs + spl_image->offset,
spl_image->size,
(void *)spl_image->load_addr);
}
diff --git a/configs/clearfog_defconfig b/configs/clearfog_defconfig
index 8f28eb8f986..d8edc453fff 100644
--- a/configs/clearfog_defconfig
+++ b/configs/clearfog_defconfig
@@ -24,7 +24,6 @@ CONFIG_USE_PREBOOT=y
CONFIG_SYS_CONSOLE_INFO_QUIET=y
# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_DISPLAY_BOARDINFO_LATE=y
-CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET=0x1
CONFIG_SPL_I2C=y
CONFIG_CMD_TLV_EEPROM=y
CONFIG_SPL_CMD_TLV_EEPROM=y
diff --git a/configs/controlcenterdc_defconfig b/configs/controlcenterdc_defconfig
index 3a2aa2063c5..bb1e09585c0 100644
--- a/configs/controlcenterdc_defconfig
+++ b/configs/controlcenterdc_defconfig
@@ -9,7 +9,6 @@ CONFIG_TARGET_CONTROLCENTERDC=y
CONFIG_ENV_SIZE=0x10000
CONFIG_ENV_OFFSET=0x100000
CONFIG_ENV_SECT_SIZE=0x40000
-CONFIG_SYS_SPI_U_BOOT_OFFS=0x30000
CONFIG_DM_GPIO=y
CONFIG_DEFAULT_DEVICE_TREE="armada-38x-controlcenterdc"
CONFIG_SPL_TEXT_BASE=0x40000030
@@ -28,7 +27,6 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_BOARD_LATE_INIT=y
CONFIG_LAST_STAGE_INIT=y
-CONFIG_SPL_BOARD_INIT=y
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
CONFIG_HUSH_PARSER=y
# CONFIG_CMD_ELF is not set
diff --git a/configs/db-88f6720_defconfig b/configs/db-88f6720_defconfig
index 963f5cdf47c..7f9d65f020b 100644
--- a/configs/db-88f6720_defconfig
+++ b/configs/db-88f6720_defconfig
@@ -10,7 +10,6 @@ CONFIG_TARGET_DB_88F6720=y
CONFIG_ENV_SIZE=0x10000
CONFIG_ENV_OFFSET=0x100000
CONFIG_ENV_SECT_SIZE=0x10000
-CONFIG_SYS_SPI_U_BOOT_OFFS=0x20000
CONFIG_DEFAULT_DEVICE_TREE="armada-375-db"
CONFIG_SPL_TEXT_BASE=0x40004030
CONFIG_SPL_SERIAL_SUPPORT=y
diff --git a/configs/db-88f6820-amc_defconfig b/configs/db-88f6820-amc_defconfig
index bd23ce71856..96841d78627 100644
--- a/configs/db-88f6820-amc_defconfig
+++ b/configs/db-88f6820-amc_defconfig
@@ -10,7 +10,6 @@ CONFIG_TARGET_DB_88F6820_AMC=y
CONFIG_ENV_SIZE=0x10000
CONFIG_ENV_OFFSET=0x100000
CONFIG_ENV_SECT_SIZE=0x40000
-CONFIG_SYS_SPI_U_BOOT_OFFS=0x24000
CONFIG_DEFAULT_DEVICE_TREE="armada-385-db-88f6820-amc"
CONFIG_SPL_TEXT_BASE=0x40000030
CONFIG_SPL_SERIAL_SUPPORT=y
diff --git a/configs/db-88f6820-gp_defconfig b/configs/db-88f6820-gp_defconfig
index be91fafcbe1..0ab8722c82f 100644
--- a/configs/db-88f6820-gp_defconfig
+++ b/configs/db-88f6820-gp_defconfig
@@ -10,7 +10,6 @@ CONFIG_TARGET_DB_88F6820_GP=y
CONFIG_ENV_SIZE=0x10000
CONFIG_ENV_OFFSET=0x100000
CONFIG_ENV_SECT_SIZE=0x40000
-CONFIG_SYS_SPI_U_BOOT_OFFS=0x24000
CONFIG_DEFAULT_DEVICE_TREE="armada-388-gp"
CONFIG_SPL_TEXT_BASE=0x40000030
CONFIG_SPL_SERIAL_SUPPORT=y
@@ -24,7 +23,6 @@ CONFIG_USE_PREBOOT=y
CONFIG_SYS_CONSOLE_INFO_QUIET=y
# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_DISPLAY_BOARDINFO_LATE=y
-CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y
CONFIG_SPL_I2C=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
diff --git a/configs/db-mv784mp-gp_defconfig b/configs/db-mv784mp-gp_defconfig
index b56ec57d548..a4345bae2b0 100644
--- a/configs/db-mv784mp-gp_defconfig
+++ b/configs/db-mv784mp-gp_defconfig
@@ -10,7 +10,6 @@ CONFIG_TARGET_DB_MV784MP_GP=y
CONFIG_ENV_SIZE=0x10000
CONFIG_ENV_OFFSET=0x100000
CONFIG_ENV_SECT_SIZE=0x10000
-CONFIG_SYS_SPI_U_BOOT_OFFS=0x20000
CONFIG_DEFAULT_DEVICE_TREE="armada-xp-gp"
CONFIG_SPL_TEXT_BASE=0x40004030
CONFIG_SPL_SERIAL_SUPPORT=y
diff --git a/configs/dreamplug_defconfig b/configs/dreamplug_defconfig
index 288182a51b1..020d8b9e417 100644
--- a/configs/dreamplug_defconfig
+++ b/configs/dreamplug_defconfig
@@ -49,3 +49,7 @@ CONFIG_KIRKWOOD_SPI=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_STORAGE=y
+CONFIG_DM_ETH=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_CMD_SATA=y
+CONFIG_SATA_MV=y
diff --git a/configs/ds414_defconfig b/configs/ds414_defconfig
index 8ec7846f0b5..bfe2e5f4fe7 100644
--- a/configs/ds414_defconfig
+++ b/configs/ds414_defconfig
@@ -10,7 +10,6 @@ CONFIG_TARGET_DS414=y
CONFIG_ENV_SIZE=0x10000
CONFIG_ENV_OFFSET=0x7E0000
CONFIG_ENV_SECT_SIZE=0x10000
-CONFIG_SYS_SPI_U_BOOT_OFFS=0x24000
CONFIG_DEFAULT_DEVICE_TREE="armada-xp-synology-ds414"
CONFIG_SPL_TEXT_BASE=0x40004030
CONFIG_SPL_SERIAL_SUPPORT=y
diff --git a/configs/helios4_defconfig b/configs/helios4_defconfig
index 77827bb1fef..4e593601efd 100644
--- a/configs/helios4_defconfig
+++ b/configs/helios4_defconfig
@@ -24,7 +24,6 @@ CONFIG_USE_PREBOOT=y
CONFIG_SYS_CONSOLE_INFO_QUIET=y
# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_DISPLAY_BOARDINFO_LATE=y
-CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET=0x1
CONFIG_SPL_I2C=y
CONFIG_CMD_TLV_EEPROM=y
CONFIG_SPL_CMD_TLV_EEPROM=y
diff --git a/configs/maxbcm_defconfig b/configs/maxbcm_defconfig
index 8e8b0ff9860..f4e493cc928 100644
--- a/configs/maxbcm_defconfig
+++ b/configs/maxbcm_defconfig
@@ -10,7 +10,6 @@ CONFIG_TARGET_MAXBCM=y
CONFIG_ENV_SIZE=0x10000
CONFIG_ENV_OFFSET=0x100000
CONFIG_ENV_SECT_SIZE=0x10000
-CONFIG_SYS_SPI_U_BOOT_OFFS=0x20000
CONFIG_DEFAULT_DEVICE_TREE="armada-xp-maxbcm"
CONFIG_SPL_TEXT_BASE=0x40004030
CONFIG_SPL_SERIAL_SUPPORT=y
diff --git a/configs/theadorable_debug_defconfig b/configs/theadorable_debug_defconfig
index 0104324a66f..93b0c6b0645 100644
--- a/configs/theadorable_debug_defconfig
+++ b/configs/theadorable_debug_defconfig
@@ -10,7 +10,6 @@ CONFIG_TARGET_THEADORABLE=y
CONFIG_ENV_SIZE=0x10000
CONFIG_ENV_OFFSET=0x100000
CONFIG_ENV_SECT_SIZE=0x40000
-CONFIG_SYS_SPI_U_BOOT_OFFS=0x1a000
CONFIG_DM_GPIO=y
CONFIG_DEFAULT_DEVICE_TREE="armada-xp-theadorable"
CONFIG_SPL_TEXT_BASE=0x40004030
diff --git a/configs/turris_omnia_defconfig b/configs/turris_omnia_defconfig
index 298a4da47f1..cd443ceb300 100644
--- a/configs/turris_omnia_defconfig
+++ b/configs/turris_omnia_defconfig
@@ -14,7 +14,6 @@ CONFIG_TARGET_TURRIS_OMNIA=y
CONFIG_ENV_SIZE=0x10000
CONFIG_ENV_OFFSET=0xF0000
CONFIG_ENV_SECT_SIZE=0x10000
-CONFIG_SYS_SPI_U_BOOT_OFFS=0x24000
CONFIG_DM_GPIO=y
CONFIG_DEFAULT_DEVICE_TREE="armada-385-turris-omnia"
CONFIG_SPL_TEXT_BASE=0x40000030
diff --git a/configs/x530_defconfig b/configs/x530_defconfig
index 90798a39969..6df383b81e6 100644
--- a/configs/x530_defconfig
+++ b/configs/x530_defconfig
@@ -10,7 +10,6 @@ CONFIG_TARGET_X530=y
CONFIG_ENV_SIZE=0x10000
CONFIG_ENV_OFFSET=0x100000
CONFIG_ENV_SECT_SIZE=0x40000
-CONFIG_SYS_SPI_U_BOOT_OFFS=0x24000
CONFIG_DM_GPIO=y
CONFIG_DEFAULT_DEVICE_TREE="armada-385-atl-x530"
CONFIG_SPL_TEXT_BASE=0x40000030
diff --git a/doc/develop/index.rst b/doc/develop/index.rst
index 54e14dd77b5..3ead7bda8fd 100644
--- a/doc/develop/index.rst
+++ b/doc/develop/index.rst
@@ -41,8 +41,16 @@ Testing
.. toctree::
:maxdepth: 1
- coccinelle
testing
py_testing
tests_writing
tests_sandbox
+
+Refactoring
+-----------
+
+.. toctree::
+ :maxdepth: 1
+
+ coccinelle
+ moveconfig
diff --git a/doc/develop/moveconfig.rst b/doc/develop/moveconfig.rst
new file mode 100644
index 00000000000..dcd4d927e40
--- /dev/null
+++ b/doc/develop/moveconfig.rst
@@ -0,0 +1,282 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+moveconfig
+==========
+
+Since Kconfig was introduced to U-Boot, we have worked on moving
+config options from headers to Kconfig (defconfig).
+
+This tool intends to help this tremendous work.
+
+Installing
+----------
+
+You may need to install 'python3-asteval' for the 'asteval' module.
+
+Usage
+-----
+
+First, you must edit the Kconfig to add the menu entries for the configs
+you are moving.
+
+Then run this tool giving CONFIG names you want to move.
+For example, if you want to move CONFIG_CMD_USB and CONFIG_SYS_TEXT_BASE,
+simply type as follows::
+
+ $ tools/moveconfig.py CONFIG_CMD_USB CONFIG_SYS_TEXT_BASE
+
+The tool walks through all the defconfig files and move the given CONFIGs.
+
+The log is also displayed on the terminal.
+
+The log is printed for each defconfig as follows::
+
+ <defconfig_name>
+ <action1>
+ <action2>
+ <action3>
+ ...
+
+`<defconfig_name>` is the name of the defconfig.
+
+`<action*>` shows what the tool did for that defconfig.
+It looks like one of the following:
+
+ - Move 'CONFIG\_... '
+ This config option was moved to the defconfig
+
+ - CONFIG\_... is not defined in Kconfig. Do nothing.
+ The entry for this CONFIG was not found in Kconfig. The option is not
+ defined in the config header, either. So, this case can be just skipped.
+
+ - CONFIG\_... is not defined in Kconfig (suspicious). Do nothing.
+ This option is defined in the config header, but its entry was not found
+ in Kconfig.
+ There are two common cases:
+
+ - You forgot to create an entry for the CONFIG before running
+ this tool, or made a typo in a CONFIG passed to this tool.
+ - The entry was hidden due to unmet 'depends on'.
+
+ The tool does not know if the result is reasonable, so please check it
+ manually.
+
+ - 'CONFIG\_...' is the same as the define in Kconfig. Do nothing.
+ The define in the config header matched the one in Kconfig.
+ We do not need to touch it.
+
+ - Compiler is missing. Do nothing.
+ The compiler specified for this architecture was not found
+ in your PATH environment.
+ (If -e option is passed, the tool exits immediately.)
+
+ - Failed to process.
+ An error occurred during processing this defconfig. Skipped.
+ (If -e option is passed, the tool exits immediately on error.)
+
+Finally, you will be asked, Clean up headers? [y/n]:
+
+If you say 'y' here, the unnecessary config defines are removed
+from the config headers (include/configs/\*.h).
+It just uses the regex method, so you should not rely on it.
+Just in case, please do 'git diff' to see what happened.
+
+
+How does it work?
+-----------------
+
+This tool runs configuration and builds include/autoconf.mk for every
+defconfig. The config options defined in Kconfig appear in the .config
+file (unless they are hidden because of unmet dependency.)
+On the other hand, the config options defined by board headers are seen
+in include/autoconf.mk. The tool looks for the specified options in both
+of them to decide the appropriate action for the options. If the given
+config option is found in the .config, but its value does not match the
+one from the board header, the config option in the .config is replaced
+with the define in the board header. Then, the .config is synced by
+"make savedefconfig" and the defconfig is updated with it.
+
+For faster processing, this tool handles multi-threading. It creates
+separate build directories where the out-of-tree build is run. The
+temporary build directories are automatically created and deleted as
+needed. The number of threads are chosen based on the number of the CPU
+cores of your system although you can change it via -j (--jobs) option.
+
+
+Toolchains
+----------
+
+Appropriate toolchain are necessary to generate include/autoconf.mk
+for all the architectures supported by U-Boot. Most of them are available
+at the kernel.org site, some are not provided by kernel.org. This tool uses
+the same tools as buildman, so see that tool for setup (e.g. --fetch-arch).
+
+
+Tips and trips
+--------------
+
+To sync only X86 defconfigs::
+
+ ./tools/moveconfig.py -s -d <(grep -l X86 configs/*)
+
+or::
+
+ grep -l X86 configs/* | ./tools/moveconfig.py -s -d -
+
+To process CONFIG_CMD_FPGAD only for a subset of configs based on path match::
+
+ ls configs/{hrcon*,iocon*,strider*} | \
+ ./tools/moveconfig.py -Cy CONFIG_CMD_FPGAD -d -
+
+
+Finding implied CONFIGs
+-----------------------
+
+Some CONFIG options can be implied by others and this can help to reduce
+the size of the defconfig files. For example, CONFIG_X86 implies
+CONFIG_CMD_IRQ, so we can put 'imply CMD_IRQ' under 'config X86' and
+all x86 boards will have that option, avoiding adding CONFIG_CMD_IRQ to
+each of the x86 defconfig files.
+
+This tool can help find such configs. To use it, first build a database::
+
+ ./tools/moveconfig.py -b
+
+Then try to query it::
+
+ ./tools/moveconfig.py -i CONFIG_I8042_KEYB
+ CONFIG_I8042_KEYB found in 33/5155 defconfigs
+ 28 : CONFIG_X86
+ 28 : CONFIG_SA_PCIEX_LENGTH
+ 28 : CONFIG_HPET_ADDRESS
+ 28 : CONFIG_MAX_PIRQ_LINKS
+ 28 : CONFIG_I8254_TIMER
+ 28 : CONFIG_I8259_PIC
+ 28 : CONFIG_RAMBASE
+ 28 : CONFIG_IRQ_SLOT_COUNT
+ 28 : CONFIG_PCIE_ECAM_SIZE
+ 28 : CONFIG_APIC
+ ...
+
+This shows a list of config options which might imply CONFIG_I8042_KEYB along
+with how many defconfigs they cover. From this you can see that CONFIG_X86
+generally implies CONFIG_I8042_KEYB but not always (28 out of 35). Therefore,
+instead of adding CONFIG_I8042_KEYB to
+the defconfig of every x86 board, you could add a single imply line to the
+Kconfig file::
+
+ config X86
+ bool "x86 architecture"
+ ...
+ imply CMD_EEPROM
+
+That will cover 28 defconfigs and you can perhaps find another condition that
+indicates that CONFIG_I8042_KEYB is not needed for the remaining 5 boards. Many
+of the options listed are not suitable as they are not related. E.g. it would be
+odd for CONFIG_RAMBASE to imply CONFIG_I8042_KEYB.
+
+Using this search you can reduce the size of moveconfig patches.
+
+You can automatically add 'imply' statements in the Kconfig with the -a
+option::
+
+ ./tools/moveconfig.py -s -i CONFIG_SCSI \
+ -a CONFIG_ARCH_LS1021A,CONFIG_ARCH_LS1043A
+
+This will add 'imply SCSI' to the two CONFIG options mentioned, assuming that
+the database indicates that they do actually imply CONFIG_SCSI and do not
+already have an 'imply SCSI'.
+
+The output shows where the imply is added::
+
+ 18 : CONFIG_ARCH_LS1021A arch/arm/cpu/armv7/ls102xa/Kconfig:1
+ 13 : CONFIG_ARCH_LS1043A arch/arm/cpu/armv8/fsl-layerscape/Kconfig:11
+ 12 : CONFIG_ARCH_LS1046A arch/arm/cpu/armv8/fsl-layerscape/Kconfig:31
+
+The first number is the number of boards which can avoid having a special
+CONFIG_SCSI option in their defconfig file if this 'imply' is added.
+The location at the right is the Kconfig file and line number where the config
+appears. For example, adding 'imply CONFIG_SCSI' to the 'config ARCH_LS1021A'
+in arch/arm/cpu/armv7/ls102xa/Kconfig at line 1 will help 18 boards to reduce
+the size of their defconfig files.
+
+If you want to add an 'imply' to every imply config in the list, you can use::
+
+ ./tools/moveconfig.py -s -i CONFIG_SCSI -a all
+
+To control which ones are displayed, use -I <list> where list is a list of
+options (use '-I help' to see possible options and their meaning).
+
+To skip showing you options that already have an 'imply' attached, use -A.
+
+When you have finished adding 'imply' options you can regenerate the
+defconfig files for affected boards with something like::
+
+ git show --stat | ./tools/moveconfig.py -s -d -
+
+This will regenerate only those defconfigs changed in the current commit.
+If you start with (say) 100 defconfigs being changed in the commit, and add
+a few 'imply' options as above, then regenerate, hopefully you can reduce the
+number of defconfigs changed in the commit.
+
+
+Available options
+-----------------
+
+ -c, --color
+ Surround each portion of the log with escape sequences to display it
+ in color on the terminal.
+
+ -C, --commit
+ Create a git commit with the changes when the operation is complete. A
+ standard commit message is used which may need to be edited.
+
+ -d, --defconfigs
+ Specify a file containing a list of defconfigs to move. The defconfig
+ files can be given with shell-style wildcards. Use '-' to read from stdin.
+
+ -n, --dry-run
+ Perform a trial run that does not make any changes. It is useful to
+ see what is going to happen before one actually runs it.
+
+ -e, --exit-on-error
+ Exit immediately if Make exits with a non-zero status while processing
+ a defconfig file.
+
+ -s, --force-sync
+ Do "make savedefconfig" forcibly for all the defconfig files.
+ If not specified, "make savedefconfig" only occurs for cases
+ where at least one CONFIG was moved.
+
+ -S, --spl
+ Look for moved config options in spl/include/autoconf.mk instead of
+ include/autoconf.mk. This is useful for moving options for SPL build
+ because SPL related options (mostly prefixed with CONFIG_SPL\_) are
+ sometimes blocked by CONFIG_SPL_BUILD ifdef conditionals.
+
+ -H, --headers-only
+ Only cleanup the headers; skip the defconfig processing
+
+ -j, --jobs
+ Specify the number of threads to run simultaneously. If not specified,
+ the number of threads is the same as the number of CPU cores.
+
+ -r, --git-ref
+ Specify the git ref to clone for building the autoconf.mk. If unspecified
+ use the CWD. This is useful for when changes to the Kconfig affect the
+ default values and you want to capture the state of the defconfig from
+ before that change was in effect. If in doubt, specify a ref pre-Kconfig
+ changes (use HEAD if Kconfig changes are not committed). Worst case it will
+ take a bit longer to run, but will always do the right thing.
+
+ -v, --verbose
+ Show any build errors as boards are built
+
+ -y, --yes
+ Instead of prompting, automatically go ahead with all operations. This
+ includes cleaning up headers, CONFIG_SYS_EXTRA_OPTIONS, the config whitelist
+ and the README.
+
+To see the complete list of supported options, run::
+
+ tools/moveconfig.py -h
diff --git a/doc/develop/testing.rst b/doc/develop/testing.rst
index ced13ac8bb4..1abe4d7f0f0 100644
--- a/doc/develop/testing.rst
+++ b/doc/develop/testing.rst
@@ -1,5 +1,7 @@
-Testing in U-Boot
-=================
+.. SPDX-License-Identifier: GPL-2.0+
+
+Introduction to testing
+=======================
U-Boot has a large amount of code. This file describes how this code is
tested and what tests you should write when adding a new feature.
diff --git a/doc/device-tree-bindings/pinctrl/marvell,armada-37xx-pinctrl.txt b/doc/device-tree-bindings/pinctrl/marvell,armada-37xx-pinctrl.txt
index 86ec11361c1..3139a99fa97 100644
--- a/doc/device-tree-bindings/pinctrl/marvell,armada-37xx-pinctrl.txt
+++ b/doc/device-tree-bindings/pinctrl/marvell,armada-37xx-pinctrl.txt
@@ -38,19 +38,19 @@ group emmc_nb
group pwm0
- pin 11 (GPIO1-11)
- - functions pwm, gpio
+ - functions pwm, led, gpio
group pwm1
- pin 12
- - functions pwm, gpio
+ - functions pwm, led, gpio
group pwm2
- pin 13
- - functions pwm, gpio
+ - functions pwm, led, gpio
group pwm3
- pin 14
- - functions pwm, gpio
+ - functions pwm, led, gpio
group pmic1
- pin 7
diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
index b9d389e70f5..1cf1f06f101 100644
--- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
+++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
@@ -160,10 +160,14 @@ static struct armada_37xx_pin_group armada_37xx_nb_groups[] = {
PIN_GRP_GPIO("jtag", 20, 5, BIT(0), "jtag"),
PIN_GRP_GPIO("sdio0", 8, 3, BIT(1), "sdio"),
PIN_GRP_GPIO("emmc_nb", 27, 9, BIT(2), "emmc"),
- PIN_GRP_GPIO("pwm0", 11, 1, BIT(3), "pwm"),
- PIN_GRP_GPIO("pwm1", 12, 1, BIT(4), "pwm"),
- PIN_GRP_GPIO("pwm2", 13, 1, BIT(5), "pwm"),
- PIN_GRP_GPIO("pwm3", 14, 1, BIT(6), "pwm"),
+ PIN_GRP_GPIO_3("pwm0", 11, 1, BIT(3) | BIT(20), 0, BIT(20), BIT(3),
+ "pwm", "led"),
+ PIN_GRP_GPIO_3("pwm1", 11, 1, BIT(4) | BIT(21), 0, BIT(21), BIT(4),
+ "pwm", "led"),
+ PIN_GRP_GPIO_3("pwm2", 11, 1, BIT(5) | BIT(22), 0, BIT(22), BIT(5),
+ "pwm", "led"),
+ PIN_GRP_GPIO_3("pwm3", 11, 1, BIT(6) | BIT(23), 0, BIT(23), BIT(6),
+ "pwm", "led"),
PIN_GRP_GPIO("pmic1", 7, 1, BIT(7), "pmic"),
PIN_GRP_GPIO("pmic0", 6, 1, BIT(8), "pmic"),
PIN_GRP_GPIO("i2c2", 2, 2, BIT(9), "i2c"),
@@ -177,11 +181,6 @@ static struct armada_37xx_pin_group armada_37xx_nb_groups[] = {
PIN_GRP_EXTRA("uart2", 9, 2, BIT(1) | BIT(13) | BIT(14) | BIT(19),
BIT(1) | BIT(13) | BIT(14), BIT(1) | BIT(19),
18, 2, "gpio", "uart"),
- PIN_GRP_GPIO("led0_od", 11, 1, BIT(20), "led"),
- PIN_GRP_GPIO("led1_od", 12, 1, BIT(21), "led"),
- PIN_GRP_GPIO("led2_od", 13, 1, BIT(22), "led"),
- PIN_GRP_GPIO("led3_od", 14, 1, BIT(23), "led"),
-
};
static struct armada_37xx_pin_group armada_37xx_sb_groups[] = {
diff --git a/drivers/serial/serial_mvebu_a3700.c b/drivers/serial/serial_mvebu_a3700.c
index c7e66fef876..6bca8e4b7e2 100644
--- a/drivers/serial/serial_mvebu_a3700.c
+++ b/drivers/serial/serial_mvebu_a3700.c
@@ -305,11 +305,12 @@ U_BOOT_DRIVER(serial_mvebu) = {
#ifdef CONFIG_DEBUG_MVEBU_A3700_UART
#include <debug_uart.h>
+#include <mach/soc.h>
static inline void _debug_uart_init(void)
{
void __iomem *base = (void __iomem *)CONFIG_DEBUG_UART_BASE;
- u32 baudrate, parent_rate, divider;
+ u32 parent_rate, divider;
/* reset FIFOs */
writel(UART_CTRL_RXFIFO_RESET | UART_CTRL_TXFIFO_RESET,
@@ -322,9 +323,9 @@ static inline void _debug_uart_init(void)
* Calculate divider
* baudrate = clock / 16 / divider
*/
- baudrate = 115200;
- parent_rate = get_ref_clk() * 1000000;
- divider = DIV_ROUND_CLOSEST(parent_rate, baudrate * 16);
+ parent_rate = (readl(MVEBU_REGISTER(0x13808)) & BIT(9)) ?
+ 40000000 : 25000000;
+ divider = DIV_ROUND_CLOSEST(parent_rate, CONFIG_BAUDRATE * 16);
writel(divider, base + UART_BAUD_REG);
/*
diff --git a/drivers/tpm/Makefile b/drivers/tpm/Makefile
index f64d20067f8..c65be526700 100644
--- a/drivers/tpm/Makefile
+++ b/drivers/tpm/Makefile
@@ -6,11 +6,11 @@ obj-$(CONFIG_$(SPL_TPL_)TPM) += tpm-uclass.o
obj-$(CONFIG_TPM_ATMEL_TWI) += tpm_atmel_twi.o
obj-$(CONFIG_TPM_TIS_INFINEON) += tpm_tis_infineon.o
obj-$(CONFIG_TPM_TIS_LPC) += tpm_tis_lpc.o
-obj-$(CONFIG_TPM_TIS_SANDBOX) += tpm_tis_sandbox.o
+obj-$(CONFIG_TPM_TIS_SANDBOX) += tpm_tis_sandbox.o sandbox_common.o
obj-$(CONFIG_TPM_ST33ZP24_I2C) += tpm_tis_st33zp24_i2c.o
obj-$(CONFIG_TPM_ST33ZP24_SPI) += tpm_tis_st33zp24_spi.o
obj-$(CONFIG_$(SPL_TPL_)TPM2_CR50_I2C) += cr50_i2c.o
-obj-$(CONFIG_TPM2_TIS_SANDBOX) += tpm2_tis_sandbox.o
+obj-$(CONFIG_TPM2_TIS_SANDBOX) += tpm2_tis_sandbox.o sandbox_common.o
obj-$(CONFIG_TPM2_TIS_SPI) += tpm2_tis_spi.o
obj-$(CONFIG_TPM2_FTPM_TEE) += tpm2_ftpm_tee.o
diff --git a/drivers/tpm/sandbox_common.c b/drivers/tpm/sandbox_common.c
new file mode 100644
index 00000000000..7e0b2502e35
--- /dev/null
+++ b/drivers/tpm/sandbox_common.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Common features for sandbox TPM1 and TPM2 implementations
+ *
+ * Copyright 2021 Google LLC
+ */
+
+#define LOG_CATEGORY UCLASS_TPM
+
+#include <common.h>
+#include <tpm-v1.h>
+#include <tpm-v2.h>
+#include <asm/unaligned.h>
+#include "sandbox_common.h"
+
+#define TPM_ERR_CODE_OFS (2 + 4) /* after tag and size */
+
+int sb_tpm_index_to_seq(u32 index)
+{
+ index &= ~HR_NV_INDEX;
+ switch (index) {
+ case FIRMWARE_NV_INDEX:
+ return NV_SEQ_FIRMWARE;
+ case KERNEL_NV_INDEX:
+ return NV_SEQ_KERNEL;
+ case BACKUP_NV_INDEX:
+ return NV_SEQ_BACKUP;
+ case FWMP_NV_INDEX:
+ return NV_SEQ_FWMP;
+ case MRC_REC_HASH_NV_INDEX:
+ return NV_SEQ_REC_HASH;
+ case 0:
+ return NV_SEQ_GLOBAL_LOCK;
+ case TPM_NV_INDEX_LOCK:
+ return NV_SEQ_ENABLE_LOCKING;
+ }
+
+ printf("Invalid nv index %#x\n", index);
+ return -1;
+}
+
+void sb_tpm_read_data(const struct nvdata_state nvdata[NV_SEQ_COUNT],
+ enum sandbox_nv_space seq, u8 *buf, int data_ofs,
+ int length)
+{
+ const struct nvdata_state *nvd = &nvdata[seq];
+
+ if (!nvd->present)
+ put_unaligned_be32(TPM_BADINDEX, buf + TPM_ERR_CODE_OFS);
+ else if (length > nvd->length)
+ put_unaligned_be32(TPM_BAD_DATASIZE, buf + TPM_ERR_CODE_OFS);
+ else
+ memcpy(buf + data_ofs, &nvd->data, length);
+}
+
+void sb_tpm_write_data(struct nvdata_state nvdata[NV_SEQ_COUNT],
+ enum sandbox_nv_space seq, const u8 *buf, int data_ofs,
+ int length)
+{
+ struct nvdata_state *nvd = &nvdata[seq];
+
+ if (length > nvd->length)
+ log_err("Invalid length %x (max %x)\n", length, nvd->length);
+ else
+ memcpy(&nvdata[seq].data, buf + data_ofs, length);
+}
+
+void sb_tpm_define_data(struct nvdata_state nvdata[NV_SEQ_COUNT],
+ enum sandbox_nv_space seq, int length)
+{
+ struct nvdata_state *nvd = &nvdata[seq];
+
+ if (length > NV_DATA_SIZE)
+ log_err("Invalid length %x (max %x)\n", length, NV_DATA_SIZE);
+ nvd->length = length;
+ nvd->present = true;
+}
diff --git a/drivers/tpm/sandbox_common.h b/drivers/tpm/sandbox_common.h
new file mode 100644
index 00000000000..e822a200fd3
--- /dev/null
+++ b/drivers/tpm/sandbox_common.h
@@ -0,0 +1,108 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Common features for sandbox TPM1 and TPM2 implementations
+ *
+ * Copyright 2021 Google LLC
+ */
+
+#ifndef __TPM_SANDBOX_COMMON_H
+#define __TPM_SANDBOX_COMMON_H
+
+/*
+ * These numbers derive from adding the sizes of command fields as shown in
+ * the TPM commands manual.
+ */
+#define TPM_HDR_LEN 10
+
+/* These are the different non-volatile spaces that we emulate */
+enum sandbox_nv_space {
+ NV_SEQ_ENABLE_LOCKING,
+ NV_SEQ_GLOBAL_LOCK,
+ NV_SEQ_FIRMWARE,
+ NV_SEQ_KERNEL,
+ NV_SEQ_BACKUP,
+ NV_SEQ_FWMP,
+ NV_SEQ_REC_HASH,
+
+ NV_SEQ_COUNT,
+};
+
+/* TPM NVRAM location indices */
+#define FIRMWARE_NV_INDEX 0x1007
+#define KERNEL_NV_INDEX 0x1008
+#define BACKUP_NV_INDEX 0x1009
+#define FWMP_NV_INDEX 0x100a
+#define MRC_REC_HASH_NV_INDEX 0x100b
+
+/* Size of each non-volatile space */
+#define NV_DATA_SIZE 0x28
+
+/**
+ * struct nvdata_state - state of a single non-volatile-data 'space'
+ *
+ * @present: true if present
+ * @length: length in bytes (max NV_DATA_SIZE)
+ * @data: contents of non-volatile space
+ */
+struct nvdata_state {
+ bool present;
+ int length;
+ u8 data[NV_DATA_SIZE];
+};
+
+/**
+ * sb_tpm_index_to_seq() - convert an index into a space sequence number
+ *
+ * This converts the index as used by the vboot code into an internal sequence
+ * number used by the sandbox emulation.
+ *
+ * @index: Index to use (FIRMWARE_NV_INDEX, etc.)
+ * @return associated space (enum sandbox_nv_space)
+ */
+int sb_tpm_index_to_seq(uint index);
+
+/**
+ * sb_tpm_read_data() - Read non-volatile data
+ *
+ * This handles a TPM read of nvdata. If the nvdata is not present, a
+ * TPM_BADINDEX error is put in the buffer. If @length is too large,
+ * TPM_BAD_DATASIZE is put in the buffer.
+ *
+ * @nvdata: Current nvdata state
+ * @seq: Sequence number to read
+ * @recvbuf: Buffer to update with the TPM response, assumed to contain zeroes
+ * @data_ofs: Offset of the 'data' portion of @recvbuf
+ * @length: Number of bytes to read
+ */
+void sb_tpm_read_data(const struct nvdata_state nvdata[NV_SEQ_COUNT],
+ enum sandbox_nv_space seq, u8 *recvbuf, int data_ofs,
+ int length);
+
+/**
+ * sb_tpm_write_data() - Write non-volatile data
+ *
+ * If @length is too large, an error is logged and nothing is written.
+ *
+ * @nvdata: Current nvdata state
+ * @seq: Sequence number to read
+ * @buf: Buffer containing the data to write
+ * @data_ofs: Offset of the 'data' portion of @buf
+ * @length: Number of bytes to write
+ */
+void sb_tpm_write_data(struct nvdata_state nvdata[NV_SEQ_COUNT],
+ enum sandbox_nv_space seq, const u8 *buf, int data_ofs,
+ int length);
+
+/**
+ * sb_tpm_define_data() - Set up non-volatile data
+ *
+ * If @length is too large, an error is logged and nothing is written.
+ *
+ * @nvdata: Current nvdata state
+ * @seq: Sequence number to set up
+ * @length: Length of space in bytes
+ */
+void sb_tpm_define_data(struct nvdata_state nvdata[NV_SEQ_COUNT],
+ enum sandbox_nv_space seq, int length);
+
+#endif
diff --git a/drivers/tpm/tpm2_tis_sandbox.c b/drivers/tpm/tpm2_tis_sandbox.c
index 24c804a5645..ac6eb143539 100644
--- a/drivers/tpm/tpm2_tis_sandbox.c
+++ b/drivers/tpm/tpm2_tis_sandbox.c
@@ -11,6 +11,8 @@
#include <asm/unaligned.h>
#include <linux/bitops.h>
#include <u-boot/crc.h>
+#include <u-boot/sha256.h>
+#include "sandbox_common.h"
/* Hierarchies */
enum tpm2_hierarchy {
@@ -38,29 +40,178 @@ enum tpm2_cap_tpm_property {
#define SANDBOX_TPM_PCR_NB 1
-static const u8 sandbox_extended_once_pcr[] = {
- 0xf5, 0xa5, 0xfd, 0x42, 0xd1, 0x6a, 0x20, 0x30,
- 0x27, 0x98, 0xef, 0x6e, 0xd3, 0x09, 0x97, 0x9b,
- 0x43, 0x00, 0x3d, 0x23, 0x20, 0xd9, 0xf0, 0xe8,
- 0xea, 0x98, 0x31, 0xa9, 0x27, 0x59, 0xfb, 0x4b,
-};
-
+/*
+ * Information about our TPM emulation. This is preserved in the sandbox
+ * state file if enabled.
+ *
+ * @valid: true if this is valid (only used in s_state)
+ * @init_done: true if open() has been called
+ * @startup_done: true if TPM2_CC_STARTUP has been processed
+ * @tests_done: true if TPM2_CC_SELF_TEST has be processed
+ * @pw: TPM password per hierarchy
+ * @pw_sz: Size of each password in bytes
+ * @properties: TPM properties
+ * @pcr: TPM Platform Configuration Registers. Each of these holds a hash and
+ * can be 'extended' a number of times, meaning another hash is added into
+ * its value (initial value all zeroes)
+ * @pcr_extensions: Number of times each PCR has been extended (starts at 0)
+ * @nvdata: non-volatile data, used to store important things for the platform
+ */
struct sandbox_tpm2 {
+ bool valid;
/* TPM internal states */
bool init_done;
bool startup_done;
bool tests_done;
- /* TPM password per hierarchy */
char pw[TPM2_HIERARCHY_NB][TPM2_DIGEST_LEN + 1];
int pw_sz[TPM2_HIERARCHY_NB];
- /* TPM properties */
u32 properties[TPM2_PROPERTY_NB];
- /* TPM PCRs */
u8 pcr[SANDBOX_TPM_PCR_NB][TPM2_DIGEST_LEN];
- /* TPM PCR extensions */
u32 pcr_extensions[SANDBOX_TPM_PCR_NB];
+ struct nvdata_state nvdata[NV_SEQ_COUNT];
};
+static struct sandbox_tpm2 s_state, *g_state;
+
+/**
+ * sandbox_tpm2_read_state() - read the sandbox EC state from the state file
+ *
+ * If data is available, then blob and node will provide access to it. If
+ * not this function sets up an empty TPM.
+ *
+ * @blob: Pointer to device tree blob, or NULL if no data to read
+ * @node: Node offset to read from
+ */
+static int sandbox_tpm2_read_state(const void *blob, int node)
+{
+ struct sandbox_tpm2 *state = &s_state;
+ char prop_name[20];
+ const char *prop;
+ int len;
+ int i;
+
+ if (!blob)
+ return 0;
+ state->tests_done = fdtdec_get_int(blob, node, "tests-done", 0);
+
+ for (i = 0; i < TPM2_HIERARCHY_NB; i++) {
+ snprintf(prop_name, sizeof(prop_name), "pw%d", i);
+
+ prop = fdt_getprop(blob, node, prop_name, &len);
+ if (len > TPM2_DIGEST_LEN)
+ return log_msg_ret("pw", -E2BIG);
+ if (prop) {
+ memcpy(state->pw[i], prop, len);
+ state->pw_sz[i] = len;
+ }
+ }
+
+ for (i = 0; i < TPM2_PROPERTY_NB; i++) {
+ snprintf(prop_name, sizeof(prop_name), "properties%d", i);
+ state->properties[i] = fdtdec_get_uint(blob, node, prop_name,
+ 0);
+ }
+
+ for (i = 0; i < SANDBOX_TPM_PCR_NB; i++) {
+ int subnode;
+
+ snprintf(prop_name, sizeof(prop_name), "pcr%d", i);
+ subnode = fdt_subnode_offset(blob, node, prop_name);
+ if (subnode < 0)
+ continue;
+ prop = fdt_getprop(blob, subnode, "value", &len);
+ if (len != TPM2_DIGEST_LEN)
+ return log_msg_ret("pcr", -E2BIG);
+ memcpy(state->pcr[i], prop, TPM2_DIGEST_LEN);
+ state->pcr_extensions[i] = fdtdec_get_uint(blob, subnode,
+ "extensions", 0);
+ }
+
+ for (i = 0; i < NV_SEQ_COUNT; i++) {
+ struct nvdata_state *nvd = &state->nvdata[i];
+
+ sprintf(prop_name, "nvdata%d", i);
+ prop = fdt_getprop(blob, node, prop_name, &len);
+ if (len > NV_DATA_SIZE)
+ return log_msg_ret("nvd", -E2BIG);
+ if (prop) {
+ memcpy(nvd->data, prop, len);
+ nvd->length = len;
+ nvd->present = true;
+ }
+ }
+ s_state.valid = true;
+
+ return 0;
+}
+
+/**
+ * sandbox_tpm2_write_state() - Write out our state to the state file
+ *
+ * The caller will ensure that there is a node ready for the state. The node
+ * may already contain the old state, in which case it is overridden.
+ *
+ * @blob: Device tree blob holding state
+ * @node: Node to write our state into
+ */
+static int sandbox_tpm2_write_state(void *blob, int node)
+{
+ const struct sandbox_tpm2 *state = g_state;
+ char prop_name[20];
+ int i;
+
+ if (!state)
+ return 0;
+
+ /*
+ * We are guaranteed enough space to write basic properties. This is
+ * SANDBOX_STATE_MIN_SPACE.
+ *
+ * We could use fdt_add_subnode() to put each set of data in its
+ * own node - perhaps useful if we add access information to each.
+ */
+ fdt_setprop_u32(blob, node, "tests-done", state->tests_done);
+
+ for (i = 0; i < TPM2_HIERARCHY_NB; i++) {
+ if (state->pw_sz[i]) {
+ snprintf(prop_name, sizeof(prop_name), "pw%d", i);
+ fdt_setprop(blob, node, prop_name, state->pw[i],
+ state->pw_sz[i]);
+ }
+ }
+
+ for (i = 0; i < TPM2_PROPERTY_NB; i++) {
+ snprintf(prop_name, sizeof(prop_name), "properties%d", i);
+ fdt_setprop_u32(blob, node, prop_name, state->properties[i]);
+ }
+
+ for (i = 0; i < SANDBOX_TPM_PCR_NB; i++) {
+ int subnode;
+
+ snprintf(prop_name, sizeof(prop_name), "pcr%d", i);
+ subnode = fdt_add_subnode(blob, node, prop_name);
+ fdt_setprop(blob, subnode, "value", state->pcr[i],
+ TPM2_DIGEST_LEN);
+ fdt_setprop_u32(blob, subnode, "extensions",
+ state->pcr_extensions[i]);
+ }
+
+ for (i = 0; i < NV_SEQ_COUNT; i++) {
+ const struct nvdata_state *nvd = &state->nvdata[i];
+
+ if (nvd->present) {
+ snprintf(prop_name, sizeof(prop_name), "nvdata%d", i);
+ fdt_setprop(blob, node, prop_name, nvd->data,
+ nvd->length);
+ }
+ }
+
+ return 0;
+}
+
+SANDBOX_STATE_IO(sandbox_tpm2, "sandbox,tpm2", sandbox_tpm2_read_state,
+ sandbox_tpm2_write_state);
+
/*
* Check the tag validity depending on the command (authentication required or
* not). If authentication is required, check it is valid. Update the auth
@@ -93,6 +244,10 @@ static int sandbox_tpm2_check_session(struct udevice *dev, u32 command, u16 tag,
case TPM2_CC_DAM_RESET:
case TPM2_CC_DAM_PARAMETERS:
case TPM2_CC_PCR_EXTEND:
+ case TPM2_CC_NV_READ:
+ case TPM2_CC_NV_WRITE:
+ case TPM2_CC_NV_WRITELOCK:
+ case TPM2_CC_NV_DEFINE_SPACE:
if (tag != TPM2_ST_SESSIONS) {
printf("Session required for command 0x%x\n", command);
return TPM2_RC_AUTH_CONTEXT;
@@ -121,6 +276,10 @@ static int sandbox_tpm2_check_session(struct udevice *dev, u32 command, u16 tag,
break;
case TPM2_RH_PLATFORM:
*hierarchy = TPM2_HIERARCHY_PLATFORM;
+ if (command == TPM2_CC_NV_READ ||
+ command == TPM2_CC_NV_WRITE ||
+ command == TPM2_CC_NV_WRITELOCK)
+ *auth += sizeof(u32);
break;
default:
printf("Wrong handle 0x%x\n", handle);
@@ -242,15 +401,17 @@ static int sandbox_tpm2_extend(struct udevice *dev, int pcr_index,
const u8 *extension)
{
struct sandbox_tpm2 *tpm = dev_get_priv(dev);
- int i;
+ sha256_context ctx;
- /* Only simulate the first extensions from all '0' with only '0' */
- for (i = 0; i < TPM2_DIGEST_LEN; i++)
- if (tpm->pcr[pcr_index][i] || extension[i])
- return TPM2_RC_FAILURE;
+ /* Zero the PCR if this is the first use */
+ if (!tpm->pcr_extensions[pcr_index])
+ memset(tpm->pcr[pcr_index], '\0', TPM2_DIGEST_LEN);
+
+ sha256_starts(&ctx);
+ sha256_update(&ctx, tpm->pcr[pcr_index], TPM2_DIGEST_LEN);
+ sha256_update(&ctx, extension, TPM2_DIGEST_LEN);
+ sha256_finish(&ctx, tpm->pcr[pcr_index]);
- memcpy(tpm->pcr[pcr_index], sandbox_extended_once_pcr,
- TPM2_DIGEST_LEN);
tpm->pcr_extensions[pcr_index]++;
return 0;
@@ -477,15 +638,8 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const u8 *sendbuf,
for (i = 0; i < pcr_array_sz; i++)
pcr_map += (u64)sent[i] << (i * 8);
- if (pcr_map >> SANDBOX_TPM_PCR_NB) {
- printf("Sandbox TPM handles up to %d PCR(s)\n",
- SANDBOX_TPM_PCR_NB);
- rc = TPM2_RC_VALUE;
- return sandbox_tpm2_fill_buf(recv, recv_len, tag, rc);
- }
-
if (!pcr_map) {
- printf("Empty PCR map.\n");
+ printf("Empty PCR map\n");
rc = TPM2_RC_VALUE;
return sandbox_tpm2_fill_buf(recv, recv_len, tag, rc);
}
@@ -494,6 +648,13 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const u8 *sendbuf,
if (pcr_map & BIT(i))
pcr_index = i;
+ if (pcr_index >= SANDBOX_TPM_PCR_NB) {
+ printf("Invalid index %d, sandbox TPM handles up to %d PCR(s)\n",
+ pcr_index, SANDBOX_TPM_PCR_NB);
+ rc = TPM2_RC_VALUE;
+ return sandbox_tpm2_fill_buf(recv, recv_len, tag, rc);
+ }
+
/* Write tag */
put_unaligned_be16(tag, recv);
recv += sizeof(tag);
@@ -527,9 +688,9 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const u8 *sendbuf,
pcr_index = get_unaligned_be32(sendbuf + sizeof(tag) +
sizeof(length) +
sizeof(command));
- if (pcr_index > SANDBOX_TPM_PCR_NB) {
- printf("Sandbox TPM handles up to %d PCR(s)\n",
- SANDBOX_TPM_PCR_NB);
+ if (pcr_index >= SANDBOX_TPM_PCR_NB) {
+ printf("Invalid index %d, sandbox TPM handles up to %d PCR(s)\n",
+ pcr_index, SANDBOX_TPM_PCR_NB);
rc = TPM2_RC_VALUE;
}
@@ -557,6 +718,64 @@ static int sandbox_tpm2_xfer(struct udevice *dev, const u8 *sendbuf,
sandbox_tpm2_fill_buf(recv, recv_len, tag, rc);
break;
+ case TPM2_CC_NV_READ: {
+ int index, seq;
+
+ index = get_unaligned_be32(sendbuf + TPM2_HDR_LEN + 4);
+ length = get_unaligned_be16(sent);
+ /* ignore offset */
+ seq = sb_tpm_index_to_seq(index);
+ if (seq < 0)
+ return log_msg_ret("index", -EINVAL);
+ printf("tpm: nvread index=%#02x, len=%#02x, seq=%#02x\n", index,
+ length, seq);
+ *recv_len = TPM2_HDR_LEN + 6 + length;
+ memset(recvbuf, '\0', *recv_len);
+ put_unaligned_be32(length, recvbuf + 2);
+ sb_tpm_read_data(tpm->nvdata, seq, recvbuf,
+ TPM2_HDR_LEN + 4 + 2, length);
+ break;
+ }
+ case TPM2_CC_NV_WRITE: {
+ int index, seq;
+
+ index = get_unaligned_be32(sendbuf + TPM2_HDR_LEN + 4);
+ length = get_unaligned_be16(sent);
+ sent += sizeof(u16);
+
+ /* ignore offset */
+ seq = sb_tpm_index_to_seq(index);
+ if (seq < 0)
+ return log_msg_ret("index", -EINVAL);
+ printf("tpm: nvwrite index=%#02x, len=%#02x, seq=%#02x\n", index,
+ length, seq);
+ memcpy(&tpm->nvdata[seq].data, sent, length);
+ tpm->nvdata[seq].present = true;
+ *recv_len = TPM2_HDR_LEN + 2;
+ memset(recvbuf, '\0', *recv_len);
+ break;
+ }
+ case TPM2_CC_NV_DEFINE_SPACE: {
+ int policy_size, index, seq;
+
+ policy_size = get_unaligned_be16(sent + 12);
+ index = get_unaligned_be32(sent + 2);
+ sent += 14 + policy_size;
+ length = get_unaligned_be16(sent);
+ seq = sb_tpm_index_to_seq(index);
+ if (seq < 0)
+ return -EINVAL;
+ printf("tpm: define_space index=%x, len=%x, seq=%x, policy_size=%x\n",
+ index, length, seq, policy_size);
+ sb_tpm_define_data(tpm->nvdata, seq, length);
+ *recv_len = 12;
+ memset(recvbuf, '\0', *recv_len);
+ break;
+ }
+ case TPM2_CC_NV_WRITELOCK:
+ *recv_len = 12;
+ memset(recvbuf, '\0', *recv_len);
+ break;
default:
printf("TPM2 command %02x unknown in Sandbox\n", command);
rc = TPM2_RC_COMMAND_CODE;
@@ -594,11 +813,13 @@ static int sandbox_tpm2_probe(struct udevice *dev)
/* Use the TPM v2 stack */
priv->version = TPM_V2;
- memset(tpm, 0, sizeof(*tpm));
-
priv->pcr_count = 32;
priv->pcr_select_min = 2;
+ if (s_state.valid)
+ memcpy(tpm, &s_state, sizeof(*tpm));
+ g_state = tpm;
+
return 0;
}
diff --git a/drivers/tpm/tpm_tis_sandbox.c b/drivers/tpm/tpm_tis_sandbox.c
index 67139cea3be..efbeb00ab63 100644
--- a/drivers/tpm/tpm_tis_sandbox.c
+++ b/drivers/tpm/tpm_tis_sandbox.c
@@ -9,61 +9,10 @@
#include <asm/state.h>
#include <asm/unaligned.h>
#include <u-boot/crc.h>
-
-/* TPM NVRAM location indices. */
-#define FIRMWARE_NV_INDEX 0x1007
-#define KERNEL_NV_INDEX 0x1008
-#define BACKUP_NV_INDEX 0x1009
-#define FWMP_NV_INDEX 0x100a
-#define REC_HASH_NV_INDEX 0x100b
-#define REC_HASH_NV_SIZE VB2_SHA256_DIGEST_SIZE
+#include "sandbox_common.h"
#define NV_DATA_PUBLIC_PERMISSIONS_OFFSET 60
-/* Kernel TPM space - KERNEL_NV_INDEX, locked with physical presence */
-#define ROLLBACK_SPACE_KERNEL_VERSION 2
-#define ROLLBACK_SPACE_KERNEL_UID 0x4752574C /* 'GRWL' */
-
-struct rollback_space_kernel {
- /* Struct version, for backwards compatibility */
- uint8_t struct_version;
- /* Unique ID to detect space redefinition */
- uint32_t uid;
- /* Kernel versions */
- uint32_t kernel_versions;
- /* Reserved for future expansion */
- uint8_t reserved[3];
- /* Checksum (v2 and later only) */
- uint8_t crc8;
-} __packed rollback_space_kernel;
-
-/*
- * These numbers derive from adding the sizes of command fields as shown in
- * the TPM commands manual.
- */
-#define TPM_REQUEST_HEADER_LENGTH 10
-#define TPM_RESPONSE_HEADER_LENGTH 10
-
-/* These are the different non-volatile spaces that we emulate */
-enum {
- NV_GLOBAL_LOCK,
- NV_SEQ_FIRMWARE,
- NV_SEQ_KERNEL,
- NV_SEQ_BACKUP,
- NV_SEQ_FWMP,
- NV_SEQ_REC_HASH,
-
- NV_SEQ_COUNT,
-};
-
-/* Size of each non-volatile space */
-#define NV_DATA_SIZE 0x20
-
-struct nvdata_state {
- bool present;
- u8 data[NV_DATA_SIZE];
-};
-
/*
* Information about our TPM emulation. This is preserved in the sandbox
* state file if enabled.
@@ -71,7 +20,7 @@ struct nvdata_state {
static struct tpm_state {
bool valid;
struct nvdata_state nvdata[NV_SEQ_COUNT];
-} g_state;
+} s_state, *g_state;
/**
* sandbox_tpm_read_state() - read the sandbox EC state from the state file
@@ -84,6 +33,7 @@ static struct tpm_state {
*/
static int sandbox_tpm_read_state(const void *blob, int node)
{
+ struct tpm_state *state = &s_state;
const char *prop;
int len;
int i;
@@ -92,22 +42,27 @@ static int sandbox_tpm_read_state(const void *blob, int node)
return 0;
for (i = 0; i < NV_SEQ_COUNT; i++) {
+ struct nvdata_state *nvd = &state->nvdata[i];
char prop_name[20];
sprintf(prop_name, "nvdata%d", i);
prop = fdt_getprop(blob, node, prop_name, &len);
- if (prop && len == NV_DATA_SIZE) {
- memcpy(g_state.nvdata[i].data, prop, NV_DATA_SIZE);
- g_state.nvdata[i].present = true;
+ if (len >= NV_DATA_SIZE)
+ return log_msg_ret("nvd", -E2BIG);
+ if (prop) {
+ memcpy(nvd->data, prop, len);
+ nvd->length = len;
+ nvd->present = true;
}
}
- g_state.valid = true;
+
+ s_state.valid = true;
return 0;
}
/**
- * cros_ec_write_state() - Write out our state to the state file
+ * sandbox_tpm_write_state() - Write out our state to the state file
*
* The caller will ensure that there is a node ready for the state. The node
* may already contain the old state, in which case it is overridden.
@@ -117,20 +72,25 @@ static int sandbox_tpm_read_state(const void *blob, int node)
*/
static int sandbox_tpm_write_state(void *blob, int node)
{
+ const struct tpm_state *state = g_state;
int i;
+ if (!state)
+ return 0;
+
/*
* We are guaranteed enough space to write basic properties.
* We could use fdt_add_subnode() to put each set of data in its
* own node - perhaps useful if we add access informaiton to each.
*/
for (i = 0; i < NV_SEQ_COUNT; i++) {
+ const struct nvdata_state *nvd = &state->nvdata[i];
char prop_name[20];
- if (g_state.nvdata[i].present) {
- sprintf(prop_name, "nvdata%d", i);
- fdt_setprop(blob, node, prop_name,
- g_state.nvdata[i].data, NV_DATA_SIZE);
+ if (nvd->present) {
+ snprintf(prop_name, sizeof(prop_name), "nvdata%d", i);
+ fdt_setprop(blob, node, prop_name, nvd->data,
+ nvd->length);
}
}
@@ -140,27 +100,6 @@ static int sandbox_tpm_write_state(void *blob, int node)
SANDBOX_STATE_IO(sandbox_tpm, "google,sandbox-tpm", sandbox_tpm_read_state,
sandbox_tpm_write_state);
-static int index_to_seq(uint32_t index)
-{
- switch (index) {
- case FIRMWARE_NV_INDEX:
- return NV_SEQ_FIRMWARE;
- case KERNEL_NV_INDEX:
- return NV_SEQ_KERNEL;
- case BACKUP_NV_INDEX:
- return NV_SEQ_BACKUP;
- case FWMP_NV_INDEX:
- return NV_SEQ_FWMP;
- case REC_HASH_NV_INDEX:
- return NV_SEQ_REC_HASH;
- case 0:
- return NV_GLOBAL_LOCK;
- }
-
- printf("Invalid nv index %#x\n", index);
- return -1;
-}
-
static void handle_cap_flag_space(u8 **datap, uint index)
{
struct tpm_nv_data_public pub;
@@ -201,16 +140,13 @@ static int sandbox_tpm_xfer(struct udevice *dev, const uint8_t *sendbuf,
printf("Get flags index %#02x\n", index);
*recv_len = 22;
memset(recvbuf, '\0', *recv_len);
- data = recvbuf + TPM_RESPONSE_HEADER_LENGTH +
- sizeof(uint32_t);
+ data = recvbuf + TPM_HDR_LEN + sizeof(uint32_t);
switch (index) {
case FIRMWARE_NV_INDEX:
break;
case KERNEL_NV_INDEX:
handle_cap_flag_space(&data, index);
- *recv_len = data - recvbuf -
- TPM_RESPONSE_HEADER_LENGTH -
- sizeof(uint32_t);
+ *recv_len = data - recvbuf;
break;
case TPM_CAP_FLAG_PERMANENT: {
struct tpm_permanent_flags *pflags;
@@ -227,15 +163,12 @@ static int sandbox_tpm_xfer(struct udevice *dev, const uint8_t *sendbuf,
printf(" ** Unknown flags index %x\n", index);
return -ENOSYS;
}
- put_unaligned_be32(*recv_len,
- recvbuf +
- TPM_RESPONSE_HEADER_LENGTH);
+ put_unaligned_be32(*recv_len, recvbuf + TPM_HDR_LEN);
break;
case TPM_CAP_NV_INDEX:
index = get_unaligned_be32(sendbuf + 18);
printf("Get cap nv index %#02x\n", index);
- put_unaligned_be32(22, recvbuf +
- TPM_RESPONSE_HEADER_LENGTH);
+ put_unaligned_be32(22, recvbuf + TPM_HDR_LEN);
break;
default:
printf(" ** Unknown 0x65 command type %#02x\n",
@@ -246,54 +179,42 @@ static int sandbox_tpm_xfer(struct udevice *dev, const uint8_t *sendbuf,
case TPM_CMD_NV_WRITE_VALUE:
index = get_unaligned_be32(sendbuf + 10);
length = get_unaligned_be32(sendbuf + 18);
- seq = index_to_seq(index);
+ seq = sb_tpm_index_to_seq(index);
if (seq < 0)
return -EINVAL;
printf("tpm: nvwrite index=%#02x, len=%#02x\n", index, length);
- memcpy(&tpm->nvdata[seq].data, sendbuf + 22, length);
- tpm->nvdata[seq].present = true;
- *recv_len = 12;
- memset(recvbuf, '\0', *recv_len);
+ sb_tpm_write_data(tpm->nvdata, seq, sendbuf, 22, length);
break;
case TPM_CMD_NV_READ_VALUE: /* nvread */
index = get_unaligned_be32(sendbuf + 10);
length = get_unaligned_be32(sendbuf + 18);
- seq = index_to_seq(index);
+ seq = sb_tpm_index_to_seq(index);
if (seq < 0)
return -EINVAL;
printf("tpm: nvread index=%#02x, len=%#02x, seq=%#02x\n", index,
length, seq);
- *recv_len = TPM_RESPONSE_HEADER_LENGTH + sizeof(uint32_t) +
- length;
+ *recv_len = TPM_HDR_LEN + sizeof(uint32_t) + length;
memset(recvbuf, '\0', *recv_len);
- put_unaligned_be32(length, recvbuf +
- TPM_RESPONSE_HEADER_LENGTH);
- if (seq == NV_SEQ_KERNEL) {
- struct rollback_space_kernel rsk;
-
- data = recvbuf + TPM_RESPONSE_HEADER_LENGTH +
- sizeof(uint32_t);
- memset(&rsk, 0, sizeof(struct rollback_space_kernel));
- rsk.struct_version = 2;
- rsk.uid = ROLLBACK_SPACE_KERNEL_UID;
- rsk.crc8 = crc8(0, (unsigned char *)&rsk,
- offsetof(struct rollback_space_kernel,
- crc8));
- memcpy(data, &rsk, sizeof(rsk));
- } else if (!tpm->nvdata[seq].present) {
- put_unaligned_be32(TPM_BADINDEX, recvbuf +
- sizeof(uint16_t) + sizeof(uint32_t));
- } else {
- memcpy(recvbuf + TPM_RESPONSE_HEADER_LENGTH +
- sizeof(uint32_t), &tpm->nvdata[seq].data,
- length);
- }
+ put_unaligned_be32(length, recvbuf + TPM_HDR_LEN);
+ sb_tpm_read_data(tpm->nvdata, seq, recvbuf, TPM_HDR_LEN + 4,
+ length);
break;
case TPM_CMD_EXTEND:
*recv_len = 30;
memset(recvbuf, '\0', *recv_len);
break;
case TPM_CMD_NV_DEFINE_SPACE:
+ index = get_unaligned_be32(sendbuf + 12);
+ length = get_unaligned_be32(sendbuf + 77);
+ seq = sb_tpm_index_to_seq(index);
+ if (seq < 0)
+ return -EINVAL;
+ printf("tpm: define_space index=%#02x, len=%#02x, seq=%#02x\n",
+ index, length, seq);
+ sb_tpm_define_data(tpm->nvdata, seq, length);
+ *recv_len = 12;
+ memset(recvbuf, '\0', *recv_len);
+ break;
case 0x15: /* pcr read */
case 0x5d: /* force clear */
case 0x6f: /* physical enable */
@@ -328,7 +249,9 @@ static int sandbox_tpm_probe(struct udevice *dev)
{
struct tpm_state *tpm = dev_get_priv(dev);
- memcpy(tpm, &g_state, sizeof(*tpm));
+ if (s_state.valid)
+ memcpy(tpm, &s_state, sizeof(*tpm));
+ g_state = tpm;
return 0;
}
diff --git a/env/Kconfig b/env/Kconfig
index 691f4d480cc..67ff172e3a9 100644
--- a/env/Kconfig
+++ b/env/Kconfig
@@ -446,8 +446,7 @@ config ENV_FAT_DEVICE_AND_PART
depends on ENV_IS_IN_FAT
default "0:1" if TI_COMMON_CMD_OPTIONS
default "0:auto" if ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL
- default "0:auto" if ARCH_SUNXI && MMC_SUNXI_SLOT_EXTRA = -1
- default "1:auto" if ARCH_SUNXI && MMC_SUNXI_SLOT_EXTRA != -1
+ default ":auto" if ARCH_SUNXI
default "0" if ARCH_AT91
help
Define this to a string to specify the partition of the device. It can
diff --git a/include/autoboot.h b/include/autoboot.h
index ac8157e5704..d6915dd0cc6 100644
--- a/include/autoboot.h
+++ b/include/autoboot.h
@@ -11,6 +11,42 @@
#ifndef __AUTOBOOT_H
#define __AUTOBOOT_H
+#include <stdbool.h>
+
+#ifdef CONFIG_SANDBOX
+
+/**
+ * autoboot_keyed() - check whether keyed autoboot should be used
+ *
+ * This is only implemented for sandbox since other platforms don't have a way
+ * of controlling the feature at runtime.
+ *
+ * @return true if enabled, false if not
+ */
+bool autoboot_keyed(void);
+
+/**
+ * autoboot_set_keyed() - set whether keyed autoboot should be used
+ *
+ * @autoboot_keyed: true to enable the feature, false to disable
+ * @return old value of the flag
+ */
+bool autoboot_set_keyed(bool autoboot_keyed);
+#else
+static inline bool autoboot_keyed(void)
+{
+ /* There is no runtime flag, so just use the CONFIG */
+ return IS_ENABLED(CONFIG_AUTOBOOT_KEYED);
+}
+
+static inline bool autoboot_set_keyed(bool autoboot_keyed)
+{
+ /* There is no runtime flag to set */
+ return false;
+}
+
+#endif
+
#ifdef CONFIG_AUTOBOOT
/**
* bootdelay_process() - process the bootd delay
diff --git a/include/configs/clearfog.h b/include/configs/clearfog.h
index c9852a72b9e..fbdd2f0a244 100644
--- a/include/configs/clearfog.h
+++ b/include/configs/clearfog.h
@@ -69,13 +69,8 @@
#define CONFIG_SPL_STACK (0x40000000 + ((192 - 16) << 10))
#define CONFIG_SPL_BOOTROM_SAVE (CONFIG_SPL_STACK + 4)
-#if defined(CONFIG_MVEBU_SPL_BOOT_DEVICE_SPI)
-/* SPL related SPI defines */
-#define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_SPI_U_BOOT_OFFS
-#elif defined(CONFIG_MVEBU_SPL_BOOT_DEVICE_MMC) || defined(CONFIG_MVEBU_SPL_BOOT_DEVICE_SATA)
+#if defined(CONFIG_MVEBU_SPL_BOOT_DEVICE_MMC) || defined(CONFIG_MVEBU_SPL_BOOT_DEVICE_SATA)
/* SPL related MMC defines */
-#define CONFIG_SYS_MMC_U_BOOT_OFFS (160 << 10)
-#define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_MMC_U_BOOT_OFFS
#ifdef CONFIG_SPL_BUILD
#define CONFIG_FIXED_SDHCI_ALIGNED_BUFFER 0x00180000 /* in SDRAM */
#endif
diff --git a/include/configs/controlcenterdc.h b/include/configs/controlcenterdc.h
index c4e9c796647..171bd189d3b 100644
--- a/include/configs/controlcenterdc.h
+++ b/include/configs/controlcenterdc.h
@@ -85,18 +85,9 @@
#define CONFIG_SPL_LIBGENERIC_SUPPORT
#define CONFIG_SPL_I2C
-#if CONFIG_SPL_BOOT_DEVICE == SPL_BOOT_SPI_NOR_FLASH
-/* SPL related SPI defines */
-#define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_SPI_U_BOOT_OFFS
-#endif
-
#if CONFIG_SPL_BOOT_DEVICE == SPL_BOOT_SDIO_MMC_CARD
/* SPL related MMC defines */
#define CONFIG_SPL_MMC_SUPPORT
-#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION 1
-#define CONFIG_SYS_MMC_U_BOOT_OFFS (168 << 10)
-#define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_MMC_U_BOOT_OFFS
-#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR (CONFIG_SYS_U_BOOT_OFFS / 512)
#ifdef CONFIG_SPL_BUILD
#define CONFIG_FIXED_SDHCI_ALIGNED_BUFFER 0x00180000 /* in SDRAM */
#endif
diff --git a/include/configs/db-88f6720.h b/include/configs/db-88f6720.h
index 83c173243c2..410a40af3e6 100644
--- a/include/configs/db-88f6720.h
+++ b/include/configs/db-88f6720.h
@@ -65,7 +65,4 @@
#define CONFIG_SPL_STACK (0x40000000 + ((192 - 16) << 10))
#define CONFIG_SPL_BOOTROM_SAVE (CONFIG_SPL_STACK + 4)
-/* SPL related SPI defines */
-#define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_SPI_U_BOOT_OFFS
-
#endif /* _CONFIG_DB_88F6720_H */
diff --git a/include/configs/db-88f6820-amc.h b/include/configs/db-88f6820-amc.h
index fe9a7ab5635..757fbc0b9bc 100644
--- a/include/configs/db-88f6820-amc.h
+++ b/include/configs/db-88f6820-amc.h
@@ -59,11 +59,6 @@
#define CONFIG_SPL_STACK (0x40000000 + ((192 - 16) << 10))
#define CONFIG_SPL_BOOTROM_SAVE (CONFIG_SPL_STACK + 4)
-#if CONFIG_SPL_BOOT_DEVICE == SPL_BOOT_SPI_NOR_FLASH
-/* SPL related SPI defines */
-#define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_SPI_U_BOOT_OFFS
-#endif
-
/*
* mv-common.h should be defined after CMD configs since it used them
* to enable certain macros
diff --git a/include/configs/db-88f6820-gp.h b/include/configs/db-88f6820-gp.h
index 5a6b42854c4..9a34fa67691 100644
--- a/include/configs/db-88f6820-gp.h
+++ b/include/configs/db-88f6820-gp.h
@@ -71,15 +71,8 @@
#define CONFIG_SPL_STACK (0x40000000 + ((192 - 16) << 10))
#define CONFIG_SPL_BOOTROM_SAVE (CONFIG_SPL_STACK + 4)
-#if CONFIG_SPL_BOOT_DEVICE == SPL_BOOT_SPI_NOR_FLASH
-/* SPL related SPI defines */
-#define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_SPI_U_BOOT_OFFS
-#endif
-
#if CONFIG_SPL_BOOT_DEVICE == SPL_BOOT_SDIO_MMC_CARD
/* SPL related MMC defines */
-#define CONFIG_SYS_MMC_U_BOOT_OFFS (160 << 10)
-#define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_MMC_U_BOOT_OFFS
#ifdef CONFIG_SPL_BUILD
#define CONFIG_FIXED_SDHCI_ALIGNED_BUFFER 0x00180000 /* in SDRAM */
#endif
diff --git a/include/configs/db-mv784mp-gp.h b/include/configs/db-mv784mp-gp.h
index 319a291a92a..b3c4079ae13 100644
--- a/include/configs/db-mv784mp-gp.h
+++ b/include/configs/db-mv784mp-gp.h
@@ -78,9 +78,6 @@
#define CONFIG_SPL_STACK (0x40000000 + ((192 - 16) << 10))
#define CONFIG_SPL_BOOTROM_SAVE (CONFIG_SPL_STACK + 4)
-/* SPL related SPI defines */
-#define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_SPI_U_BOOT_OFFS
-
/* Enable DDR support in SPL (DDR3 training from Marvell bin_hdr) */
#define CONFIG_SPD_EEPROM 0x4e
#define CONFIG_BOARD_ECC_SUPPORT /* this board supports ECC */
diff --git a/include/configs/dreamplug.h b/include/configs/dreamplug.h
index 9106203ebc4..65962ee7330 100644
--- a/include/configs/dreamplug.h
+++ b/include/configs/dreamplug.h
@@ -31,8 +31,8 @@
/*
* Default environment variables
*/
-#define CONFIG_BOOTCOMMAND "setenv ethact egiga0; " \
- "${x_bootcmd_ethernet}; setenv ethact egiga1; " \
+#define CONFIG_BOOTCOMMAND "setenv ethact ethernet-controller@72000; " \
+ "${x_bootcmd_ethernet}; setenv ethact ethernet-controller@76000; " \
"${x_bootcmd_ethernet}; ${x_bootcmd_usb}; ${x_bootcmd_kernel}; "\
"setenv bootargs ${x_bootargs} ${x_bootargs_root}; " \
"bootm 0x6400000;"
@@ -52,4 +52,12 @@
#define CONFIG_PHY_BASE_ADR 0
#endif /* CONFIG_CMD_NET */
+/*
+ * SATA Driver configuration
+ */
+#ifdef CONFIG_SATA
+#define CONFIG_SYS_SATA_MAX_DEVICE 1
+#define CONFIG_LBA48
+#endif /* CONFIG_SATA */
+
#endif /* _CONFIG_DREAMPLUG_H */
diff --git a/include/configs/ds414.h b/include/configs/ds414.h
index 80fd148f712..4475de24a9d 100644
--- a/include/configs/ds414.h
+++ b/include/configs/ds414.h
@@ -68,11 +68,6 @@
#define CONFIG_SPL_STACK (0x40000000 + ((192 - 16) << 10))
#define CONFIG_SPL_BOOTROM_SAVE (CONFIG_SPL_STACK + 4)
-#if defined(CONFIG_MVEBU_SPL_BOOT_DEVICE_SPI)
-/* SPL related SPI defines */
-#define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_SPI_U_BOOT_OFFS
-#endif
-
/* DS414 bus width is 32bits */
#define CONFIG_DDR_32BIT
diff --git a/include/configs/helios4.h b/include/configs/helios4.h
index 2cda05c85a0..1368080f036 100644
--- a/include/configs/helios4.h
+++ b/include/configs/helios4.h
@@ -69,13 +69,8 @@
#define CONFIG_SPL_STACK (0x40000000 + ((192 - 16) << 10))
#define CONFIG_SPL_BOOTROM_SAVE (CONFIG_SPL_STACK + 4)
-#if defined(CONFIG_MVEBU_SPL_BOOT_DEVICE_SPI)
-/* SPL related SPI defines */
-#define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_SPI_U_BOOT_OFFS
-#elif defined(CONFIG_MVEBU_SPL_BOOT_DEVICE_MMC) || defined(CONFIG_MVEBU_SPL_BOOT_DEVICE_SATA)
+#if defined(CONFIG_MVEBU_SPL_BOOT_DEVICE_MMC) || defined(CONFIG_MVEBU_SPL_BOOT_DEVICE_SATA)
/* SPL related MMC defines */
-#define CONFIG_SYS_MMC_U_BOOT_OFFS (160 << 10)
-#define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_MMC_U_BOOT_OFFS
#ifdef CONFIG_SPL_BUILD
#define CONFIG_FIXED_SDHCI_ALIGNED_BUFFER 0x00180000 /* in SDRAM */
#endif
diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h
index 9b4675e4c37..27c9808a494 100644
--- a/include/configs/sun8i.h
+++ b/include/configs/sun8i.h
@@ -12,6 +12,16 @@
* A23 specific configuration
*/
+#ifdef SUNXI_SRAM_A2_SIZE
+/*
+ * If the SoC has enough SRAM A2, use that for the secure monitor.
+ * Skip the first 16 KiB of SRAM A2, which is not usable, as only certain bytes
+ * are writable. Reserve the last 17 KiB for the resume shim and SCP firmware.
+ */
+#define CONFIG_ARMV7_SECURE_BASE (SUNXI_SRAM_A2_BASE + 16 * 1024)
+#define CONFIG_ARMV7_SECURE_MAX_SIZE (SUNXI_SRAM_A2_SIZE - 33 * 1024)
+#endif
+
/*
* Include common sunxi configuration where most the settings are
*/
diff --git a/include/configs/theadorable.h b/include/configs/theadorable.h
index 70dd15115bf..c6a2cfe9310 100644
--- a/include/configs/theadorable.h
+++ b/include/configs/theadorable.h
@@ -93,9 +93,6 @@
#define CONFIG_SPL_STACK (0x40000000 + ((192 - 16) << 10))
#define CONFIG_SPL_BOOTROM_SAVE (CONFIG_SPL_STACK + 4)
-/* SPL related SPI defines */
-#define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_SPI_U_BOOT_OFFS
-
/* Enable DDR support in SPL (DDR3 training from Marvell bin_hdr) */
#define CONFIG_DDR_FIXED_SIZE (2 << 20) /* 2GiB */
diff --git a/include/configs/turris_omnia.h b/include/configs/turris_omnia.h
index bc5a5f298e0..2553da12097 100644
--- a/include/configs/turris_omnia.h
+++ b/include/configs/turris_omnia.h
@@ -45,15 +45,8 @@
#define CONFIG_SPL_BOOTROM_SAVE (CONFIG_SPL_STACK + 4)
#define CONFIG_SPL_DRIVERS_MISC
-#ifdef CONFIG_MVEBU_SPL_BOOT_DEVICE_SPI
-/* SPL related SPI defines */
-# define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_SPI_U_BOOT_OFFS
-#endif
-
#ifdef CONFIG_MVEBU_SPL_BOOT_DEVICE_MMC
/* SPL related MMC defines */
-# define CONFIG_SYS_MMC_U_BOOT_OFFS (160 << 10)
-# define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_MMC_U_BOOT_OFFS
# ifdef CONFIG_SPL_BUILD
# define CONFIG_FIXED_SDHCI_ALIGNED_BUFFER 0x00180000 /* in SDRAM */
# endif
diff --git a/include/configs/x530.h b/include/configs/x530.h
index 4446510df4e..515c6e7ff45 100644
--- a/include/configs/x530.h
+++ b/include/configs/x530.h
@@ -97,7 +97,4 @@
#define CONFIG_SPL_STACK (0x40000000 + ((192 - 16) << 10))
#define CONFIG_SPL_BOOTROM_SAVE (CONFIG_SPL_STACK + 4)
-/* SPL related SPI defines */
-#define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_SPI_U_BOOT_OFFS
-
#endif /* _CONFIG_X530_H */
diff --git a/include/spl.h b/include/spl.h
index 925b6f0cc64..afbf39bef49 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -219,6 +219,7 @@ struct spl_image_info {
void *fdt_addr;
#endif
u32 boot_device;
+ u32 offset;
u32 size;
u32 flags;
void *arg;
diff --git a/include/tpm-v2.h b/include/tpm-v2.h
index 247b3869676..949a13c917a 100644
--- a/include/tpm-v2.h
+++ b/include/tpm-v2.h
@@ -32,6 +32,8 @@ struct udevice;
#define TPM2_MAX_TPM_PROPERTIES ((TPM2_MAX_CAP_BUFFER - sizeof(u32) /* TPM2_CAP */ - \
sizeof(u32)) / sizeof(struct tpms_tagged_property))
+#define TPM2_HDR_LEN 10
+
/*
* We deviate from this draft of the specification by increasing the value of
* TPM2_NUM_PCR_BANKS from 3 to 16 to ensure compatibility with TPM2
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index 66678cf2a24..812d8f2836f 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -3271,7 +3271,6 @@ CONFIG_SYS_USE_NAND
CONFIG_SYS_USE_NANDFLASH
CONFIG_SYS_USE_NORFLASH
CONFIG_SYS_USR_EXCEP
-CONFIG_SYS_U_BOOT_OFFS
CONFIG_SYS_VCXK_ACKNOWLEDGE_DDR
CONFIG_SYS_VCXK_ACKNOWLEDGE_PIN
CONFIG_SYS_VCXK_ACKNOWLEDGE_PORT
diff --git a/test/common/test_autoboot.c b/test/common/test_autoboot.c
index 6564ac70496..42a1e4ab1fa 100644
--- a/test/common/test_autoboot.c
+++ b/test/common/test_autoboot.c
@@ -16,13 +16,19 @@
static int check_for_input(struct unit_test_state *uts, const char *in,
bool correct)
{
+ bool old_val;
/* The bootdelay is set to 1 second in test_autoboot() */
const char *autoboot_prompt =
"Enter password \"a\" in 1 seconds to stop autoboot";
console_record_reset_enable();
console_in_puts(in);
+
+ /* turn on keyed autoboot for the test, if possible */
+ old_val = autoboot_set_keyed(true);
autoboot_command("echo Autoboot password unlock not successful");
+ old_val = autoboot_set_keyed(old_val);
+
ut_assert_nextline(autoboot_prompt);
if (!correct)
ut_assert_nextline("Autoboot password unlock not successful");
diff --git a/test/dm/of_platdata.c b/test/dm/of_platdata.c
index 0f89c7a7da8..0463cf0b433 100644
--- a/test/dm/of_platdata.c
+++ b/test/dm/of_platdata.c
@@ -35,12 +35,13 @@ static int dm_test_of_plat_props(struct unit_test_state *uts)
plat = dev_get_plat(dev);
ut_assert(plat->boolval);
ut_asserteq(1, plat->intval);
- ut_asserteq(4, ARRAY_SIZE(plat->intarray));
+ ut_asserteq(3, ARRAY_SIZE(plat->intarray));
ut_asserteq(2, plat->intarray[0]);
ut_asserteq(3, plat->intarray[1]);
ut_asserteq(4, plat->intarray[2]);
- ut_asserteq(0, plat->intarray[3]);
ut_asserteq(5, plat->byteval);
+ ut_asserteq(1, ARRAY_SIZE(plat->maybe_empty_int));
+ ut_asserteq(0, plat->maybe_empty_int[0]);
ut_asserteq(3, ARRAY_SIZE(plat->bytearray));
ut_asserteq(6, plat->bytearray[0]);
ut_asserteq(0, plat->bytearray[1]);
@@ -61,7 +62,6 @@ static int dm_test_of_plat_props(struct unit_test_state *uts)
ut_asserteq(5, plat->intarray[0]);
ut_asserteq(0, plat->intarray[1]);
ut_asserteq(0, plat->intarray[2]);
- ut_asserteq(0, plat->intarray[3]);
ut_asserteq(8, plat->byteval);
ut_asserteq(3, ARRAY_SIZE(plat->bytearray));
ut_asserteq(1, plat->bytearray[0]);
@@ -80,6 +80,7 @@ static int dm_test_of_plat_props(struct unit_test_state *uts)
ut_asserteq_str("one", plat->stringarray[0]);
ut_asserteq_str("", plat->stringarray[1]);
ut_asserteq_str("", plat->stringarray[2]);
+ ut_asserteq(1, plat->maybe_empty_int[0]);
ut_assertok(uclass_next_device_err(&dev));
plat = dev_get_plat(dev);
diff --git a/test/py/tests/test_tpm2.py b/test/py/tests/test_tpm2.py
index 70f906da511..ac04f7191ec 100644
--- a/test/py/tests/test_tpm2.py
+++ b/test/py/tests/test_tpm2.py
@@ -216,7 +216,9 @@ def test_tpm2_pcr_extend(u_boot_console):
output = u_boot_console.run_command('echo $?')
assert output.endswith('0')
- read_pcr = u_boot_console.run_command('tpm2 pcr_read 0 0x%x' % ram)
+ # Read the value back into a different place so we can still use 'ram' as
+ # our zero bytes
+ read_pcr = u_boot_console.run_command('tpm2 pcr_read 0 0x%x' % (ram + 0x20))
output = u_boot_console.run_command('echo $?')
assert output.endswith('0')
assert 'f5 a5 fd 42 d1 6a 20 30 27 98 ef 6e d3 09 97 9b' in read_pcr
@@ -226,6 +228,20 @@ def test_tpm2_pcr_extend(u_boot_console):
new_updates = int(re.findall(r'\d+', str)[0])
assert (updates + 1) == new_updates
+ u_boot_console.run_command('tpm2 pcr_extend 0 0x%x' % ram)
+ output = u_boot_console.run_command('echo $?')
+ assert output.endswith('0')
+
+ read_pcr = u_boot_console.run_command('tpm2 pcr_read 0 0x%x' % (ram + 0x20))
+ output = u_boot_console.run_command('echo $?')
+ assert output.endswith('0')
+ assert '7a 05 01 f5 95 7b df 9c b3 a8 ff 49 66 f0 22 65' in read_pcr
+ assert 'f9 68 65 8b 7a 9c 62 64 2c ba 11 65 e8 66 42 f5' in read_pcr
+
+ str = re.findall(r'\d+ known updates', read_pcr)[0]
+ new_updates = int(re.findall(r'\d+', str)[0])
+ assert (updates + 2) == new_updates
+
@pytest.mark.buildconfigspec('cmd_tpm_v2')
def test_tpm2_cleanup(u_boot_console):
"""Ensure the TPM is cleared from password or test related configuration."""
diff --git a/tools/Makefile b/tools/Makefile
index bae3f95c499..4a86321f646 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -169,14 +169,6 @@ HOST_EXTRACFLAGS += -DCONFIG_FIT_SIGNATURE_MAX_SIZE=0xffffffff
HOST_EXTRACFLAGS += -DCONFIG_FIT_CIPHER
endif
-ifdef CONFIG_SYS_U_BOOT_OFFS
-HOSTCFLAGS_kwbimage.o += -DCONFIG_SYS_U_BOOT_OFFS=$(CONFIG_SYS_U_BOOT_OFFS)
-endif
-
-ifneq ($(CONFIG_ARMADA_38X),)
-HOSTCFLAGS_kwbimage.o += -DCONFIG_KWB_SECURE
-endif
-
# MXSImage needs LibSSL
ifneq ($(CONFIG_MX23)$(CONFIG_MX28)$(CONFIG_ARMADA_38X)$(CONFIG_TOOLS_LIBCRYPTO),)
HOSTCFLAGS_kwbimage.o += \
diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py
index 3996971e39c..32a7aa98290 100644
--- a/tools/dtoc/fdt.py
+++ b/tools/dtoc/fdt.py
@@ -24,16 +24,19 @@ from patman import tools
# A list of types we support
class Type(IntEnum):
+ # Types in order from widest to narrowest
(BYTE, INT, STRING, BOOL, INT64) = range(5)
- def is_wider_than(self, other):
- """Check if another type is 'wider' than this one
+ def needs_widening(self, other):
+ """Check if this type needs widening to hold a value from another type
- A wider type is one that holds more information than an earlier one,
- similar to the concept of type-widening in C.
+ A wider type is one that can hold a wider array of information than
+ another one, or is less restrictive, so it can hold the information of
+ another type as well as its own. This is similar to the concept of
+ type-widening in C.
This uses a simple arithmetic comparison, since type values are in order
- from narrowest (BYTE) to widest (INT64).
+ from widest (BYTE) to narrowest (INT64).
Args:
other: Other type to compare against
@@ -149,7 +152,19 @@ class Prop:
update the current property to be like the second, since it is less
specific.
"""
- if self.type.is_wider_than(newprop.type):
+ if self.type.needs_widening(newprop.type):
+
+ # A boolean has an empty value: if it exists it is True and if not
+ # it is False. So when widening we always start with an empty list
+ # since the only valid integer property would be an empty list of
+ # integers.
+ # e.g. this is a boolean:
+ # some-prop;
+ # and it would be widened to int list by:
+ # some-prop = <1 2>;
+ if self.type == Type.BOOL:
+ self.type = Type.INT
+ self.value = [self.GetEmpty(self.type)]
if self.type == Type.INT and newprop.type == Type.BYTE:
if type(self.value) == list:
new_value = []
@@ -160,13 +175,14 @@ class Prop:
self.value = new_value
self.type = newprop.type
- if type(newprop.value) == list and type(self.value) != list:
- self.value = [self.value]
+ if type(newprop.value) == list:
+ if type(self.value) != list:
+ self.value = [self.value]
- if type(self.value) == list and len(newprop.value) > len(self.value):
- val = self.GetEmpty(self.type)
- while len(self.value) < len(newprop.value):
- self.value.append(val)
+ if len(newprop.value) > len(self.value):
+ val = self.GetEmpty(self.type)
+ while len(self.value) < len(newprop.value):
+ self.value.append(val)
@classmethod
def GetEmpty(self, type):
diff --git a/tools/dtoc/test/dtoc_test_simple.dts b/tools/dtoc/test/dtoc_test_simple.dts
index b5c1274bb7c..5a6fa88d5cc 100644
--- a/tools/dtoc/test/dtoc_test_simple.dts
+++ b/tools/dtoc/test/dtoc_test_simple.dts
@@ -14,6 +14,7 @@
u-boot,dm-pre-reloc;
compatible = "sandbox,spl-test";
boolval;
+ maybe-empty-int = <>;
intval = <1>;
intarray = <2 3 4>;
byteval = [05];
@@ -42,6 +43,7 @@
compatible = "sandbox,spl-test";
stringarray = "one";
longbytearray = [09 0a 0b 0c 0d 0e 0f 10];
+ maybe-empty-int = <1>;
};
i2c@0 {
diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py
index 863ede90b7a..752061f27a4 100755
--- a/tools/dtoc/test_dtoc.py
+++ b/tools/dtoc/test_dtoc.py
@@ -296,9 +296,10 @@ struct dtd_sandbox_spl_test {
\tbool\t\tboolval;
\tunsigned char\tbytearray[3];
\tunsigned char\tbyteval;
-\tfdt32_t\t\tintarray[4];
+\tfdt32_t\t\tintarray[3];
\tfdt32_t\t\tintval;
\tunsigned char\tlongbytearray[9];
+\tfdt32_t\t\tmaybe_empty_int[1];
\tunsigned char\tnotstring[5];
\tconst char *\tstringarray[3];
\tconst char *\tstringval;
@@ -354,10 +355,11 @@ static struct dtd_sandbox_spl_test dtv_spl_test = {
\t.boolval\t\t= true,
\t.bytearray\t\t= {0x6, 0x0, 0x0},
\t.byteval\t\t= 0x5,
-\t.intarray\t\t= {0x2, 0x3, 0x4, 0x0},
+\t.intarray\t\t= {0x2, 0x3, 0x4},
\t.intval\t\t\t= 0x1,
\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,
\t\t0x11},
+\t.maybe_empty_int\t= {0x0},
\t.notstring\t\t= {0x20, 0x21, 0x22, 0x10, 0x0},
\t.stringarray\t\t= {"multi-word", "message", ""},
\t.stringval\t\t= "message",
@@ -377,7 +379,7 @@ static struct dtd_sandbox_spl_test dtv_spl_test2 = {
\t.acpi_name\t\t= "\\\\_SB.GPO0",
\t.bytearray\t\t= {0x1, 0x23, 0x34},
\t.byteval\t\t= 0x8,
-\t.intarray\t\t= {0x5, 0x0, 0x0, 0x0},
+\t.intarray\t\t= {0x5, 0x0, 0x0},
\t.intval\t\t\t= 0x3,
\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0x0, 0x0, 0x0, 0x0,
\t\t0x0},
@@ -398,6 +400,7 @@ U_BOOT_DRVINFO(spl_test2) = {
static struct dtd_sandbox_spl_test dtv_spl_test3 = {
\t.longbytearray\t\t= {0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10,
\t\t0x0},
+\t.maybe_empty_int\t= {0x1},
\t.stringarray\t\t= {"one", "", ""},
};
U_BOOT_DRVINFO(spl_test3) = {
diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py
index 856392b1bd9..1119e6b7847 100755
--- a/tools/dtoc/test_fdt.py
+++ b/tools/dtoc/test_fdt.py
@@ -122,8 +122,9 @@ class TestFdt(unittest.TestCase):
node = self.dtb.GetNode('/spl-test')
props = self.dtb.GetProps(node)
self.assertEqual(['boolval', 'bytearray', 'byteval', 'compatible',
- 'intarray', 'intval', 'longbytearray', 'notstring',
- 'stringarray', 'stringval', 'u-boot,dm-pre-reloc'],
+ 'intarray', 'intval', 'longbytearray',
+ 'maybe-empty-int', 'notstring', 'stringarray',
+ 'stringval', 'u-boot,dm-pre-reloc'],
sorted(props.keys()))
def testCheckError(self):
@@ -379,7 +380,7 @@ class TestProp(unittest.TestCase):
self.assertEqual(Type.INT, prop.type)
self.assertEqual(1, fdt32_to_cpu(prop.value))
- # Convert singla value to array
+ # Convert single value to array
prop2 = self.node.props['intarray']
prop.Widen(prop2)
self.assertEqual(Type.INT, prop.type)
@@ -422,6 +423,28 @@ class TestProp(unittest.TestCase):
self.assertTrue(isinstance(prop.value, list))
self.assertEqual(3, len(prop.value))
+ # Widen an array of ints with an int (should do nothing)
+ prop = self.node.props['intarray']
+ prop2 = node2.props['intarray']
+ self.assertEqual(Type.INT, prop.type)
+ self.assertEqual(3, len(prop.value))
+ prop.Widen(prop2)
+ self.assertEqual(Type.INT, prop.type)
+ self.assertEqual(3, len(prop.value))
+
+ # Widen an empty bool to an int
+ prop = self.node.props['maybe-empty-int']
+ prop3 = node3.props['maybe-empty-int']
+ self.assertEqual(Type.BOOL, prop.type)
+ self.assertEqual(True, prop.value)
+ self.assertEqual(Type.INT, prop3.type)
+ self.assertFalse(isinstance(prop.value, list))
+ self.assertEqual(4, len(prop3.value))
+ prop.Widen(prop3)
+ self.assertEqual(Type.INT, prop.type)
+ self.assertTrue(isinstance(prop.value, list))
+ self.assertEqual(1, len(prop.value))
+
def testAdd(self):
"""Test adding properties"""
self.fdt.pack()
diff --git a/tools/kwbimage.c b/tools/kwbimage.c
index 02fd0c949ff..00cb338d64f 100644
--- a/tools/kwbimage.c
+++ b/tools/kwbimage.c
@@ -16,7 +16,6 @@
#include <stdint.h>
#include "kwbimage.h"
-#ifdef CONFIG_KWB_SECURE
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
@@ -42,13 +41,10 @@ void EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
EVP_MD_CTX_reset(ctx);
}
#endif
-#endif
static struct image_cfg_element *image_cfg;
static int cfgn;
-#ifdef CONFIG_KWB_SECURE
static int verbose_mode;
-#endif
struct boot_mode {
unsigned int id;
@@ -89,7 +85,7 @@ struct nand_ecc_mode nand_ecc_modes[] = {
/* Used to identify an undefined execution or destination address */
#define ADDR_INVALID ((uint32_t)-1)
-#define BINARY_MAX_ARGS 8
+#define BINARY_MAX_ARGS 255
/* In-memory representation of a line of the configuration file */
@@ -103,8 +99,8 @@ enum image_cfg_type {
IMAGE_CFG_NAND_ECC_MODE,
IMAGE_CFG_NAND_PAGESZ,
IMAGE_CFG_BINARY,
- IMAGE_CFG_PAYLOAD,
IMAGE_CFG_DATA,
+ IMAGE_CFG_DATA_DELAY,
IMAGE_CFG_BAUDRATE,
IMAGE_CFG_DEBUG,
IMAGE_CFG_KAK,
@@ -131,8 +127,8 @@ static const char * const id_strs[] = {
[IMAGE_CFG_NAND_ECC_MODE] = "NAND_ECC_MODE",
[IMAGE_CFG_NAND_PAGESZ] = "NAND_PAGE_SIZE",
[IMAGE_CFG_BINARY] = "BINARY",
- [IMAGE_CFG_PAYLOAD] = "PAYLOAD",
[IMAGE_CFG_DATA] = "DATA",
+ [IMAGE_CFG_DATA_DELAY] = "DATA_DELAY",
[IMAGE_CFG_BAUDRATE] = "BAUDRATE",
[IMAGE_CFG_DEBUG] = "DEBUG",
[IMAGE_CFG_KAK] = "KAK",
@@ -157,7 +153,6 @@ struct image_cfg_element {
unsigned int args[BINARY_MAX_ARGS];
unsigned int nargs;
} binary;
- const char *payload;
unsigned int dstaddr;
unsigned int execaddr;
unsigned int nandblksz;
@@ -165,6 +160,7 @@ struct image_cfg_element {
unsigned int nandeccmode;
unsigned int nandpagesz;
struct ext_hdr_v0_reg regdata;
+ unsigned int regdata_delay;
unsigned int baudrate;
unsigned int debug;
const char *key_name;
@@ -243,8 +239,6 @@ image_count_options(unsigned int optiontype)
return count;
}
-#if defined(CONFIG_KWB_SECURE)
-
static int image_get_csk_index(void)
{
struct image_cfg_element *e;
@@ -267,8 +261,6 @@ static bool image_get_spezialized_img(void)
return e->sec_specialized_img;
}
-#endif
-
/*
* Compute a 8-bit checksum of a memory area. This algorithm follows
* the requirements of the Marvell SoC BootROM specifications.
@@ -363,7 +355,6 @@ static uint8_t baudrate_to_option(unsigned int baudrate)
}
}
-#if defined(CONFIG_KWB_SECURE)
static void kwb_msg(const char *fmt, ...)
{
if (verbose_mode) {
@@ -852,8 +843,6 @@ done:
return ret;
}
-#endif
-
static void *image_create_v0(size_t *imagesz, struct image_tool_params *params,
int payloadsz)
{
@@ -874,11 +863,6 @@ static void *image_create_v0(size_t *imagesz, struct image_tool_params *params,
headersz += sizeof(struct ext_hdr_v0);
}
- if (image_count_options(IMAGE_CFG_PAYLOAD) > 1) {
- fprintf(stderr, "More than one payload, not possible\n");
- return NULL;
- }
-
image = malloc(headersz);
if (!image) {
fprintf(stderr, "Cannot allocate memory for image\n");
@@ -891,7 +875,7 @@ static void *image_create_v0(size_t *imagesz, struct image_tool_params *params,
/* Fill in the main header */
main_hdr->blocksize =
- cpu_to_le32(payloadsz + sizeof(uint32_t) - headersz);
+ cpu_to_le32(payloadsz - headersz);
main_hdr->srcaddr = cpu_to_le32(headersz);
main_hdr->ext = has_ext;
main_hdr->destaddr = cpu_to_le32(params->addr);
@@ -941,7 +925,9 @@ static void *image_create_v0(size_t *imagesz, struct image_tool_params *params,
static size_t image_headersz_v1(int *hasext)
{
struct image_cfg_element *binarye;
+ unsigned int count;
size_t headersz;
+ int cfgi;
/*
* Calculate the size of the header and the size of the
@@ -949,21 +935,18 @@ static size_t image_headersz_v1(int *hasext)
*/
headersz = sizeof(struct main_hdr_v1);
- if (image_count_options(IMAGE_CFG_BINARY) > 1) {
- fprintf(stderr, "More than one binary blob, not supported\n");
- return 0;
- }
-
- if (image_count_options(IMAGE_CFG_PAYLOAD) > 1) {
- fprintf(stderr, "More than one payload, not possible\n");
- return 0;
- }
+ count = image_count_options(IMAGE_CFG_DATA);
+ if (count > 0)
+ headersz += sizeof(struct register_set_hdr_v1) + 8 * count + 4;
- binarye = image_find_option(IMAGE_CFG_BINARY);
- if (binarye) {
+ for (cfgi = 0; cfgi < cfgn; cfgi++) {
int ret;
struct stat s;
+ binarye = &image_cfg[cfgi];
+ if (binarye->type != IMAGE_CFG_BINARY)
+ continue;
+
ret = stat(binarye->binary.file, &s);
if (ret < 0) {
char cwd[PATH_MAX];
@@ -978,38 +961,23 @@ static size_t image_headersz_v1(int *hasext)
fprintf(stderr,
"Didn't find the file '%s' in '%s' which is mandatory to generate the image\n"
"This file generally contains the DDR3 training code, and should be extracted from an existing bootable\n"
- "image for your board. See 'kwbimage -x' to extract it from an existing image.\n",
+ "image for your board. Use 'dumpimage -T kwbimage -p 0' to extract it from an existing image.\n",
binarye->binary.file, dir);
return 0;
}
headersz += sizeof(struct opt_hdr_v1) +
- s.st_size +
+ ALIGN(s.st_size, 4) +
(binarye->binary.nargs + 2) * sizeof(uint32_t);
if (hasext)
*hasext = 1;
}
-#if defined(CONFIG_KWB_SECURE)
if (image_get_csk_index() >= 0) {
headersz += sizeof(struct secure_hdr_v1);
if (hasext)
*hasext = 1;
}
-#endif
-
-#if defined(CONFIG_SYS_U_BOOT_OFFS)
- if (headersz > CONFIG_SYS_U_BOOT_OFFS) {
- fprintf(stderr,
- "Error: Image header (incl. SPL image) too big!\n");
- fprintf(stderr, "header=0x%x CONFIG_SYS_U_BOOT_OFFS=0x%x!\n",
- (int)headersz, CONFIG_SYS_U_BOOT_OFFS);
- fprintf(stderr, "Increase CONFIG_SYS_U_BOOT_OFFS!\n");
- return 0;
- }
-
- headersz = CONFIG_SYS_U_BOOT_OFFS;
-#endif
/*
* The payload should be aligned on some reasonable
@@ -1018,10 +986,10 @@ static size_t image_headersz_v1(int *hasext)
return ALIGN(headersz, 4096);
}
-int add_binary_header_v1(uint8_t *cur)
+int add_binary_header_v1(uint8_t **cur, uint8_t **next_ext,
+ struct image_cfg_element *binarye)
{
- struct image_cfg_element *binarye;
- struct opt_hdr_v1 *hdr = (struct opt_hdr_v1 *)cur;
+ struct opt_hdr_v1 *hdr = (struct opt_hdr_v1 *)*cur;
uint32_t *args;
size_t binhdrsz;
struct stat s;
@@ -1029,11 +997,6 @@ int add_binary_header_v1(uint8_t *cur)
FILE *bin;
int ret;
- binarye = image_find_option(IMAGE_CFG_BINARY);
-
- if (!binarye)
- return 0;
-
hdr->headertype = OPT_HDR_V1_BINARY_TYPE;
bin = fopen(binarye->binary.file, "r");
@@ -1051,28 +1014,21 @@ int add_binary_header_v1(uint8_t *cur)
binhdrsz = sizeof(struct opt_hdr_v1) +
(binarye->binary.nargs + 2) * sizeof(uint32_t) +
- s.st_size;
-
- /*
- * The size includes the binary image size, rounded
- * up to a 4-byte boundary. Plus 4 bytes for the
- * next-header byte and 3-byte alignment at the end.
- */
- binhdrsz = ALIGN(binhdrsz, 4) + 4;
+ ALIGN(s.st_size, 4);
hdr->headersz_lsb = cpu_to_le16(binhdrsz & 0xFFFF);
hdr->headersz_msb = (binhdrsz & 0xFFFF0000) >> 16;
- cur += sizeof(struct opt_hdr_v1);
+ *cur += sizeof(struct opt_hdr_v1);
- args = (uint32_t *)cur;
+ args = (uint32_t *)*cur;
*args = cpu_to_le32(binarye->binary.nargs);
args++;
for (argi = 0; argi < binarye->binary.nargs; argi++)
args[argi] = cpu_to_le32(binarye->binary.args[argi]);
- cur += (binarye->binary.nargs + 1) * sizeof(uint32_t);
+ *cur += (binarye->binary.nargs + 1) * sizeof(uint32_t);
- ret = fread(cur, s.st_size, 1, bin);
+ ret = fread(*cur, s.st_size, 1, bin);
if (ret != 1) {
fprintf(stderr,
"Could not read binary image %s\n",
@@ -1082,17 +1038,13 @@ int add_binary_header_v1(uint8_t *cur)
fclose(bin);
- cur += ALIGN(s.st_size, 4);
+ *cur += ALIGN(s.st_size, 4);
- /*
- * For now, we don't support more than one binary
- * header, and no other header types are
- * supported. So, the binary header is necessarily the
- * last one
- */
- *((uint32_t *)cur) = 0x00000000;
+ *((uint32_t *)*cur) = 0x00000000;
+ **next_ext = 1;
+ *next_ext = *cur;
- cur += sizeof(uint32_t);
+ *cur += sizeof(uint32_t);
return 0;
@@ -1102,8 +1054,6 @@ err_close:
return -1;
}
-#if defined(CONFIG_KWB_SECURE)
-
int export_pub_kak_hash(RSA *kak, struct secure_hdr_v1 *secure_hdr)
{
FILE *hashf;
@@ -1211,20 +1161,19 @@ int add_secure_header_v1(struct image_tool_params *params, uint8_t *ptr,
return 0;
}
-#endif
static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
uint8_t *ptr, int payloadsz)
{
struct image_cfg_element *e;
struct main_hdr_v1 *main_hdr;
-#if defined(CONFIG_KWB_SECURE)
+ struct register_set_hdr_v1 *register_set_hdr;
struct secure_hdr_v1 *secure_hdr = NULL;
-#endif
size_t headersz;
uint8_t *image, *cur;
int hasext = 0;
uint8_t *next_ext = NULL;
+ int cfgi, datai, size;
/*
* Calculate the size of the header and the size of the
@@ -1249,11 +1198,10 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
/* Fill the main header */
main_hdr->blocksize =
- cpu_to_le32(payloadsz - headersz + sizeof(uint32_t));
+ cpu_to_le32(payloadsz - headersz);
main_hdr->headersz_lsb = cpu_to_le16(headersz & 0xFFFF);
main_hdr->headersz_msb = (headersz & 0xFFFF0000) >> 16;
- main_hdr->destaddr = cpu_to_le32(params->addr)
- - sizeof(image_header_t);
+ main_hdr->destaddr = cpu_to_le32(params->addr);
main_hdr->execaddr = cpu_to_le32(params->ep);
main_hdr->srcaddr = cpu_to_le32(headersz);
main_hdr->ext = hasext;
@@ -1273,15 +1221,29 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
e = image_find_option(IMAGE_CFG_DEBUG);
if (e)
main_hdr->flags = e->debug ? 0x1 : 0;
- e = image_find_option(IMAGE_CFG_BINARY);
- if (e) {
- char *s = strrchr(e->binary.file, '/');
- if (strcmp(s, "/binary.0") == 0)
- main_hdr->destaddr = cpu_to_le32(params->addr);
- }
+ /*
+ * For SATA srcaddr is specified in number of sectors starting from
+ * sector 0. The main header is stored at sector number 1.
+ * This expects the sector size to be 512 bytes.
+ * Header size is already aligned.
+ */
+ if (main_hdr->blockid == IBR_HDR_SATA_ID)
+ main_hdr->srcaddr = cpu_to_le32(headersz / 512 + 1);
+
+ /*
+ * For SDIO srcaddr is specified in number of sectors starting from
+ * sector 0. The main header is stored at sector number 0.
+ * This expects sector size to be 512 bytes.
+ * Header size is already aligned.
+ */
+ if (main_hdr->blockid == IBR_HDR_SDIO_ID)
+ main_hdr->srcaddr = cpu_to_le32(headersz / 512);
+
+ /* For PCIe srcaddr is not used and must be set to 0xFFFFFFFF. */
+ if (main_hdr->blockid == IBR_HDR_PEX_ID)
+ main_hdr->srcaddr = cpu_to_le32(0xFFFFFFFF);
-#if defined(CONFIG_KWB_SECURE)
if (image_get_csk_index() >= 0) {
/*
* only reserve the space here; we fill the header later since
@@ -1289,19 +1251,59 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
*/
secure_hdr = (struct secure_hdr_v1 *)cur;
cur += sizeof(struct secure_hdr_v1);
+ *next_ext = 1;
next_ext = &secure_hdr->next;
}
-#endif
- *next_ext = 1;
- if (add_binary_header_v1(cur))
- return NULL;
+ datai = 0;
+ register_set_hdr = (struct register_set_hdr_v1 *)cur;
+ for (cfgi = 0; cfgi < cfgn; cfgi++) {
+ e = &image_cfg[cfgi];
+ if (e->type != IMAGE_CFG_DATA &&
+ e->type != IMAGE_CFG_DATA_DELAY)
+ continue;
+ if (e->type == IMAGE_CFG_DATA_DELAY) {
+ size = sizeof(struct register_set_hdr_v1) + 8 * datai + 4;
+ register_set_hdr->headertype = OPT_HDR_V1_REGISTER_TYPE;
+ register_set_hdr->headersz_lsb = cpu_to_le16(size & 0xFFFF);
+ register_set_hdr->headersz_msb = size >> 16;
+ register_set_hdr->data[datai].last_entry.delay = e->regdata_delay;
+ cur += size;
+ *next_ext = 1;
+ next_ext = &register_set_hdr->data[datai].last_entry.next;
+ datai = 0;
+ continue;
+ }
+ register_set_hdr->data[datai].entry.address =
+ cpu_to_le32(e->regdata.raddr);
+ register_set_hdr->data[datai].entry.value =
+ cpu_to_le32(e->regdata.rdata);
+ datai++;
+ }
+ if (datai != 0) {
+ size = sizeof(struct register_set_hdr_v1) + 8 * datai + 4;
+ register_set_hdr->headertype = OPT_HDR_V1_REGISTER_TYPE;
+ register_set_hdr->headersz_lsb = cpu_to_le16(size & 0xFFFF);
+ register_set_hdr->headersz_msb = size >> 16;
+ /* Set delay to the smallest possible value 1ms. */
+ register_set_hdr->data[datai].last_entry.delay = 1;
+ cur += size;
+ *next_ext = 1;
+ next_ext = &register_set_hdr->data[datai].last_entry.next;
+ }
+
+ for (cfgi = 0; cfgi < cfgn; cfgi++) {
+ e = &image_cfg[cfgi];
+ if (e->type != IMAGE_CFG_BINARY)
+ continue;
+
+ if (add_binary_header_v1(&cur, &next_ext, e))
+ return NULL;
+ }
-#if defined(CONFIG_KWB_SECURE)
if (secure_hdr && add_secure_header_v1(params, ptr, payloadsz,
headersz, image, secure_hdr))
return NULL;
-#endif
/* Calculate and set the header checksum */
main_hdr->checksum = image_checksum8(main_hdr, headersz);
@@ -1408,6 +1410,12 @@ static int image_create_config_parse_oneline(char *line,
el->regdata.raddr = strtoul(value1, NULL, 16);
el->regdata.rdata = strtoul(value2, NULL, 16);
break;
+ case IMAGE_CFG_DATA_DELAY:
+ if (!strcmp(value1, "SDRAM_SETUP"))
+ el->regdata_delay = REGISTER_SET_HDR_OPT_DELAY_SDRAM_SETUP;
+ else
+ el->regdata_delay = REGISTER_SET_HDR_OPT_DELAY_MS(strtoul(value1, NULL, 10));
+ break;
case IMAGE_CFG_BAUDRATE:
el->baudrate = strtoul(value1, NULL, 10);
break;
@@ -1510,6 +1518,17 @@ static int image_get_version(void)
return e->version;
}
+static int image_get_bootfrom(void)
+{
+ struct image_cfg_element *e;
+
+ e = image_find_option(IMAGE_CFG_BOOT_FROM);
+ if (!e)
+ return -1;
+
+ return e->bootfrom;
+}
+
static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd,
struct image_tool_params *params)
{
@@ -1519,7 +1538,6 @@ static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd,
size_t headersz = 0;
uint32_t checksum;
int ret;
- int size;
fcfg = fopen(params->imagename, "r");
if (!fcfg) {
@@ -1547,9 +1565,6 @@ static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd,
exit(EXIT_FAILURE);
}
- /* The MVEBU BootROM does not allow non word aligned payloads */
- sbuf->st_size = ALIGN(sbuf->st_size, 4);
-
version = image_get_version();
switch (version) {
/*
@@ -1580,16 +1595,10 @@ static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd,
free(image_cfg);
/* Build and add image checksum header */
- checksum =
- cpu_to_le32(image_checksum32((uint32_t *)ptr, sbuf->st_size));
- size = write(ifd, &checksum, sizeof(uint32_t));
- if (size != sizeof(uint32_t)) {
- fprintf(stderr, "Error:%s - Checksum write %d bytes %s\n",
- params->cmdname, size, params->imagefile);
- exit(EXIT_FAILURE);
- }
-
- sbuf->st_size += sizeof(uint32_t);
+ checksum = cpu_to_le32(image_checksum32((uint8_t *)ptr + headersz,
+ sbuf->st_size - headersz - sizeof(uint32_t)));
+ memcpy((uint8_t *)ptr + sbuf->st_size - sizeof(uint32_t), &checksum,
+ sizeof(uint32_t));
/* Finally copy the header into the image area */
memcpy(ptr, image, headersz);
@@ -1604,6 +1613,30 @@ static void kwbimage_print_header(const void *ptr)
printf("Image Type: MVEBU Boot from %s Image\n",
image_boot_mode_name(mhdr->blockid));
printf("Image version:%d\n", image_version((void *)ptr));
+ if (image_version((void *)ptr) == 1) {
+ struct main_hdr_v1 *mhdr = (struct main_hdr_v1 *)ptr;
+
+ if (mhdr->ext & 0x1) {
+ struct opt_hdr_v1 *ohdr = (struct opt_hdr_v1 *)
+ ((uint8_t *)ptr +
+ sizeof(*mhdr));
+
+ while (1) {
+ uint32_t ohdr_size;
+
+ ohdr_size = (ohdr->headersz_msb << 16) |
+ le16_to_cpu(ohdr->headersz_lsb);
+ if (ohdr->headertype == OPT_HDR_V1_BINARY_TYPE) {
+ printf("BIN Hdr Size: ");
+ genimg_print_size(ohdr_size - 12 - 4 * ohdr->data[0]);
+ }
+ if (!(*((uint8_t *)ohdr + ohdr_size - 4) & 0x1))
+ break;
+ ohdr = (struct opt_hdr_v1 *)((uint8_t *)ohdr +
+ ohdr_size);
+ }
+ }
+ }
printf("Data Size: ");
genimg_print_size(mhdr->blocksize - sizeof(uint32_t));
printf("Load Address: %08x\n", mhdr->destaddr);
@@ -1632,14 +1665,90 @@ static int kwbimage_verify_header(unsigned char *ptr, int image_size,
/* Only version 0 extended header has checksum */
if (image_version((void *)ptr) == 0) {
- struct ext_hdr_v0 *ext_hdr;
+ struct main_hdr_v0 *mhdr = (struct main_hdr_v0 *)ptr;
- ext_hdr = (struct ext_hdr_v0 *)
+ if (mhdr->ext & 0x1) {
+ struct ext_hdr_v0 *ext_hdr;
+
+ ext_hdr = (struct ext_hdr_v0 *)
(ptr + sizeof(struct main_hdr_v0));
- checksum = image_checksum8(ext_hdr,
- sizeof(struct ext_hdr_v0)
- - sizeof(uint8_t));
- if (checksum != ext_hdr->checksum)
+ checksum = image_checksum8(ext_hdr,
+ sizeof(struct ext_hdr_v0)
+ - sizeof(uint8_t));
+ if (checksum != ext_hdr->checksum)
+ return -FDT_ERR_BADSTRUCTURE;
+ }
+ }
+
+ if (image_version((void *)ptr) == 1) {
+ struct main_hdr_v1 *mhdr = (struct main_hdr_v1 *)ptr;
+ uint32_t offset;
+ uint32_t size;
+
+ if (mhdr->ext & 0x1) {
+ uint32_t ohdr_size;
+ struct opt_hdr_v1 *ohdr = (struct opt_hdr_v1 *)
+ (ptr + sizeof(*mhdr));
+
+ while (1) {
+ if ((uint8_t *)ohdr + sizeof(*ohdr) >
+ (uint8_t *)mhdr + header_size)
+ return -FDT_ERR_BADSTRUCTURE;
+
+ ohdr_size = (ohdr->headersz_msb << 16) |
+ le16_to_cpu(ohdr->headersz_lsb);
+
+ if (ohdr_size < 8 ||
+ (uint8_t *)ohdr + ohdr_size >
+ (uint8_t *)mhdr + header_size)
+ return -FDT_ERR_BADSTRUCTURE;
+
+ if (!(*((uint8_t *)ohdr + ohdr_size - 4) & 0x1))
+ break;
+ ohdr = (struct opt_hdr_v1 *)((uint8_t *)ohdr +
+ ohdr_size);
+ }
+ }
+
+ offset = le32_to_cpu(mhdr->srcaddr);
+
+ /*
+ * For SATA srcaddr is specified in number of sectors.
+ * The main header is must be stored at sector number 1.
+ * This expects that sector size is 512 bytes and recalculates
+ * data offset to bytes relative to the main header.
+ */
+ if (mhdr->blockid == IBR_HDR_SATA_ID) {
+ if (offset < 1)
+ return -FDT_ERR_BADSTRUCTURE;
+ offset -= 1;
+ offset *= 512;
+ }
+
+ /*
+ * For SDIO srcaddr is specified in number of sectors.
+ * This expects that sector size is 512 bytes and recalculates
+ * data offset to bytes.
+ */
+ if (mhdr->blockid == IBR_HDR_SDIO_ID)
+ offset *= 512;
+
+ /*
+ * For PCIe srcaddr is always set to 0xFFFFFFFF.
+ * This expects that data starts after all headers.
+ */
+ if (mhdr->blockid == IBR_HDR_PEX_ID && offset == 0xFFFFFFFF)
+ offset = header_size;
+
+ if (offset > image_size || offset % 4 != 0)
+ return -FDT_ERR_BADSTRUCTURE;
+
+ size = le32_to_cpu(mhdr->blocksize);
+ if (offset + size > image_size || size % 4 != 0)
+ return -FDT_ERR_BADSTRUCTURE;
+
+ if (image_checksum32(ptr + offset, size - 4) !=
+ *(uint32_t *)(ptr + offset + size - 4))
return -FDT_ERR_BADSTRUCTURE;
}
@@ -1650,7 +1759,9 @@ static int kwbimage_generate(struct image_tool_params *params,
struct image_type_params *tparams)
{
FILE *fcfg;
+ struct stat s;
int alloc_len;
+ int bootfrom;
int version;
void *hdr;
int ret;
@@ -1662,6 +1773,12 @@ static int kwbimage_generate(struct image_tool_params *params,
exit(EXIT_FAILURE);
}
+ if (stat(params->datafile, &s)) {
+ fprintf(stderr, "Could not stat data file %s: %s\n",
+ params->datafile, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
image_cfg = malloc(IMAGE_CFG_ELEMENT_MAX *
sizeof(struct image_cfg_element));
if (!image_cfg) {
@@ -1681,6 +1798,7 @@ static int kwbimage_generate(struct image_tool_params *params,
exit(EXIT_FAILURE);
}
+ bootfrom = image_get_bootfrom();
version = image_get_version();
switch (version) {
/*
@@ -1719,12 +1837,77 @@ static int kwbimage_generate(struct image_tool_params *params,
/*
* The resulting image needs to be 4-byte aligned. At least
* the Marvell hdrparser tool complains if its unaligned.
- * By returning 1 here in this function, called via
- * tparams->vrec_header() in mkimage.c, mkimage will
- * automatically pad the the resulting image to a 4-byte
- * size if necessary.
+ * After the image data is stored 4-byte checksum.
+ * Final SPI and NAND images must be aligned to 256 bytes.
+ * Final SATA and SDIO images must be aligned to 512 bytes.
*/
- return 1;
+ if (bootfrom == IBR_HDR_SPI_ID || bootfrom == IBR_HDR_NAND_ID)
+ return 4 + (256 - (alloc_len + s.st_size + 4) % 256) % 256;
+ else if (bootfrom == IBR_HDR_SATA_ID || bootfrom == IBR_HDR_SDIO_ID)
+ return 4 + (512 - (alloc_len + s.st_size + 4) % 512) % 512;
+ else
+ return 4 + (4 - s.st_size % 4) % 4;
+}
+
+static int kwbimage_extract_subimage(void *ptr, struct image_tool_params *params)
+{
+ struct main_hdr_v1 *mhdr = (struct main_hdr_v1 *)ptr;
+ size_t header_size = kwbimage_header_size(ptr);
+ int idx = params->pflag;
+ int cur_idx = 0;
+ uint32_t offset;
+ ulong image;
+ ulong size;
+
+ if (image_version((void *)ptr) == 1 && (mhdr->ext & 0x1)) {
+ struct opt_hdr_v1 *ohdr = (struct opt_hdr_v1 *)
+ ((uint8_t *)ptr +
+ sizeof(*mhdr));
+
+ while (1) {
+ uint32_t ohdr_size = (ohdr->headersz_msb << 16) |
+ le16_to_cpu(ohdr->headersz_lsb);
+
+ if (ohdr->headertype == OPT_HDR_V1_BINARY_TYPE) {
+ if (idx == cur_idx) {
+ image = (ulong)&ohdr->data[4 +
+ 4 * ohdr->data[0]];
+ size = ohdr_size - 12 -
+ 4 * ohdr->data[0];
+ goto extract;
+ }
+ ++cur_idx;
+ }
+ if (!(*((uint8_t *)ohdr + ohdr_size - 4) & 0x1))
+ break;
+ ohdr = (struct opt_hdr_v1 *)((uint8_t *)ohdr +
+ ohdr_size);
+ }
+ }
+
+ if (idx != cur_idx) {
+ printf("Image %d is not present\n", idx);
+ return -1;
+ }
+
+ offset = le32_to_cpu(mhdr->srcaddr);
+
+ if (mhdr->blockid == IBR_HDR_SATA_ID) {
+ offset -= 1;
+ offset *= 512;
+ }
+
+ if (mhdr->blockid == IBR_HDR_SDIO_ID)
+ offset *= 512;
+
+ if (mhdr->blockid == IBR_HDR_PEX_ID && offset == 0xFFFFFFFF)
+ offset = header_size;
+
+ image = (ulong)((uint8_t *)ptr + offset);
+ size = le32_to_cpu(mhdr->blocksize) - 4;
+
+extract:
+ return imagetool_save_subimage(params->outfile, image, size);
}
/*
@@ -1732,7 +1915,7 @@ static int kwbimage_generate(struct image_tool_params *params,
*/
static int kwbimage_check_params(struct image_tool_params *params)
{
- if (!strlen(params->imagename)) {
+ if (!params->iflag && (!params->imagename || !strlen(params->imagename))) {
char *msg = "Configuration file for kwbimage creation omitted";
fprintf(stderr, "Error:%s - %s\n", params->cmdname, msg);
@@ -1742,7 +1925,7 @@ static int kwbimage_check_params(struct image_tool_params *params)
return (params->dflag && (params->fflag || params->lflag)) ||
(params->fflag && (params->dflag || params->lflag)) ||
(params->lflag && (params->dflag || params->fflag)) ||
- (params->xflag) || !(strlen(params->imagename));
+ (params->xflag);
}
/*
@@ -1757,7 +1940,7 @@ U_BOOT_IMAGE_TYPE(
kwbimage_verify_header,
kwbimage_print_header,
kwbimage_set_header,
- NULL,
+ kwbimage_extract_subimage,
kwbimage_check_image_types,
NULL,
kwbimage_generate
diff --git a/tools/kwbimage.h b/tools/kwbimage.h
index 0b6d05bef10..e063e3e41eb 100644
--- a/tools/kwbimage.h
+++ b/tools/kwbimage.h
@@ -11,6 +11,12 @@
#include <compiler.h>
#include <stdint.h>
+#ifdef __GNUC__
+#define __packed __attribute((packed))
+#else
+#define __packed
+#endif
+
#define KWBIMAGE_MAX_CONFIG ((0x1dc - 0x20)/sizeof(struct reg_config))
#define MAX_TEMPBUF_LEN 32
@@ -27,7 +33,8 @@
#define IBR_HDR_SATA_ID 0x78
#define IBR_HDR_PEX_ID 0x9C
#define IBR_HDR_UART_ID 0x69
-#define IBR_DEF_ATTRIB 0x00
+#define IBR_HDR_SDIO_ID 0xAE
+#define IBR_DEF_ATTRIB 0x00
/* Structure of the main header, version 0 (Kirkwood, Dove) */
struct main_hdr_v0 {
@@ -45,12 +52,12 @@ struct main_hdr_v0 {
uint16_t rsvd2; /* 0x1C-0x1D */
uint8_t ext; /* 0x1E */
uint8_t checksum; /* 0x1F */
-};
+} __packed;
struct ext_hdr_v0_reg {
uint32_t raddr;
uint32_t rdata;
-};
+} __packed;
#define EXT_HDR_V0_REG_COUNT ((0x1dc - 0x20) / sizeof(struct ext_hdr_v0_reg))
@@ -60,12 +67,12 @@ struct ext_hdr_v0 {
struct ext_hdr_v0_reg rcfg[EXT_HDR_V0_REG_COUNT];
uint8_t reserved2[7];
uint8_t checksum;
-};
+} __packed;
struct kwb_header {
struct main_hdr_v0 kwb_hdr;
struct ext_hdr_v0 kwb_exthdr;
-};
+} __packed;
/* Structure of the main header, version 1 (Armada 370/38x/XP) */
struct main_hdr_v1 {
@@ -86,7 +93,7 @@ struct main_hdr_v1 {
uint16_t reserved5; /* 0x1C-0x1D */
uint8_t ext; /* 0x1E */
uint8_t checksum; /* 0x1F */
-};
+} __packed;
/*
* Main header options
@@ -108,21 +115,21 @@ struct opt_hdr_v1 {
uint8_t headersz_msb;
uint16_t headersz_lsb;
char data[0];
-};
+} __packed;
/*
* Public Key data in DER format
*/
struct pubkey_der_v1 {
uint8_t key[524];
-};
+} __packed;
/*
* Signature (RSA 2048)
*/
struct sig_v1 {
uint8_t sig[256];
-};
+} __packed;
/*
* Structure of secure header (Armada 38x)
@@ -145,7 +152,34 @@ struct secure_hdr_v1 {
uint8_t next; /* 0x25E0 */
uint8_t reserved4; /* 0x25E1 */
uint16_t reserved5; /* 0x25E2 - 0x25E3 */
-};
+} __packed;
+
+/*
+ * Structure of register set
+ */
+struct register_set_hdr_v1 {
+ uint8_t headertype; /* 0x0 */
+ uint8_t headersz_msb; /* 0x1 */
+ uint16_t headersz_lsb; /* 0x2 - 0x3 */
+ union {
+ struct {
+ uint32_t address; /* 0x4+8*N - 0x7+8*N */
+ uint32_t value; /* 0x8+8*N - 0xB+8*N */
+ } __packed entry;
+ struct {
+ uint8_t next; /* 0xC+8*N */
+ uint8_t delay; /* 0xD+8*N */
+ uint16_t reserved; /* 0xE+8*N - 0xF+8*N */
+ } __packed last_entry;
+ } data[];
+} __packed;
+
+/*
+ * Value 0 in register_set_hdr_v1 delay field is special.
+ * Instead of delay it setup SDRAM Controller.
+ */
+#define REGISTER_SET_HDR_OPT_DELAY_SDRAM_SETUP 0
+#define REGISTER_SET_HDR_OPT_DELAY_MS(val) ((val) ?: 1)
/*
* Various values for the opt_hdr_v1->headertype field, describing the
diff --git a/tools/kwboot.c b/tools/kwboot.c
index 4be094c9c8d..7feeaa45a22 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -26,12 +26,6 @@
#include <sys/mman.h>
#include <sys/stat.h>
-#ifdef __GNUC__
-#define PACKED __attribute((packed))
-#else
-#define PACKED
-#endif
-
/*
* Marvell BootROM UART Sensing
*/
@@ -68,7 +62,7 @@ struct kwboot_block {
uint8_t _pnum;
uint8_t data[128];
uint8_t csum;
-} PACKED;
+} __packed;
#define KWBOOT_BLK_RSP_TIMEO 1000 /* ms */
@@ -471,7 +465,7 @@ kwboot_term_pipe(int in, int out, char *quit, int *s)
ssize_t nin, nout;
char _buf[128], *buf = _buf;
- nin = read(in, buf, sizeof(buf));
+ nin = read(in, buf, sizeof(_buf));
if (nin <= 0)
return -1;
@@ -485,13 +479,14 @@ kwboot_term_pipe(int in, int out, char *quit, int *s)
return 0;
buf++;
nin--;
- } else
+ } else {
while (*s > 0) {
nout = write(out, quit, *s);
if (nout <= 0)
return -1;
(*s) -= nout;
}
+ }
}
}
@@ -564,7 +559,9 @@ kwboot_terminal(int tty)
}
} while (quit[s] != 0);
- tcsetattr(in, TCSANOW, &otio);
+ if (in >= 0)
+ tcsetattr(in, TCSANOW, &otio);
+ printf("\n");
out:
return rc;
}
@@ -637,7 +634,7 @@ kwboot_img_patch_hdr(void *img, size_t size)
}
image_ver = image_version(img);
- if (image_ver < 0) {
+ if (image_ver != 0 && image_ver != 1) {
fprintf(stderr, "Invalid image header version\n");
errno = EINVAL;
goto out;
@@ -648,6 +645,11 @@ kwboot_img_patch_hdr(void *img, size_t size)
else
hdrsz = KWBHEADER_V1_SIZE(hdr);
+ if (size < hdrsz) {
+ errno = EINVAL;
+ goto out;
+ }
+
csum = kwboot_img_csum8(hdr, hdrsz) - hdr->checksum;
if (csum != hdr->checksum) {
errno = EINVAL;
diff --git a/tools/moveconfig.py b/tools/moveconfig.py
index 41dd803c4ef..373b395fda4 100755
--- a/tools/moveconfig.py
+++ b/tools/moveconfig.py
@@ -7,296 +7,7 @@
"""
Move config options from headers to defconfig files.
-Since Kconfig was introduced to U-Boot, we have worked on moving
-config options from headers to Kconfig (defconfig).
-
-This tool intends to help this tremendous work.
-
-Installing
-----------
-
-You may need to install 'python3-asteval' for the 'asteval' module.
-
-Usage
------
-
-First, you must edit the Kconfig to add the menu entries for the configs
-you are moving.
-
-And then run this tool giving CONFIG names you want to move.
-For example, if you want to move CONFIG_CMD_USB and CONFIG_SYS_TEXT_BASE,
-simply type as follows:
-
- $ tools/moveconfig.py CONFIG_CMD_USB CONFIG_SYS_TEXT_BASE
-
-The tool walks through all the defconfig files and move the given CONFIGs.
-
-The log is also displayed on the terminal.
-
-The log is printed for each defconfig as follows:
-
-<defconfig_name>
- <action1>
- <action2>
- <action3>
- ...
-
-<defconfig_name> is the name of the defconfig.
-
-<action*> shows what the tool did for that defconfig.
-It looks like one of the following:
-
- - Move 'CONFIG_... '
- This config option was moved to the defconfig
-
- - CONFIG_... is not defined in Kconfig. Do nothing.
- The entry for this CONFIG was not found in Kconfig. The option is not
- defined in the config header, either. So, this case can be just skipped.
-
- - CONFIG_... is not defined in Kconfig (suspicious). Do nothing.
- This option is defined in the config header, but its entry was not found
- in Kconfig.
- There are two common cases:
- - You forgot to create an entry for the CONFIG before running
- this tool, or made a typo in a CONFIG passed to this tool.
- - The entry was hidden due to unmet 'depends on'.
- The tool does not know if the result is reasonable, so please check it
- manually.
-
- - 'CONFIG_...' is the same as the define in Kconfig. Do nothing.
- The define in the config header matched the one in Kconfig.
- We do not need to touch it.
-
- - Compiler is missing. Do nothing.
- The compiler specified for this architecture was not found
- in your PATH environment.
- (If -e option is passed, the tool exits immediately.)
-
- - Failed to process.
- An error occurred during processing this defconfig. Skipped.
- (If -e option is passed, the tool exits immediately on error.)
-
-Finally, you will be asked, Clean up headers? [y/n]:
-
-If you say 'y' here, the unnecessary config defines are removed
-from the config headers (include/configs/*.h).
-It just uses the regex method, so you should not rely on it.
-Just in case, please do 'git diff' to see what happened.
-
-
-How does it work?
------------------
-
-This tool runs configuration and builds include/autoconf.mk for every
-defconfig. The config options defined in Kconfig appear in the .config
-file (unless they are hidden because of unmet dependency.)
-On the other hand, the config options defined by board headers are seen
-in include/autoconf.mk. The tool looks for the specified options in both
-of them to decide the appropriate action for the options. If the given
-config option is found in the .config, but its value does not match the
-one from the board header, the config option in the .config is replaced
-with the define in the board header. Then, the .config is synced by
-"make savedefconfig" and the defconfig is updated with it.
-
-For faster processing, this tool handles multi-threading. It creates
-separate build directories where the out-of-tree build is run. The
-temporary build directories are automatically created and deleted as
-needed. The number of threads are chosen based on the number of the CPU
-cores of your system although you can change it via -j (--jobs) option.
-
-
-Toolchains
-----------
-
-Appropriate toolchain are necessary to generate include/autoconf.mk
-for all the architectures supported by U-Boot. Most of them are available
-at the kernel.org site, some are not provided by kernel.org. This tool uses
-the same tools as buildman, so see that tool for setup (e.g. --fetch-arch).
-
-
-Tips and trips
---------------
-
-To sync only X86 defconfigs:
-
- ./tools/moveconfig.py -s -d <(grep -l X86 configs/*)
-
-or:
-
- grep -l X86 configs/* | ./tools/moveconfig.py -s -d -
-
-To process CONFIG_CMD_FPGAD only for a subset of configs based on path match:
-
- ls configs/{hrcon*,iocon*,strider*} | \
- ./tools/moveconfig.py -Cy CONFIG_CMD_FPGAD -d -
-
-
-Finding implied CONFIGs
------------------------
-
-Some CONFIG options can be implied by others and this can help to reduce
-the size of the defconfig files. For example, CONFIG_X86 implies
-CONFIG_CMD_IRQ, so we can put 'imply CMD_IRQ' under 'config X86' and
-all x86 boards will have that option, avoiding adding CONFIG_CMD_IRQ to
-each of the x86 defconfig files.
-
-This tool can help find such configs. To use it, first build a database:
-
- ./tools/moveconfig.py -b
-
-Then try to query it:
-
- ./tools/moveconfig.py -i CONFIG_CMD_IRQ
- CONFIG_CMD_IRQ found in 311/2384 defconfigs
- 44 : CONFIG_SYS_FSL_ERRATUM_IFC_A002769
- 41 : CONFIG_SYS_FSL_ERRATUM_A007075
- 31 : CONFIG_SYS_FSL_DDR_VER_44
- 28 : CONFIG_ARCH_P1010
- 28 : CONFIG_SYS_FSL_ERRATUM_P1010_A003549
- 28 : CONFIG_SYS_FSL_ERRATUM_SEC_A003571
- 28 : CONFIG_SYS_FSL_ERRATUM_IFC_A003399
- 25 : CONFIG_SYS_FSL_ERRATUM_A008044
- 22 : CONFIG_ARCH_P1020
- 21 : CONFIG_SYS_FSL_DDR_VER_46
- 20 : CONFIG_MAX_PIRQ_LINKS
- 20 : CONFIG_HPET_ADDRESS
- 20 : CONFIG_X86
- 20 : CONFIG_PCIE_ECAM_SIZE
- 20 : CONFIG_IRQ_SLOT_COUNT
- 20 : CONFIG_I8259_PIC
- 20 : CONFIG_CPU_ADDR_BITS
- 20 : CONFIG_RAMBASE
- 20 : CONFIG_SYS_FSL_ERRATUM_A005871
- 20 : CONFIG_PCIE_ECAM_BASE
- 20 : CONFIG_X86_TSC_TIMER
- 20 : CONFIG_I8254_TIMER
- 20 : CONFIG_CMD_GETTIME
- 19 : CONFIG_SYS_FSL_ERRATUM_A005812
- 18 : CONFIG_X86_RUN_32BIT
- 17 : CONFIG_CMD_CHIP_CONFIG
- ...
-
-This shows a list of config options which might imply CONFIG_CMD_EEPROM along
-with how many defconfigs they cover. From this you can see that CONFIG_X86
-implies CONFIG_CMD_EEPROM. Therefore, instead of adding CONFIG_CMD_EEPROM to
-the defconfig of every x86 board, you could add a single imply line to the
-Kconfig file:
-
- config X86
- bool "x86 architecture"
- ...
- imply CMD_EEPROM
-
-That will cover 20 defconfigs. Many of the options listed are not suitable as
-they are not related. E.g. it would be odd for CONFIG_CMD_GETTIME to imply
-CMD_EEPROM.
-
-Using this search you can reduce the size of moveconfig patches.
-
-You can automatically add 'imply' statements in the Kconfig with the -a
-option:
-
- ./tools/moveconfig.py -s -i CONFIG_SCSI \
- -a CONFIG_ARCH_LS1021A,CONFIG_ARCH_LS1043A
-
-This will add 'imply SCSI' to the two CONFIG options mentioned, assuming that
-the database indicates that they do actually imply CONFIG_SCSI and do not
-already have an 'imply SCSI'.
-
-The output shows where the imply is added:
-
- 18 : CONFIG_ARCH_LS1021A arch/arm/cpu/armv7/ls102xa/Kconfig:1
- 13 : CONFIG_ARCH_LS1043A arch/arm/cpu/armv8/fsl-layerscape/Kconfig:11
- 12 : CONFIG_ARCH_LS1046A arch/arm/cpu/armv8/fsl-layerscape/Kconfig:31
-
-The first number is the number of boards which can avoid having a special
-CONFIG_SCSI option in their defconfig file if this 'imply' is added.
-The location at the right is the Kconfig file and line number where the config
-appears. For example, adding 'imply CONFIG_SCSI' to the 'config ARCH_LS1021A'
-in arch/arm/cpu/armv7/ls102xa/Kconfig at line 1 will help 18 boards to reduce
-the size of their defconfig files.
-
-If you want to add an 'imply' to every imply config in the list, you can use
-
- ./tools/moveconfig.py -s -i CONFIG_SCSI -a all
-
-To control which ones are displayed, use -I <list> where list is a list of
-options (use '-I help' to see possible options and their meaning).
-
-To skip showing you options that already have an 'imply' attached, use -A.
-
-When you have finished adding 'imply' options you can regenerate the
-defconfig files for affected boards with something like:
-
- git show --stat | ./tools/moveconfig.py -s -d -
-
-This will regenerate only those defconfigs changed in the current commit.
-If you start with (say) 100 defconfigs being changed in the commit, and add
-a few 'imply' options as above, then regenerate, hopefully you can reduce the
-number of defconfigs changed in the commit.
-
-
-Available options
------------------
-
- -c, --color
- Surround each portion of the log with escape sequences to display it
- in color on the terminal.
-
- -C, --commit
- Create a git commit with the changes when the operation is complete. A
- standard commit message is used which may need to be edited.
-
- -d, --defconfigs
- Specify a file containing a list of defconfigs to move. The defconfig
- files can be given with shell-style wildcards. Use '-' to read from stdin.
-
- -n, --dry-run
- Perform a trial run that does not make any changes. It is useful to
- see what is going to happen before one actually runs it.
-
- -e, --exit-on-error
- Exit immediately if Make exits with a non-zero status while processing
- a defconfig file.
-
- -s, --force-sync
- Do "make savedefconfig" forcibly for all the defconfig files.
- If not specified, "make savedefconfig" only occurs for cases
- where at least one CONFIG was moved.
-
- -S, --spl
- Look for moved config options in spl/include/autoconf.mk instead of
- include/autoconf.mk. This is useful for moving options for SPL build
- because SPL related options (mostly prefixed with CONFIG_SPL_) are
- sometimes blocked by CONFIG_SPL_BUILD ifdef conditionals.
-
- -H, --headers-only
- Only cleanup the headers; skip the defconfig processing
-
- -j, --jobs
- Specify the number of threads to run simultaneously. If not specified,
- the number of threads is the same as the number of CPU cores.
-
- -r, --git-ref
- Specify the git ref to clone for building the autoconf.mk. If unspecified
- use the CWD. This is useful for when changes to the Kconfig affect the
- default values and you want to capture the state of the defconfig from
- before that change was in effect. If in doubt, specify a ref pre-Kconfig
- changes (use HEAD if Kconfig changes are not committed). Worst case it will
- take a bit longer to run, but will always do the right thing.
-
- -v, --verbose
- Show any build errors as boards are built
-
- -y, --yes
- Instead of prompting, automatically go ahead with all operations. This
- includes cleaning up headers, CONFIG_SYS_EXTRA_OPTIONS, the config whitelist
- and the README.
-
-To see the complete list of supported options, run
-
- $ tools/moveconfig.py -h
-
+See doc/develop/moveconfig.rst for documentation.
"""
import asteval
@@ -1551,8 +1262,8 @@ def find_kconfig_rules(kconf, config, imply_config):
"""
sym = kconf.syms.get(imply_config)
if sym:
- for sel in sym.get_selected_symbols() | sym.get_implied_symbols():
- if sel.get_name() == config:
+ for sel, cond in (sym.selects + sym.implies):
+ if sel == config:
return sym
return None
@@ -1577,10 +1288,10 @@ def check_imply_rule(kconf, config, imply_config):
sym = kconf.syms.get(imply_config)
if not sym:
return 'cannot find sym'
- locs = sym.get_def_locations()
- if len(locs) != 1:
- return '%d locations' % len(locs)
- fname, linenum = locs[0]
+ nodes = sym.nodes
+ if len(nodes) != 1:
+ return '%d locations' % len(nodes)
+ fname, linenum = nodes[0].filename, nodes[0].linern
cwd = os.getcwd()
if cwd and fname.startswith(cwd):
fname = fname[len(cwd) + 1:]
@@ -1791,9 +1502,9 @@ def do_imply_config(config_list, add_imply, imply_flags, skip_added,
iconfig[CONFIG_LEN:])
kconfig_info = ''
if sym:
- locs = sym.get_def_locations()
- if len(locs) == 1:
- fname, linenum = locs[0]
+ nodes = sym.nodes
+ if len(nodes) == 1:
+ fname, linenum = nodes[0].filename, nodes[0].linenr
if cwd and fname.startswith(cwd):
fname = fname[len(cwd) + 1:]
kconfig_info = '%s:%d' % (fname, linenum)
@@ -1803,9 +1514,9 @@ def do_imply_config(config_list, add_imply, imply_flags, skip_added,
sym = kconf.syms.get(iconfig[CONFIG_LEN:])
fname = ''
if sym:
- locs = sym.get_def_locations()
- if len(locs) == 1:
- fname, linenum = locs[0]
+ nodes = sym.nodes
+ if len(nodes) == 1:
+ fname, linenum = nodes[0].filename, nodes[0].linenr
if cwd and fname.startswith(cwd):
fname = fname[len(cwd) + 1:]
in_arch_board = not sym or (fname.startswith('arch') or
diff --git a/tools/patman/func_test.py b/tools/patman/func_test.py
index 1ce6448d00b..9871bb580d0 100644
--- a/tools/patman/func_test.py
+++ b/tools/patman/func_test.py
@@ -506,6 +506,17 @@ Tested-by: %s
'Reviewed-by': {self.joe, self.mary},
'Tested-by': {self.leb}})
+ def testInvalidTag(self):
+ """Test invalid tag in a patchstream"""
+ text = '''This is a patch
+
+Serie-version: 2
+'''
+ with self.assertRaises(ValueError) as exc:
+ pstrm = PatchStream.process_text(text)
+ self.assertEqual("Line 3: Invalid tag = 'Serie-version: 2'",
+ str(exc.exception))
+
def testMissingEnd(self):
"""Test a missing END tag"""
text = '''This is a patch
diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py
index a44cd861afc..b9602924273 100644
--- a/tools/patman/patchstream.py
+++ b/tools/patman/patchstream.py
@@ -59,6 +59,9 @@ RE_DIFF = re.compile(r'^>.*diff --git a/(.*) b/(.*)$')
# Detect a context line, like '> @@ -153,8 +153,13 @@ CheckPatch
RE_LINE = re.compile(r'>.*@@ \-(\d+),\d+ \+(\d+),\d+ @@ *(.*)')
+# Detect line with invalid TAG
+RE_INV_TAG = re.compile('^Serie-([a-z-]*): *(.*)')
+
# States we can be in - can we use range() and still have comments?
STATE_MSG_HEADER = 0 # Still in the message header
STATE_PATCH_SUBJECT = 1 # In patch subject (first line of log for a commit)
@@ -318,6 +321,7 @@ class PatchStream:
leading_whitespace_match = RE_LEADING_WHITESPACE.match(line)
diff_match = RE_DIFF.match(line)
line_match = RE_LINE.match(line)
+ invalid_match = RE_INV_TAG.match(line)
tag_match = None
if self.state == STATE_PATCH_HEADER:
tag_match = RE_TAG.match(line)
@@ -471,6 +475,11 @@ class PatchStream:
self._add_warn('Line %d: Ignoring Commit-%s' %
(self.linenum, name))
+ # Detect invalid tags
+ elif invalid_match:
+ raise ValueError("Line %d: Invalid tag = '%s'" %
+ (self.linenum, line))
+
# Detect the start of a new commit
elif commit_match:
self._close_commit()