diff options
Diffstat (limited to 'bootloader')
-rw-r--r-- | bootloader/iriver_h1x0.c | 59 | ||||
-rw-r--r-- | bootloader/iriver_h300.c | 251 |
2 files changed, 268 insertions, 42 deletions
diff --git a/bootloader/iriver_h1x0.c b/bootloader/iriver_h1x0.c index 168bd29b67..d5a3b887a2 100644 --- a/bootloader/iriver_h1x0.c +++ b/bootloader/iriver_h1x0.c @@ -61,9 +61,7 @@ extern int line; extern int remote_line; -#ifdef HAVE_EEPROM_SETTINGS static bool recovery_mode = false; -#endif /* Reset the cookie for the crt0 crash check */ inline void __reset_cookie(void) @@ -96,12 +94,12 @@ void start_firmware(void) void start_flashed_romimage(void) { uint8_t *src = (uint8_t *)FLASH_ROMIMAGE_ENTRY; - int *reset_vector; + uint32_t *reset_vector; if (!detect_flashed_romimage()) return ; - reset_vector = (int *)(&src[sizeof(struct flash_header)+4]); + reset_vector = (uint32_t *)(&src[sizeof(struct flash_header)+sizeof(uint32_t)]); asm(" move.w #0x2700,%sr"); __reset_cookie(); @@ -119,7 +117,7 @@ void start_flashed_romimage(void) void start_flashed_ramimage(void) { struct flash_header hdr; - unsigned char *buf = (unsigned char *)DRAM_START; + uint8_t *buf = (uint8_t *)DRAM_START; uint8_t *src = (uint8_t *)FLASH_RAMIMAGE_ENTRY; if (!detect_flashed_ramimage()) @@ -141,11 +139,9 @@ void start_flashed_ramimage(void) void shutdown(void) { printf("Shutting down..."); -#ifdef HAVE_EEPROM_SETTINGS /* Reset the rockbox crash check. */ firmware_settings.bl_version = 0; eeprom_settings_store(); -#endif /* We need to gracefully spin down the disk to prevent clicks. */ if (ide_powered()) @@ -185,7 +181,6 @@ void check_battery(void) } } -#ifdef HAVE_EEPROM_SETTINGS void initialize_eeprom(void) { if (detect_original_firmware()) @@ -235,17 +230,17 @@ void try_flashboot(void) } } -static const char *options[] = { - "Boot from disk", - "Boot RAM image", - "Boot ROM image", - "Shutdown" -}; - -#define FAILSAFE_OPTIONS 4 -#define TIMEOUT (15*HZ) void failsafe_menu(void) { + static const char *options[] = + { + "Boot from disk", + "Boot RAM image", + "Boot ROM image", + "Shutdown" + }; + const int FAILSAFE_OPTIONS = sizeof(options) / sizeof(*options); + const long TIMEOUT = 15 * HZ; long start_tick = current_tick; int option = 3; int button; @@ -355,7 +350,6 @@ void failsafe_menu(void) shutdown(); } -#endif /* get rid of a nasty humming sound during boot -> RESET signal */ @@ -427,9 +421,7 @@ void main(void) coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS); enable_irq(); -#ifdef HAVE_EEPROM_SETTINGS initialize_eeprom(); -#endif usb_init(); /* A small delay after usb_init is necessary to read the I/O port correctly @@ -458,19 +450,11 @@ void main(void) } /* Power on the hard drive early, to speed up the loading. */ - if (!hold_status -# ifdef HAVE_EEPROM_SETTINGS - && !recovery_mode -# endif - ) - { + if (!hold_status && !recovery_mode) ide_power_enable(true); - } -# ifdef HAVE_EEPROM_SETTINGS if (!hold_status && (usb_detect() != USB_INSERTED) && !recovery_mode) try_flashboot(); -# endif lcd_init(); @@ -500,11 +484,7 @@ void main(void) /* Don't start if the Hold button is active on the device you are starting with */ - if ((usb_detect() != USB_INSERTED) && (hold_status -#ifdef HAVE_EEPROM_SETTINGS - || recovery_mode -#endif - )) + if ((usb_detect() != USB_INSERTED) && (hold_status || recovery_mode)) { if (detect_original_firmware()) { @@ -512,9 +492,7 @@ void main(void) shutdown(); } -#ifdef HAVE_EEPROM_SETTINGS failsafe_menu(); -#endif } /* Holding REC while starting runs the original firmware */ @@ -537,13 +515,12 @@ void main(void) lcd_remote_puts(0, 3, msg); lcd_remote_update(); -#ifdef HAVE_EEPROM_SETTINGS if (firmware_settings.initialized) { firmware_settings.disk_clean = false; eeprom_settings_store(); } -#endif + ide_power_enable(true); storage_enable(false); sleep(HZ/20); @@ -570,6 +547,11 @@ void main(void) lcd_update(); } + /* boot from flash if that is the default */ + try_flashboot(); + if (recovery_mode) + printf("Falling back to boot from disk"); + rc = storage_init(); if(rc) { @@ -580,7 +562,6 @@ void main(void) while(!(button_get(true) & BUTTON_REL)); } - filesystem_init(); rc = disk_mount_all(); 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 @@ #include "power.h" #include "powermgmt.h" #include "file.h" +#include "eeprom_settings.h" +#include "rbunicode.h" #include "pcf50606.h" #include "common.h" #include "rb-loader.h" #include "loader_strerror.h" -#include "rbunicode.h" #include "isp1362.h" #include "version.h" @@ -62,6 +63,8 @@ extern int line; extern int remote_line; +static bool recovery_mode = false; + /* Reset the cookie for the crt0 crash check */ inline void __reset_cookie(void) { @@ -90,9 +93,57 @@ void start_firmware(void) asm(" jmp (%a0)"); } +void start_flashed_romimage(void) +{ + uint8_t *src = (uint8_t *)FLASH_ROMIMAGE_ENTRY; + uint32_t *reset_vector; + + if (!detect_flashed_romimage()) + return ; + + reset_vector = (uint32_t *)(&src[sizeof(struct flash_header)+sizeof(uint32_t)]); + + asm(" move.w #0x2700,%sr"); + __reset_cookie(); + + asm(" move.l %0,%%d0" :: "i"(DRAM_START)); + asm(" movec.l %d0,%vbr"); + asm(" move.l %0,%%sp" :: "m"(reset_vector[0])); + asm(" move.l %0,%%a0" :: "m"(reset_vector[1])); + asm(" jmp (%a0)"); + + /* Failure */ + power_off(); +} + +void start_flashed_ramimage(void) +{ + struct flash_header hdr; + uint8_t *buf = (uint8_t *)DRAM_START; + uint8_t *src = (uint8_t *)FLASH_RAMIMAGE_ENTRY; + + if (!detect_flashed_ramimage()) + return; + + /* Load firmware from flash */ + cpu_boost(true); + memcpy(&hdr, src, sizeof(struct flash_header)); + src += sizeof(struct flash_header); + memcpy(buf, src, hdr.length); + cpu_boost(false); + + start_firmware(); + + /* Failure */ + power_off(); +} + void shutdown(void) { printf("Shutting down..."); + /* Reset the rockbox crash check. */ + firmware_settings.bl_version = 0; + eeprom_settings_store(); /* We need to gracefully spin down the disk to prevent clicks. */ if (ide_powered()) @@ -106,6 +157,7 @@ void shutdown(void) sleep(HZ*2); + /* Backlight OFF */ backlight_hw_off(); remote_backlight_hw_off(); @@ -131,6 +183,176 @@ void check_battery(void) } } +void initialize_eeprom(void) +{ + if (detect_original_firmware()) + return ; + + if (!eeprom_settings_init()) + { + recovery_mode = true; + return ; + } + + /* If bootloader version has not been reset, disk might + * not be intact. */ + if (firmware_settings.bl_version || !firmware_settings.disk_clean) + { + firmware_settings.disk_clean = false; + recovery_mode = true; + } + + firmware_settings.bl_version = EEPROM_SETTINGS_BL_MINVER; + eeprom_settings_store(); +} + +void try_flashboot(void) +{ + if (!firmware_settings.initialized) + return ; + + switch (firmware_settings.bootmethod) + { + case BOOT_DISK: + return; + + case BOOT_ROM: + start_flashed_romimage(); + recovery_mode = true; + break; + + case BOOT_RAM: + start_flashed_ramimage(); + recovery_mode = true; + break; + + default: + recovery_mode = true; + return; + } +} + +void failsafe_menu(void) +{ + static const char *options[] = + { + "Boot from disk", + "Boot RAM image", + "Boot ROM image", + "Shutdown" + }; + const int FAILSAFE_OPTIONS = sizeof(options) / sizeof(*options); + const long TIMEOUT = 15 * HZ; + long start_tick = current_tick; + int option = 3; + int button; + int defopt = -1; + char buf[32]; + int i; + + reset_screen(); + printf("Bootloader %s", rbversion); + check_battery(); + printf("========================="); + line += FAILSAFE_OPTIONS; + printf(""); + printf(" [NAVI] to confirm."); + printf(" [REC] to set as default."); + printf(""); + + if (firmware_settings.initialized) + { + defopt = firmware_settings.bootmethod; + if (defopt < 0 || defopt >= FAILSAFE_OPTIONS) + defopt = option; + } + + while (current_tick - start_tick < TIMEOUT) + { + /* Draw the menu. */ + line = 3; + for (i = 0; i < FAILSAFE_OPTIONS; i++) + { + char *def = "[DEF]"; + char *arrow = "->"; + + if (i != defopt) + def = ""; + if (i != option) + arrow = " "; + + printf("%s %s %s", arrow, options[i], def); + } + + snprintf(buf, sizeof(buf), "Time left: %lds", + (TIMEOUT - (current_tick - start_tick)) / HZ); + lcd_puts(0, 10, buf); + lcd_update(); + button = button_get_w_tmo(HZ); + + if (button == BUTTON_NONE || button & SYS_EVENT) + continue ; + + start_tick = current_tick; + + /* Ignore the ON/PLAY -button because it can cause trouble + with the RTC alarm mod. */ + switch (button & ~(BUTTON_ON)) + { + case BUTTON_UP: + case BUTTON_RC_REW: + if (option > 0) + option--; + break ; + + case BUTTON_DOWN: + case BUTTON_RC_FF: + if (option < FAILSAFE_OPTIONS-1) + option++; + break ; + + case BUTTON_SELECT: + case BUTTON_RC_ON: + goto execute; + + case BUTTON_REC: + case BUTTON_RC_REC: + if (firmware_settings.initialized) + { + firmware_settings.bootmethod = option; + eeprom_settings_store(); + defopt = option; + } + break ; + } + } + + execute: + + lcd_puts(0, 10, "Executing command..."); + lcd_update(); + sleep(HZ); + reset_screen(); + + switch (option) + { + case BOOT_DISK: + return ; + + case BOOT_RAM: + start_flashed_ramimage(); + printf("Image not found"); + break; + + case BOOT_ROM: + start_flashed_romimage(); + printf("Image not found"); + break; + } + + shutdown(); +} + /* From the pcf50606 driver */ extern unsigned char pcf50606_intregs[3]; @@ -187,6 +409,7 @@ void main(void) backlight_hw_init(); backlight_hw_off(); + /* Remote backlight ON */ remote_backlight_hw_on(); system_init(); @@ -197,11 +420,20 @@ void main(void) coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS); enable_irq(); + initialize_eeprom(); + isp1362_init(); adc_init(); button_init(); + /* Power on the hard drive early, to speed up the loading. */ + if (!hold_status && !recovery_mode) + ide_power_enable(true); + + if (!hold_status && (usb_detect() != USB_INSERTED) && !recovery_mode) + try_flashboot(); + lcd_init(); lcd_remote_init(); font_init(); @@ -229,14 +461,16 @@ void main(void) { hold_status = true; } - if (hold_status && !rtc_alarm && (usb_detect() != USB_INSERTED) && - !charger_inserted()) + if ((hold_status || recovery_mode) && !rtc_alarm && + (usb_detect() != USB_INSERTED) && !charger_inserted()) { if (detect_original_firmware()) { printf("Hold switch on"); shutdown(); } + + failsafe_menu(); } /* Holding REC while starting runs the original firmware */ @@ -321,6 +555,12 @@ void main(void) lcd_remote_puts(0, 3, msg); lcd_remote_update(); + if (firmware_settings.initialized) + { + firmware_settings.disk_clean = false; + eeprom_settings_store(); + } + ide_power_enable(true); storage_enable(false); sleep(HZ/20); @@ -351,6 +591,11 @@ void main(void) usb_charge = false; } + /* boot from flash if that is the default */ + try_flashboot(); + if (recovery_mode) + printf("Falling back to boot from disk"); + rc = storage_init(); if(rc) { |