summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-imx/external-nand-boot.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2013-01-24 17:09:00 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2013-02-04 15:52:38 +0100
commitcf4271ee12f8ce61598a327a72026226441dca72 (patch)
tree9c7d740469c8980eb541e4abe958bec5e2c8f038 /arch/arm/mach-imx/external-nand-boot.c
parent028ae2ba6e763e8f6685c5d6f80286da81ea132e (diff)
downloadbarebox-cf4271ee12f8ce61598a327a72026226441dca72.tar.gz
barebox-cf4271ee12f8ce61598a327a72026226441dca72.tar.xz
ARM i.MX: prepare external nand boot for SoC specific entry
i.MX will get SoC specific entry points for barebox. To find the correct one we have to call these from the SoC specific imx*_barebox_boot_nand_external functions. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/mach-imx/external-nand-boot.c')
-rw-r--r--arch/arm/mach-imx/external-nand-boot.c73
1 files changed, 53 insertions, 20 deletions
diff --git a/arch/arm/mach-imx/external-nand-boot.c b/arch/arm/mach-imx/external-nand-boot.c
index 39ffb944f3..c97fec9b43 100644
--- a/arch/arm/mach-imx/external-nand-boot.c
+++ b/arch/arm/mach-imx/external-nand-boot.c
@@ -259,14 +259,19 @@ 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.
+ * This function assumes the currently running binary has been
+ * copied from its current position to an offset. It returns
+ * to the calling function - offset.
+ * NOTE: The calling function may not return itself since it still
+ * works on the old content of the lr register. Only call this
+ * from a __noreturn function.
*/
-static void __bare_init __naked insdram(void)
+static __bare_init __naked void jump_sdram(unsigned long offset)
{
- imx_nand_load_image((void *)_text, barebox_image_size);
-
- board_init_lowlevel_return();
+ __asm__ __volatile__ (
+ "sub lr, lr, %0;"
+ "mov pc, lr;" : : "r"(offset)
+ );
}
/*
@@ -274,7 +279,7 @@ static void __bare_init __naked insdram(void)
* 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)
+void __bare_init imx_barebox_boot_nand_external(unsigned long nfc_base)
{
u32 r;
u32 *src, *trg;
@@ -283,7 +288,7 @@ void __bare_init __noreturn imx_barebox_boot_nand_external(unsigned long nfc_bas
/* skip NAND boot if not running from NFC space */
r = get_pc();
if (r < nfc_base || r > nfc_base + 0x800)
- board_init_lowlevel_return();
+ return;
src = (unsigned int *)nfc_base;
trg = (unsigned int *)_text;
@@ -291,13 +296,6 @@ void __bare_init __noreturn imx_barebox_boot_nand_external(unsigned long nfc_bas
/* 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);
}
/*
@@ -306,30 +304,65 @@ void __bare_init __noreturn imx_barebox_boot_nand_external(unsigned long nfc_bas
* NAND. In this case the booting is continued without loading an image from
* NAND. This function needs a stack to be set up.
*/
+#ifdef CONFIG_ARCH_IMX21
void __bare_init __noreturn imx21_barebox_boot_nand_external(void)
{
- imx_barebox_boot_nand_external(MX21_NFC_BASE_ADDR);
+ unsigned long nfc_base = MX21_NFC_BASE_ADDR;
+
+ imx_barebox_boot_nand_external(nfc_base);
+ jump_sdram(nfc_base - (unsigned long)_text);
+ imx_nand_load_image((void *)_text, barebox_image_size);
+ board_init_lowlevel_return();
}
+#endif
+#ifdef CONFIG_ARCH_IMX25
void __bare_init __noreturn imx25_barebox_boot_nand_external(void)
{
- imx_barebox_boot_nand_external(MX25_NFC_BASE_ADDR);
+ unsigned long nfc_base = MX25_NFC_BASE_ADDR;
+
+ imx_barebox_boot_nand_external(nfc_base);
+ jump_sdram(nfc_base - (unsigned long)_text);
+ imx_nand_load_image((void *)_text, barebox_image_size);
+ board_init_lowlevel_return();
}
+#endif
+#ifdef CONFIG_ARCH_IMX27
void __bare_init __noreturn imx27_barebox_boot_nand_external(void)
{
- imx_barebox_boot_nand_external(MX27_NFC_BASE_ADDR);
+ unsigned long nfc_base = MX27_NFC_BASE_ADDR;
+
+ imx_barebox_boot_nand_external(nfc_base);
+ jump_sdram(nfc_base - (unsigned long)_text);
+ imx_nand_load_image((void *)_text, barebox_image_size);
+ board_init_lowlevel_return();
}
+#endif
+#ifdef CONFIG_ARCH_IMX31
void __bare_init __noreturn imx31_barebox_boot_nand_external(void)
{
- imx_barebox_boot_nand_external(MX31_NFC_BASE_ADDR);
+ unsigned long nfc_base = MX31_NFC_BASE_ADDR;
+
+ imx_barebox_boot_nand_external(nfc_base);
+ jump_sdram(nfc_base - (unsigned long)_text);
+ imx_nand_load_image((void *)_text, barebox_image_size);
+ board_init_lowlevel_return();
}
+#endif
+#ifdef CONFIG_ARCH_IMX35
void __bare_init __noreturn imx35_barebox_boot_nand_external(void)
{
- imx_barebox_boot_nand_external(MX35_NFC_BASE_ADDR);
+ unsigned long nfc_base = MX35_NFC_BASE_ADDR;
+
+ imx_barebox_boot_nand_external(nfc_base);
+ jump_sdram(nfc_base - (unsigned long)_text);
+ imx_nand_load_image((void *)_text, barebox_image_size);
+ board_init_lowlevel_return();
}
+#endif
#define CONFIG_NAND_IMX_BOOT_DEBUG
#ifdef CONFIG_NAND_IMX_BOOT_DEBUG