diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2013-01-15 12:40:20 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2013-01-20 16:53:46 +0100 |
commit | 6e45abe47ece9052956afcda8331fd50a2500e96 (patch) | |
tree | d79713205a53dffedd6a004a3ac8b28bd625e0ab /arch | |
parent | 3de3b677ee3adc4e10235b623a8e0aa45be48893 (diff) | |
download | barebox-6e45abe47ece9052956afcda8331fd50a2500e96.tar.gz barebox-6e45abe47ece9052956afcda8331fd50a2500e96.tar.xz |
ARM i.MX: Add a common NAND entry for external boot mode
The pattern for i.MX boards starting in external NAND boot mode is always
the same:
- Check if we are running in NFC address space, if not call
board_init_lowlevel_return()
- copy binary to link address
- execute relocated binary
- call imx_nand_load_image()
Add a common function for this to make the board code easier.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-imx/external-nand-boot.c | 75 | ||||
-rw-r--r-- | arch/arm/mach-imx/include/mach/imx-nand.h | 5 |
2 files changed, 80 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/external-nand-boot.c b/arch/arm/mach-imx/external-nand-boot.c index 2e9e475fed..39ffb944f3 100644 --- a/arch/arm/mach-imx/external-nand-boot.c +++ b/arch/arm/mach-imx/external-nand-boot.c @@ -15,6 +15,8 @@ #include <init.h> #include <io.h> #include <linux/mtd/nand.h> +#include <asm/sections.h> +#include <asm/barebox-arm.h> #include <mach/imx-nand.h> #include <mach/generic.h> #include <mach/imx21-regs.h> @@ -256,6 +258,79 @@ void __bare_init imx_nand_load_image(void *dest, int size) } } +/* + * We are now running at the address we are linked at. Now load the image from + * NAND to SDRAM and continue booting. + */ +static void __bare_init __naked insdram(void) +{ + imx_nand_load_image((void *)_text, barebox_image_size); + + board_init_lowlevel_return(); +} + +/* + * Load and start barebox from NAND. This function also checks if we are really + * running inside the NFC address space. If not, barebox is started from the + * currently running address without loading anything from NAND. + */ +void __bare_init __noreturn imx_barebox_boot_nand_external(unsigned long nfc_base) +{ + u32 r; + u32 *src, *trg; + int i; + + /* skip NAND boot if not running from NFC space */ + r = get_pc(); + if (r < nfc_base || r > nfc_base + 0x800) + board_init_lowlevel_return(); + + src = (unsigned int *)nfc_base; + trg = (unsigned int *)_text; + + /* Move ourselves out of NFC SRAM */ + for (i = 0; i < 0x800 / sizeof(int); i++) + *trg++ = *src++; + + /* Jump to SDRAM */ + r = (unsigned int)&insdram; + __asm__ __volatile__("mov pc, %0" : : "r"(r)); + + /* not reached */ + while (1); +} + +/* + * SoC specific entries for booting in external NAND mode. To be called from + * the board specific entry code. This is safe to call even if not booting from + * NAND. In this case the booting is continued without loading an image from + * NAND. This function needs a stack to be set up. + */ +void __bare_init __noreturn imx21_barebox_boot_nand_external(void) +{ + imx_barebox_boot_nand_external(MX21_NFC_BASE_ADDR); +} + +void __bare_init __noreturn imx25_barebox_boot_nand_external(void) +{ + imx_barebox_boot_nand_external(MX25_NFC_BASE_ADDR); +} + +void __bare_init __noreturn imx27_barebox_boot_nand_external(void) +{ + imx_barebox_boot_nand_external(MX27_NFC_BASE_ADDR); +} + +void __bare_init __noreturn imx31_barebox_boot_nand_external(void) +{ + imx_barebox_boot_nand_external(MX31_NFC_BASE_ADDR); +} + +void __bare_init __noreturn imx35_barebox_boot_nand_external(void) +{ + imx_barebox_boot_nand_external(MX35_NFC_BASE_ADDR); +} + #define CONFIG_NAND_IMX_BOOT_DEBUG #ifdef CONFIG_NAND_IMX_BOOT_DEBUG #include <command.h> diff --git a/arch/arm/mach-imx/include/mach/imx-nand.h b/arch/arm/mach-imx/include/mach/imx-nand.h index fb753cfc13..a1f209ed2c 100644 --- a/arch/arm/mach-imx/include/mach/imx-nand.h +++ b/arch/arm/mach-imx/include/mach/imx-nand.h @@ -4,6 +4,11 @@ #include <linux/mtd/mtd.h> void imx_nand_load_image(void *dest, int size); +void imx21_barebox_boot_nand_external(void); +void imx25_barebox_boot_nand_external(void); +void imx27_barebox_boot_nand_external(void); +void imx31_barebox_boot_nand_external(void); +void imx35_barebox_boot_nand_external(void); void imx_nand_set_layout(int writesize, int datawidth); struct imx_nand_platform_data { |