summaryrefslogtreecommitdiff
path: root/firmware/target/arm/crt0-pp.S
diff options
context:
space:
mode:
authorBarry Wardell <rockbox@barrywardell.net>2006-12-19 11:33:53 +0000
committerBarry Wardell <rockbox@barrywardell.net>2006-12-19 11:33:53 +0000
commit2f16d4f1b3e52f0a268fa9679a72694f5a89dedf (patch)
tree332b7b5390bcd95fea7b291ca840e709c7aa1f83 /firmware/target/arm/crt0-pp.S
parent6f4f58916417bdd11f2faf8339a0e94a039ca7a8 (diff)
downloadrockbox-2f16d4f1b3e52f0a268fa9679a72694f5a89dedf.tar.gz
rockbox-2f16d4f1b3e52f0a268fa9679a72694f5a89dedf.zip
Add working dual-boot bootloaders for H10 and Sansa, which allow booting the OF and Rockbox. Rolo also works.
Changes made: Combine bootloader/h10.c and bootloader/e200.c into a common bootloader file (bootloader/main-pp.c) to be used by all mi4 based PortalPlayer targets. The file bootloader/main-pp.c is based off the old bootloader/h10.c with some minor changes to allow it to work on the Sansa too. This effectively adds a Sansa bootloader. Define MODEL_NAME string in config-*.h for use in bootloader. Split crt0-pp.S into separate files for bootloader and normal builds. Bootloader code is now in crt0-pp-bl.S while normal build code stays in crt0-pp.S. Improvements to crt0-pp.S and crt0-pp-bl.S (mostly to make it more multiprocessor safe): * Leave space in bootloader at 0xe0-0xeb since scramble writes over there when it creates the mi4 file (don't leave space for iPods since it's not needed and all code in crt0-pp-bl.S needs to fit before the boot_table at 0x100). * Remove unused DEBUG and STUB code from crt0-pp.S. * Make CPU wait for COP to be sleeping when we put the COP to sleep. * Invalidate COP cache when COP wakes * Flush CPU cache before waking COP * Make sure only the CPU clears the BSS (not the COP) * Make sure only the CPU sets up its own stack (not the COP) Rolo works on H10, so enable it. Make Sansa e200 use rockbox.e200 rather than PP5022.mi4 for 'Normal' builds. This makes updating rockbox simpler as we don't need to go through the firmware update procedure, but rather just put a new rockbox.e200 on the device. rockbox.e200 uses a simple 'add' checksum. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11815 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm/crt0-pp.S')
-rw-r--r--firmware/target/arm/crt0-pp.S135
1 files changed, 29 insertions, 106 deletions
diff --git a/firmware/target/arm/crt0-pp.S b/firmware/target/arm/crt0-pp.S
index 17b1e8a4a3..892275e411 100644
--- a/firmware/target/arm/crt0-pp.S
+++ b/firmware/target/arm/crt0-pp.S
@@ -52,15 +52,9 @@ start:
52 52
53 msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ */ 53 msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ */
54 54
55#ifndef BOOTLOADER
56 b pad_skip 55 b pad_skip
57 56
58#if defined(SANSA_E200) 57.space 50*4 /* (more than enough) space for exception vectors */
59/* mi4tool writes junk between 0xe0 and 0xeb. Avoid this. */
60.space 60*4 /* (more than enough) space for exception vectors */
61#else
62.space 50*4
63#endif
64 58
65pad_skip: 59pad_skip:
66#ifdef SANSA_E200 60#ifdef SANSA_E200
@@ -108,11 +102,13 @@ remap_end:
108 102
109 /* After doing the remapping, send the COP to sleep. 103 /* After doing the remapping, send the COP to sleep.
110 On wakeup it will go to cop_init */ 104 On wakeup it will go to cop_init */
105
106 /* Find out which processor we are */
111 ldr r0, =PROC_ID 107 ldr r0, =PROC_ID
112 ldr r0, [r0] 108 ldr r0, [r0]
113 and r0, r0, #0xff 109 and r0, r0, #0xff
114 cmp r0, #0x55 110 cmp r0, #0x55
115 beq 1f 111 beq cpu_init
116 112
117 /* put us (co-processor) to sleep */ 113 /* put us (co-processor) to sleep */
118 ldr r4, =COP_CTRL 114 ldr r4, =COP_CTRL
@@ -121,9 +117,15 @@ remap_end:
121 117
122 ldr pc, =cop_init 118 ldr pc, =cop_init
123 119
1241:
125 120
126#ifndef DEBUG 121cpu_init:
122 /* Wait for COP to be sleeping */
123 ldr r4, =COP_STATUS
1241:
125 ldr r3, [r4]
126 ands r3, r3, #SLEEPING
127 beq 1b
128
127 /* Copy exception handler code to address 0 */ 129 /* Copy exception handler code to address 0 */
128 ldr r2, =_vectorsstart 130 ldr r2, =_vectorsstart
129 ldr r3, =_vectorsend 131 ldr r3, =_vectorsend
@@ -133,15 +135,7 @@ remap_end:
133 ldrhi r5, [r4], #4 135 ldrhi r5, [r4], #4
134 strhi r5, [r2], #4 136 strhi r5, [r2], #4
135 bhi 1b 137 bhi 1b
136#else
137 ldr r1, =vectors
138 ldr r0, =irq_handler
139 str r0, [r1, #24]
140 ldr r0, =fiq_handler
141 str r0, [r1, #28]
142#endif
143 138
144#ifndef STUB
145 /* Zero out IBSS */ 139 /* Zero out IBSS */
146 ldr r2, =_iedata 140 ldr r2, =_iedata
147 ldr r3, =_iend 141 ldr r3, =_iend
@@ -160,8 +154,6 @@ remap_end:
160 ldrhi r5, [r2], #4 154 ldrhi r5, [r2], #4
161 strhi r5, [r3], #4 155 strhi r5, [r3], #4
162 bhi 1b 156 bhi 1b
163#endif /* !STUB */
164#endif /* !BOOTLOADER */
165 157
166 /* Initialise bss section to zero */ 158 /* Initialise bss section to zero */
167 ldr r2, =_edata 159 ldr r2, =_edata
@@ -181,90 +173,6 @@ remap_end:
181 cmp r3, r2 173 cmp r3, r2
182 strhi r4, [r2], #4 174 strhi r4, [r2], #4
183 bhi 1b 175 bhi 1b
184
185#ifdef BOOTLOADER
186 /* TODO: the high part of the address is probably dependent on CONFIG_CPU.
187 Since we tend to use ifdefs for each chipset target
188 anyway, we might as well just hardcode it here.
189 */
190
191 /* get the high part of our execute address */
192 ldr r0, =0xff000000
193 and r8, pc, r0 @ r8 is used later
194
195 /* Find out which processor we are */
196 mov r0, #PROC_ID
197 ldr r0, [r0]
198 and r0, r0, #0xff
199 cmp r0, #0x55
200 beq 1f
201
202 /* put us (co-processor) to sleep */
203 ldr r4, =COP_CTRL
204 mov r3, #SLEEP
205 str r3, [r4]
206 ldr pc, =cop_wake_start
207
208cop_wake_start:
209 /* jump the COP to startup */
210 ldr r0, =startup_loc
211 ldr pc, [r0]
212
2131:
214
215 /* get the high part of our execute address */
216 ldr r2, =0xffffff00
217 and r4, pc, r2
218
219 /* Copy bootloader to safe area - 0x40000000 */
220 mov r5, #0x40000000
221 ldr r6, = _dataend
222 sub r0, r6, r5 /* length of loader */
223 add r0, r4, r0 /* r0 points to start of loader */
2241:
225 cmp r5, r6
226 ldrcc r2, [r4], #4
227 strcc r2, [r5], #4
228 bcc 1b
229
230 ldr pc, =start_loc /* jump to the relocated start_loc: */
231
232start_loc:
233
234 /* execute the loader - this will load an image to 0x10000000 */
235 bl main
236
237 /* Wake up the coprocessor before executing the firmware */
238
239 /* save the startup address for the COP */
240 ldr r1, =startup_loc
241 str r0, [r1]
242
243 /* make sure COP is sleeping */
244 ldr r4, =COP_STATUS
2451:
246 ldr r3, [r4]
247 ands r3, r3, #SLEEPING
248 beq 1b
249
250 /* wake up COP */
251 ldr r4, =COP_CTRL
252 mov r3, #WAKE
253 str r3, [r4]
254
255 /* jump to start location */
256 mov pc, r0
257
258startup_loc:
259 .word 0x0
260
261.align 8 /* starts at 0x100 */
262.global boot_table
263boot_table:
264 /* here comes the boot table, don't move its offset */
265 .space 400
266
267#else /* BOOTLOADER */
268 176
269 /* Set up stack for IRQ mode */ 177 /* Set up stack for IRQ mode */
270 msr cpsr_c, #0xd2 178 msr cpsr_c, #0xd2
@@ -290,6 +198,21 @@ boot_table:
290 /* main() should never return */ 198 /* main() should never return */
291 199
292cop_init: 200cop_init:
201#if CONFIG_CPU != PP5002
202 /* COP: Invalidate cache */
203 ldr r0, =0xf000f044
204 ldr r1, [r0]
205 orr r1, r1, #0x6
206 str r1, [r0]
207
208 ldr r0, =0x6000c000
2091:
210 ldr r1, [r0]
211 tst r1, #0x8000
212 bne 1b
213#endif
214
215 /* Setup stack for COP */
293 ldr sp, =cop_stackend 216 ldr sp, =cop_stackend
294 mov r3, sp 217 mov r3, sp
295 ldr r2, =cop_stackbegin 218 ldr r2, =cop_stackbegin
@@ -300,6 +223,8 @@ cop_init:
300 bhi 2b 223 bhi 2b
301 224
302 ldr sp, =cop_stackend 225 ldr sp, =cop_stackend
226
227 /* Run cop_main() in apps/main.c */
303 bl cop_main 228 bl cop_main
304 229
305/* Exception handlers. Will be copied to address 0 after memory remapping */ 230/* Exception handlers. Will be copied to address 0 after memory remapping */
@@ -385,5 +310,3 @@ irq_stack:
385/* 256 words of FIQ stack */ 310/* 256 words of FIQ stack */
386 .space 256*4 311 .space 256*4
387fiq_stack: 312fiq_stack:
388
389#endif /* BOOTLOADER */