[U-Boot,v2] sunxi: Increase SPL header size to 64 bytes to avoid code corruption
diff mbox

Message ID 1463188406-4707-1-git-send-email-siarhei.siamashka@gmail.com
State Accepted
Commit b19236fd1c1ef289bab9e243ee5b50d658fcac3f
Delegated to: Hans de Goede
Headers show

Commit Message

Siarhei Siamashka May 14, 2016, 1:13 a.m. UTC
The current SPL header, created by the 'mksunxiboot' tool, has size
32 bytes. But the code in the boot ROM stores the information about
the boot media at the offset 0x28 before passing control to the SPL.
For example, when booting from the SD card, the magic number written
by the boot ROM is 0. And when booting from the SPI flash, the magic
number is 3. NAND and eMMC probably have their own special magic
numbers too.

Currently the corrupted byte is a part of one of the instructions in
the reset vectors table:

    b     reset
    ldr   pc, _undefined_instruction
    ldr   pc, _software_interrupt      <- Corruption happens here
    ldr   pc, _prefetch_abort
    ldr   pc, _data_abort
    ldr   pc, _not_used
    ldr   pc, _irq
    ldr   pc, _fiq

In practice this does not cause any visible problems, but it's still
better to fix it. As a bonus, the reported boot media type can be
later used in the 'spl_boot_device' function, but this is out of
the scope of this patch.

Signed-off-by: Siarhei Siamashka <siarhei.siamashka@gmail.com>
---

Changes in v2:
 - Increase the header size to 64 bytes instead of 48 bytes in order
   to satisfy the VBAR alignment requirements.

 arch/arm/include/asm/arch-sunxi/spl.h |  8 +++++++-
 include/configs/sunxi-common.h        | 12 ++++++------
 2 files changed, 13 insertions(+), 7 deletions(-)

Comments

Hans de Goede May 15, 2016, 10:04 a.m. UTC | #1
Hi,

On 14-05-16 03:13, Siarhei Siamashka wrote:
> The current SPL header, created by the 'mksunxiboot' tool, has size
> 32 bytes. But the code in the boot ROM stores the information about
> the boot media at the offset 0x28 before passing control to the SPL.
> For example, when booting from the SD card, the magic number written
> by the boot ROM is 0. And when booting from the SPI flash, the magic
> number is 3. NAND and eMMC probably have their own special magic
> numbers too.
>
> Currently the corrupted byte is a part of one of the instructions in
> the reset vectors table:
>
>     b     reset
>     ldr   pc, _undefined_instruction
>     ldr   pc, _software_interrupt      <- Corruption happens here
>     ldr   pc, _prefetch_abort
>     ldr   pc, _data_abort
>     ldr   pc, _not_used
>     ldr   pc, _irq
>     ldr   pc, _fiq
>
> In practice this does not cause any visible problems, but it's still
> better to fix it. As a bonus, the reported boot media type can be
> later used in the 'spl_boot_device' function, but this is out of
> the scope of this patch.
>
> Signed-off-by: Siarhei Siamashka <siarhei.siamashka@gmail.com>

Thanks, looks good to me applied to:

http://git.denx.de/?p=u-boot/u-boot-sunxi.git;a=shortlog;h=refs/heads/next

This will be part of my first pull-req for u-boot v2016.07.

Regards,

Hans



