summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 87fbd97..3ee2330 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -352,6 +352,10 @@ Lyre prototype 1 */
#define IMX233_TQFP128 3
#define IMX233_LQFP100 4
+/* IMX233_PARTITIONS */
+#define IMX233_FREESCALE (1 << 0) /* Freescale I.MX233 nonstandard two-level MBR */
+#define IMX233_CREATIVE (1 << 1) /* Creative MBLK windowing */
+
/* now go and pick yours */
#if defined(ARCHOS_PLAYER)
#include "config/archosplayer.h"
diff --git a/firmware/export/config/creativezenxfi3.h b/firmware/export/config/creativezenxfi3.h
index de0ff8b..b4a328d 100644
--- a/firmware/export/config/creativezenxfi3.h
+++ b/firmware/export/config/creativezenxfi3.h
@@ -3,6 +3,7 @@
*/
#define IMX233_SUBTARGET 3780
#define IMX233_PACKAGE IMX233_BGA169
+#define IMX233_PARTITIONS IMX233_FREESCALE
/* For Rolo and boot loader */
#define MODEL_NUMBER 83
diff --git a/firmware/export/config/sansafuzeplus.h b/firmware/export/config/sansafuzeplus.h
index 1c5c2e0..e7622fa 100644
--- a/firmware/export/config/sansafuzeplus.h
+++ b/firmware/export/config/sansafuzeplus.h
@@ -3,6 +3,7 @@
*/
#define IMX233_SUBTARGET 3780
#define IMX233_PACKAGE IMX233_BGA169
+#define IMX233_PARTITIONS IMX233_FREESCALE
/* For Rolo and boot loader */
#define MODEL_NUMBER 72
diff --git a/firmware/export/config/sonynwze360.h b/firmware/export/config/sonynwze360.h
index d914c1c..a0f05f4 100644
--- a/firmware/export/config/sonynwze360.h
+++ b/firmware/export/config/sonynwze360.h
@@ -3,6 +3,7 @@
*/
#define IMX233_SUBTARGET 3780
#define IMX233_PACKAGE IMX233_BGA169
+#define IMX233_PARTITIONS IMX233_FREESCALE
/* For Rolo and boot loader */
#define MODEL_NUMBER 89
diff --git a/firmware/export/config/sonynwze370.h b/firmware/export/config/sonynwze370.h
index 45fa289..412200a 100644
--- a/firmware/export/config/sonynwze370.h
+++ b/firmware/export/config/sonynwze370.h
@@ -3,6 +3,7 @@
*/
#define IMX233_SUBTARGET 3780
#define IMX233_PACKAGE IMX233_BGA169
+#define IMX233_PARTITIONS IMX233_FREESCALE
/* For Rolo and boot loader */
#define MODEL_NUMBER 88
diff --git a/firmware/target/arm/imx233/partitions-imx233.c b/firmware/target/arm/imx233/partitions-imx233.c
index 06c5a48..ebc7b9a 100644
--- a/firmware/target/arm/imx233/partitions-imx233.c
+++ b/firmware/target/arm/imx233/partitions-imx233.c
@@ -19,6 +19,7 @@
*
****************************************************************************/
#include "partitions-imx233.h"
+#include "string.h"
static bool enable_window = true;
@@ -32,8 +33,79 @@ bool imx233_partitions_is_window_enabled(void)
return enable_window;
}
-int imx233_partitions_compute_window(uint8_t mbr[512], unsigned *start, unsigned *end)
+#if (IMX233_PARTITIONS & IMX233_CREATIVE)
+#define MBLK_MAGIC 0x4d424c4b /* MBLK */
+#define MBLK_COUNT 31
+/* MBLK is not located in the first sector !
+ * Creative code uses the hard-coded *absolute* address 0x3ffe00,
+ * bypassing all partition related information !!
+ * NOTE: for some reason, the ZEN uses a different value ?! */
+#ifdef CREATIVE_ZEN
+#define MBLK_ADDR 0x400000
+#else
+#define MBLK_ADDR 0x3ffe00
+#endif
+
+struct mblk_header_t
+{
+ uint32_t magic;
+ uint32_t block_size;
+ uint64_t total_size;
+} __attribute__((packed));
+
+struct mblk_partition_t
+{
+ uint32_t size;
+ uint32_t start;
+ char name[8];
+} __attribute__((packed));
+
+static const char *creative_part_name(enum imx233_part_t part)
+{
+ switch(part)
+ {
+ case IMX233_PART_USER: return "cfs";
+ case IMX233_PART_CFS: return "cfs";
+ case IMX233_PART_MINIFS: return "minifs";
+ default: return "";
+ }
+}
+
+static int compute_window_creative(IF_MD(int drive,) enum imx233_part_t part,
+ unsigned *start, unsigned *end)
{
+ uint8_t mblk[512];
+ int ret = storage_read_sectors(IF_MD(drive,) MBLK_ADDR / 512, 1, mblk);
+ if(ret < 0)
+ return ret;
+ struct mblk_header_t *hdr = (void *)mblk;
+ if(hdr->magic != MBLK_MAGIC)
+ return -70; /* bad magic */
+ struct mblk_partition_t *ent = (void *)(hdr + 1);
+ const char *name = creative_part_name(part);
+ for(int i = 0; i < MBLK_COUNT; i++)
+ {
+ if(ent[i].name[0] == 0)
+ continue;
+ if(strcmp(ent[i].name, name) == 0)
+ {
+ *start = ent[i].start * hdr->block_size / 512;
+ *end = *start + ent[i].size * hdr->block_size / 512;
+ return 0;
+ }
+ }
+ return -80; /* not found */
+}
+#endif /* #(IMX233_PARTITIONS & IMX233_CREATIVE) */
+
+#if (IMX233_PARTITIONS & IMX233_FREESCALE)
+static int compute_window_freescale(IF_MD(int drive,) enum imx233_part_t part,
+ unsigned *start, unsigned *end)
+{
+ uint8_t mbr[512];
+ int ret = storage_read_sectors(IF_MD(drive,) 0, 1, mbr);
+ if(ret < 0)
+ return ret;
/**
* Freescale uses a strange layout: is has a first MBR at sector 0 with four entries:
* 1) Actual user partition
@@ -54,19 +126,54 @@ int imx233_partitions_compute_window(uint8_t mbr[512], unsigned *start, unsigned
* it seems that it is similarly truncated. */
if(mbr[510] != 0x55 || mbr[511] != 0xAA)
return -101; /* invalid MBR */
- /* sanity check that the first partition is greater than 2Gib */
- uint8_t *ent = &mbr[446];
- *start = ent[8] | ent[9] << 8 | ent[10] << 16 | ent[11] << 24;
- /* ignore two lowest bits(see comment above) */
- *start &= ~3;
- *end = (ent[12] | ent[13] << 8 | ent[14] << 16 | ent[15] << 24);
- *end &= ~3;
- /* ignore two lowest bits(order is important, first truncate then add start) */
- *end += *start;
-
- if(ent[4] == 0x53)
- return -102; /* sigmatel partition */
- if((*end - *start) < 4 * 1024 * 1024)
- return -103; /* partition too small */
- return 0;
+ if(part == IMX233_PART_USER)
+ {
+ /* sanity check that the first partition is greater than 2Gib */
+ uint8_t *ent = &mbr[446];
+ *start = ent[8] | ent[9] << 8 | ent[10] << 16 | ent[11] << 24;
+ /* ignore two lowest bits(see comment above) */
+ *start &= ~3;
+ *end = (ent[12] | ent[13] << 8 | ent[14] << 16 | ent[15] << 24);
+ *end &= ~3;
+ /* ignore two lowest bits(order is important, first truncate then add start) */
+ *end += *start;
+
+ if(ent[4] == 0x53)
+ return -102; /* sigmatel partition */
+ if((*end - *start) < 4 * 1024 * 1024)
+ return -103; /* partition too small */
+ return 0;
+ }
+ else if(part == IMX233_PART_BOOT)
+ {
+ /* sanity check that the second partition is correct */
+ uint8_t *ent = &mbr[462];
+ if(ent[4] != 0x53)
+ return -104; /* wrong type */
+ *start = ent[8] | ent[9] << 8 | ent[10] << 16 | ent[11] << 24;
+ *end = (ent[12] | ent[13] << 8 | ent[14] << 16 | ent[15] << 24);
+ *end += *start;
+
+ return 0;
+ }
+ else
+ return -50;
+}
+#endif /* (IMX233_PARTITIONS & IMX233_FREESCALE) */
+
+int imx233_partitions_compute_window(IF_MD(int drive,) enum imx233_part_t part,
+ unsigned *start, unsigned *end)
+{
+ int ret = -1;
+#if (IMX233_PARTITIONS & IMX233_CREATIVE)
+ ret = compute_window_creative(IF_MD(drive,) part, start, end);
+ if(ret >= 0)
+ return ret;
+#endif
+#if (IMX233_PARTITIONS & IMX233_FREESCALE)
+ ret = compute_window_freescale(IF_MD(drive,) part, start, end);
+ if(ret >= 0)
+ return ret;
+#endif
+ return ret;
}
diff --git a/firmware/target/arm/imx233/partitions-imx233.h b/firmware/target/arm/imx233/partitions-imx233.h
index 4490aad..b7ed251 100644
--- a/firmware/target/arm/imx233/partitions-imx233.h
+++ b/firmware/target/arm/imx233/partitions-imx233.h
@@ -24,10 +24,27 @@
#include "system.h"
#include "storage.h"
+#ifndef IMX233_PARTITIONS
+#error You must define IMX233_PARTITIONS
+#endif
+
+enum imx233_part_t
+{
+ IMX233_PART_USER,
+#if (IMX233_PARTITIONS & IMX233_FREESCALE)
+ IMX233_PART_BOOT,
+#endif
+#if (IMX233_PARTITIONS & IMX233_CREATIVE)
+ IMX233_PART_CFS,
+ IMX233_PART_MINIFS,
+#endif
+};
+
/* Enable/Disable window computations for internal storage following the
* Freescale convention */
void imx233_partitions_enable_window(bool enable);
bool imx233_partitions_is_window_enabled(void);
-int imx233_partitions_compute_window(uint8_t mbr[512], unsigned *start, unsigned *end);
+int imx233_partitions_compute_window(IF_MD(int drive,) enum imx233_part_t part,
+ unsigned *start, unsigned *end);
#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 a4329b1..978e5b7 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)
/* compute window */
if((SDMMC_FLAGS(drive) & WINDOW) && imx233_partitions_is_window_enabled())
{
- uint8_t mbr[512];
- int ret = transfer_sectors(drive, 0, 1, mbr, true);
- if(ret)
- panicf("Cannot read MBR: %d", ret);
- ret = imx233_partitions_compute_window(mbr, &window_start[drive],
- &window_end[drive]);
+ /* NOTE: at this point the window shows the whole disk so raw disk
+ * accesses can be made to lookup partitions */
+ ret = imx233_partitions_compute_window(IF_MD(drive,) IMX233_PART_USER,
+ &window_start[drive], &window_end[drive]);
if(ret)
panicf("cannot compute partitions window: %d", ret);
SDMMC_INFO(drive).numblocks = window_end[drive] - window_start[drive];