summaryrefslogtreecommitdiffstats
path: root/arch/arm/include
diff options
context:
space:
mode:
authorJan Luebbe <jlu@pengutronix.de>2012-09-24 10:18:34 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2012-09-27 19:30:04 +0200
commitfaf7b7af6e51a33b88453821d792c89a84f72b1d (patch)
treebff70e6a71339e4d62e90c23ead1fc351effc89a /arch/arm/include
parentcc1602604d1654991f3ce02b664178b3e672afe7 (diff)
downloadbarebox-faf7b7af6e51a33b88453821d792c89a84f72b1d.tar.gz
barebox-faf7b7af6e51a33b88453821d792c89a84f72b1d.tar.xz
ARM: give boards control of the reset entry point
On some SoCs (for example AM35xx), the ROM bootloader passes useful information in r0 when jumping to barebox. To avoid overwriting this in the generic reset code, we introduce common_reset as a C function and as an assembler macro. This is then called form the reset entry point (either in common or in board code). This patch is based on code by Sascha Hauer <s.hauer@pengutronix.de>. Signed-off-by: Jan Luebbe <jlu@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/include')
-rw-r--r--arch/arm/include/asm/barebox-arm-head.h68
-rw-r--r--arch/arm/include/asm/system.h4
2 files changed, 72 insertions, 0 deletions
diff --git a/arch/arm/include/asm/barebox-arm-head.h b/arch/arm/include/asm/barebox-arm-head.h
index 0b1d78644d..eafad4e311 100644
--- a/arch/arm/include/asm/barebox-arm-head.h
+++ b/arch/arm/include/asm/barebox-arm-head.h
@@ -1,6 +1,37 @@
#ifndef __ASM_ARM_HEAD_H
#define __ASM_ARM_HEAD_H
+#include <asm/system.h>
+
+#ifndef __ASSEMBLY__
+
+static inline void common_reset(void)
+{
+ uint32_t r;
+
+ /* set the cpu to SVC32 mode */
+ __asm__ __volatile__("mrs %0, cpsr":"=r"(r));
+ r &= ~0x1f;
+ r |= 0xd3;
+ __asm__ __volatile__("msr cpsr, %0" : : "r"(r));
+
+ /* disable MMU stuff and caches */
+ r = get_cr();
+ r &= ~(CR_M | CR_C | CR_B | CR_S | CR_R | CR_V);
+ r |= CR_I;
+
+#if __LINUX_ARM_ARCH__ >= 6
+ r |= CR_U;
+#else
+ r |= CR_A;
+#endif
+
+#ifdef __ARMEB__
+ r |= CR_B;
+#endif
+ set_cr(r);
+}
+
#ifdef CONFIG_HAVE_MACH_ARM_HEAD
#include <mach/barebox-arm-head.h>
#else
@@ -36,4 +67,41 @@ static inline void barebox_arm_head(void)
}
#endif
+#else
+
+.macro common_reset, scratch
+
+ /* set the cpu to SVC32 mode */
+ mrs \scratch, cpsr
+ bic \scratch, \scratch, #0x1f
+ orr \scratch, \scratch, #0xd3
+ msr cpsr, \scratch
+
+#if __LINUX_ARM_ARCH__ >= 7
+ isb
+#elif __LINUX_ARM_ARCH__ == 6
+ mcr p15, 0, \scratch, c7, c5, 4
+#endif
+
+ /* disable MMU stuff and caches */
+ mrc p15, 0, \scratch, c1, c0, 0
+ bic \scratch, \scratch , #(CR_M | CR_C | CR_B)
+ bic \scratch, \scratch, #(CR_S | CR_R | CR_V)
+ orr \scratch, \scratch, #CR_I
+
+#if __LINUX_ARM_ARCH__ >= 6
+ orr \scratch, \scratch, #CR_U
+#else
+ orr \scratch, \scratch, #CR_A
+#endif
+
+#ifdef __ARMEB__
+ orr \scratch, \scratch, #CR_B
+#endif
+
+ mcr p15, 0, \scratch, c1, c0, 0
+.endm
+
+#endif /* __ASSEMBLY__ */
+
#endif /* __ASM_ARM_HEAD_H */
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 1d67492477..26fb18c79a 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -56,6 +56,7 @@
#define CR_AFE (1 << 29) /* Access flag enable */
#define CR_TE (1 << 30) /* Thumb exception enable */
+#ifndef __ASSEMBLY__
static inline unsigned int get_cr(void)
{
unsigned int val;
@@ -69,4 +70,7 @@ static inline void set_cr(unsigned int val)
: : "r" (val) : "cc");
isb();
}
+
+#endif
+
#endif /* __ASM_ARM_SYSTEM_H */