summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiika Pekkarinen <miipekk@ihme.org>2006-08-05 20:19:10 +0000
committerMiika Pekkarinen <miipekk@ihme.org>2006-08-05 20:19:10 +0000
commit954b73265404075ec4d379ddea14e626113a8677 (patch)
tree5c6ff0056ebd118aadb896856e7679a41c595cba
parent85ba65d2a3fa3d10799efadbe3a33f026bf354df (diff)
downloadrockbox-954b73265404075ec4d379ddea14e626113a8677.zip
rockbox-954b73265404075ec4d379ddea14e626113a8677.tar.gz
rockbox-954b73265404075ec4d379ddea14e626113a8677.tar.bz2
rockbox-954b73265404075ec4d379ddea14e626113a8677.tar.xz
Initial support and use for EEPROM memory on H120 & H140 players when
Rockbox firmware has been flashed over original firmware (not yet possible to do). Dircache & tagcache serialization for fast bootup without the need to scan disk when Rockbox is in flash. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10464 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/debug_menu.c18
-rw-r--r--apps/main.c46
-rw-r--r--apps/misc.c25
-rw-r--r--apps/tagcache.c109
-rw-r--r--apps/tagcache.h2
-rw-r--r--apps/tree.c9
-rw-r--r--firmware/SOURCES4
-rw-r--r--firmware/common/crc32.c4
-rw-r--r--firmware/common/dircache.c32
-rw-r--r--firmware/drivers/eeprom_24cxx.c6
-rw-r--r--firmware/eeprom_settings.c116
-rw-r--r--firmware/export/config-h100.h6
-rw-r--r--firmware/export/config-h120.h10
-rw-r--r--firmware/export/eeprom_settings.h48
-rw-r--r--firmware/export/system.h8
-rw-r--r--firmware/include/crc32.h2
-rw-r--r--firmware/powermgmt.c4
-rw-r--r--firmware/system.c21
18 files changed, 422 insertions, 48 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index 724bab9..ce3140b 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -53,6 +53,8 @@
#include "tagcache.h"
#include "lcd-remote.h"
#include "crc32.h"
+#include "eeprom_24cxx.h"
+#include "logf.h"
#ifdef HAVE_LCD_BITMAP
#include "widgets.h"
@@ -1952,6 +1954,22 @@ bool dbg_save_roms(void)
close(fd);
}
system_memory_guard(oldmode);
+
+#ifdef HAVE_EEPROM
+ fd = creat("/internal_eeprom.bin", O_WRONLY);
+ if (fd >= 0)
+ {
+ char buf[EEPROM_SIZE];
+
+ if (!eeprom_24cxx_read(0, buf, sizeof buf))
+ gui_syncsplash(HZ*3, true, "Eeprom read failure!");
+ else
+ write(fd, buf, sizeof buf);
+
+ close(fd);
+ }
+#endif
+
return false;
}
#endif /* CPU */
diff --git a/apps/main.c b/apps/main.c
index b725d02..907e112 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -65,6 +65,7 @@
#include "lang.h"
#include "string.h"
#include "splash.h"
+#include "eeprom_settings.h"
#if (CONFIG_CODEC == SWCODEC)
#include "playback.h"
@@ -108,35 +109,30 @@ void app_main(void)
browse_root();
}
-#ifdef HAVE_DIRCACHE
-void init_dircache(void)
+int init_dircache(void)
{
- int result;
- bool clear = false;
+#ifdef HAVE_DIRCACHE
+ int result = 0;
dircache_init();
if (global_settings.dircache)
{
- if (global_settings.dircache_size == 0)
+# ifdef HAVE_EEPROM
+ if (firmware_settings.initialized && firmware_settings.disk_clean)
{
- gui_syncsplash(0, true, str(LANG_DIRCACHE_BUILDING));
- clear = true;
+ if (dircache_load(DIRCACHE_FILE) == 0)
+ return 0;
}
+# endif
result = dircache_build(global_settings.dircache_size);
- if (result < 0)
- gui_syncsplash(0, true, "Failed! Result: %d", result);
-
- if (clear)
- {
- backlight_on();
- show_logo();
- }
}
-}
+
+ return result;
#else
-# define init_dircache(...)
+ return 0;
#endif
+}
void init_tagcache(void)
{
@@ -376,6 +372,10 @@ void init(void)
}
}
+#ifdef HAVE_EEPROM
+ eeprom_settings_init();
+#endif
+
settings_calc_config_sector();
#if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD)
@@ -395,11 +395,21 @@ void init(void)
settings_load(SETTINGS_ALL);
+ init_dircache();
+
gui_sync_wps_init();
settings_apply();
- init_dircache();
+ //init_dircache();
init_tagcache();
+#ifdef HAVE_EEPROM
+ if (firmware_settings.initialized)
+ {
+ /* In case we crash. */
+ firmware_settings.disk_clean = false;
+ eeprom_settings_store();
+ }
+#endif
status_init();
playlist_init();
tree_init();
diff --git a/apps/misc.c b/apps/misc.c
index ff05819..b0c315a 100644
--- a/apps/misc.c
+++ b/apps/misc.c
@@ -49,6 +49,7 @@
#include "ata_mmc.h"
#endif
#include "tree.h"
+#include "eeprom_settings.h"
#ifdef HAVE_LCD_BITMAP
#include "bmp.h"
@@ -484,13 +485,6 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter)
#else
int i;
- if (tagcache_get_commit_step() > 0)
- {
- cancel_shutdown();
- gui_syncsplash(HZ, true, str(LANG_TAGCACHE_BUSY));
- return false;
- }
-
#if defined(CONFIG_CHARGING) && !defined(HAVE_POWEROFF_WHILE_CHARGING)
if(!charger_inserted())
#endif
@@ -498,11 +492,26 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter)
FOR_NB_SCREENS(i)
screens[i].clear_display();
gui_syncsplash(0, true, str(LANG_SHUTTINGDOWN));
+
+ if (!tagcache_prepare_shutdown())
+ {
+ cancel_shutdown();
+ gui_syncsplash(HZ, true, str(LANG_TAGCACHE_BUSY));
+ return false;
+ }
+
if (callback != NULL)
callback(parameter);
system_flush();
-
+#ifdef HAVE_EEPROM
+ if (firmware_settings.initialized)
+ {
+ firmware_settings.disk_clean = true;
+ firmware_settings.bl_version = 0;
+ eeprom_settings_store();
+ }
+#endif
shutdown_hw();
}
#endif
diff --git a/apps/tagcache.c b/apps/tagcache.c
index 1485ed8..4812198 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -70,6 +70,7 @@
#include "buffer.h"
#include "atoi.h"
#include "crc32.h"
+#include "eeprom_settings.h"
/* Tag Cache thread. */
static struct event_queue tagcache_queue;
@@ -152,6 +153,13 @@ struct ramcache_header {
int entry_count[TAG_COUNT]; /* Number of entries in the indices. */
};
+# ifdef HAVE_EEPROM
+struct statefile_header {
+ struct ramcache_header *hdr;
+ struct tagcache_stat stat;
+};
+# endif
+
/* Pointer to allocated ramcache_header */
static struct ramcache_header *hdr;
#endif
@@ -2795,6 +2803,85 @@ static bool allocate_tagcache(void)
return true;
}
+# ifdef HAVE_EEPROM
+static bool tagcache_dumpload(void)
+{
+ struct statefile_header shdr;
+ int fd, rc;
+ long offpos;
+ int i;
+
+ fd = open(TAGCACHE_STATEFILE, O_RDONLY);
+ if (fd < 0)
+ {
+ logf("no tagcache statedump");
+ return false;
+ }
+
+ /* Check the statefile memory placement */
+ hdr = buffer_alloc(0);
+ rc = read(fd, &shdr, sizeof(struct statefile_header));
+ if (rc != sizeof(struct statefile_header)
+ /* || (long)hdr != (long)shdr.hdr */)
+ {
+ logf("incorrect statefile");
+ hdr = NULL;
+ close(fd);
+ return false;
+ }
+
+ offpos = (long)hdr - (long)shdr.hdr;
+
+ /* Lets allocate real memory and load it */
+ hdr = buffer_alloc(shdr.stat.ramcache_allocated);
+ rc = read(fd, hdr, shdr.stat.ramcache_allocated);
+ close(fd);
+
+ if (rc != shdr.stat.ramcache_allocated)
+ {
+ logf("read failure!");
+ hdr = NULL;
+ return false;
+ }
+
+ memcpy(&stat, &shdr.stat, sizeof(struct tagcache_stat));
+
+ /* Now fix the pointers */
+ hdr->indices = (struct index_entry *)((long)hdr->indices + offpos);
+ for (i = 0; i < TAG_COUNT; i++)
+ hdr->tags[i] += offpos;
+
+ return true;
+}
+
+static bool tagcache_dumpsave(void)
+{
+ struct statefile_header shdr;
+ int fd;
+
+ if (!stat.ramcache)
+ return false;
+
+ fd = open(TAGCACHE_STATEFILE, O_WRONLY | O_CREAT | O_TRUNC);
+ if (fd < 0)
+ {
+ logf("failed to create a statedump");
+ return false;
+ }
+
+ /* Create the header */
+ shdr.hdr = hdr;
+ memcpy(&shdr.stat, &stat, sizeof(struct tagcache_stat));
+ write(fd, &shdr, sizeof(struct statefile_header));
+
+ /* And dump the data too */
+ write(fd, hdr, stat.ramcache_allocated);
+ close(fd);
+
+ return true;
+}
+# endif
+
static bool load_tagcache(void)
{
struct tagcache_header *tch;
@@ -3250,8 +3337,15 @@ static void tagcache_thread(void)
free_tempbuf();
#ifdef HAVE_TC_RAMCACHE
+# ifdef HAVE_EEPROM
+ if (firmware_settings.initialized && firmware_settings.disk_clean)
+ check_done = tagcache_dumpload();
+
+ remove(TAGCACHE_STATEFILE);
+# endif
+
/* Allocate space for the tagcache if found on disk. */
- if (global_settings.tagcache_ram)
+ if (global_settings.tagcache_ram && !stat.ramcache)
allocate_tagcache();
#endif
@@ -3330,6 +3424,19 @@ static void tagcache_thread(void)
}
}
+bool tagcache_prepare_shutdown(void)
+{
+ if (tagcache_get_commit_step() > 0)
+ return false;
+
+#ifdef HAVE_EEPROM
+ if (stat.ramcache)
+ tagcache_dumpsave();
+#endif
+
+ return true;
+}
+
static int get_progress(void)
{
int total_count = -1;
diff --git a/apps/tagcache.h b/apps/tagcache.h
index 450c21c..d5ce772 100644
--- a/apps/tagcache.h
+++ b/apps/tagcache.h
@@ -64,6 +64,7 @@ enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title,
#define TAGCACHE_FILE_MASTER ROCKBOX_DIR "/tagcache_idx.tcd"
#define TAGCACHE_FILE_INDEX ROCKBOX_DIR "/tagcache_%d.tcd"
#define TAGCACHE_FILE_CHANGELOG ROCKBOX_DIR "/tagcache_changelog.txt"
+#define TAGCACHE_STATEFILE ROCKBOX_DIR "/tagcache_state.tcd"
/* Flags */
#define FLAG_DELETED 0x0001 /* Entry has been removed from db */
@@ -149,6 +150,7 @@ bool tagcache_modify_numeric_entry(struct tagcache_search *tcs,
struct tagcache_stat* tagcache_get_stat(void);
int tagcache_get_commit_step(void);
+bool tagcache_prepare_shutdown(void);
#ifdef HAVE_TC_RAMCACHE
bool tagcache_is_ramcache(void);
diff --git a/apps/tree.c b/apps/tree.c
index 7543ceb..fde4da0 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -64,6 +64,7 @@
#include "tagcache.h"
#include "yesno.h"
#include "gwps-common.h"
+#include "eeprom_settings.h"
/* gui api */
#include "list.h"
@@ -1367,8 +1368,13 @@ void tree_flush(void)
#ifdef HAVE_DIRCACHE
if (global_settings.dircache)
{
- if (dircache_is_enabled())
+# ifdef HAVE_EEPROM
+ if (dircache_is_enabled() && firmware_settings.initialized)
+ {
global_settings.dircache_size = dircache_get_cache_size();
+ dircache_save(DIRCACHE_FILE);
+ }
+# endif
dircache_disable();
}
else
@@ -1382,6 +1388,7 @@ void tree_flush(void)
void tree_restore(void)
{
#ifdef HAVE_DIRCACHE
+ remove(DIRCACHE_FILE);
if (global_settings.dircache)
{
/* Print "Scanning disk..." to the display. */
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 8e2ca74..480c7ce 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -145,6 +145,10 @@ drivers/mas.c
#ifdef IRIVER_H300_SERIES
drivers/pcf50606.c
#endif
+#ifdef HAVE_EEPROM
+drivers/eeprom_24cxx.c
+eeprom_settings.c
+#endif
#ifdef IPOD_ARCH
drivers/pcf50605.c
#endif
diff --git a/firmware/common/crc32.c b/firmware/common/crc32.c
index 18ee6ac..21fefac 100644
--- a/firmware/common/crc32.c
+++ b/firmware/common/crc32.c
@@ -21,8 +21,10 @@
/* Tool function to calculate a CRC32 across some buffer */
/* third argument is either 0xFFFFFFFF to start or value from last piece */
-unsigned crc_32(unsigned char* buf, unsigned len, unsigned crc32)
+unsigned crc_32(const void *src, unsigned len, unsigned crc32)
{
+ const unsigned char *buf = (const unsigned char *)src;
+
/* CCITT standard polynomial 0x04C11DB7 */
static const unsigned crc32_lookup[16] =
{ /* lookup table for 4 bits at a time is affordable */
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index 6167aa3..d2c77a2 100644
--- a/firmware/common/dircache.c
+++ b/firmware/common/dircache.c
@@ -402,7 +402,7 @@ static struct dircache_entry* dircache_get_entry(const char *path,
return cache_entry;
}
-#if 0
+#if 1
/**
* Function to load the internal cache structure from disk to initialize
* the dircache really fast and little disk access.
@@ -423,32 +423,41 @@ int dircache_load(const char *path)
if (fd < 0)
return -2;
- dircache_root = (struct dircache_entry *)(((long)audiobuf & ~0x03) + 0x04);
bytes_read = read(fd, &maindata, sizeof(struct dircache_maindata));
if (bytes_read != sizeof(struct dircache_maindata)
- || (long)maindata.root_entry != (long)dircache_root
|| maindata.size <= 0)
{
+ logf("Dircache file header error");
close(fd);
return -3;
}
+ dircache_root = buffer_alloc(0);
+ if ((long)maindata.root_entry != (long)dircache_root)
+ {
+ logf("Position missmatch");
+ close(fd);
+ return -4;
+ }
+
+ dircache_root = buffer_alloc(maindata.size + DIRCACHE_RESERVE);
entry_count = maindata.entry_count;
bytes_read = read(fd, dircache_root, MIN(DIRCACHE_LIMIT, maindata.size));
close(fd);
if (bytes_read != maindata.size)
+ {
+ logf("Dircache read failed");
return -6;
+ }
/* Cache successfully loaded. */
dircache_size = maindata.size;
+ allocated_size = dircache_size + DIRCACHE_RESERVE;
+ reserve_used = 0;
logf("Done, %d KiB used", dircache_size / 1024);
dircache_initialized = true;
memset(fd_bindings, 0, sizeof(fd_bindings));
-
- /* We have to long align the audiobuf to keep the buffer access fast. */
- audiobuf += (long)((dircache_size & ~0x03) + 0x04);
- audiobuf += DIRCACHE_RESERVE;
return 0;
}
@@ -472,7 +481,7 @@ int dircache_save(const char *path)
return -1;
logf("Saving directory cache");
- fd = open(path, O_WRONLY | O_CREAT);
+ fd = open(path, O_WRONLY | O_CREAT | O_TRUNC);
maindata.magic = DIRCACHE_MAGIC;
maindata.size = dircache_size;
@@ -484,6 +493,7 @@ int dircache_save(const char *path)
if (bytes_written != sizeof(struct dircache_maindata))
{
close(fd);
+ logf("dircache: write failed #1");
return -2;
}
@@ -491,8 +501,11 @@ int dircache_save(const char *path)
bytes_written = write(fd, dircache_root, dircache_size);
close(fd);
if (bytes_written != dircache_size)
+ {
+ logf("dircache: write failed #2");
return -3;
-
+ }
+
return 0;
}
#endif /* #if 0 */
@@ -616,6 +629,7 @@ int dircache_build(int last_size)
return -3;
logf("Building directory cache");
+ /* Background build, dircache has been previously allocated */
if (dircache_size > 0)
{
thread_enabled = true;
diff --git a/firmware/drivers/eeprom_24cxx.c b/firmware/drivers/eeprom_24cxx.c
index 4f7362e..33c02f1 100644
--- a/firmware/drivers/eeprom_24cxx.c
+++ b/firmware/drivers/eeprom_24cxx.c
@@ -308,7 +308,7 @@ bool eeprom_24cxx_read_byte(unsigned int address, char *c)
bool eeprom_24cxx_write_byte(unsigned int address, char c)
{
int ret;
- int count = 10;
+ int count = 100;
if (address >= EEPROM_SIZE)
{
@@ -318,10 +318,6 @@ bool eeprom_24cxx_write_byte(unsigned int address, char c)
do {
ret = sw_i2c_write_byte(address, c);
- if (ret < 0)
- {
- logf("EEPROM Fail: %d/%d", ret, address);
- }
} while (ret < 0 && count--) ;
if (ret < 0)
diff --git a/firmware/eeprom_settings.c b/firmware/eeprom_settings.c
new file mode 100644
index 0000000..43f519d
--- /dev/null
+++ b/firmware/eeprom_settings.c
@@ -0,0 +1,116 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Miika Pekkarinen
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "eeprom_settings.h"
+#include "eeprom_24cxx.h"
+#include "crc32.h"
+
+#include "string.h"
+#include "logf.h"
+
+struct eeprom_settings firmware_settings;
+
+static void reset_config(void)
+{
+ memset(&firmware_settings, 0, sizeof(struct eeprom_settings));
+ firmware_settings.version = EEPROM_SETTINGS_VERSION;
+ firmware_settings.initialized = true;
+ firmware_settings.boot_disk = false;
+ firmware_settings.bl_version = 0;
+}
+
+bool eeprom_settings_init(void)
+{
+ bool ret;
+ uint32_t sum;
+
+ eeprom_24cxx_init();
+
+ /* Check if player has been flashed. */
+ if (!detect_flashed_rockbox())
+ {
+ memset(&firmware_settings, 0, sizeof(struct eeprom_settings));
+ firmware_settings.initialized = false;
+ logf("Rockbox in flash is required");
+ return false;
+ }
+
+ ret = eeprom_24cxx_read(0, &firmware_settings,
+ sizeof(struct eeprom_settings));
+
+ if (!ret)
+ {
+ memset(&firmware_settings, 0, sizeof(struct eeprom_settings));
+ firmware_settings.initialized = false;
+ return false;
+ }
+
+ sum = crc_32(&firmware_settings, sizeof(struct eeprom_settings)-4,
+ 0xffffffff);
+
+ if (firmware_settings.checksum != sum)
+ {
+ logf("Checksum mismatch");
+ reset_config();
+ return true;
+ }
+
+ if (firmware_settings.version != EEPROM_SETTINGS_VERSION)
+ {
+ logf("Version mismatch");
+ reset_config();
+ return true;
+ }
+
+#ifndef BOOTLOADER
+ if (firmware_settings.bl_version < EEPROM_SETTINGS_BL_MINVER)
+ {
+ logf("Too old bootloader: %d", firmware_settings.bl_version);
+ reset_config();
+ return true;
+ }
+#endif
+
+ return true;
+}
+
+bool eeprom_settings_store(void)
+{
+ bool ret;
+ uint32_t sum;
+
+ if (!firmware_settings.initialized || !detect_flashed_rockbox())
+ {
+ logf("Rockbox in flash is required");
+ return false;
+ }
+
+ /* Update the checksum. */
+ sum = crc_32(&firmware_settings, sizeof(struct eeprom_settings)-4,
+ 0xffffffff);
+ firmware_settings.checksum = sum;
+ ret = eeprom_24cxx_write(0, &firmware_settings,
+ sizeof(struct eeprom_settings));
+
+ if (!ret)
+ firmware_settings.initialized = false;
+
+ return ret;
+}
+
diff --git a/firmware/export/config-h100.h b/firmware/export/config-h100.h
index 6d204c3..7310dfa 100644
--- a/firmware/export/config-h100.h
+++ b/firmware/export/config-h100.h
@@ -123,7 +123,10 @@
#define BOOTFILE_EXT "iriver"
#define BOOTFILE "rockbox." BOOTFILE_EXT
-#endif
+/* Define this if there is an EEPROM chip */
+#define HAVE_EEPROM
+
+#endif /* !SIMULATOR */
/* Define this for S/PDIF input available */
#define HAVE_SPDIF_IN
@@ -134,3 +137,4 @@
/* Define this if you can control the S/PDIF power */
#define HAVE_SPDIF_POWER
#define SPDIF_POWER_INVERTED
+
diff --git a/firmware/export/config-h120.h b/firmware/export/config-h120.h
index 5635a92..ca61813 100644
--- a/firmware/export/config-h120.h
+++ b/firmware/export/config-h120.h
@@ -118,7 +118,14 @@
#define BOOTFILE_EXT "iriver"
#define BOOTFILE "rockbox." BOOTFILE_EXT
-#endif
+#define BOOTLOADER_ENTRYPOINT 0x001F0000
+#define FLASH_ENTRYPOINT 0x00001000
+#define FLASH_MAGIC 0xfbfbfbf1
+
+/* Define this if there is an EEPROM chip */
+#define HAVE_EEPROM
+
+#endif /* !SIMULATOR */
/* Define this for S/PDIF input available */
#define HAVE_SPDIF_IN
@@ -128,3 +135,4 @@
/* Define this if you can control the S/PDIF power */
#define HAVE_SPDIF_POWER
+
diff --git a/firmware/export/eeprom_settings.h b/firmware/export/eeprom_settings.h
new file mode 100644
index 0000000..a3515bd
--- /dev/null
+++ b/firmware/export/eeprom_settings.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2006 by Miika Pekkarinen
+ *
+ * All files in this archive are subject to the GNU General Public License.
+ * See the file COPYING in the source tree root for full license agreement.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef _EEPROM_SETTINGS_H_
+#define _EEPROM_SETTINGS_H_
+
+#include <stdbool.h>
+#include "inttypes.h"
+
+#define EEPROM_SETTINGS_VERSION 0x24c01001
+#define EEPROM_SETTINGS_BL_MINVER 7
+
+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 bl_version; /* Installed bootloader version */
+
+ /* This must be the last entry */
+ uint32_t checksum; /* Checksum of this structure */
+};
+
+extern struct eeprom_settings firmware_settings;
+
+bool detect_flashed_rockbox(void);
+bool eeprom_settings_init(void);
+bool eeprom_settings_store(void);
+
+#endif
+
diff --git a/firmware/export/system.h b/firmware/export/system.h
index dae5d95..1b326e1 100644
--- a/firmware/export/system.h
+++ b/firmware/export/system.h
@@ -45,6 +45,14 @@ static inline void udelay(unsigned usecs)
}
#endif
+struct flash_header {
+ unsigned long magic;
+ unsigned long length;
+ char version[32];
+};
+
+bool detect_flashed_rockbox(void);
+
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
#define FREQ cpu_frequency
void set_cpu_frequency(long frequency);
diff --git a/firmware/include/crc32.h b/firmware/include/crc32.h
index 5e998ab..a2b7ae2 100644
--- a/firmware/include/crc32.h
+++ b/firmware/include/crc32.h
@@ -19,7 +19,7 @@
#ifndef _CRC32_H
#define _CRC32_H
-unsigned crc_32(unsigned char* buf, unsigned len, unsigned crc32);
+unsigned crc_32(const void *src, unsigned len, unsigned crc32);
#endif
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c
index 4bccd4e..a8e641e 100644
--- a/firmware/powermgmt.c
+++ b/firmware/powermgmt.c
@@ -993,8 +993,8 @@ void sys_poweroff(void)
{
logf("sys_poweroff()");
/* If the main thread fails to shut down the system, we will force a
- power off after an 8 second timeout */
- shutdown_timeout = HZ*8;
+ power off after an 20 second timeout */
+ shutdown_timeout = HZ*20;
queue_post(&button_queue, SYS_POWEROFF, NULL);
}
diff --git a/firmware/system.c b/firmware/system.c
index 1874c04..bb09dbc 100644
--- a/firmware/system.c
+++ b/firmware/system.c
@@ -24,6 +24,8 @@
#include "system.h"
#include "kernel.h"
#include "timer.h"
+#include "inttypes.h"
+#include "string.h"
#ifndef SIMULATOR
long cpu_frequency = CPU_FREQ;
@@ -76,6 +78,25 @@ void cpu_idle_mode(bool on_off)
#endif
+#if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
+bool detect_flashed_rockbox(void)
+{
+ struct flash_header hdr;
+ uint8_t *src = (uint8_t *)FLASH_ENTRYPOINT;
+
+ memcpy(&hdr, src, sizeof(struct flash_header));
+ if (hdr.magic != FLASH_MAGIC)
+ return false;
+
+ return true;
+}
+#else
+bool detect_flashed_rockbox(void)
+{
+ return false;
+}
+#endif
+
#if CONFIG_CPU == TCC730
void* volatile interrupt_vector[16] __attribute__ ((section(".idata")));