diff options
-rw-r--r-- | bootloader/imx233.c | 19 | ||||
-rw-r--r-- | firmware/SOURCES | 1 | ||||
-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 |
5 files changed, 133 insertions, 36 deletions
diff --git a/bootloader/imx233.c b/bootloader/imx233.c index 6d356b9cce..c1ab4893c3 100644 --- a/bootloader/imx233.c +++ b/bootloader/imx233.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include "fmradio_i2c.h" | 40 | #include "fmradio_i2c.h" |
41 | #include "version.h" | 41 | #include "version.h" |
42 | #include "powermgmt.h" | 42 | #include "powermgmt.h" |
43 | #include "partitions-imx233.h" | ||
44 | #include "adc-imx233.h" | ||
43 | 45 | ||
44 | #include "usb.h" | 46 | #include "usb.h" |
45 | 47 | ||
@@ -84,6 +86,7 @@ static void usb_mode(int connect_timeout) | |||
84 | printf("Bootloader USB mode"); | 86 | printf("Bootloader USB mode"); |
85 | /* Enable power management to charge */ | 87 | /* Enable power management to charge */ |
86 | powermgmt_init(); | 88 | powermgmt_init(); |
89 | adc_init(); | ||
87 | 90 | ||
88 | usb_acknowledge(SYS_USB_CONNECTED_ACK); | 91 | usb_acknowledge(SYS_USB_CONNECTED_ACK); |
89 | 92 | ||
@@ -101,6 +104,14 @@ static void usb_mode(int connect_timeout) | |||
101 | info.state == TOPOFF ? "topoff" : | 104 | info.state == TOPOFF ? "topoff" : |
102 | info.state == CHARGING ? "charging" : "<unknown>"); | 105 | info.state == CHARGING ? "charging" : "<unknown>"); |
103 | lcd_putsf(0, 8, "Battery: %d%%", battery_level()); | 106 | lcd_putsf(0, 8, "Battery: %d%%", battery_level()); |
107 | lcd_putsf(0, 9, "Die temp: %d°C [%d, %d]", | ||
108 | adc_read(ADC_DIE_TEMP), IMX233_DIE_TEMP_HIGH, | ||
109 | IMX233_DIE_TEMP_LOW); | ||
110 | #ifdef ADC_BATT_TEMP | ||
111 | lcd_putsf(0, 10, "Batt temp: %d [%d, %d]", | ||
112 | adc_read(ADC_BATT_TEMP), IMX233_BATT_TEMP_HIGH, | ||
113 | IMX233_BATT_TEMP_LOW); | ||
114 | #endif | ||
104 | lcd_update(); | 115 | lcd_update(); |
105 | } | 116 | } |
106 | } | 117 | } |
@@ -137,19 +148,15 @@ void main(uint32_t arg, uint32_t addr) | |||
137 | 148 | ||
138 | button_init(); | 149 | button_init(); |
139 | 150 | ||
140 | //button_debug_screen(); | ||
141 | printf("Boot version: %s", RBVERSION); | 151 | printf("Boot version: %s", RBVERSION); |
142 | printf("arg=%x addr=%x", arg, addr); | 152 | printf("arg=%x addr=%x", arg, addr); |
143 | printf("power up source: %x", __XTRACT(HW_POWER_STS, PWRUP_SOURCE)); | 153 | printf("power up source: %x", __XTRACT(HW_POWER_STS, PWRUP_SOURCE)); |
144 | 154 | ||
145 | #ifdef SANSA_FUZEPLUS | ||
146 | extern void imx233_mmc_disable_window(void); | ||
147 | if(arg == 0xfee1dead) | 155 | if(arg == 0xfee1dead) |
148 | { | 156 | { |
149 | printf("Disable MMC window."); | 157 | printf("Disable partitions window."); |
150 | imx233_mmc_disable_window(); | 158 | imx233_partitions_enable_window(false); |
151 | } | 159 | } |
152 | #endif | ||
153 | 160 | ||
154 | ret = storage_init(); | 161 | ret = storage_init(); |
155 | if(ret < 0) | 162 | if(ret < 0) |
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 | |||
506 | target/arm/imx233/kernel-imx233.c | 506 | target/arm/imx233/kernel-imx233.c |
507 | target/arm/imx233/sd-imx233.c | 507 | target/arm/imx233/sd-imx233.c |
508 | target/arm/imx233/mmc-imx233.c | 508 | target/arm/imx233/mmc-imx233.c |
509 | target/arm/imx233/partitions-imx233.c | ||
509 | target/arm/imx233/ssp-imx233.c | 510 | target/arm/imx233/ssp-imx233.c |
510 | target/arm/imx233/dma-imx233.c | 511 | target/arm/imx233/dma-imx233.c |
511 | target/arm/imx233/icoll-imx233.c | 512 | target/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 */ |
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 | ||