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.tar.gz
rockbox-954b73265404075ec4d379ddea14e626113a8677.zip
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 724bab90ab..ce3140be63 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -53,6 +53,8 @@
53#include "tagcache.h" 53#include "tagcache.h"
54#include "lcd-remote.h" 54#include "lcd-remote.h"
55#include "crc32.h" 55#include "crc32.h"
56#include "eeprom_24cxx.h"
57#include "logf.h"
56 58
57#ifdef HAVE_LCD_BITMAP 59#ifdef HAVE_LCD_BITMAP
58#include "widgets.h" 60#include "widgets.h"
@@ -1952,6 +1954,22 @@ bool dbg_save_roms(void)
1952 close(fd); 1954 close(fd);
1953 } 1955 }
1954 system_memory_guard(oldmode); 1956 system_memory_guard(oldmode);
1957
1958#ifdef HAVE_EEPROM
1959 fd = creat("/internal_eeprom.bin", O_WRONLY);
1960 if (fd >= 0)
1961 {
1962 char buf[EEPROM_SIZE];
1963
1964 if (!eeprom_24cxx_read(0, buf, sizeof buf))
1965 gui_syncsplash(HZ*3, true, "Eeprom read failure!");
1966 else
1967 write(fd, buf, sizeof buf);
1968
1969 close(fd);
1970 }
1971#endif
1972
1955 return false; 1973 return false;
1956} 1974}
1957#endif /* CPU */ 1975#endif /* CPU */
diff --git a/apps/main.c b/apps/main.c
index b725d0252f..907e1126cf 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -65,6 +65,7 @@
65#include "lang.h" 65#include "lang.h"
66#include "string.h" 66#include "string.h"
67#include "splash.h" 67#include "splash.h"
68#include "eeprom_settings.h"
68 69
69#if (CONFIG_CODEC == SWCODEC) 70#if (CONFIG_CODEC == SWCODEC)
70#include "playback.h" 71#include "playback.h"
@@ -108,35 +109,30 @@ void app_main(void)
108 browse_root(); 109 browse_root();
109} 110}
110 111
111#ifdef HAVE_DIRCACHE 112int init_dircache(void)
112void init_dircache(void)
113{ 113{
114 int result; 114#ifdef HAVE_DIRCACHE
115 bool clear = false; 115 int result = 0;
116 116
117 dircache_init(); 117 dircache_init();
118 if (global_settings.dircache) 118 if (global_settings.dircache)
119 { 119 {
120 if (global_settings.dircache_size == 0) 120# ifdef HAVE_EEPROM
121 if (firmware_settings.initialized && firmware_settings.disk_clean)
121 { 122 {
122 gui_syncsplash(0, true, str(LANG_DIRCACHE_BUILDING)); 123 if (dircache_load(DIRCACHE_FILE) == 0)
123 clear = true; 124 return 0;
124 } 125 }
126# endif
125 127
126 result = dircache_build(global_settings.dircache_size); 128 result = dircache_build(global_settings.dircache_size);
127 if (result < 0)
128 gui_syncsplash(0, true, "Failed! Result: %d", result);
129
130 if (clear)
131 {
132 backlight_on();
133 show_logo();
134 }
135 } 129 }
136} 130
131 return result;
137#else 132#else
138# define init_dircache(...) 133 return 0;
139#endif 134#endif
135}
140 136
141void init_tagcache(void) 137void init_tagcache(void)
142{ 138{
@@ -376,6 +372,10 @@ void init(void)
376 } 372 }
377 } 373 }
378 374
375#ifdef HAVE_EEPROM
376 eeprom_settings_init();
377#endif
378
379 settings_calc_config_sector(); 379 settings_calc_config_sector();
380 380
381#if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD) 381#if defined(SETTINGS_RESET) || (CONFIG_KEYPAD == IPOD_4G_PAD)
@@ -395,11 +395,21 @@ void init(void)
395 settings_load(SETTINGS_ALL); 395 settings_load(SETTINGS_ALL);
396 396
397 397
398 init_dircache();
399
398 gui_sync_wps_init(); 400 gui_sync_wps_init();
399 settings_apply(); 401 settings_apply();
400 init_dircache(); 402 //init_dircache();
401 init_tagcache(); 403 init_tagcache();
402 404
405#ifdef HAVE_EEPROM
406 if (firmware_settings.initialized)
407 {
408 /* In case we crash. */
409 firmware_settings.disk_clean = false;
410 eeprom_settings_store();
411 }
412#endif
403 status_init(); 413 status_init();
404 playlist_init(); 414 playlist_init();
405 tree_init(); 415 tree_init();
diff --git a/apps/misc.c b/apps/misc.c
index ff05819a4d..b0c315af98 100644
--- a/apps/misc.c
+++ b/apps/misc.c
@@ -49,6 +49,7 @@
49#include "ata_mmc.h" 49#include "ata_mmc.h"
50#endif 50#endif
51#include "tree.h" 51#include "tree.h"
52#include "eeprom_settings.h"
52 53
53#ifdef HAVE_LCD_BITMAP 54#ifdef HAVE_LCD_BITMAP
54#include "bmp.h" 55#include "bmp.h"
@@ -484,13 +485,6 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter)
484#else 485#else
485 int i; 486 int i;
486 487
487 if (tagcache_get_commit_step() > 0)
488 {
489 cancel_shutdown();
490 gui_syncsplash(HZ, true, str(LANG_TAGCACHE_BUSY));
491 return false;
492 }
493
494#if defined(CONFIG_CHARGING) && !defined(HAVE_POWEROFF_WHILE_CHARGING) 488#if defined(CONFIG_CHARGING) && !defined(HAVE_POWEROFF_WHILE_CHARGING)
495 if(!charger_inserted()) 489 if(!charger_inserted())
496#endif 490#endif
@@ -498,11 +492,26 @@ static bool clean_shutdown(void (*callback)(void *), void *parameter)
498 FOR_NB_SCREENS(i) 492 FOR_NB_SCREENS(i)
499 screens[i].clear_display(); 493 screens[i].clear_display();
500 gui_syncsplash(0, true, str(LANG_SHUTTINGDOWN)); 494 gui_syncsplash(0, true, str(LANG_SHUTTINGDOWN));
495
496 if (!tagcache_prepare_shutdown())
497 {
498 cancel_shutdown();
499 gui_syncsplash(HZ, true, str(LANG_TAGCACHE_BUSY));
500 return false;
501 }
502
501 if (callback != NULL) 503 if (callback != NULL)
502 callback(parameter); 504 callback(parameter);
503 505
504 system_flush(); 506 system_flush();
505 507#ifdef HAVE_EEPROM
508 if (firmware_settings.initialized)
509 {
510 firmware_settings.disk_clean = true;
511 firmware_settings.bl_version = 0;
512 eeprom_settings_store();
513 }
514#endif
506 shutdown_hw(); 515 shutdown_hw();
507 } 516 }
508#endif 517#endif
diff --git a/apps/tagcache.c b/apps/tagcache.c
index 1485ed8e51..4812198167 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -70,6 +70,7 @@
70#include "buffer.h" 70#include "buffer.h"
71#include "atoi.h" 71#include "atoi.h"
72#include "crc32.h" 72#include "crc32.h"
73#include "eeprom_settings.h"
73 74
74/* Tag Cache thread. */ 75/* Tag Cache thread. */
75static struct event_queue tagcache_queue; 76static struct event_queue tagcache_queue;
@@ -152,6 +153,13 @@ struct ramcache_header {
152 int entry_count[TAG_COUNT]; /* Number of entries in the indices. */ 153 int entry_count[TAG_COUNT]; /* Number of entries in the indices. */
153}; 154};
154 155
156# ifdef HAVE_EEPROM
157struct statefile_header {
158 struct ramcache_header *hdr;
159 struct tagcache_stat stat;
160};
161# endif
162
155/* Pointer to allocated ramcache_header */ 163/* Pointer to allocated ramcache_header */
156static struct ramcache_header *hdr; 164static struct ramcache_header *hdr;
157#endif 165#endif
@@ -2795,6 +2803,85 @@ static bool allocate_tagcache(void)
2795 return true; 2803 return true;
2796} 2804}
2797 2805
2806# ifdef HAVE_EEPROM
2807static bool tagcache_dumpload(void)
2808{
2809 struct statefile_header shdr;
2810 int fd, rc;
2811 long offpos;
2812 int i;
2813
2814 fd = open(TAGCACHE_STATEFILE, O_RDONLY);
2815 if (fd < 0)
2816 {
2817 logf("no tagcache statedump");
2818 return false;
2819 }
2820
2821 /* Check the statefile memory placement */
2822 hdr = buffer_alloc(0);
2823 rc = read(fd, &shdr, sizeof(struct statefile_header));
2824 if (rc != sizeof(struct statefile_header)
2825 /* || (long)hdr != (long)shdr.hdr */)
2826 {
2827 logf("incorrect statefile");
2828 hdr = NULL;
2829 close(fd);
2830 return false;
2831 }
2832
2833 offpos = (long)hdr - (long)shdr.hdr;
2834
2835 /* Lets allocate real memory and load it */
2836 hdr = buffer_alloc(shdr.stat.ramcache_allocated);
2837 rc = read(fd, hdr, shdr.stat.ramcache_allocated);
2838 close(fd);
2839
2840 if (rc != shdr.stat.ramcache_allocated)
2841 {
2842 logf("read failure!");
2843 hdr = NULL;
2844 return false;
2845 }
2846
2847 memcpy(&stat, &shdr.stat, sizeof(struct tagcache_stat));
2848
2849 /* Now fix the pointers */
2850 hdr->indices = (struct index_entry *)((long)hdr->indices + offpos);
2851 for (i = 0; i < TAG_COUNT; i++)
2852 hdr->tags[i] += offpos;
2853
2854 return true;
2855}
2856
2857static bool tagcache_dumpsave(void)
2858{
2859 struct statefile_header shdr;
2860 int fd;
2861
2862 if (!stat.ramcache)
2863 return false;
2864
2865 fd = open(TAGCACHE_STATEFILE, O_WRONLY | O_CREAT | O_TRUNC);
2866 if (fd < 0)
2867 {
2868 logf("failed to create a statedump");
2869 return false;
2870 }
2871
2872 /* Create the header */
2873 shdr.hdr = hdr;
2874 memcpy(&shdr.stat, &stat, sizeof(struct tagcache_stat));
2875 write(fd, &shdr, sizeof(struct statefile_header));
2876
2877 /* And dump the data too */
2878 write(fd, hdr, stat.ramcache_allocated);
2879 close(fd);
2880
2881 return true;
2882}
2883# endif
2884
2798static bool load_tagcache(void) 2885static bool load_tagcache(void)
2799{ 2886{
2800 struct tagcache_header *tch; 2887 struct tagcache_header *tch;
@@ -3250,8 +3337,15 @@ static void tagcache_thread(void)
3250 free_tempbuf(); 3337 free_tempbuf();
3251 3338
3252#ifdef HAVE_TC_RAMCACHE 3339#ifdef HAVE_TC_RAMCACHE
3340# ifdef HAVE_EEPROM
3341 if (firmware_settings.initialized && firmware_settings.disk_clean)
3342 check_done = tagcache_dumpload();
3343
3344 remove(TAGCACHE_STATEFILE);
3345# endif
3346
3253 /* Allocate space for the tagcache if found on disk. */ 3347 /* Allocate space for the tagcache if found on disk. */
3254 if (global_settings.tagcache_ram) 3348 if (global_settings.tagcache_ram && !stat.ramcache)
3255 allocate_tagcache(); 3349 allocate_tagcache();
3256#endif 3350#endif
3257 3351
@@ -3330,6 +3424,19 @@ static void tagcache_thread(void)
3330 } 3424 }
3331} 3425}
3332 3426
3427bool tagcache_prepare_shutdown(void)
3428{
3429 if (tagcache_get_commit_step() > 0)
3430 return false;
3431
3432#ifdef HAVE_EEPROM
3433 if (stat.ramcache)
3434 tagcache_dumpsave();
3435#endif
3436
3437 return true;
3438}
3439
3333static int get_progress(void) 3440static int get_progress(void)
3334{ 3441{
3335 int total_count = -1; 3442 int total_count = -1;
diff --git a/apps/tagcache.h b/apps/tagcache.h
index 450c21c26e..d5ce772904 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,
64#define TAGCACHE_FILE_MASTER ROCKBOX_DIR "/tagcache_idx.tcd" 64#define TAGCACHE_FILE_MASTER ROCKBOX_DIR "/tagcache_idx.tcd"
65#define TAGCACHE_FILE_INDEX ROCKBOX_DIR "/tagcache_%d.tcd" 65#define TAGCACHE_FILE_INDEX ROCKBOX_DIR "/tagcache_%d.tcd"
66#define TAGCACHE_FILE_CHANGELOG ROCKBOX_DIR "/tagcache_changelog.txt" 66#define TAGCACHE_FILE_CHANGELOG ROCKBOX_DIR "/tagcache_changelog.txt"
67#define TAGCACHE_STATEFILE ROCKBOX_DIR "/tagcache_state.tcd"
67 68
68/* Flags */ 69/* Flags */
69#define FLAG_DELETED 0x0001 /* Entry has been removed from db */ 70#define FLAG_DELETED 0x0001 /* Entry has been removed from db */
@@ -149,6 +150,7 @@ bool tagcache_modify_numeric_entry(struct tagcache_search *tcs,
149 150
150struct tagcache_stat* tagcache_get_stat(void); 151struct tagcache_stat* tagcache_get_stat(void);
151int tagcache_get_commit_step(void); 152int tagcache_get_commit_step(void);
153bool tagcache_prepare_shutdown(void);
152 154
153#ifdef HAVE_TC_RAMCACHE 155#ifdef HAVE_TC_RAMCACHE
154bool tagcache_is_ramcache(void); 156bool tagcache_is_ramcache(void);
diff --git a/apps/tree.c b/apps/tree.c
index 7543ceb3f7..fde4da0e04 100644
--- a/apps/tree.c
+++ b/apps/tree.c
@@ -64,6 +64,7 @@
64#include "tagcache.h" 64#include "tagcache.h"
65#include "yesno.h" 65#include "yesno.h"
66#include "gwps-common.h" 66#include "gwps-common.h"
67#include "eeprom_settings.h"
67 68
68/* gui api */ 69/* gui api */
69#include "list.h" 70#include "list.h"
@@ -1367,8 +1368,13 @@ void tree_flush(void)
1367#ifdef HAVE_DIRCACHE 1368#ifdef HAVE_DIRCACHE
1368 if (global_settings.dircache) 1369 if (global_settings.dircache)
1369 { 1370 {
1370 if (dircache_is_enabled()) 1371# ifdef HAVE_EEPROM
1372 if (dircache_is_enabled() && firmware_settings.initialized)
1373 {
1371 global_settings.dircache_size = dircache_get_cache_size(); 1374 global_settings.dircache_size = dircache_get_cache_size();
1375 dircache_save(DIRCACHE_FILE);
1376 }
1377# endif
1372 dircache_disable(); 1378 dircache_disable();
1373 } 1379 }
1374 else 1380 else
@@ -1382,6 +1388,7 @@ void tree_flush(void)
1382void tree_restore(void) 1388void tree_restore(void)
1383{ 1389{
1384#ifdef HAVE_DIRCACHE 1390#ifdef HAVE_DIRCACHE
1391 remove(DIRCACHE_FILE);
1385 if (global_settings.dircache) 1392 if (global_settings.dircache)
1386 { 1393 {
1387 /* Print "Scanning disk..." to the display. */ 1394 /* Print "Scanning disk..." to the display. */
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 8e2ca740ab..480c7ce630 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -145,6 +145,10 @@ drivers/mas.c
145#ifdef IRIVER_H300_SERIES 145#ifdef IRIVER_H300_SERIES
146drivers/pcf50606.c 146drivers/pcf50606.c
147#endif 147#endif
148#ifdef HAVE_EEPROM
149drivers/eeprom_24cxx.c
150eeprom_settings.c
151#endif
148#ifdef IPOD_ARCH 152#ifdef IPOD_ARCH
149drivers/pcf50605.c 153drivers/pcf50605.c
150#endif 154#endif
diff --git a/firmware/common/crc32.c b/firmware/common/crc32.c
index 18ee6ac710..21fefac07f 100644
--- a/firmware/common/crc32.c
+++ b/firmware/common/crc32.c
@@ -21,8 +21,10 @@
21 21
22/* Tool function to calculate a CRC32 across some buffer */ 22/* Tool function to calculate a CRC32 across some buffer */
23/* third argument is either 0xFFFFFFFF to start or value from last piece */ 23/* third argument is either 0xFFFFFFFF to start or value from last piece */
24unsigned crc_32(unsigned char* buf, unsigned len, unsigned crc32) 24unsigned crc_32(const void *src, unsigned len, unsigned crc32)
25{ 25{
26 const unsigned char *buf = (const unsigned char *)src;
27
26 /* CCITT standard polynomial 0x04C11DB7 */ 28 /* CCITT standard polynomial 0x04C11DB7 */
27 static const unsigned crc32_lookup[16] = 29 static const unsigned crc32_lookup[16] =
28 { /* lookup table for 4 bits at a time is affordable */ 30 { /* lookup table for 4 bits at a time is affordable */
diff --git a/firmware/common/dircache.c b/firmware/common/dircache.c
index 6167aa3933..d2c77a2e25 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,
402 return cache_entry; 402 return cache_entry;
403} 403}
404 404
405#if 0 405#if 1
406/** 406/**
407 * Function to load the internal cache structure from disk to initialize 407 * Function to load the internal cache structure from disk to initialize
408 * the dircache really fast and little disk access. 408 * the dircache really fast and little disk access.
@@ -423,32 +423,41 @@ int dircache_load(const char *path)
423 if (fd < 0) 423 if (fd < 0)
424 return -2; 424 return -2;
425 425
426 dircache_root = (struct dircache_entry *)(((long)audiobuf & ~0x03) + 0x04);
427 bytes_read = read(fd, &maindata, sizeof(struct dircache_maindata)); 426 bytes_read = read(fd, &maindata, sizeof(struct dircache_maindata));
428 if (bytes_read != sizeof(struct dircache_maindata) 427 if (bytes_read != sizeof(struct dircache_maindata)
429 || (long)maindata.root_entry != (long)dircache_root
430 || maindata.size <= 0) 428 || maindata.size <= 0)
431 { 429 {
430 logf("Dircache file header error");
432 close(fd); 431 close(fd);
433 return -3; 432 return -3;
434 } 433 }
435 434
435 dircache_root = buffer_alloc(0);
436 if ((long)maindata.root_entry != (long)dircache_root)
437 {
438 logf("Position missmatch");
439 close(fd);
440 return -4;
441 }
442
443 dircache_root = buffer_alloc(maindata.size + DIRCACHE_RESERVE);
436 entry_count = maindata.entry_count; 444 entry_count = maindata.entry_count;
437 bytes_read = read(fd, dircache_root, MIN(DIRCACHE_LIMIT, maindata.size)); 445 bytes_read = read(fd, dircache_root, MIN(DIRCACHE_LIMIT, maindata.size));
438 close(fd); 446 close(fd);
439 447
440 if (bytes_read != maindata.size) 448 if (bytes_read != maindata.size)
449 {
450 logf("Dircache read failed");
441 return -6; 451 return -6;
452 }
442 453
443 /* Cache successfully loaded. */ 454 /* Cache successfully loaded. */
444 dircache_size = maindata.size; 455 dircache_size = maindata.size;
456 allocated_size = dircache_size + DIRCACHE_RESERVE;
457 reserve_used = 0;
445 logf("Done, %d KiB used", dircache_size / 1024); 458 logf("Done, %d KiB used", dircache_size / 1024);
446 dircache_initialized = true; 459 dircache_initialized = true;
447 memset(fd_bindings, 0, sizeof(fd_bindings)); 460 memset(fd_bindings, 0, sizeof(fd_bindings));
448
449 /* We have to long align the audiobuf to keep the buffer access fast. */
450 audiobuf += (long)((dircache_size & ~0x03) + 0x04);
451 audiobuf += DIRCACHE_RESERVE;
452 461
453 return 0; 462 return 0;
454} 463}
@@ -472,7 +481,7 @@ int dircache_save(const char *path)
472 return -1; 481 return -1;
473 482
474 logf("Saving directory cache"); 483 logf("Saving directory cache");
475 fd = open(path, O_WRONLY | O_CREAT); 484 fd = open(path, O_WRONLY | O_CREAT | O_TRUNC);
476 485
477 maindata.magic = DIRCACHE_MAGIC; 486 maindata.magic = DIRCACHE_MAGIC;
478 maindata.size = dircache_size; 487 maindata.size = dircache_size;
@@ -484,6 +493,7 @@ int dircache_save(const char *path)
484 if (bytes_written != sizeof(struct dircache_maindata)) 493 if (bytes_written != sizeof(struct dircache_maindata))
485 { 494 {
486 close(fd); 495 close(fd);
496 logf("dircache: write failed #1");
487 return -2; 497 return -2;
488 } 498 }
489 499
@@ -491,8 +501,11 @@ int dircache_save(const char *path)
491 bytes_written = write(fd, dircache_root, dircache_size); 501 bytes_written = write(fd, dircache_root, dircache_size);
492 close(fd); 502 close(fd);
493 if (bytes_written != dircache_size) 503 if (bytes_written != dircache_size)
504 {
505 logf("dircache: write failed #2");
494 return -3; 506 return -3;
495 507 }
508
496 return 0; 509 return 0;
497} 510}
498#endif /* #if 0 */ 511#endif /* #if 0 */
@@ -616,6 +629,7 @@ int dircache_build(int last_size)
616 return -3; 629 return -3;
617 630
618 logf("Building directory cache"); 631 logf("Building directory cache");
632 /* Background build, dircache has been previously allocated */
619 if (dircache_size > 0) 633 if (dircache_size > 0)
620 { 634 {
621 thread_enabled = true; 635 thread_enabled = true;
diff --git a/firmware/drivers/eeprom_24cxx.c b/firmware/drivers/eeprom_24cxx.c
index 4f7362ec82..33c02f1bc8 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)
308bool eeprom_24cxx_write_byte(unsigned int address, char c) 308bool eeprom_24cxx_write_byte(unsigned int address, char c)
309{ 309{
310 int ret; 310 int ret;
311 int count = 10; 311 int count = 100;
312 312
313 if (address >= EEPROM_SIZE) 313 if (address >= EEPROM_SIZE)
314 { 314 {
@@ -318,10 +318,6 @@ bool eeprom_24cxx_write_byte(unsigned int address, char c)
318 318
319 do { 319 do {
320 ret = sw_i2c_write_byte(address, c); 320 ret = sw_i2c_write_byte(address, c);
321 if (ret < 0)
322 {
323 logf("EEPROM Fail: %d/%d", ret, address);
324 }
325 } while (ret < 0 && count--) ; 321 } while (ret < 0 && count--) ;
326 322
327 if (ret < 0) 323 if (ret < 0)
diff --git a/firmware/eeprom_settings.c b/firmware/eeprom_settings.c
new file mode 100644
index 0000000000..43f519d3fa
--- /dev/null
+++ b/firmware/eeprom_settings.c
@@ -0,0 +1,116 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by Miika Pekkarinen
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "eeprom_settings.h"
21#include "eeprom_24cxx.h"
22#include "crc32.h"
23
24#include "string.h"
25#include "logf.h"
26
27struct eeprom_settings firmware_settings;
28
29static void reset_config(void)
30{
31 memset(&firmware_settings, 0, sizeof(struct eeprom_settings));
32 firmware_settings.version = EEPROM_SETTINGS_VERSION;
33 firmware_settings.initialized = true;
34 firmware_settings.boot_disk = false;
35 firmware_settings.bl_version = 0;
36}
37
38bool eeprom_settings_init(void)
39{
40 bool ret;
41 uint32_t sum;
42
43 eeprom_24cxx_init();
44
45 /* Check if player has been flashed. */
46 if (!detect_flashed_rockbox())
47 {
48 memset(&firmware_settings, 0, sizeof(struct eeprom_settings));
49 firmware_settings.initialized = false;
50 logf("Rockbox in flash is required");
51 return false;
52 }
53
54 ret = eeprom_24cxx_read(0, &firmware_settings,
55 sizeof(struct eeprom_settings));
56
57 if (!ret)
58 {
59 memset(&firmware_settings, 0, sizeof(struct eeprom_settings));
60 firmware_settings.initialized = false;
61 return false;
62 }
63
64 sum = crc_32(&firmware_settings, sizeof(struct eeprom_settings)-4,
65 0xffffffff);
66
67 if (firmware_settings.checksum != sum)
68 {
69 logf("Checksum mismatch");
70 reset_config();
71 return true;
72 }
73
74 if (firmware_settings.version != EEPROM_SETTINGS_VERSION)
75 {
76 logf("Version mismatch");
77 reset_config();
78 return true;
79 }
80
81#ifndef BOOTLOADER
82 if (firmware_settings.bl_version < EEPROM_SETTINGS_BL_MINVER)
83 {
84 logf("Too old bootloader: %d", firmware_settings.bl_version);
85 reset_config();
86 return true;
87 }
88#endif
89
90 return true;
91}
92
93bool eeprom_settings_store(void)
94{
95 bool ret;
96 uint32_t sum;
97
98 if (!firmware_settings.initialized || !detect_flashed_rockbox())
99 {
100 logf("Rockbox in flash is required");
101 return false;
102 }
103
104 /* Update the checksum. */
105 sum = crc_32(&firmware_settings, sizeof(struct eeprom_settings)-4,
106 0xffffffff);
107 firmware_settings.checksum = sum;
108 ret = eeprom_24cxx_write(0, &firmware_settings,
109 sizeof(struct eeprom_settings));
110
111 if (!ret)
112 firmware_settings.initialized = false;
113
114 return ret;
115}
116
diff --git a/firmware/export/config-h100.h b/firmware/export/config-h100.h
index 6d204c3d66..7310dfa42f 100644
--- a/firmware/export/config-h100.h
+++ b/firmware/export/config-h100.h
@@ -123,7 +123,10 @@
123#define BOOTFILE_EXT "iriver" 123#define BOOTFILE_EXT "iriver"
124#define BOOTFILE "rockbox." BOOTFILE_EXT 124#define BOOTFILE "rockbox." BOOTFILE_EXT
125 125
126#endif 126/* Define this if there is an EEPROM chip */
127#define HAVE_EEPROM
128
129#endif /* !SIMULATOR */
127 130
128/* Define this for S/PDIF input available */ 131/* Define this for S/PDIF input available */
129#define HAVE_SPDIF_IN 132#define HAVE_SPDIF_IN
@@ -134,3 +137,4 @@
134/* Define this if you can control the S/PDIF power */ 137/* Define this if you can control the S/PDIF power */
135#define HAVE_SPDIF_POWER 138#define HAVE_SPDIF_POWER
136#define SPDIF_POWER_INVERTED 139#define SPDIF_POWER_INVERTED
140
diff --git a/firmware/export/config-h120.h b/firmware/export/config-h120.h
index 5635a92b51..ca618139e9 100644
--- a/firmware/export/config-h120.h
+++ b/firmware/export/config-h120.h
@@ -118,7 +118,14 @@
118#define BOOTFILE_EXT "iriver" 118#define BOOTFILE_EXT "iriver"
119#define BOOTFILE "rockbox." BOOTFILE_EXT 119#define BOOTFILE "rockbox." BOOTFILE_EXT
120 120
121#endif 121#define BOOTLOADER_ENTRYPOINT 0x001F0000
122#define FLASH_ENTRYPOINT 0x00001000
123#define FLASH_MAGIC 0xfbfbfbf1
124
125/* Define this if there is an EEPROM chip */
126#define HAVE_EEPROM
127
128#endif /* !SIMULATOR */
122 129
123/* Define this for S/PDIF input available */ 130/* Define this for S/PDIF input available */
124#define HAVE_SPDIF_IN 131#define HAVE_SPDIF_IN
@@ -128,3 +135,4 @@
128 135
129/* Define this if you can control the S/PDIF power */ 136/* Define this if you can control the S/PDIF power */
130#define HAVE_SPDIF_POWER 137#define HAVE_SPDIF_POWER
138
diff --git a/firmware/export/eeprom_settings.h b/firmware/export/eeprom_settings.h
new file mode 100644
index 0000000000..a3515bd69e
--- /dev/null
+++ b/firmware/export/eeprom_settings.h
@@ -0,0 +1,48 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by Miika Pekkarinen
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#ifndef _EEPROM_SETTINGS_H_
21#define _EEPROM_SETTINGS_H_
22
23#include <stdbool.h>
24#include "inttypes.h"
25
26#define EEPROM_SETTINGS_VERSION 0x24c01001
27#define EEPROM_SETTINGS_BL_MINVER 7
28
29struct eeprom_settings
30{
31 long version; /* Settings version number */
32 bool initialized; /* Is eeprom_settings ready to be used */
33 bool disk_clean; /* Is disk intact from last reboot */
34 bool boot_disk; /* Load firmware from disk (default=FLASH) */
35 uint8_t bl_version; /* Installed bootloader version */
36
37 /* This must be the last entry */
38 uint32_t checksum; /* Checksum of this structure */
39};
40
41extern struct eeprom_settings firmware_settings;
42
43bool detect_flashed_rockbox(void);
44bool eeprom_settings_init(void);
45bool eeprom_settings_store(void);
46
47#endif
48
diff --git a/firmware/export/system.h b/firmware/export/system.h
index dae5d95794..1b326e1b8b 100644
--- a/firmware/export/system.h
+++ b/firmware/export/system.h
@@ -45,6 +45,14 @@ static inline void udelay(unsigned usecs)
45} 45}
46#endif 46#endif
47 47
48struct flash_header {
49 unsigned long magic;
50 unsigned long length;
51 char version[32];
52};
53
54bool detect_flashed_rockbox(void);
55
48#ifdef HAVE_ADJUSTABLE_CPU_FREQ 56#ifdef HAVE_ADJUSTABLE_CPU_FREQ
49#define FREQ cpu_frequency 57#define FREQ cpu_frequency
50void set_cpu_frequency(long frequency); 58void set_cpu_frequency(long frequency);
diff --git a/firmware/include/crc32.h b/firmware/include/crc32.h
index 5e998ab1b9..a2b7ae2f0a 100644
--- a/firmware/include/crc32.h
+++ b/firmware/include/crc32.h
@@ -19,7 +19,7 @@
19#ifndef _CRC32_H 19#ifndef _CRC32_H
20#define _CRC32_H 20#define _CRC32_H
21 21
22unsigned crc_32(unsigned char* buf, unsigned len, unsigned crc32); 22unsigned crc_32(const void *src, unsigned len, unsigned crc32);
23 23
24#endif 24#endif
25 25
diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c
index 4bccd4e211..a8e641e1ed 100644
--- a/firmware/powermgmt.c
+++ b/firmware/powermgmt.c
@@ -993,8 +993,8 @@ void sys_poweroff(void)
993{ 993{
994 logf("sys_poweroff()"); 994 logf("sys_poweroff()");
995 /* If the main thread fails to shut down the system, we will force a 995 /* If the main thread fails to shut down the system, we will force a
996 power off after an 8 second timeout */ 996 power off after an 20 second timeout */
997 shutdown_timeout = HZ*8; 997 shutdown_timeout = HZ*20;
998 998
999 queue_post(&button_queue, SYS_POWEROFF, NULL); 999 queue_post(&button_queue, SYS_POWEROFF, NULL);
1000} 1000}
diff --git a/firmware/system.c b/firmware/system.c
index 1874c0480e..bb09dbcd59 100644
--- a/firmware/system.c
+++ b/firmware/system.c
@@ -24,6 +24,8 @@
24#include "system.h" 24#include "system.h"
25#include "kernel.h" 25#include "kernel.h"
26#include "timer.h" 26#include "timer.h"
27#include "inttypes.h"
28#include "string.h"
27 29
28#ifndef SIMULATOR 30#ifndef SIMULATOR
29long cpu_frequency = CPU_FREQ; 31long cpu_frequency = CPU_FREQ;
@@ -76,6 +78,25 @@ void cpu_idle_mode(bool on_off)
76 78
77#endif 79#endif
78 80
81#if defined(IRIVER_H100_SERIES) && !defined(SIMULATOR)
82bool detect_flashed_rockbox(void)
83{
84 struct flash_header hdr;
85 uint8_t *src = (uint8_t *)FLASH_ENTRYPOINT;
86
87 memcpy(&hdr, src, sizeof(struct flash_header));
88 if (hdr.magic != FLASH_MAGIC)
89 return false;
90
91 return true;
92}
93#else
94bool detect_flashed_rockbox(void)
95{
96 return false;
97}
98#endif
99
79#if CONFIG_CPU == TCC730 100#if CONFIG_CPU == TCC730
80 101
81void* volatile interrupt_vector[16] __attribute__ ((section(".idata"))); 102void* volatile interrupt_vector[16] __attribute__ ((section(".idata")));