summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/SOURCES1
-rw-r--r--firmware/target/arm/imx233/mmc-imx233.c44
-rw-r--r--firmware/target/arm/imx233/partitions-imx233.c72
-rw-r--r--firmware/target/arm/imx233/partitions-imx233.h33
4 files changed, 120 insertions, 30 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 61b437779b..81f7d87c3c 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -506,6 +506,7 @@ target/arm/imx233/timrot-imx233.c
506target/arm/imx233/kernel-imx233.c 506target/arm/imx233/kernel-imx233.c
507target/arm/imx233/sd-imx233.c 507target/arm/imx233/sd-imx233.c
508target/arm/imx233/mmc-imx233.c 508target/arm/imx233/mmc-imx233.c
509target/arm/imx233/partitions-imx233.c
509target/arm/imx233/ssp-imx233.c 510target/arm/imx233/ssp-imx233.c
510target/arm/imx233/dma-imx233.c 511target/arm/imx233/dma-imx233.c
511target/arm/imx233/icoll-imx233.c 512target/arm/imx233/icoll-imx233.c
diff --git a/firmware/target/arm/imx233/mmc-imx233.c b/firmware/target/arm/imx233/mmc-imx233.c
index f4dab30bcc..b2b18c871e 100644
--- a/firmware/target/arm/imx233/mmc-imx233.c
+++ b/firmware/target/arm/imx233/mmc-imx233.c
@@ -25,6 +25,7 @@
25#include "storage.h" 25#include "storage.h"
26#include "ssp-imx233.h" 26#include "ssp-imx233.h"
27#include "pinctrl-imx233.h" 27#include "pinctrl-imx233.h"
28#include "partitions-imx233.h"
28 29
29/** 30/**
30 * This code assumes a single eMMC internal flash 31 * This code assumes a single eMMC internal flash
@@ -39,12 +40,13 @@
39#define MMC_RCA 1 40#define MMC_RCA 1
40 41
41/** When set, this values restrict the windows of the read and writes */ 42/** When set, this values restrict the windows of the read and writes */
42static unsigned mmc_window_start = 0; 43static unsigned mmc_window_start;
43static unsigned mmc_window_end = INT_MAX; 44static unsigned mmc_window_end;
44static bool mmc_window_enable = true; 45static bool mmc_window_enable = true;
45static long mmc_last_activity = -1; 46static long mmc_last_activity = -1;
46static bool mmc_is_active = false; 47static bool mmc_is_active = false;
47static unsigned mmc_size = 0; 48static unsigned mmc_size = 0;
49static int mmc_first_drive = 0;
48 50
49static struct mutex mmc_mutex; 51static struct mutex mmc_mutex;
50 52
@@ -142,37 +144,19 @@ int mmc_init(void)
142 mmc_size = *sec_count; 144 mmc_size = *sec_count;
143 } 145 }
144 146
147 mmc_window_start = 0;
148 mmc_window_end = INT_MAX;
145 #ifdef SANSA_FUZEPLUS 149 #ifdef SANSA_FUZEPLUS
146 if(mmc_window_enable) 150 if(imx233_partitions_is_window_enabled())
147 { 151 {
148 /** 152 /* WARNING: mmc_first_drive is not set yet at this point */
149 * The Fuze+ uses a strange layout: is has a first MBR at sector 0 with four entries:
150 * 1) Actual user partition
151 * 2) Sigmatel boot partition
152 * 3)4) Other (certificate related ?) partitions
153 * The partition 1) has type 1 but it's actually a type 5 (logical partition) with
154 * a second partition table with usually one entry which is the FAT32 one.
155 * The first table uses 512-byte sector size and the second one usually uses
156 * 2048-byte logical sector size.
157 *
158 * We restrict mmc window to the user partition */
159 uint8_t mbr[512]; 153 uint8_t mbr[512];
160 mmc_window_start = 0;
161 mmc_window_end = INT_MAX;
162 ret = mmc_read_sectors(IF_MD2(0,) 0, 1, mbr); 154 ret = mmc_read_sectors(IF_MD2(0,) 0, 1, mbr);
163 if(ret != 0) 155 if(ret)
164 return -100; 156 panicf("cannot read MBR: %d", ret);
165 if(mbr[510] != 0x55 || mbr[511] != 0xAA) 157 ret = imx233_partitions_compute_window(mbr, &mmc_window_start, &mmc_window_end);
166 return -101; /* invalid MBR */ 158 if(ret)
167 /* sanity check that the first partition is greater than 2Gib */ 159 panicf("cannot compute partitions window: %d", ret);
168 uint8_t *ent = &mbr[446];
169 mmc_window_start = ent[8] | ent[9] << 8 | ent[10] << 16 | ent[11] << 24;
170 mmc_window_end = (ent[12] | ent[13] << 8 | ent[14] << 16 | ent[15] << 24) +
171 mmc_window_start;
172 if(ent[4] == 0x53)
173 return -102; /* sigmatel partition */
174 if((mmc_window_end - mmc_window_start) < 4 * 1024 * 1024)
175 return -103; /* partition too small */
176 mmc_size = mmc_window_end - mmc_window_start; 160 mmc_size = mmc_window_end - mmc_window_start;
177 } 161 }
178 #endif 162 #endif
@@ -182,7 +166,7 @@ int mmc_init(void)
182 166
183int mmc_num_drives(int first_drive) 167int mmc_num_drives(int first_drive)
184{ 168{
185 (void) first_drive; 169 mmc_first_drive = first_drive;
186 return 1; 170 return 1;
187} 171}
188 172
diff --git a/firmware/target/arm/imx233/partitions-imx233.c b/firmware/target/arm/imx233/partitions-imx233.c
new file mode 100644
index 0000000000..06c5a48f32
--- /dev/null
+++ b/firmware/target/arm/imx233/partitions-imx233.c
@@ -0,0 +1,72 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2012 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "partitions-imx233.h"
22
23static bool enable_window = true;
24
25void imx233_partitions_enable_window(bool enable)
26{
27 enable_window = enable;
28}
29
30bool imx233_partitions_is_window_enabled(void)
31{
32 return enable_window;
33}
34
35int imx233_partitions_compute_window(uint8_t mbr[512], unsigned *start, unsigned *end)
36{
37 /**
38 * Freescale uses a strange layout: is has a first MBR at sector 0 with four entries:
39 * 1) Actual user partition
40 * 2) Sigmatel boot partition
41 * 3)4) Other (certificate related ?) partitions
42 * The partition 1) has type 1 but it's actually a type 5 (logical partition) with
43 * a second partition table with usually one entry which is the FAT32 one.
44 * The first table uses 512-byte sector size and the second one usually uses
45 * 2048-byte logical sector size.
46 *
47 * We restrict the window to the user partition
48 *
49 * WARNING HACK FIXME BUG
50 * Reverse engineering and experiments suggests that the OF ignores the lowest 2 bits
51 * of the LBAs in the partition table. There is at least one example
52 * (the Creative Zen X-Fi3) where this is important because the LBA of the user partition
53 * is not a multiple of 4. The behaviour of the size field is less clear but
54 * it seems that it is similarly truncated. */
55 if(mbr[510] != 0x55 || mbr[511] != 0xAA)
56 return -101; /* invalid MBR */
57 /* sanity check that the first partition is greater than 2Gib */
58 uint8_t *ent = &mbr[446];
59 *start = ent[8] | ent[9] << 8 | ent[10] << 16 | ent[11] << 24;
60 /* ignore two lowest bits(see comment above) */
61 *start &= ~3;
62 *end = (ent[12] | ent[13] << 8 | ent[14] << 16 | ent[15] << 24);
63 *end &= ~3;
64 /* ignore two lowest bits(order is important, first truncate then add start) */
65 *end += *start;
66
67 if(ent[4] == 0x53)
68 return -102; /* sigmatel partition */
69 if((*end - *start) < 4 * 1024 * 1024)
70 return -103; /* partition too small */
71 return 0;
72}
diff --git a/firmware/target/arm/imx233/partitions-imx233.h b/firmware/target/arm/imx233/partitions-imx233.h
new file mode 100644
index 0000000000..4490aad77f
--- /dev/null
+++ b/firmware/target/arm/imx233/partitions-imx233.h
@@ -0,0 +1,33 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2012 by Amaury Pouly
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef __PARTITIONS_IMX233__
22#define __PARTITIONS_IMX233__
23
24#include "system.h"
25#include "storage.h"
26
27/* Enable/Disable window computations for internal storage following the
28 * Freescale convention */
29void imx233_partitions_enable_window(bool enable);
30bool imx233_partitions_is_window_enabled(void);
31int imx233_partitions_compute_window(uint8_t mbr[512], unsigned *start, unsigned *end);
32
33#endif /* __PARTITIONS_IMX233__ */ \ No newline at end of file