summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2008-05-08 12:09:14 +0000
committerMichael Sevakis <jethead71@rockbox.org>2008-05-08 12:09:14 +0000
commit6dd6ea74af4ebfa1112f2e606db67357c0e2632f (patch)
tree5506268620a9dfe49923a4e6e5c957bedcd6fabe
parente616092fd566e9d0455727ef32a2879f15ac80da (diff)
downloadrockbox-6dd6ea74af4ebfa1112f2e606db67357c0e2632f.tar.gz
rockbox-6dd6ea74af4ebfa1112f2e606db67357c0e2632f.zip
Gigabeat S RoLo: Properly execute firmware copy from an IRAM stub because the currently running image was being overwritten in place. Minor tweak to rolo.c based on imx31 errata sheet about not masking FIQ without masking IRQ which is fine to use on all ARM anyway.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17414 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/SOURCES1
-rw-r--r--firmware/rolo.c15
-rw-r--r--firmware/target/arm/imx31/rolo_restart.S66
3 files changed, 77 insertions, 5 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 3fe773babd..ecd5e69c22 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -657,6 +657,7 @@ target/arm/s3c2440/gigabeat-fx/wmcodec-meg-fx.c
657target/arm/lcd-as-memframe.S 657target/arm/lcd-as-memframe.S
658target/arm/mmu-arm.c 658target/arm/mmu-arm.c
659target/arm/imx31/debug-imx31.c 659target/arm/imx31/debug-imx31.c
660target/arm/imx31/rolo_restart.S
660target/arm/imx31/gigabeat-s/adc-imx31.c 661target/arm/imx31/gigabeat-s/adc-imx31.c
661target/arm/imx31/gigabeat-s/ata-imx31.c 662target/arm/imx31/gigabeat-s/ata-imx31.c
662target/arm/imx31/gigabeat-s/avic-imx31.c 663target/arm/imx31/gigabeat-s/avic-imx31.c
diff --git a/firmware/rolo.c b/firmware/rolo.c
index 5dbb6f9874..06ae9e1380 100644
--- a/firmware/rolo.c
+++ b/firmware/rolo.c
@@ -108,10 +108,11 @@ static void rolo_error(const char *text)
108 lcd_stop_scroll(); 108 lcd_stop_scroll();
109} 109}
110 110
111#if CONFIG_CPU == SH7034 111#if CONFIG_CPU == SH7034 || CONFIG_CPU == IMX31L
112/* these are in assembler file "descramble.S" */ 112/* these are in assembler file "descramble.S" for SH7034 */
113extern unsigned short descramble(const unsigned char* source, 113extern unsigned short descramble(const unsigned char* source,
114 unsigned char* dest, int length); 114 unsigned char* dest, int length);
115/* this is in firmware/target/arm/imx31/rolo_restart.S for IMX31 */
115extern void rolo_restart(const unsigned char* source, unsigned char* dest, 116extern void rolo_restart(const unsigned char* source, unsigned char* dest,
116 int length); 117 int length);
117#else 118#else
@@ -169,7 +170,7 @@ void rolo_restart(const unsigned char* source, unsigned char* dest,
169 "mov pc, r0 \n" 170 "mov pc, r0 \n"
170 ); 171 );
171 172
172#elif defined(CPU_TCC780X) || (CONFIG_CPU==IMX31L) || (CONFIG_CPU == S3C2440) 173#elif defined(CPU_TCC780X) || (CONFIG_CPU == S3C2440)
173 /* Flush and invalidate caches */ 174 /* Flush and invalidate caches */
174 invalidate_icache(); 175 invalidate_icache();
175 176
@@ -284,9 +285,13 @@ int rolo_load(const char* filename)
284 adc_close(); 285 adc_close();
285 286
286#ifdef CPU_ARM 287#ifdef CPU_ARM
287 disable_fiq(); 288 /* Should do these together since some ARM version should never have
288#endif 289 * FIQ disabled and not IRQ (imx31 errata). */
290 disable_interrupt(IRQ_FIQ_STATUS);
291#else
292 /* Some targets have a higher disable level than HIGEST_IRQ_LEVEL */
289 set_irq_level(DISABLE_INTERRUPTS); 293 set_irq_level(DISABLE_INTERRUPTS);
294#endif
290 295
291#elif CONFIG_CPU == SH7034 296#elif CONFIG_CPU == SH7034
292 /* Read file length from header and compare to real file length */ 297 /* Read file length from header and compare to real file length */
diff --git a/firmware/target/arm/imx31/rolo_restart.S b/firmware/target/arm/imx31/rolo_restart.S
new file mode 100644
index 0000000000..39053de96f
--- /dev/null
+++ b/firmware/target/arm/imx31/rolo_restart.S
@@ -0,0 +1,66 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2008 by Michael Sevakis
11 *
12 * RoLo restart code for IMX31
13 *
14 * All files in this archive are subject to the GNU General Public License.
15 * See the file COPYING in the source tree root for full license agreement.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "config.h"
22#include "cpu.h"
23
24/****************************************************************************
25 * void rolo_restart(const unsigned char* source, unsigned char* dest,
26 * int length) __attribute__((noreturn));
27 */
28 .section .text, "ax", %progbits
29 .align 2
30 .global rolo_restart
31rolo_restart:
32 adr r4, restart_copy_start
33 adr r5, restart_copy_end
34 ldr r6, =IRAM_BASE_ADDR
35 mov r7, r6
36
37 @ Copy stub to IRAM
381:
39 ldr r8, [r4], #4
40 str r8, [r7], #4
41 cmp r5, r4
42 bhi 1b
43
44 @ Branch to stub
45 bx r6
46
47restart_copy_start:
48 @ Trivial copy of firmware to final location
49 mov r4, r1
501:
51 subs r2, r2, #1
52 ldrb r7, [r0], #1
53 strb r7, [r4], #1
54 bge 1b
55
56 @ Clean and invalidate all caches
57 mov r0, #0
58 mcr p15, 0, r0, c7, c14, 0
59 mcr p15, 0, r0, c7, c5, 0
60 mcr p15, 0, r0, c7, c10, 4
61 mcr p15, 0, r0, c7, c5, 4
62
63 @ Branch to destination (should be address 0x00000000)
64 bx r1
65restart_copy_end:
66 .size rolo_restart,.-rolo_restart