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"
33 #if !defined(IRIVER_IFP7XX_SERIES) && \
34 (CONFIG_CPU != PP5002) && (CONFIG_CPU != S3C2440)
35 /* FIX: this doesn't work on iFP, 3rd Gen ipods */
37 #define IRQ0_EDGE_TRIGGER 0x80
40 /* Handle the COP properly - it needs to jump to a function outside SDRAM while
41 * the new firmware is being loaded, and then jump to the start of SDRAM
42 * TODO: Use the mailboxes built into the PP processor for this
45 volatile unsigned char IDATA_ATTR cpu_message
= 0;
46 volatile unsigned char IDATA_ATTR cpu_reply
= 0;
48 void rolo_restart_cop(void) ICODE_ATTR
;
49 void rolo_restart_cop(void)
51 /* Invalidate cache */
52 outl(inl(0xf000f044) | 0x6, 0xf000f044);
53 while ((CACHE_CTL
& 0x8000) != 0) {}
56 CACHE_CTL
= CACHE_DISABLE
;
58 /* Tell the main core that we're ready to reload */
61 /* Wait while RoLo loads the image into SDRAM */
62 /* TODO: Accept checksum failure gracefully */
63 while(cpu_message
== 1) {}
65 /* Acknowledge the CPU and then reload */
69 "mov r0, #0x10000000 \n"
75 static void rolo_error(const char *text
)
78 lcd_puts(0, 0, "ROLO error:");
79 lcd_puts_scroll(0, 1, text
);
87 #if CONFIG_CPU == SH7034
88 /* these are in assembler file "descramble.S" */
89 extern unsigned short descramble(const unsigned char* source
,
90 unsigned char* dest
, int length
);
91 extern void rolo_restart(const unsigned char* source
, unsigned char* dest
,
94 void rolo_restart(const unsigned char* source
, unsigned char* dest
,
95 long length
) __attribute__ ((section (".icode")));
96 void rolo_restart(const unsigned char* source
, unsigned char* dest
,
100 unsigned char* localdest
= dest
;
101 #if (CONFIG_CPU==PP5020) || (CONFIG_CPU==PP5024)
102 unsigned long* memmapregs
= (unsigned long*)0xf000f000;
105 for(i
= 0;i
< length
;i
++)
106 *localdest
++ = *source
++;
108 #if defined(CPU_COLDFIRE)
110 "movec.l %0,%%vbr \n"
111 "move.l (%0)+,%%sp \n"
116 #elif (CONFIG_CPU==PP5020) || (CONFIG_CPU==PP5024)
118 /* Tell the COP that we've finished loading and started rebooting */
122 outl(inl(0xf000f044) | 0x2, 0xf000f044);
123 while ((CACHE_CTL
& 0x8000) != 0) {}
126 CACHE_CTL
= CACHE_DISABLE
;
128 /* Reset the memory mapping registers to zero */
132 /* Wait for the COP to tell us it is rebooting */
133 while(cpu_reply
!= 1) {}
136 "mov r0, #0x10000000 \n"
143 /* This is assigned in the linker control file */
144 extern unsigned long loadaddress
;
146 /***************************************************************************
148 * Name: rolo_load_app(char *filename,int scrambled)
149 * Filename must be a fully defined filename including the path and extension
151 ***************************************************************************/
152 int rolo_load(const char* filename
)
156 #if defined(CPU_COLDFIRE) || defined(CPU_PP)
158 unsigned long checksum
,file_checksum
;
161 unsigned short checksum
,file_checksum
;
163 unsigned char* ramstart
= (void*)&loadaddress
;
166 lcd_puts(0, 0, "ROLO...");
167 lcd_puts(0, 1, "Loading");
169 #ifdef HAVE_REMOTE_LCD
170 lcd_remote_clear_display();
171 lcd_remote_puts(0, 0, "ROLO...");
172 lcd_remote_puts(0, 1, "Loading");
178 fd
= open(filename
, O_RDONLY
);
180 rolo_error("File not found");
184 length
= filesize(fd
) - FIRMWARE_OFFSET_FILE_DATA
;
186 #if defined(CPU_COLDFIRE) || defined(CPU_PP)
187 /* Read and save checksum */
188 lseek(fd
, FIRMWARE_OFFSET_FILE_CRC
, SEEK_SET
);
189 if (read(fd
, &file_checksum
, 4) != 4) {
190 rolo_error("Error Reading checksum");
194 /* Rockbox checksums are big-endian */
195 file_checksum
= betoh32(file_checksum
);
197 cpu_message
= COP_REBOOT
;
199 lcd_puts(0, 2, "Waiting for coprocessor...");
201 while(cpu_reply
!= 2) {}
206 lseek(fd
, FIRMWARE_OFFSET_FILE_DATA
, SEEK_SET
);
208 if (read(fd
, audiobuf
, length
) != length
) {
209 rolo_error("Error Reading File");
213 checksum
= MODEL_NUMBER
;
215 for(i
= 0;i
< length
;i
++) {
216 checksum
+= audiobuf
[i
];
219 /* Verify checksum against file header */
220 if (checksum
!= file_checksum
) {
221 rolo_error("Checksum Error");
225 lcd_puts(0, 1, "Executing");
227 #ifdef HAVE_REMOTE_LCD
228 lcd_remote_puts(0, 1, "Executing");
232 set_irq_level(HIGHEST_IRQ_LEVEL
);
233 #elif CONFIG_CPU == SH7034
234 /* Read file length from header and compare to real file length */
235 lseek(fd
, FIRMWARE_OFFSET_FILE_LENGTH
, SEEK_SET
);
236 if(read(fd
, &file_length
, 4) != 4) {
237 rolo_error("Error Reading File Length");
240 if (length
!= file_length
) {
241 rolo_error("File length mismatch");
245 /* Read and save checksum */
246 lseek(fd
, FIRMWARE_OFFSET_FILE_CRC
, SEEK_SET
);
247 if (read(fd
, &file_checksum
, 2) != 2) {
248 rolo_error("Error Reading checksum");
251 lseek(fd
, FIRMWARE_OFFSET_FILE_DATA
, SEEK_SET
);
253 /* verify that file can be read and descrambled */
254 if ((audiobuf
+ (2*length
)+4) >= audiobufend
) {
255 rolo_error("Not enough room to load file");
259 if (read(fd
, &audiobuf
[length
], length
) != (int)length
) {
260 rolo_error("Error Reading File");
264 lcd_puts(0, 1, "Descramble");
267 checksum
= descramble(audiobuf
+ length
, audiobuf
, length
);
269 /* Verify checksum against file header */
270 if (checksum
!= file_checksum
) {
271 rolo_error("Checksum Error");
275 lcd_puts(0, 1, "Executing ");
278 set_irq_level(HIGHEST_IRQ_LEVEL
);
280 /* Calling these 2 initialization routines was necessary to get the
281 the origional Archos version of the firmware to load and execute. */
282 system_init(); /* Initialize system for restart */
283 i2c_init(); /* Init i2c bus - it seems like a good idea */
284 ICR
= IRQ0_EDGE_TRIGGER
; /* Make IRQ0 edge triggered */
285 TSTR
= 0xE0; /* disable all timers */
286 /* model-specific de-init, needed when flashed */
287 /* Especially the Archos software is picky about this */
288 #if defined(ARCHOS_RECORDER) || defined(ARCHOS_RECORDERV2) || \
289 defined(ARCHOS_FMRECORDER)
293 rolo_restart(audiobuf
, ramstart
, length
);
295 return 0; /* this is never reached */
297 #else /* !defined(IRIVER_IFP7XX_SERIES) */
298 int rolo_load(const char* filename
)
305 #endif /* !defined(IRIVER_IFP7XX_SERIES) */