summaryrefslogtreecommitdiff
path: root/utils/hwstub/stub/rk27xx/crt0.S
diff options
context:
space:
mode:
authorMarcin Bukat <marcin.bukat@gmail.com>2013-07-18 23:55:35 +0200
committerMarcin Bukat <marcin.bukat@gmail.com>2013-11-24 00:10:36 +0100
commit8e633385912494ff5e871ec4c264d3a7db46fb98 (patch)
treea8d6b23861969b7df72bb79695ad742082ce2b02 /utils/hwstub/stub/rk27xx/crt0.S
parent1ed57aaa5049d2bbe4e94bed6674bd405e98a4a5 (diff)
downloadrockbox-8e633385912494ff5e871ec4c264d3a7db46fb98.tar.gz
rockbox-8e633385912494ff5e871ec4c264d3a7db46fb98.zip
hwstub rk27xx port
Change-Id: I85ac57117911544b65ccd56eb16303e30be67cab
Diffstat (limited to 'utils/hwstub/stub/rk27xx/crt0.S')
-rw-r--r--utils/hwstub/stub/rk27xx/crt0.S164
1 files changed, 164 insertions, 0 deletions
diff --git a/utils/hwstub/stub/rk27xx/crt0.S b/utils/hwstub/stub/rk27xx/crt0.S
new file mode 100644
index 0000000000..0c702eca91
--- /dev/null
+++ b/utils/hwstub/stub/rk27xx/crt0.S
@@ -0,0 +1,164 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2008 by Marcoen Hirschberg
10 * Copyright (C) 2008 by Denes Balatoni
11 * Copyright (C) 2010 by Marcin Bukat
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22
23 .extern INT_UDC
24
25 .global start
26 .global entry_point
27
28 /* Exception vectors */
29 .section .intvect,"ax",%progbits
30 ldr pc, =start
31 ldr pc, =start
32 ldr pc, =start
33 ldr pc, =start
34 ldr pc, =start
35 ldr pc, =start
36 ldr pc, =irq_handler
37 ldr pc, =start
38 .ltorg
39
40 .section .text,"ax",%progbits
41start:
42 msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
43
44 sub r4, pc, #12 /* copy running address, accomodate
45 * for prefetch (-8) and msr instr (-4)
46 */
47
48 ldr r0, =0xefff0000 /* cache controler base address */
49 ldrh r1, [r0]
50 strh r1, [r0] /* global cache disable */
51
52 ldr r2, =_relocstart
53 ldr r3, =_relocend
54
55 cmp r2, r4
56 beq entry_point /* skip copying if we are in place already */
571:
58 cmp r3, r2
59 ldrhi r1, [r4], #4
60 strhi r1, [r2], #4
61 bhi 1b
62
63entry_point_jmp:
64 ldr pc, =entry_point
65
66entry_point:
67 mov r0, #0x18000000
68 add r0, r0, #0x1c000
69
70 /* setup ARM core freq = 200MHz
71 * AHB bus freq (HCLK) = 100MHz
72 * APB bus freq (PCLK) = 50MHz
73 * Note: it seems there is no way to run AHB bus at ARM freq
74 * bit2 in DIVCON1 must have different meaning to what datasheet
75 * states. It influences SDRAM read speed but does not change
76 * APB freq
77 */
78 ldr r1, [r0,#0x14] /* SCU_DIVCON1 */
79 bic r1, r1, #0x1f
80 orr r1, r1, #9 /* ((1<<3)|(1<<0)) ARM slow mode, HCLK:PCLK = 2:1 */
81 str r1, [r0,#0x14]
82
83 ldr r1,=0x1850310 /* ((1<<24)|(1<<23)|(5<<16)|(49<<4)) */
84 str r1, [r0,#0x08]
85
86 ldr r2,=0x40000
871:
88 ldr r1, [r0,#0x2c] /* SCU_STATUS */
89 tst r1, #1 /* ARM pll lock */
90 bne 1f
91 subs r2, r2, #1
92 bne 1b
931:
94 ldr r1, [r0,#0x14] /* SCU_DIVCON1 */
95 bic r1, #1 /* leave ARM slow mode */
96 str r1, [r0,#0x14]
97
98 /* remap iram to 0x00000000 */
99 ldr r1,=0xdeadbeef
100 str r1, [r0, #4]
101
102 /* Copy interrupt vectors to iram */
103 ldr r2, =_intvectstart
104 ldr r3, =_intvectend
105 ldr r4, =_intvectcopy
1061:
107 cmp r3, r2
108 ldrhi r1, [r4], #4
109 strhi r1, [r2], #4
110 bhi 1b
111
112 /* Initialise bss section to zero */
113 ldr r2, =_edata
114 ldr r3, =_end
115 mov r4, #0
1161:
117 cmp r3, r2
118 strhi r4, [r2], #4
119 bhi 1b
120
121 /* Set up stack for IRQ mode */
122 msr cpsr_c, #0xd2
123 ldr sp, =_irqstackend
124
125 /* Set up stack for FIQ mode */
126 msr cpsr_c, #0xd1
127 ldr sp, =_fiqstackend
128
129 /* Let svc, abort and undefined modes use irq stack */
130 msr cpsr_c, #0xd3
131 ldr sp, =_irqstackend
132 msr cpsr_c, #0xd7
133 ldr sp, =_irqstackend
134 msr cpsr_c, #0xdb
135 ldr sp, =_irqstackend
136
137 /* Switch to sys mode */
138 msr cpsr_c, #0xdf
139
140 /* Set up some stack and munge it with 0xdeadbeef */
141 ldr sp, =stackend
142 ldr r2, =stackbegin
143 ldr r3, =0xdeadbeef
1441:
145 cmp sp, r2
146 strhi r3, [r2], #4
147 bhi 1b
148
149 /* Jump to C code */
150 b main
151
152/* copy from rockbox code - context save may be excessive but who cares */
153irq_handler:
154 stmfd sp!, {r0-r5, ip, lr} /* store context */
155 ldr r4, =0x18080000 /* INTC base */
156 ldr r5, [r4, #0x104] /* INTC_ISR */
157 and r5, r5, #0x1f /* irq_no = INTC_ISR & 0x1f */
158 cmp r5, #0x10 /* UDC irq */
159 bleq INT_UDC /* handle it */
160 mov r3, #1
161 lsl r5, r3, r5 /* clear interrupt */
162 str r5, [r4, #0x118] /* INTC_ICCR = (1<<irq_no) */
163 ldmfd sp!, {r0-r5, ip, lr} /* restore context */
164 subs pc, lr, #4