summaryrefslogtreecommitdiff
path: root/bootloader/iriver_h300.c
diff options
context:
space:
mode:
Diffstat (limited to 'bootloader/iriver_h300.c')
-rw-r--r--bootloader/iriver_h300.c251
1 files changed, 248 insertions, 3 deletions
diff --git a/bootloader/iriver_h300.c b/bootloader/iriver_h300.c
index ee344d4165..ff3c8de2af 100644
--- a/bootloader/iriver_h300.c
+++ b/bootloader/iriver_h300.c
@@ -43,11 +43,12 @@
43#include "power.h" 43#include "power.h"
44#include "powermgmt.h" 44#include "powermgmt.h"
45#include "file.h" 45#include "file.h"
46#include "eeprom_settings.h"
47#include "rbunicode.h"
46#include "pcf50606.h" 48#include "pcf50606.h"
47#include "common.h" 49#include "common.h"
48#include "rb-loader.h" 50#include "rb-loader.h"
49#include "loader_strerror.h" 51#include "loader_strerror.h"
50#include "rbunicode.h"
51#include "isp1362.h" 52#include "isp1362.h"
52#include "version.h" 53#include "version.h"
53 54
@@ -62,6 +63,8 @@
62extern int line; 63extern int line;
63extern int remote_line; 64extern int remote_line;
64 65
66static bool recovery_mode = false;
67
65/* Reset the cookie for the crt0 crash check */ 68/* Reset the cookie for the crt0 crash check */
66inline void __reset_cookie(void) 69inline void __reset_cookie(void)
67{ 70{
@@ -90,9 +93,57 @@ void start_firmware(void)
90 asm(" jmp (%a0)"); 93 asm(" jmp (%a0)");
91} 94}
92 95
96void start_flashed_romimage(void)
97{
98 uint8_t *src = (uint8_t *)FLASH_ROMIMAGE_ENTRY;
99 uint32_t *reset_vector;
100
101 if (!detect_flashed_romimage())
102 return ;
103
104 reset_vector = (uint32_t *)(&src[sizeof(struct flash_header)+sizeof(uint32_t)]);
105
106 asm(" move.w #0x2700,%sr");
107 __reset_cookie();
108
109 asm(" move.l %0,%%d0" :: "i"(DRAM_START));
110 asm(" movec.l %d0,%vbr");
111 asm(" move.l %0,%%sp" :: "m"(reset_vector[0]));
112 asm(" move.l %0,%%a0" :: "m"(reset_vector[1]));
113 asm(" jmp (%a0)");
114
115 /* Failure */
116 power_off();
117}
118
119void start_flashed_ramimage(void)
120{
121 struct flash_header hdr;
122 uint8_t *buf = (uint8_t *)DRAM_START;
123 uint8_t *src = (uint8_t *)FLASH_RAMIMAGE_ENTRY;
124
125 if (!detect_flashed_ramimage())
126 return;
127
128 /* Load firmware from flash */
129 cpu_boost(true);
130 memcpy(&hdr, src, sizeof(struct flash_header));
131 src += sizeof(struct flash_header);
132 memcpy(buf, src, hdr.length);
133 cpu_boost(false);
134
135 start_firmware();
136
137 /* Failure */
138 power_off();
139}
140
93void shutdown(void) 141void shutdown(void)
94{ 142{
95 printf("Shutting down..."); 143 printf("Shutting down...");
144 /* Reset the rockbox crash check. */
145 firmware_settings.bl_version = 0;
146 eeprom_settings_store();
96 147
97 /* We need to gracefully spin down the disk to prevent clicks. */ 148 /* We need to gracefully spin down the disk to prevent clicks. */
98 if (ide_powered()) 149 if (ide_powered())
@@ -106,6 +157,7 @@ void shutdown(void)
106 157
107 sleep(HZ*2); 158 sleep(HZ*2);
108 159
160 /* Backlight OFF */
109 backlight_hw_off(); 161 backlight_hw_off();
110 remote_backlight_hw_off(); 162 remote_backlight_hw_off();
111 163
@@ -131,6 +183,176 @@ void check_battery(void)
131 } 183 }
132} 184}
133 185
186void initialize_eeprom(void)
187{
188 if (detect_original_firmware())
189 return ;
190
191 if (!eeprom_settings_init())
192 {
193 recovery_mode = true;
194 return ;
195 }
196
197 /* If bootloader version has not been reset, disk might
198 * not be intact. */
199 if (firmware_settings.bl_version || !firmware_settings.disk_clean)
200 {
201 firmware_settings.disk_clean = false;
202 recovery_mode = true;
203 }
204
205 firmware_settings.bl_version = EEPROM_SETTINGS_BL_MINVER;
206 eeprom_settings_store();
207}
208
209void try_flashboot(void)
210{
211 if (!firmware_settings.initialized)
212 return ;
213
214 switch (firmware_settings.bootmethod)
215 {
216 case BOOT_DISK:
217 return;
218
219 case BOOT_ROM:
220 start_flashed_romimage();
221 recovery_mode = true;
222 break;
223
224 case BOOT_RAM:
225 start_flashed_ramimage();
226 recovery_mode = true;
227 break;
228
229 default:
230 recovery_mode = true;
231 return;
232 }
233}
234
235void failsafe_menu(void)
236{
237 static const char *options[] =
238 {
239 "Boot from disk",
240 "Boot RAM image",
241 "Boot ROM image",
242 "Shutdown"
243 };
244 const int FAILSAFE_OPTIONS = sizeof(options) / sizeof(*options);
245 const long TIMEOUT = 15 * HZ;
246 long start_tick = current_tick;
247 int option = 3;
248 int button;
249 int defopt = -1;
250 char buf[32];
251 int i;
252
253 reset_screen();
254 printf("Bootloader %s", rbversion);
255 check_battery();
256 printf("=========================");
257 line += FAILSAFE_OPTIONS;
258 printf("");
259 printf(" [NAVI] to confirm.");
260 printf(" [REC] to set as default.");
261 printf("");
262
263 if (firmware_settings.initialized)
264 {
265 defopt = firmware_settings.bootmethod;
266 if (defopt < 0 || defopt >= FAILSAFE_OPTIONS)
267 defopt = option;
268 }
269
270 while (current_tick - start_tick < TIMEOUT)
271 {
272 /* Draw the menu. */
273 line = 3;
274 for (i = 0; i < FAILSAFE_OPTIONS; i++)
275 {
276 char *def = "[DEF]";
277 char *arrow = "->";
278
279 if (i != defopt)
280 def = "";
281 if (i != option)
282 arrow = " ";
283
284 printf("%s %s %s", arrow, options[i], def);
285 }
286
287 snprintf(buf, sizeof(buf), "Time left: %lds",
288 (TIMEOUT - (current_tick - start_tick)) / HZ);
289 lcd_puts(0, 10, buf);
290 lcd_update();
291 button = button_get_w_tmo(HZ);
292
293 if (button == BUTTON_NONE || button & SYS_EVENT)
294 continue ;
295
296 start_tick = current_tick;
297
298 /* Ignore the ON/PLAY -button because it can cause trouble
299 with the RTC alarm mod. */
300 switch (button & ~(BUTTON_ON))
301 {
302 case BUTTON_UP:
303 case BUTTON_RC_REW:
304 if (option > 0)
305 option--;
306 break ;
307
308 case BUTTON_DOWN:
309 case BUTTON_RC_FF:
310 if (option < FAILSAFE_OPTIONS-1)
311 option++;
312 break ;
313
314 case BUTTON_SELECT:
315 case BUTTON_RC_ON:
316 goto execute;
317
318 case BUTTON_REC:
319 case BUTTON_RC_REC:
320 if (firmware_settings.initialized)
321 {
322 firmware_settings.bootmethod = option;
323 eeprom_settings_store();
324 defopt = option;
325 }
326 break ;
327 }
328 }
329
330 execute:
331
332 lcd_puts(0, 10, "Executing command...");
333 lcd_update();
334 sleep(HZ);
335 reset_screen();
336
337 switch (option)
338 {
339 case BOOT_DISK:
340 return ;
341
342 case BOOT_RAM:
343 start_flashed_ramimage();
344 printf("Image not found");
345 break;
346
347 case BOOT_ROM:
348 start_flashed_romimage();
349 printf("Image not found");
350 break;
351 }
352
353 shutdown();
354}
355
134/* From the pcf50606 driver */ 356/* From the pcf50606 driver */
135extern unsigned char pcf50606_intregs[3]; 357extern unsigned char pcf50606_intregs[3];
136 358
@@ -187,6 +409,7 @@ void main(void)
187 backlight_hw_init(); 409 backlight_hw_init();
188 backlight_hw_off(); 410 backlight_hw_off();
189 411
412 /* Remote backlight ON */
190 remote_backlight_hw_on(); 413 remote_backlight_hw_on();
191 414
192 system_init(); 415 system_init();
@@ -197,11 +420,20 @@ void main(void)
197 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS); 420 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS);
198 enable_irq(); 421 enable_irq();
199 422
423 initialize_eeprom();
424
200 isp1362_init(); 425 isp1362_init();
201 426
202 adc_init(); 427 adc_init();
203 button_init(); 428 button_init();
204 429
430 /* Power on the hard drive early, to speed up the loading. */
431 if (!hold_status && !recovery_mode)
432 ide_power_enable(true);
433
434 if (!hold_status && (usb_detect() != USB_INSERTED) && !recovery_mode)
435 try_flashboot();
436
205 lcd_init(); 437 lcd_init();
206 lcd_remote_init(); 438 lcd_remote_init();
207 font_init(); 439 font_init();
@@ -229,14 +461,16 @@ void main(void)
229 { 461 {
230 hold_status = true; 462 hold_status = true;
231 } 463 }
232 if (hold_status && !rtc_alarm && (usb_detect() != USB_INSERTED) && 464 if ((hold_status || recovery_mode) && !rtc_alarm &&
233 !charger_inserted()) 465 (usb_detect() != USB_INSERTED) && !charger_inserted())
234 { 466 {
235 if (detect_original_firmware()) 467 if (detect_original_firmware())
236 { 468 {
237 printf("Hold switch on"); 469 printf("Hold switch on");
238 shutdown(); 470 shutdown();
239 } 471 }
472
473 failsafe_menu();
240 } 474 }
241 475
242 /* Holding REC while starting runs the original firmware */ 476 /* Holding REC while starting runs the original firmware */
@@ -321,6 +555,12 @@ void main(void)
321 lcd_remote_puts(0, 3, msg); 555 lcd_remote_puts(0, 3, msg);
322 lcd_remote_update(); 556 lcd_remote_update();
323 557
558 if (firmware_settings.initialized)
559 {
560 firmware_settings.disk_clean = false;
561 eeprom_settings_store();
562 }
563
324 ide_power_enable(true); 564 ide_power_enable(true);
325 storage_enable(false); 565 storage_enable(false);
326 sleep(HZ/20); 566 sleep(HZ/20);
@@ -351,6 +591,11 @@ void main(void)
351 usb_charge = false; 591 usb_charge = false;
352 } 592 }
353 593
594 /* boot from flash if that is the default */
595 try_flashboot();
596 if (recovery_mode)
597 printf("Falling back to boot from disk");
598
354 rc = storage_init(); 599 rc = storage_init();
355 if(rc) 600 if(rc)
356 { 601 {