1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 Randy D. Wood
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
22 #include "lcd-remote.h"
37 #include "crc32-mi4.h"
38 #undef FIRMWARE_OFFSET_FILE_CRC
39 #undef FIRMWARE_OFFSET_FILE_DATA
40 #define FIRMWARE_OFFSET_FILE_CRC 0xC
41 #define FIRMWARE_OFFSET_FILE_DATA 0x200
44 #if !defined(IRIVER_IFP7XX_SERIES) && \
45 (CONFIG_CPU != PP5002)
46 /* FIX: this doesn't work on iFP, 3rd Gen ipods */
48 #define IRQ0_EDGE_TRIGGER 0x80
51 /* Handle the COP properly - it needs to jump to a function outside SDRAM while
52 * the new firmware is being loaded, and then jump to the start of SDRAM
53 * TODO: Use the mailboxes built into the PP processor for this
57 volatile unsigned char IDATA_ATTR cpu_message
= 0;
58 volatile unsigned char IDATA_ATTR cpu_reply
= 0;
59 extern int cop_idlestackbegin
[];
61 void rolo_restart_cop(void) ICODE_ATTR
;
62 void rolo_restart_cop(void)
64 if (CURRENT_CORE
== CPU
)
66 /* There should be free thread slots aplenty */
67 create_thread(rolo_restart_cop
, cop_idlestackbegin
, IDLE_STACK_SIZE
,
68 0, "rolo COP" IF_PRIO(, PRIORITY_REALTIME
)
75 /* Invalidate cache */
79 CACHE_CTL
= CACHE_CTL_DISABLE
;
81 /* Tell the main core that we're ready to reload */
84 /* Wait while RoLo loads the image into SDRAM */
85 /* TODO: Accept checksum failure gracefully */
86 while(cpu_message
!= 1);
88 /* Acknowledge the CPU and then reload */
92 "mov r0, #0x10000000 \n"
96 #endif /* NUM_CORES > 1 */
99 static void rolo_error(const char *text
)
102 lcd_puts(0, 0, "ROLO error:");
103 lcd_puts_scroll(0, 1, text
);
111 #if CONFIG_CPU == SH7034
112 /* these are in assembler file "descramble.S" */
113 extern unsigned short descramble(const unsigned char* source
,
114 unsigned char* dest
, int length
);
115 extern void rolo_restart(const unsigned char* source
, unsigned char* dest
,
119 /* explicitly put this code in iram, ICODE_ATTR is defined to be null for some
120 targets that are low on iram, like the gigabeat F/X */
121 void rolo_restart(const unsigned char* source
, unsigned char* dest
,
122 long length
) __attribute__ ((section(".icode")));
123 void rolo_restart(const unsigned char* source
, unsigned char* dest
,
127 unsigned char* localdest
= dest
;
129 /* This is the equivalent of a call to memcpy() but this must be done from
130 iram to avoid overwriting itself and we don't want to depend on memcpy()
131 always being in iram */
132 for(i
= 0;i
< length
;i
++)
133 *localdest
++ = *source
++;
135 #if defined(CPU_COLDFIRE)
137 "movec.l %0,%%vbr \n"
138 "move.l (%0)+,%%sp \n"
143 #elif defined(CPU_PP502x)
150 CACHE_CTL
= CACHE_CTL_DISABLE
;
152 /* Reset the memory mapping registers to zero */
154 volatile unsigned long *mmap_reg
;
155 for (mmap_reg
= &MMAP_FIRST
; mmap_reg
<= &MMAP_LAST
; mmap_reg
++)
160 /* Tell the COP it's safe to continue rebooting */
163 /* Wait for the COP to tell us it is rebooting */
164 while(cpu_reply
!= 2);
168 "mov r0, #0x10000000 \n"
172 #elif defined(CPU_TCC780X) || (CONFIG_CPU==IMX31L) || (CONFIG_CPU == S3C2440)
173 /* Flush and invalidate caches */
184 /* This is assigned in the linker control file */
185 extern unsigned long loadaddress
;
187 /***************************************************************************
189 * Name: rolo_load_app(char *filename,int scrambled)
190 * Filename must be a fully defined filename including the path and extension
192 ***************************************************************************/
193 int rolo_load(const char* filename
)
197 #if defined(CPU_COLDFIRE) || defined(CPU_ARM)
198 #if !defined(MI4_FORMAT)
201 unsigned long checksum
,file_checksum
;
204 unsigned short checksum
,file_checksum
;
206 unsigned char* ramstart
= (void*)&loadaddress
;
209 lcd_puts(0, 0, "ROLO...");
210 lcd_puts(0, 1, "Loading");
212 #ifdef HAVE_REMOTE_LCD
213 lcd_remote_clear_display();
214 lcd_remote_puts(0, 0, "ROLO...");
215 lcd_remote_puts(0, 1, "Loading");
221 fd
= open(filename
, O_RDONLY
);
223 rolo_error("File not found");
227 length
= filesize(fd
) - FIRMWARE_OFFSET_FILE_DATA
;
229 #if defined(CPU_COLDFIRE) || defined(CPU_PP) || (CONFIG_CPU==DM320) \
230 || defined(CPU_TCC780X) || (CONFIG_CPU==IMX31L) || (CONFIG_CPU == S3C2440)
231 /* Read and save checksum */
232 lseek(fd
, FIRMWARE_OFFSET_FILE_CRC
, SEEK_SET
);
233 if (read(fd
, &file_checksum
, 4) != 4) {
234 rolo_error("Error Reading checksum");
238 #if !defined(MI4_FORMAT)
239 /* Rockbox checksums are big-endian */
240 file_checksum
= betoh32(file_checksum
);
243 #if defined(CPU_PP) && NUM_CORES > 1
244 lcd_puts(0, 2, "Waiting for coprocessor...");
247 /* Wait for COP to be in safe code */
248 while(cpu_reply
!= 1);
253 lseek(fd
, FIRMWARE_OFFSET_FILE_DATA
, SEEK_SET
);
255 if (read(fd
, audiobuf
, length
) != length
) {
256 rolo_error("Error Reading File");
261 /* Check CRC32 to see if we have a valid file */
262 chksum_crc32gentab();
263 checksum
= chksum_crc32 (audiobuf
, length
);
265 checksum
= MODEL_NUMBER
;
267 for(i
= 0;i
< length
;i
++) {
268 checksum
+= audiobuf
[i
];
272 /* Verify checksum against file header */
273 if (checksum
!= file_checksum
) {
274 rolo_error("Checksum Error");
278 lcd_puts(0, 1, "Executing");
280 #ifdef HAVE_REMOTE_LCD
281 lcd_remote_puts(0, 1, "Executing");
289 set_irq_level(DISABLE_INTERRUPTS
);
291 #elif CONFIG_CPU == SH7034
292 /* Read file length from header and compare to real file length */
293 lseek(fd
, FIRMWARE_OFFSET_FILE_LENGTH
, SEEK_SET
);
294 if(read(fd
, &file_length
, 4) != 4) {
295 rolo_error("Error Reading File Length");
298 if (length
!= file_length
) {
299 rolo_error("File length mismatch");
303 /* Read and save checksum */
304 lseek(fd
, FIRMWARE_OFFSET_FILE_CRC
, SEEK_SET
);
305 if (read(fd
, &file_checksum
, 2) != 2) {
306 rolo_error("Error Reading checksum");
309 lseek(fd
, FIRMWARE_OFFSET_FILE_DATA
, SEEK_SET
);
311 /* verify that file can be read and descrambled */
312 if ((audiobuf
+ (2*length
)+4) >= audiobufend
) {
313 rolo_error("Not enough room to load file");
317 if (read(fd
, &audiobuf
[length
], length
) != (int)length
) {
318 rolo_error("Error Reading File");
322 lcd_puts(0, 1, "Descramble");
325 checksum
= descramble(audiobuf
+ length
, audiobuf
, length
);
327 /* Verify checksum against file header */
328 if (checksum
!= file_checksum
) {
329 rolo_error("Checksum Error");
333 lcd_puts(0, 1, "Executing ");
336 set_irq_level(HIGHEST_IRQ_LEVEL
);
338 /* Calling these 2 initialization routines was necessary to get the
339 the origional Archos version of the firmware to load and execute. */
340 system_init(); /* Initialize system for restart */
341 i2c_init(); /* Init i2c bus - it seems like a good idea */
342 ICR
= IRQ0_EDGE_TRIGGER
; /* Make IRQ0 edge triggered */
343 TSTR
= 0xE0; /* disable all timers */
344 /* model-specific de-init, needed when flashed */
345 /* Especially the Archos software is picky about this */
346 #if defined(ARCHOS_RECORDER) || defined(ARCHOS_RECORDERV2) || \
347 defined(ARCHOS_FMRECORDER)
351 rolo_restart(audiobuf
, ramstart
, length
);
353 return 0; /* this is never reached */
354 (void)checksum
; (void)file_checksum
;
356 #else /* !defined(IRIVER_IFP7XX_SERIES) */
357 int rolo_load(const char* filename
)
364 #endif /* !defined(IRIVER_IFP7XX_SERIES) */