summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README18
-rw-r--r--arch/arm/cpu/armv7/omap-common/boot-common.c39
-rw-r--r--arch/arm/cpu/armv7/omap-common/hwinit-common.c38
-rw-r--r--arch/arm/include/asm/arch-am33xx/omap.h6
-rw-r--r--arch/arm/include/asm/arch-am33xx/sys_proto.h1
-rw-r--r--arch/arm/include/asm/arch-omap4/omap.h1
-rw-r--r--arch/arm/include/asm/arch-omap4/sys_proto.h1
-rw-r--r--arch/arm/include/asm/arch-omap5/omap.h1
-rw-r--r--arch/arm/include/asm/arch-omap5/sys_proto.h1
-rw-r--r--arch/arm/include/asm/omap_common.h1
-rw-r--r--board/isee/igep0033/board.c9
-rw-r--r--board/phytec/pcm051/board.c9
-rw-r--r--board/ti/am335x/board.c9
-rw-r--r--board/ti/ti814x/evm.c9
-rw-r--r--common/board_f.c9
-rw-r--r--common/cmd_bootm.c170
-rw-r--r--common/cmd_fitupd.c3
-rw-r--r--common/image-fdt.c207
-rw-r--r--common/image-fit.c310
-rw-r--r--common/image.c122
-rw-r--r--common/main.c296
-rw-r--r--disk/part_efi.c11
-rw-r--r--drivers/input/key_matrix.c68
-rw-r--r--drivers/tpm/Makefile7
-rw-r--r--drivers/tpm/slb9635_i2c/compatibility.h51
-rw-r--r--drivers/tpm/tis_i2c.c4
-rw-r--r--drivers/tpm/tpm.c (renamed from drivers/tpm/slb9635_i2c/tpm.c)280
-rw-r--r--drivers/tpm/tpm_private.h (renamed from drivers/tpm/slb9635_i2c/tpm.h)46
-rw-r--r--drivers/tpm/tpm_tis_i2c.c (renamed from drivers/tpm/slb9635_i2c/tpm_tis_i2c.c)354
-rw-r--r--drivers/tpm/tpm_tis_lpc.c (renamed from drivers/tpm/generic_lpc_tpm.c)0
-rw-r--r--include/bootstage.h51
-rw-r--r--include/common.h3
-rw-r--r--include/configs/am335x_evm.h7
-rw-r--r--include/configs/coreboot.h3
-rw-r--r--include/configs/exynos5250-dt.h6
-rw-r--r--include/configs/igep0033.h7
-rw-r--r--include/configs/pcm051.h7
-rw-r--r--include/configs/pm9263.h2
-rw-r--r--include/fdtdec.h1
-rw-r--r--include/image.h105
-rw-r--r--include/net.h3
-rw-r--r--lib/fdtdec.c1
-rwxr-xr-xtest/image/test-fit.py422
-rwxr-xr-xtools/checkpatch.pl1
-rw-r--r--tools/mkimage.h12
45 files changed, 1618 insertions, 1094 deletions
diff --git a/README b/README
index b1b3e17..3780564 100644
--- a/README
+++ b/README
@@ -1209,7 +1209,23 @@ The following options need to be configured:
If this option is set, the driver enables cache flush.
- TPM Support:
- CONFIG_GENERIC_LPC_TPM
+ CONFIG_TPM
+ Support TPM devices.
+
+ CONFIG_TPM_TIS_I2C
+ Support for i2c bus TPM devices. Only one device
+ per system is supported at this time.
+
+ CONFIG_TPM_TIS_I2C_BUS_NUMBER
+ Define the the i2c bus number for the TPM device
+
+ CONFIG_TPM_TIS_I2C_SLAVE_ADDRESS
+ Define the TPM's address on the i2c bus
+
+ CONFIG_TPM_TIS_I2C_BURST_LIMITATION
+ Define the burst count bytes upper limit
+
+ CONFIG_TPM_TIS_LPC
Support for generic parallel port TPM devices. Only one device
per system is supported at this time.
diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c
index bff7e9c..76ae1b6 100644
--- a/arch/arm/cpu/armv7/omap-common/boot-common.c
+++ b/arch/arm/cpu/armv7/omap-common/boot-common.c
@@ -25,6 +25,45 @@
DECLARE_GLOBAL_DATA_PTR;
+void save_omap_boot_params(void)
+{
+ u32 rom_params = *((u32 *)OMAP_SRAM_SCRATCH_BOOT_PARAMS);
+ u8 boot_device;
+ u32 dev_desc, dev_data;
+
+ if ((rom_params < NON_SECURE_SRAM_START) ||
+ (rom_params > NON_SECURE_SRAM_END))
+ return;
+
+ /*
+ * rom_params can be type casted to omap_boot_parameters and
+ * used. But it not correct to assume that romcode structure
+ * encoding would be same as u-boot. So use the defined offsets.
+ */
+ gd->arch.omap_boot_params.omap_bootdevice = boot_device =
+ *((u8 *)(rom_params + BOOT_DEVICE_OFFSET));
+
+ gd->arch.omap_boot_params.ch_flags =
+ *((u8 *)(rom_params + CH_FLAGS_OFFSET));
+
+ if ((boot_device >= MMC_BOOT_DEVICES_START) &&
+ (boot_device <= MMC_BOOT_DEVICES_END)) {
+#if !defined(CONFIG_AM33XX) && !defined(CONFIG_TI81XX)
+ if ((omap_hw_init_context() ==
+ OMAP_INIT_CONTEXT_UBOOT_AFTER_SPL)) {
+ gd->arch.omap_boot_params.omap_bootmode =
+ *((u8 *)(rom_params + BOOT_MODE_OFFSET));
+ } else
+#endif
+ {
+ dev_desc = *((u32 *)(rom_params + DEV_DESC_PTR_OFFSET));
+ dev_data = *((u32 *)(dev_desc + DEV_DATA_PTR_OFFSET));
+ gd->arch.omap_boot_params.omap_bootmode =
+ *((u32 *)(dev_data + BOOT_MODE_OFFSET));
+ }
+ }
+}
+
#ifdef CONFIG_SPL_BUILD
u32 spl_boot_device(void)
{
diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
index 1645120..0776d5c 100644
--- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c
+++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
@@ -84,7 +84,7 @@ u32 cortex_rev(void)
return rev;
}
-void omap_rev_string(void)
+static void omap_rev_string(void)
{
u32 omap_rev = omap_revision();
u32 soc_variant = (omap_rev & 0xF0000000) >> 28;
@@ -111,42 +111,6 @@ void __weak srcomp_enable(void)
{
}
-static void save_omap_boot_params(void)
-{
- u32 rom_params = *((u32 *)OMAP_SRAM_SCRATCH_BOOT_PARAMS);
- u8 boot_device;
- u32 dev_desc, dev_data;
-
- if ((rom_params < NON_SECURE_SRAM_START) ||
- (rom_params > NON_SECURE_SRAM_END))
- return;
-
- /*
- * rom_params can be type casted to omap_boot_parameters and
- * used. But it not correct to assume that romcode structure
- * encoding would be same as u-boot. So use the defined offsets.
- */
- gd->arch.omap_boot_params.omap_bootdevice = boot_device =
- *((u8 *)(rom_params + BOOT_DEVICE_OFFSET));
-
- gd->arch.omap_boot_params.ch_flags =
- *((u8 *)(rom_params + CH_FLAGS_OFFSET));
-
- if ((boot_device >= MMC_BOOT_DEVICES_START) &&
- (boot_device <= MMC_BOOT_DEVICES_END)) {
- if ((omap_hw_init_context() ==
- OMAP_INIT_CONTEXT_UBOOT_AFTER_SPL)) {
- gd->arch.omap_boot_params.omap_bootmode =
- *((u8 *)(rom_params + BOOT_MODE_OFFSET));
- } else {
- dev_desc = *((u32 *)(rom_params + DEV_DESC_PTR_OFFSET));
- dev_data = *((u32 *)(dev_desc + DEV_DATA_PTR_OFFSET));
- gd->arch.omap_boot_params.omap_bootmode =
- *((u32 *)(dev_data + BOOT_MODE_OFFSET));
- }
- }
-}
-
#ifdef CONFIG_ARCH_CPU_INIT
/*
* SOC specific cpu init
diff --git a/arch/arm/include/asm/arch-am33xx/omap.h b/arch/arm/include/asm/arch-am33xx/omap.h
index 7e3bb9c..e7576c1 100644
--- a/arch/arm/include/asm/arch-am33xx/omap.h
+++ b/arch/arm/include/asm/arch-am33xx/omap.h
@@ -29,10 +29,12 @@
* at 0x40304000(EMU base) so that our code works for both EMU and GP
*/
#ifdef CONFIG_AM33XX
-#define NON_SECURE_SRAM_START 0x40304000
-#define NON_SECURE_SRAM_END 0x4030E000
+#define NON_SECURE_SRAM_START 0x402F0400
+#define NON_SECURE_SRAM_END 0x40310000
+#define SRAM_SCRATCH_SPACE_ADDR 0x4030C000
#elif defined(CONFIG_TI814X)
#define NON_SECURE_SRAM_START 0x40300000
#define NON_SECURE_SRAM_END 0x40320000
+#define SRAM_SCRATCH_SPACE_ADDR 0x4031B800
#endif
#endif
diff --git a/arch/arm/include/asm/arch-am33xx/sys_proto.h b/arch/arm/include/asm/arch-am33xx/sys_proto.h
index c913b5f..fedc674 100644
--- a/arch/arm/include/asm/arch-am33xx/sys_proto.h
+++ b/arch/arm/include/asm/arch-am33xx/sys_proto.h
@@ -30,6 +30,7 @@ int print_cpuinfo(void);
extern struct ctrl_stat *cstat;
u32 get_device_type(void);
+void save_omap_boot_params(void);
void setup_clocks_for_console(void);
void ddr_pll_config(unsigned int ddrpll_M);
diff --git a/arch/arm/include/asm/arch-omap4/omap.h b/arch/arm/include/asm/arch-omap4/omap.h
index e9a6ffe..44353a4 100644
--- a/arch/arm/include/asm/arch-omap4/omap.h
+++ b/arch/arm/include/asm/arch-omap4/omap.h
@@ -141,6 +141,7 @@ struct s32ktimer {
*/
#define NON_SECURE_SRAM_START 0x40304000
#define NON_SECURE_SRAM_END 0x4030E000 /* Not inclusive */
+#define SRAM_SCRATCH_SPACE_ADDR NON_SECURE_SRAM_START
/* base address for indirect vectors (internal boot mode) */
#define SRAM_ROM_VECT_BASE 0x4030D000
#endif
diff --git a/arch/arm/include/asm/arch-omap4/sys_proto.h b/arch/arm/include/asm/arch-omap4/sys_proto.h
index 039a1f2..ef85594 100644
--- a/arch/arm/include/asm/arch-omap4/sys_proto.h
+++ b/arch/arm/include/asm/arch-omap4/sys_proto.h
@@ -54,6 +54,7 @@ void cancel_out(u32 *num, u32 *den, u32 den_limit);
void sdram_init(void);
u32 omap_sdram_size(void);
u32 cortex_rev(void);
+void save_omap_boot_params(void);
void init_omap_revision(void);
void do_io_settings(void);
void omap_vc_init(u16 speed_khz);
diff --git a/arch/arm/include/asm/arch-omap5/omap.h b/arch/arm/include/asm/arch-omap5/omap.h
index 4f43a90..04af227 100644
--- a/arch/arm/include/asm/arch-omap5/omap.h
+++ b/arch/arm/include/asm/arch-omap5/omap.h
@@ -188,6 +188,7 @@ struct s32ktimer {
*/
#define NON_SECURE_SRAM_START 0x40300000
#define NON_SECURE_SRAM_END 0x40320000 /* Not inclusive */
+#define SRAM_SCRATCH_SPACE_ADDR NON_SECURE_SRAM_START
/* base address for indirect vectors (internal boot mode) */
#define SRAM_ROM_VECT_BASE 0x4031F000
diff --git a/arch/arm/include/asm/arch-omap5/sys_proto.h b/arch/arm/include/asm/arch-omap5/sys_proto.h
index b79161d..4d99db9 100644
--- a/arch/arm/include/asm/arch-omap5/sys_proto.h
+++ b/arch/arm/include/asm/arch-omap5/sys_proto.h
@@ -58,6 +58,7 @@ void cancel_out(u32 *num, u32 *den, u32 den_limit);
void sdram_init(void);
u32 omap_sdram_size(void);
u32 cortex_rev(void);
+void save_omap_boot_params(void);
void init_omap_revision(void);
void do_io_settings(void);
void omap_vc_init(u16 speed_khz);
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h
index ee7b188..baeef4e 100644
--- a/arch/arm/include/asm/omap_common.h
+++ b/arch/arm/include/asm/omap_common.h
@@ -591,7 +591,6 @@ static inline u32 omap_revision(void)
/*
* SRAM scratch space entries
*/
-#define SRAM_SCRATCH_SPACE_ADDR NON_SECURE_SRAM_START
#define OMAP_SRAM_SCRATCH_OMAP_REV SRAM_SCRATCH_SPACE_ADDR
#define OMAP_SRAM_SCRATCH_EMIF_SIZE (SRAM_SCRATCH_SPACE_ADDR + 0x4)
#define OMAP_SRAM_SCRATCH_EMIF_T_NUM (SRAM_SCRATCH_SPACE_ADDR + 0xC)
diff --git a/board/isee/igep0033/board.c b/board/isee/igep0033/board.c
index d315516..826cead 100644
--- a/board/isee/igep0033/board.c
+++ b/board/isee/igep0033/board.c
@@ -105,6 +105,15 @@ static struct emif_regs ddr3_emif_reg_data = {
*/
void s_init(void)
{
+ /*
+ * Save the boot parameters passed from romcode.
+ * We cannot delay the saving further than this,
+ * to prevent overwrites.
+ */
+#ifdef CONFIG_SPL_BUILD
+ save_omap_boot_params();
+#endif
+
/* WDT1 is already running when the bootloader gets control
* Disable it to avoid "random" resets
*/
diff --git a/board/phytec/pcm051/board.c b/board/phytec/pcm051/board.c
index 43d7b6e..93c611d 100644
--- a/board/phytec/pcm051/board.c
+++ b/board/phytec/pcm051/board.c
@@ -115,6 +115,15 @@ static struct emif_regs ddr3_emif_reg_data = {
void s_init(void)
{
/*
+ * Save the boot parameters passed from romcode.
+ * We cannot delay the saving further than this,
+ * to prevent overwrites.
+ */
+#ifdef CONFIG_SPL_BUILD
+ save_omap_boot_params();
+#endif
+
+ /*
* WDT1 is already running when the bootloader gets control
* Disable it to avoid "random" resets
*/
diff --git a/board/ti/am335x/board.c b/board/ti/am335x/board.c
index b371376..ebddf0c 100644
--- a/board/ti/am335x/board.c
+++ b/board/ti/am335x/board.c
@@ -304,6 +304,15 @@ static struct emif_regs ddr3_evm_emif_reg_data = {
*/
void s_init(void)
{
+ /*
+ * Save the boot parameters passed from romcode.
+ * We cannot delay the saving further than this,
+ * to prevent overwrites.
+ */
+#ifdef CONFIG_SPL_BUILD
+ save_omap_boot_params();
+#endif
+
/* WDT1 is already running when the bootloader gets control
* Disable it to avoid "random" resets
*/
diff --git a/board/ti/ti814x/evm.c b/board/ti/ti814x/evm.c
index 7adb524..4759b16 100644
--- a/board/ti/ti814x/evm.c
+++ b/board/ti/ti814x/evm.c
@@ -149,6 +149,15 @@ static const struct ddr_data evm_ddr2_data = {
void s_init(void)
{
#ifdef CONFIG_SPL_BUILD
+ /*
+ * Save the boot parameters passed from romcode.
+ * We cannot delay the saving further than this,
+ * to prevent overwrites.
+ */
+#ifdef CONFIG_SPL_BUILD
+ save_omap_boot_params();
+#endif
+
/* WDT1 is already running when the bootloader gets control
* Disable it to avoid "random" resets
*/
diff --git a/common/board_f.c b/common/board_f.c
index 81edbdf..9fa7363 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -851,12 +851,6 @@ static init_fnc_t init_sequence_f[] = {
#ifdef CONFIG_ARM
timer_init, /* initialize timer */
#endif
-#ifdef CONFIG_BOARD_POSTCLK_INIT
- board_postclk_init,
-#endif
-#ifdef CONFIG_FSL_ESDHC
- get_clocks,
-#endif
#ifdef CONFIG_SYS_ALLOC_DPRAM
#if !defined(CONFIG_CPM2)
dpram_init,
@@ -865,6 +859,9 @@ static init_fnc_t init_sequence_f[] = {
#if defined(CONFIG_BOARD_POSTCLK_INIT)
board_postclk_init,
#endif
+#ifdef CONFIG_FSL_ESDHC
+ get_clocks,
+#endif
env_init, /* initialize environment */
#if defined(CONFIG_8xx_CPUCLK_DEFAULT)
/* get CPU and bus clocks according to the environment variable */
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 15f4599..05130b6 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -93,11 +93,6 @@ static int do_imls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
static void fixup_silent_linux(void);
#endif
-static image_header_t *image_get_kernel(ulong img_addr, int verify);
-#if defined(CONFIG_FIT)
-static int fit_check_kernel(const void *fit, int os_noffset, int verify);
-#endif
-
static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[], bootm_headers_t *images,
ulong *os_data, ulong *os_len);
@@ -306,7 +301,7 @@ static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
#if defined(CONFIG_OF_LIBFDT)
/* find flattened device tree */
- ret = boot_get_fdt(flag, argc, argv, &images,
+ ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images,
&images.ft_addr, &images.ft_len);
if (ret) {
puts("Could not find a valid device tree\n");
@@ -336,12 +331,15 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
ulong image_len = os.image_len;
__maybe_unused uint unc_len = CONFIG_SYS_BOOTM_LEN;
int no_overlap = 0;
+ void *load_buf, *image_buf;
#if defined(CONFIG_LZMA) || defined(CONFIG_LZO)
int ret;
#endif /* defined(CONFIG_LZMA) || defined(CONFIG_LZO) */
const char *type_name = genimg_get_type_name(os.type);
+ load_buf = map_sysmem(load, image_len);
+ image_buf = map_sysmem(image_start, image_len);
switch (comp) {
case IH_COMP_NONE:
if (load == blob_start || load == image_start) {
@@ -349,8 +347,7 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
no_overlap = 1;
} else {
printf(" Loading %s ... ", type_name);
- memmove_wd((void *)load, (void *)image_start,
- image_len, CHUNKSZ);
+ memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);
}
*load_end = load + image_len;
puts("OK\n");
@@ -358,8 +355,7 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
#ifdef CONFIG_GZIP
case IH_COMP_GZIP:
printf(" Uncompressing %s ... ", type_name);
- if (gunzip((void *)load, unc_len,
- (uchar *)image_start, &image_len) != 0) {
+ if (gunzip(load_buf, unc_len, image_buf, &image_len) != 0) {
puts("GUNZIP: uncompress, out-of-mem or overwrite "
"error - must RESET board to recover\n");
if (boot_progress)
@@ -378,9 +374,9 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
* use slower decompression algorithm which requires
* at most 2300 KB of memory.
*/
- int i = BZ2_bzBuffToBuffDecompress((char *)load,
- &unc_len, (char *)image_start, image_len,
- CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
+ int i = BZ2_bzBuffToBuffDecompress(load_buf, &unc_len,
+ image_buf, image_len,
+ CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
if (i != BZ_OK) {
printf("BUNZIP2: uncompress or overwrite error %d "
"- must RESET board to recover\n", i);
@@ -397,9 +393,8 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
SizeT lzma_len = unc_len;
printf(" Uncompressing %s ... ", type_name);
- ret = lzmaBuffToBuffDecompress(
- (unsigned char *)load, &lzma_len,
- (unsigned char *)image_start, image_len);
+ ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len,
+ image_buf, image_len);
unc_len = lzma_len;
if (ret != SZ_OK) {
printf("LZMA: uncompress or overwrite error %d "
@@ -415,9 +410,8 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
case IH_COMP_LZO:
printf(" Uncompressing %s ... ", type_name);
- ret = lzop_decompress((const unsigned char *)image_start,
- image_len, (unsigned char *)load,
- &unc_len);
+ ret = lzop_decompress(image_buf, image_len, load_buf,
+ &unc_len);
if (ret != LZO_E_OK) {
printf("LZO: uncompress or overwrite error %d "
"- must RESET board to recover\n", ret);
@@ -797,54 +791,6 @@ static image_header_t *image_get_kernel(ulong img_addr, int verify)
}
/**
- * fit_check_kernel - verify FIT format kernel subimage
- * @fit_hdr: pointer to the FIT image header
- * os_noffset: kernel subimage node offset within FIT image
- * @verify: data CRC verification flag
- *
- * fit_check_kernel() verifies integrity of the kernel subimage and from
- * specified FIT image.
- *
- * returns:
- * 1, on success
- * 0, on failure
- */
-#if defined(CONFIG_FIT)
-static int fit_check_kernel(const void *fit, int os_noffset, int verify)
-{
- fit_image_print(fit, os_noffset, " ");
-
- if (verify) {
- puts(" Verifying Hash Integrity ... ");
- if (!fit_image_verify(fit, os_noffset)) {
- puts("Bad Data Hash\n");
- bootstage_error(BOOTSTAGE_ID_FIT_CHECK_HASH);
- return 0;
- }
- puts("OK\n");
- }
- bootstage_mark(BOOTSTAGE_ID_FIT_CHECK_ARCH);
-
- if (!fit_image_check_target_arch(fit, os_noffset)) {
- puts("Unsupported Architecture\n");
- bootstage_error(BOOTSTAGE_ID_FIT_CHECK_ARCH);
- return 0;
- }
-
- bootstage_mark(BOOTSTAGE_ID_FIT_CHECK_KERNEL);
- if (!fit_image_check_type(fit, os_noffset, IH_TYPE_KERNEL) &&
- !fit_image_check_type(fit, os_noffset, IH_TYPE_KERNEL_NOLOAD)) {
- puts("Not a kernel image\n");
- bootstage_error(BOOTSTAGE_ID_FIT_CHECK_KERNEL);
- return 0;
- }
-
- bootstage_mark(BOOTSTAGE_ID_FIT_CHECKED);
- return 1;
-}
-#endif /* CONFIG_FIT */
-
-/**
* boot_get_kernel - find kernel image
* @os_data: pointer to a ulong variable, will hold os data start address
* @os_len: pointer to a ulong variable, will hold os data length
@@ -864,12 +810,8 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
ulong img_addr;
const void *buf;
#if defined(CONFIG_FIT)
- const void *fit_hdr;
const char *fit_uname_config = NULL;
const char *fit_uname_kernel = NULL;
- const void *data;
- size_t len;
- int cfg_noffset;
int os_noffset;
#endif
@@ -946,84 +888,16 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
break;
#if defined(CONFIG_FIT)
case IMAGE_FORMAT_FIT:
- fit_hdr = buf;
- printf("## Booting kernel from FIT Image at %08lx ...\n",
- img_addr);
-
- if (!fit_check_format(fit_hdr)) {
- puts("Bad FIT kernel image format!\n");
- bootstage_error(BOOTSTAGE_ID_FIT_FORMAT);
+ os_noffset = fit_image_load(images, FIT_KERNEL_PROP,
+ img_addr,
+ &fit_uname_kernel, fit_uname_config,
+ IH_ARCH_DEFAULT, IH_TYPE_KERNEL,
+ BOOTSTAGE_ID_FIT_KERNEL_START,
+ FIT_LOAD_IGNORED, os_data, os_len);
+ if (os_noffset < 0)
return NULL;
- }
- bootstage_mark(BOOTSTAGE_ID_FIT_FORMAT);
-
- if (!fit_uname_kernel) {
- /*
- * no kernel image node unit name, try to get config
- * node first. If config unit node name is NULL
- * fit_conf_get_node() will try to find default config
- * node
- */
- bootstage_mark(BOOTSTAGE_ID_FIT_NO_UNIT_NAME);
-#ifdef CONFIG_FIT_BEST_MATCH
- if (fit_uname_config)
- cfg_noffset =
- fit_conf_get_node(fit_hdr,
- fit_uname_config);
- else
- cfg_noffset =
- fit_conf_find_compat(fit_hdr,
- gd->fdt_blob);
-#else
- cfg_noffset = fit_conf_get_node(fit_hdr,
- fit_uname_config);
-#endif
- if (cfg_noffset < 0) {
- bootstage_error(BOOTSTAGE_ID_FIT_NO_UNIT_NAME);
- return NULL;
- }
- /* save configuration uname provided in the first
- * bootm argument
- */
- images->fit_uname_cfg = fdt_get_name(fit_hdr,
- cfg_noffset,
- NULL);
- printf(" Using '%s' configuration\n",
- images->fit_uname_cfg);
- bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);
-
- os_noffset = fit_conf_get_kernel_node(fit_hdr,
- cfg_noffset);
- fit_uname_kernel = fit_get_name(fit_hdr, os_noffset,
- NULL);
- } else {
- /* get kernel component image node offset */
- bootstage_mark(BOOTSTAGE_ID_FIT_UNIT_NAME);
- os_noffset = fit_image_get_node(fit_hdr,
- fit_uname_kernel);
- }
- if (os_noffset < 0) {
- bootstage_error(BOOTSTAGE_ID_FIT_CONFIG);
- return NULL;
- }
-
- printf(" Trying '%s' kernel subimage\n", fit_uname_kernel);
-
- bootstage_mark(BOOTSTAGE_ID_FIT_CHECK_SUBIMAGE);
- if (!fit_check_kernel(fit_hdr, os_noffset, images->verify))
- return NULL;
-
- /* get kernel image data address and length */
- if (fit_image_get_data(fit_hdr, os_noffset, &data, &len)) {
- puts("Could not find kernel subimage data!\n");
- bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO_ERR);
- return NULL;
- }
- bootstage_mark(BOOTSTAGE_ID_FIT_KERNEL_INFO);
- *os_len = len;
- *os_data = (ulong)data;
- images->fit_hdr_os = (void *)fit_hdr;
+ images->fit_hdr_os = map_sysmem(img_addr, 0);
images->fit_uname_os = fit_uname_kernel;
images->fit_noffset_os = os_noffset;
break;
@@ -1820,7 +1694,7 @@ static int bootz_start(cmd_tbl_t *cmdtp, int flag, int argc,
#if defined(CONFIG_OF_LIBFDT)
/* find flattened device tree */
- ret = boot_get_fdt(flag, argc, argv, images,
+ ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, images,
&images->ft_addr, &images->ft_len);
if (ret) {
puts("Could not find a valid device tree\n");
diff --git a/common/cmd_fitupd.c b/common/cmd_fitupd.c
index 7a3789e..618ff7c 100644
--- a/common/cmd_fitupd.c
+++ b/common/cmd_fitupd.c
@@ -8,13 +8,12 @@
#include <common.h>
#include <command.h>
+#include <net.h>
#if !defined(CONFIG_UPDATE_TFTP)
#error "CONFIG_UPDATE_TFTP required"
#endif
-extern int update_tftp(ulong addr);
-
static int do_fitupd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
ulong addr = 0UL;
diff --git a/common/image-fdt.c b/common/image-fdt.c
index 158c9cf..0d421d9 100644
--- a/common/image-fdt.c
+++ b/common/image-fdt.c
@@ -211,51 +211,11 @@ error:
return 1;
}
-#if defined(CONFIG_FIT)
-/**
- * fit_check_fdt - verify FIT format FDT subimage
- * @fit_hdr: pointer to the FIT header
- * fdt_noffset: FDT subimage node offset within FIT image
- * @verify: data CRC verification flag
- *
- * fit_check_fdt() verifies integrity of the FDT subimage and from
- * specified FIT image.
- *
- * returns:
- * 1, on success
- * 0, on failure
- */
-static int fit_check_fdt(const void *fit, int fdt_noffset, int verify)
-{
- fit_image_print(fit, fdt_noffset, " ");
-
- if (verify) {
- puts(" Verifying Hash Integrity ... ");
- if (!fit_image_verify(fit, fdt_noffset)) {
- fdt_error("Bad Data Hash");
- return 0;
- }
- puts("OK\n");
- }
-
- if (!fit_image_check_type(fit, fdt_noffset, IH_TYPE_FLATDT)) {
- fdt_error("Not a FDT image");
- return 0;
- }
-
- if (!fit_image_check_comp(fit, fdt_noffset, IH_COMP_NONE)) {
- fdt_error("FDT image is compressed");
- return 0;
- }
-
- return 1;
-}
-#endif
-
/**
* boot_get_fdt - main fdt handling routine
* @argc: command argument count
* @argv: command argument list
+ * @arch: architecture (IH_ARCH_...)
* @images: pointer to the bootm images structure
* @of_flat_tree: pointer to a char* variable, will hold fdt start address
* @of_size: pointer to a ulong variable, will hold fdt length
@@ -273,24 +233,20 @@ static int fit_check_fdt(const void *fit, int fdt_noffset, int verify)
* 1, if fdt image is found but corrupted
* of_flat_tree and of_size are set to 0 if no fdt exists
*/
-int boot_get_fdt(int flag, int argc, char * const argv[],
+int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch,
bootm_headers_t *images, char **of_flat_tree, ulong *of_size)
{
const image_header_t *fdt_hdr;
ulong fdt_addr;
char *fdt_blob = NULL;
ulong image_start, image_data, image_end;
- ulong load_start, load_end;
+ ulong load, load_end;
void *buf;
#if defined(CONFIG_FIT)
- void *fit_hdr;
const char *fit_uname_config = NULL;
const char *fit_uname_fdt = NULL;
ulong default_addr;
- int cfg_noffset;
int fdt_noffset;
- const void *data;
- size_t size;
#endif
*of_flat_tree = NULL;
@@ -333,31 +289,15 @@ int boot_get_fdt(int flag, int argc, char * const argv[],
* command argument
*/
fdt_addr = map_to_sysmem(images->fit_hdr_os);
- fit_uname_config = images->fit_uname_cfg;
- debug("* fdt: using config '%s' from image at 0x%08lx\n",
- fit_uname_config, fdt_addr);
-
- /*
- * Check whether configuration has FDT blob defined,
- * if not quit silently.
- */
- fit_hdr = images->fit_hdr_os;
- cfg_noffset = fit_conf_get_node(fit_hdr,
- fit_uname_config);
- if (cfg_noffset < 0) {
- debug("* fdt: no such config\n");
+ fdt_noffset = fit_get_node_from_config(images,
+ FIT_FDT_PROP,
+ fdt_addr);
+ if (fdt_noffset == -ENOLINK)
return 0;
- }
-
- fdt_noffset = fit_conf_get_fdt_node(fit_hdr,
- cfg_noffset);
- if (fdt_noffset < 0) {
- debug("* fdt: no fdt in config\n");
- return 0;
- }
+ else if (fdt_noffset < 0)
+ return 1;
}
#endif
-
debug("## Checking for 'FDT'/'FDT Image' at %08lx\n",
fdt_addr);
@@ -387,29 +327,28 @@ int boot_get_fdt(int flag, int argc, char * const argv[],
image_data = (ulong)image_get_data(fdt_hdr);
image_end = image_get_image_end(fdt_hdr);
- load_start = image_get_load(fdt_hdr);
- load_end = load_start + image_get_data_size(fdt_hdr);
+ load = image_get_load(fdt_hdr);
+ load_end = load + image_get_data_size(fdt_hdr);
- if (load_start == image_start ||
- load_start == image_data) {
+ if (load == image_start ||
+ load == image_data) {
fdt_blob = (char *)image_data;
break;
}
- if ((load_start < image_end) &&
- (load_end > image_start)) {
+ if ((load < image_end) && (load_end > image_start)) {
fdt_error("fdt overwritten");
goto error;
}
debug(" Loading FDT from 0x%08lx to 0x%08lx\n",
- image_data, load_start);
+ image_data, load);
- memmove((void *)load_start,
+ memmove((void *)load,
(void *)image_data,
image_get_data_size(fdt_hdr));
- fdt_blob = (char *)load_start;
+ fdt_addr = load;
break;
case IMAGE_FORMAT_FIT:
/*
@@ -420,107 +359,20 @@ int boot_get_fdt(int flag, int argc, char * const argv[],
#if defined(CONFIG_FIT)
/* check FDT blob vs FIT blob */
if (fit_check_format(buf)) {
- /*
- * FIT image
- */
- fit_hdr = buf;
- printf("## Flattened Device Tree from FIT Image at %08lx\n",
- fdt_addr);
-
- if (!fit_uname_fdt) {
- /*
- * no FDT blob image node unit name,
- * try to get config node first. If
- * config unit node name is NULL
- * fit_conf_get_node() will try to
- * find default config node
- */
- cfg_noffset = fit_conf_get_node(fit_hdr,
- fit_uname_config);
-
- if (cfg_noffset < 0) {
- fdt_error("Could not find configuration node\n");
- goto error;
- }
-
- fit_uname_config = fdt_get_name(fit_hdr,
- cfg_noffset, NULL);
- printf(" Using '%s' configuration\n",
- fit_uname_config);
-
- fdt_noffset = fit_conf_get_fdt_node(
- fit_hdr,
- cfg_noffset);
- fit_uname_fdt = fit_get_name(fit_hdr,
- fdt_noffset, NULL);
- } else {
- /*
- * get FDT component image node
- * offset
- */
- fdt_noffset = fit_image_get_node(
- fit_hdr,
- fit_uname_fdt);
- }
- if (fdt_noffset < 0) {
- fdt_error("Could not find subimage node\n");
- goto error;
- }
-
- printf(" Trying '%s' FDT blob subimage\n",
- fit_uname_fdt);
-
- if (!fit_check_fdt(fit_hdr, fdt_noffset,
- images->verify))
- goto error;
-
- /* get ramdisk image data address and length */
- if (fit_image_get_data(fit_hdr, fdt_noffset,
- &data, &size)) {
- fdt_error("Could not find FDT subimage data");
- goto error;
- }
+ ulong load, len;
- /*
- * verify that image data is a proper FDT
- * blob
- */
- if (fdt_check_header((char *)data) != 0) {
- fdt_error("Subimage data is not a FTD");
- goto error;
- }
-
- /*
- * move image data to the load address,
- * make sure we don't overwrite initial image
- */
- image_start = (ulong)fit_hdr;
- image_end = fit_get_end(fit_hdr);
-
- if (fit_image_get_load(fit_hdr, fdt_noffset,
- &load_start) == 0) {
- load_end = load_start + size;
+ fdt_noffset = fit_image_load(images,
+ FIT_FDT_PROP,
+ fdt_addr, &fit_uname_fdt,
+ fit_uname_config,
+ arch, IH_TYPE_FLATDT,
+ BOOTSTAGE_ID_FIT_FDT_START,
+ FIT_LOAD_OPTIONAL, &load, &len);
- if ((load_start < image_end) &&
- (load_end > image_start)) {
- fdt_error("FDT overwritten");
- goto error;
- }
-
- printf(" Loading FDT from 0x%08lx to 0x%08lx\n",
- (ulong)data, load_start);
-
- memmove((void *)load_start,
- (void *)data, size);
-
- fdt_blob = (char *)load_start;
- } else {
- fdt_blob = (char *)data;
- }
-
- images->fit_hdr_fdt = fit_hdr;
+ images->fit_hdr_fdt = map_sysmem(fdt_addr, 0);
images->fit_uname_fdt = fit_uname_fdt;
images->fit_noffset_fdt = fdt_noffset;
+ fdt_addr = load;
break;
} else
#endif
@@ -528,7 +380,6 @@ int boot_get_fdt(int flag, int argc, char * const argv[],
/*
* FDT blob
*/
- fdt_blob = buf;
debug("* fdt: raw FDT blob\n");
printf("## Flattened Device Tree blob at %08lx\n",
(long)fdt_addr);
@@ -539,8 +390,8 @@ int boot_get_fdt(int flag, int argc, char * const argv[],
goto error;
}
- printf(" Booting using the fdt blob at 0x%p\n", fdt_blob);
-
+ printf(" Booting using the fdt blob at %#08lx\n", fdt_addr);
+ fdt_blob = map_sysmem(fdt_addr, 0);
} else if (images->legacy_hdr_valid &&
image_check_type(&images->legacy_hdr_os_copy,
IH_TYPE_MULTI)) {
diff --git a/common/image-fit.c b/common/image-fit.c
index 254feec..7bf82d3 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -31,6 +31,9 @@
#include <time.h>
#else
#include <common.h>
+#include <errno.h>
+#include <asm/io.h>
+DECLARE_GLOBAL_DATA_PTR;
#endif /* !USE_HOSTCC*/
#include <bootstage.h>
@@ -348,10 +351,13 @@ void fit_image_print(const void *fit, int image_noffset, const char *p)
#ifndef USE_HOSTCC
printf("%s Data Start: ", p);
- if (ret)
+ if (ret) {
printf("unavailable\n");
- else
- printf("0x%08lx\n", (ulong)data);
+ } else {
+ void *vdata = (void *)data;
+
+ printf("0x%08lx\n", (ulong)map_to_sysmem(vdata));
+ }
#endif
printf("%s Data Size: ", p);
@@ -1349,63 +1355,6 @@ int fit_conf_get_prop_node(const void *fit, int noffset,
}
/**
- * fit_conf_get_kernel_node - get kernel image node offset that corresponds to
- * a given configuration
- * @fit: pointer to the FIT format image header
- * @noffset: configuration node offset
- *
- * fit_conf_get_kernel_node() retrives kernel image node unit name from
- * configuration FIT_KERNEL_PROP property and translates it to the node
- * offset.
- *
- * returns:
- * image node offset when found (>=0)
- * negative number on failure (FDT_ERR_* code)
- */
-int fit_conf_get_kernel_node(const void *fit, int noffset)
-{
- return fit_conf_get_prop_node(fit, noffset, FIT_KERNEL_PROP);
-}
-
-/**
- * fit_conf_get_ramdisk_node - get ramdisk image node offset that corresponds to
- * a given configuration
- * @fit: pointer to the FIT format image header
- * @noffset: configuration node offset
- *
- * fit_conf_get_ramdisk_node() retrives ramdisk image node unit name from
- * configuration FIT_KERNEL_PROP property and translates it to the node
- * offset.
- *
- * returns:
- * image node offset when found (>=0)
- * negative number on failure (FDT_ERR_* code)
- */
-int fit_conf_get_ramdisk_node(const void *fit, int noffset)
-{
- return fit_conf_get_prop_node(fit, noffset, FIT_RAMDISK_PROP);
-}
-
-/**
- * fit_conf_get_fdt_node - get fdt image node offset that corresponds to
- * a given configuration
- * @fit: pointer to the FIT format image header
- * @noffset: configuration node offset
- *
- * fit_conf_get_fdt_node() retrives fdt image node unit name from
- * configuration FIT_KERNEL_PROP property and translates it to the node
- * offset.
- *
- * returns:
- * image node offset when found (>=0)
- * negative number on failure (FDT_ERR_* code)
- */
-int fit_conf_get_fdt_node(const void *fit, int noffset)
-{
- return fit_conf_get_prop_node(fit, noffset, FIT_FDT_PROP);
-}
-
-/**
* fit_conf_print - prints out the FIT configuration details
* @fit: pointer to the FIT format image header
* @noffset: offset of the configuration node
@@ -1448,22 +1397,7 @@ void fit_conf_print(const void *fit, int noffset, const char *p)
printf("%s FDT: %s\n", p, uname);
}
-/**
- * fit_check_ramdisk - verify FIT format ramdisk subimage
- * @fit_hdr: pointer to the FIT ramdisk header
- * @rd_noffset: ramdisk subimage node offset within FIT image
- * @arch: requested ramdisk image architecture type
- * @verify: data CRC verification flag
- *
- * fit_check_ramdisk() verifies integrity of the ramdisk subimage and from
- * specified FIT image.
- *
- * returns:
- * 1, on success
- * 0, on failure
- */
-int fit_check_ramdisk(const void *fit, int rd_noffset, uint8_t arch,
- int verify)
+int fit_image_select(const void *fit, int rd_noffset, int verify)
{
fit_image_print(fit, rd_noffset, " ");
@@ -1471,22 +1405,222 @@ int fit_check_ramdisk(const void *fit, int rd_noffset, uint8_t arch,
puts(" Verifying Hash Integrity ... ");
if (!fit_image_verify(fit, rd_noffset)) {
puts("Bad Data Hash\n");
- bootstage_error(BOOTSTAGE_ID_FIT_RD_HASH);
- return 0;
+ return -EACCES;
}
puts("OK\n");
}
- bootstage_mark(BOOTSTAGE_ID_FIT_RD_CHECK_ALL);
- if (!fit_image_check_os(fit, rd_noffset, IH_OS_LINUX) ||
- !fit_image_check_arch(fit, rd_noffset, arch) ||
- !fit_image_check_type(fit, rd_noffset, IH_TYPE_RAMDISK)) {
- printf("No Linux %s Ramdisk Image\n",
- genimg_get_arch_name(arch));
- bootstage_error(BOOTSTAGE_ID_FIT_RD_CHECK_ALL);
- return 0;
+ return 0;
+}
+
+int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name,
+ ulong addr)
+{
+ int cfg_noffset;
+ void *fit_hdr;
+ int noffset;
+
+ debug("* %s: using config '%s' from image at 0x%08lx\n",
+ prop_name, images->fit_uname_cfg, addr);
+
+ /* Check whether configuration has this property defined */
+ fit_hdr = map_sysmem(addr, 0);
+ cfg_noffset = fit_conf_get_node(fit_hdr, images->fit_uname_cfg);
+ if (cfg_noffset < 0) {
+ debug("* %s: no such config\n", prop_name);
+ return -ENOENT;
}
- bootstage_mark(BOOTSTAGE_ID_FIT_RD_CHECK_ALL_OK);
- return 1;
+ noffset = fit_conf_get_prop_node(fit_hdr, cfg_noffset, prop_name);
+ if (noffset < 0) {
+ debug("* %s: no '%s' in config\n", prop_name, prop_name);
+ return -ENOLINK;
+ }
+
+ return noffset;
+}
+
+int fit_image_load(bootm_headers_t *images, const char *prop_name, ulong addr,
+ const char **fit_unamep, const char *fit_uname_config,
+ int arch, int image_type, int bootstage_id,
+ enum fit_load_op load_op, ulong *datap, ulong *lenp)
+{
+ int cfg_noffset, noffset;
+ const char *fit_uname;
+ const void *fit;
+ const void *buf;
+ size_t size;
+ int type_ok, os_ok;
+ ulong load, data, len;
+ int ret;
+
+ fit = map_sysmem(addr, 0);
+ fit_uname = fit_unamep ? *fit_unamep : NULL;
+ printf("## Loading %s from FIT Image at %08lx ...\n", prop_name, addr);
+
+ bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT);
+ if (!fit_check_format(fit)) {
+ printf("Bad FIT %s image format!\n", prop_name);
+ bootstage_error(bootstage_id + BOOTSTAGE_SUB_FORMAT);
+ return -ENOEXEC;
+ }
+ bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT_OK);
+ if (fit_uname) {
+ /* get ramdisk component image node offset */
+ bootstage_mark(bootstage_id + BOOTSTAGE_SUB_UNIT_NAME);
+ noffset = fit_image_get_node(fit, fit_uname);
+ } else {
+ /*
+ * no image node unit name, try to get config
+ * node first. If config unit node name is NULL
+ * fit_conf_get_node() will try to find default config node
+ */
+ bootstage_mark(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME);
+ if (IMAGE_ENABLE_BEST_MATCH && !fit_uname_config) {
+ cfg_noffset = fit_conf_find_compat(fit, gd_fdt_blob());
+ } else {
+ cfg_noffset = fit_conf_get_node(fit,
+ fit_uname_config);
+ }
+ if (cfg_noffset < 0) {
+ puts("Could not find configuration node\n");
+ bootstage_error(bootstage_id +
+ BOOTSTAGE_SUB_NO_UNIT_NAME);
+ return -ENOENT;
+ }
+ fit_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
+ printf(" Using '%s' configuration\n", fit_uname_config);
+ if (image_type == IH_TYPE_KERNEL) {
+ /* Remember (and possibly verify) this config */
+ images->fit_uname_cfg = fit_uname_config;
+ if (IMAGE_ENABLE_VERIFY && images->verify) {
+ puts(" Verifying Hash Integrity ... ");
+ if (!fit_config_verify(fit, cfg_noffset)) {
+ puts("Bad Data Hash\n");
+ bootstage_error(bootstage_id +
+ BOOTSTAGE_SUB_HASH);
+ return -EACCES;
+ }
+ puts("OK\n");
+ }
+ bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);
+ }
+
+ noffset = fit_conf_get_prop_node(fit, cfg_noffset,
+ prop_name);
+ fit_uname = fit_get_name(fit, noffset, NULL);
+ }
+ if (noffset < 0) {
+ puts("Could not find subimage node\n");
+ bootstage_error(bootstage_id + BOOTSTAGE_SUB_SUBNODE);
+ return -ENOENT;
+ }
+
+ printf(" Trying '%s' %s subimage\n", fit_uname, prop_name);
+
+ ret = fit_image_select(fit, noffset, images->verify);
+ if (ret) {
+ bootstage_error(bootstage_id + BOOTSTAGE_SUB_HASH);
+ return ret;
+ }
+
+ bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
+ if (!fit_image_check_target_arch(fit, noffset)) {
+ puts("Unsupported Architecture\n");
+ bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
+ return -ENOEXEC;
+ }
+
+ if (image_type == IH_TYPE_FLATDT &&
+ !fit_image_check_comp(fit, noffset, IH_COMP_NONE)) {
+ puts("FDT image is compressed");
+ return -EPROTONOSUPPORT;
+ }
+
+ bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
+ type_ok = fit_image_check_type(fit, noffset, image_type) ||
+ (image_type == IH_TYPE_KERNEL &&
+ fit_image_check_type(fit, noffset,
+ IH_TYPE_KERNEL_NOLOAD));
+ os_ok = image_type == IH_TYPE_FLATDT ||
+ fit_image_check_os(fit, noffset, IH_OS_LINUX);
+ if (!type_ok || !os_ok) {
+ printf("No Linux %s %s Image\n", genimg_get_arch_name(arch),
+ genimg_get_type_name(image_type));
+ bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
+ return -EIO;
+ }
+
+ bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK);
+
+ /* get image data address and length */
+ if (fit_image_get_data(fit, noffset, &buf, &size)) {
+ printf("Could not find %s subimage data!\n", prop_name);
+ bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA);
+ return -ENOMEDIUM;
+ }
+ len = (ulong)size;
+
+ /* verify that image data is a proper FDT blob */
+ if (image_type == IH_TYPE_FLATDT && fdt_check_header((char *)buf)) {
+ puts("Subimage data is not a FDT");
+ return -ENOEXEC;
+ }
+
+ bootstage_mark(bootstage_id + BOOTSTAGE_SUB_GET_DATA_OK);
+
+ /*
+ * Work-around for eldk-4.2 which gives this warning if we try to
+ * case in the unmap_sysmem() call:
+ * warning: initialization discards qualifiers from pointer target type
+ */
+ {
+ void *vbuf = (void *)buf;
+
+ data = map_to_sysmem(vbuf);
+ }
+
+ if (load_op == FIT_LOAD_IGNORED) {
+ /* Don't load */
+ } else if (fit_image_get_load(fit, noffset, &load)) {
+ if (load_op == FIT_LOAD_REQUIRED) {
+ printf("Can't get %s subimage load address!\n",
+ prop_name);
+ bootstage_error(bootstage_id + BOOTSTAGE_SUB_LOAD);
+ return -EBADF;
+ }
+ } else {
+ ulong image_start, image_end;
+ ulong load_end;
+ void *dst;
+
+ /*
+ * move image data to the load address,
+ * make sure we don't overwrite initial image
+ */
+ image_start = addr;
+ image_end = addr + fit_get_size(fit);
+
+ load_end = load + len;
+ if (image_type != IH_TYPE_KERNEL &&
+ load < image_end && load_end > image_start) {
+ printf("Error: %s overwritten\n", prop_name);
+ return -EXDEV;
+ }
+
+ printf(" Loading %s from 0x%08lx to 0x%08lx\n",
+ prop_name, data, load);
+
+ dst = map_sysmem(load, len);
+ memmove(dst, buf, len);
+ data = load;
+ }
+ bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD);
+
+ *datap = data;
+ *lenp = len;
+ if (fit_unamep)
+ *fit_unamep = (char *)fit_uname;
+
+ return noffset;
}
diff --git a/common/image.c b/common/image.c
index e91c89e..f863502 100644
--- a/common/image.c
+++ b/common/image.c
@@ -51,6 +51,7 @@
#include <u-boot/md5.h>
#include <sha1.h>
+#include <asm/errno.h>
#include <asm/io.h>
#ifdef CONFIG_CMD_BDI
@@ -810,14 +811,10 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
char *end;
#endif
#if defined(CONFIG_FIT)
- void *fit_hdr;
const char *fit_uname_config = NULL;
const char *fit_uname_ramdisk = NULL;
ulong default_addr;
int rd_noffset;
- int cfg_noffset;
- const void *data;
- size_t size;
#endif
*rd_start = 0;
@@ -865,32 +862,16 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
#if defined(CONFIG_FIT)
} else {
/* use FIT configuration provided in first bootm
- * command argument
+ * command argument. If the property is not defined,
+ * quit silently.
*/
rd_addr = map_to_sysmem(images->fit_hdr_os);
- fit_uname_config = images->fit_uname_cfg;
- debug("* ramdisk: using config '%s' from image "
- "at 0x%08lx\n",
- fit_uname_config, rd_addr);
-
- /*
- * Check whether configuration has ramdisk defined,
- * if not, don't try to use it, quit silently.
- */
- fit_hdr = images->fit_hdr_os;
- cfg_noffset = fit_conf_get_node(fit_hdr,
- fit_uname_config);
- if (cfg_noffset < 0) {
- debug("* ramdisk: no such config\n");
- return 1;
- }
-
- rd_noffset = fit_conf_get_ramdisk_node(fit_hdr,
- cfg_noffset);
- if (rd_noffset < 0) {
- debug("* ramdisk: no ramdisk in config\n");
+ rd_noffset = fit_get_node_from_config(images,
+ FIT_RAMDISK_PROP, rd_addr);
+ if (rd_noffset == -ENOLINK)
return 0;
- }
+ else if (rd_noffset < 0)
+ return 1;
}
#endif
@@ -921,87 +902,16 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
break;
#if defined(CONFIG_FIT)
case IMAGE_FORMAT_FIT:
- fit_hdr = buf;
- printf("## Loading init Ramdisk from FIT "
- "Image at %08lx ...\n", rd_addr);
-
- bootstage_mark(BOOTSTAGE_ID_FIT_RD_FORMAT);
- if (!fit_check_format(fit_hdr)) {
- puts("Bad FIT ramdisk image format!\n");
- bootstage_error(
- BOOTSTAGE_ID_FIT_RD_FORMAT);
+ rd_noffset = fit_image_load(images, FIT_RAMDISK_PROP,
+ rd_addr, &fit_uname_ramdisk,
+ fit_uname_config, arch,
+ IH_TYPE_RAMDISK,
+ BOOTSTAGE_ID_FIT_RD_START,
+ FIT_LOAD_REQUIRED, &rd_data, &rd_len);
+ if (rd_noffset < 0)
return 1;
- }
- bootstage_mark(BOOTSTAGE_ID_FIT_RD_FORMAT_OK);
-
- if (!fit_uname_ramdisk) {
- /*
- * no ramdisk image node unit name, try to get config
- * node first. If config unit node name is NULL
- * fit_conf_get_node() will try to find default config node
- */
- bootstage_mark(
- BOOTSTAGE_ID_FIT_RD_NO_UNIT_NAME);
- cfg_noffset = fit_conf_get_node(fit_hdr,
- fit_uname_config);
- if (cfg_noffset < 0) {
- puts("Could not find configuration "
- "node\n");
- bootstage_error(
- BOOTSTAGE_ID_FIT_RD_NO_UNIT_NAME);
- return 1;
- }
- fit_uname_config = fdt_get_name(fit_hdr,
- cfg_noffset, NULL);
- printf(" Using '%s' configuration\n",
- fit_uname_config);
-
- rd_noffset = fit_conf_get_ramdisk_node(fit_hdr,
- cfg_noffset);
- fit_uname_ramdisk = fit_get_name(fit_hdr,
- rd_noffset, NULL);
- } else {
- /* get ramdisk component image node offset */
- bootstage_mark(
- BOOTSTAGE_ID_FIT_RD_UNIT_NAME);
- rd_noffset = fit_image_get_node(fit_hdr,
- fit_uname_ramdisk);
- }
- if (rd_noffset < 0) {
- puts("Could not find subimage node\n");
- bootstage_error(BOOTSTAGE_ID_FIT_RD_SUBNODE);
- return 1;
- }
-
- printf(" Trying '%s' ramdisk subimage\n",
- fit_uname_ramdisk);
-
- bootstage_mark(BOOTSTAGE_ID_FIT_RD_CHECK);
- if (!fit_check_ramdisk(fit_hdr, rd_noffset, arch,
- images->verify))
- return 1;
-
- /* get ramdisk image data address and length */
- if (fit_image_get_data(fit_hdr, rd_noffset, &data,
- &size)) {
- puts("Could not find ramdisk subimage data!\n");
- bootstage_error(BOOTSTAGE_ID_FIT_RD_GET_DATA);
- return 1;
- }
- bootstage_mark(BOOTSTAGE_ID_FIT_RD_GET_DATA_OK);
-
- rd_data = (ulong)data;
- rd_len = size;
-
- if (fit_image_get_load(fit_hdr, rd_noffset, &rd_load)) {
- puts("Can't get ramdisk subimage load "
- "address!\n");
- bootstage_error(BOOTSTAGE_ID_FIT_RD_LOAD);
- return 1;
- }
- bootstage_mark(BOOTSTAGE_ID_FIT_RD_LOAD);
- images->fit_hdr_rd = fit_hdr;
+ images->fit_hdr_rd = map_sysmem(rd_addr, 0);
images->fit_uname_rd = fit_uname_ramdisk;
images->fit_noffset_rd = rd_noffset;
break;
diff --git a/common/main.c b/common/main.c
index 953ef29..56da214 100644
--- a/common/main.c
+++ b/common/main.c
@@ -28,26 +28,15 @@
/* #define DEBUG */
#include <common.h>
-#include <watchdog.h>
#include <command.h>
#include <fdtdec.h>
-#include <malloc.h>
-#include <version.h>
-#ifdef CONFIG_MODEM_SUPPORT
-#include <malloc.h> /* for free() prototype */
-#endif
-
-#ifdef CONFIG_SYS_HUSH_PARSER
#include <hush.h>
-#endif
-
-#ifdef CONFIG_OF_CONTROL
-#include <fdtdec.h>
-#endif
-
+#include <malloc.h>
+#include <menu.h>
#include <post.h>
+#include <version.h>
+#include <watchdog.h>
#include <linux/ctype.h>
-#include <menu.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -57,13 +46,18 @@ DECLARE_GLOBAL_DATA_PTR;
void inline __show_boot_progress (int val) {}
void show_boot_progress (int val) __attribute__((weak, alias("__show_boot_progress")));
-#if defined(CONFIG_UPDATE_TFTP)
-int update_tftp (ulong addr);
-#endif /* CONFIG_UPDATE_TFTP */
-
#define MAX_DELAY_STOP_STR 32
-#undef DEBUG_PARSER
+#define DEBUG_PARSER 0 /* set to 1 to debug */
+
+#define debug_parser(fmt, args...) \
+ debug_cond(DEBUG_PARSER, fmt, ##args)
+
+#ifndef DEBUG_BOOTKEYS
+#define DEBUG_BOOTKEYS 0
+#endif
+#define debug_bootkeys(fmt, args...) \
+ debug_cond(DEBUG_BOOTKEYS, fmt, ##args)
char console_buffer[CONFIG_SYS_CBSIZE + 1]; /* console I/O buffer */
@@ -93,10 +87,7 @@ extern void mdm_init(void); /* defined in board.c */
*/
#if defined(CONFIG_BOOTDELAY)
# if defined(CONFIG_AUTOBOOT_KEYED)
-#ifndef CONFIG_MENU
-static inline
-#endif
-int abortboot(int bootdelay)
+static int abortboot_keyed(int bootdelay)
{
int abort = 0;
uint64_t etime = endtick(bootdelay);
@@ -152,11 +143,9 @@ int abortboot(int bootdelay)
presskey_max = presskey_max > delaykey[i].len ?
presskey_max : delaykey[i].len;
-# if DEBUG_BOOTKEYS
- printf("%s key:<%s>\n",
- delaykey[i].retry ? "delay" : "stop",
- delaykey[i].str ? delaykey[i].str : "NULL");
-# endif
+ debug_bootkeys("%s key:<%s>\n",
+ delaykey[i].retry ? "delay" : "stop",
+ delaykey[i].str ? delaykey[i].str : "NULL");
}
/* In order to keep up with incoming data, check timeout only
@@ -181,10 +170,9 @@ int abortboot(int bootdelay)
memcmp (presskey + presskey_len - delaykey[i].len,
delaykey[i].str,
delaykey[i].len) == 0) {
-# if DEBUG_BOOTKEYS
- printf("got %skey\n",
- delaykey[i].retry ? "delay" : "stop");
-# endif
+ debug_bootkeys("got %skey\n",
+ delaykey[i].retry ? "delay" :
+ "stop");
# ifdef CONFIG_BOOT_RETRY_TIME
/* don't retry auto boot */
@@ -196,10 +184,8 @@ int abortboot(int bootdelay)
}
} while (!abort && get_ticks() <= etime);
-# if DEBUG_BOOTKEYS
if (!abort)
- puts("key timeout\n");
-# endif
+ debug_bootkeys("key timeout\n");
#ifdef CONFIG_SILENT_CONSOLE
if (abort)
@@ -215,10 +201,7 @@ int abortboot(int bootdelay)
static int menukey = 0;
#endif
-#ifndef CONFIG_MENU
-static inline
-#endif
-int abortboot(int bootdelay)
+static int abortboot_normal(int bootdelay)
{
int abort = 0;
unsigned long ts;
@@ -275,6 +258,15 @@ int abortboot(int bootdelay)
return abort;
}
# endif /* CONFIG_AUTOBOOT_KEYED */
+
+static int abortboot(int bootdelay)
+{
+#ifdef CONFIG_AUTOBOOT_KEYED
+ return abortboot_keyed(bootdelay);
+#else
+ return abortboot_normal(bootdelay);
+#endif
+}
#endif /* CONFIG_BOOTDELAY */
/*
@@ -342,93 +334,35 @@ static void process_fdt_options(const void *blob)
}
#endif /* CONFIG_OF_CONTROL */
-
-/****************************************************************************/
-
-void main_loop (void)
+#ifdef CONFIG_BOOTDELAY
+static void process_boot_delay(void)
{
-#ifndef CONFIG_SYS_HUSH_PARSER
- static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, };
- int len;
- int rc = 1;
- int flag;
-#endif
-#if defined(CONFIG_BOOTDELAY) && defined(CONFIG_OF_CONTROL)
+#ifdef CONFIG_OF_CONTROL
char *env;
#endif
-#if defined(CONFIG_BOOTDELAY)
char *s;
int bootdelay;
-#endif
-#ifdef CONFIG_PREBOOT
- char *p;
-#endif
#ifdef CONFIG_BOOTCOUNT_LIMIT
unsigned long bootcount = 0;
unsigned long bootlimit = 0;
- char *bcs;
- char bcs_set[16];
#endif /* CONFIG_BOOTCOUNT_LIMIT */
- bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");
-
#ifdef CONFIG_BOOTCOUNT_LIMIT
bootcount = bootcount_load();
bootcount++;
bootcount_store (bootcount);
- sprintf (bcs_set, "%lu", bootcount);
- setenv ("bootcount", bcs_set);
- bcs = getenv ("bootlimit");
- bootlimit = bcs ? simple_strtoul (bcs, NULL, 10) : 0;
+ setenv_ulong("bootcount", bootcount);
+ bootlimit = getenv_ulong("bootlimit", 10, 0);
#endif /* CONFIG_BOOTCOUNT_LIMIT */
-#ifdef CONFIG_MODEM_SUPPORT
- debug ("DEBUG: main_loop: do_mdm_init=%d\n", do_mdm_init);
- if (do_mdm_init) {
- char *str = strdup(getenv("mdm_cmd"));
- setenv ("preboot", str); /* set or delete definition */
- if (str != NULL)
- free (str);
- mdm_init(); /* wait for modem connection */
- }
-#endif /* CONFIG_MODEM_SUPPORT */
-
-#ifdef CONFIG_VERSION_VARIABLE
- {
- setenv ("ver", version_string); /* set version variable */
- }
-#endif /* CONFIG_VERSION_VARIABLE */
-
-#ifdef CONFIG_SYS_HUSH_PARSER
- u_boot_hush_start ();
-#endif
-
-#if defined(CONFIG_HUSH_INIT_VAR)
- hush_init_var ();
-#endif
-
-#ifdef CONFIG_PREBOOT
- if ((p = getenv ("preboot")) != NULL) {
-# ifdef CONFIG_AUTOBOOT_KEYED
- int prev = disable_ctrlc(1); /* disable Control C checking */
-# endif
-
- run_command_list(p, -1, 0);
-
-# ifdef CONFIG_AUTOBOOT_KEYED
- disable_ctrlc(prev); /* restore Control C checking */
-# endif
- }
-#endif /* CONFIG_PREBOOT */
-
-#if defined(CONFIG_UPDATE_TFTP)
- update_tftp (0UL);
-#endif /* CONFIG_UPDATE_TFTP */
-
-#if defined(CONFIG_BOOTDELAY)
s = getenv ("bootdelay");
bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;
+#ifdef CONFIG_OF_CONTROL
+ bootdelay = fdtdec_get_config_int(gd->fdt_blob, "bootdelay",
+ bootdelay);
+#endif
+
debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);
#if defined(CONFIG_MENU_SHOW)
@@ -474,26 +408,88 @@ void main_loop (void)
debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");
if (bootdelay != -1 && s && !abortboot(bootdelay)) {
-# ifdef CONFIG_AUTOBOOT_KEYED
+#ifdef CONFIG_AUTOBOOT_KEYED
int prev = disable_ctrlc(1); /* disable Control C checking */
-# endif
+#endif
run_command_list(s, -1, 0);
-# ifdef CONFIG_AUTOBOOT_KEYED
+#ifdef CONFIG_AUTOBOOT_KEYED
disable_ctrlc(prev); /* restore Control C checking */
-# endif
+#endif
}
-# ifdef CONFIG_MENUKEY
+#ifdef CONFIG_MENUKEY
if (menukey == CONFIG_MENUKEY) {
s = getenv("menucmd");
if (s)
run_command_list(s, -1, 0);
}
#endif /* CONFIG_MENUKEY */
+}
#endif /* CONFIG_BOOTDELAY */
+void main_loop(void)
+{
+#ifndef CONFIG_SYS_HUSH_PARSER
+ static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, };
+ int len;
+ int rc = 1;
+ int flag;
+#endif
+#ifdef CONFIG_PREBOOT
+ char *p;
+#endif
+
+ bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");
+
+#ifdef CONFIG_MODEM_SUPPORT
+ debug("DEBUG: main_loop: do_mdm_init=%d\n", do_mdm_init);
+ if (do_mdm_init) {
+ char *str = strdup(getenv("mdm_cmd"));
+ setenv("preboot", str); /* set or delete definition */
+ if (str != NULL)
+ free(str);
+ mdm_init(); /* wait for modem connection */
+ }
+#endif /* CONFIG_MODEM_SUPPORT */
+
+#ifdef CONFIG_VERSION_VARIABLE
+ {
+ setenv("ver", version_string); /* set version variable */
+ }
+#endif /* CONFIG_VERSION_VARIABLE */
+
+#ifdef CONFIG_SYS_HUSH_PARSER
+ u_boot_hush_start();
+#endif
+
+#if defined(CONFIG_HUSH_INIT_VAR)
+ hush_init_var();
+#endif
+
+#ifdef CONFIG_PREBOOT
+ p = getenv("preboot");
+ if (p != NULL) {
+# ifdef CONFIG_AUTOBOOT_KEYED
+ int prev = disable_ctrlc(1); /* disable Control C checking */
+# endif
+
+ run_command_list(p, -1, 0);
+
+# ifdef CONFIG_AUTOBOOT_KEYED
+ disable_ctrlc(prev); /* restore Control C checking */
+# endif
+ }
+#endif /* CONFIG_PREBOOT */
+
+#if defined(CONFIG_UPDATE_TFTP)
+ update_tftp(0UL);
+#endif /* CONFIG_UPDATE_TFTP */
+
+#ifdef CONFIG_BOOTDELAY
+ process_boot_delay();
+#endif
/*
* Main Loop for Monitor Command Processing
*/
@@ -1080,20 +1076,20 @@ int readline_into_buffer(const char *const prompt, char *buffer, int timeout)
* Special character handling
*/
switch (c) {
- case '\r': /* Enter */
+ case '\r': /* Enter */
case '\n':
*p = '\0';
puts ("\r\n");
- return (p - p_buf);
+ return p - p_buf;
- case '\0': /* nul */
+ case '\0': /* nul */
continue;
- case 0x03: /* ^C - break */
+ case 0x03: /* ^C - break */
p_buf[0] = '\0'; /* discard input */
- return (-1);
+ return -1;
- case 0x15: /* ^U - erase line */
+ case 0x15: /* ^U - erase line */
while (col > plen) {
puts (erase_seq);
--col;
@@ -1102,15 +1098,15 @@ int readline_into_buffer(const char *const prompt, char *buffer, int timeout)
n = 0;
continue;
- case 0x17: /* ^W - erase word */
+ case 0x17: /* ^W - erase word */
p=delete_char(p_buf, p, &col, &n, plen);
while ((n > 0) && (*p != ' ')) {
p=delete_char(p_buf, p, &col, &n, plen);
}
continue;
- case 0x08: /* ^H - backspace */
- case 0x7F: /* DEL - backspace */
+ case 0x08: /* ^H - backspace */
+ case 0x7F: /* DEL - backspace */
p=delete_char(p_buf, p, &col, &n, plen);
continue;
@@ -1119,7 +1115,7 @@ int readline_into_buffer(const char *const prompt, char *buffer, int timeout)
* Must be a normal character then
*/
if (n < CONFIG_SYS_CBSIZE-2) {
- if (c == '\t') { /* expand TABs */
+ if (c == '\t') { /* expand TABs */
#ifdef CONFIG_AUTO_COMPLETE
/* if auto completion triggered just continue */
*p = '\0';
@@ -1134,7 +1130,7 @@ int readline_into_buffer(const char *const prompt, char *buffer, int timeout)
char buf[2];
/*
- * Echo input using puts() to force am
+ * Echo input using puts() to force an
* LCD flush if we are using an LCD
*/
++col;
@@ -1192,9 +1188,7 @@ int parse_line (char *line, char *argv[])
{
int nargs = 0;
-#ifdef DEBUG_PARSER
- printf ("parse_line: \"%s\"\n", line);
-#endif
+ debug_parser("parse_line: \"%s\"\n", line);
while (nargs < CONFIG_SYS_MAXARGS) {
/* skip any white space */
@@ -1203,10 +1197,8 @@ int parse_line (char *line, char *argv[])
if (*line == '\0') { /* end of line, no more args */
argv[nargs] = NULL;
-#ifdef DEBUG_PARSER
- printf ("parse_line: nargs=%d\n", nargs);
-#endif
- return (nargs);
+ debug_parser("parse_line: nargs=%d\n", nargs);
+ return nargs;
}
argv[nargs++] = line; /* begin of argument string */
@@ -1217,10 +1209,8 @@ int parse_line (char *line, char *argv[])
if (*line == '\0') { /* end of line, no more args */
argv[nargs] = NULL;
-#ifdef DEBUG_PARSER
- printf ("parse_line: nargs=%d\n", nargs);
-#endif
- return (nargs);
+ debug_parser("parse_line: nargs=%d\n", nargs);
+ return nargs;
}
*line++ = '\0'; /* terminate current arg */
@@ -1228,9 +1218,7 @@ int parse_line (char *line, char *argv[])
printf ("** Too many args (max. %d) **\n", CONFIG_SYS_MAXARGS);
-#ifdef DEBUG_PARSER
- printf ("parse_line: nargs=%d\n", nargs);
-#endif
+ debug_parser("parse_line: nargs=%d\n", nargs);
return (nargs);
}
@@ -1248,12 +1236,10 @@ static void process_macros (const char *input, char *output)
/* 1 = waiting for '(' or '{' */
/* 2 = waiting for ')' or '}' */
/* 3 = waiting for ''' */
-#ifdef DEBUG_PARSER
char *output_start = output;
- printf ("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen (input),
- input);
-#endif
+ debug_parser("[PROCESS_MACROS] INPUT len %zd: \"%s\"\n", strlen(input),
+ input);
prev = '\0'; /* previous character */
@@ -1341,10 +1327,8 @@ static void process_macros (const char *input, char *output)
else
*(output - 1) = 0;
-#ifdef DEBUG_PARSER
- printf ("[PROCESS_MACROS] OUTPUT len %d: \"%s\"\n",
- strlen (output_start), output_start);
-#endif
+ debug_parser("[PROCESS_MACROS] OUTPUT len %zd: \"%s\"\n",
+ strlen(output_start), output_start);
}
/****************************************************************************
@@ -1375,12 +1359,12 @@ static int builtin_run_command(const char *cmd, int flag)
int repeatable = 1;
int rc = 0;
-#ifdef DEBUG_PARSER
- printf ("[RUN_COMMAND] cmd[%p]=\"", cmd);
- puts (cmd ? cmd : "NULL"); /* use puts - string may be loooong */
- puts ("\"\n");
-#endif
-
+ debug_parser("[RUN_COMMAND] cmd[%p]=\"", cmd);
+ if (DEBUG_PARSER) {
+ /* use puts - string may be loooong */
+ puts(cmd ? cmd : "NULL");
+ puts("\"\n");
+ }
clear_ctrlc(); /* forget any previous Control C */
if (!cmd || !*cmd) {
@@ -1398,9 +1382,7 @@ static int builtin_run_command(const char *cmd, int flag)
* repeatable commands
*/
-#ifdef DEBUG_PARSER
- printf ("[PROCESS_SEPARATORS] %s\n", cmd);
-#endif
+ debug_parser("[PROCESS_SEPARATORS] %s\n", cmd);
while (*str) {
/*
@@ -1429,9 +1411,7 @@ static int builtin_run_command(const char *cmd, int flag)
}
else
str = sep; /* no more commands for next pass */
-#ifdef DEBUG_PARSER
- printf ("token: \"%s\"\n", token);
-#endif
+ debug_parser("token: \"%s\"\n", token);
/* find macros in this token and replace them */
process_macros (token, finaltoken);
diff --git a/disk/part_efi.c b/disk/part_efi.c
index 5986589..fb5e9f0 100644
--- a/disk/part_efi.c
+++ b/disk/part_efi.c
@@ -372,7 +372,7 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
u32 offset = (u32)le32_to_cpu(gpt_h->first_usable_lba);
ulong start;
int i, k;
- size_t name_len;
+ size_t efiname_len, dosname_len;
#ifdef CONFIG_PARTITION_UUIDS
char *str_uuid;
#endif
@@ -420,9 +420,14 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
sizeof(gpt_entry_attributes));
/* partition name */
- name_len = sizeof(gpt_e[i].partition_name)
+ efiname_len = sizeof(gpt_e[i].partition_name)
/ sizeof(efi_char16_t);
- for (k = 0; k < name_len; k++)
+ dosname_len = sizeof(partitions[i].name);
+
+ memset(gpt_e[i].partition_name, 0,
+ sizeof(gpt_e[i].partition_name));
+
+ for (k = 0; k < min(dosname_len, efiname_len); k++)
gpt_e[i].partition_name[k] =
(efi_char16_t)(partitions[i].name[k]);
diff --git a/drivers/input/key_matrix.c b/drivers/input/key_matrix.c
index 946a186..c900e45 100644
--- a/drivers/input/key_matrix.c
+++ b/drivers/input/key_matrix.c
@@ -154,54 +154,42 @@ static uchar *create_keymap(struct key_matrix *config, u32 *data, int len,
return map;
}
-int key_matrix_decode_fdt(struct key_matrix *config, const void *blob,
- int node)
+int key_matrix_decode_fdt(struct key_matrix *config, const void *blob, int node)
{
const struct fdt_property *prop;
- const char prefix[] = "linux,";
- int plen = sizeof(prefix) - 1;
- int offset;
-
- /* Check each property name for ones that we understand */
- for (offset = fdt_first_property_offset(blob, node);
- offset > 0;
- offset = fdt_next_property_offset(blob, offset)) {
- const char *name;
- int len;
-
- prop = fdt_get_property_by_offset(blob, offset, NULL);
- name = fdt_string(blob, fdt32_to_cpu(prop->nameoff));
- len = strlen(name);
-
- /* Name needs to match "1,<type>keymap" */
- debug("%s: property '%s'\n", __func__, name);
- if (strncmp(name, prefix, plen) ||
- len < plen + 6 ||
- strcmp(name + len - 6, "keymap"))
- continue;
+ int proplen;
+ uchar *plain_keycode;
- len -= plen + 6;
- if (len == 0) {
- config->plain_keycode = create_keymap(config,
- (u32 *)prop->data, fdt32_to_cpu(prop->len),
- KEY_FN, &config->fn_pos);
- } else if (0 == strncmp(name + plen, "fn-", len)) {
- config->fn_keycode = create_keymap(config,
- (u32 *)prop->data, fdt32_to_cpu(prop->len),
- -1, NULL);
- } else {
- debug("%s: unrecognised property '%s'\n", __func__,
- name);
- }
+ prop = fdt_get_property(blob, node, "linux,keymap", &proplen);
+ /* Basic keymap is required */
+ if (!prop) {
+ debug("%s: cannot find keycode-plain map\n", __func__);
+ return -1;
}
- debug("%s: Decoded key maps %p, %p from fdt\n", __func__,
- config->plain_keycode, config->fn_keycode);
- if (!config->plain_keycode) {
- debug("%s: cannot find keycode-plain map\n", __func__);
+ plain_keycode = create_keymap(config, (u32 *)prop->data,
+ proplen, KEY_FN, &config->fn_pos);
+ config->plain_keycode = plain_keycode;
+ /* Conversion error -> fail */
+ if (!config->plain_keycode)
+ return -1;
+
+ prop = fdt_get_property(blob, node, "linux,fn-keymap", &proplen);
+ /* fn keymap is optional */
+ if (!prop)
+ goto done;
+
+ config->fn_keycode = create_keymap(config, (u32 *)prop->data,
+ proplen, -1, NULL);
+ /* Conversion error -> fail */
+ if (!config->fn_keycode) {
+ free(plain_keycode);
return -1;
}
+done:
+ debug("%s: Decoded key maps %p, %p from fdt\n", __func__,
+ config->plain_keycode, config->fn_keycode);
return 0;
}
diff --git a/drivers/tpm/Makefile b/drivers/tpm/Makefile
index e8c159c..913dd9c 100644
--- a/drivers/tpm/Makefile
+++ b/drivers/tpm/Makefile
@@ -25,9 +25,10 @@ LIB := $(obj)libtpm.o
$(shell mkdir -p $(obj)slb9635_i2c)
-COBJS-$(CONFIG_GENERIC_LPC_TPM) = generic_lpc_tpm.o
-COBJS-$(CONFIG_INFINEON_TPM_I2C) += tis_i2c.o slb9635_i2c/tpm.o
-COBJS-$(CONFIG_INFINEON_TPM_I2C) += slb9635_i2c/tpm_tis_i2c.o
+# TODO: Merge tpm_tis_lpc.c with tpm.c
+COBJS-$(CONFIG_TPM_TIS_I2C) += tpm.o
+COBJS-$(CONFIG_TPM_TIS_I2C) += tpm_tis_i2c.o
+COBJS-$(CONFIG_TPM_TIS_LPC) += tpm_tis_lpc.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/tpm/slb9635_i2c/compatibility.h b/drivers/tpm/slb9635_i2c/compatibility.h
deleted file mode 100644
index 62dc9fa..0000000
--- a/drivers/tpm/slb9635_i2c/compatibility.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2011 Infineon Technologies
- *
- * Authors:
- * Peter Huewe <huewe.external@infineon.com>
- *
- * Version: 2.1.1
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#ifndef _COMPATIBILITY_H_
-#define _COMPATIBILITY_H_
-
-/* all includes from U-Boot */
-#include <linux/types.h>
-#include <linux/unaligned/be_byteshift.h>
-#include <asm-generic/errno.h>
-#include <compiler.h>
-#include <common.h>
-
-/* extended error numbers from linux (see errno.h) */
-#define ECANCELED 125 /* Operation Canceled */
-
-#define msleep(t) udelay((t)*1000)
-
-/* Timer frequency. Corresponds to msec timer resolution*/
-#define HZ 1000
-
-#define dev_dbg(dev, format, arg...) debug(format, ##arg)
-#define dev_err(dev, format, arg...) printf(format, ##arg)
-#define dev_info(dev, format, arg...) debug(format, ##arg)
-#define dbg_printf debug
-
-#endif
diff --git a/drivers/tpm/tis_i2c.c b/drivers/tpm/tis_i2c.c
index e818fba..22554e1 100644
--- a/drivers/tpm/tis_i2c.c
+++ b/drivers/tpm/tis_i2c.c
@@ -68,6 +68,10 @@ static int tpm_decode_config(struct tpm *dev)
node = fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9635_TPM);
if (node < 0) {
+ node = fdtdec_next_compatible(blob, 0,
+ COMPAT_INFINEON_SLB9645_TPM);
+ }
+ if (node < 0) {
debug("%s: Node not found\n", __func__);
return -1;
}
diff --git a/drivers/tpm/slb9635_i2c/tpm.c b/drivers/tpm/tpm.c
index 496c48e..b657334 100644
--- a/drivers/tpm/slb9635_i2c/tpm.c
+++ b/drivers/tpm/tpm.c
@@ -32,11 +32,30 @@
* MA 02111-1307 USA
*/
-#include <malloc.h>
-#include "tpm.h"
+#include <config.h>
+#include <common.h>
+#include <compiler.h>
+#include <fdtdec.h>
+#include <i2c.h>
+#include <tpm.h>
+#include <asm-generic/errno.h>
+#include <linux/types.h>
+#include <linux/unaligned/be_byteshift.h>
-/* global structure for tpm chip data */
-struct tpm_chip g_chip;
+#include "tpm_private.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* TPM configuration */
+struct tpm {
+ int i2c_bus;
+ int slave_addr;
+ char inited;
+ int old_bus;
+} tpm;
+
+/* Global structure for tpm chip data */
+static struct tpm_chip g_chip;
enum tpm_duration {
TPM_SHORT = 0,
@@ -45,9 +64,18 @@ enum tpm_duration {
TPM_UNDEFINED,
};
-#define TPM_MAX_ORDINAL 243
-#define TPM_MAX_PROTECTED_ORDINAL 12
-#define TPM_PROTECTED_ORDINAL_MASK 0xFF
+/* Extended error numbers from linux (see errno.h) */
+#define ECANCELED 125 /* Operation Canceled */
+
+/* Timer frequency. Corresponds to msec timer resolution*/
+#define HZ 1000
+
+#define TPM_MAX_ORDINAL 243
+#define TPM_MAX_PROTECTED_ORDINAL 12
+#define TPM_PROTECTED_ORDINAL_MASK 0xFF
+
+#define TPM_CMD_COUNT_BYTE 2
+#define TPM_CMD_ORDINAL_BYTE 6
/*
* Array with one entry per ordinal defining the maximum amount
@@ -318,34 +346,31 @@ static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
TPM_MEDIUM,
};
-/*
- * Returns max number of milliseconds to wait
- */
-unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
+/* Returns max number of milliseconds to wait */
+static unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
+ u32 ordinal)
{
int duration_idx = TPM_UNDEFINED;
int duration = 0;
- if (ordinal < TPM_MAX_ORDINAL)
+ if (ordinal < TPM_MAX_ORDINAL) {
duration_idx = tpm_ordinal_duration[ordinal];
- else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
- TPM_MAX_PROTECTED_ORDINAL)
- duration_idx =
- tpm_protected_ordinal_duration[ordinal &
- TPM_PROTECTED_ORDINAL_MASK];
+ } else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
+ TPM_MAX_PROTECTED_ORDINAL) {
+ duration_idx = tpm_protected_ordinal_duration[
+ ordinal & TPM_PROTECTED_ORDINAL_MASK];
+ }
if (duration_idx != TPM_UNDEFINED)
duration = chip->vendor.duration[duration_idx];
+
if (duration <= 0)
- return 2 * 60 * HZ; /*two minutes timeout*/
+ return 2 * 60 * HZ; /* Two minutes timeout */
else
return duration;
}
-#define TPM_CMD_COUNT_BYTE 2
-#define TPM_CMD_ORDINAL_BYTE 6
-
-ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
+static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
{
ssize_t rc;
u32 count, ordinal;
@@ -358,18 +383,17 @@ ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
ordinal = get_unaligned_be32(buf + TPM_CMD_ORDINAL_BYTE);
if (count == 0) {
- dev_err(chip->dev, "no data\n");
+ error("no data\n");
return -ENODATA;
}
if (count > bufsiz) {
- dev_err(chip->dev,
- "invalid count value %x %zx\n", count, bufsiz);
+ error("invalid count value %x %zx\n", count, bufsiz);
return -E2BIG;
}
rc = chip->vendor.send(chip, (u8 *)buf, count);
if (rc < 0) {
- dev_err(chip->dev, "tpm_transmit: tpm_send: error %zd\n", rc);
+ error("tpm_transmit: tpm_send: error %zd\n", rc);
goto out;
}
@@ -379,47 +403,126 @@ ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
start = get_timer(0);
stop = tpm_calc_ordinal_duration(chip, ordinal);
do {
- dbg_printf("waiting for status...\n");
+ debug("waiting for status...\n");
u8 status = chip->vendor.status(chip);
if ((status & chip->vendor.req_complete_mask) ==
chip->vendor.req_complete_val) {
- dbg_printf("...got it;\n");
+ debug("...got it;\n");
goto out_recv;
}
if ((status == chip->vendor.req_canceled)) {
- dev_err(chip->dev, "Operation Canceled\n");
+ error("Operation Canceled\n");
rc = -ECANCELED;
goto out;
}
- msleep(TPM_TIMEOUT);
+ udelay(TPM_TIMEOUT * 1000);
} while (get_timer(start) < stop);
chip->vendor.cancel(chip);
- dev_err(chip->dev, "Operation Timed out\n");
+ error("Operation Timed out\n");
rc = -ETIME;
goto out;
out_recv:
-
- dbg_printf("out_recv: reading response...\n");
+ debug("out_recv: reading response...\n");
rc = chip->vendor.recv(chip, (u8 *)buf, TPM_BUFSIZE);
if (rc < 0)
- dev_err(chip->dev, "tpm_transmit: tpm_recv: error %zd\n", rc);
+ error("tpm_transmit: tpm_recv: error %zd\n", rc);
+
out:
return rc;
}
-#define TPM_ERROR_SIZE 10
+static int tpm_open(uint32_t dev_addr)
+{
+ int rc;
+ if (g_chip.is_open)
+ return -EBUSY;
+ rc = tpm_vendor_init(dev_addr);
+ if (rc < 0)
+ g_chip.is_open = 0;
+ return rc;
+}
-enum tpm_capabilities {
- TPM_CAP_PROP = cpu_to_be32(5),
-};
+static void tpm_close(void)
+{
+ if (g_chip.is_open) {
+ tpm_vendor_cleanup(&g_chip);
+ g_chip.is_open = 0;
+ }
+}
-enum tpm_sub_capabilities {
- TPM_CAP_PROP_TIS_TIMEOUT = cpu_to_be32(0x115),
- TPM_CAP_PROP_TIS_DURATION = cpu_to_be32(0x120),
-};
+static int tpm_select(void)
+{
+ int ret;
+
+ tpm.old_bus = i2c_get_bus_num();
+ if (tpm.old_bus != tpm.i2c_bus) {
+ ret = i2c_set_bus_num(tpm.i2c_bus);
+ if (ret) {
+ debug("%s: Fail to set i2c bus %d\n", __func__,
+ tpm.i2c_bus);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int tpm_deselect(void)
+{
+ int ret;
+
+ if (tpm.old_bus != i2c_get_bus_num()) {
+ ret = i2c_set_bus_num(tpm.old_bus);
+ if (ret) {
+ debug("%s: Fail to restore i2c bus %d\n",
+ __func__, tpm.old_bus);
+ return -1;
+ }
+ }
+ tpm.old_bus = -1;
+ return 0;
+}
+
+/**
+ * Decode TPM configuration.
+ *
+ * @param dev Returns a configuration of TPM device
+ * @return 0 if ok, -1 on error
+ */
+static int tpm_decode_config(struct tpm *dev)
+{
+#ifdef CONFIG_OF_CONTROL
+ const void *blob = gd->fdt_blob;
+ int node, parent;
+ int i2c_bus;
+
+ node = fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9635_TPM);
+ if (node < 0) {
+ node = fdtdec_next_compatible(blob, 0,
+ COMPAT_INFINEON_SLB9645_TPM);
+ }
+ if (node < 0) {
+ debug("%s: Node not found\n", __func__);
+ return -1;
+ }
+ parent = fdt_parent_offset(blob, node);
+ if (parent < 0) {
+ debug("%s: Cannot find node parent\n", __func__);
+ return -1;
+ }
+ i2c_bus = i2c_get_bus_num_fdt(parent);
+ if (i2c_bus < 0)
+ return -1;
+ dev->i2c_bus = i2c_bus;
+ dev->slave_addr = fdtdec_get_addr(blob, node, "reg");
+#else
+ dev->i2c_bus = CONFIG_TPM_TIS_I2C_BUS_NUMBER;
+ dev->slave_addr = CONFIG_TPM_TIS_I2C_SLAVE_ADDRESS;
+#endif
+ return 0;
+}
struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *entry)
{
@@ -433,21 +536,94 @@ struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *entry)
return chip;
}
-int tpm_open(uint32_t dev_addr)
+int tis_init(void)
+{
+ if (tpm.inited)
+ return 0;
+
+ if (tpm_decode_config(&tpm))
+ return -1;
+
+ if (tpm_select())
+ return -1;
+
+ /*
+ * Probe TPM twice; the first probing might fail because TPM is asleep,
+ * and the probing can wake up TPM.
+ */
+ if (i2c_probe(tpm.slave_addr) && i2c_probe(tpm.slave_addr)) {
+ debug("%s: fail to probe i2c addr 0x%x\n", __func__,
+ tpm.slave_addr);
+ return -1;
+ }
+
+ tpm_deselect();
+
+ tpm.inited = 1;
+
+ return 0;
+}
+
+int tis_open(void)
{
int rc;
- if (g_chip.is_open)
- return -EBUSY;
- rc = tpm_vendor_init(dev_addr);
- if (rc < 0)
- g_chip.is_open = 0;
+
+ if (!tpm.inited)
+ return -1;
+
+ if (tpm_select())
+ return -1;
+
+ rc = tpm_open(tpm.slave_addr);
+
+ tpm_deselect();
+
return rc;
}
-void tpm_close(void)
+int tis_close(void)
{
- if (g_chip.is_open) {
- tpm_vendor_cleanup(&g_chip);
- g_chip.is_open = 0;
+ if (!tpm.inited)
+ return -1;
+
+ if (tpm_select())
+ return -1;
+
+ tpm_close();
+
+ tpm_deselect();
+
+ return 0;
+}
+
+int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
+ uint8_t *recvbuf, size_t *rbuf_len)
+{
+ int len;
+ uint8_t buf[4096];
+
+ if (!tpm.inited)
+ return -1;
+
+ if (sizeof(buf) < sbuf_size)
+ return -1;
+
+ memcpy(buf, sendbuf, sbuf_size);
+
+ if (tpm_select())
+ return -1;
+
+ len = tpm_transmit(buf, sbuf_size);
+
+ tpm_deselect();
+
+ if (len < 10) {
+ *rbuf_len = 0;
+ return -1;
}
+
+ memcpy(recvbuf, buf, len);
+ *rbuf_len = len;
+
+ return 0;
}
diff --git a/drivers/tpm/slb9635_i2c/tpm.h b/drivers/tpm/tpm_private.h
index 9ddee86..888a074 100644
--- a/drivers/tpm/slb9635_i2c/tpm.h
+++ b/drivers/tpm/tpm_private.h
@@ -33,12 +33,11 @@
* MA 02111-1307 USA
*/
-#ifndef _TPM_H_
-#define _TPM_H_
+#ifndef _TPM_PRIVATE_H_
+#define _TPM_PRIVATE_H_
#include <linux/compiler.h>
-
-#include "compatibility.h"
+#include <linux/types.h>
enum tpm_timeout {
TPM_TIMEOUT = 5, /* msecs */
@@ -47,13 +46,9 @@ enum tpm_timeout {
/* Size of external transmit buffer (used in tpm_transmit)*/
#define TPM_BUFSIZE 4096
-/* Index of fields in TPM command buffer */
-#define TPM_CMD_SIZE_BYTE 2
-#define TPM_CMD_ORDINAL_BYTE 6
-
/* Index of Count field in TPM response buffer */
-#define TPM_RSP_SIZE_BYTE 2
-#define TPM_RSP_RC_BYTE 6
+#define TPM_RSP_SIZE_BYTE 2
+#define TPM_RSP_RC_BYTE 6
struct tpm_chip;
@@ -65,10 +60,10 @@ struct tpm_vendor_specific {
int (*recv) (struct tpm_chip *, u8 *, size_t);
int (*send) (struct tpm_chip *, u8 *, size_t);
void (*cancel) (struct tpm_chip *);
- u8(*status) (struct tpm_chip *);
+ u8(*status) (struct tpm_chip *);
int locality;
- unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* msec */
- unsigned long duration[3]; /* msec */
+ unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* msec */
+ unsigned long duration[3]; /* msec */
};
struct tpm_chip {
@@ -132,30 +127,11 @@ struct tpm_cmd_t {
union tpm_cmd_params params;
} __packed;
+struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *);
-/* ---------- Interface for TPM vendor ------------ */
-
-extern struct tpm_chip *tpm_register_hardware(
- const struct tpm_vendor_specific *);
+int tpm_vendor_init(uint32_t dev_addr);
-extern int tpm_vendor_init(uint32_t dev_addr);
+void tpm_vendor_cleanup(struct tpm_chip *chip);
-extern void tpm_vendor_cleanup(struct tpm_chip *chip);
-
-/* ---------- Interface for TDDL ------------------- */
-
-/*
- * if dev_addr != 0 - redefines TPM device address
- * Returns < 0 on error, 0 on success.
- */
-extern int tpm_open(uint32_t dev_addr);
-
-extern void tpm_close(void);
-
-/*
- * Transmit bufsiz bytes out of buf to TPM and get results back in buf, too.
- * Returns < 0 on error, 0 on success.
- */
-extern ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz);
#endif
diff --git a/drivers/tpm/slb9635_i2c/tpm_tis_i2c.c b/drivers/tpm/tpm_tis_i2c.c
index 82a41bf..2dd8501 100644
--- a/drivers/tpm/slb9635_i2c/tpm_tis_i2c.c
+++ b/drivers/tpm/tpm_tis_i2c.c
@@ -37,46 +37,102 @@
*/
#include <common.h>
+#include <fdtdec.h>
+#include <compiler.h>
#include <i2c.h>
+#include <tpm.h>
+#include <asm-generic/errno.h>
#include <linux/types.h>
+#include <linux/unaligned/be_byteshift.h>
-#include "compatibility.h"
-#include "tpm.h"
+#include "tpm_private.h"
+
+DECLARE_GLOBAL_DATA_PTR;
-/* max. buffer size supported by our tpm */
-#ifdef TPM_BUFSIZE
-#undef TPM_BUFSIZE
-#endif
-#define TPM_BUFSIZE 1260
/* Address of the TPM on the I2C bus */
-#define TPM_I2C_ADDR 0x20
-/* max. number of iterations after i2c NAK */
-#define MAX_COUNT 3
+#define TPM_I2C_ADDR 0x20
+
+/* Max buffer size supported by our tpm */
+#define TPM_DEV_BUFSIZE 1260
-#define SLEEP_DURATION 60 /*in usec*/
+/* Max number of iterations after i2c NAK */
+#define MAX_COUNT 3
-/* max. number of iterations after i2c NAK for 'long' commands
- * we need this especially for sending TPM_READY, since the cleanup after the
+/*
+ * Max number of iterations after i2c NAK for 'long' commands
+ *
+ * We need this especially for sending TPM_READY, since the cleanup after the
* transtion to the ready state may take some time, but it is unpredictable
* how long it will take.
*/
-#define MAX_COUNT_LONG 50
+#define MAX_COUNT_LONG 50
+
+#define SLEEP_DURATION 60 /* in usec */
+#define SLEEP_DURATION_LONG 210 /* in usec */
-#define SLEEP_DURATION_LONG 210 /* in usec */
+#define TPM_HEADER_SIZE 10
+
+/*
+ * Expected value for DIDVID register
+ *
+ * The only device the system knows about at this moment is Infineon slb9635.
+ */
+#define TPM_TIS_I2C_DID_VID 0x000b15d1L
+
+enum tis_access {
+ TPM_ACCESS_VALID = 0x80,
+ TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
+ TPM_ACCESS_REQUEST_PENDING = 0x04,
+ TPM_ACCESS_REQUEST_USE = 0x02,
+};
+
+enum tis_status {
+ TPM_STS_VALID = 0x80,
+ TPM_STS_COMMAND_READY = 0x40,
+ TPM_STS_GO = 0x20,
+ TPM_STS_DATA_AVAIL = 0x10,
+ TPM_STS_DATA_EXPECT = 0x08,
+};
+
+enum tis_defaults {
+ TIS_SHORT_TIMEOUT = 750, /* ms */
+ TIS_LONG_TIMEOUT = 2000, /* ms */
+};
/* expected value for DIDVID register */
-#define TPM_TIS_I2C_DID_VID 0x000b15d1L
+#define TPM_TIS_I2C_DID_VID_9635 0x000b15d1L
+#define TPM_TIS_I2C_DID_VID_9645 0x001a15d1L
+
+enum i2c_chip_type {
+ SLB9635,
+ SLB9645,
+ UNKNOWN,
+};
+
+static const char * const chip_name[] = {
+ [SLB9635] = "slb9635tt",
+ [SLB9645] = "slb9645tt",
+ [UNKNOWN] = "unknown/fallback to slb9635",
+};
+
+#define TPM_ACCESS(l) (0x0000 | ((l) << 4))
+#define TPM_STS(l) (0x0001 | ((l) << 4))
+#define TPM_DATA_FIFO(l) (0x0005 | ((l) << 4))
+#define TPM_DID_VID(l) (0x0006 | ((l) << 4))
/* Structure to store I2C TPM specific stuff */
-struct tpm_inf_dev {
+struct tpm_dev {
uint addr;
- u8 buf[TPM_BUFSIZE + sizeof(u8)]; /* max. buffer size + addr */
+ u8 buf[TPM_DEV_BUFSIZE + sizeof(u8)]; /* Max buffer size + addr */
+ enum i2c_chip_type chip_type;
};
-static struct tpm_inf_dev tpm_dev = {
+static struct tpm_dev tpm_dev = {
.addr = TPM_I2C_ADDR
};
+static struct tpm_dev tpm_dev;
+
/*
* iic_tpm_read() - read from TPM register
* @addr: register address to read from
@@ -91,34 +147,52 @@ static struct tpm_inf_dev tpm_dev = {
*
* Return -EIO on error, 0 on success.
*/
-int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
+static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
{
int rc;
int count;
- uint myaddr = addr;
- /* we have to use uint here, uchar hangs the board */
-
- for (count = 0; count < MAX_COUNT; count++) {
- rc = i2c_write(tpm_dev.addr, 0, 0, (uchar *)&myaddr, 1);
- if (rc == 0)
- break; /*success, break to skip sleep*/
-
- udelay(SLEEP_DURATION);
- }
-
- if (rc)
- return -rc;
-
- /* After the TPM has successfully received the register address it needs
- * some time, thus we're sleeping here again, before retrieving the data
- */
- for (count = 0; count < MAX_COUNT; count++) {
- udelay(SLEEP_DURATION);
- rc = i2c_read(tpm_dev.addr, 0, 0, buffer, len);
- if (rc == 0)
- break; /*success, break to skip sleep*/
+ uint32_t addrbuf = addr;
+
+ if ((tpm_dev.chip_type == SLB9635) || (tpm_dev.chip_type == UNKNOWN)) {
+ /* slb9635 protocol should work in both cases */
+ for (count = 0; count < MAX_COUNT; count++) {
+ rc = i2c_write(tpm_dev.addr, 0, 0,
+ (uchar *)&addrbuf, 1);
+ if (rc == 0)
+ break; /* Success, break to skip sleep */
+ udelay(SLEEP_DURATION);
+ }
+ if (rc)
+ return -rc;
+
+ /* After the TPM has successfully received the register address
+ * it needs some time, thus we're sleeping here again, before
+ * retrieving the data
+ */
+ for (count = 0; count < MAX_COUNT; count++) {
+ udelay(SLEEP_DURATION);
+ rc = i2c_read(tpm_dev.addr, 0, 0, buffer, len);
+ if (rc == 0)
+ break; /* success, break to skip sleep */
+ }
+ } else {
+ /*
+ * Use a combined read for newer chips.
+ * Unfortunately the smbus functions are not suitable due to
+ * the 32 byte limit of the smbus.
+ * Retries should usually not be needed, but are kept just to
+ * be safe on the safe side.
+ */
+ for (count = 0; count < MAX_COUNT; count++) {
+ rc = i2c_read(tpm_dev.addr, addr, 1, buffer, len);
+ if (rc == 0)
+ break; /* break here to skip sleep */
+ udelay(SLEEP_DURATION);
+ }
}
+ /* Take care of 'guard time' */
+ udelay(SLEEP_DURATION);
if (rc)
return -rc;
@@ -126,24 +200,24 @@ int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
}
static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len,
- unsigned int sleep_time,
- u8 max_count)
+ unsigned int sleep_time, u8 max_count)
{
int rc = 0;
int count;
- /* prepare send buffer */
+ /* Prepare send buffer */
tpm_dev.buf[0] = addr;
memcpy(&(tpm_dev.buf[1]), buffer, len);
for (count = 0; count < max_count; count++) {
rc = i2c_write(tpm_dev.addr, 0, 0, tpm_dev.buf, len + 1);
if (rc == 0)
- break; /*success, break to skip sleep*/
-
+ break; /* Success, break to skip sleep */
udelay(sleep_time);
}
+ /* take care of 'guard time' */
+ udelay(SLEEP_DURATION);
if (rc)
return -rc;
@@ -175,42 +249,16 @@ static int iic_tpm_write(u8 addr, u8 *buffer, size_t len)
/*
* This function is needed especially for the cleanup situation after
* sending TPM_READY
- * */
+ */
static int iic_tpm_write_long(u8 addr, u8 *buffer, size_t len)
{
return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION_LONG,
MAX_COUNT_LONG);
}
-#define TPM_HEADER_SIZE 10
-
-enum tis_access {
- TPM_ACCESS_VALID = 0x80,
- TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
- TPM_ACCESS_REQUEST_PENDING = 0x04,
- TPM_ACCESS_REQUEST_USE = 0x02,
-};
-
-enum tis_status {
- TPM_STS_VALID = 0x80,
- TPM_STS_COMMAND_READY = 0x40,
- TPM_STS_GO = 0x20,
- TPM_STS_DATA_AVAIL = 0x10,
- TPM_STS_DATA_EXPECT = 0x08,
-};
-
-enum tis_defaults {
- TIS_SHORT_TIMEOUT = 750, /* ms */
- TIS_LONG_TIMEOUT = 2000, /* 2 sec */
-};
-
-#define TPM_ACCESS(l) (0x0000 | ((l) << 4))
-#define TPM_STS(l) (0x0001 | ((l) << 4))
-#define TPM_DATA_FIFO(l) (0x0005 | ((l) << 4))
-#define TPM_DID_VID(l) (0x0006 | ((l) << 4))
-
static int check_locality(struct tpm_chip *chip, int loc)
{
+ const u8 mask = TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID;
u8 buf;
int rc;
@@ -218,8 +266,7 @@ static int check_locality(struct tpm_chip *chip, int loc)
if (rc < 0)
return rc;
- if ((buf & (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
- (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) {
+ if ((buf & mask) == mask) {
chip->vendor.locality = loc;
return loc;
}
@@ -229,12 +276,13 @@ static int check_locality(struct tpm_chip *chip, int loc)
static void release_locality(struct tpm_chip *chip, int loc, int force)
{
+ const u8 mask = TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID;
u8 buf;
+
if (iic_tpm_read(TPM_ACCESS(loc), &buf, 1) < 0)
return;
- if (force || (buf & (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
- (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) {
+ if (force || (buf & mask) == mask) {
buf = TPM_ACCESS_ACTIVE_LOCALITY;
iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
}
@@ -246,17 +294,17 @@ static int request_locality(struct tpm_chip *chip, int loc)
u8 buf = TPM_ACCESS_REQUEST_USE;
if (check_locality(chip, loc) >= 0)
- return loc; /* we already have the locality */
+ return loc; /* We already have the locality */
iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
- /* wait for burstcount */
+ /* Wait for burstcount */
start = get_timer(0);
stop = chip->vendor.timeout_a;
do {
if (check_locality(chip, loc) >= 0)
return loc;
- msleep(TPM_TIMEOUT);
+ udelay(TPM_TIMEOUT * 1000);
} while (get_timer(start) < stop);
return -1;
@@ -264,8 +312,9 @@ static int request_locality(struct tpm_chip *chip, int loc)
static u8 tpm_tis_i2c_status(struct tpm_chip *chip)
{
- /* NOTE: since i2c read may fail, return 0 in this case --> time-out */
+ /* NOTE: Since i2c read may fail, return 0 in this case --> time-out */
u8 buf;
+
if (iic_tpm_read(TPM_STS(chip->vendor.locality), &buf, 1) < 0)
return 0;
else
@@ -274,8 +323,9 @@ static u8 tpm_tis_i2c_status(struct tpm_chip *chip)
static void tpm_tis_i2c_ready(struct tpm_chip *chip)
{
- /* this causes the current command to be aborted */
+ /* This causes the current command to be aborted */
u8 buf = TPM_STS_COMMAND_READY;
+
iic_tpm_write_long(TPM_STS(chip->vendor.locality), &buf, 1);
}
@@ -283,34 +333,34 @@ static ssize_t get_burstcount(struct tpm_chip *chip)
{
unsigned long start, stop;
ssize_t burstcnt;
- u8 buf[3];
+ u8 addr, buf[3];
- /* wait for burstcount */
- /* which timeout value, spec has 2 answers (c & d) */
+ /* Wait for burstcount */
+ /* XXX: Which timeout value? Spec has 2 answers (c & d) */
start = get_timer(0);
stop = chip->vendor.timeout_d;
do {
/* Note: STS is little endian */
- if (iic_tpm_read(TPM_STS(chip->vendor.locality) + 1, buf, 3)
- < 0)
+ addr = TPM_STS(chip->vendor.locality) + 1;
+ if (iic_tpm_read(addr, buf, 3) < 0)
burstcnt = 0;
else
burstcnt = (buf[2] << 16) + (buf[1] << 8) + buf[0];
if (burstcnt)
return burstcnt;
- msleep(TPM_TIMEOUT);
+ udelay(TPM_TIMEOUT * 1000);
} while (get_timer(start) < stop);
return -EBUSY;
}
static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
- int *status)
+ int *status)
{
unsigned long start, stop;
- /* check current status */
+ /* Check current status */
*status = tpm_tis_i2c_status(chip);
if ((*status & mask) == mask)
return 0;
@@ -318,11 +368,10 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
start = get_timer(0);
stop = timeout;
do {
- msleep(TPM_TIMEOUT);
+ udelay(TPM_TIMEOUT * 1000);
*status = tpm_tis_i2c_status(chip);
if ((*status & mask) == mask)
return 0;
-
} while (get_timer(start) < stop);
return -ETIME;
@@ -337,17 +386,16 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
while (size < count) {
burstcnt = get_burstcount(chip);
- /* burstcount < 0 = tpm is busy */
+ /* burstcount < 0 -> tpm is busy */
if (burstcnt < 0)
return burstcnt;
- /* limit received data to max. left */
+ /* Limit received data to max left */
if (burstcnt > (count - size))
burstcnt = count - size;
rc = iic_tpm_read(TPM_DATA_FIFO(chip->vendor.locality),
- &(buf[size]),
- burstcnt);
+ &(buf[size]), burstcnt);
if (rc == 0)
size += burstcnt;
}
@@ -365,10 +413,10 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
goto out;
}
- /* read first 10 bytes, including tag, paramsize, and result */
+ /* Read first 10 bytes, including tag, paramsize, and result */
size = recv_data(chip, buf, TPM_HEADER_SIZE);
if (size < TPM_HEADER_SIZE) {
- dev_err(chip->dev, "Unable to read header\n");
+ error("Unable to read header\n");
goto out;
}
@@ -379,23 +427,24 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
}
size += recv_data(chip, &buf[TPM_HEADER_SIZE],
- expected - TPM_HEADER_SIZE);
+ expected - TPM_HEADER_SIZE);
if (size < expected) {
- dev_err(chip->dev, "Unable to read remainder of result\n");
+ error("Unable to read remainder of result\n");
size = -ETIME;
goto out;
}
wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
- if (status & TPM_STS_DATA_AVAIL) { /* retry? */
- dev_err(chip->dev, "Error left over data\n");
+ if (status & TPM_STS_DATA_AVAIL) { /* Retry? */
+ error("Error left over data\n");
size = -EIO;
goto out;
}
out:
tpm_tis_i2c_ready(chip);
- /* The TPM needs some time to clean up here,
+ /*
+ * The TPM needs some time to clean up here,
* so we sleep rather than keeping the bus busy
*/
udelay(2000);
@@ -409,10 +458,11 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
int rc, status;
ssize_t burstcnt;
size_t count = 0;
+ int retry = 0;
u8 sts = TPM_STS_GO;
- if (len > TPM_BUFSIZE)
- return -E2BIG; /* command is too long for our tpm, sorry */
+ if (len > TPM_DEV_BUFSIZE)
+ return -E2BIG; /* Command is too long for our tpm, sorry */
if (request_locality(chip, 0) < 0)
return -EBUSY;
@@ -420,44 +470,45 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
status = tpm_tis_i2c_status(chip);
if ((status & TPM_STS_COMMAND_READY) == 0) {
tpm_tis_i2c_ready(chip);
- if (wait_for_stat
- (chip, TPM_STS_COMMAND_READY,
- chip->vendor.timeout_b, &status) < 0) {
+ if (wait_for_stat(chip, TPM_STS_COMMAND_READY,
+ chip->vendor.timeout_b, &status) < 0) {
rc = -ETIME;
goto out_err;
}
}
- while (count < len - 1) {
- burstcnt = get_burstcount(chip);
+ burstcnt = get_burstcount(chip);
- /* burstcount < 0 = tpm is busy */
- if (burstcnt < 0)
- return burstcnt;
+ /* burstcount < 0 -> tpm is busy */
+ if (burstcnt < 0)
+ return burstcnt;
- if (burstcnt > (len-1-count))
- burstcnt = len-1-count;
+ while (count < len - 1) {
+ if (burstcnt > len - 1 - count)
+ burstcnt = len - 1 - count;
-#ifdef CONFIG_TPM_I2C_BURST_LIMITATION
- if (burstcnt > CONFIG_TPM_I2C_BURST_LIMITATION)
- burstcnt = CONFIG_TPM_I2C_BURST_LIMITATION;
-#endif /* CONFIG_TPM_I2C_BURST_LIMITATION */
+#ifdef CONFIG_TPM_TIS_I2C_BURST_LIMITATION
+ if (retry && burstcnt > CONFIG_TPM_TIS_I2C_BURST_LIMITATION)
+ burstcnt = CONFIG_TPM_TIS_I2C_BURST_LIMITATION;
+#endif /* CONFIG_TPM_TIS_I2C_BURST_LIMITATION */
rc = iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality),
- &(buf[count]), burstcnt);
+ &(buf[count]), burstcnt);
if (rc == 0)
count += burstcnt;
-
- wait_for_stat(chip, TPM_STS_VALID,
- chip->vendor.timeout_c, &status);
-
- if ((status & TPM_STS_DATA_EXPECT) == 0) {
- rc = -EIO;
- goto out_err;
+ else {
+ retry++;
+ wait_for_stat(chip, TPM_STS_VALID,
+ chip->vendor.timeout_c, &status);
+
+ if ((status & TPM_STS_DATA_EXPECT) == 0) {
+ rc = -EIO;
+ goto out_err;
+ }
}
}
- /* write last byte */
+ /* Write last byte */
iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality), &(buf[count]), 1);
wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
if ((status & TPM_STS_DATA_EXPECT) != 0) {
@@ -465,13 +516,15 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
goto out_err;
}
- /* go and do it */
+ /* Go and do it */
iic_tpm_write(TPM_STS(chip->vendor.locality), &sts, 1);
return len;
+
out_err:
tpm_tis_i2c_ready(chip);
- /* The TPM needs some time to clean up here,
+ /*
+ * The TPM needs some time to clean up here,
* so we sleep rather than keeping the bus busy
*/
udelay(2000);
@@ -490,12 +543,26 @@ static struct tpm_vendor_specific tpm_tis_i2c = {
.req_canceled = TPM_STS_COMMAND_READY,
};
-/* initialisation of i2c tpm */
+static enum i2c_chip_type tpm_vendor_chip_type(void)
+{
+#ifdef CONFIG_OF_CONTROL
+ const void *blob = gd->fdt_blob;
+
+ if (fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9645_TPM) >= 0)
+ return SLB9645;
+
+ if (fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9635_TPM) >= 0)
+ return SLB9635;
+#endif
+ return UNKNOWN;
+}
+/* Initialisation of i2c tpm */
int tpm_vendor_init(uint32_t dev_addr)
{
u32 vendor;
+ u32 expected_did_vid;
uint old_addr;
int rc = 0;
struct tpm_chip *chip;
@@ -504,6 +571,8 @@ int tpm_vendor_init(uint32_t dev_addr)
if (dev_addr != 0)
tpm_dev.addr = dev_addr;
+ tpm_dev.chip_type = tpm_vendor_chip_type();
+
chip = tpm_register_hardware(&tpm_tis_i2c);
if (chip < 0) {
rc = -ENODEV;
@@ -519,26 +588,33 @@ int tpm_vendor_init(uint32_t dev_addr)
chip->vendor.timeout_c = TIS_SHORT_TIMEOUT;
chip->vendor.timeout_d = TIS_SHORT_TIMEOUT;
- if (request_locality(chip, 0) != 0) {
+ if (request_locality(chip, 0) < 0) {
rc = -ENODEV;
goto out_err;
}
- /* read four bytes from DID_VID register */
+ /* Read four bytes from DID_VID register */
if (iic_tpm_read(TPM_DID_VID(0), (uchar *)&vendor, 4) < 0) {
rc = -EIO;
goto out_release;
}
- /* create DID_VID register value, after swapping to little-endian */
- vendor = be32_to_cpu(vendor);
+ if (tpm_dev.chip_type == SLB9635) {
+ vendor = be32_to_cpu(vendor);
+ expected_did_vid = TPM_TIS_I2C_DID_VID_9635;
+ } else {
+ /* device id and byte order has changed for newer i2c tpms */
+ expected_did_vid = TPM_TIS_I2C_DID_VID_9645;
+ }
- if (vendor != TPM_TIS_I2C_DID_VID) {
+ if (tpm_dev.chip_type != UNKNOWN && vendor != expected_did_vid) {
+ error("Vendor id did not match! ID was %08x\n", vendor);
rc = -ENODEV;
goto out_release;
}
- dev_info(dev, "1.2 TPM (device-id 0x%X)\n", vendor >> 16);
+ debug("1.2 TPM (chip type %s device-id 0x%X)\n",
+ chip_name[tpm_dev.chip_type], vendor >> 16);
/*
* A timeout query to TPM can be placed here.
diff --git a/drivers/tpm/generic_lpc_tpm.c b/drivers/tpm/tpm_tis_lpc.c
index 04ad418..04ad418 100644
--- a/drivers/tpm/generic_lpc_tpm.c
+++ b/drivers/tpm/tpm_tis_lpc.c
diff --git a/include/bootstage.h b/include/bootstage.h
index 6dc0422..ef07a87 100644
--- a/include/bootstage.h
+++ b/include/bootstage.h
@@ -37,6 +37,24 @@ enum bootstage_flags {
BOOTSTAGEF_ALLOC = 1 << 1, /* Allocate an id */
};
+/* bootstate sub-IDs used for kernel and ramdisk ranges */
+enum {
+ BOOTSTAGE_SUB_FORMAT,
+ BOOTSTAGE_SUB_FORMAT_OK,
+ BOOTSTAGE_SUB_NO_UNIT_NAME,
+ BOOTSTAGE_SUB_UNIT_NAME,
+ BOOTSTAGE_SUB_SUBNODE,
+
+ BOOTSTAGE_SUB_CHECK,
+ BOOTSTAGE_SUB_HASH = 5,
+ BOOTSTAGE_SUB_CHECK_ARCH = 5,
+ BOOTSTAGE_SUB_CHECK_ALL,
+ BOOTSTAGE_SUB_GET_DATA,
+ BOOTSTAGE_SUB_CHECK_ALL_OK = 7,
+ BOOTSTAGE_SUB_GET_DATA_OK,
+ BOOTSTAGE_SUB_LOAD,
+};
+
/*
* A list of boot stages that we know about. Each of these indicates the
* state that we are at, and the action that we are about to perform. For
@@ -137,43 +155,24 @@ enum bootstage_id {
BOOTSTAGE_ID_NET_DONE_ERR,
BOOTSTAGE_ID_NET_DONE,
+ BOOTSTAGE_ID_FIT_FDT_START = 90,
/*
* Boot stages related to loading a FIT image. Some of these are a
* bit wonky.
*/
- BOOTSTAGE_ID_FIT_FORMAT = 100,
- BOOTSTAGE_ID_FIT_NO_UNIT_NAME,
- BOOTSTAGE_ID_FIT_UNIT_NAME,
- BOOTSTAGE_ID_FIT_CONFIG,
- BOOTSTAGE_ID_FIT_CHECK_SUBIMAGE,
- BOOTSTAGE_ID_FIT_CHECK_HASH = 104,
-
- BOOTSTAGE_ID_FIT_CHECK_ARCH,
- BOOTSTAGE_ID_FIT_CHECK_KERNEL,
- BOOTSTAGE_ID_FIT_CHECKED,
-
- BOOTSTAGE_ID_FIT_KERNEL_INFO_ERR = 107,
- BOOTSTAGE_ID_FIT_KERNEL_INFO,
+ BOOTSTAGE_ID_FIT_KERNEL_START = 100,
+
+ BOOTSTAGE_ID_FIT_CONFIG = 110,
BOOTSTAGE_ID_FIT_TYPE,
+ BOOTSTAGE_ID_FIT_KERNEL_INFO,
BOOTSTAGE_ID_FIT_COMPRESSION,
BOOTSTAGE_ID_FIT_OS,
BOOTSTAGE_ID_FIT_LOADADDR,
BOOTSTAGE_ID_OVERWRITTEN,
- BOOTSTAGE_ID_FIT_RD_FORMAT = 120,
- BOOTSTAGE_ID_FIT_RD_FORMAT_OK,
- BOOTSTAGE_ID_FIT_RD_NO_UNIT_NAME,
- BOOTSTAGE_ID_FIT_RD_UNIT_NAME,
- BOOTSTAGE_ID_FIT_RD_SUBNODE,
-
- BOOTSTAGE_ID_FIT_RD_CHECK,
- BOOTSTAGE_ID_FIT_RD_HASH = 125,
- BOOTSTAGE_ID_FIT_RD_CHECK_ALL,
- BOOTSTAGE_ID_FIT_RD_GET_DATA,
- BOOTSTAGE_ID_FIT_RD_CHECK_ALL_OK = 127,
- BOOTSTAGE_ID_FIT_RD_GET_DATA_OK,
- BOOTSTAGE_ID_FIT_RD_LOAD,
+ /* Next 10 IDs used by BOOTSTAGE_SUB_... */
+ BOOTSTAGE_ID_FIT_RD_START = 120, /* Ramdisk stages */
BOOTSTAGE_ID_IDE_FIT_READ = 140,
BOOTSTAGE_ID_IDE_FIT_READ_OK,
diff --git a/include/common.h b/include/common.h
index e682bd8..126891d 100644
--- a/include/common.h
+++ b/include/common.h
@@ -310,9 +310,6 @@ int readline_into_buffer(const char *const prompt, char *buffer,
int parse_line (char *, char *[]);
void init_cmd_timeout(void);
void reset_cmd_timeout(void);
-#ifdef CONFIG_MENU
-int abortboot(int bootdelay);
-#endif
extern char console_buffer[];
/* arch/$(ARCH)/lib/board.c */
diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h
index f019134..cd2c078 100644
--- a/include/configs/am335x_evm.h
+++ b/include/configs/am335x_evm.h
@@ -305,8 +305,13 @@
/* Defines for SPL */
#define CONFIG_SPL
#define CONFIG_SPL_FRAMEWORK
+/*
+ * Place the image at the start of the ROM defined image space.
+ * We limit our size to the ROM-defined downloaded image area, and use the
+ * rest of the space for stack.
+ */
#define CONFIG_SPL_TEXT_BASE 0x402F0400
-#define CONFIG_SPL_MAX_SIZE (101 * 1024)
+#define CONFIG_SPL_MAX_SIZE (0x4030C000 - CONFIG_SPL_TEXT_BASE)
#define CONFIG_SPL_STACK CONFIG_SYS_INIT_SP_ADDR
#define CONFIG_SPL_BSS_START_ADDR 0x80000000
diff --git a/include/configs/coreboot.h b/include/configs/coreboot.h
index be04a75..2fefdc8 100644
--- a/include/configs/coreboot.h
+++ b/include/configs/coreboot.h
@@ -90,7 +90,8 @@
#endif
/* Generic TPM interfaced through LPC bus */
-#define CONFIG_GENERIC_LPC_TPM
+#define CONFIG_TPM
+#define CONFIG_TPM_TIS_LPC
#define CONFIG_TPM_TIS_BASE_ADDRESS 0xfed40000
/*-----------------------------------------------------------------------
diff --git a/include/configs/exynos5250-dt.h b/include/configs/exynos5250-dt.h
index 8a82892..41d6cf9 100644
--- a/include/configs/exynos5250-dt.h
+++ b/include/configs/exynos5250-dt.h
@@ -142,9 +142,9 @@
/* TPM */
#define CONFIG_TPM
#define CONFIG_CMD_TPM
-#define CONFIG_INFINEON_TPM_I2C
-#define CONFIG_INFINEON_TPM_I2C_BUS 3
-#define CONFIG_INFINEON_TPM_I2C_ADDR 0x20
+#define CONFIG_TPM_TIS_I2C
+#define CONFIG_TPM_TIS_I2C_BUS_NUMBER 3
+#define CONFIG_TPM_TIS_I2C_SLAVE_ADDR 0x20
/* MMC SPL */
#define CONFIG_SPL
diff --git a/include/configs/igep0033.h b/include/configs/igep0033.h
index 1912d7d..12f28f8 100644
--- a/include/configs/igep0033.h
+++ b/include/configs/igep0033.h
@@ -214,8 +214,13 @@
/* Defines for SPL */
#define CONFIG_SPL
#define CONFIG_SPL_FRAMEWORK
+/*
+ * Place the image at the start of the ROM defined image space.
+ * We limit our size to the ROM-defined downloaded image area, and use the
+ * rest of the space for stack.
+ */
#define CONFIG_SPL_TEXT_BASE 0x402F0400
-#define CONFIG_SPL_MAX_SIZE (101 * 1024)
+#define CONFIG_SPL_MAX_SIZE (0x4030C000 - CONFIG_SPL_TEXT_BASE)
#define CONFIG_SPL_STACK CONFIG_SYS_INIT_SP_ADDR
#define CONFIG_SPL_BSS_START_ADDR 0x80000000
diff --git a/include/configs/pcm051.h b/include/configs/pcm051.h
index 478f805..2ecd105 100644
--- a/include/configs/pcm051.h
+++ b/include/configs/pcm051.h
@@ -204,8 +204,13 @@
/* Defines for SPL */
#define CONFIG_SPL
#define CONFIG_SPL_FRAMEWORK
+/*
+ * Place the image at the start of the ROM defined image space.
+ * We limit our size to the ROM-defined downloaded image area, and use the
+ * rest of the space for stack.
+ */
#define CONFIG_SPL_TEXT_BASE 0x402F0400
-#define CONFIG_SPL_MAX_SIZE (101 * 1024)
+#define CONFIG_SPL_MAX_SIZE (0x4030C000 - CONFIG_SPL_TEXT_BASE)
#define CONFIG_SPL_STACK CONFIG_SYS_INIT_SP_ADDR
#define CONFIG_SPL_BSS_START_ADDR 0x80000000
diff --git a/include/configs/pm9263.h b/include/configs/pm9263.h
index b60a9ad..6f6ddfa 100644
--- a/include/configs/pm9263.h
+++ b/include/configs/pm9263.h
@@ -355,7 +355,7 @@
#define CONFIG_BOOTCOMMAND "run flashboot"
#define CONFIG_ROOTPATH "/ronetix/rootfs"
-#define CONFIG_AUTOBOOT_PROMPT "autoboot in %d seconds\n"
+#define CONFIG_AUTOBOOT_PROMPT "autoboot in %d seconds\n", bootdelay
#define CONFIG_CON_ROT "fbcon=rotate:3 "
#define CONFIG_BOOTARGS "root=/dev/mtdblock4 rootfstype=jffs2 "\
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 4e8032b..1ece612 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -93,6 +93,7 @@ enum fdt_compat_id {
COMPAT_GENERIC_SPI_FLASH, /* Generic SPI Flash chip */
COMPAT_MAXIM_98095_CODEC, /* MAX98095 Codec */
COMPAT_INFINEON_SLB9635_TPM, /* Infineon SLB9635 TPM */
+ COMPAT_INFINEON_SLB9645_TPM, /* Infineon SLB9645 TPM */
COMPAT_COUNT,
};
diff --git a/include/image.h b/include/image.h
index b8cc523..8ccc00b 100644
--- a/include/image.h
+++ b/include/image.h
@@ -402,6 +402,13 @@ void genimg_print_size(uint32_t size);
#endif
void genimg_print_time(time_t timestamp);
+/* What to do with a image load address ('load = <> 'in the FIT) */
+enum fit_load_op {
+ FIT_LOAD_IGNORED, /* Ignore load address */
+ FIT_LOAD_OPTIONAL, /* Can be provided, but optional */
+ FIT_LOAD_REQUIRED, /* Must be provided */
+};
+
#ifndef USE_HOSTCC
/* Image format types, returned by _get_format() routine */
#define IMAGE_FORMAT_INVALID 0x00
@@ -415,8 +422,71 @@ ulong genimg_get_image(ulong img_addr);
int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
uint8_t arch, ulong *rd_start, ulong *rd_end);
-int boot_get_fdt(int flag, int argc, char * const argv[],
- bootm_headers_t *images, char **of_flat_tree, ulong *of_size);
+/**
+ * fit_image_load() - load an image from a FIT
+ *
+ * This deals with all aspects of loading an image from a FIT, including
+ * selecting the right image based on configuration, verifying it, printing
+ * out progress messages, checking the type/arch/os and optionally copying it
+ * to the right load address.
+ *
+ * @param images Boot images structure
+ * @param prop_name Property name to look up (FIT_..._PROP)
+ * @param addr Address of FIT in memory
+ * @param fit_unamep On entry this is the requested image name
+ * (e.g. "kernel@1") or NULL to use the default. On exit
+ * points to the selected image name
+ * @param fit_uname_config Requested configuration name, or NULL for the
+ * default
+ * @param arch Expected architecture (IH_ARCH_...)
+ * @param image_type Required image type (IH_TYPE_...). If this is
+ * IH_TYPE_KERNEL then we allow IH_TYPE_KERNEL_NOLOAD
+ * also.
+ * @param bootstage_id ID of starting bootstage to use for progress updates.
+ * This will be added to the BOOTSTAGE_SUB values when
+ * calling bootstage_mark()
+ * @param load_op Decribes what to do with the load address
+ * @param datap Returns address of loaded image
+ * @param lenp Returns length of loaded image
+ */
+int fit_image_load(bootm_headers_t *images, const char *prop_name, ulong addr,
+ const char **fit_unamep, const char *fit_uname_config,
+ int arch, int image_type, int bootstage_id,
+ enum fit_load_op load_op, ulong *datap, ulong *lenp);
+
+/**
+ * fit_get_node_from_config() - Look up an image a FIT by type
+ *
+ * This looks in the selected conf@ node (images->fit_uname_cfg) for a
+ * particular image type (e.g. "kernel") and then finds the image that is
+ * referred to.
+ *
+ * For example, for something like:
+ *
+ * images {
+ * kernel@1 {
+ * ...
+ * };
+ * };
+ * configurations {
+ * conf@1 {
+ * kernel = "kernel@1";
+ * };
+ * };
+ *
+ * the function will return the node offset of the kernel@1 node, assuming
+ * that conf@1 is the chosen configuration.
+ *
+ * @param images Boot images structure
+ * @param prop_name Property name to look up (FIT_..._PROP)
+ * @param addr Address of FIT in memory
+ */
+int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name,
+ ulong addr);
+
+int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch,
+ bootm_headers_t *images,
+ char **of_flat_tree, ulong *of_size);
void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob);
int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size);
@@ -697,6 +767,7 @@ int fit_set_timestamp(void *fit, int noffset, time_t timestamp);
int fit_add_verification_data(void *fit);
int fit_image_verify(const void *fit, int noffset);
+int fit_config_verify(const void *fit, int conf_noffset);
int fit_all_image_verify(const void *fit);
int fit_image_check_os(const void *fit, int noffset, uint8_t os);
int fit_image_check_arch(const void *fit, int noffset, uint8_t arch);
@@ -706,9 +777,6 @@ int fit_check_format(const void *fit);
int fit_conf_find_compat(const void *fit, const void *fdt);
int fit_conf_get_node(const void *fit, const char *conf_uname);
-int fit_conf_get_kernel_node(const void *fit, int noffset);
-int fit_conf_get_ramdisk_node(const void *fit, int noffset);
-int fit_conf_get_fdt_node(const void *fit, int noffset);
/**
* fit_conf_get_prop_node() - Get node refered to by a configuration
@@ -732,12 +800,35 @@ int fit_check_ramdisk(const void *fit, int os_noffset,
int calculate_hash(const void *data, int data_len, const char *algo,
uint8_t *value, int *value_len);
-#ifndef USE_HOSTCC
+/*
+ * At present we only support verification on the device
+ */
+#if defined(CONFIG_FIT_SIGNATURE)
+# ifdef USE_HOSTCC
+# define IMAGE_ENABLE_VERIFY 0
+#else
+# define IMAGE_ENABLE_VERIFY 1
+# endif
+#else
+# define IMAGE_ENABLE_VERIFY 0
+#endif
+
+#ifdef USE_HOSTCC
+# define gd_fdt_blob() NULL
+#else
+# define gd_fdt_blob() (gd->fdt_blob)
+#endif
+
+#ifdef CONFIG_FIT_BEST_MATCH
+#define IMAGE_ENABLE_BEST_MATCH 1
+#else
+#define IMAGE_ENABLE_BEST_MATCH 0
+#endif
+
static inline int fit_image_check_target_arch(const void *fdt, int node)
{
return fit_image_check_arch(fdt, node, IH_ARCH_DEFAULT);
}
-#endif /* USE_HOSTCC */
#ifdef CONFIG_FIT_VERBOSE
#define fit_unsupported(msg) printf("! %s:%d " \
diff --git a/include/net.h b/include/net.h
index 970d4d1..23fb947 100644
--- a/include/net.h
+++ b/include/net.h
@@ -695,6 +695,9 @@ extern void copy_filename(char *dst, const char *src, int size);
/* get a random source port */
extern unsigned int random_port(void);
+/* Update U-Boot over TFTP */
+extern int update_tftp(ulong addr);
+
/**********************************************************************/
#endif /* __NET_H__ */
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index ac1fe0b..005ad3d 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -66,6 +66,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
COMPAT(GENERIC_SPI_FLASH, "spi-flash"),
COMPAT(MAXIM_98095_CODEC, "maxim,max98095-codec"),
COMPAT(INFINEON_SLB9635_TPM, "infineon,slb9635-tpm"),
+ COMPAT(INFINEON_SLB9645_TPM, "infineon,slb9645-tpm"),
};
const char *fdtdec_get_compatible(enum fdt_compat_id id)
diff --git a/test/image/test-fit.py b/test/image/test-fit.py
new file mode 100755
index 0000000..c4e8211
--- /dev/null
+++ b/test/image/test-fit.py
@@ -0,0 +1,422 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2013, Google Inc.
+#
+# Sanity check of the FIT handling in U-Boot
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+# To run this:
+#
+# make O=sandbox sandbox_config
+# make O=sandbox
+# ./test/image/test-fit.py -u sandbox/u-boot
+
+import doctest
+from optparse import OptionParser
+import os
+import shutil
+import struct
+import sys
+import tempfile
+
+# The 'command' library in patman is convenient for running commands
+base_path = os.path.dirname(sys.argv[0])
+patman = os.path.join(base_path, '../../tools/patman')
+sys.path.append(patman)
+
+import command
+
+# Define a base ITS which we can adjust using % and a dictionary
+base_its = '''
+/dts-v1/;
+
+/ {
+ description = "Chrome OS kernel image with one or more FDT blobs";
+ #address-cells = <1>;
+
+ images {
+ kernel@1 {
+ data = /incbin/("%(kernel)s");
+ type = "kernel";
+ arch = "sandbox";
+ os = "linux";
+ compression = "none";
+ load = <0x40000>;
+ entry = <0x8>;
+ };
+ fdt@1 {
+ description = "snow";
+ data = /incbin/("u-boot.dtb");
+ type = "flat_dt";
+ arch = "sandbox";
+ %(fdt_load)s
+ compression = "none";
+ signature@1 {
+ algo = "sha1,rsa2048";
+ key-name-hint = "dev";
+ };
+ };
+ ramdisk@1 {
+ description = "snow";
+ data = /incbin/("%(ramdisk)s");
+ type = "ramdisk";
+ arch = "sandbox";
+ os = "linux";
+ %(ramdisk_load)s
+ compression = "none";
+ };
+ };
+ configurations {
+ default = "conf@1";
+ conf@1 {
+ kernel = "kernel@1";
+ fdt = "fdt@1";
+ %(ramdisk_config)s
+ };
+ };
+};
+'''
+
+# Define a base FDT - currently we don't use anything in this
+base_fdt = '''
+/dts-v1/;
+
+/ {
+ model = "Sandbox Verified Boot Test";
+ compatible = "sandbox";
+
+};
+'''
+
+# This is the U-Boot script that is run for each test. First load the fit,
+# then do the 'bootm' command, then save out memory from the places where
+# we expect 'bootm' to write things. Then quit.
+base_script = '''
+sb load host 0 %(fit_addr)x %(fit)s
+fdt addr %(fit_addr)x
+bootm start %(fit_addr)x
+bootm loados
+sb save host 0 %(kernel_out)s %(kernel_addr)x %(kernel_size)x
+sb save host 0 %(fdt_out)s %(fdt_addr)x %(fdt_size)x
+sb save host 0 %(ramdisk_out)s %(ramdisk_addr)x %(ramdisk_size)x
+reset
+'''
+
+def make_fname(leaf):
+ """Make a temporary filename
+
+ Args:
+ leaf: Leaf name of file to create (within temporary directory)
+ Return:
+ Temporary filename
+ """
+ global base_dir
+
+ return os.path.join(base_dir, leaf)
+
+def filesize(fname):
+ """Get the size of a file
+
+ Args:
+ fname: Filename to check
+ Return:
+ Size of file in bytes
+ """
+ return os.stat(fname).st_size
+
+def read_file(fname):
+ """Read the contents of a file
+
+ Args:
+ fname: Filename to read
+ Returns:
+ Contents of file as a string
+ """
+ with open(fname, 'r') as fd:
+ return fd.read()
+
+def make_dtb():
+ """Make a sample .dts file and compile it to a .dtb
+
+ Returns:
+ Filename of .dtb file created
+ """
+ src = make_fname('u-boot.dts')
+ dtb = make_fname('u-boot.dtb')
+ with open(src, 'w') as fd:
+ print >>fd, base_fdt
+ command.Output('dtc', src, '-O', 'dtb', '-o', dtb)
+ return dtb
+
+def make_its(params):
+ """Make a sample .its file with parameters embedded
+
+ Args:
+ params: Dictionary containing parameters to embed in the %() strings
+ Returns:
+ Filename of .its file created
+ """
+ its = make_fname('test.its')
+ with open(its, 'w') as fd:
+ print >>fd, base_its % params
+ return its
+
+def make_fit(mkimage, params):
+ """Make a sample .fit file ready for loading
+
+ This creates a .its script with the selected parameters and uses mkimage to
+ turn this into a .fit image.
+
+ Args:
+ mkimage: Filename of 'mkimage' utility
+ params: Dictionary containing parameters to embed in the %() strings
+ Return:
+ Filename of .fit file created
+ """
+ fit = make_fname('test.fit')
+ its = make_its(params)
+ command.Output(mkimage, '-f', its, fit)
+ with open(make_fname('u-boot.dts'), 'w') as fd:
+ print >>fd, base_fdt
+ return fit
+
+def make_kernel():
+ """Make a sample kernel with test data
+
+ Returns:
+ Filename of kernel created
+ """
+ fname = make_fname('test-kernel.bin')
+ data = ''
+ for i in range(100):
+ data += 'this kernel %d is unlikely to boot\n' % i
+ with open(fname, 'w') as fd:
+ print >>fd, data
+ return fname
+
+def make_ramdisk():
+ """Make a sample ramdisk with test data
+
+ Returns:
+ Filename of ramdisk created
+ """
+ fname = make_fname('test-ramdisk.bin')
+ data = ''
+ for i in range(100):
+ data += 'ramdisk %d was seldom used in the middle ages\n' % i
+ with open(fname, 'w') as fd:
+ print >>fd, data
+ return fname
+
+def find_matching(text, match):
+ """Find a match in a line of text, and return the unmatched line portion
+
+ This is used to extract a part of a line from some text. The match string
+ is used to locate the line - we use the first line that contains that
+ match text.
+
+ Once we find a match, we discard the match string itself from the line,
+ and return what remains.
+
+ TODO: If this function becomes more generally useful, we could change it
+ to use regex and return groups.
+
+ Args:
+ text: Text to check (each line separated by \n)
+ match: String to search for
+ Return:
+ String containing unmatched portion of line
+ Exceptions:
+ ValueError: If match is not found
+
+ >>> find_matching('first line:10\\nsecond_line:20', 'first line:')
+ '10'
+ >>> find_matching('first line:10\\nsecond_line:20', 'second linex')
+ Traceback (most recent call last):
+ ...
+ ValueError: Test aborted
+ >>> find_matching('first line:10\\nsecond_line:20', 'second_line:')
+ '20'
+ """
+ for line in text.splitlines():
+ pos = line.find(match)
+ if pos != -1:
+ return line[:pos] + line[pos + len(match):]
+
+ print "Expected '%s' but not found in output:"
+ print text
+ raise ValueError('Test aborted')
+
+def set_test(name):
+ """Set the name of the current test and print a message
+
+ Args:
+ name: Name of test
+ """
+ global test_name
+
+ test_name = name
+ print name
+
+def fail(msg):
+ """Raise an error with a helpful failure message
+
+ Args:
+ msg: Message to display
+ """
+ raise ValueError("Test '%s' failed: %s" % (test_name, msg))
+
+def run_fit_test(mkimage, u_boot):
+ """Basic sanity check of FIT loading in U-Boot
+
+ TODO: Almost everything:
+ - hash algorithms - invalid hash/contents should be detected
+ - signature algorithms - invalid sig/contents should be detected
+ - compression
+ - checking that errors are detected like:
+ - image overwriting
+ - missing images
+ - invalid configurations
+ - incorrect os/arch/type fields
+ - empty data
+ - images too large/small
+ - invalid FDT (e.g. putting a random binary in instead)
+ - default configuration selection
+ - bootm command line parameters should have desired effect
+ - run code coverage to make sure we are testing all the code
+ """
+ global test_name
+
+ # Set up invariant files
+ control_dtb = make_dtb()
+ kernel = make_kernel()
+ ramdisk = make_ramdisk()
+ kernel_out = make_fname('kernel-out.bin')
+ fdt_out = make_fname('fdt-out.dtb')
+ ramdisk_out = make_fname('ramdisk-out.bin')
+
+ # Set up basic parameters with default values
+ params = {
+ 'fit_addr' : 0x1000,
+
+ 'kernel' : kernel,
+ 'kernel_out' : kernel_out,
+ 'kernel_addr' : 0x40000,
+ 'kernel_size' : filesize(kernel),
+
+ 'fdt_out' : fdt_out,
+ 'fdt_addr' : 0x80000,
+ 'fdt_size' : filesize(control_dtb),
+ 'fdt_load' : '',
+
+ 'ramdisk' : ramdisk,
+ 'ramdisk_out' : ramdisk_out,
+ 'ramdisk_addr' : 0xc0000,
+ 'ramdisk_size' : filesize(ramdisk),
+ 'ramdisk_load' : '',
+ 'ramdisk_config' : '',
+ }
+
+ # Make a basic FIT and a script to load it
+ fit = make_fit(mkimage, params)
+ params['fit'] = fit
+ cmd = base_script % params
+
+ # First check that we can load a kernel
+ # We could perhaps reduce duplication with some loss of readability
+ set_test('Kernel load')
+ stdout = command.Output(u_boot, '-d', control_dtb, '-c', cmd)
+ if read_file(kernel) != read_file(kernel_out):
+ fail('Kernel not loaded')
+ if read_file(control_dtb) == read_file(fdt_out):
+ fail('FDT loaded but should be ignored')
+ if read_file(ramdisk) == read_file(ramdisk_out):
+ fail('Ramdisk loaded but should not be')
+
+ # Find out the offset in the FIT where U-Boot has found the FDT
+ line = find_matching(stdout, 'Booting using the fdt blob at ')
+ fit_offset = int(line, 16) - params['fit_addr']
+ fdt_magic = struct.pack('>L', 0xd00dfeed)
+ data = read_file(fit)
+
+ # Now find where it actually is in the FIT (skip the first word)
+ real_fit_offset = data.find(fdt_magic, 4)
+ if fit_offset != real_fit_offset:
+ fail('U-Boot loaded FDT from offset %#x, FDT is actually at %#x' %
+ (fit_offset, real_fit_offset))
+
+ # Now a kernel and an FDT
+ set_test('Kernel + FDT load')
+ params['fdt_load'] = 'load = <%#x>;' % params['fdt_addr']
+ fit = make_fit(mkimage, params)
+ stdout = command.Output(u_boot, '-d', control_dtb, '-c', cmd)
+ if read_file(kernel) != read_file(kernel_out):
+ fail('Kernel not loaded')
+ if read_file(control_dtb) != read_file(fdt_out):
+ fail('FDT not loaded')
+ if read_file(ramdisk) == read_file(ramdisk_out):
+ fail('Ramdisk loaded but should not be')
+
+ # Try a ramdisk
+ set_test('Kernel + FDT + Ramdisk load')
+ params['ramdisk_config'] = 'ramdisk = "ramdisk@1";'
+ params['ramdisk_load'] = 'load = <%#x>;' % params['ramdisk_addr']
+ fit = make_fit(mkimage, params)
+ stdout = command.Output(u_boot, '-d', control_dtb, '-c', cmd)
+ if read_file(ramdisk) != read_file(ramdisk_out):
+ fail('Ramdisk not loaded')
+
+def run_tests():
+ """Parse options, run the FIT tests and print the result"""
+ global base_path, base_dir
+
+ # Work in a temporary directory
+ base_dir = tempfile.mkdtemp()
+ parser = OptionParser()
+ parser.add_option('-u', '--u-boot',
+ default=os.path.join(base_path, 'u-boot'),
+ help='Select U-Boot sandbox binary')
+ parser.add_option('-k', '--keep', action='store_true',
+ help="Don't delete temporary directory even when tests pass")
+ parser.add_option('-t', '--selftest', action='store_true',
+ help='Run internal self tests')
+ (options, args) = parser.parse_args()
+
+ # Find the path to U-Boot, and assume mkimage is in its tools/mkimage dir
+ base_path = os.path.dirname(options.u_boot)
+ mkimage = os.path.join(base_path, 'tools/mkimage')
+
+ # There are a few doctests - handle these here
+ if options.selftest:
+ doctest.testmod()
+ return
+
+ title = 'FIT Tests'
+ print title, '\n', '=' * len(title)
+
+ run_fit_test(mkimage, options.u_boot)
+
+ print '\nTests passed'
+ print 'Caveat: this is only a sanity check - test coverage is poor'
+
+ # Remove the tempoerary directory unless we are asked to keep it
+ if options.keep:
+ print "Output files are in '%s'" % base_dir
+ else:
+ shutil.rmtree(base_dir)
+
+run_tests()
diff --git a/tools/checkpatch.pl b/tools/checkpatch.pl
index 9f23901..896e2bc 100755
--- a/tools/checkpatch.pl
+++ b/tools/checkpatch.pl
@@ -273,6 +273,7 @@ our $logFunctions = qr{(?x:
WARN(?:_RATELIMIT|_ONCE|)|
panic|
debug|
+ printf|
MODULE_[A-Z_]+
)};
diff --git a/tools/mkimage.h b/tools/mkimage.h
index e07a615..03c6c8f 100644
--- a/tools/mkimage.h
+++ b/tools/mkimage.h
@@ -44,12 +44,24 @@
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+static inline void *map_sysmem(ulong paddr, unsigned long len)
+{
+ return (void *)(uintptr_t)paddr;
+}
+
+static inline ulong map_to_sysmem(void *ptr)
+{
+ return (ulong)(uintptr_t)ptr;
+}
+
#define MKIMAGE_TMPFILE_SUFFIX ".tmp"
#define MKIMAGE_MAX_TMPFILE_LEN 256
#define MKIMAGE_DEFAULT_DTC_OPTIONS "-I dts -O dtb -p 500"
#define MKIMAGE_MAX_DTC_CMDLINE_LEN 512
#define MKIMAGE_DTC "dtc" /* assume dtc is in $PATH */
+#define IH_ARCH_DEFAULT IH_ARCH_INVALID
+
/*
* This structure defines all such variables those are initialized by
* mkimage main core and need to be referred by image type specific