summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/export/config.h4
-rw-r--r--firmware/export/config/creativezenxfi3.h1
-rw-r--r--firmware/export/config/sansafuzeplus.h1
-rw-r--r--firmware/export/config/sonynwze360.h1
-rw-r--r--firmware/export/config/sonynwze370.h1
-rw-r--r--firmware/target/arm/imx233/partitions-imx233.c139
-rw-r--r--firmware/target/arm/imx233/partitions-imx233.h19
-rw-r--r--firmware/target/arm/imx233/sdmmc-imx233.c10
8 files changed, 153 insertions, 23 deletions
diff --git a/firmware/export/config.h b/firmware/export/config.h
index 87fbd97516..3ee2330879 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -352,6 +352,10 @@ Lyre prototype 1 */
352#define IMX233_TQFP128 3 352#define IMX233_TQFP128 3
353#define IMX233_LQFP100 4 353#define IMX233_LQFP100 4
354 354
355/* IMX233_PARTITIONS */
356#define IMX233_FREESCALE (1 << 0) /* Freescale I.MX233 nonstandard two-level MBR */
357#define IMX233_CREATIVE (1 << 1) /* Creative MBLK windowing */
358
355/* now go and pick yours */ 359/* now go and pick yours */
356#if defined(ARCHOS_PLAYER) 360#if defined(ARCHOS_PLAYER)
357#include "config/archosplayer.h" 361#include "config/archosplayer.h"
diff --git a/firmware/export/config/creativezenxfi3.h b/firmware/export/config/creativezenxfi3.h
index de0ff8bac8..b4a328d894 100644
--- a/firmware/export/config/creativezenxfi3.h
+++ b/firmware/export/config/creativezenxfi3.h
@@ -3,6 +3,7 @@
3 */ 3 */
4#define IMX233_SUBTARGET 3780 4#define IMX233_SUBTARGET 3780
5#define IMX233_PACKAGE IMX233_BGA169 5#define IMX233_PACKAGE IMX233_BGA169
6#define IMX233_PARTITIONS IMX233_FREESCALE
6 7
7/* For Rolo and boot loader */ 8/* For Rolo and boot loader */
8#define MODEL_NUMBER 83 9#define MODEL_NUMBER 83
diff --git a/firmware/export/config/sansafuzeplus.h b/firmware/export/config/sansafuzeplus.h
index 1c5c2e0193..e7622fa568 100644
--- a/firmware/export/config/sansafuzeplus.h
+++ b/firmware/export/config/sansafuzeplus.h
@@ -3,6 +3,7 @@
3 */ 3 */
4#define IMX233_SUBTARGET 3780 4#define IMX233_SUBTARGET 3780
5#define IMX233_PACKAGE IMX233_BGA169 5#define IMX233_PACKAGE IMX233_BGA169
6#define IMX233_PARTITIONS IMX233_FREESCALE
6 7
7/* For Rolo and boot loader */ 8/* For Rolo and boot loader */
8#define MODEL_NUMBER 72 9#define MODEL_NUMBER 72
diff --git a/firmware/export/config/sonynwze360.h b/firmware/export/config/sonynwze360.h
index d914c1c253..a0f05f4342 100644
--- a/firmware/export/config/sonynwze360.h
+++ b/firmware/export/config/sonynwze360.h
@@ -3,6 +3,7 @@
3 */ 3 */
4#define IMX233_SUBTARGET 3780 4#define IMX233_SUBTARGET 3780
5#define IMX233_PACKAGE IMX233_BGA169 5#define IMX233_PACKAGE IMX233_BGA169
6#define IMX233_PARTITIONS IMX233_FREESCALE
6 7
7/* For Rolo and boot loader */ 8/* For Rolo and boot loader */
8#define MODEL_NUMBER 89 9#define MODEL_NUMBER 89
diff --git a/firmware/export/config/sonynwze370.h b/firmware/export/config/sonynwze370.h
index 45fa289e0d..412200a4ce 100644
--- a/firmware/export/config/sonynwze370.h
+++ b/firmware/export/config/sonynwze370.h
@@ -3,6 +3,7 @@
3 */ 3 */
4#define IMX233_SUBTARGET 3780 4#define IMX233_SUBTARGET 3780
5#define IMX233_PACKAGE IMX233_BGA169 5#define IMX233_PACKAGE IMX233_BGA169
6#define IMX233_PARTITIONS IMX233_FREESCALE
6 7
7/* For Rolo and boot loader */ 8/* For Rolo and boot loader */
8#define MODEL_NUMBER 88 9#define MODEL_NUMBER 88
diff --git a/firmware/target/arm/imx233/partitions-imx233.c b/firmware/target/arm/imx233/partitions-imx233.c
index 06c5a48f32..ebc7b9a6e6 100644
--- a/firmware/target/arm/imx233/partitions-imx233.c
+++ b/firmware/target/arm/imx233/partitions-imx233.c
@@ -19,6 +19,7 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#include "partitions-imx233.h" 21#include "partitions-imx233.h"
22#include "string.h"
22 23
23static bool enable_window = true; 24static bool enable_window = true;
24 25
@@ -32,8 +33,79 @@ bool imx233_partitions_is_window_enabled(void)
32 return enable_window; 33 return enable_window;
33} 34}
34 35
35int imx233_partitions_compute_window(uint8_t mbr[512], unsigned *start, unsigned *end) 36#if (IMX233_PARTITIONS & IMX233_CREATIVE)
37#define MBLK_MAGIC 0x4d424c4b /* MBLK */
38#define MBLK_COUNT 31
39/* MBLK is not located in the first sector !
40 * Creative code uses the hard-coded *absolute* address 0x3ffe00,
41 * bypassing all partition related information !!
42 * NOTE: for some reason, the ZEN uses a different value ?! */
43#ifdef CREATIVE_ZEN
44#define MBLK_ADDR 0x400000
45#else
46#define MBLK_ADDR 0x3ffe00
47#endif
48
49struct mblk_header_t
50{
51 uint32_t magic;
52 uint32_t block_size;
53 uint64_t total_size;
54} __attribute__((packed));
55
56struct mblk_partition_t
57{
58 uint32_t size;
59 uint32_t start;
60 char name[8];
61} __attribute__((packed));
62
63static const char *creative_part_name(enum imx233_part_t part)
64{
65 switch(part)
66 {
67 case IMX233_PART_USER: return "cfs";
68 case IMX233_PART_CFS: return "cfs";
69 case IMX233_PART_MINIFS: return "minifs";
70 default: return "";
71 }
72}
73
74static int compute_window_creative(IF_MD(int drive,) enum imx233_part_t part,
75 unsigned *start, unsigned *end)
36{ 76{
77 uint8_t mblk[512];
78 int ret = storage_read_sectors(IF_MD(drive,) MBLK_ADDR / 512, 1, mblk);
79 if(ret < 0)
80 return ret;
81 struct mblk_header_t *hdr = (void *)mblk;
82 if(hdr->magic != MBLK_MAGIC)
83 return -70; /* bad magic */
84 struct mblk_partition_t *ent = (void *)(hdr + 1);
85 const char *name = creative_part_name(part);
86 for(int i = 0; i < MBLK_COUNT; i++)
87 {
88 if(ent[i].name[0] == 0)
89 continue;
90 if(strcmp(ent[i].name, name) == 0)
91 {
92 *start = ent[i].start * hdr->block_size / 512;
93 *end = *start + ent[i].size * hdr->block_size / 512;
94 return 0;
95 }
96 }
97 return -80; /* not found */
98}
99#endif /* #(IMX233_PARTITIONS & IMX233_CREATIVE) */
100
101#if (IMX233_PARTITIONS & IMX233_FREESCALE)
102static int compute_window_freescale(IF_MD(int drive,) enum imx233_part_t part,
103 unsigned *start, unsigned *end)
104{
105 uint8_t mbr[512];
106 int ret = storage_read_sectors(IF_MD(drive,) 0, 1, mbr);
107 if(ret < 0)
108 return ret;
37 /** 109 /**
38 * Freescale uses a strange layout: is has a first MBR at sector 0 with four entries: 110 * Freescale uses a strange layout: is has a first MBR at sector 0 with four entries:
39 * 1) Actual user partition 111 * 1) Actual user partition
@@ -54,19 +126,54 @@ int imx233_partitions_compute_window(uint8_t mbr[512], unsigned *start, unsigned
54 * it seems that it is similarly truncated. */ 126 * it seems that it is similarly truncated. */
55 if(mbr[510] != 0x55 || mbr[511] != 0xAA) 127 if(mbr[510] != 0x55 || mbr[511] != 0xAA)
56 return -101; /* invalid MBR */ 128 return -101; /* invalid MBR */
57 /* sanity check that the first partition is greater than 2Gib */ 129 if(part == IMX233_PART_USER)
58 uint8_t *ent = &mbr[446]; 130 {
59 *start = ent[8] | ent[9] << 8 | ent[10] << 16 | ent[11] << 24; 131 /* sanity check that the first partition is greater than 2Gib */
60 /* ignore two lowest bits(see comment above) */ 132 uint8_t *ent = &mbr[446];
61 *start &= ~3; 133 *start = ent[8] | ent[9] << 8 | ent[10] << 16 | ent[11] << 24;
62 *end = (ent[12] | ent[13] << 8 | ent[14] << 16 | ent[15] << 24); 134 /* ignore two lowest bits(see comment above) */
63 *end &= ~3; 135 *start &= ~3;
64 /* ignore two lowest bits(order is important, first truncate then add start) */ 136 *end = (ent[12] | ent[13] << 8 | ent[14] << 16 | ent[15] << 24);
65 *end += *start; 137 *end &= ~3;
66 138 /* ignore two lowest bits(order is important, first truncate then add start) */
67 if(ent[4] == 0x53) 139 *end += *start;
68 return -102; /* sigmatel partition */ 140
69 if((*end - *start) < 4 * 1024 * 1024) 141 if(ent[4] == 0x53)
70 return -103; /* partition too small */ 142 return -102; /* sigmatel partition */
71 return 0; 143 if((*end - *start) < 4 * 1024 * 1024)
144 return -103; /* partition too small */
145 return 0;
146 }
147 else if(part == IMX233_PART_BOOT)
148 {
149 /* sanity check that the second partition is correct */
150 uint8_t *ent = &mbr[462];
151 if(ent[4] != 0x53)
152 return -104; /* wrong type */
153 *start = ent[8] | ent[9] << 8 | ent[10] << 16 | ent[11] << 24;
154 *end = (ent[12] | ent[13] << 8 | ent[14] << 16 | ent[15] << 24);
155 *end += *start;
156
157 return 0;
158 }
159 else
160 return -50;
161}
162#endif /* (IMX233_PARTITIONS & IMX233_FREESCALE) */
163
164int imx233_partitions_compute_window(IF_MD(int drive,) enum imx233_part_t part,
165 unsigned *start, unsigned *end)
166{
167 int ret = -1;
168#if (IMX233_PARTITIONS & IMX233_CREATIVE)
169 ret = compute_window_creative(IF_MD(drive,) part, start, end);
170 if(ret >= 0)
171 return ret;
172#endif
173#if (IMX233_PARTITIONS & IMX233_FREESCALE)
174 ret = compute_window_freescale(IF_MD(drive,) part, start, end);
175 if(ret >= 0)
176 return ret;
177#endif
178 return ret;
72} 179}
diff --git a/firmware/target/arm/imx233/partitions-imx233.h b/firmware/target/arm/imx233/partitions-imx233.h
index 4490aad77f..b7ed251dee 100644
--- a/firmware/target/arm/imx233/partitions-imx233.h
+++ b/firmware/target/arm/imx233/partitions-imx233.h
@@ -24,10 +24,27 @@
24#include "system.h" 24#include "system.h"
25#include "storage.h" 25#include "storage.h"
26 26
27#ifndef IMX233_PARTITIONS
28#error You must define IMX233_PARTITIONS
29#endif
30
31enum imx233_part_t
32{
33 IMX233_PART_USER,
34#if (IMX233_PARTITIONS & IMX233_FREESCALE)
35 IMX233_PART_BOOT,
36#endif
37#if (IMX233_PARTITIONS & IMX233_CREATIVE)
38 IMX233_PART_CFS,
39 IMX233_PART_MINIFS,
40#endif
41};
42
27/* Enable/Disable window computations for internal storage following the 43/* Enable/Disable window computations for internal storage following the
28 * Freescale convention */ 44 * Freescale convention */
29void imx233_partitions_enable_window(bool enable); 45void imx233_partitions_enable_window(bool enable);
30bool imx233_partitions_is_window_enabled(void); 46bool imx233_partitions_is_window_enabled(void);
31int imx233_partitions_compute_window(uint8_t mbr[512], unsigned *start, unsigned *end); 47int imx233_partitions_compute_window(IF_MD(int drive,) enum imx233_part_t part,
48 unsigned *start, unsigned *end);
32 49
33#endif /* __PARTITIONS_IMX233__ */ \ No newline at end of file 50#endif /* __PARTITIONS_IMX233__ */ \ No newline at end of file
diff --git a/firmware/target/arm/imx233/sdmmc-imx233.c b/firmware/target/arm/imx233/sdmmc-imx233.c
index a4329b1416..978e5b7247 100644
--- a/firmware/target/arm/imx233/sdmmc-imx233.c
+++ b/firmware/target/arm/imx233/sdmmc-imx233.c
@@ -664,12 +664,10 @@ static int init_drive(int drive)
664 /* compute window */ 664 /* compute window */
665 if((SDMMC_FLAGS(drive) & WINDOW) && imx233_partitions_is_window_enabled()) 665 if((SDMMC_FLAGS(drive) & WINDOW) && imx233_partitions_is_window_enabled())
666 { 666 {
667 uint8_t mbr[512]; 667 /* NOTE: at this point the window shows the whole disk so raw disk
668 int ret = transfer_sectors(drive, 0, 1, mbr, true); 668 * accesses can be made to lookup partitions */
669 if(ret) 669 ret = imx233_partitions_compute_window(IF_MD(drive,) IMX233_PART_USER,
670 panicf("Cannot read MBR: %d", ret); 670 &window_start[drive], &window_end[drive]);
671 ret = imx233_partitions_compute_window(mbr, &window_start[drive],
672 &window_end[drive]);
673 if(ret) 671 if(ret)
674 panicf("cannot compute partitions window: %d", ret); 672 panicf("cannot compute partitions window: %d", ret);
675 SDMMC_INFO(drive).numblocks = window_end[drive] - window_start[drive]; 673 SDMMC_INFO(drive).numblocks = window_end[drive] - window_start[drive];