summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx233/crt0.S
diff options
context:
space:
mode:
authorAmaury Pouly <pamaury@rockbox.org>2011-05-01 13:02:46 +0000
committerAmaury Pouly <pamaury@rockbox.org>2011-05-01 13:02:46 +0000
commit08fb3f65745a237e2c1eae55d856ff27702246e5 (patch)
treea56ce11ac20e4df0e36de9195306c10b71752538 /firmware/target/arm/imx233/crt0.S
parentc0838cbfd8e45621fe3450aee1bf9458ff420d16 (diff)
Sansa Fuze+: initial commit (bootloader only, LCD basically working)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29808 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/imx233/crt0.S')
-rw-r--r--firmware/target/arm/imx233/crt0.S117
1 files changed, 117 insertions, 0 deletions
diff --git a/firmware/target/arm/imx233/crt0.S b/firmware/target/arm/imx233/crt0.S
new file mode 100644
index 0000000000..836c3e88cb
--- /dev/null
+++ b/firmware/target/arm/imx233/crt0.S
@@ -0,0 +1,117 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2011 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#include "config.h"
+#include "cpu.h"
+
+.section .vectors,"ax",%progbits
+.code 32
+.global start
+start:
+ /* most handlers are in DRAM which is too far away for a relative jump */
+ ldr pc, =newstart
+ ldr pc, =undef_instr_handler
+ ldr pc, =software_int_handler
+ ldr pc, =prefetch_abort_handler
+ ldr pc, =data_abort_handler
+ ldr pc, =reserved_handler
+ ldr pc, =irq_handler
+ ldr pc, =fiq_handler
+
+.text
+newstart:
+ msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
+ /* Set up some stack and munge it with 0xdeadbeef */
+ ldr sp, =stackend
+ ldr r2, =stackbegin
+ ldr r3, =0xdeadbeef
+1:
+ cmp sp, r2
+ strhi r3, [r2], #4
+ bhi 1b
+
+ /* Set up stack for IRQ mode */
+ msr cpsr_c, #0xd2
+ ldr sp, =irq_stack
+
+ /* Set up stack for FIQ mode */
+ msr cpsr_c, #0xd1
+ ldr sp, =fiq_stack
+
+ /* Let abort and undefined modes use IRQ stack */
+ msr cpsr_c, #0xd7
+ ldr sp, =irq_stack
+ msr cpsr_c, #0xdb
+ ldr sp, =irq_stack
+
+ /* Switch back to supervisor mode */
+ msr cpsr_c, #0xd3
+
+ /* Disable MMU, disable caching and buffering;
+ * use low exception range address (the core uses high range by default) */
+ mrc p15, 0, r0, c1, c0, 0
+ ldr r1, =0x3005
+ bic r0, r1
+ mcr p15, 0, r0, c1, c0, 0
+
+ /* Jump to main */
+ bl main
+1:
+ b 1b
+
+/* All illegal exceptions call into UIE with exception address as first
+ * parameter. This is calculated differently depending on which exception
+ * we're in. Second parameter is exception number, used for a string lookup
+ * in UIE. */
+undef_instr_handler:
+ sub r0, lr, #4 @ r0 points to the faulty ARM instruction
+#ifdef USE_THUMB
+ mrs r1, spsr
+ tst r1, #(1<<5) @ T bit set ?
+ subne r0, lr, #2 @ if yes, r0 points to the faulty THUMB instruction
+#endif /* USE_THUMB */
+ mov r1, #0
+ b UIE
+
+/* We run supervisor mode most of the time, and should never see a software
+ * exception being thrown. Perhaps make it illegal and call UIE? */
+software_int_handler:
+reserved_handler:
+ movs pc, lr
+
+prefetch_abort_handler:
+ sub r0, lr, #4
+ mov r1, #1
+ b UIE
+
+data_abort_handler:
+ sub r0, lr, #8
+ mov r1, #2
+ b UIE
+
+/* 256 words of IRQ stack */
+ .space 256*4
+irq_stack:
+
+/* 256 words of FIQ stack */
+ .space 256*4
+fiq_stack:
+
+end: