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 --- apps/debug_menu.c | 43 +++- apps/main.c | 6 +- bootloader/common.c | 2 +- bootloader/gigabeat.c | 278 +++++---------------- firmware/export/config-gigabeat.h | 2 +- .../target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c | 4 +- .../target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c | 17 ++ .../target/arm/s3c2440/gigabeat-fx/mmu-meg-fx.c | 17 +- .../target/arm/s3c2440/gigabeat-fx/mmu-meg-fx.h | 2 +- .../target/arm/s3c2440/gigabeat-fx/system-meg-fx.c | 2 + .../target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c | 2 +- tools/configure | 2 +- tools/scramble.c | 2 + 13 files changed, 150 insertions(+), 229 deletions(-) diff --git a/apps/debug_menu.c b/apps/debug_menu.c index 12d5f435b7..9f827e7b7b 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c @@ -88,6 +88,10 @@ #endif #include "hwcompat.h" +#if CONFIG_CPU == S3C2440 +#include "s3c2440.h" +#endif + #ifndef SIMULATOR static bool dbg_list(char *title, int count, int selection_size, int (*action_callback)(int btn, struct gui_synclist *lists), @@ -1129,6 +1133,43 @@ bool dbg_ports(void) snprintf(buf, sizeof(buf), "GPIO_C: %02x GPIO_D: %02x", gpio_c, gpio_d); lcd_puts(0, line++, buf); + lcd_update(); + if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL)) + return false; + } +#elif CONFIG_CPU == S3C2440 + char buf[128]; + int line, fd; + + lcd_setmargins(0, 0); + lcd_clear_display(); + lcd_setfont(FONT_SYSFIXED); + + while(1) + { + line = 0; + snprintf(buf, sizeof(buf), "GPACON: %08x GPBCON: %08x", GPACON, GPBCON); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPADAT: %08x GPBDAT: %08x", GPADAT, GPBDAT); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPAUP: %08x GPBUP: %08x", 0, GPBUP); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf); + + snprintf(buf, sizeof(buf), "GPCCON: %08x GPDCON: %08x", GPCCON, GPDCON); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPCDAT: %08x GPDDAT: %08x", GPCDAT, GPDDAT); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPCUP: %08x GPDUP: %08x", GPCUP, GPDUP); lcd_puts(0, line++, buf); + + snprintf(buf, sizeof(buf), "GPECON: %08x GPFCON: %08x", GPECON, GPFCON); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPEDAT: %08x GPFDAT: %08x", GPEDAT, GPFDAT); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPEUP: %08x GPFUP: %08x", GPEUP, GPFUP); lcd_puts(0, line++, buf); + + snprintf(buf, sizeof(buf), "GPGCON: %08x GPHCON: %08x", GPGCON, GPHCON); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPGDAT: %08x GPHDAT: %08x", GPGDAT, GPHDAT); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPGUP: %08x GPHUP: %08x", GPGUP, GPHUP); lcd_puts(0, line++, buf); + + snprintf(buf, sizeof(buf), "GPJCON: %08x", GPJCON); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPJDAT: %08x", GPJDAT); lcd_puts(0, line++, buf); + snprintf(buf, sizeof(buf), "GPJUP: %08x", GPJUP); lcd_puts(0, line++, buf); lcd_update(); if (button_get_w_tmo(HZ/10) == (DEBUG_CANCEL|BUTTON_REL)) return false; @@ -2271,7 +2312,7 @@ bool debug_menu(void) (defined(CPU_PP) && !defined(SANSA_E200)) { "Dump ROM contents", dbg_save_roms }, #endif -#if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) +#if CONFIG_CPU == SH7034 || defined(CPU_COLDFIRE) || defined(CPU_PP) || CONFIG_CPU == S3C2440 { "View I/O ports", dbg_ports }, #endif #ifdef HAVE_ADJUSTABLE_CPU_FREQ diff --git a/apps/main.c b/apps/main.c index ab7f9f39b4..31bf32c714 100644 --- a/apps/main.c +++ b/apps/main.c @@ -336,12 +336,8 @@ static void init(void) lcd_remote_init(); #endif font_init(); - -#if !defined(TOSHIBA_GIGABEAT_F) || defined(SIMULATOR) + show_logo(); -#else - sleep(1); /* Weird. We crash w/o this tiny delay. */ -#endif lang_init(); #ifdef DEBUG diff --git a/bootloader/common.c b/bootloader/common.c index 51b751cbf9..1ac8e8f7e3 100644 --- a/bootloader/common.c +++ b/bootloader/common.c @@ -31,7 +31,7 @@ /* TODO: Other bootloaders need to be adjusted to set this variable to true 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) + defined(SANSA_E200) || defined(GIGABEAT_F) bool verbose = false; #else bool verbose = true; 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); } diff --git a/firmware/export/config-gigabeat.h b/firmware/export/config-gigabeat.h index ef6d8243b8..6a6e1d2977 100644 --- a/firmware/export/config-gigabeat.h +++ b/firmware/export/config-gigabeat.h @@ -6,7 +6,7 @@ #define TOSHIBA_GIGABEAT_F 1 /* For Rolo and boot loader */ -#define MODEL_NUMBER 1 +#define MODEL_NUMBER 18 /* define this if you have a bitmap LCD display */ #define HAVE_LCD_BITMAP diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c index bc2b53d776..34fbc2b2ac 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/ata-meg-fx.c @@ -52,8 +52,8 @@ void ata_enable(bool on) else USB_ATA_ENABLE; - GPBCON=( GPGCON&~(1<<11) ) | (1<<10); /* Make the pin an output */ -// GPBUP|=1<<5; /* Disable pullup in SOC as we are now driving */ + GPBCON=( GPBCON&~(1<<11) ) | (1<<10); /* Make the pin an output */ + GPBUP|=1<<5; /* Disable pullup in SOC as we are now driving */ } bool ata_is_coldstart(void) diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c index 1bb68f9686..11edcfecb1 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/lcd-meg-fx.c @@ -53,6 +53,23 @@ unsigned int LCDBASEL(unsigned int address) /* LCD init */ void lcd_init_device(void) { +#ifdef BOOTLOADER + /* When the Rockbox bootloader starts, we are changing framebuffer address, + but we don't want what's shown on the LCD to change until we do an + lcd_update(), so copy the data from the old framebuffer to the new one */ + int i; + unsigned short *buf = (unsigned short*)FRAME; + + memcpy(FRAME, (short *)((LCDSADDR1)<<1), 320*240*2); + + /* The Rockbox bootloader is transitioning from RGB555I to RGB565 mode + so convert the frambuffer data accordingly */ + for(i=0; i< 320*240; i++){ + *buf = ((*buf>>1) & 0x1F) | (*buf & 0xffc0); + buf++; + } +#endif + LCDSADDR1 = (LCDBANK((unsigned)FRAME) << 21) | (LCDBASEU((unsigned)FRAME)); LCDSADDR2 = LCDBASEL((unsigned)FRAME); LCDSADDR3 = 0x000000F0; diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/mmu-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/mmu-meg-fx.c index 6142213f0c..c47c1330bc 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/mmu-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/mmu-meg-fx.c @@ -3,7 +3,6 @@ #include "mmu-meg-fx.h" #include "panic.h" -void map_memory(void); static void enable_mmu(void); static void set_ttb(void); static void set_page_tables(void); @@ -15,7 +14,7 @@ static void map_section(unsigned int pa, unsigned int va, int mb, int cache_flag #define BUFFERED (1 << 2) #define MB (1 << 20) -void map_memory(void) { +void memory_init(void) { set_ttb(); set_page_tables(); enable_mmu(); @@ -69,6 +68,20 @@ void map_section(unsigned int pa, unsigned int va, int mb, int cache_flags) { } static void enable_mmu(void) { + int regread; + + asm volatile( + "MRC p15, 0, %r0, c1, c0, 0\n" /* Read reg1, control register */ + : /* outputs */ + "=r"(regread) + : /* inputs */ + : /* clobbers */ + "r0" + ); + + if ( !(regread & 0x04) || !(regread & 0x00001000) ) /* Was the ICache or DCache Enabled? */ + clean_dcache(); /* If so we need to clean the DCache before invalidating below */ + asm volatile("mov r0, #0\n" "mcr p15, 0, r0, c8, c7, 0\n" /* invalidate TLB */ diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/mmu-meg-fx.h b/firmware/target/arm/s3c2440/gigabeat-fx/mmu-meg-fx.h index 71b1b83801..524978852d 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/mmu-meg-fx.h +++ b/firmware/target/arm/s3c2440/gigabeat-fx/mmu-meg-fx.h @@ -32,4 +32,4 @@ void dump_dcache_range(const void *base, unsigned int size); /* Cleans entire DCache */ void clean_dcache(void); - +void memory_init(void); diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c index b7e59e66ea..6c5e35f0d5 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/system-meg-fx.c @@ -1,6 +1,7 @@ #include "kernel.h" #include "system.h" #include "panic.h" +#include "mmu-meg-fx.h" #include "lcd.h" #include @@ -11,6 +12,7 @@ const int DMA0_MASK = (1 << 17); const int DMA1_MASK = (1 << 18); const int DMA2_MASK = (1 << 19); const int DMA3_MASK = (1 << 20); +const int ALARM_MASK = (1 << 30); int system_memory_guard(int newmode) { diff --git a/firmware/target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c b/firmware/target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c index 3aed8c3256..af66e2a60c 100644 --- a/firmware/target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c +++ b/firmware/target/arm/s3c2440/gigabeat-fx/usb-meg-fx.c @@ -44,7 +44,7 @@ inline bool usb_detect(void) void usb_init_device(void) { /* Input is the default configuration, only pullups need to be disabled */ - GPFUP|=0x02; +/* GPFUP|=0x02; */ USB_VPLUS_PWR_ASSERT; GPBCON=( GPBCON&~(1<<13) ) | (1 << 12); diff --git a/tools/configure b/tools/configure index 2f79755335..a507fdd31a 100755 --- a/tools/configure +++ b/tools/configure @@ -1048,7 +1048,7 @@ EOF target="-DGIGABEAT_F" memory=32 # always arm9tdmicc - tool="cp" + tool="$rootdir/tools/scramble -add=giga" bmp2rb_mono="$rootdir/tools/bmp2rb -f 0" bmp2rb_native="$rootdir/tools/bmp2rb -f 4" output="rockbox.gigabeat" diff --git a/tools/scramble.c b/tools/scramble.c index 9a64a5aeed..531728379d 100644 --- a/tools/scramble.c +++ b/tools/scramble.c @@ -224,6 +224,8 @@ int main (int argc, char** argv) modelnum = 16; else if(!strcmp(&argv[1][5], "iam5")) modelnum = 17; + else if(!strcmp(&argv[1][5], "giga")) + modelnum = 18; else { fprintf(stderr, "unsupported model: %s\n", &argv[1][5]); return 2; -- cgit v1.2.3