From 8a1fd8c686d2a4b8be36754e545338a476150e6a Mon Sep 17 00:00:00 2001 From: Karl Kurbjun Date: Sat, 21 Apr 2007 04:48:20 +0000 Subject: Commit FS#6929 - Gigabeat bootloader improvements by Barry Wardell and myself. This build fixes the problems seen with the latest builds on the Gigabeat X. Added View IO Ports under the Debug menu for the Gigabeat. Make sure you grab the latest bootloader from the Wiki as the old bootloader will not work properly with new builds. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13225 a1c6a512-1295-4272-9138-f99709370657 --- bootloader/gigabeat.c | 278 ++++++++++++-------------------------------------- 1 file changed, 64 insertions(+), 214 deletions(-) (limited to 'bootloader/gigabeat.c') diff --git a/bootloader/gigabeat.c b/bootloader/gigabeat.c index e4cf6f08fd..e482c70d16 100644 --- a/bootloader/gigabeat.c +++ b/bootloader/gigabeat.c @@ -20,7 +20,8 @@ #include #include -#include +#include "inttypes.h" +#include "string.h" #include "cpu.h" #include "system.h" #include "lcd.h" @@ -32,250 +33,99 @@ #include "font.h" #include "adc.h" #include "backlight.h" +#include "backlight-target.h" +#include "button.h" #include "panic.h" #include "power.h" #include "file.h" -#include "button-target.h" #include "common.h" +#include "rbunicode.h" +#include "usb.h" +#include "mmu-meg-fx.h" -extern void map_memory(void); +#include char version[] = APPSVERSION; -static void go_usb_mode(void) +void main(void) { - /* Drop into USB mode. This does not check for disconnection. */ - int i; - - GPBDAT &= 0x7EF; - GPBCON |= 1<<8; - - GPGDAT &= 0xE7FF; - GPGDAT |= 1<<11; - - for(i = 0; i < 10000000; i++) { - continue; - } - - GPBCON &= 0x2FFCFF; - GPBDAT |= 1<<5; - GPBDAT |= 1<<6; -} - - -/* Restores a factory kernel/bootloader from a known location */ -/* Restores the FWIMG01.DAT file back in the case of a bootloader failure */ -/* The factory or "good" bootloader must be in /GBSYSTEM/FWIMG/FWIMG01.DAT.ORIG */ -/* Returns non-zero on failure */ -int restore_fwimg01dat(void) -{ - int orig_file = 0, dest_file = 0; - int size = 0, size_read; - static char buf[4096]; - - orig_file = open("/GBSYSTEM/FWIMG/FWIMG01.DAT.ORIG", O_RDONLY); - if(orig_file < 0) { - /* Couldn't open source file */ - printf("Couldn't open FWIMG01.DAT.ORIG for reading"); - return(1); - } - - printf("FWIMG01.DAT.ORIG opened for reading"); - - dest_file = open("/GBSYSTEM/FWIMG/FWIMG01.DAT", O_RDWR); - if(dest_file < 0) { - /* Couldn't open destination file */ - printf("Couldn't open FWIMG01.DAT.ORIG for writing"); - close(orig_file); - return(2); - } - - printf("FWIMG01.DAT opened for writing"); - - do { - /* Copy in chunks */ - size_read = read(orig_file, buf, sizeof(buf)); - if(size_read != write(dest_file, buf, size_read)) { - close(orig_file); - close(dest_file); - return(3); - } - size += size_read; - - } while(size_read > 0); - - close(orig_file); - close(dest_file); - - printf("Finished copying %ld bytes from", size); - printf("FWIMG01.DAT.ORIG to FWIMG01.DAT"); - - return(0); -} - -char buf[256]; - -void display_instructions(void) -{ - lcd_setfont(FONT_SYSFIXED); - printf("Hold MENU when booting for rescue mode."); - printf(" \"VOL+\" button to restore original kernel"); - printf(" \"A\" button to load original firmware"); - printf(""); - printf("FRAME %x TTB %x", FRAME, TTB_BASE); -} - -void * main(void) -{ - int i; - struct partinfo* pinfo; - unsigned short* identify_info; unsigned char* loadbuffer; int buffer_size; - bool load_original = false; int rc; int(*kernel_entry)(void); - bool show_bootsplash = true; - - if(GPGDAT & 2) - show_bootsplash = false; + memory_init(); + power_init(); + system_init(); + lcd_init(); + backlight_init(); + font_init(); - if(!show_bootsplash) { - lcd_init(); - display_instructions(); - sleep(2*HZ); - } - if(GPGDAT & 2) { - lcd_init(); - printf("Entering rescue mode.."); - go_usb_mode(); - while(1); - } - if(GPGDAT & 0x10) { - lcd_init(); - load_original = true; - printf("Loading original firmware..."); - } - - i = ata_init(); - i = disk_mount_all(); - if(!show_bootsplash) { - printf("disk_mount_all: %d", i); - } - if(show_bootsplash) { - int fd = open("/bootsplash.raw", O_RDONLY); - if(fd < 0) { - show_bootsplash = false; - lcd_init(); - display_instructions(); - } - else { - read(fd, lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT*2); - close(fd); - lcd_update(); - lcd_init(); - } - } - /* hold VOL+ to enter rescue mode to copy old image */ - /* needs to be after ata_init and disk_mount_all */ - if(GPGDAT & 4) { - - /* Try to restore the original kernel/bootloader if a copy is found */ - printf("Restoring FWIMG01.DAT..."); - - if(!restore_fwimg01dat()) { - printf("Restoring FWIMG01.DAT successful."); - } else { - printf("Restoring FWIMG01.DAT failed."); - } - - printf("Now power cycle to boot original"); - while(1); - } - - if(!show_bootsplash) { - identify_info = ata_get_identify(); - - for(i=0; i < 20; i++) - ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]); - - buf[40]=0; + lcd_setfont(FONT_SYSFIXED); - /* kill trailing space */ - for(i=39; i && buf[i]==' '; i--) - buf[i] = 0; + usb_init(); - printf("Model"); - printf(buf); + /* Enter USB mode without USB thread */ + if(usb_detect()) + { + const char msg[] = "Bootloader USB mode"; + reset_screen(); + lcd_putsxy( (LCD_WIDTH - (SYSFONT_WIDTH * strlen(msg))) / 2, + (LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg); + lcd_update(); - for(i=0; i < 4; i++) - ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]); + ata_enable(false); + sleep(HZ/20); + usb_enable(true); - buf[8]=0; + while (usb_detect()) + sleep(HZ); - printf("Firmware"); - printf(buf); + usb_enable(false); - pinfo = disk_partinfo(0); - printf("Partition 0: 0x%02x %ld MB", pinfo->type, pinfo->size / 2048); + reset_screen(); + lcd_update(); + } + + kernel_init(); + adc_init(); + button_init(); + + /* Show debug messages if button is pressed */ + if(button_read_device()) + verbose = true; + + printf("Rockbox boot loader"); + printf("Version %s", version); + + rc = ata_init(); + if(rc) + { + reset_screen(); + error(EATA, rc); } - /* Load original firmware */ - if(load_original) { - loadbuffer = (unsigned char*)0x30008000; - buffer_size =(unsigned char*)0x31000000 - loadbuffer; - rc = load_raw_firmware(loadbuffer, "/rockbox.gigabeat", buffer_size); - if(rc < EOK) { - printf("Error!"); - printf("Failed to load original firmware:"); - printf(strerror(rc)); - printf("Loading rockbox"); - sleep(2*HZ); - goto load_rockbox; - } - - printf("Loaded: %d", rc); - sleep(2*HZ); - (*((int*)0x7000000)) = 333; - rc = *((int*)0x7000000+0x8000000); - printf("Bank0 mem test: %d", rc); - sleep(3*HZ); + disk_init(); - printf("Woops, should not return from firmware!"); - goto usb; + rc = disk_mount_all(); + if (rc<=0) + { + error(EDISK,rc); } -load_rockbox: - map_memory(); - if(!show_bootsplash) { - printf("Loading Rockbox..."); - } + printf("Loading firmware"); loadbuffer = (unsigned char*) 0x100; buffer_size = (unsigned char*)0x400000 - loadbuffer; - rc = load_raw_firmware(loadbuffer, "/.rockbox/rockbox.gigabeat", buffer_size); - if(rc < EOK) { - rc = load_raw_firmware(loadbuffer, "/rockbox.gigabeat", buffer_size); - } - if(rc < EOK) { - printf("Error!"); - printf("Can't load rockbox.gigabeat:"); - printf(strerror(rc)); - } else { - if(!show_bootsplash) { - printf("Rockbox loaded."); - } + + rc = load_firmware(loadbuffer, BOOTFILE, buffer_size); + if(rc < 0) + error(EBOOTFILE, rc); + + if (rc == EOK) + { kernel_entry = (void*) loadbuffer; rc = kernel_entry(); - printf("Woops, should not return from firmware: %d", rc); - goto usb; } -usb: - /* now wait in USB mode so the bootloader can be updated */ - go_usb_mode(); - while(1); - - return((void *)0); } -- cgit v1.2.3