Message ID | 1442508773-29993-4-git-send-email-bernhard.nortmann@web.de |
---|---|
State | Accepted |
Delegated to: | Hans de Goede |
Headers | show |
Hi, On 09/17/2015 12:52 PM, Bernhard Nortmann wrote: > This patch extends the misc_init_r() function on sunxi boards > to test for the presence of a suitable "sunxi" SPL header. If > found, and the loader ("fel" utility) provided a non-zero value > for the boot.scr address, then the corresponding environment > variable fel_scriptaddr gets set. > > misc_init_r() also sets (or clears) the "fel_booted" variable depending > on the active boot device, using the same logic as spl_boot_device(). > > The goal is to provide sufficient information (within the U-Boot > environment) to make intelligent decisions on how to continue the boot > process, allowing specific customizations for the "FEL boot" case. > > Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de> > --- > > Changes in v3: > - make use of asm/arch/spl.h to share definitions / helper macro > - revert SPL version check to expect exact SPL_HEADER_VERSION > > Changes in v2: > - renamed fel_data_addr to fel_script_addr, discarded fel_data_size > - make sure that FEL-related environment vars are always cleared first > - support minimum and maximum SPL (header) version, more verbose error messages > > arch/arm/cpu/armv7/sunxi/board.c | 2 +- > arch/arm/include/asm/arch-sunxi/spl.h | 5 +++++ > arch/arm/include/asm/spl.h | 5 +++++ > board/sunxi/board.c | 35 +++++++++++++++++++++++++++++++++++ > 4 files changed, 46 insertions(+), 1 deletion(-) > > diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c > index b40198b..0d68d20 100644 > --- a/arch/arm/cpu/armv7/sunxi/board.c > +++ b/arch/arm/cpu/armv7/sunxi/board.c > @@ -152,7 +152,7 @@ u32 spl_boot_device(void) > * binary over USB. If it is found, it determines where SPL was > * read from. > */ > - if (readl(4) != 0x4E4F4765 || readl(8) != 0x3054422E) /* eGON.BT0 */ > + if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */ > return BOOT_DEVICE_BOARD; > > /* The BROM will try to boot from mmc0 first, so try that first. */ > diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h > index 08fe32d..8abf79a 100644 > --- a/arch/arm/include/asm/arch-sunxi/spl.h > +++ b/arch/arm/include/asm/arch-sunxi/spl.h > @@ -13,6 +13,9 @@ > #define SPL_SIGNATURE "SPL" /* marks "sunxi" SPL header */ > #define SPL_HEADER_VERSION 1 > > +/* Note: A80 will require special handling here: SPL_ADDR 0x10000 */ > +#define SPL_ADDR 0x0 > + > /* boot head definition from sun4i boot code */ > struct boot_file_head { > uint32_t b_instruction; /* one intruction jumping to real code */ > @@ -43,4 +46,6 @@ struct boot_file_head { > uint32_t reserved; /* padding, align to 32 bytes */ > }; > > +#define is_boot0_magic(addr) (memcmp((void *)addr, BOOT0_MAGIC, 8) == 0) > + > #endif > diff --git a/arch/arm/include/asm/spl.h b/arch/arm/include/asm/spl.h > index 6db405d..6587732 100644 > --- a/arch/arm/include/asm/spl.h > +++ b/arch/arm/include/asm/spl.h > @@ -7,6 +7,11 @@ > #ifndef _ASM_SPL_H_ > #define _ASM_SPL_H_ > > +#if defined(CONFIG_SUNXI) > +/* sunxi platform-specific additions */ > +#include <asm/arch/spl.h> > +#endif > + > #if defined(CONFIG_OMAP) \ > || defined(CONFIG_EXYNOS4) || defined(CONFIG_EXYNOS5) \ > || defined(CONFIG_EXYNOS4210) There is no need to pollute a non sunxi header this way, we can simply do "#include <asm/arch/spl.h>" where needed. No need to resend I've fixed this up in my tree. Regards, Hans > diff --git a/board/sunxi/board.c b/board/sunxi/board.c > index 9c855f6..096d127 100644 > --- a/board/sunxi/board.c > +++ b/board/sunxi/board.c > @@ -516,6 +516,31 @@ void get_board_serial(struct tag_serialnr *serialnr) > } > #endif > > +#if !defined(CONFIG_SPL_BUILD) > +#include <asm/arch/spl.h> > + > +/* > + * Check the SPL header for the "sunxi" variant. If found: parse values > + * that might have been passed by the loader ("fel" utility), and update > + * the environment accordingly. > + */ > +static void parse_spl_header(const uint32_t spl_addr) > +{ > + struct boot_file_head *spl = (void *)spl_addr; > + if (memcmp(spl->spl_signature, SPL_SIGNATURE, 3) == 0) { > + uint8_t spl_header_version = spl->spl_signature[3]; > + if (spl_header_version == SPL_HEADER_VERSION) { > + if (spl->fel_script_address) > + setenv_hex("fel_scriptaddr", > + spl->fel_script_address); > + return; > + } > + printf("sunxi SPL version mismatch: expected %u, got %u\n", > + SPL_HEADER_VERSION, spl_header_version); > + } > +} > +#endif > + > #ifdef CONFIG_MISC_INIT_R > int misc_init_r(void) > { > @@ -524,6 +549,16 @@ int misc_init_r(void) > uint8_t mac_addr[6]; > int ret; > > +#if !defined(CONFIG_SPL_BUILD) > + setenv("fel_booted", NULL); > + setenv("fel_scriptaddr", NULL); > + /* determine if we are running in FEL mode */ > + if (!is_boot0_magic(SPL_ADDR + 4)) { /* eGON.BT0 */ > + setenv("fel_booted", "1"); > + parse_spl_header(SPL_ADDR); > + } > +#endif > + > ret = sunxi_get_sid(sid); > if (ret == 0 && sid[0] != 0 && sid[3] != 0) { > if (!getenv("ethaddr")) { >
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index b40198b..0d68d20 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -152,7 +152,7 @@ u32 spl_boot_device(void) * binary over USB. If it is found, it determines where SPL was * read from. */ - if (readl(4) != 0x4E4F4765 || readl(8) != 0x3054422E) /* eGON.BT0 */ + if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */ return BOOT_DEVICE_BOARD; /* The BROM will try to boot from mmc0 first, so try that first. */ diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h index 08fe32d..8abf79a 100644 --- a/arch/arm/include/asm/arch-sunxi/spl.h +++ b/arch/arm/include/asm/arch-sunxi/spl.h @@ -13,6 +13,9 @@ #define SPL_SIGNATURE "SPL" /* marks "sunxi" SPL header */ #define SPL_HEADER_VERSION 1 +/* Note: A80 will require special handling here: SPL_ADDR 0x10000 */ +#define SPL_ADDR 0x0 + /* boot head definition from sun4i boot code */ struct boot_file_head { uint32_t b_instruction; /* one intruction jumping to real code */ @@ -43,4 +46,6 @@ struct boot_file_head { uint32_t reserved; /* padding, align to 32 bytes */ }; +#define is_boot0_magic(addr) (memcmp((void *)addr, BOOT0_MAGIC, 8) == 0) + #endif diff --git a/arch/arm/include/asm/spl.h b/arch/arm/include/asm/spl.h index 6db405d..6587732 100644 --- a/arch/arm/include/asm/spl.h +++ b/arch/arm/include/asm/spl.h @@ -7,6 +7,11 @@ #ifndef _ASM_SPL_H_ #define _ASM_SPL_H_ +#if defined(CONFIG_SUNXI) +/* sunxi platform-specific additions */ +#include <asm/arch/spl.h> +#endif + #if defined(CONFIG_OMAP) \ || defined(CONFIG_EXYNOS4) || defined(CONFIG_EXYNOS5) \ || defined(CONFIG_EXYNOS4210) diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 9c855f6..096d127 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -516,6 +516,31 @@ void get_board_serial(struct tag_serialnr *serialnr) } #endif +#if !defined(CONFIG_SPL_BUILD) +#include <asm/arch/spl.h> + +/* + * Check the SPL header for the "sunxi" variant. If found: parse values + * that might have been passed by the loader ("fel" utility), and update + * the environment accordingly. + */ +static void parse_spl_header(const uint32_t spl_addr) +{ + struct boot_file_head *spl = (void *)spl_addr; + if (memcmp(spl->spl_signature, SPL_SIGNATURE, 3) == 0) { + uint8_t spl_header_version = spl->spl_signature[3]; + if (spl_header_version == SPL_HEADER_VERSION) { + if (spl->fel_script_address) + setenv_hex("fel_scriptaddr", + spl->fel_script_address); + return; + } + printf("sunxi SPL version mismatch: expected %u, got %u\n", + SPL_HEADER_VERSION, spl_header_version); + } +} +#endif + #ifdef CONFIG_MISC_INIT_R int misc_init_r(void) { @@ -524,6 +549,16 @@ int misc_init_r(void) uint8_t mac_addr[6]; int ret; +#if !defined(CONFIG_SPL_BUILD) + setenv("fel_booted", NULL); + setenv("fel_scriptaddr", NULL); + /* determine if we are running in FEL mode */ + if (!is_boot0_magic(SPL_ADDR + 4)) { /* eGON.BT0 */ + setenv("fel_booted", "1"); + parse_spl_header(SPL_ADDR); + } +#endif + ret = sunxi_get_sid(sid); if (ret == 0 && sid[0] != 0 && sid[3] != 0) { if (!getenv("ethaddr")) {
This patch extends the misc_init_r() function on sunxi boards to test for the presence of a suitable "sunxi" SPL header. If found, and the loader ("fel" utility) provided a non-zero value for the boot.scr address, then the corresponding environment variable fel_scriptaddr gets set. misc_init_r() also sets (or clears) the "fel_booted" variable depending on the active boot device, using the same logic as spl_boot_device(). The goal is to provide sufficient information (within the U-Boot environment) to make intelligent decisions on how to continue the boot process, allowing specific customizations for the "FEL boot" case. Signed-off-by: Bernhard Nortmann <bernhard.nortmann@web.de> --- Changes in v3: - make use of asm/arch/spl.h to share definitions / helper macro - revert SPL version check to expect exact SPL_HEADER_VERSION Changes in v2: - renamed fel_data_addr to fel_script_addr, discarded fel_data_size - make sure that FEL-related environment vars are always cleared first - support minimum and maximum SPL (header) version, more verbose error messages arch/arm/cpu/armv7/sunxi/board.c | 2 +- arch/arm/include/asm/arch-sunxi/spl.h | 5 +++++ arch/arm/include/asm/spl.h | 5 +++++ board/sunxi/board.c | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-)