Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 1 | /*************************************************************************** |
| 2 | * __________ __ ___. |
| 3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
| 4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / |
| 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
| 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
| 7 | * \/ \/ \/ \/ \/ |
| 8 | * $Id$ |
| 9 | * |
| 10 | * Copyright (C) 2002 Randy D. Wood |
| 11 | * |
Daniel Stenberg | 2acc0ac | 2008-06-28 18:10:04 +0000 | [diff] [blame^] | 12 | * This program is free software; you can redistribute it and/or |
| 13 | * modify it under the terms of the GNU General Public License |
| 14 | * as published by the Free Software Foundation; either version 2 |
| 15 | * of the License, or (at your option) any later version. |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 16 | * |
| 17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
| 18 | * KIND, either express or implied. |
| 19 | * |
| 20 | ****************************************************************************/ |
| 21 | |
Daniel Stenberg | 36355a5 | 2005-02-02 21:47:08 +0000 | [diff] [blame] | 22 | #include "config.h" |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 23 | #include "lcd.h" |
Jens Arnold | 1aae0a0 | 2006-04-24 06:45:27 +0000 | [diff] [blame] | 24 | #include "lcd-remote.h" |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 25 | #include "thread.h" |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 26 | #include "kernel.h" |
| 27 | #include "sprintf.h" |
| 28 | #include "button.h" |
| 29 | #include "file.h" |
Linus Nielsen Feltzing | 8a237a8 | 2005-04-04 12:06:29 +0000 | [diff] [blame] | 30 | #include "audio.h" |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 31 | #include "system.h" |
| 32 | #include "i2c.h" |
Dave Chapman | 78d29f5 | 2008-03-26 23:35:34 +0000 | [diff] [blame] | 33 | #include "adc.h" |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 34 | #include "string.h" |
Linus Nielsen Feltzing | 20d031f | 2003-05-09 16:01:21 +0000 | [diff] [blame] | 35 | #include "buffer.h" |
Bertrik Sikken | 2124a9f | 2008-05-03 07:17:44 +0000 | [diff] [blame] | 36 | #include "rolo.h" |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 37 | |
Barry Wardell | 54c73a2 | 2007-06-04 13:48:21 +0000 | [diff] [blame] | 38 | #ifdef MI4_FORMAT |
| 39 | #include "crc32-mi4.h" |
| 40 | #undef FIRMWARE_OFFSET_FILE_CRC |
| 41 | #undef FIRMWARE_OFFSET_FILE_DATA |
| 42 | #define FIRMWARE_OFFSET_FILE_CRC 0xC |
| 43 | #define FIRMWARE_OFFSET_FILE_DATA 0x200 |
| 44 | #endif |
| 45 | |
Jens Arnold | 780f79e | 2006-11-10 20:26:01 +0000 | [diff] [blame] | 46 | #if !defined(IRIVER_IFP7XX_SERIES) && \ |
Karl Kurbjun | 6c6a2ed | 2008-05-02 03:27:17 +0000 | [diff] [blame] | 47 | (CONFIG_CPU != PP5002) |
Barry Wardell | 2f16d4f | 2006-12-19 11:33:53 +0000 | [diff] [blame] | 48 | /* FIX: this doesn't work on iFP, 3rd Gen ipods */ |
Daniel Stenberg | 36355a5 | 2005-02-02 21:47:08 +0000 | [diff] [blame] | 49 | |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 50 | #define IRQ0_EDGE_TRIGGER 0x80 |
| 51 | |
Daniel Ankers | b856636 | 2007-02-27 22:55:12 +0000 | [diff] [blame] | 52 | #ifdef CPU_PP |
| 53 | /* Handle the COP properly - it needs to jump to a function outside SDRAM while |
| 54 | * the new firmware is being loaded, and then jump to the start of SDRAM |
| 55 | * TODO: Use the mailboxes built into the PP processor for this |
| 56 | */ |
| 57 | |
Michael Sevakis | 3e7d4f0 | 2007-09-29 06:56:21 +0000 | [diff] [blame] | 58 | #if NUM_CORES > 1 |
Daniel Ankers | b856636 | 2007-02-27 22:55:12 +0000 | [diff] [blame] | 59 | volatile unsigned char IDATA_ATTR cpu_message = 0; |
| 60 | volatile unsigned char IDATA_ATTR cpu_reply = 0; |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 61 | extern int cop_idlestackbegin[]; |
Daniel Ankers | b856636 | 2007-02-27 22:55:12 +0000 | [diff] [blame] | 62 | |
| 63 | void rolo_restart_cop(void) ICODE_ATTR; |
| 64 | void rolo_restart_cop(void) |
| 65 | { |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 66 | if (CURRENT_CORE == CPU) |
| 67 | { |
| 68 | /* There should be free thread slots aplenty */ |
| 69 | create_thread(rolo_restart_cop, cop_idlestackbegin, IDLE_STACK_SIZE, |
Michael Sevakis | a9b2fb5 | 2007-10-16 01:25:17 +0000 | [diff] [blame] | 70 | 0, "rolo COP" IF_PRIO(, PRIORITY_REALTIME) |
| 71 | IF_COP(, COP)); |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 72 | return; |
| 73 | } |
| 74 | |
Michael Sevakis | fa5bd07 | 2008-06-03 05:19:32 +0000 | [diff] [blame] | 75 | COP_INT_DIS = -1; |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 76 | |
Daniel Ankers | b856636 | 2007-02-27 22:55:12 +0000 | [diff] [blame] | 77 | /* Invalidate cache */ |
Michael Sevakis | d95c390 | 2007-04-13 20:55:48 +0000 | [diff] [blame] | 78 | invalidate_icache(); |
Daniel Ankers | b856636 | 2007-02-27 22:55:12 +0000 | [diff] [blame] | 79 | |
| 80 | /* Disable cache */ |
Michael Sevakis | e760ba5 | 2007-09-30 10:53:31 +0000 | [diff] [blame] | 81 | CACHE_CTL = CACHE_CTL_DISABLE; |
Daniel Ankers | b856636 | 2007-02-27 22:55:12 +0000 | [diff] [blame] | 82 | |
Daniel Ankers | ee07215 | 2007-03-04 23:53:38 +0000 | [diff] [blame] | 83 | /* Tell the main core that we're ready to reload */ |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 84 | cpu_reply = 1; |
Daniel Ankers | ee07215 | 2007-03-04 23:53:38 +0000 | [diff] [blame] | 85 | |
Daniel Ankers | b856636 | 2007-02-27 22:55:12 +0000 | [diff] [blame] | 86 | /* Wait while RoLo loads the image into SDRAM */ |
| 87 | /* TODO: Accept checksum failure gracefully */ |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 88 | while(cpu_message != 1); |
Daniel Ankers | b856636 | 2007-02-27 22:55:12 +0000 | [diff] [blame] | 89 | |
Daniel Ankers | ee07215 | 2007-03-04 23:53:38 +0000 | [diff] [blame] | 90 | /* Acknowledge the CPU and then reload */ |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 91 | cpu_reply = 2; |
Daniel Ankers | b856636 | 2007-02-27 22:55:12 +0000 | [diff] [blame] | 92 | |
| 93 | asm volatile( |
| 94 | "mov r0, #0x10000000 \n" |
| 95 | "mov pc, r0 \n" |
| 96 | ); |
| 97 | } |
Michael Sevakis | 3e7d4f0 | 2007-09-29 06:56:21 +0000 | [diff] [blame] | 98 | #endif /* NUM_CORES > 1 */ |
| 99 | #endif /* CPU_PP */ |
Daniel Ankers | b856636 | 2007-02-27 22:55:12 +0000 | [diff] [blame] | 100 | |
Jens Arnold | c76c568 | 2004-08-16 23:37:23 +0000 | [diff] [blame] | 101 | static void rolo_error(const char *text) |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 102 | { |
| 103 | lcd_clear_display(); |
| 104 | lcd_puts(0, 0, "ROLO error:"); |
| 105 | lcd_puts_scroll(0, 1, text); |
| 106 | lcd_update(); |
| 107 | button_get(true); |
Linus Nielsen Feltzing | 20d031f | 2003-05-09 16:01:21 +0000 | [diff] [blame] | 108 | button_get(true); |
| 109 | button_get(true); |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 110 | lcd_stop_scroll(); |
| 111 | } |
Jörg Hohensohn | cbbbcd1 | 2003-10-12 16:40:45 +0000 | [diff] [blame] | 112 | |
Michael Sevakis | 6dd6ea7 | 2008-05-08 12:09:14 +0000 | [diff] [blame] | 113 | #if CONFIG_CPU == SH7034 || CONFIG_CPU == IMX31L |
| 114 | /* these are in assembler file "descramble.S" for SH7034 */ |
Jens Arnold | c76c568 | 2004-08-16 23:37:23 +0000 | [diff] [blame] | 115 | extern unsigned short descramble(const unsigned char* source, |
| 116 | unsigned char* dest, int length); |
Michael Sevakis | 6dd6ea7 | 2008-05-08 12:09:14 +0000 | [diff] [blame] | 117 | /* this is in firmware/target/arm/imx31/rolo_restart.S for IMX31 */ |
Jens Arnold | c76c568 | 2004-08-16 23:37:23 +0000 | [diff] [blame] | 118 | extern void rolo_restart(const unsigned char* source, unsigned char* dest, |
| 119 | int length); |
Linus Nielsen Feltzing | bd42d31 | 2005-03-31 08:47:02 +0000 | [diff] [blame] | 120 | #else |
Nils Wallménius | 4102ed5 | 2007-07-17 14:53:44 +0000 | [diff] [blame] | 121 | |
| 122 | /* explicitly put this code in iram, ICODE_ATTR is defined to be null for some |
| 123 | targets that are low on iram, like the gigabeat F/X */ |
| 124 | void rolo_restart(const unsigned char* source, unsigned char* dest, |
| 125 | long length) __attribute__ ((section(".icode"))); |
| 126 | void rolo_restart(const unsigned char* source, unsigned char* dest, |
| 127 | long length) |
Linus Nielsen Feltzing | bd42d31 | 2005-03-31 08:47:02 +0000 | [diff] [blame] | 128 | { |
| 129 | long i; |
Jens Arnold | b7aaa64 | 2005-06-22 16:53:12 +0000 | [diff] [blame] | 130 | unsigned char* localdest = dest; |
Linus Nielsen Feltzing | bd42d31 | 2005-03-31 08:47:02 +0000 | [diff] [blame] | 131 | |
Nils Wallménius | 76fa0f7e | 2007-07-16 19:26:07 +0000 | [diff] [blame] | 132 | /* This is the equivalent of a call to memcpy() but this must be done from |
| 133 | iram to avoid overwriting itself and we don't want to depend on memcpy() |
| 134 | always being in iram */ |
Linus Nielsen Feltzing | bd42d31 | 2005-03-31 08:47:02 +0000 | [diff] [blame] | 135 | for(i = 0;i < length;i++) |
Jens Arnold | b7aaa64 | 2005-06-22 16:53:12 +0000 | [diff] [blame] | 136 | *localdest++ = *source++; |
Linus Nielsen Feltzing | bd42d31 | 2005-03-31 08:47:02 +0000 | [diff] [blame] | 137 | |
Linus Nielsen Feltzing | 15db7f2 | 2006-07-13 21:11:20 +0000 | [diff] [blame] | 138 | #if defined(CPU_COLDFIRE) |
Jens Arnold | b7aaa64 | 2005-06-22 16:53:12 +0000 | [diff] [blame] | 139 | asm ( |
| 140 | "movec.l %0,%%vbr \n" |
| 141 | "move.l (%0)+,%%sp \n" |
| 142 | "move.l (%0),%0 \n" |
| 143 | "jmp (%0) \n" |
| 144 | : : "a"(dest) |
| 145 | ); |
Jens Arnold | fe23dc8 | 2007-07-02 05:16:40 +0000 | [diff] [blame] | 146 | #elif defined(CPU_PP502x) |
Michael Sevakis | 191320c | 2008-06-03 05:08:24 +0000 | [diff] [blame] | 147 | CPU_INT_DIS = -1; |
Daniel Ankers | b856636 | 2007-02-27 22:55:12 +0000 | [diff] [blame] | 148 | |
Daniel Ankers | cb51abb | 2006-12-10 15:20:26 +0000 | [diff] [blame] | 149 | /* Flush cache */ |
Michael Sevakis | d95c390 | 2007-04-13 20:55:48 +0000 | [diff] [blame] | 150 | flush_icache(); |
Daniel Ankers | cb51abb | 2006-12-10 15:20:26 +0000 | [diff] [blame] | 151 | |
Dave Chapman | ffc0cab | 2006-07-23 14:30:10 +0000 | [diff] [blame] | 152 | /* Disable cache */ |
Michael Sevakis | e760ba5 | 2007-09-30 10:53:31 +0000 | [diff] [blame] | 153 | CACHE_CTL = CACHE_CTL_DISABLE; |
Dave Chapman | ffc0cab | 2006-07-23 14:30:10 +0000 | [diff] [blame] | 154 | |
| 155 | /* Reset the memory mapping registers to zero */ |
Michael Sevakis | e760ba5 | 2007-09-30 10:53:31 +0000 | [diff] [blame] | 156 | { |
| 157 | volatile unsigned long *mmap_reg; |
| 158 | for (mmap_reg = &MMAP_FIRST; mmap_reg <= &MMAP_LAST; mmap_reg++) |
| 159 | *mmap_reg = 0; |
| 160 | } |
Dave Chapman | ffc0cab | 2006-07-23 14:30:10 +0000 | [diff] [blame] | 161 | |
Michael Sevakis | 3e7d4f0 | 2007-09-29 06:56:21 +0000 | [diff] [blame] | 162 | #if NUM_CORES > 1 |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 163 | /* Tell the COP it's safe to continue rebooting */ |
| 164 | cpu_message = 1; |
| 165 | |
Daniel Ankers | ee07215 | 2007-03-04 23:53:38 +0000 | [diff] [blame] | 166 | /* Wait for the COP to tell us it is rebooting */ |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 167 | while(cpu_reply != 2); |
Michael Sevakis | 3e7d4f0 | 2007-09-29 06:56:21 +0000 | [diff] [blame] | 168 | #endif |
Karl Kurbjun | d3d0b26 | 2007-11-15 06:44:35 +0000 | [diff] [blame] | 169 | |
Dave Chapman | ffc0cab | 2006-07-23 14:30:10 +0000 | [diff] [blame] | 170 | asm volatile( |
| 171 | "mov r0, #0x10000000 \n" |
| 172 | "mov pc, r0 \n" |
| 173 | ); |
Rob Purchase | d88c566 | 2008-04-15 20:02:24 +0000 | [diff] [blame] | 174 | |
Michael Sevakis | 6dd6ea7 | 2008-05-08 12:09:14 +0000 | [diff] [blame] | 175 | #elif defined(CPU_TCC780X) || (CONFIG_CPU == S3C2440) |
Michael Sevakis | 7fee486 | 2008-04-16 23:49:21 +0000 | [diff] [blame] | 176 | /* Flush and invalidate caches */ |
| 177 | invalidate_icache(); |
Rob Purchase | d88c566 | 2008-04-15 20:02:24 +0000 | [diff] [blame] | 178 | |
| 179 | asm volatile( |
| 180 | "mov pc, %0 \n" |
| 181 | : : "r"(dest) |
| 182 | ); |
Dave Chapman | d31a32c | 2005-11-11 17:51:35 +0000 | [diff] [blame] | 183 | #endif |
Linus Nielsen Feltzing | bd42d31 | 2005-03-31 08:47:02 +0000 | [diff] [blame] | 184 | } |
| 185 | #endif |
| 186 | |
| 187 | /* This is assigned in the linker control file */ |
| 188 | extern unsigned long loadaddress; |
Jörg Hohensohn | cbbbcd1 | 2003-10-12 16:40:45 +0000 | [diff] [blame] | 189 | |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 190 | /*************************************************************************** |
| 191 | * |
| 192 | * Name: rolo_load_app(char *filename,int scrambled) |
| 193 | * Filename must be a fully defined filename including the path and extension |
| 194 | * |
| 195 | ***************************************************************************/ |
Jens Arnold | c76c568 | 2004-08-16 23:37:23 +0000 | [diff] [blame] | 196 | int rolo_load(const char* filename) |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 197 | { |
Jörg Hohensohn | cbbbcd1 | 2003-10-12 16:40:45 +0000 | [diff] [blame] | 198 | int fd; |
Linus Nielsen Feltzing | bd42d31 | 2005-03-31 08:47:02 +0000 | [diff] [blame] | 199 | long length; |
Karl Kurbjun | b7a4e10 | 2007-10-13 14:53:34 +0000 | [diff] [blame] | 200 | #if defined(CPU_COLDFIRE) || defined(CPU_ARM) |
Barry Wardell | 54c73a2 | 2007-06-04 13:48:21 +0000 | [diff] [blame] | 201 | #if !defined(MI4_FORMAT) |
Linus Nielsen Feltzing | bd42d31 | 2005-03-31 08:47:02 +0000 | [diff] [blame] | 202 | int i; |
Barry Wardell | 54c73a2 | 2007-06-04 13:48:21 +0000 | [diff] [blame] | 203 | #endif |
Linus Nielsen Feltzing | bd42d31 | 2005-03-31 08:47:02 +0000 | [diff] [blame] | 204 | unsigned long checksum,file_checksum; |
| 205 | #else |
| 206 | long file_length; |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 207 | unsigned short checksum,file_checksum; |
Linus Nielsen Feltzing | bd42d31 | 2005-03-31 08:47:02 +0000 | [diff] [blame] | 208 | #endif |
| 209 | unsigned char* ramstart = (void*)&loadaddress; |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 210 | |
| 211 | lcd_clear_display(); |
| 212 | lcd_puts(0, 0, "ROLO..."); |
| 213 | lcd_puts(0, 1, "Loading"); |
| 214 | lcd_update(); |
Jens Arnold | 1aae0a0 | 2006-04-24 06:45:27 +0000 | [diff] [blame] | 215 | #ifdef HAVE_REMOTE_LCD |
| 216 | lcd_remote_clear_display(); |
| 217 | lcd_remote_puts(0, 0, "ROLO..."); |
| 218 | lcd_remote_puts(0, 1, "Loading"); |
| 219 | lcd_remote_update(); |
| 220 | #endif |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 221 | |
Linus Nielsen Feltzing | 8a237a8 | 2005-04-04 12:06:29 +0000 | [diff] [blame] | 222 | audio_stop(); |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 223 | |
| 224 | fd = open(filename, O_RDONLY); |
| 225 | if(-1 == fd) { |
| 226 | rolo_error("File not found"); |
| 227 | return -1; |
| 228 | } |
| 229 | |
Linus Nielsen Feltzing | bd42d31 | 2005-03-31 08:47:02 +0000 | [diff] [blame] | 230 | length = filesize(fd) - FIRMWARE_OFFSET_FILE_DATA; |
| 231 | |
Rob Purchase | d88c566 | 2008-04-15 20:02:24 +0000 | [diff] [blame] | 232 | #if defined(CPU_COLDFIRE) || defined(CPU_PP) || (CONFIG_CPU==DM320) \ |
Karl Kurbjun | 6c6a2ed | 2008-05-02 03:27:17 +0000 | [diff] [blame] | 233 | || defined(CPU_TCC780X) || (CONFIG_CPU==IMX31L) || (CONFIG_CPU == S3C2440) |
Linus Nielsen Feltzing | bd42d31 | 2005-03-31 08:47:02 +0000 | [diff] [blame] | 234 | /* Read and save checksum */ |
| 235 | lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET); |
| 236 | if (read(fd, &file_checksum, 4) != 4) { |
| 237 | rolo_error("Error Reading checksum"); |
| 238 | return -1; |
| 239 | } |
Dave Chapman | ffc0cab | 2006-07-23 14:30:10 +0000 | [diff] [blame] | 240 | |
Barry Wardell | 54c73a2 | 2007-06-04 13:48:21 +0000 | [diff] [blame] | 241 | #if !defined(MI4_FORMAT) |
Dave Chapman | ffc0cab | 2006-07-23 14:30:10 +0000 | [diff] [blame] | 242 | /* Rockbox checksums are big-endian */ |
| 243 | file_checksum = betoh32(file_checksum); |
Barry Wardell | 54c73a2 | 2007-06-04 13:48:21 +0000 | [diff] [blame] | 244 | #endif |
| 245 | |
Michael Sevakis | 3e7d4f0 | 2007-09-29 06:56:21 +0000 | [diff] [blame] | 246 | #if defined(CPU_PP) && NUM_CORES > 1 |
Daniel Ankers | ee07215 | 2007-03-04 23:53:38 +0000 | [diff] [blame] | 247 | lcd_puts(0, 2, "Waiting for coprocessor..."); |
| 248 | lcd_update(); |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 249 | rolo_restart_cop(); |
| 250 | /* Wait for COP to be in safe code */ |
| 251 | while(cpu_reply != 1); |
Daniel Ankers | ee07215 | 2007-03-04 23:53:38 +0000 | [diff] [blame] | 252 | lcd_puts(0, 2, " "); |
| 253 | lcd_update(); |
Daniel Ankers | b856636 | 2007-02-27 22:55:12 +0000 | [diff] [blame] | 254 | #endif |
Dave Chapman | ffc0cab | 2006-07-23 14:30:10 +0000 | [diff] [blame] | 255 | |
Linus Nielsen Feltzing | bd42d31 | 2005-03-31 08:47:02 +0000 | [diff] [blame] | 256 | lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET); |
| 257 | |
Linus Nielsen Feltzing | d34865a | 2005-04-05 11:33:58 +0000 | [diff] [blame] | 258 | if (read(fd, audiobuf, length) != length) { |
Linus Nielsen Feltzing | bd42d31 | 2005-03-31 08:47:02 +0000 | [diff] [blame] | 259 | rolo_error("Error Reading File"); |
| 260 | return -1; |
| 261 | } |
| 262 | |
Barry Wardell | 54c73a2 | 2007-06-04 13:48:21 +0000 | [diff] [blame] | 263 | #ifdef MI4_FORMAT |
| 264 | /* Check CRC32 to see if we have a valid file */ |
| 265 | chksum_crc32gentab(); |
| 266 | checksum = chksum_crc32 (audiobuf, length); |
| 267 | #else |
Linus Nielsen Feltzing | aa10422 | 2005-07-18 15:50:06 +0000 | [diff] [blame] | 268 | checksum = MODEL_NUMBER; |
Karl Kurbjun | b7a4e10 | 2007-10-13 14:53:34 +0000 | [diff] [blame] | 269 | |
Linus Nielsen Feltzing | bd42d31 | 2005-03-31 08:47:02 +0000 | [diff] [blame] | 270 | for(i = 0;i < length;i++) { |
Linus Nielsen Feltzing | d34865a | 2005-04-05 11:33:58 +0000 | [diff] [blame] | 271 | checksum += audiobuf[i]; |
Linus Nielsen Feltzing | bd42d31 | 2005-03-31 08:47:02 +0000 | [diff] [blame] | 272 | } |
Barry Wardell | 54c73a2 | 2007-06-04 13:48:21 +0000 | [diff] [blame] | 273 | #endif |
Linus Nielsen Feltzing | bd42d31 | 2005-03-31 08:47:02 +0000 | [diff] [blame] | 274 | |
| 275 | /* Verify checksum against file header */ |
| 276 | if (checksum != file_checksum) { |
| 277 | rolo_error("Checksum Error"); |
| 278 | return -1; |
| 279 | } |
| 280 | |
Jens Arnold | 1aae0a0 | 2006-04-24 06:45:27 +0000 | [diff] [blame] | 281 | lcd_puts(0, 1, "Executing"); |
Linus Nielsen Feltzing | bd42d31 | 2005-03-31 08:47:02 +0000 | [diff] [blame] | 282 | lcd_update(); |
Jens Arnold | 1aae0a0 | 2006-04-24 06:45:27 +0000 | [diff] [blame] | 283 | #ifdef HAVE_REMOTE_LCD |
| 284 | lcd_remote_puts(0, 1, "Executing"); |
| 285 | lcd_remote_update(); |
| 286 | #endif |
Jens Arnold | ed3ff1b | 2008-03-17 23:47:38 +0000 | [diff] [blame] | 287 | adc_close(); |
Linus Nielsen Feltzing | bd42d31 | 2005-03-31 08:47:02 +0000 | [diff] [blame] | 288 | |
Michael Sevakis | af395f4 | 2008-03-26 01:50:41 +0000 | [diff] [blame] | 289 | #ifdef CPU_ARM |
Michael Sevakis | 6dd6ea7 | 2008-05-08 12:09:14 +0000 | [diff] [blame] | 290 | /* Should do these together since some ARM version should never have |
| 291 | * FIQ disabled and not IRQ (imx31 errata). */ |
| 292 | disable_interrupt(IRQ_FIQ_STATUS); |
| 293 | #else |
| 294 | /* Some targets have a higher disable level than HIGEST_IRQ_LEVEL */ |
Michael Sevakis | af395f4 | 2008-03-26 01:50:41 +0000 | [diff] [blame] | 295 | set_irq_level(DISABLE_INTERRUPTS); |
Michael Sevakis | 6dd6ea7 | 2008-05-08 12:09:14 +0000 | [diff] [blame] | 296 | #endif |
Michael Sevakis | af395f4 | 2008-03-26 01:50:41 +0000 | [diff] [blame] | 297 | |
Dave Chapman | 77372d1 | 2005-11-07 23:07:19 +0000 | [diff] [blame] | 298 | #elif CONFIG_CPU == SH7034 |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 299 | /* Read file length from header and compare to real file length */ |
Daniel Stenberg | 8f1d3c9 | 2003-01-22 18:47:35 +0000 | [diff] [blame] | 300 | lseek(fd, FIRMWARE_OFFSET_FILE_LENGTH, SEEK_SET); |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 301 | if(read(fd, &file_length, 4) != 4) { |
| 302 | rolo_error("Error Reading File Length"); |
| 303 | return -1; |
| 304 | } |
| 305 | if (length != file_length) { |
| 306 | rolo_error("File length mismatch"); |
| 307 | return -1; |
| 308 | } |
Karl Kurbjun | b7a4e10 | 2007-10-13 14:53:34 +0000 | [diff] [blame] | 309 | |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 310 | /* Read and save checksum */ |
Daniel Stenberg | 8f1d3c9 | 2003-01-22 18:47:35 +0000 | [diff] [blame] | 311 | lseek(fd, FIRMWARE_OFFSET_FILE_CRC, SEEK_SET); |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 312 | if (read(fd, &file_checksum, 2) != 2) { |
| 313 | rolo_error("Error Reading checksum"); |
| 314 | return -1; |
| 315 | } |
Daniel Stenberg | 8f1d3c9 | 2003-01-22 18:47:35 +0000 | [diff] [blame] | 316 | lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET); |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 317 | |
| 318 | /* verify that file can be read and descrambled */ |
Linus Nielsen Feltzing | d34865a | 2005-04-05 11:33:58 +0000 | [diff] [blame] | 319 | if ((audiobuf + (2*length)+4) >= audiobufend) { |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 320 | rolo_error("Not enough room to load file"); |
| 321 | return -1; |
| 322 | } |
| 323 | |
Linus Nielsen Feltzing | d34865a | 2005-04-05 11:33:58 +0000 | [diff] [blame] | 324 | if (read(fd, &audiobuf[length], length) != (int)length) { |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 325 | rolo_error("Error Reading File"); |
| 326 | return -1; |
| 327 | } |
| 328 | |
Linus Nielsen Feltzing | 1c79260 | 2002-09-09 12:59:06 +0000 | [diff] [blame] | 329 | lcd_puts(0, 1, "Descramble"); |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 330 | lcd_update(); |
| 331 | |
Linus Nielsen Feltzing | d34865a | 2005-04-05 11:33:58 +0000 | [diff] [blame] | 332 | checksum = descramble(audiobuf + length, audiobuf, length); |
Karl Kurbjun | b7a4e10 | 2007-10-13 14:53:34 +0000 | [diff] [blame] | 333 | |
Jörg Hohensohn | cbbbcd1 | 2003-10-12 16:40:45 +0000 | [diff] [blame] | 334 | /* Verify checksum against file header */ |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 335 | if (checksum != file_checksum) { |
| 336 | rolo_error("Checksum Error"); |
| 337 | return -1; |
| 338 | } |
| 339 | |
Linus Nielsen Feltzing | 1c79260 | 2002-09-09 12:59:06 +0000 | [diff] [blame] | 340 | lcd_puts(0, 1, "Executing "); |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 341 | lcd_update(); |
| 342 | |
Linus Nielsen Feltzing | bd42d31 | 2005-03-31 08:47:02 +0000 | [diff] [blame] | 343 | set_irq_level(HIGHEST_IRQ_LEVEL); |
Karl Kurbjun | b7a4e10 | 2007-10-13 14:53:34 +0000 | [diff] [blame] | 344 | |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 345 | /* Calling these 2 initialization routines was necessary to get the |
| 346 | the origional Archos version of the firmware to load and execute. */ |
| 347 | system_init(); /* Initialize system for restart */ |
| 348 | i2c_init(); /* Init i2c bus - it seems like a good idea */ |
| 349 | ICR = IRQ0_EDGE_TRIGGER; /* Make IRQ0 edge triggered */ |
Daniel Stenberg | 36355a5 | 2005-02-02 21:47:08 +0000 | [diff] [blame] | 350 | TSTR = 0xE0; /* disable all timers */ |
Jens Arnold | ab232fc | 2004-10-14 23:40:58 +0000 | [diff] [blame] | 351 | /* model-specific de-init, needed when flashed */ |
| 352 | /* Especially the Archos software is picky about this */ |
Daniel Stenberg | 36355a5 | 2005-02-02 21:47:08 +0000 | [diff] [blame] | 353 | #if defined(ARCHOS_RECORDER) || defined(ARCHOS_RECORDERV2) || \ |
| 354 | defined(ARCHOS_FMRECORDER) |
| 355 | PAIOR = 0x0FA0; |
Jörg Hohensohn | cbbbcd1 | 2003-10-12 16:40:45 +0000 | [diff] [blame] | 356 | #endif |
Linus Nielsen Feltzing | bd42d31 | 2005-03-31 08:47:02 +0000 | [diff] [blame] | 357 | #endif |
Linus Nielsen Feltzing | d34865a | 2005-04-05 11:33:58 +0000 | [diff] [blame] | 358 | rolo_restart(audiobuf, ramstart, length); |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 359 | |
| 360 | return 0; /* this is never reached */ |
Steve Bavin | ba58dd8 | 2008-04-15 15:41:13 +0000 | [diff] [blame] | 361 | (void)checksum; (void)file_checksum; |
Björn Stenberg | c521ed1 | 2002-09-03 09:44:08 +0000 | [diff] [blame] | 362 | } |
Jens Arnold | 780f79e | 2006-11-10 20:26:01 +0000 | [diff] [blame] | 363 | #else /* !defined(IRIVER_IFP7XX_SERIES) */ |
Daniel Stenberg | 36355a5 | 2005-02-02 21:47:08 +0000 | [diff] [blame] | 364 | int rolo_load(const char* filename) |
| 365 | { |
| 366 | /* dummy */ |
Daniel Stenberg | e81fb19 | 2005-02-03 10:07:11 +0000 | [diff] [blame] | 367 | (void)filename; |
| 368 | return 0; |
Daniel Stenberg | 36355a5 | 2005-02-02 21:47:08 +0000 | [diff] [blame] | 369 | } |
| 370 | |
Jens Arnold | 780f79e | 2006-11-10 20:26:01 +0000 | [diff] [blame] | 371 | #endif /* !defined(IRIVER_IFP7XX_SERIES) */ |