diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2012-05-19 13:33:45 +0200 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2012-05-19 16:10:52 +0200 |
commit | 07138ba2ba08ce586486baab081aa455eb021fea (patch) | |
tree | 5a751693228edaa964e2212528e0b41c06ccc553 /firmware/target/arm | |
parent | 61b129ac1e41014fc5da846c48a361c7ec752d76 (diff) | |
download | rockbox-07138ba2ba08ce586486baab081aa455eb021fea.tar.gz rockbox-07138ba2ba08ce586486baab081aa455eb021fea.zip |
imx233: move the freescale partition handling to its own file
The freescale firmware partitions has a lots of quirks that
need to be dealt with, so do it the proper way.
Change-Id: I8a5bd3fb462a4df143bc6c931057f3ffedd4b3d3
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/imx233/mmc-imx233.c | 44 | ||||
-rw-r--r-- | firmware/target/arm/imx233/partitions-imx233.c | 72 | ||||
-rw-r--r-- | firmware/target/arm/imx233/partitions-imx233.h | 33 |
3 files changed, 119 insertions, 30 deletions
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 */ |
42 | static unsigned mmc_window_start = 0; | 43 | static unsigned mmc_window_start; |
43 | static unsigned mmc_window_end = INT_MAX; | 44 | static unsigned mmc_window_end; |
44 | static bool mmc_window_enable = true; | 45 | static bool mmc_window_enable = true; |
45 | static long mmc_last_activity = -1; | 46 | static long mmc_last_activity = -1; |
46 | static bool mmc_is_active = false; | 47 | static bool mmc_is_active = false; |
47 | static unsigned mmc_size = 0; | 48 | static unsigned mmc_size = 0; |
49 | static int mmc_first_drive = 0; | ||
48 | 50 | ||
49 | static struct mutex mmc_mutex; | 51 | static 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 | ||
183 | int mmc_num_drives(int first_drive) | 167 | int 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 | |||
23 | static bool enable_window = true; | ||
24 | |||
25 | void imx233_partitions_enable_window(bool enable) | ||
26 | { | ||
27 | enable_window = enable; | ||
28 | } | ||
29 | |||
30 | bool imx233_partitions_is_window_enabled(void) | ||
31 | { | ||
32 | return enable_window; | ||
33 | } | ||
34 | |||
35 | int 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 */ | ||
29 | void imx233_partitions_enable_window(bool enable); | ||
30 | bool imx233_partitions_is_window_enabled(void); | ||
31 | int imx233_partitions_compute_window(uint8_t mbr[512], unsigned *start, unsigned *end); | ||
32 | |||
33 | #endif /* __PARTITIONS_IMX233__ */ \ No newline at end of file | ||