From: Marek Vasut <marek.vasut@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 16/20] iMX28: Fix ARM vector handling
Date: Wed, 9 Nov 2011 10:18:23 +0100 [thread overview]
Message-ID: <1320830307-4762-17-git-send-email-marek.vasut@gmail.com> (raw)
In-Reply-To: <1320830307-4762-1-git-send-email-marek.vasut@gmail.com>
This patch introduces proper ARM vector handling for i.MX28 CPU. This issue
wasn't addressed because the interrupts weren't enabled on any ARMv5 core,
therefore the issue wasn't noticed earlier.
In previous implementation, the vectoring code used by i.MX28 CPU when an
exception happened was that of the SPL. With this change, the branch target when
an exception happens can be reconfigured by U-Boot.
Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
Cc: Stefano Babic <sbabic@denx.de>
Cc: Wolfgang Denk <wd@denx.de>
Cc: Detlev Zundel <dzu@denx.de>
---
arch/arm/cpu/arm926ejs/mx28/mx28.c | 22 +++
board/denx/m28evk/start.S | 264 +++++++-----------------------------
include/configs/m28evk.h | 1 +
3 files changed, 74 insertions(+), 213 deletions(-)
diff --git a/arch/arm/cpu/arm926ejs/mx28/mx28.c b/arch/arm/cpu/arm926ejs/mx28/mx28.c
index e990f3c..088c019 100644
--- a/arch/arm/cpu/arm926ejs/mx28/mx28.c
+++ b/arch/arm/cpu/arm926ejs/mx28/mx28.c
@@ -35,6 +35,8 @@
#include <asm/arch/imx-regs.h>
#include <asm/arch/sys_proto.h>
+DECLARE_GLOBAL_DATA_PTR;
+
/* 1 second delay should be plenty of time for block reset. */
#define RESET_MAX_TIMEOUT 1000000
@@ -116,11 +118,31 @@ int mx28_reset_block(struct mx28_register *reg)
return 0;
}
+void mx28_fixup_vt(uint32_t start_addr)
+{
+ uint32_t *vt = (uint32_t *)0x20;
+ int i;
+
+ for (i = 0; i < 8; i++)
+ vt[i] = start_addr + (4 * i);
+}
+
+#ifdef CONFIG_ARCH_MISC_INIT
+int arch_misc_init(void)
+{
+ mx28_fixup_vt(gd->relocaddr);
+ return 0;
+}
+#endif
+
#ifdef CONFIG_ARCH_CPU_INIT
int arch_cpu_init(void)
{
struct mx28_clkctrl_regs *clkctrl_regs =
(struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
+ extern uint32_t _start;
+
+ mx28_fixup_vt((uint32_t)&_start);
/*
* Enable NAND clock
diff --git a/board/denx/m28evk/start.S b/board/denx/m28evk/start.S
index cf67599..94696d6 100644
--- a/board/denx/m28evk/start.S
+++ b/board/denx/m28evk/start.S
@@ -58,54 +58,58 @@
.globl _start
_start:
b reset
-#ifdef CONFIG_SPL_BUILD
-/* No exception handlers in preloader */
- ldr pc, _hang
- ldr pc, _hang
- ldr pc, _hang
- ldr pc, _hang
- b reset
- ldr pc, _hang
- ldr pc, _hang
+ b undefined_instruction
+ b software_interrupt
+ b prefetch_abort
+ b data_abort
+ b not_used
+ b irq
+ b fiq
-_hang:
- .word do_hang
-/* pad to 64 byte boundary */
- .word 0x12345678
- .word 0x12345678
- .word 0x12345678
- .word 0x12345678
- .word 0x12345678
- .word 0x12345678
- .word 0x12345678
-#else
- ldr pc, _undefined_instruction
- ldr pc, _software_interrupt
- ldr pc, _prefetch_abort
- ldr pc, _data_abort
- ldr pc, _not_used
- ldr pc, _irq
- ldr pc, _fiq
+/*
+ * Vector table, located at address 0x20.
+ * This table allows the code running AFTER SPL, the U-Boot, to install it's
+ * interrupt handlers here. The problem is that the U-Boot is loaded into RAM,
+ * including it's interrupt vectoring table and the table at 0x0 is still the
+ * SPLs. So if interrupt happens in U-Boot, the SPLs interrupt vectoring table
+ * is still used.
+ */
+_vt_reset:
+ .word _reset
+_vt_undefined_instruction:
+ .word _hang
+_vt_software_interrupt:
+ .word _hang
+_vt_prefetch_abort:
+ .word _hang
+_vt_data_abort:
+ .word _hang
+_vt_not_used:
+ .word _reset
+_vt_irq:
+ .word _hang
+_vt_fiq:
+ .word _hang
-_undefined_instruction:
- .word undefined_instruction
-_software_interrupt:
- .word software_interrupt
-_prefetch_abort:
- .word prefetch_abort
-_data_abort:
- .word data_abort
-_not_used:
- .word not_used
-_irq:
- .word irq
-_fiq:
- .word fiq
+reset:
+ ldr pc, _vt_reset
+undefined_instruction:
+ ldr pc, _vt_undefined_instruction
+software_interrupt:
+ ldr pc, _vt_software_interrupt
+prefetch_abort:
+ ldr pc, _vt_prefetch_abort
+data_abort:
+ ldr pc, _vt_data_abort
+not_used:
+ ldr pc, _vt_not_used
+irq:
+ ldr pc, _vt_irq
+fiq:
+ ldr pc, _vt_fiq
-#endif /* CONFIG_SPL_BUILD */
.balignl 16,0xdeadbeef
-
/*
*************************************************************************
*
@@ -162,7 +166,7 @@ IRQ_STACK_START_IN:
* the actual reset code
*/
-reset:
+_reset:
/*
* Store all registers on old stack pointer, this will allow us later to
* return to the BootROM and let the BootROM load U-Boot into RAM.
@@ -220,177 +224,11 @@ cpu_init_crit:
mcr p15, 0, r0, c1, c0, 0
mov pc, lr /* back to my caller */
-#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
-
-#ifndef CONFIG_SPL_BUILD
-/*
- *************************************************************************
- *
- * Interrupt handling
- *
- *************************************************************************
- */
-
-@
-@ IRQ stack frame.
-@
-#define S_FRAME_SIZE 72
-
-#define S_OLD_R0 68
-#define S_PSR 64
-#define S_PC 60
-#define S_LR 56
-#define S_SP 52
-
-#define S_IP 48
-#define S_FP 44
-#define S_R10 40
-#define S_R9 36
-#define S_R8 32
-#define S_R7 28
-#define S_R6 24
-#define S_R5 20
-#define S_R4 16
-#define S_R3 12
-#define S_R2 8
-#define S_R1 4
-#define S_R0 0
-
-#define MODE_SVC 0x13
-#define I_BIT 0x80
-
-/*
- * use bad_save_user_regs for abort/prefetch/undef/swi ...
- * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
- */
-
- .macro bad_save_user_regs
- @ carve out a frame on current user stack
- sub sp, sp, #S_FRAME_SIZE
- stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
- ldr r2, IRQ_STACK_START_IN
- @ get values for "aborted" pc and cpsr (into parm regs)
- ldmia r2, {r2 - r3}
- add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
- add r5, sp, #S_SP
- mov r1, lr
- stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
- mov r0, sp @ save current stack into r0 (param register)
- .endm
-
- .macro irq_save_user_regs
- sub sp, sp, #S_FRAME_SIZE
- stmia sp, {r0 - r12} @ Calling r0-r12
- @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
- add r8, sp, #S_PC
- stmdb r8, {sp, lr}^ @ Calling SP, LR
- str lr, [r8, #0] @ Save calling PC
- mrs r6, spsr
- str r6, [r8, #4] @ Save CPSR
- str r0, [r8, #8] @ Save OLD_R0
- mov r0, sp
- .endm
-
- .macro irq_restore_user_regs
- ldmia sp, {r0 - lr}^ @ Calling r0 - lr
- mov r0, r0
- ldr lr, [sp, #S_PC] @ Get PC
- add sp, sp, #S_FRAME_SIZE
- subs pc, lr, #4 @ return & move spsr_svc into cpsr
- .endm
-
- .macro get_bad_stack
- ldr r13, IRQ_STACK_START_IN @ setup our mode stack
-
- str lr, [r13] @ save caller lr in position 0 of saved stack
- mrs lr, spsr @ get the spsr
- str lr, [r13, #4] @ save spsr in position 1 of saved stack
- mov r13, #MODE_SVC @ prepare SVC-Mode
- @ msr spsr_c, r13
- msr spsr, r13 @ switch modes, make sure moves will execute
- mov lr, pc @ capture return pc
- movs pc, lr @ jump to next instruction & switch modes.
- .endm
-
- .macro get_irq_stack @ setup IRQ stack
- ldr sp, IRQ_STACK_START
- .endm
-
- .macro get_fiq_stack @ setup FIQ stack
- ldr sp, FIQ_STACK_START
- .endm
-#endif /* CONFIG_SPL_BUILD */
-/*
- * exception handlers
- */
-#ifdef CONFIG_SPL_BUILD
.align 5
-do_hang:
+#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
+
+_hang:
ldr sp, _TEXT_BASE /* switch to abort stack */
1:
bl 1b /* hang and never return */
-#else /* !CONFIG_SPL_BUILD */
- .align 5
-undefined_instruction:
- get_bad_stack
- bad_save_user_regs
- bl do_undefined_instruction
-
- .align 5
-software_interrupt:
- get_bad_stack
- bad_save_user_regs
- bl do_software_interrupt
-
- .align 5
-prefetch_abort:
- get_bad_stack
- bad_save_user_regs
- bl do_prefetch_abort
-
- .align 5
-data_abort:
- get_bad_stack
- bad_save_user_regs
- bl do_data_abort
-
- .align 5
-not_used:
- get_bad_stack
- bad_save_user_regs
- bl do_not_used
-
-#ifdef CONFIG_USE_IRQ
-
- .align 5
-irq:
- get_irq_stack
- irq_save_user_regs
- bl do_irq
- irq_restore_user_regs
-
- .align 5
-fiq:
- get_fiq_stack
- /* someone ought to write a more effiction fiq_save_user_regs */
- irq_save_user_regs
- bl do_fiq
- irq_restore_user_regs
-
-#else
-
- .align 5
-irq:
- get_bad_stack
- bad_save_user_regs
- bl do_irq
-
- .align 5
-fiq:
- get_bad_stack
- bad_save_user_regs
- bl do_fiq
-
-#endif
-#endif /* CONFIG_SPL_BUILD */
diff --git a/include/configs/m28evk.h b/include/configs/m28evk.h
index 59e3e05..381b01e 100644
--- a/include/configs/m28evk.h
+++ b/include/configs/m28evk.h
@@ -41,6 +41,7 @@
#define CONFIG_SYS_DCACHE_OFF
#define CONFIG_BOARD_EARLY_INIT_F
#define CONFIG_ARCH_CPU_INIT
+#define CONFIG_ARCH_MISC_INIT
/*
* SPL
--
1.7.7.1
next prev parent reply other threads:[~2011-11-09 9:18 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-11-09 9:18 [U-Boot] [PATCH 00/20 FINAL] Support for the DENX M28 SoM Marek Vasut
2011-11-09 9:18 ` [U-Boot] [PATCH 01/20] iMX28: Initial support for iMX28 CPU Marek Vasut
2011-11-09 9:18 ` [U-Boot] [PATCH 02/20] iMX28: Add SSP MMC driver Marek Vasut
2011-11-10 13:08 ` Stefano Babic
2011-11-09 9:18 ` [U-Boot] [PATCH 03/20] FEC: Add support for iMX28 quirks Marek Vasut
2011-11-10 13:09 ` Stefano Babic
2011-11-09 9:18 ` [U-Boot] [PATCH 04/20] iMX28: Add PINMUX control Marek Vasut
2011-11-10 13:09 ` Stefano Babic
2011-11-09 9:18 ` [U-Boot] [PATCH 05/20] iMX28: Add I2C bus driver Marek Vasut
2011-11-09 9:38 ` Heiko Schocher
2011-11-09 10:46 ` Marek Vasut
2011-11-10 13:10 ` Stefano Babic
2011-11-09 9:18 ` [U-Boot] [PATCH 06/20] iMX28: Add GPIO control Marek Vasut
2011-11-10 13:11 ` Stefano Babic
2011-11-10 16:23 ` Mike Frysinger
2011-11-10 16:58 ` Marek Vasut
2011-11-10 17:10 ` Mike Frysinger
2011-11-10 17:44 ` Marek Vasut
2011-11-09 9:18 ` [U-Boot] [PATCH 07/20] iMX28: Add SPI driver Marek Vasut
2011-11-10 13:11 ` Stefano Babic
2011-11-09 9:18 ` [U-Boot] [PATCH 08/20] iMX28: Add APBH DMA driver Marek Vasut
2011-11-10 13:12 ` Stefano Babic
2011-11-09 9:18 ` [U-Boot] [PATCH 09/20] iMX28: Add GPMI NAND driver Marek Vasut
2011-11-10 13:12 ` Stefano Babic
2011-11-09 9:18 ` [U-Boot] [PATCH 10/20] iMX28: Add driver for internal RTC Marek Vasut
2011-11-10 13:12 ` Stefano Babic
2011-11-09 9:18 ` [U-Boot] [PATCH 11/20] iMX28: Add image header generator tool Marek Vasut
2011-11-10 13:12 ` Stefano Babic
2011-11-09 9:18 ` [U-Boot] [PATCH 12/20] iMX28: Add u-boot.sb target to Makefile Marek Vasut
2011-11-10 13:13 ` Stefano Babic
2011-11-09 9:18 ` [U-Boot] [PATCH 13/20] iMX28: Add support for DENX M28EVK board Marek Vasut
2011-11-10 13:13 ` Stefano Babic
2011-11-09 9:18 ` [U-Boot] [PATCH 14/20] M28: Add MMC SPL Marek Vasut
2011-11-10 13:13 ` Stefano Babic
2011-11-09 9:18 ` [U-Boot] [PATCH 15/20] M28: Add doc/README.m28 documentation Marek Vasut
2011-11-10 13:14 ` Stefano Babic
2011-11-09 9:18 ` Marek Vasut [this message]
2011-11-10 13:14 ` [U-Boot] [PATCH 16/20] iMX28: Fix ARM vector handling Stefano Babic
2011-11-09 9:18 ` [U-Boot] [PATCH 17/20] M28: Add memory detection into SPL Marek Vasut
2011-11-10 13:14 ` Stefano Babic
2011-11-09 9:18 ` [U-Boot] [PATCH 18/20] iMX28: Add USB and USB PHY register definitions Marek Vasut
2011-11-10 13:15 ` Stefano Babic
2011-11-09 9:18 ` [U-Boot] [PATCH 19/20] iMX28: Add USB HOST driver Marek Vasut
2011-11-10 13:15 ` Stefano Babic
2011-11-09 9:18 ` [U-Boot] [PATCH 20/20] M28EVK: Enable USB HOST support Marek Vasut
2011-11-10 13:16 ` Stefano Babic
2011-11-11 14:07 ` Veli-Pekka Peltola
2011-11-11 17:49 ` Marek Vasut
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1320830307-4762-17-git-send-email-marek.vasut@gmail.com \
--to=marek.vasut@gmail.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox