diff options
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/imx233/partitions-imx233.c | 139 | ||||
-rw-r--r-- | firmware/target/arm/imx233/partitions-imx233.h | 19 | ||||
-rw-r--r-- | firmware/target/arm/imx233/sdmmc-imx233.c | 10 |
3 files changed, 145 insertions, 23 deletions
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 | ||
23 | static bool enable_window = true; | 24 | static 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 | ||
35 | int 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 | |||
49 | struct mblk_header_t | ||
50 | { | ||
51 | uint32_t magic; | ||
52 | uint32_t block_size; | ||
53 | uint64_t total_size; | ||
54 | } __attribute__((packed)); | ||
55 | |||
56 | struct mblk_partition_t | ||
57 | { | ||
58 | uint32_t size; | ||
59 | uint32_t start; | ||
60 | char name[8]; | ||
61 | } __attribute__((packed)); | ||
62 | |||
63 | static 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 | |||
74 | static 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) | ||
102 | static 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 | |||
164 | int 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 | |||
31 | enum 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 */ |
29 | void imx233_partitions_enable_window(bool enable); | 45 | void imx233_partitions_enable_window(bool enable); |
30 | bool imx233_partitions_is_window_enabled(void); | 46 | bool imx233_partitions_is_window_enabled(void); |
31 | int imx233_partitions_compute_window(uint8_t mbr[512], unsigned *start, unsigned *end); | 47 | int 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]; |