aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-mvebu/Kconfig23
-rw-r--r--arch/arm/mach-mvebu/Makefile13
-rw-r--r--arch/arm/mach-mvebu/cpu.c11
-rw-r--r--arch/arm/mach-mvebu/include/mach/cpu.h21
-rw-r--r--arch/arm/mach-mvebu/kwbimage.cfg.in5
-rw-r--r--arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c4
-rw-r--r--arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.h4
-rw-r--r--arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c14
-rw-r--r--arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h30
-rw-r--r--arch/arm/mach-mvebu/spl.c84
-rw-r--r--cmd/mvebu/Kconfig18
-rw-r--r--cmd/mvebu/bubt.c253
-rw-r--r--common/spl/Kconfig9
-rw-r--r--common/spl/spl_mmc.c12
-rw-r--r--configs/clearfog_sata_defconfig83
-rw-r--r--configs/db-88f6820-amc_nand_defconfig92
-rw-r--r--doc/kwboot.13
-rw-r--r--doc/mvebu/cmd/bubt.txt25
-rw-r--r--drivers/mtd/nand/raw/Kconfig4
-rw-r--r--tools/kwbimage.c297
-rw-r--r--tools/kwboot.c200
-rw-r--r--tools/mkimage.c11
22 files changed, 937 insertions, 279 deletions
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index 16c5e72..cdb1776 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -331,7 +331,7 @@ choice
depends on SPL
config MVEBU_SPL_BOOT_DEVICE_SPI
- bool "SPI NOR flash"
+ bool "NOR flash (SPI or parallel)"
imply ENV_IS_IN_SPI_FLASH
imply SPL_DM_SPI
imply SPL_SPI_FLASH_SUPPORT
@@ -339,8 +339,13 @@ config MVEBU_SPL_BOOT_DEVICE_SPI
imply SPL_SPI
select SPL_BOOTROM_SUPPORT
+config MVEBU_SPL_BOOT_DEVICE_NAND
+ bool "NAND flash (SPI or parallel)"
+ select MTD_RAW_NAND
+ select SPL_BOOTROM_SUPPORT
+
config MVEBU_SPL_BOOT_DEVICE_MMC
- bool "SDIO/MMC card"
+ bool "eMMC or SD card"
imply ENV_IS_IN_MMC
# GPIO needed for eMMC/SD card presence detection
imply SPL_DM_GPIO
@@ -348,6 +353,8 @@ config MVEBU_SPL_BOOT_DEVICE_MMC
imply SPL_GPIO
imply SPL_LIBDISK_SUPPORT
imply SPL_MMC
+ select SUPPORT_EMMC_BOOT if SPL_MMC
+ select SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR if SPL_MMC
select SPL_BOOTROM_SUPPORT
config MVEBU_SPL_BOOT_DEVICE_SATA
@@ -356,12 +363,24 @@ config MVEBU_SPL_BOOT_DEVICE_SATA
imply SPL_LIBDISK_SUPPORT
select SPL_BOOTROM_SUPPORT
+config MVEBU_SPL_BOOT_DEVICE_PEX
+ bool "PCI Express"
+ select SPL_BOOTROM_SUPPORT
+
config MVEBU_SPL_BOOT_DEVICE_UART
bool "UART"
select SPL_BOOTROM_SUPPORT
endchoice
+config MVEBU_SPL_NAND_BADBLK_LOCATION
+ hex "NAND Bad block indicator location"
+ depends on MVEBU_SPL_BOOT_DEVICE_NAND
+ range 0x0 0x1
+ help
+ Value 0x0 = SLC flash = BBI at page 0 or page 1
+ Value 0x1 = MLC flash = BBI at last page in the block
+
config MVEBU_EFUSE
bool "Enable eFuse support"
depends on HAVE_MVEBU_EFUSE
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
index a9f506c..90f8833 100644
--- a/arch/arm/mach-mvebu/Makefile
+++ b/arch/arm/mach-mvebu/Makefile
@@ -50,16 +50,29 @@ KWB_REPLACE += BOOT_FROM
ifneq ($(CONFIG_MVEBU_SPL_BOOT_DEVICE_SPI),)
KWB_CFG_BOOT_FROM=spi
endif
+ifneq ($(CONFIG_MVEBU_SPL_BOOT_DEVICE_NAND),)
+ KWB_CFG_BOOT_FROM=nand
+endif
ifneq ($(CONFIG_MVEBU_SPL_BOOT_DEVICE_MMC),)
KWB_CFG_BOOT_FROM=sdio
endif
ifneq ($(CONFIG_MVEBU_SPL_BOOT_DEVICE_SATA),)
KWB_CFG_BOOT_FROM=sata
endif
+ifneq ($(CONFIG_MVEBU_SPL_BOOT_DEVICE_PEX),)
+ KWB_CFG_BOOT_FROM=pex
+endif
ifneq ($(CONFIG_MVEBU_SPL_BOOT_DEVICE_UART),)
KWB_CFG_BOOT_FROM=uart
endif
+ifneq ($(CONFIG_MVEBU_SPL_BOOT_DEVICE_NAND),)
+KWB_REPLACE += NAND_PAGE_SIZE NAND_BLKSZ NAND_BADBLK_LOCATION
+KWB_CFG_NAND_PAGE_SIZE = $(CONFIG_SYS_NAND_PAGE_SIZE)
+KWB_CFG_NAND_BLKSZ = $(CONFIG_SYS_NAND_BLOCK_SIZE)
+KWB_CFG_NAND_BADBLK_LOCATION = $(CONFIG_MVEBU_SPL_NAND_BADBLK_LOCATION)
+endif
+
ifneq ($(CONFIG_SECURED_MODE_IMAGE),)
KWB_REPLACE += CSK_INDEX
KWB_CFG_CSK_INDEX = $(CONFIG_SECURED_MODE_CSK_INDEX)
diff --git a/arch/arm/mach-mvebu/cpu.c b/arch/arm/mach-mvebu/cpu.c
index 329d136..bbe167e 100644
--- a/arch/arm/mach-mvebu/cpu.c
+++ b/arch/arm/mach-mvebu/cpu.c
@@ -25,7 +25,7 @@ static const struct mbus_win windows[] = {
{ MBUS_SPI_BASE, MBUS_SPI_SIZE,
CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_SPIFLASH },
- /* NOR */
+ /* BootROM */
{ MBUS_BOOTROM_BASE, MBUS_BOOTROM_SIZE,
CPU_TARGET_DEVICEBUS_BOOTROM_SPI, CPU_ATTR_BOOTROM },
@@ -35,6 +35,15 @@ static const struct mbus_win windows[] = {
#endif
};
+/* SPI0 CS0 Flash of size MBUS_SPI_SIZE is mapped to address MBUS_SPI_BASE */
+#if CONFIG_ENV_SPI_BUS == 0 && CONFIG_ENV_SPI_CS == 0 && \
+ CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE <= MBUS_SPI_SIZE
+void *env_sf_get_env_addr(void)
+{
+ return (void *)MBUS_SPI_BASE + CONFIG_ENV_OFFSET;
+}
+#endif
+
void lowlevel_init(void)
{
/*
diff --git a/arch/arm/mach-mvebu/include/mach/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h
index c17c244..904e715 100644
--- a/arch/arm/mach-mvebu/include/mach/cpu.h
+++ b/arch/arm/mach-mvebu/include/mach/cpu.h
@@ -66,17 +66,38 @@ enum cpu_attrib {
/*
* Default Device Address MAP BAR values
*/
+#ifdef CONFIG_SPL_BUILD
+#ifdef CONFIG_ARMADA_38X
+#define MBUS_PCI_MEM_BASE 0x88000000
+#define MBUS_PCI_MEM_SIZE ((3 * 128) << 20)
+#else
+#define MBUS_PCI_MEM_BASE 0x80000000
+#define MBUS_PCI_MEM_SIZE ((4 * 128) << 20)
+#endif
+#else
#define MBUS_PCI_MAX_PORTS 6
#define MBUS_PCI_MEM_BASE MVEBU_SDRAM_SIZE_MAX
#define MBUS_PCI_MEM_SIZE ((MBUS_PCI_MAX_PORTS * 128) << 20)
#define MBUS_PCI_IO_BASE 0xF1100000
#define MBUS_PCI_IO_SIZE ((MBUS_PCI_MAX_PORTS * 64) << 10)
+#endif
+#ifdef CONFIG_SPL_BUILD
+#define MBUS_SPI_BASE 0xD4000000
+#define MBUS_SPI_SIZE (64 << 20)
+#else
#define MBUS_SPI_BASE 0xF4000000
#define MBUS_SPI_SIZE (8 << 20)
+#endif
+#ifndef CONFIG_SPL_BUILD
#define MBUS_DFX_BASE 0xF6000000
#define MBUS_DFX_SIZE (1 << 20)
+#endif
#define MBUS_BOOTROM_BASE 0xF8000000
+#ifdef CONFIG_SPL_BUILD
+#define MBUS_BOOTROM_SIZE (128 << 20)
+#else
#define MBUS_BOOTROM_SIZE (8 << 20)
+#endif
struct mbus_win {
u32 base;
diff --git a/arch/arm/mach-mvebu/kwbimage.cfg.in b/arch/arm/mach-mvebu/kwbimage.cfg.in
index ccb0997..90cf00c 100644
--- a/arch/arm/mach-mvebu/kwbimage.cfg.in
+++ b/arch/arm/mach-mvebu/kwbimage.cfg.in
@@ -11,6 +11,11 @@ VERSION 1
# Boot Media configurations
#@BOOT_FROM
+# NAND configuration
+#@NAND_PAGE_SIZE
+#@NAND_BLKSZ
+#@NAND_BADBLK_LOCATION
+
# Enable BootROM output via DEBUG flag on SoCs which require it
#@DEBUG
diff --git a/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c b/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c
index 943ae01..3349f4e 100644
--- a/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c
+++ b/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c
@@ -53,7 +53,7 @@ u8 serdes_lane_in_use_count[MAX_UNITS_ID][MAX_UNIT_NUMB] = {
*/
u8 serdes_unit_count[MAX_UNITS_ID] = { 0 };
-/* Selector mapping for A380-A0 and A390-Z1 */
+/* Selector mapping for A380-A0 */
u8 selectors_serdes_rev2_map[LAST_SERDES_TYPE][MAX_SERDES_LANES] = {
/* 0 1 2 3 4 5 6 */
{ 0x1, 0x1, NA, NA, NA, NA, NA }, /* PEX0 */
@@ -812,7 +812,7 @@ u8 hws_ctrl_serdes_rev_get(void)
if (sys_env_device_rev_get() == MV_88F68XX_Z1_ID)
return MV_SERDES_REV_1_2;
- /* for A39x-Z1, A38x-A0 */
+ /* for A38x-A0 */
return MV_SERDES_REV_2_1;
}
diff --git a/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.h b/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.h
index dd229e1..6925a9d 100644
--- a/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.h
+++ b/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.h
@@ -15,12 +15,12 @@
#define SET_BIT(data, bit) ((data) | (0x1 << (bit)))
#define CLEAR_BIT(data, bit) ((data) & (~(0x1 << (bit))))
-#define MAX_SERDES_LANES 7 /* as in a39x */
+#define MAX_SERDES_LANES 7
/* Serdes revision */
/* Serdes revision 1.2 (for A38x-Z1) */
#define MV_SERDES_REV_1_2 0x0
-/* Serdes revision 2.1 (for A39x-Z1, A38x-A0) */
+/* Serdes revision 2.1 (for A38x-A0) */
#define MV_SERDES_REV_2_1 0x1
#define MV_SERDES_REV_NA 0xff
diff --git a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c
index 950680a..fb8ec11 100644
--- a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c
+++ b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c
@@ -145,10 +145,6 @@ u32 sys_env_id_index_get(u32 ctrl_model)
return MV_6811_INDEX;
case MV_6828_DEV_ID:
return MV_6828_INDEX;
- case MV_6920_DEV_ID:
- return MV_6920_INDEX;
- case MV_6928_DEV_ID:
- return MV_6928_INDEX;
default:
return MV_6820_INDEX;
}
@@ -183,11 +179,9 @@ u16 sys_env_model_get(void)
case MV_6810_DEV_ID:
case MV_6811_DEV_ID:
case MV_6828_DEV_ID:
- case MV_6920_DEV_ID:
- case MV_6928_DEV_ID:
return ctrl_id;
default:
- /* Device ID Default for A38x: 6820 , for A39x: 6920 */
+ /* Device ID Default for A38x: 6820 */
default_ctrl_id = MV_6820_DEV_ID;
printf("%s: Error retrieving device ID (%x), using default ID = %x\n",
__func__, ctrl_id, default_ctrl_id);
@@ -201,8 +195,8 @@ u16 sys_env_model_get(void)
*/
u32 sys_env_device_id_get(void)
{
- char *device_id_str[7] = {
- "6810", "6820", "6811", "6828", "NONE", "6920", "6928"
+ char *device_id_str[4] = {
+ "6810", "6820", "6811", "6828",
};
if (g_dev_id != -1)
@@ -210,7 +204,7 @@ u32 sys_env_device_id_get(void)
g_dev_id = reg_read(DEVICE_SAMPLE_AT_RESET1_REG);
g_dev_id = g_dev_id >> SAR_DEV_ID_OFFS & SAR_DEV_ID_MASK;
- printf("Detected Device ID %s\n", device_id_str[g_dev_id]);
+ printf("Detected Device ID %s\n", g_dev_id < 4 ? device_id_str[g_dev_id] : "NONE");
return g_dev_id;
}
diff --git a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h
index 94c43b4..20039f7 100644
--- a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h
+++ b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h
@@ -198,22 +198,6 @@
#define A38X_MV_MARVELL_BOARD_NUM (A38X_MV_MAX_MARVELL_BOARD_ID - \
A38X_MARVELL_BOARD_ID_BASE)
-/* Customer boards for A39x */
-#define A39X_CUSTOMER_BOARD_ID_BASE 0x20
-#define A39X_CUSTOMER_BOARD_ID0 (A39X_CUSTOMER_BOARD_ID_BASE + 0)
-#define A39X_CUSTOMER_BOARD_ID1 (A39X_CUSTOMER_BOARD_ID_BASE + 1)
-#define A39X_MV_MAX_CUSTOMER_BOARD_ID (A39X_CUSTOMER_BOARD_ID_BASE + 2)
-#define A39X_MV_CUSTOMER_BOARD_NUM (A39X_MV_MAX_CUSTOMER_BOARD_ID - \
- A39X_CUSTOMER_BOARD_ID_BASE)
-
-/* Marvell boards for A39x */
-#define A39X_MARVELL_BOARD_ID_BASE 0x30
-#define A39X_DB_69XX_ID (A39X_MARVELL_BOARD_ID_BASE + 0)
-#define A39X_RD_69XX_ID (A39X_MARVELL_BOARD_ID_BASE + 1)
-#define A39X_MV_MAX_MARVELL_BOARD_ID (A39X_MARVELL_BOARD_ID_BASE + 2)
-#define A39X_MV_MARVELL_BOARD_NUM (A39X_MV_MAX_MARVELL_BOARD_ID - \
- A39X_MARVELL_BOARD_ID_BASE)
-
#define CUTOMER_BOARD_ID_BASE A38X_CUSTOMER_BOARD_ID_BASE
#define CUSTOMER_BOARD_ID0 A38X_CUSTOMER_BOARD_ID0
#define CUSTOMER_BOARD_ID1 A38X_CUSTOMER_BOARD_ID1
@@ -236,8 +220,6 @@
#define MV_88F68XX_Z1_ID 0x0
#define MV_88F68XX_A0_ID 0x4
#define MV_88F68XX_B0_ID 0xa
-/* A39x revisions */
-#define MV_88F69XX_Z1_ID 0x2
#define MPP_CONTROL_REG(id) (0x18000 + (id * 4))
#define GPP_DATA_OUT_REG(grp) (MV_GPP_REGS_BASE(grp) + 0x00)
@@ -257,19 +239,12 @@
#define MV_6811_DEV_ID 0x6811
#define MV_6820_DEV_ID 0x6820
#define MV_6828_DEV_ID 0x6828
-/* Armada 39x Family */
-#define MV_6920_DEV_ID 0x6920
-#define MV_6928_DEV_ID 0x6928
enum {
MV_6810,
MV_6820,
MV_6811,
MV_6828,
- MV_NONE,
- MV_6920,
- MV_6928,
- MV_MAX_DEV_ID,
};
#define MV_6820_INDEX 0
@@ -277,17 +252,12 @@ enum {
#define MV_6811_INDEX 2
#define MV_6828_INDEX 3
-#define MV_6920_INDEX 0
-#define MV_6928_INDEX 1
-
#define MAX_DEV_ID_NUM 4
#define MV_6820_INDEX 0
#define MV_6810_INDEX 1
#define MV_6811_INDEX 2
#define MV_6828_INDEX 3
-#define MV_6920_INDEX 0
-#define MV_6928_INDEX 1
enum unit_id {
PEX_UNIT_ID,
diff --git a/arch/arm/mach-mvebu/spl.c b/arch/arm/mach-mvebu/spl.c
index 4245992..6b8c72a 100644
--- a/arch/arm/mach-mvebu/spl.c
+++ b/arch/arm/mach-mvebu/spl.c
@@ -33,21 +33,44 @@
#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.
+ * When loading U-Boot via SPL from eMMC, the kwbimage main header is stored at
+ * sector 0 and either on HW boot partition or on data partition. Choice of HW
+ * partition depends on what is configured in eMMC EXT_CSC register.
+ * When loading U-Boot via SPL from SD card, the kwbimage main header is stored
+ * at sector 1.
+ * Therefore MBR/GPT partition booting, fixed sector number and fixed eMMC HW
+ * partition number are unsupported due to limitation of Marvell BootROM.
+ * Correct sector number must be determined as runtime in mvebu SPL code based
+ * on the detected boot source. Otherwise U-Boot SPL would not be able to load
+ * U-Boot proper.
+ * Runtime mvebu SPL sector calculation code expects:
+ * - CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET=0
+ * - CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0
*/
#ifdef CONFIG_SPL_MMC
+#ifdef CONFIG_SYS_MMCSD_FS_BOOT
+#error CONFIG_SYS_MMCSD_FS_BOOT is unsupported
+#endif
+#ifdef CONFIG_SYS_MMCSD_FS_BOOT_PARTITION
+#error CONFIG_SYS_MMCSD_FS_BOOT_PARTITION is unsupported
+#endif
+#ifdef CONFIG_SUPPORT_EMMC_BOOT_OVERRIDE_PART_CONFIG
+#error CONFIG_SUPPORT_EMMC_BOOT_OVERRIDE_PART_CONFIG is unsupported
+#endif
+#ifdef CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION
+#error CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION is unsupported
+#endif
#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
+#ifndef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
+#error CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR must be enabled for SD/eMMC boot support
+#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) && \
+#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
@@ -98,7 +121,12 @@ struct kwbimage_main_hdr_v1 {
#ifdef CONFIG_SPL_MMC
u32 spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
{
- return MMCSD_MODE_RAW;
+ return IS_SD(mmc) ? MMCSD_MODE_RAW : MMCSD_MODE_EMMCBOOT;
+}
+unsigned long spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
+ unsigned long raw_sect)
+{
+ return IS_SD(mmc) ? 1 : 0;
}
#endif
@@ -169,9 +197,7 @@ int spl_parse_board_header(struct spl_image_info *spl_image,
}
if (IS_ENABLED(CONFIG_SPL_MMC) &&
- (bootdev->boot_device == BOOT_DEVICE_MMC1 ||
- bootdev->boot_device == BOOT_DEVICE_MMC2 ||
- bootdev->boot_device == BOOT_DEVICE_MMC2_2) &&
+ (bootdev->boot_device == BOOT_DEVICE_MMC1) &&
mhdr->blockid != IBR_HDR_SDIO_ID) {
printf("ERROR: Wrong blockid (0x%x) in SDIO kwbimage\n",
mhdr->blockid);
@@ -182,26 +208,9 @@ int spl_parse_board_header(struct spl_image_info *spl_image,
/*
* 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 (IS_ENABLED(CONFIG_SPL_SATA) && mhdr->blockid == IBR_HDR_SATA_ID) {
- if (spl_image->offset < 1) {
- printf("ERROR: Wrong srcaddr (0x%08x) in SATA kwbimage\n",
- spl_image->offset);
- return -EINVAL;
- }
- spl_image->offset -= 1;
- spl_image->offset *= 512;
- }
-
- /*
- * For SDIO (eMMC) srcaddr is specified in number of sectors.
- * This expects that sector size is 512 bytes and recalculates
- * data offset to bytes.
+ * This expects that sector size is 512 bytes.
*/
- if (IS_ENABLED(CONFIG_SPL_MMC) && mhdr->blockid == IBR_HDR_SDIO_ID)
+ if (IS_ENABLED(CONFIG_SPL_SATA) && mhdr->blockid == IBR_HDR_SATA_ID)
spl_image->offset *= 512;
if (spl_image->offset % 4 != 0) {
@@ -299,19 +308,6 @@ int board_return_to_bootrom(struct spl_image_info *spl_image,
hang();
}
-/*
- * SPI0 CS0 Flash is mapped to address range 0xD4000000 - 0xD7FFFFFF by BootROM.
- * Proper U-Boot removes this direct mapping. So it is available only in SPL.
- */
-#if defined(CONFIG_SPL_ENV_IS_IN_SPI_FLASH) && \
- CONFIG_ENV_SPI_BUS == 0 && CONFIG_ENV_SPI_CS == 0 && \
- CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE <= 64*1024*1024
-void *env_sf_get_env_addr(void)
-{
- return (void *)0xD4000000 + CONFIG_ENV_OFFSET;
-}
-#endif
-
void board_init_f(ulong dummy)
{
int ret;
diff --git a/cmd/mvebu/Kconfig b/cmd/mvebu/Kconfig
index 9ec3aa9..e83a982 100644
--- a/cmd/mvebu/Kconfig
+++ b/cmd/mvebu/Kconfig
@@ -3,8 +3,12 @@ depends on ARCH_MVEBU
config CMD_MVEBU_BUBT
bool "bubt"
+ default y
select SHA256 if ARMADA_3700
select SHA512 if ARMADA_3700
+ select DOS_PARTITION if ARMADA_3700
+ select EFI_PARTITION if ARMADA_3700
+ select PARTITION_TYPE_GUID if ARMADA_3700
select MVEBU_EFUSE if ARMADA_38X || ARMADA_3700
help
bubt - Burn a u-boot image to flash
@@ -15,6 +19,10 @@ if CMD_MVEBU_BUBT
choice
prompt "Flash for image"
+ default MVEBU_SPI_BOOT if MVEBU_SPL_BOOT_DEVICE_SPI
+ default MVEBU_NAND_BOOT if MVEBU_SPL_BOOT_DEVICE_NAND
+ default MVEBU_MMC_BOOT if MVEBU_SPL_BOOT_DEVICE_MMC
+ default MVEBU_SATA_BOOT if MVEBU_SPL_BOOT_DEVICE_SATA
default MVEBU_SPI_BOOT
config MVEBU_NAND_BOOT
@@ -44,10 +52,20 @@ config MVEBU_MMC_BOOT
For details about bubt command please see the documentation
in doc/mvebu/cmd/bubt.txt
+config MVEBU_SATA_BOOT
+ bool "SATA flash boot"
+ depends on SCSI
+ help
+ Enable boot from SATA disk.
+ Allow usage of SATA disk as a target for "bubt" command
+ For details about bubt command please see the documentation
+ in doc/mvebu/cmd/bubt.txt
+
endchoice
config MVEBU_UBOOT_DFLT_NAME
string "Default image name for bubt command"
+ default BUILD_TARGET if ARMADA_32BIT && BUILD_TARGET != ""
default "flash-image.bin"
help
This option should contain a default file name to be used with
diff --git a/cmd/mvebu/bubt.c b/cmd/mvebu/bubt.c
index 1efbe2e..49797b2 100644
--- a/cmd/mvebu/bubt.c
+++ b/cmd/mvebu/bubt.c
@@ -19,6 +19,7 @@
#include <spi_flash.h>
#include <spi.h>
#include <nand.h>
+#include <scsi.h>
#include <usb.h>
#include <fs.h>
#include <mmc.h>
@@ -189,6 +190,11 @@ static int mmc_burn_image(size_t image_size)
#ifdef CONFIG_BLK
struct blk_desc *blk_desc;
#endif
+#ifdef CONFIG_SUPPORT_EMMC_BOOT
+ u8 part;
+ u8 orig_part;
+#endif
+
mmc = find_mmc_device(mmc_dev_num);
if (!mmc) {
printf("No SD/MMC/eMMC card found\n");
@@ -202,6 +208,38 @@ static int mmc_burn_image(size_t image_size)
return err;
}
+#ifdef CONFIG_BLK
+ blk_desc = mmc_get_blk_desc(mmc);
+ if (!blk_desc) {
+ printf("Error - failed to obtain block descriptor\n");
+ return -ENODEV;
+ }
+#endif
+
+#ifdef CONFIG_SUPPORT_EMMC_BOOT
+#ifdef CONFIG_BLK
+ orig_part = blk_desc->hwpart;
+#else
+ orig_part = mmc->block_dev.hwpart;
+#endif
+
+ part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
+
+ if (part == 7)
+ part = 0;
+
+#ifdef CONFIG_BLK
+ err = blk_dselect_hwpart(blk_desc, part);
+#else
+ err = mmc_switch_part(mmc, part);
+#endif
+
+ if (err) {
+ printf("Error - MMC partition switch failed\n");
+ return err;
+ }
+#endif
+
/* SD reserves LBA-0 for MBR and boots from LBA-1,
* MMC/eMMC boots from LBA-0
*/
@@ -211,11 +249,6 @@ static int mmc_burn_image(size_t image_size)
if (image_size % mmc->write_bl_len)
blk_count += 1;
- blk_desc = mmc_get_blk_desc(mmc);
- if (!blk_desc) {
- printf("Error - failed to obtain block descriptor\n");
- return -ENODEV;
- }
blk_written = blk_dwrite(blk_desc, start_lba, blk_count,
(void *)get_load_addr());
#else
@@ -227,6 +260,17 @@ static int mmc_burn_image(size_t image_size)
start_lba, blk_count,
(void *)get_load_addr());
#endif /* CONFIG_BLK */
+
+#ifdef CONFIG_SUPPORT_EMMC_BOOT
+#ifdef CONFIG_BLK
+ err = blk_dselect_hwpart(blk_desc, orig_part);
+#else
+ err = mmc_switch_part(mmc, orig_part);
+#endif
+ if (err)
+ printf("Error - MMC failed to switch back to original partition\n");
+#endif
+
if (blk_written != blk_count) {
printf("Error - written %#lx blocks\n", blk_written);
return -ENOSPC;
@@ -291,6 +335,143 @@ static int is_mmc_active(void)
#endif /* CONFIG_DM_MMC */
/********************************************************************
+ * SATA services
+ ********************************************************************/
+#if defined(CONFIG_SCSI) && defined(CONFIG_BLK)
+static int sata_burn_image(size_t image_size)
+{
+#if defined(CONFIG_ARMADA_3700) || defined(CONFIG_ARMADA_32BIT)
+ lbaint_t start_lba;
+ lbaint_t blk_count;
+ ulong blk_written;
+ struct blk_desc *blk_desc;
+#ifdef CONFIG_ARMADA_3700
+ struct disk_partition info;
+ int part;
+#endif
+
+ scsi_scan(false);
+
+ blk_desc = blk_get_devnum_by_uclass_id(UCLASS_SCSI, 0);
+ if (!blk_desc)
+ return -ENODEV;
+
+#ifdef CONFIG_ARMADA_3700
+ /*
+ * 64-bit Armada 3700 BootROM loads SATA firmware from
+ * GPT 'Marvell Armada 3700 Boot partition' or from
+ * MBR 'M' (0x4d) partition.
+ */
+ switch (blk_desc->part_type) {
+ case PART_TYPE_DOS:
+ for (part = 1; part <= 4; part++) {
+ info.sys_ind = 0;
+ if (part_get_info(blk_desc, part, &info))
+ continue;
+ if (info.sys_ind == 'M')
+ break;
+ }
+ if (part > 4) {
+ printf("Error - cannot find MBR 'M' (0x4d) partition on SATA disk\n");
+ return -ENODEV;
+ }
+ start_lba = info.start;
+ break;
+ case PART_TYPE_EFI:
+ for (part = 1; part <= 64; part++) {
+ info.type_guid[0] = 0;
+ if (part_get_info(blk_desc, part, &info))
+ continue;
+ /* Check for GPT type GUID of 'Marvell Armada 3700 Boot partition' */
+ if (strcmp(info.type_guid, "6828311A-BA55-42A4-BCDE-A89BB5EDECAE") == 0)
+ break;
+ }
+ if (part > 64) {
+ printf("Error - cannot find GPT 'Marvell Armada 3700 Boot partition' on SATA disk\n");
+ return -ENODEV;
+ }
+ start_lba = info.start;
+ break;
+ default:
+ printf("Error - no partitions on SATA disk\n");
+ return -ENODEV;
+ }
+#else
+ /* 32-bit Armada BootROM loads SATA firmware from the sector 1. */
+ start_lba = 1;
+#endif
+
+ blk_count = image_size / blk_desc->blksz;
+ if (image_size % blk_desc->blksz)
+ blk_count += 1;
+
+ blk_written = blk_dwrite(blk_desc, start_lba, blk_count,
+ (void *)get_load_addr());
+
+ if (blk_written != blk_count) {
+ printf("Error - written %#lx blocks\n", blk_written);
+ return -ENOSPC;
+ }
+
+ printf("Done!\n");
+ return 0;
+#else
+ return -ENODEV;
+#endif
+}
+
+static size_t sata_read_file(const char *file_name)
+{
+ loff_t act_read = 0;
+ struct udevice *dev;
+ int rc;
+
+ /* try to recognize storage devices immediately */
+ scsi_scan(false);
+
+ /* Try to recognize storage devices immediately */
+ blk_first_device(UCLASS_SCSI, &dev);
+ if (!dev) {
+ printf("Error: SATA device not found\n");
+ return 0;
+ }
+
+ /* Always load from scsi 0 */
+ if (fs_set_blk_dev("scsi", "0", FS_TYPE_ANY)) {
+ printf("Error: SATA 0 not found\n");
+ return 0;
+ }
+
+ /* Perfrom file read */
+ rc = fs_read(file_name, get_load_addr(), 0, 0, &act_read);
+ if (rc)
+ return 0;
+
+ return act_read;
+}
+
+static int is_sata_active(void)
+{
+ return 1;
+}
+#else /* CONFIG_SCSI */
+static int sata_burn_image(size_t image_size)
+{
+ return -ENODEV;
+}
+
+static size_t sata_read_file(const char *file_name)
+{
+ return 0;
+}
+
+static int is_sata_active(void)
+{
+ return 0;
+}
+#endif /* CONFIG_SCSI */
+
+/********************************************************************
* SPI services
********************************************************************/
#ifdef CONFIG_SPI_FLASH
@@ -499,16 +680,18 @@ enum bubt_devices {
BUBT_DEV_NET = 0,
BUBT_DEV_USB,
BUBT_DEV_MMC,
+ BUBT_DEV_SATA,
BUBT_DEV_SPI,
BUBT_DEV_NAND,
BUBT_MAX_DEV
};
-struct bubt_dev bubt_devs[BUBT_MAX_DEV] = {
+static struct bubt_dev bubt_devs[BUBT_MAX_DEV] = {
{"tftp", tftp_read_file, NULL, is_tftp_active},
{"usb", usb_read_file, NULL, is_usb_active},
{"mmc", mmc_read_file, mmc_burn_image, is_mmc_active},
+ {"sata", sata_read_file, sata_burn_image, is_sata_active},
{"spi", NULL, spi_burn_image, is_spi_active},
{"nand", NULL, nand_burn_image, is_nand_active},
};
@@ -524,7 +707,7 @@ static int bubt_write_file(struct bubt_dev *dst, size_t image_size)
}
#if defined(CONFIG_ARMADA_8K)
-u32 do_checksum32(u32 *start, int32_t len)
+static u32 do_checksum32(u32 *start, int32_t len)
{
u32 sum = 0;
u32 *startp = start;
@@ -542,9 +725,8 @@ static int check_image_header(void)
{
struct mvebu_image_header *hdr =
(struct mvebu_image_header *)get_load_addr();
- u32 header_len = hdr->prolog_size;
u32 checksum;
- u32 checksum_ref = hdr->prolog_checksum;
+ u32 checksum_ref;
/*
* For now compare checksum, and magic. Later we can
@@ -556,18 +738,23 @@ static int check_image_header(void)
return -ENOEXEC;
}
- /* The checksum value is discarded from checksum calculation */
- hdr->prolog_checksum = 0;
+ checksum_ref = hdr->prolog_checksum;
+ checksum = do_checksum32((u32 *)hdr, hdr->prolog_size);
+ checksum -= hdr->prolog_checksum;
+ if (checksum != checksum_ref) {
+ printf("Error: Bad Prolog checksum. 0x%x != 0x%x\n",
+ checksum, checksum_ref);
+ return -ENOEXEC;
+ }
- checksum = do_checksum32((u32 *)hdr, header_len);
+ checksum_ref = hdr->boot_image_checksum;
+ checksum = do_checksum32((u32 *)((u8 *)hdr + hdr->prolog_size), hdr->boot_image_size);
if (checksum != checksum_ref) {
printf("Error: Bad Image checksum. 0x%x != 0x%x\n",
checksum, checksum_ref);
return -ENOEXEC;
}
- /* Restore the checksum before writing */
- hdr->prolog_checksum = checksum_ref;
printf("Image checksum...OK!\n");
return 0;
@@ -722,12 +909,12 @@ static int check_image_header(void)
u32 offset, size;
const struct a38x_main_hdr_v1 *hdr =
(struct a38x_main_hdr_v1 *)get_load_addr();
- const size_t image_size = a38x_header_size(hdr);
+ const size_t hdr_size = a38x_header_size(hdr);
- if (!image_size)
+ if (!hdr_size)
return -ENOEXEC;
- checksum = image_checksum8(hdr, image_size);
+ checksum = image_checksum8(hdr, hdr_size);
checksum -= hdr->checksum;
if (checksum != hdr->checksum) {
printf("Error: Bad A38x image header checksum. 0x%x != 0x%x\n",
@@ -738,16 +925,7 @@ static int check_image_header(void)
offset = le32_to_cpu(hdr->srcaddr);
size = le32_to_cpu(hdr->blocksize);
- if (hdr->blockid == 0x78) { /* SATA id */
- if (offset < 1) {
- printf("Error: Bad A38x image srcaddr.\n");
- return -ENOEXEC;
- }
- offset -= 1;
- offset *= 512;
- }
-
- if (hdr->blockid == 0xAE) /* SDIO id */
+ if (hdr->blockid == 0x78) /* SATA id */
offset *= 512;
if (offset % 4 != 0 || size < 4 || size % 4 != 0) {
@@ -770,7 +948,7 @@ static int check_image_header(void)
#if defined(CONFIG_ARMADA_38X)
static int a38x_image_is_secure(const struct a38x_main_hdr_v1 *hdr)
{
- u32 image_size = a38x_header_size(hdr);
+ const size_t hdr_size = a38x_header_size(hdr);
struct a38x_opt_hdr_v1 *ohdr;
u32 ohdr_size;
@@ -791,7 +969,7 @@ static int a38x_image_is_secure(const struct a38x_main_hdr_v1 *hdr)
break;
ohdr = (struct a38x_opt_hdr_v1 *)((u8 *)ohdr + ohdr_size);
- if ((u8 *)ohdr >= (u8 *)hdr + image_size)
+ if ((u8 *)ohdr >= (u8 *)hdr + hdr_size)
break;
} while (1);
@@ -806,7 +984,7 @@ static int check_image_header(void)
}
#endif
-#if defined(CONFIG_ARMADA_3700) || defined(CONFIG_ARMADA_32BIT)
+#if defined(CONFIG_ARMADA_3700) || defined(CONFIG_ARMADA_38X)
static u64 fuse_read_u64(u32 bank)
{
u32 val[2];
@@ -835,7 +1013,10 @@ static inline u8 maj3(u8 val)
static int bubt_check_boot_mode(const struct bubt_dev *dst)
{
#if defined(CONFIG_ARMADA_3700) || defined(CONFIG_ARMADA_32BIT)
- int mode, secure_mode;
+ int mode;
+#if defined(CONFIG_ARMADA_3700) || defined(CONFIG_ARMADA_38X)
+ int secure_mode;
+#endif
#if defined(CONFIG_ARMADA_3700)
const struct tim_boot_flash_sign *boot_modes = tim_boot_flash_signs;
const struct common_tim_data *hdr =
@@ -966,7 +1147,7 @@ static int bubt_is_dev_active(struct bubt_dev *dev)
return 1;
}
-struct bubt_dev *find_bubt_dev(char *dev_name)
+static struct bubt_dev *find_bubt_dev(char *dev_name)
{
int dev;
@@ -987,12 +1168,14 @@ struct bubt_dev *find_bubt_dev(char *dev_name)
#define DEFAULT_BUBT_DST "nand"
#elif defined(CONFIG_MVEBU_MMC_BOOT)
#define DEFAULT_BUBT_DST "mmc"
+#elif defined(CONFIG_MVEBU_SATA_BOOT)
+#define DEFAULT_BUBT_DST "sata"
#else
#define DEFAULT_BUBT_DST "error"
#endif
#endif /* DEFAULT_BUBT_DST */
-int do_bubt_cmd(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
+static int do_bubt_cmd(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
struct bubt_dev *src, *dst;
size_t image_size;
@@ -1064,8 +1247,8 @@ U_BOOT_CMD(
"Burn a u-boot image to flash",
"[file-name] [destination [source]]\n"
"\t-file-name The image file name to burn. Default = " CONFIG_MVEBU_UBOOT_DFLT_NAME "\n"
- "\t-destination Flash to burn to [spi, nand, mmc]. Default = " DEFAULT_BUBT_DST "\n"
- "\t-source The source to load image from [tftp, usb, mmc]. Default = " DEFAULT_BUBT_SRC "\n"
+ "\t-destination Flash to burn to [spi, nand, mmc, sata]. Default = " DEFAULT_BUBT_DST "\n"
+ "\t-source The source to load image from [tftp, usb, mmc, sata]. Default = " DEFAULT_BUBT_SRC "\n"
"Examples:\n"
"\tbubt - Burn flash-image.bin from tftp to active boot device\n"
"\tbubt flash-image-new.bin nand - Burn flash-image-new.bin from tftp to NAND flash\n"
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 3c2af45..2c042ad 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -816,8 +816,17 @@ config SPL_MMC
this option to build the drivers in drivers/mmc as part of an SPL
build.
+config SYS_MMCSD_FS_BOOT
+ bool "MMC FS Boot mode"
+ depends on SPL_MMC
+ default y if !ARCH_MVEBU
+ help
+ Enable MMC FS Boot mode. Partition is selected by option
+ SYS_MMCSD_FS_BOOT_PARTITION.
+
config SYS_MMCSD_FS_BOOT_PARTITION
int "MMC Boot Partition"
+ depends on SYS_MMCSD_FS_BOOT
default 1
help
Partition on the MMC to load U-Boot from when the MMC is being
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index e4135b2..bd5e6ad 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -272,7 +272,7 @@ int spl_start_uboot(void)
}
#endif
-#ifdef CONFIG_SYS_MMCSD_FS_BOOT_PARTITION
+#ifdef CONFIG_SYS_MMCSD_FS_BOOT
static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image,
struct spl_boot_device *bootdev,
struct mmc *mmc,
@@ -341,14 +341,6 @@ static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image,
return err;
}
-#else
-static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image,
- struct spl_boot_device *bootdev,
- struct mmc *mmc,
- const char *filename)
-{
- return -ENOSYS;
-}
#endif
u32 __weak spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
@@ -481,6 +473,7 @@ int spl_mmc_load(struct spl_image_info *spl_image,
return err;
#endif
/* If RAW mode fails, try FS mode. */
+#ifdef CONFIG_SYS_MMCSD_FS_BOOT
case MMCSD_MODE_FS:
debug("spl: mmc boot mode: fs\n");
@@ -489,6 +482,7 @@ int spl_mmc_load(struct spl_image_info *spl_image,
return err;
break;
+#endif
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
default:
puts("spl: mmc: wrong boot mode\n");
diff --git a/configs/clearfog_sata_defconfig b/configs/clearfog_sata_defconfig
new file mode 100644
index 0000000..e9b3615
--- /dev/null
+++ b/configs/clearfog_sata_defconfig
@@ -0,0 +1,83 @@
+CONFIG_ARM=y
+CONFIG_ARCH_CPU_INIT=y
+CONFIG_SYS_THUMB_BUILD=y
+CONFIG_ARCH_MVEBU=y
+CONFIG_TEXT_BASE=0x00800000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_TARGET_CLEARFOG=y
+CONFIG_MVEBU_SPL_BOOT_DEVICE_SATA=y
+CONFIG_DEFAULT_DEVICE_TREE="armada-388-clearfog"
+CONFIG_SPL_TEXT_BASE=0x40000030
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL=y
+CONFIG_DEBUG_UART_BASE=0xf1012000
+CONFIG_DEBUG_UART_CLOCK=250000000
+CONFIG_SYS_LOAD_ADDR=0x800000
+CONFIG_DEBUG_UART=y
+CONFIG_AHCI=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xff0000
+CONFIG_BOOTDELAY=3
+CONFIG_USE_PREBOOT=y
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_SPL_MAX_SIZE=0x22fd0
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x40023000
+CONFIG_SPL_BSS_MAX_SIZE=0x4000
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_STACK=0x4002c000
+CONFIG_SPL_I2C=y
+CONFIG_SYS_MAXARGS=32
+CONFIG_CMD_TLV_EEPROM=y
+CONFIG_SPL_CMD_TLV_EEPROM=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PCI=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_TFTPPUT=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_MVEBU_BUBT=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_MIN_ENTRIES=128
+CONFIG_ARP_TIMEOUT=200
+CONFIG_NET_RETRY_COUNT=50
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SPL_OF_TRANSLATE=y
+CONFIG_AHCI_MVEBU=y
+CONFIG_DM_PCA953X=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_MVTWSI=y
+CONFIG_I2C_EEPROM=y
+CONFIG_SPL_I2C_EEPROM=y
+CONFIG_SUPPORT_EMMC_BOOT=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SDMA=y
+CONFIG_MMC_SDHCI_MV=y
+CONFIG_MTD=y
+CONFIG_SF_DEFAULT_BUS=1
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_PHY_MARVELL=y
+CONFIG_PHY_GIGE=y
+CONFIG_MVNETA=y
+CONFIG_MII=y
+CONFIG_MVMDIO=y
+CONFIG_PCI=y
+CONFIG_PCI_MVEBU=y
+CONFIG_SCSI=y
+CONFIG_SPL_DEBUG_UART_BASE=0xd0012000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550=y
+CONFIG_KIRKWOOD_SPI=y
+CONFIG_USB=y
+CONFIG_USB_XHCI_HCD=y
diff --git a/configs/db-88f6820-amc_nand_defconfig b/configs/db-88f6820-amc_nand_defconfig
new file mode 100644
index 0000000..e784c34
--- /dev/null
+++ b/configs/db-88f6820-amc_nand_defconfig
@@ -0,0 +1,92 @@
+CONFIG_ARM=y
+CONFIG_ARCH_CPU_INIT=y
+CONFIG_ARCH_MVEBU=y
+CONFIG_TEXT_BASE=0x00800000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_TARGET_DB_88F6820_AMC=y
+CONFIG_MVEBU_SPL_BOOT_DEVICE_NAND=y
+CONFIG_MVEBU_SPL_NAND_BADBLK_LOCATION=0x00
+CONFIG_ENV_SIZE=0x10000
+CONFIG_ENV_OFFSET=0x100000
+CONFIG_ENV_SECT_SIZE=0x40000
+CONFIG_DEFAULT_DEVICE_TREE="armada-385-db-88f6820-amc"
+CONFIG_SPL_TEXT_BASE=0x40000030
+CONFIG_SPL_SERIAL=y
+CONFIG_SPL=y
+CONFIG_DEBUG_UART_BASE=0xf1012000
+CONFIG_DEBUG_UART_CLOCK=200000000
+CONFIG_SYS_LOAD_ADDR=0x800000
+CONFIG_DEBUG_UART=y
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0xff0000
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_BOOTDELAY=3
+CONFIG_USE_PREBOOT=y
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_SPL_MAX_SIZE=0x22fd0
+CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
+CONFIG_SPL_BSS_START_ADDR=0x40023000
+CONFIG_SPL_BSS_MAX_SIZE=0x4000
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_STACK=0x4002c000
+CONFIG_SPL_I2C=y
+CONFIG_SYS_MAXARGS=96
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_I2C=y
+CONFIG_CMD_PCI=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_TFTPPUT=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CACHE=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_EXT2=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_EFI_PARTITION=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_ENV_SPI_MAX_HZ=50000000
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_ARP_TIMEOUT=200
+CONFIG_NET_RETRY_COUNT=50
+CONFIG_SPL_OF_TRANSLATE=y
+# CONFIG_SPL_BLK is not set
+# CONFIG_BLOCK_CACHE is not set
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_MVTWSI=y
+# CONFIG_MMC is not set
+CONFIG_MTD=y
+CONFIG_SYS_NAND_USE_FLASH_BBT=y
+CONFIG_NAND_PXA3XX=y
+CONFIG_SYS_NAND_BLOCK_SIZE=0x40000
+CONFIG_SYS_NAND_ONFI_DETECTION=y
+CONFIG_SYS_NAND_PAGE_SIZE=0x1000
+CONFIG_SF_DEFAULT_BUS=1
+CONFIG_SPI_FLASH_BAR=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_PHY_MARVELL=y
+CONFIG_PHY_GIGE=y
+CONFIG_MVNETA=y
+CONFIG_MII=y
+CONFIG_MVMDIO=y
+CONFIG_PCI=y
+CONFIG_PCI_MVEBU=y
+CONFIG_SPL_DEBUG_UART_BASE=0xd0012000
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550=y
+CONFIG_KIRKWOOD_SPI=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_STORAGE=y
diff --git a/doc/kwboot.1 b/doc/kwboot.1
index a528fbb..5cda3b4 100644
--- a/doc/kwboot.1
+++ b/doc/kwboot.1
@@ -159,7 +159,8 @@ program:
Instruct BootROM to enter boot Xmodem boot mode, send header of
\fIu-boot-with-spl.kwb\fP kwbimage file via Xmodem at 115200 Bd, then instruct
BootROM to change baudrate to 5200000 Bd, send data part of the kwbimage
-file via Xmodem at high speed and finally run terminal program:
+file via Xmodem at high speed, then change baudrate back to 115200 Bd,
+and finally run terminal program:
.IP
.B kwboot -b u-boot-with-spl.kwb -B 5200000 -t /dev/ttyUSB0
diff --git a/doc/mvebu/cmd/bubt.txt b/doc/mvebu/cmd/bubt.txt
index 6051243..52bd3e6 100644
--- a/doc/mvebu/cmd/bubt.txt
+++ b/doc/mvebu/cmd/bubt.txt
@@ -5,8 +5,8 @@ Bubt command is used to burn a new ATF image to flash device.
The bubt command gets the following parameters: ATF file name, destination device and source device.
bubt [file-name] [destination [source]]
- file-name Image file name to burn. default = flash-image.bin
- - destination Flash to burn to [spi, nand, mmc]. default = active flash
- - source Source to load image from [tftp, usb]. default = tftp
+ - destination Flash to burn to [spi, nand, mmc, sata]. default = active flash
+ - source Source to load image from [tftp, usb, mmc, sata]. default = tftp
Examples:
bubt - Burn flash-image.bin from tftp to active flash
@@ -14,8 +14,7 @@ Examples:
Notes:
- For the TFTP interface set serverip and ipaddr.
-- To burn image to SD/eMMC device, the target is defined
- by parameters CONFIG_SYS_MMC_ENV_DEV and CONFIG_SYS_MMC_ENV_PART.
+- To burn image to SD/eMMC device, the target is defined by HW partition.
Bubt command details (burn image step by-step)
----------------------------------------------
@@ -40,10 +39,20 @@ Notes:
Number 0 is used for user data partition and should not be utilized for storing
boot images and U-Boot environment in RAW mode since it will break file system
structures usually located here.
- The default boot partition is BOOT0. It is selected by the following parameter:
- CONFIG_SYS_MMC_ENV_PART=1
- Valid values for this parameter are 1 for BOOT0 and 2 for BOOT1.
- Please never use partition number 0 here!
+
+ Currently configured boot partition can be printed by command:
+ # mmc partconf 0
+ (search for BOOT_PARTITION_ACCESS output, number 7 is user data)
+
+ Change it to BOOT0:
+ # mmc partconf 0 0 1 1
+
+ Change it to BOOT1:
+ # mmc partconf 0 0 2 2
+
+ Change it to user data:
+ # mmc partconf 0 0 7 0
+
- The partition number is ignored if the target device is SD card.
- The boot image offset starts at block 0 for eMMC and block 1 for SD devices.
The block 0 on SD devices is left for MBR storage.
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 5b35da4..5c7b0d9 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -628,7 +628,8 @@ comment "Generic NAND options"
config SYS_NAND_BLOCK_SIZE
hex "NAND chip eraseblock size"
- depends on ARCH_SUNXI || SPL_NAND_SUPPORT || TPL_NAND_SUPPORT
+ depends on ARCH_SUNXI || SPL_NAND_SUPPORT || TPL_NAND_SUPPORT || \
+ MVEBU_SPL_BOOT_DEVICE_NAND
depends on !NAND_MXS && !NAND_DENALI_DT && !NAND_LPC32XX_MLC && \
!NAND_FSL_IFC && !NAND_MT7621
help
@@ -655,6 +656,7 @@ config SYS_NAND_PAGE_SIZE
hex "NAND chip page size"
depends on ARCH_SUNXI || NAND_OMAP_GPMC || NAND_LPC32XX_SLC || \
SPL_NAND_SIMPLE || (NAND_MXC && SPL_NAND_SUPPORT) || \
+ MVEBU_SPL_BOOT_DEVICE_NAND || \
(NAND_ATMEL && SPL_NAND_SUPPORT) || SPL_GENERATE_ATMEL_PMECC_HEADER
depends on !NAND_MXS && !NAND_DENALI_DT && !NAND_LPC32XX_MLC && !NAND_MT7621
help
diff --git a/tools/kwbimage.c b/tools/kwbimage.c
index 6abb9f2..309657a 100644
--- a/tools/kwbimage.c
+++ b/tools/kwbimage.c
@@ -927,6 +927,71 @@ done:
return ret;
}
+static int image_fill_xip_header(void *image, struct image_tool_params *params)
+{
+ struct main_hdr_v1 *main_hdr = image; /* kwbimage v0 and v1 have same XIP members */
+ int version = kwbimage_version(image);
+ uint32_t srcaddr = le32_to_cpu(main_hdr->srcaddr);
+ uint32_t startaddr = 0;
+
+ if (main_hdr->blockid != IBR_HDR_SPI_ID) {
+ fprintf(stderr, "XIP is supported only for SPI images\n");
+ return 0;
+ }
+
+ if (version == 0 &&
+ params->addr >= 0xE8000000 && params->addr < 0xEFFFFFFF &&
+ params->ep >= 0xE8000000 && params->ep < 0xEFFFFFFF) {
+ /* Load and Execute address is in SPI address space (kwbimage v0) */
+ startaddr = 0xE8000000;
+ } else if (version != 0 &&
+ params->addr >= 0xD4000000 && params->addr < 0xD7FFFFFF &&
+ params->ep >= 0xD4000000 && params->ep < 0xD7FFFFFF) {
+ /* Load and Execute address is in SPI address space (kwbimage v1) */
+ startaddr = 0xD4000000;
+ } else if (version != 0 &&
+ params->addr >= 0xD8000000 && params->addr < 0xDFFFFFFF &&
+ params->ep >= 0xD8000000 && params->ep < 0xDFFFFFFF) {
+ /* Load and Execute address is in Device bus space (kwbimage v1) */
+ startaddr = 0xD8000000;
+ } else if (params->addr != 0x0) {
+ /* Load address is non-zero */
+ if (version == 0)
+ fprintf(stderr, "XIP Load Address or XIP Entry Point is not in SPI address space\n");
+ else
+ fprintf(stderr, "XIP Load Address or XIP Entry Point is not in SPI nor in Device bus address space\n");
+ return 0;
+ }
+
+ /*
+ * For XIP destaddr must be set to 0xFFFFFFFF and
+ * execaddr relative to the start of XIP memory address space.
+ */
+ main_hdr->destaddr = cpu_to_le32(0xFFFFFFFF);
+
+ if (startaddr == 0) {
+ /*
+ * mkimage's --load-address 0x0 means that binary is Position
+ * Independent and in this case mkimage's --entry-point address
+ * is relative offset from beginning of the data part of image.
+ */
+ main_hdr->execaddr = cpu_to_le32(srcaddr + params->ep);
+ } else {
+ /* The lowest possible load address is after the header at srcaddr. */
+ if (params->addr - startaddr < srcaddr) {
+ fprintf(stderr,
+ "Invalid XIP Load Address 0x%08x.\n"
+ "The lowest address for this configuration is 0x%08x.\n",
+ params->addr, (unsigned)(startaddr + srcaddr));
+ return 0;
+ }
+ main_hdr->srcaddr = cpu_to_le32(params->addr - startaddr);
+ main_hdr->execaddr = cpu_to_le32(params->ep - startaddr);
+ }
+
+ return 1;
+}
+
static size_t image_headersz_align(size_t headersz, uint8_t blockid)
{
/*
@@ -959,10 +1024,10 @@ static size_t image_headersz_v0(int *hasext)
*hasext = 1;
}
- return image_headersz_align(headersz, image_get_bootfrom());
+ return headersz;
}
-static void *image_create_v0(size_t *imagesz, struct image_tool_params *params,
+static void *image_create_v0(size_t *dataoff, struct image_tool_params *params,
int payloadsz)
{
struct image_cfg_element *e;
@@ -972,10 +1037,11 @@ static void *image_create_v0(size_t *imagesz, struct image_tool_params *params,
int has_ext = 0;
/*
- * Calculate the size of the header and the size of the
+ * Calculate the size of the header and the offset of the
* payload
*/
headersz = image_headersz_v0(&has_ext);
+ *dataoff = image_headersz_align(headersz, image_get_bootfrom());
image = malloc(headersz);
if (!image) {
@@ -990,7 +1056,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);
- main_hdr->srcaddr = cpu_to_le32(headersz);
+ main_hdr->srcaddr = cpu_to_le32(*dataoff);
main_hdr->ext = has_ext;
main_hdr->version = 0;
main_hdr->destaddr = cpu_to_le32(params->addr);
@@ -1009,31 +1075,26 @@ static void *image_create_v0(size_t *imagesz, struct image_tool_params *params,
e = image_find_option(IMAGE_CFG_NAND_BADBLK_LOCATION);
if (e)
main_hdr->nandbadblklocation = e->nandbadblklocation;
- main_hdr->checksum = image_checksum8(image,
- sizeof(struct main_hdr_v0));
/*
- * For SATA srcaddr is specified in number of sectors starting from
- * sector 0. The main header is stored at sector number 1.
+ * For SATA srcaddr is specified in number of sectors.
* 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);
+ main_hdr->srcaddr = cpu_to_le32(le32_to_cpu(main_hdr->srcaddr) / 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 (params->xflag) {
+ if (!image_fill_xip_header(main_hdr, params)) {
+ free(image);
+ return NULL;
+ }
+ *dataoff = le32_to_cpu(main_hdr->srcaddr);
+ }
+
/* Generate the ext header */
if (has_ext) {
struct ext_hdr_v0 *ext_hdr;
@@ -1059,7 +1120,9 @@ static void *image_create_v0(size_t *imagesz, struct image_tool_params *params,
sizeof(struct ext_hdr_v0));
}
- *imagesz = headersz;
+ main_hdr->checksum = image_checksum8(image,
+ sizeof(struct main_hdr_v0));
+
return image;
}
@@ -1073,10 +1136,6 @@ static size_t image_headersz_v1(int *hasext)
int cfgi;
int ret;
- /*
- * Calculate the size of the header and the size of the
- * payload
- */
headersz = sizeof(struct main_hdr_v1);
if (image_get_csk_index() >= 0) {
@@ -1172,7 +1231,7 @@ static size_t image_headersz_v1(int *hasext)
if (count > 0)
headersz += sizeof(struct register_set_hdr_v1) + 8 * count + 4;
- return image_headersz_align(headersz, image_get_bootfrom());
+ return headersz;
}
static int add_binary_header_v1(uint8_t **cur, uint8_t **next_ext,
@@ -1331,16 +1390,14 @@ static int kwb_sign_csk_with_kak(struct image_tool_params *params,
return 0;
}
-static int add_secure_header_v1(struct image_tool_params *params, uint8_t *ptr,
- int payloadsz, size_t headersz, uint8_t *image,
+static int add_secure_header_v1(struct image_tool_params *params, uint8_t *image_ptr,
+ size_t image_size, uint8_t *header_ptr, size_t headersz,
struct secure_hdr_v1 *secure_hdr)
{
struct image_cfg_element *e_jtagdelay;
struct image_cfg_element *e_boxid;
struct image_cfg_element *e_flashid;
RSA *csk = NULL;
- unsigned char *image_ptr;
- size_t image_size;
struct sig_v1 tmp_sig;
bool specialized_img = image_get_spezialized_img();
@@ -1366,14 +1423,11 @@ static int add_secure_header_v1(struct image_tool_params *params, uint8_t *ptr,
if (kwb_sign_csk_with_kak(params, secure_hdr, csk))
return 1;
- image_ptr = ptr + headersz;
- image_size = payloadsz - headersz;
-
- if (kwb_sign_and_verify(csk, image_ptr, image_size,
+ if (kwb_sign_and_verify(csk, image_ptr, image_size - 4,
&secure_hdr->imgsig, "image") < 0)
return 1;
- if (kwb_sign_and_verify(csk, image, headersz, &tmp_sig, "header") < 0)
+ if (kwb_sign_and_verify(csk, header_ptr, headersz, &tmp_sig, "header") < 0)
return 1;
secure_hdr->hdrsig = tmp_sig;
@@ -1399,12 +1453,11 @@ static void finish_register_set_header_v1(uint8_t **cur, uint8_t **next_ext,
*datai = 0;
}
-static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
+static void *image_create_v1(size_t *dataoff, struct image_tool_params *params,
uint8_t *ptr, int payloadsz)
{
struct image_cfg_element *e;
struct main_hdr_v1 *main_hdr;
- struct opt_hdr_v1 *ohdr;
struct register_set_hdr_v1 *register_set_hdr;
struct secure_hdr_v1 *secure_hdr = NULL;
size_t headersz;
@@ -1415,12 +1468,13 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
uint8_t delay;
/*
- * Calculate the size of the header and the size of the
+ * Calculate the size of the header and the offset of the
* payload
*/
headersz = image_headersz_v1(&hasext);
if (headersz == 0)
return NULL;
+ *dataoff = image_headersz_align(headersz, image_get_bootfrom());
image = malloc(headersz);
if (!image) {
@@ -1442,7 +1496,7 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
main_hdr->headersz_msb = (headersz & 0xFFFF0000) >> 16;
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->srcaddr = cpu_to_le32(*dataoff);
main_hdr->ext = hasext;
main_hdr->version = 1;
main_hdr->blockid = image_get_bootfrom();
@@ -1470,27 +1524,24 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
main_hdr->flags = e->debug ? 0x1 : 0;
/*
- * For SATA srcaddr is specified in number of sectors starting from
- * sector 0. The main header is stored at sector number 1.
+ * For SATA srcaddr is specified in number of sectors.
* 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);
+ main_hdr->srcaddr = cpu_to_le32(le32_to_cpu(main_hdr->srcaddr) / 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 (params->xflag) {
+ if (!image_fill_xip_header(main_hdr, params)) {
+ free(image);
+ return NULL;
+ }
+ *dataoff = le32_to_cpu(main_hdr->srcaddr);
+ }
+
if (image_get_csk_index() >= 0) {
/*
* only reserve the space here; we fill the header later since
@@ -1552,19 +1603,10 @@ static void *image_create_v1(size_t *imagesz, struct image_tool_params *params,
&datai, delay);
}
- if (secure_hdr && add_secure_header_v1(params, ptr, payloadsz + headersz,
- headersz, image, secure_hdr))
+ if (secure_hdr && add_secure_header_v1(params, ptr + *dataoff, payloadsz,
+ image, headersz, secure_hdr))
return NULL;
- *imagesz = headersz;
-
- /* Fill the real header size without padding into the main header */
- headersz = sizeof(*main_hdr);
- for_each_opt_hdr_v1 (ohdr, main_hdr)
- headersz += opt_hdr_v1_size(ohdr);
- main_hdr->headersz_lsb = cpu_to_le16(headersz & 0xFFFF);
- main_hdr->headersz_msb = (headersz & 0xFFFF0000) >> 16;
-
/* Calculate and set the header checksum */
main_hdr->checksum = image_checksum8(main_hdr, headersz);
@@ -1835,7 +1877,7 @@ static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd,
FILE *fcfg;
void *image = NULL;
int version;
- size_t headersz = 0;
+ size_t dataoff = 0;
size_t datasz;
uint32_t checksum;
struct stat s;
@@ -1845,7 +1887,9 @@ static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd,
* Do not use sbuf->st_size as it contains size with padding.
* We need original image data size, so stat original file.
*/
- if (stat(params->datafile, &s)) {
+ if (params->skipcpy) {
+ s.st_size = 0;
+ } else if (stat(params->datafile, &s)) {
fprintf(stderr, "Could not stat data file %s: %s\n",
params->datafile, strerror(errno));
exit(EXIT_FAILURE);
@@ -1886,11 +1930,11 @@ static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd,
*/
case -1:
case 0:
- image = image_create_v0(&headersz, params, datasz + 4);
+ image = image_create_v0(&dataoff, params, datasz + 4);
break;
case 1:
- image = image_create_v1(&headersz, params, ptr, datasz + 4);
+ image = image_create_v1(&dataoff, params, ptr, datasz + 4);
break;
default:
@@ -1908,12 +1952,12 @@ static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd,
free(image_cfg);
/* Build and add image data checksum */
- checksum = cpu_to_le32(image_checksum32((uint8_t *)ptr + headersz,
+ checksum = cpu_to_le32(image_checksum32((uint8_t *)ptr + dataoff,
datasz));
- memcpy((uint8_t *)ptr + headersz + datasz, &checksum, sizeof(uint32_t));
+ memcpy((uint8_t *)ptr + dataoff + datasz, &checksum, sizeof(uint32_t));
/* Finally copy the header into the image area */
- memcpy(ptr, image, headersz);
+ memcpy(ptr, image, kwbheader_size(image));
free(image);
}
@@ -1933,9 +1977,9 @@ static void kwbimage_print_header(const void *ptr)
printf("BIN Img Size: ");
genimg_print_size(opt_hdr_v1_size(ohdr) - 12 -
4 * ohdr->data[0]);
- printf("BIN Img Offs: %08x\n",
- (unsigned)((uint8_t *)ohdr - (uint8_t *)mhdr) +
- 8 + 4 * ohdr->data[0]);
+ printf("BIN Img Offs: ");
+ genimg_print_size(((uint8_t *)ohdr - (uint8_t *)mhdr) +
+ 8 + 4 * ohdr->data[0]);
}
}
@@ -1947,9 +1991,20 @@ static void kwbimage_print_header(const void *ptr)
}
printf("Data Size: ");
- genimg_print_size(mhdr->blocksize - sizeof(uint32_t));
- printf("Load Address: %08x\n", mhdr->destaddr);
- printf("Entry Point: %08x\n", mhdr->execaddr);
+ genimg_print_size(le32_to_cpu(mhdr->blocksize) - sizeof(uint32_t));
+ printf("Data Offset: ");
+ if (mhdr->blockid == IBR_HDR_SATA_ID)
+ printf("%u Sector%s (LBA)\n", le32_to_cpu(mhdr->srcaddr),
+ le32_to_cpu(mhdr->srcaddr) != 1 ? "s" : "");
+ else
+ genimg_print_size(le32_to_cpu(mhdr->srcaddr));
+ if (mhdr->blockid == IBR_HDR_SPI_ID && le32_to_cpu(mhdr->destaddr) == 0xFFFFFFFF) {
+ printf("Load Address: XIP\n");
+ printf("Execute Offs: %08x\n", le32_to_cpu(mhdr->execaddr));
+ } else {
+ printf("Load Address: %08x\n", le32_to_cpu(mhdr->destaddr));
+ printf("Entry Point: %08x\n", le32_to_cpu(mhdr->execaddr));
+ }
}
static int kwbimage_check_image_types(uint8_t type)
@@ -2028,23 +2083,9 @@ static int kwbimage_verify_header(unsigned char *ptr, int image_size,
/*
* 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.
+ * This expects that sector size is 512 bytes.
*/
- if (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 (blockid == IBR_HDR_SDIO_ID)
+ if (blockid == IBR_HDR_SATA_ID)
offset *= 512;
/*
@@ -2067,6 +2108,8 @@ static int kwbimage_verify_header(unsigned char *ptr, int image_size,
return 0;
}
+static int kwbimage_align_size(int bootfrom, int alloc_len, struct stat s);
+
static int kwbimage_generate(struct image_tool_params *params,
struct image_type_params *tparams)
{
@@ -2085,7 +2128,9 @@ static int kwbimage_generate(struct image_tool_params *params,
exit(EXIT_FAILURE);
}
- if (stat(params->datafile, &s)) {
+ if (params->skipcpy) {
+ s.st_size = 0;
+ } else if (stat(params->datafile, &s)) {
fprintf(stderr, "Could not stat data file %s: %s\n",
params->datafile, strerror(errno));
exit(EXIT_FAILURE);
@@ -2141,6 +2186,8 @@ static int kwbimage_generate(struct image_tool_params *params,
exit(EXIT_FAILURE);
}
+ alloc_len = image_headersz_align(alloc_len, image_get_bootfrom());
+
free(image_cfg);
hdr = malloc(alloc_len);
@@ -2155,6 +2202,22 @@ static int kwbimage_generate(struct image_tool_params *params,
tparams->hdr = hdr;
/*
+ * This function should return aligned size of the datafile.
+ * When skipcpy is set (datafile is skipped) then return value of this
+ * function is ignored, so we have to put required kwbimage aligning
+ * into the preallocated header size.
+ */
+ if (params->skipcpy) {
+ tparams->header_size += kwbimage_align_size(bootfrom, alloc_len, s);
+ return 0;
+ } else {
+ return kwbimage_align_size(bootfrom, alloc_len, s);
+ }
+}
+
+static int kwbimage_align_size(int bootfrom, int alloc_len, struct stat s)
+{
+ /*
* The resulting image needs to be 4-byte aligned. At least
* the Marvell hdrparser tool complains if its unaligned.
* After the image data is stored 4-byte checksum.
@@ -2182,6 +2245,7 @@ static int kwbimage_generate_config(void *ptr, struct image_tool_params *params)
struct ext_hdr_v0 *ehdr0;
struct bin_hdr_v0 *bhdr0;
struct opt_hdr_v1 *ohdr;
+ int regset_count;
int params_count;
unsigned offset;
int is_v0_ext;
@@ -2215,12 +2279,18 @@ static int kwbimage_generate_config(void *ptr, struct image_tool_params *params)
fprintf(f, "NAND_ECC_MODE %s\n", image_nand_ecc_mode_name(mhdr0->nandeccmode));
if (mhdr->blockid == IBR_HDR_NAND_ID)
- fprintf(f, "NAND_PAGE_SIZE 0x%x\n", (unsigned)mhdr->nandpagesize);
+ fprintf(f, "NAND_PAGE_SIZE 0x%x\n", (unsigned)le16_to_cpu(mhdr->nandpagesize));
- if (version != 0 && mhdr->blockid == IBR_HDR_NAND_ID)
- fprintf(f, "NAND_BLKSZ 0x%x\n", (unsigned)mhdr->nandblocksize);
+ if (mhdr->blockid == IBR_HDR_NAND_ID && (version != 0 || is_v0_ext || mhdr->nandblocksize != 0)) {
+ if (mhdr->nandblocksize != 0) /* block size explicitly set in 64 kB unit */
+ fprintf(f, "NAND_BLKSZ 0x%x\n", (unsigned)mhdr->nandblocksize * 64*1024);
+ else if (le16_to_cpu(mhdr->nandpagesize) > 512)
+ fprintf(f, "NAND_BLKSZ 0x10000\n"); /* large page NAND flash = 64 kB block size */
+ else
+ fprintf(f, "NAND_BLKSZ 0x4000\n"); /* small page NAND flash = 16 kB block size */
+ }
- if (mhdr->blockid == IBR_HDR_NAND_ID && (mhdr->nandbadblklocation != 0 || is_v0_ext))
+ if (mhdr->blockid == IBR_HDR_NAND_ID && (version != 0 || is_v0_ext))
fprintf(f, "NAND_BADBLK_LOCATION 0x%x\n", (unsigned)mhdr->nandbadblklocation);
if (version == 0 && mhdr->blockid == IBR_HDR_SATA_ID)
@@ -2266,18 +2336,20 @@ static int kwbimage_generate_config(void *ptr, struct image_tool_params *params)
cur_idx++;
} else if (ohdr->headertype == OPT_HDR_V1_REGISTER_TYPE) {
regset_hdr = (struct register_set_hdr_v1 *)ohdr;
- for (i = 0;
- i < opt_hdr_v1_size(ohdr) - sizeof(struct opt_hdr_v1) -
- sizeof(regset_hdr->data[0].last_entry);
- i++)
+ if (opt_hdr_v1_size(ohdr) > sizeof(*ohdr))
+ regset_count = (opt_hdr_v1_size(ohdr) - sizeof(*ohdr)) /
+ sizeof(regset_hdr->data[0].entry);
+ else
+ regset_count = 0;
+ for (i = 0; i < regset_count; i++)
fprintf(f, "DATA 0x%08x 0x%08x\n",
le32_to_cpu(regset_hdr->data[i].entry.address),
le32_to_cpu(regset_hdr->data[i].entry.value));
- if (opt_hdr_v1_size(ohdr) - sizeof(struct opt_hdr_v1) >=
- sizeof(regset_hdr->data[0].last_entry)) {
- if (regset_hdr->data[0].last_entry.delay)
+ if (regset_count > 0) {
+ if (regset_hdr->data[regset_count-1].last_entry.delay !=
+ REGISTER_SET_HDR_OPT_DELAY_SDRAM_SETUP)
fprintf(f, "DATA_DELAY %u\n",
- (unsigned)regset_hdr->data[0].last_entry.delay);
+ (unsigned)regset_hdr->data[regset_count-1].last_entry.delay);
else
fprintf(f, "DATA_DELAY SDRAM_SETUP\n");
}
@@ -2403,12 +2475,7 @@ static int kwbimage_extract_subimage(void *ptr, struct image_tool_params *params
/* Extract data image when -p is not specified or when '-p 0' is specified */
offset = le32_to_cpu(mhdr->srcaddr);
- if (mhdr->blockid == IBR_HDR_SATA_ID) {
- offset -= 1;
- offset *= 512;
- }
-
- if (mhdr->blockid == IBR_HDR_SDIO_ID)
+ if (mhdr->blockid == IBR_HDR_SATA_ID)
offset *= 512;
if (mhdr->blockid == IBR_HDR_PEX_ID && offset == 0xFFFFFFFF)
@@ -2455,9 +2522,6 @@ static int kwbimage_extract_subimage(void *ptr, struct image_tool_params *params
return imagetool_save_subimage(params->outfile, image, size);
}
-/*
- * Report Error if xflag is set in addition to default
- */
static int kwbimage_check_params(struct image_tool_params *params)
{
if (!params->lflag && !params->iflag && !params->pflag &&
@@ -2468,10 +2532,9 @@ static int kwbimage_check_params(struct image_tool_params *params)
return 1;
}
- return (params->dflag && (params->fflag || params->lflag)) ||
- (params->fflag && (params->dflag || params->lflag)) ||
- (params->lflag && (params->dflag || params->fflag)) ||
- (params->xflag);
+ return (params->dflag && (params->fflag || params->lflag || params->skipcpy)) ||
+ (params->fflag) ||
+ (params->lflag && (params->dflag || params->fflag));
}
/*
diff --git a/tools/kwboot.c b/tools/kwboot.c
index da4fe32..7c66648 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -15,6 +15,12 @@
* Processor, and High-Definition Video Decoder: Functional Specifications"
* August 3, 2011. Chapter 5 "BootROM Firmware"
* https://web.archive.org/web/20120130172443/https://www.marvell.com/application-processors/armada-500/assets/Armada-510-Functional-Spec.pdf
+ * - "88F6665, 88F6660, 88F6658, 88F6655, 88F6655F, 88F6650, 88F6650F, 88F6610,
+ * and 88F6610F Avanta LP Family Integrated Single/Dual CPU Ecosystem for
+ * Gateway (GW), Home Gateway Unit (HGU), and Single Family Unit (SFU)
+ * Functional Specifications" Doc. No. MV-S108952-00, Rev. A. November 7, 2013.
+ * Chapter 7 "Boot Flow"
+ * CONFIDENTIAL, no public documentation available
* - "88F6710, 88F6707, and 88F6W11: ARMADA(R) 370 SoC: Functional Specifications"
* May 26, 2014. Chapter 6 "BootROM Firmware".
* https://web.archive.org/web/20140617183701/https://www.marvell.com/embedded-processors/armada-300/assets/ARMADA370-FunctionalSpec-datasheet.pdf
@@ -22,6 +28,15 @@
* Multi-Core ARMv7 Based SoC Processors: Functional Specifications"
* May 29, 2014. Chapter 6 "BootROM Firmware".
* https://web.archive.org/web/20180829171131/https://www.marvell.com/embedded-processors/armada-xp/assets/ARMADA-XP-Functional-SpecDatasheet.pdf
+ * - "BobCat2 Control and Management Subsystem Functional Specifications"
+ * Doc. No. MV-S109400-00, Rev. A. December 4, 2014.
+ * Chapter 1.6 BootROM Firmware
+ * CONFIDENTIAL, no public documentation available
+ * - "AlleyCat3 and PONCat3 Highly Integrated 1/10 Gigabit Ethernet Switch
+ * Control and Management Subsystem: Functional Specifications"
+ * Doc. No. MV-S109693-00, Rev. A. May 20, 2014.
+ * Chapter 1.6 BootROM Firmware
+ * CONFIDENTIAL, no public documentation available
* - "ARMADA(R) 375 Value-Performance Dual Core CPU System on Chip: Functional
* Specifications" Doc. No. MV-S109377-00, Rev. A. September 18, 2013.
* Chapter 7 "Boot Sequence"
@@ -35,6 +50,72 @@
* System on Chip Functional Specifications" Doc. No. MV-S109896-00, Rev. B.
* December 22, 2015. Chapter 7 "Boot Flow"
* CONFIDENTIAL, no public documentation available
+ * - "Marvell boot image parser", Marvell U-Boot 2013.01, version 18.06. September 17, 2015.
+ * https://github.com/MarvellEmbeddedProcessors/u-boot-marvell/blob/u-boot-2013.01-armada-18.06/tools/marvell/doimage_mv/hdrparser.c
+ * - "Marvell doimage Tool", Marvell U-Boot 2013.01, version 18.06. August 30, 2015.
+ * https://github.com/MarvellEmbeddedProcessors/u-boot-marvell/blob/u-boot-2013.01-armada-18.06/tools/marvell/doimage_mv/doimage.c
+ *
+ * Storage location / offset of different image types:
+ * - IBR_HDR_SPI_ID (0x5A):
+ * SPI image can be stored at any 2 MB aligned offset in the first 16 MB of
+ * SPI-NOR or parallel-NOR. Despite the type name it really can be stored on
+ * parallel-NOR and cannot be stored on other SPI devices, like SPI-NAND.
+ * So it should have been named NOR image, not SPI image. This image type
+ * supports XIP - Execute In Place directly from NOR memory.
+ *
+ * - IBR_HDR_NAND_ID (0x8B):
+ * NAND image can be stored either at any 2 MB aligned offset in the first
+ * 16 MB of SPI-NAND or at any blocksize aligned offset in the first 64 MB
+ * of parallel-NAND.
+ *
+ * - IBR_HDR_PEX_ID (0x9C):
+ * PEX image is used for booting from PCI Express device. Source address
+ * stored in image is ignored by BootROM. It is not the BootROM who parses
+ * or loads data part of the PEX image. BootROM just configures SoC to the
+ * PCIe endpoint mode and let the PCIe device on the other end of the PCIe
+ * link (which must be in Root Complex mode) to load kwbimage into SoC's
+ * memory and tell BootROM physical address.
+ *
+ * - IBR_HDR_UART_ID (0x69):
+ * UART image can be transfered via xmodem protocol over first UART.
+ *
+ * - IBR_HDR_I2C_ID (0x4D):
+ * It is unknown for what kind of storage is used this image. It is not
+ * specified in any document from References section.
+ *
+ * - IBR_HDR_SATA_ID (0x78):
+ * SATA image can be stored at sector 1 (after the MBR table), sector 34
+ * (after the GPT table) or at any next sector which is aligned to 2 MB and
+ * is in the first 16 MB of SATA disk. Note that source address in SATA image
+ * is stored in sector unit and not in bytes like for any other images.
+ * Unfortunately sector size is disk specific, in most cases it is 512 bytes
+ * but there are also Native 4K SATA disks which have 4096 bytes long sectors.
+ *
+ * - IBR_HDR_SDIO_ID (0xAE):
+ * SDIO image can be stored on different medias:
+ * - SD(SC) card
+ * - SDHC/SDXC card
+ * - eMMC HW boot partition
+ * - eMMC user data partition / MMC card
+ * It cannot be stored on SDIO card despite the image name.
+ *
+ * For SD(SC)/SDHC/SDXC cards, image can be stored at the same locations as
+ * the SATA image (sector 1, sector 34 or any 2 MB aligned sector) but within
+ * the first 64 MB. SDHC and SDXC cards have fixed 512 bytes long sector size.
+ * Old SD(SC) cards unfortunately can have also different sector sizes, mostly
+ * 1024 bytes long sector sizes and also can be changed at runtime.
+ *
+ * For MMC-compatible devices, image can be stored at offset 0 or at offset
+ * 2 MB. If MMC device supports HW boot partitions then image must be stored
+ * on the HW partition as is configured in the EXT_CSC register (it can be
+ * either boot or user data).
+ *
+ * Note that source address for SDIO image is stored in byte unit, like for
+ * any other images (except SATA). Marvell Functional Specifications for
+ * A38x and A39x SoCs say that source address is in sector units, but this
+ * is purely incorrect information. A385 BootROM really expects source address
+ * for SDIO images in bytes and also Marvell tools generate SDIO image with
+ * source address in byte units.
*/
#include "kwbimage.h"
@@ -1699,6 +1780,47 @@ kwboot_img_is_secure(void *img)
return 0;
}
+static int
+kwboot_img_has_ddr_init(void *img)
+{
+ const struct register_set_hdr_v1 *rhdr;
+ const struct main_hdr_v0 *hdr0;
+ struct opt_hdr_v1 *ohdr;
+ u32 ohdrsz;
+ int last;
+
+ /*
+ * kwbimage v0 image headers contain DDR init code either in
+ * extension header or in binary code header.
+ */
+ if (kwbimage_version(img) == 0) {
+ hdr0 = img;
+ return hdr0->ext || hdr0->bin;
+ }
+
+ /*
+ * kwbimage v1 image headers contain DDR init code either in binary
+ * code header or in a register set list header with SDRAM_SETUP.
+ */
+ for_each_opt_hdr_v1 (ohdr, img) {
+ if (ohdr->headertype == OPT_HDR_V1_BINARY_TYPE)
+ return 1;
+ if (ohdr->headertype == OPT_HDR_V1_REGISTER_TYPE) {
+ rhdr = (const struct register_set_hdr_v1 *)ohdr;
+ ohdrsz = opt_hdr_v1_size(ohdr);
+ if (ohdrsz >= sizeof(*ohdr) + sizeof(rhdr->data[0].last_entry)) {
+ ohdrsz -= sizeof(*ohdr) + sizeof(rhdr->data[0].last_entry);
+ last = ohdrsz / sizeof(rhdr->data[0].entry);
+ if (rhdr->data[last].last_entry.delay ==
+ REGISTER_SET_HDR_OPT_DELAY_SDRAM_SETUP)
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
static void *
kwboot_img_grow_data_right(void *img, size_t *size, size_t grow)
{
@@ -1854,10 +1976,26 @@ _inject_baudrate_change_code(void *img, size_t *size, int for_data,
}
}
+static const char *
+kwboot_img_type(uint8_t blockid)
+{
+ switch (blockid) {
+ case IBR_HDR_I2C_ID: return "I2C";
+ case IBR_HDR_SPI_ID: return "SPI";
+ case IBR_HDR_NAND_ID: return "NAND";
+ case IBR_HDR_SATA_ID: return "SATA";
+ case IBR_HDR_PEX_ID: return "PEX";
+ case IBR_HDR_UART_ID: return "UART";
+ case IBR_HDR_SDIO_ID: return "SDIO";
+ default: return "unknown";
+ }
+}
+
static int
kwboot_img_patch(void *img, size_t *size, int baudrate)
{
struct main_hdr_v1 *hdr;
+ struct opt_hdr_v1 *ohdr;
uint32_t srcaddr;
uint8_t csum;
size_t hdrsz;
@@ -1866,8 +2004,10 @@ kwboot_img_patch(void *img, size_t *size, int baudrate)
hdr = img;
- if (*size < sizeof(struct main_hdr_v1))
+ if (*size < sizeof(struct main_hdr_v1)) {
+ fprintf(stderr, "Invalid image header size\n");
goto err;
+ }
image_ver = kwbimage_version(img);
if (image_ver != 0 && image_ver != 1) {
@@ -1877,24 +2017,23 @@ kwboot_img_patch(void *img, size_t *size, int baudrate)
hdrsz = kwbheader_size(hdr);
- if (*size < hdrsz)
+ if (*size < hdrsz) {
+ fprintf(stderr, "Invalid image header size\n");
goto err;
+ }
+
+ kwboot_printv("Detected kwbimage v%d with %s boot signature\n", image_ver, kwboot_img_type(hdr->blockid));
csum = kwboot_hdr_csum8(hdr) - hdr->checksum;
- if (csum != hdr->checksum)
+ if (csum != hdr->checksum) {
+ fprintf(stderr, "Image has invalid header checksum stored in image header\n");
goto err;
+ }
srcaddr = le32_to_cpu(hdr->srcaddr);
switch (hdr->blockid) {
case IBR_HDR_SATA_ID:
- if (srcaddr < 1)
- goto err;
-
- hdr->srcaddr = cpu_to_le32((srcaddr - 1) * 512);
- break;
-
- case IBR_HDR_SDIO_ID:
hdr->srcaddr = cpu_to_le32(srcaddr * 512);
break;
@@ -1906,18 +2045,48 @@ kwboot_img_patch(void *img, size_t *size, int baudrate)
case IBR_HDR_SPI_ID:
if (hdr->destaddr == cpu_to_le32(0xFFFFFFFF)) {
kwboot_printv("Patching destination and execution addresses from SPI/NOR XIP area to DDR area 0x00800000\n");
- hdr->destaddr = cpu_to_le32(0x00800000);
- hdr->execaddr = cpu_to_le32(0x00800000);
+ hdr->destaddr = cpu_to_le32(0x00800000 + le32_to_cpu(hdr->srcaddr));
+ hdr->execaddr = cpu_to_le32(0x00800000 + le32_to_cpu(hdr->execaddr));
}
break;
}
- if (hdrsz > le32_to_cpu(hdr->srcaddr) ||
- *size < le32_to_cpu(hdr->srcaddr) + le32_to_cpu(hdr->blocksize))
+ if (hdrsz > le32_to_cpu(hdr->srcaddr)) {
+ fprintf(stderr, "Image has invalid data offset stored in image header\n");
goto err;
+ }
- if (kwboot_img_csum32(img) != *kwboot_img_csum32_ptr(img))
+ if (*size < le32_to_cpu(hdr->srcaddr) + le32_to_cpu(hdr->blocksize)) {
+ fprintf(stderr, "Image has invalid data size stored in image header\n");
goto err;
+ }
+
+ for_each_opt_hdr_v1 (ohdr, hdr) {
+ if (!opt_hdr_v1_valid_size(ohdr, (const uint8_t *)hdr + hdrsz)) {
+ fprintf(stderr, "Invalid optional image header\n");
+ goto err;
+ }
+ }
+
+ /*
+ * The 32-bit data checksum is optional for UART image. If it is not
+ * present (checksum detected as invalid) then grow data part of the
+ * image for the checksum, so it can be inserted there.
+ */
+ if (kwboot_img_csum32(img) != *kwboot_img_csum32_ptr(img)) {
+ if (hdr->blockid != IBR_HDR_UART_ID) {
+ fprintf(stderr, "Image has invalid data checksum\n");
+ goto err;
+ }
+ kwboot_img_grow_data_right(img, size, sizeof(uint32_t));
+ }
+
+ if (!kwboot_img_has_ddr_init(img) &&
+ (le32_to_cpu(hdr->destaddr) < 0x40000000 ||
+ le32_to_cpu(hdr->destaddr) + le32_to_cpu(hdr->blocksize) > 0x40034000)) {
+ fprintf(stderr, "Image does not contain DDR init code needed for UART booting\n");
+ goto err;
+ }
is_secure = kwboot_img_is_secure(img);
@@ -2182,6 +2351,7 @@ main(int argc, char **argv)
KWBOOT_XM_BLKSZ +
sizeof(kwboot_baud_code) +
sizeof(kwboot_baud_code_data_jump) +
+ sizeof(uint32_t) +
KWBOOT_XM_BLKSZ;
if (imgpath) {
diff --git a/tools/mkimage.c b/tools/mkimage.c
index af7b0e0..a92d9d5 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -599,7 +599,12 @@ int main(int argc, char **argv)
exit (retval);
}
- if ((params.type != IH_TYPE_MULTI) && (params.type != IH_TYPE_SCRIPT)) {
+ if (!params.skipcpy && params.type != IH_TYPE_MULTI && params.type != IH_TYPE_SCRIPT) {
+ if (!params.datafile) {
+ fprintf(stderr, "%s: Option -d with image data file was not specified\n",
+ params.cmdname);
+ exit(EXIT_FAILURE);
+ }
dfd = open(params.datafile, O_RDONLY | O_BINARY);
if (dfd < 0) {
fprintf(stderr, "%s: Can't open %s: %s\n",
@@ -860,7 +865,9 @@ copy_file (int ifd, const char *datafile, int pad)
exit (EXIT_FAILURE);
}
- if (params.xflag) {
+ if (params.xflag &&
+ (((params.type > IH_TYPE_INVALID) && (params.type < IH_TYPE_FLATDT)) ||
+ (params.type == IH_TYPE_KERNEL_NOLOAD) || (params.type == IH_TYPE_FIRMWARE_IVT))) {
unsigned char *p = NULL;
/*
* XIP: do not append the struct legacy_img_hdr at the