summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-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
12 files changed, 241 insertions, 20 deletions
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")));