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:
parent
12ef310466
commit
0ea4d3197e
9 changed files with 180 additions and 56 deletions
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue