diff --git a/bootloader/common.c b/bootloader/common.c index 5f824cf1b8..a382816791 100644 --- a/bootloader/common.c +++ b/bootloader/common.c @@ -25,10 +25,13 @@ #include #include "cpu.h" #include "common.h" +#include "power.h" +#include "kernel.h" /* TODO: Other bootloaders need to be adjusted to set this variable to true - on a button press - currently only the ipod version does. */ -#ifdef IPOD_ARCH + on a button press - currently only the ipod, H10 and Sansa versions do. */ +#if defined(IPOD_ARCH) || defined(IRIVER_H10) || defined(IRIVER_H10_5GB) || \ + defined(SANSA_E200) bool verbose = false; #else bool verbose = true; @@ -99,6 +102,28 @@ char *strerror(int error) } } +void error(int errortype, int error) +{ + switch(errortype) + { + case EATA: + printf("ATA error: %d", error); + break; + + case EDISK: + printf("No partition found"); + break; + + case EBOOTFILE: + printf(strerror(error)); + break; + } + + lcd_update(); + sleep(5*HZ); + power_off(); +} + /* Load firmware image in a format created by tools/scramble */ int load_firmware(unsigned char* buf, char* firmware, int buffer_size) { diff --git a/bootloader/common.h b/bootloader/common.h index adb833fd1d..3607dd0f68 100644 --- a/bootloader/common.h +++ b/bootloader/common.h @@ -31,9 +31,15 @@ /* Set this to true to enable lcd_update() in the printf function */ extern bool verbose; +/* Error types */ +#define EATA -1 +#define EDISK -2 +#define EBOOTFILE -3 + /* Functions common to all bootloaders */ void reset_screen(void); void printf(const char *format, ...); char *strerror(int error); +void error(int errortype, int error); int load_firmware(unsigned char* buf, char* firmware, int buffer_size); int load_raw_firmware(unsigned char* buf, char* firmware, int buffer_size); diff --git a/bootloader/main-pp.c b/bootloader/main-pp.c index 5659073457..0f85404fc7 100644 --- a/bootloader/main-pp.c +++ b/bootloader/main-pp.c @@ -29,7 +29,17 @@ #include "ata.h" #include "button.h" #include "disk.h" -#include "power.h" + +/* Button definitions */ +#if CONFIG_KEYPAD == IRIVER_H10_PAD +#define BOOTLOADER_VERBOSE BUTTON_PLAY +#define BOOTLOADER_BOOT_OF BUTTON_LEFT + +#elif CONFIG_KEYPAD == SANSA_E200_PAD +#define BOOTLOADER_VERBOSE BUTTON_RIGHT +#define BOOTLOADER_BOOT_OF BUTTON_LEFT + +#endif /* Maximum allowed firmware image size. 10MB is more than enough */ #define MAX_LOADSIZE (10*1024*1024) @@ -44,6 +54,7 @@ void* main(void) { char buf[256]; int i; + int btn; int rc; unsigned short* identify_info; struct partinfo* pinfo; @@ -54,6 +65,12 @@ void* main(void) font_init(); button_init(); + btn = button_read_device(); + + /* Enable bootloader messages */ + if (btn==BOOTLOADER_VERBOSE) + verbose = true; + lcd_setfont(FONT_SYSFIXED); printf("Rockbox boot loader"); @@ -73,25 +90,20 @@ void* main(void) } printf(buf); } else { - printf("ATA error: %d", i); - udelay(5000000); - power_off(); + error(EATA, i); } disk_init(); rc = disk_mount_all(); if (rc<=0) { - printf("No partition found"); - udelay(5000000); - power_off(); + error(EDISK,rc); } pinfo = disk_partinfo(0); printf("Partition 0: 0x%02x %ld MB", pinfo->type, pinfo->size / 2048); - i=button_read_device(); - if(i==BUTTON_LEFT) + if(btn==BOOTLOADER_BOOT_OF) { /* Load original mi4 firmware. This expects a file called "/System/OF.bin" on the player. It should be a mi4 firmware decrypted @@ -101,21 +113,15 @@ void* main(void) printf("Loading original firmware..."); rc=load_raw_firmware(loadbuffer, "/System/OF.bin", MAX_LOADSIZE); if (rc < EOK) { - printf("Error!"); - printf("Can't load /System/OF.bin:"); - printf(strerror(rc)); - udelay(5000000); - power_off(); + printf("Can't load /System/OF.bin"); + error(EBOOTFILE, rc); } } else { printf("Loading Rockbox..."); rc=load_firmware(loadbuffer, BOOTFILE, MAX_LOADSIZE); if (rc < EOK) { - printf("Error!"); printf("Can't load %s:", BOOTFILE); - printf(strerror(rc)); - udelay(5000000); - power_off(); + error(EBOOTFILE, rc); } } diff --git a/firmware/kernel.c b/firmware/kernel.c index c304e455c2..e794fed3fe 100644 --- a/firmware/kernel.c +++ b/firmware/kernel.c @@ -72,6 +72,10 @@ void sleep(int ticks) counter = TCNTO4; } while(counter > 0); +#elif defined(CPU_PP) && defined(BOOTLOADER) + unsigned stop = USEC_TIMER + ticks * (1000000/HZ); + while (TIME_BEFORE(USEC_TIMER, stop)) + switch_thread(true,NULL); #else sleep_thread(ticks); #endif