diff options
author | Barry Wardell <rockbox@barrywardell.net> | 2006-12-19 11:33:53 +0000 |
---|---|---|
committer | Barry Wardell <rockbox@barrywardell.net> | 2006-12-19 11:33:53 +0000 |
commit | 2f16d4f1b3e52f0a268fa9679a72694f5a89dedf (patch) | |
tree | 332b7b5390bcd95fea7b291ca840e709c7aa1f83 /firmware/target/arm/crt0-pp.S | |
parent | 6f4f58916417bdd11f2faf8339a0e94a039ca7a8 (diff) | |
download | rockbox-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.S | 135 |
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 | ||
65 | pad_skip: | 59 | pad_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 | ||
124 | 1: | ||
125 | 120 | ||
126 | #ifndef DEBUG | 121 | cpu_init: |
122 | /* Wait for COP to be sleeping */ | ||
123 | ldr r4, =COP_STATUS | ||
124 | 1: | ||
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 | |||
208 | cop_wake_start: | ||
209 | /* jump the COP to startup */ | ||
210 | ldr r0, =startup_loc | ||
211 | ldr pc, [r0] | ||
212 | |||
213 | 1: | ||
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 */ | ||
224 | 1: | ||
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 | |||
232 | start_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 | ||
245 | 1: | ||
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 | |||
258 | startup_loc: | ||
259 | .word 0x0 | ||
260 | |||
261 | .align 8 /* starts at 0x100 */ | ||
262 | .global boot_table | ||
263 | boot_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 | ||
292 | cop_init: | 200 | cop_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 | ||
209 | 1: | ||
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 |
387 | fiq_stack: | 312 | fiq_stack: |
388 | |||
389 | #endif /* BOOTLOADER */ | ||