Prepare core support for the iriver bootloader supporting ROM images

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11991 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Miika Pekkarinen 2007-01-12 18:34:00 +00:00
parent 12ef310466
commit 0ea4d3197e
9 changed files with 180 additions and 56 deletions

View file

@ -487,6 +487,13 @@ static const struct plugin_api rockbox_api = {
pcm_record_more,
#endif
create_thread_on_core,
#ifdef IRIVER_H100_SERIES
/* Routines for the iriver_flash -plugin. */
detect_original_firmware,
detect_flashed_ramimage,
detect_flashed_romimage,
#endif
};
int plugin_load(const char* plugin, void* parameter)

View file

@ -602,11 +602,18 @@ struct plugin_api {
int (*sound_default)(int setting);
void (*pcm_record_more)(void *start, size_t size);
#endif
struct thread_entry*(*create_thread_on_core)(
unsigned int core, void (*function)(void),
void* stack, int stack_size,
const char *name IF_PRIO(, int priority));
#ifdef IRIVER_H100_SERIES
/* Routines for the iriver_flash -plugin. */
bool (*detect_original_firmware)(void);
bool (*detect_flashed_ramimage)(void);
bool (*detect_flashed_romimage)(void);
#endif
};
/* plugin header */

View file

@ -59,6 +59,10 @@ static struct plugin_api* rb; /* here is a global api struct pointer */
#ifdef IRIVER_H100_SERIES
#define SEC_SIZE 4096
#define BOOTLOADER_ERASEGUARD (BOOTLOADER_ENTRYPOINT / SEC_SIZE)
enum sections {
SECT_RAMIMAGE = 1,
SECT_ROMIMAGE = 2,
};
static volatile uint16_t* FB = (uint16_t*)0x00000000; /* Flash base address */
#endif
@ -338,23 +342,9 @@ int load_firmware_file(const char *filename, uint32_t *checksum)
return len;
}
bool detect_flashed_rockbox(void)
{
struct flash_header hdr;
uint8_t *src = (uint8_t *)FLASH_ENTRYPOINT;
rb->memcpy(&hdr, src, sizeof(struct flash_header));
if (hdr.magic != FLASH_MAGIC)
return false;
return true;
}
unsigned long valid_bootloaders[][2] = {
/* Size-8 CRC32 */
{ 62332, 0x77395351 }, /* Pre-release v7 */
{ 63340, 0xc41857b6 }, /* Pre-release v7, fixed crash unless firmware found. */
{ 63844, 0x98c5027a }, /* 7-pre3, improved failsafe functions */
{ 0, 0 }
};
@ -378,15 +368,28 @@ bool detect_valid_bootloader(const unsigned char *addr, int len)
return false;
}
int flash_rockbox(const char *filename)
static int get_section_address(int section)
{
if (section == SECT_RAMIMAGE)
return FLASH_RAMIMAGE_ENTRY;
else if (section == SECT_ROMIMAGE)
return FLASH_ROMIMAGE_ENTRY;
else
return -1;
}
int flash_rockbox(const char *filename, int section)
{
struct flash_header hdr;
char buf[32];
char buf[64];
int pos, i, len, rc;
unsigned long checksum, sum;
unsigned char *p8;
uint16_t *p16;
if (get_section_address(section) < 0)
return -1;
p8 = (char *)BOOTLOADER_ENTRYPOINT;
if (!detect_valid_bootloader(p8, 0))
{
@ -394,7 +397,7 @@ int flash_rockbox(const char *filename)
return -1;
}
if (detect_flashed_rockbox())
if (!rb->detect_original_firmware())
{
if (!confirm("Update Rockbox flash image?"))
return -2;
@ -409,13 +412,36 @@ int flash_rockbox(const char *filename)
if (len <= 0)
return len * 10;
/* Erase the program flash. */
for (i = 1; i < BOOTLOADER_ERASEGUARD && (i-1)*4096 < len + 32; i++)
pos = get_section_address(section);
/* Check if image relocation seems to be sane. */
if (section == SECT_ROMIMAGE)
{
rc = cfi_erase_sector(FB + (SEC_SIZE/2) * i);
rb->snprintf(buf, sizeof(buf), "Erase: 0x%03x (%d)", i, rc);
uint32_t *p32 = (uint32_t *)audiobuf;
if (pos+sizeof(struct flash_header) != *p32)
{
rb->snprintf(buf, sizeof(buf), "Incorrect relocation: 0x%08x/0x%08x",
*p32, pos+sizeof(struct flash_header));
rb->splash(HZ*10, true, buf);
return -1;
}
}
/* Erase the program flash. */
for (i = 0; i + pos < BOOTLOADER_ENTRYPOINT && i < len + 32; i += SEC_SIZE)
{
/* Additional safety check. */
if (i + pos < SEC_SIZE)
return -1;
rb->snprintf(buf, sizeof(buf), "Erasing... %d%%",
(i+SEC_SIZE)*100/len);
rb->lcd_puts(0, 3, buf);
rb->lcd_update();
rc = cfi_erase_sector(FB + (i + pos)/2);
}
/* Write the magic and size. */
@ -425,11 +451,11 @@ int flash_rockbox(const char *filename)
// rb->strncpy(hdr.version, APPSVERSION, sizeof(hdr.version)-1);
p16 = (uint16_t *)&hdr;
rb->snprintf(buf, sizeof(buf), "Programming");
rb->snprintf(buf, sizeof(buf), "Programming...");
rb->lcd_puts(0, 4, buf);
rb->lcd_update();
pos = FLASH_ENTRYPOINT/2;
pos = get_section_address(section)/2;
for (i = 0; i < (long)sizeof(struct flash_header)/2; i++)
{
cfi_program_word(FB + pos, p16[i]);
@ -438,14 +464,24 @@ int flash_rockbox(const char *filename)
p16 = (uint16_t *)audiobuf;
for (i = 0; i < len/2 && pos + i < (BOOTLOADER_ENTRYPOINT/2); i++)
{
if (i % SEC_SIZE == 0)
{
rb->snprintf(buf, sizeof(buf), "Programming... %d%%",
(i+1)*100/(len/2));
rb->lcd_puts(0, 4, buf);
rb->lcd_update();
}
cfi_program_word(FB + pos + i, p16[i]);
}
/* Verify */
rb->snprintf(buf, sizeof(buf), "Verifying");
rb->lcd_puts(0, 5, buf);
rb->lcd_update();
p8 = (char *)FLASH_ENTRYPOINT;
p8 = (char *)get_section_address(section);
p8 += sizeof(struct flash_header);
sum = 0;
for (i = 0; i < len; i++)
@ -456,7 +492,10 @@ int flash_rockbox(const char *filename)
rb->splash(HZ*3, true, "Verify failed!");
/* Erase the magic sector so bootloader does not try to load
* rockbox from flash and crash. */
cfi_erase_sector(FB + SEC_SIZE/2);
if (section == SECT_RAMIMAGE)
cfi_erase_sector(FB + FLASH_RAMIMAGE_ENTRY/2);
else
cfi_erase_sector(FB + FLASH_ROMIMAGE_ENTRY/2);
return -5;
}
@ -741,7 +780,9 @@ void DoUserDialog(char* filename)
audiobuf = rb->plugin_get_audio_buffer(&audiobuf_size);
if (rb->strcasestr(filename, "/rockbox.iriver"))
flash_rockbox(filename);
flash_rockbox(filename, SECT_RAMIMAGE);
else if (rb->strcasestr(filename, "/rombox.iriver"))
flash_rockbox(filename, SECT_ROMIMAGE);
else if (rb->strcasestr(filename, "/bootloader.iriver"))
flash_bootloader(filename);
else if (rb->strcasestr(filename, "/ihp_120.bin"))

View file

@ -36,7 +36,7 @@ static bool reset_config(void)
#else
firmware_settings.version = EEPROM_SETTINGS_VERSION;
firmware_settings.initialized = true;
firmware_settings.boot_disk = false;
firmware_settings.bootmethod = BOOT_RECOVERY;
firmware_settings.bl_version = 0;
#endif
@ -51,7 +51,7 @@ bool eeprom_settings_init(void)
eeprom_24cxx_init();
/* Check if player has been flashed. */
if (!detect_flashed_rockbox())
if (detect_original_firmware())
{
memset(&firmware_settings, 0, sizeof(struct eeprom_settings));
firmware_settings.initialized = false;
@ -61,7 +61,7 @@ bool eeprom_settings_init(void)
ret = eeprom_24cxx_read(0, &firmware_settings,
sizeof(struct eeprom_settings));
if (ret < 0)
{
memset(&firmware_settings, 0, sizeof(struct eeprom_settings));
@ -101,7 +101,7 @@ bool eeprom_settings_store(void)
int ret;
uint32_t sum;
if (!firmware_settings.initialized || !detect_flashed_rockbox())
if (!firmware_settings.initialized || detect_original_firmware())
{
logf("Rockbox in flash is required");
return false;

View file

@ -139,8 +139,9 @@
#define BOOTFILE "rockbox." BOOTFILE_EXT
#define BOOTLOADER_ENTRYPOINT 0x001F0000
#define FLASH_ENTRYPOINT 0x00001000
#define FLASH_MAGIC 0xfbfbfbf1
#define FLASH_RAMIMAGE_ENTRY 0x00001000
#define FLASH_ROMIMAGE_ENTRY 0x00100000
#define FLASH_MAGIC 0xfbfbfbf2
/* Define this if there is an EEPROM chip */
#define HAVE_EEPROM

View file

@ -23,17 +23,26 @@
#include <stdbool.h>
#include "inttypes.h"
#define EEPROM_SETTINGS_VERSION 0x24c01001
#define EEPROM_SETTINGS_VERSION 0x24c01002
#define EEPROM_SETTINGS_BL_MINVER 7
enum boot_methods {
BOOT_DISK = 0,
BOOT_RAM,
BOOT_ROM,
BOOT_RECOVERY,
};
struct eeprom_settings
{
long version; /* Settings version number */
bool initialized; /* Is eeprom_settings ready to be used */
bool disk_clean; /* Is disk intact from last reboot */
bool boot_disk; /* Load firmware from disk (default=FLASH) */
uint8_t bootmethod; /* The default boot method. */
uint8_t bl_version; /* Installed bootloader version */
long reserved; /* A few reserved bits for the future. */
/* This must be the last entry */
uint32_t checksum; /* Checksum of this structure */
};

View file

@ -52,7 +52,9 @@ struct flash_header {
char version[32];
};
bool detect_flashed_rockbox(void);
bool detect_flashed_romimage(void);
bool detect_flashed_ramimage(void);
bool detect_original_firmware(void);
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
#define FREQ cpu_frequency

View file

@ -82,31 +82,44 @@ void cpu_idle_mode(bool on_off)
#endif /* HAVE_ADJUSTABLE_CPU_FREQ */
bool detect_flashed_rockbox(void)
{
#ifdef HAVE_FLASHED_ROCKBOX
struct flash_header hdr;
uint8_t *src = (uint8_t *)FLASH_ENTRYPOINT;
static bool detect_flash_header(uint8_t *addr)
{
#ifndef BOOTLOADER
int oldmode = system_memory_guard(MEMGUARD_NONE);
#endif
memcpy(&hdr, src, sizeof(struct flash_header));
struct flash_header hdr;
memcpy(&hdr, addr, sizeof(struct flash_header));
#ifndef BOOTLOADER
system_memory_guard(oldmode);
#endif
return hdr.magic == FLASH_MAGIC;
}
#endif
if (hdr.magic != FLASH_MAGIC)
return false;
return true;
bool detect_flashed_romimage(void)
{
#ifdef HAVE_FLASHED_ROCKBOX
return detect_flash_header((uint8_t *)FLASH_ROMIMAGE_ENTRY);
#else
return false;
#endif /* HAVE_FLASHED_ROCKBOX */
}
bool detect_flashed_ramimage(void)
{
#ifdef HAVE_FLASHED_ROCKBOX
return detect_flash_header((uint8_t *)FLASH_RAMIMAGE_ENTRY);
#else
return false;
#endif /* HAVE_FLASHED_ROCKBOX */
}
bool detect_original_firmware(void)
{
return !(detect_flashed_ramimage() || detect_flashed_romimage());
}
#if CONFIG_CPU == SH7034
#include "led.h"
#include "system.h"

View file

@ -89,28 +89,40 @@ start:
#endif
#ifdef BOOTLOADER
/* Check if original firmware is still present */
/* Check if we have a Rockbox ROM image */
lea 0x00100000,%a2
move.l (%a2),%d0
move.l #FLASH_MAGIC,%d1
cmp.l %d0,%d1
beq.b .imagefound
/* Check for RAM image */
lea 0x00001000,%a2
move.l (%a2),%d0
move.l #0xfbfbfbf1,%d1
move.l #FLASH_MAGIC,%d1
cmp.l %d0,%d1
beq.b .ignorecookie
beq.b .imagefound
/* The cookie is not reset. This must mean that the boot loader
has crashed. Let's start the original firmware immediately. */
/* Not either ROM or RAM image was found, so original firmware
should be still present. */
/* Check if the cookie is present. */
lea 0x10017ffc,%a2
move.l (%a2),%d0
move.l #0xc0015a17,%d1
cmp.l %d0,%d1
bne.b .nocookie
/* Clear the cookie again */
/* The cookie is not reset. This must mean that the boot loader
has crashed. Let's start the original firmware immediately. */
lea 0x10017ffc,%a2
clr.l (%a2)
jmp 8
.nocookie:
/* Set the cookie */
move.l %d1,(%a2)
.ignorecookie:
.imagefound:
/* Set up the DRAM controller. The refresh is based on the 11.2896MHz
clock (5.6448MHz bus frequency). We haven't yet started the PLL */
@ -168,6 +180,38 @@ start:
move.l %d0,0x31000800 /* A12=1 means CASL=1 (a0 is not connected) */
/* DACR0[IMRS] gets deactivated by the SDRAM controller */
/* Check if we have a Rockbox ROM image. For RAM image only cookie is
not set at all. But we could support also RAM images loading. */
lea 0x00100000,%a2
move.l (%a2),%d0
move.l #FLASH_MAGIC,%d1
cmp.l %d0,%d1
bne.b .noromimage
/* Check again if the cookie is present. */
lea 0x10017ffc,%a2
move.l (%a2),%d0
move.l #0xc0015a17,%d1
cmp.l %d0,%d1
bne.b .nocookie2
/* We have found Rockbox in ROM!
Clear the cookie and load the ROM image */
lea 0x10017ffc,%a2
clr.l (%a2)
lea 0x00100028+4,%a2
move.l (%a2),%sp
lea 0x00100028+8,%a2
move.l (%a2),%d0
move.l %d0,%a2
jmp (%a2)
.nocookie2:
/* Set the cookie */
move.l %d1,(%a2)
.noromimage:
#endif /* BOOTLOADER */
/* Invalicate cache */