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
This commit is contained in:
Karl Kurbjun 2007-04-21 04:48:20 +00:00
parent dd0f1c7db1
commit 8a1fd8c686
13 changed files with 154 additions and 233 deletions

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -20,7 +20,8 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#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 <stdarg.h>
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;
memory_init();
power_init();
system_init();
lcd_init();
backlight_init();
font_init();
if(GPGDAT & 2)
show_bootsplash = false;
lcd_setfont(FONT_SYSFIXED);
if(!show_bootsplash) {
lcd_init();
display_instructions();
sleep(2*HZ);
usb_init();
/* 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();
ata_enable(false);
sleep(HZ/20);
usb_enable(true);
while (usb_detect())
sleep(HZ);
usb_enable(false);
reset_screen();
lcd_update();
}
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...");
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);
}
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) {
disk_init();
/* 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);
rc = disk_mount_all();
if (rc<=0)
{
error(EDISK,rc);
}
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;
/* kill trailing space */
for(i=39; i && buf[i]==' '; i--)
buf[i] = 0;
printf("Model");
printf(buf);
for(i=0; i < 4; i++)
((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
buf[8]=0;
printf("Firmware");
printf(buf);
pinfo = disk_partinfo(0);
printf("Partition 0: 0x%02x %ld MB", pinfo->type, pinfo->size / 2048);
}
/* 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);
printf("Woops, should not return from firmware!");
goto usb;
}
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);
}

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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 */

View File

@ -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);

View File

@ -1,6 +1,7 @@
#include "kernel.h"
#include "system.h"
#include "panic.h"
#include "mmu-meg-fx.h"
#include "lcd.h"
#include <stdio.h>
@ -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)
{

View File

@ -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);

2
tools/configure vendored
View File

@ -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"

View File

@ -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;