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 (CONFIG_CPU != TCC730) && !defined(IRIVER_IFP7XX_SERIES) && \
34 (CONFIG_CPU != PP5002) && !defined(IRIVER_H10) && \
35 !defined(IRIVER_H10_5GB) && (CONFIG_CPU != S3C2440)
36 /* FIX: this doesn't work on Gmini, iFP, 3rd Gen ipods, or H10 yet */
38 #define IRQ0_EDGE_TRIGGER 0x80
40 static void rolo_error(const char *text
)
43 lcd_puts(0, 0, "ROLO error:");
44 lcd_puts_scroll(0, 1, text
);
52 #if CONFIG_CPU == SH7034
53 /* these are in assembler file "descramble.S" */
54 extern unsigned short descramble(const unsigned char* source
,
55 unsigned char* dest
, int length
);
56 extern void rolo_restart(const unsigned char* source
, unsigned char* dest
,
59 void rolo_restart(const unsigned char* source
, unsigned char* dest
,
60 long length
) __attribute__ ((section (".icode")));
61 void rolo_restart(const unsigned char* source
, unsigned char* dest
,
65 unsigned char* localdest
= dest
;
66 #if (CONFIG_CPU==PP5020)
67 unsigned long* memmapregs
= (unsigned long*)0xf000f000;
70 for(i
= 0;i
< length
;i
++)
71 *localdest
++ = *source
++;
73 #if defined(CPU_COLDFIRE)
76 "move.l (%0)+,%%sp \n"
81 #elif (CONFIG_CPU==PP5020)
82 /* Copy a further 8KB of data to try and ensure the cache is flushed */
83 for(i
= length
; i
< length
+8192; i
++)
84 *localdest
++ = *source
++;
87 outl(0x0, 0x6000C000);
89 /* Reset the memory mapping registers to zero */
94 "mov r0, #0x10000000 \n"
101 /* This is assigned in the linker control file */
102 extern unsigned long loadaddress
;
104 /***************************************************************************
106 * Name: rolo_load_app(char *filename,int scrambled)
107 * Filename must be a fully defined filename including the path and extension
109 ***************************************************************************/
110 int rolo_load(const char* filename
)
114 #if defined(CPU_COLDFIRE) || (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020)
116 unsigned long checksum
,file_checksum
;
119 unsigned short checksum
,file_checksum
;
121 unsigned char* ramstart
= (void*)&loadaddress
;
124 lcd_puts(0, 0, "ROLO...");
125 lcd_puts(0, 1, "Loading");
127 #ifdef HAVE_REMOTE_LCD
128 lcd_remote_clear_display();
129 lcd_remote_puts(0, 0, "ROLO...");
130 lcd_remote_puts(0, 1, "Loading");
136 fd
= open(filename
, O_RDONLY
);
138 rolo_error("File not found");
142 length
= filesize(fd
) - FIRMWARE_OFFSET_FILE_DATA
;
144 #if defined(CPU_COLDFIRE) || (CONFIG_CPU == PP5002) || (CONFIG_CPU == PP5020)
145 /* Read and save checksum */
146 lseek(fd
, FIRMWARE_OFFSET_FILE_CRC
, SEEK_SET
);
147 if (read(fd
, &file_checksum
, 4) != 4) {
148 rolo_error("Error Reading checksum");
152 /* Rockbox checksums are big-endian */
153 file_checksum
= betoh32(file_checksum
);
155 lseek(fd
, FIRMWARE_OFFSET_FILE_DATA
, SEEK_SET
);
157 if (read(fd
, audiobuf
, length
) != length
) {
158 rolo_error("Error Reading File");
162 checksum
= MODEL_NUMBER
;
164 for(i
= 0;i
< length
;i
++) {
165 checksum
+= audiobuf
[i
];
168 /* Verify checksum against file header */
169 if (checksum
!= file_checksum
) {
170 rolo_error("Checksum Error");
174 lcd_puts(0, 1, "Executing");
176 #ifdef HAVE_REMOTE_LCD
177 lcd_remote_puts(0, 1, "Executing");
181 set_irq_level(HIGHEST_IRQ_LEVEL
);
182 #elif CONFIG_CPU == SH7034
183 /* Read file length from header and compare to real file length */
184 lseek(fd
, FIRMWARE_OFFSET_FILE_LENGTH
, SEEK_SET
);
185 if(read(fd
, &file_length
, 4) != 4) {
186 rolo_error("Error Reading File Length");
189 if (length
!= file_length
) {
190 rolo_error("File length mismatch");
194 /* Read and save checksum */
195 lseek(fd
, FIRMWARE_OFFSET_FILE_CRC
, SEEK_SET
);
196 if (read(fd
, &file_checksum
, 2) != 2) {
197 rolo_error("Error Reading checksum");
200 lseek(fd
, FIRMWARE_OFFSET_FILE_DATA
, SEEK_SET
);
202 /* verify that file can be read and descrambled */
203 if ((audiobuf
+ (2*length
)+4) >= audiobufend
) {
204 rolo_error("Not enough room to load file");
208 if (read(fd
, &audiobuf
[length
], length
) != (int)length
) {
209 rolo_error("Error Reading File");
213 lcd_puts(0, 1, "Descramble");
216 checksum
= descramble(audiobuf
+ length
, audiobuf
, length
);
218 /* Verify checksum against file header */
219 if (checksum
!= file_checksum
) {
220 rolo_error("Checksum Error");
224 lcd_puts(0, 1, "Executing ");
227 set_irq_level(HIGHEST_IRQ_LEVEL
);
229 /* Calling these 2 initialization routines was necessary to get the
230 the origional Archos version of the firmware to load and execute. */
231 system_init(); /* Initialize system for restart */
232 i2c_init(); /* Init i2c bus - it seems like a good idea */
233 ICR
= IRQ0_EDGE_TRIGGER
; /* Make IRQ0 edge triggered */
234 TSTR
= 0xE0; /* disable all timers */
235 /* model-specific de-init, needed when flashed */
236 /* Especially the Archos software is picky about this */
237 #if defined(ARCHOS_RECORDER) || defined(ARCHOS_RECORDERV2) || \
238 defined(ARCHOS_FMRECORDER)
242 rolo_restart(audiobuf
, ramstart
, length
);
244 return 0; /* this is never reached */
246 #else /* (CONFIG_CPU != TCC730) && !defined(IRIVER_IFP7XX_SERIES) */
247 int rolo_load(const char* filename
)
254 #endif /* (CONFIG_CPU != TCC730) && !defined(IRIVER_IFP7XX_SERIES) */