> ---
>
> Changes in v2:
>  - Increase the header size to 64 bytes instead of 48 bytes in order
>    to satisfy the VBAR alignment requirements.
>
>  arch/arm/include/asm/arch-sunxi/spl.h |  8 +++++++-
>  include/configs/sunxi-common.h        | 12 ++++++------
>  2 files changed, 13 insertions(+), 7 deletions(-)
>
> diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h
> index ca9a4f9..a0f33b0 100644
> --- a/arch/arm/include/asm/arch-sunxi/spl.h
> +++ b/arch/arm/include/asm/arch-sunxi/spl.h
> @@ -18,6 +18,10 @@
>  #define SPL_ADDR		0x0
>  #endif
>
> +/* The low 8-bits of the 'boot_media' field in the SPL header */
> +#define SUNXI_BOOTED_FROM_MMC0	0
> +#define SUNXI_BOOTED_FROM_SPI	3
> +
>  /* boot head definition from sun4i boot code */
>  struct boot_file_head {
>  	uint32_t b_instruction;	/* one intruction jumping to real code */
> @@ -45,7 +49,9 @@ struct boot_file_head {
>  		uint8_t spl_signature[4];
>  	};
>  	uint32_t fel_script_address;
> -	uint32_t reserved;		/* padding, align to 32 bytes */
> +	uint32_t reserved1[3];
> +	uint32_t boot_media;		/* written here by the boot ROM */
> +	uint32_t reserved2[5];		/* padding, align to 64 bytes */
>  };
>
>  #define is_boot0_magic(addr)	(memcmp((void *)addr, BOOT0_MAGIC, 8) == 0)
> diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
> index 2406115..e2ee908 100644
> --- a/include/configs/sunxi-common.h
> +++ b/include/configs/sunxi-common.h
> @@ -189,14 +189,14 @@
>  #define CONFIG_SPL_BOARD_LOAD_IMAGE
>
>  #if defined(CONFIG_MACH_SUN9I)
> -#define CONFIG_SPL_TEXT_BASE		0x10020		/* sram start+header */
> -#define CONFIG_SPL_MAX_SIZE		0x5fe0		/* ? KiB on sun9i */
> +#define CONFIG_SPL_TEXT_BASE		0x10040		/* sram start+header */
> +#define CONFIG_SPL_MAX_SIZE		0x5fc0		/* ? KiB on sun9i */
>  #elif defined(CONFIG_MACH_SUN50I)
> -#define CONFIG_SPL_TEXT_BASE		0x10020		/* sram start+header */
> -#define CONFIG_SPL_MAX_SIZE		0x7fe0		/* 32 KiB on sun50i */
> +#define CONFIG_SPL_TEXT_BASE		0x10040		/* sram start+header */
> +#define CONFIG_SPL_MAX_SIZE		0x7fc0		/* 32 KiB on sun50i */
>  #else
> -#define CONFIG_SPL_TEXT_BASE		0x20		/* sram start+header */
> -#define CONFIG_SPL_MAX_SIZE		0x5fe0		/* 24KB on sun4i/sun7i */
> +#define CONFIG_SPL_TEXT_BASE		0x40		/* sram start+header */
> +#define CONFIG_SPL_MAX_SIZE		0x5fc0		/* 24KB on sun4i/sun7i */
>  #endif
>
>  #define CONFIG_SPL_LIBDISK_SUPPORT
>

Patch
diff mbox

diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h
index ca9a4f9..a0f33b0 100644
--- a/arch/arm/include/asm/arch-sunxi/spl.h
+++ b/arch/arm/include/asm/arch-sunxi/spl.h
@@ -18,6 +18,10 @@ 
 #define SPL_ADDR		0x0
 #endif
 
+/* The low 8-bits of the 'boot_media' field in the SPL header */
+#define SUNXI_BOOTED_FROM_MMC0	0
+#define SUNXI_BOOTED_FROM_SPI	3
+
 /* boot head definition from sun4i boot code */
 struct boot_file_head {
 	uint32_t b_instruction;	/* one intruction jumping to real code */
@@ -45,7 +49,9 @@  struct boot_file_head {
 		uint8_t spl_signature[4];
 	};
 	uint32_t fel_script_address;
-	uint32_t reserved;		/* padding, align to 32 bytes */
+	uint32_t reserved1[3];
+	uint32_t boot_media;		/* written here by the boot ROM */
+	uint32_t reserved2[5];		/* padding, align to 64 bytes */
 };
 
 #define is_boot0_magic(addr)	(memcmp((void *)addr, BOOT0_MAGIC, 8) == 0)
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 2406115..e2ee908 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -189,14 +189,14 @@ 
 #define CONFIG_SPL_BOARD_LOAD_IMAGE
 
 #if defined(CONFIG_MACH_SUN9I)
-#define CONFIG_SPL_TEXT_BASE		0x10020		/* sram start+header */
-#define CONFIG_SPL_MAX_SIZE		0x5fe0		/* ? KiB on sun9i */
+#define CONFIG_SPL_TEXT_BASE		0x10040		/* sram start+header */
+#define CONFIG_SPL_MAX_SIZE		0x5fc0		/* ? KiB on sun9i */
 #elif defined(CONFIG_MACH_SUN50I)
-#define CONFIG_SPL_TEXT_BASE		0x10020		/* sram start+header */
-#define CONFIG_SPL_MAX_SIZE		0x7fe0		/* 32 KiB on sun50i */
+#define CONFIG_SPL_TEXT_BASE		0x10040		/* sram start+header */
+#define CONFIG_SPL_MAX_SIZE		0x7fc0		/* 32 KiB on sun50i */
 #else
-#define CONFIG_SPL_TEXT_BASE		0x20		/* sram start+header */
-#define CONFIG_SPL_MAX_SIZE		0x5fe0		/* 24KB on sun4i/sun7i */
+#define CONFIG_SPL_TEXT_BASE		0x40		/* sram start+header */
+#define CONFIG_SPL_MAX_SIZE		0x5fc0		/* 24KB on sun4i/sun7i */
 #endif
 
 #define CONFIG_SPL_LIBDISK_SUPPORT