diff options
author | Cástor Muñoz <cmvidal@gmail.com> | 2016-02-05 02:02:02 +0100 |
---|---|---|
committer | Cástor Muñoz <cmvidal@gmail.com> | 2017-02-09 20:47:16 +0100 |
commit | 882921efb64218e9b8cc3a7d9c7308734f9b12f3 (patch) | |
tree | fca2e1b77104419156a07c6b6d80fa7af9fa3969 | |
parent | 0d0b163dd15c35a427c8bb2bbd7b906afe9c491d (diff) | |
download | rockbox-882921efb64218e9b8cc3a7d9c7308734f9b12f3.tar.gz rockbox-882921efb64218e9b8cc3a7d9c7308734f9b12f3.zip |
ipod6g: bootloader v1bootloader_ipod6g_v1
- dual boot
- USB mode
- battery trap
Change-Id: I8586cfeb21ee63f45ab965430725225fdfc4212d
-rw-r--r-- | bootloader/SOURCES | 2 | ||||
-rw-r--r-- | bootloader/ipod6g.c | 462 | ||||
-rw-r--r-- | firmware/SOURCES | 12 | ||||
-rw-r--r-- | firmware/export/config.h | 4 | ||||
-rw-r--r-- | firmware/export/config/ipod6g.h | 13 | ||||
-rw-r--r-- | firmware/target/arm/s5l8702/boot.lds | 54 | ||||
-rw-r--r-- | firmware/target/arm/s5l8702/crt0.S | 67 |
7 files changed, 582 insertions, 32 deletions
diff --git a/bootloader/SOURCES b/bootloader/SOURCES index 12347c57c9..a9c6aebd37 100644 --- a/bootloader/SOURCES +++ b/bootloader/SOURCES | |||
@@ -2,6 +2,8 @@ common.c | |||
2 | 2 | ||
3 | #if defined(IPOD_NANO2G) | 3 | #if defined(IPOD_NANO2G) |
4 | ipodnano2g.c | 4 | ipodnano2g.c |
5 | #elif defined(IPOD_6G) | ||
6 | ipod6g.c | ||
5 | #elif defined(IPOD_ARCH) | 7 | #elif defined(IPOD_ARCH) |
6 | ipod.c | 8 | ipod.c |
7 | #elif defined(GIGABEAT_F) | 9 | #elif defined(GIGABEAT_F) |
diff --git a/bootloader/ipod6g.c b/bootloader/ipod6g.c new file mode 100644 index 0000000000..0ab9444578 --- /dev/null +++ b/bootloader/ipod6g.c | |||
@@ -0,0 +1,462 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 by Dave Chapman | ||
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 <stdlib.h> | ||
22 | #include <stdio.h> | ||
23 | #include <stdarg.h> | ||
24 | #include <string.h> | ||
25 | |||
26 | #include "config.h" | ||
27 | |||
28 | #include "inttypes.h" | ||
29 | #include "cpu.h" | ||
30 | #include "system.h" | ||
31 | #include "lcd.h" | ||
32 | #include "../kernel-internal.h" | ||
33 | #include "file_internal.h" | ||
34 | #include "storage.h" | ||
35 | #include "fat.h" | ||
36 | #include "disk.h" | ||
37 | #include "font.h" | ||
38 | #include "backlight.h" | ||
39 | #include "backlight-target.h" | ||
40 | #include "button.h" | ||
41 | #include "panic.h" | ||
42 | #include "power.h" | ||
43 | #include "file.h" | ||
44 | #include "common.h" | ||
45 | #include "rb-loader.h" | ||
46 | #include "loader_strerror.h" | ||
47 | #include "version.h" | ||
48 | #include "powermgmt.h" | ||
49 | #include "usb.h" | ||
50 | #ifdef HAVE_SERIAL | ||
51 | #include "serial.h" | ||
52 | #endif | ||
53 | |||
54 | #include "s5l8702.h" | ||
55 | #include "clocking-s5l8702.h" | ||
56 | #include "spi-s5l8702.h" | ||
57 | #include "i2c-s5l8702.h" | ||
58 | #include "gpio-s5l8702.h" | ||
59 | #include "pmu-target.h" | ||
60 | #include "nor-target.h" | ||
61 | |||
62 | |||
63 | #define FW_ROCKBOX 0 | ||
64 | #define FW_APPLE 1 | ||
65 | |||
66 | #define ERR_RB 0 | ||
67 | #define ERR_OF 1 | ||
68 | #define ERR_HDD 2 | ||
69 | |||
70 | /* Safety measure - maximum allowed firmware image size. | ||
71 | The largest known current (October 2009) firmware is about 6.2MB so | ||
72 | we set this to 8MB. | ||
73 | */ | ||
74 | #define MAX_LOADSIZE (8*1024*1024) | ||
75 | |||
76 | #define LCD_RBYELLOW LCD_RGBPACK(255,192,0) | ||
77 | #define LCD_REDORANGE LCD_RGBPACK(255,70,0) | ||
78 | |||
79 | extern void bss_init(void); | ||
80 | extern uint32_t _movestart; | ||
81 | extern uint32_t start_loc; | ||
82 | |||
83 | extern int line; | ||
84 | |||
85 | #ifdef HAVE_BOOTLOADER_USB_MODE | ||
86 | static void usb_mode(void) | ||
87 | { | ||
88 | int button; | ||
89 | |||
90 | verbose = true; | ||
91 | |||
92 | printf("Entering USB mode..."); | ||
93 | |||
94 | powermgmt_init(); | ||
95 | |||
96 | /* The code will ask for the maximum possible value */ | ||
97 | usb_charging_enable(USB_CHARGING_ENABLE); | ||
98 | |||
99 | usb_init(); | ||
100 | usb_start_monitoring(); | ||
101 | |||
102 | /* Wait until USB is plugged */ | ||
103 | while (usb_detect() != USB_INSERTED) | ||
104 | { | ||
105 | printf("Plug USB cable"); | ||
106 | line--; | ||
107 | sleep(HZ/10); | ||
108 | } | ||
109 | |||
110 | while(1) | ||
111 | { | ||
112 | button = button_get_w_tmo(HZ/10); | ||
113 | |||
114 | if (button == SYS_USB_CONNECTED) | ||
115 | break; /* Hit */ | ||
116 | |||
117 | if (usb_detect() == USB_EXTRACTED) | ||
118 | break; /* Cable pulled */ | ||
119 | |||
120 | /* Wait for threads to connect or cable is pulled */ | ||
121 | printf("USB: Connecting..."); | ||
122 | line--; | ||
123 | } | ||
124 | |||
125 | if (button == SYS_USB_CONNECTED) | ||
126 | { | ||
127 | /* Got the message - wait for disconnect */ | ||
128 | printf("Bootloader USB mode"); | ||
129 | |||
130 | /* Ack the SYS_USB_CONNECTED polled from the button queue */ | ||
131 | usb_acknowledge(SYS_USB_CONNECTED_ACK); | ||
132 | |||
133 | while(1) | ||
134 | { | ||
135 | button = button_get_w_tmo(HZ/2); | ||
136 | if (button == SYS_USB_DISCONNECTED) | ||
137 | break; | ||
138 | } | ||
139 | } | ||
140 | |||
141 | /* We don't want the HDD to spin up if the USB is attached again */ | ||
142 | usb_close(); | ||
143 | printf("USB mode exit "); | ||
144 | } | ||
145 | #endif /* HAVE_BOOTLOADER_USB_MODE */ | ||
146 | |||
147 | void fatal_error(int err) | ||
148 | { | ||
149 | verbose = true; | ||
150 | |||
151 | /* System font is 6 pixels wide */ | ||
152 | line++; | ||
153 | switch (err) | ||
154 | { | ||
155 | case ERR_RB: | ||
156 | #ifdef HAVE_BOOTLOADER_USB_MODE | ||
157 | usb_mode(); | ||
158 | printf("Hold MENU+SELECT to reboot"); | ||
159 | break; | ||
160 | #endif | ||
161 | case ERR_HDD: | ||
162 | printf("Hold MENU+SELECT to reboot"); | ||
163 | printf("then SELECT+PLAY for disk mode"); | ||
164 | break; | ||
165 | case ERR_OF: | ||
166 | printf("Hold MENU+SELECT to reboot"); | ||
167 | printf("and enter Rockbox firmware"); | ||
168 | break; | ||
169 | } | ||
170 | |||
171 | if (ide_powered()) | ||
172 | ata_sleepnow(); /* Immediately spindown the disk. */ | ||
173 | |||
174 | line++; | ||
175 | lcd_set_foreground(LCD_REDORANGE); | ||
176 | while (1) { | ||
177 | lcd_puts(0, line, button_hold() ? "Hold switch on!" | ||
178 | : " "); | ||
179 | lcd_update(); | ||
180 | } | ||
181 | } | ||
182 | |||
183 | static void battery_trap(void) | ||
184 | { | ||
185 | int vbat, old_verb; | ||
186 | int th = 50; | ||
187 | |||
188 | old_verb = verbose; | ||
189 | verbose = true; | ||
190 | |||
191 | usb_charging_maxcurrent_change(100); | ||
192 | |||
193 | while (1) | ||
194 | { | ||
195 | vbat = _battery_voltage(); | ||
196 | |||
197 | /* Two reasons to use this threshold (may require adjustments): | ||
198 | * - when USB (or wall adaptor) is plugged/unplugged, Vbat readings | ||
199 | * differ as much as more than 200 mV when charge current is at | ||
200 | * maximum (~340 mA). | ||
201 | * - RB uses some sort of average/compensation for battery voltage | ||
202 | * measurements, battery icon blinks at battery_level_dangerous, | ||
203 | * when the HDD is used heavily (large database) the level drops | ||
204 | * to battery_level_shutoff quickly. | ||
205 | */ | ||
206 | if (vbat >= battery_level_dangerous[0] + th) | ||
207 | break; | ||
208 | th = 200; | ||
209 | |||
210 | if (power_input_status() != POWER_INPUT_NONE) { | ||
211 | lcd_set_foreground(LCD_RBYELLOW); | ||
212 | printf("Low battery: %d mV, charging... ", vbat); | ||
213 | sleep(HZ*3); | ||
214 | } | ||
215 | else { | ||
216 | /* Wait for the user to insert a charger */ | ||
217 | int tmo = 10; | ||
218 | lcd_set_foreground(LCD_REDORANGE); | ||
219 | while (1) { | ||
220 | vbat = _battery_voltage(); | ||
221 | printf("Low battery: %d mV, power off in %d ", vbat, tmo); | ||
222 | if (!tmo--) { | ||
223 | /* Raise Vsysok (hyst=0.02*Vsysok) to avoid PMU | ||
224 | standby<->active looping */ | ||
225 | if (vbat < 3200) | ||
226 | pmu_write(PCF5063X_REG_SVMCTL, 0xA /*3200mV*/); | ||
227 | power_off(); | ||
228 | } | ||
229 | sleep(HZ*1); | ||
230 | if (power_input_status() != POWER_INPUT_NONE) | ||
231 | break; | ||
232 | line--; | ||
233 | } | ||
234 | } | ||
235 | line--; | ||
236 | } | ||
237 | |||
238 | verbose = old_verb; | ||
239 | lcd_set_foreground(LCD_WHITE); | ||
240 | printf("Battery status ok: %d mV ", vbat); | ||
241 | } | ||
242 | |||
243 | static int launch_onb(int clkdiv) | ||
244 | { | ||
245 | /* SPI clock = PClk/(clkdiv+1) */ | ||
246 | spi_clkdiv(SPI_PORT, clkdiv); | ||
247 | |||
248 | /* Actually IRAM1_ORIG contains current RB bootloader IM3 header, | ||
249 | it will be replaced by ONB IM3 header, so this function must | ||
250 | be called once!!! */ | ||
251 | struct Im3Info *hinfo = (struct Im3Info*)IRAM1_ORIG; | ||
252 | |||
253 | /* Loads ONB in IRAM0, exception vector table is destroyed !!! */ | ||
254 | int rc = im3_read( | ||
255 | NORBOOT_OFF + im3_nor_sz(hinfo), hinfo, (void*)IRAM0_ORIG); | ||
256 | |||
257 | if (rc != 0) { | ||
258 | /* Restore exception vector table */ | ||
259 | memcpy((void*)IRAM0_ORIG, &_movestart, 4*(&start_loc-&_movestart)); | ||
260 | commit_discard_idcache(); | ||
261 | return rc; | ||
262 | } | ||
263 | |||
264 | /* Disable all external interrupts */ | ||
265 | eint_init(); | ||
266 | |||
267 | commit_discard_idcache(); | ||
268 | |||
269 | /* Branch to start of IRAM */ | ||
270 | asm volatile("mov pc, %0"::"r"(IRAM0_ORIG)); | ||
271 | while(1); | ||
272 | } | ||
273 | |||
274 | /* Launch OF when kernel mode is running */ | ||
275 | static int kernel_launch_onb(void) | ||
276 | { | ||
277 | disable_irq(); | ||
278 | int rc = launch_onb(3); /* 54/4 = 13.5 MHz. */ | ||
279 | enable_irq(); | ||
280 | return rc; | ||
281 | } | ||
282 | |||
283 | static bool pmu_is_hibernated(void) | ||
284 | { | ||
285 | /* OF sets GPIO3 to low when SDRAM is hibernated */ | ||
286 | return !(pmu_rd(PCF5063X_REG_GPIO3CFG) & 7) && | ||
287 | !(pmu_rd(PCF5063X_REG_OOCSHDWN) & PCF5063X_OOCSHDWN_COLDBOOT); | ||
288 | } | ||
289 | |||
290 | /* The boot sequence is executed on power-on or reset. After power-up | ||
291 | * the device could come from a state of hibernation, OF hibernates | ||
292 | * the iPod after an inactive period of ~30 minutes (FW 1.1.2), on | ||
293 | * this state the SDRAM is in self-refresh mode. | ||
294 | * | ||
295 | * t0 = 0 | ||
296 | * S5L8702 BOOTROM loads an IM3 image located at NOR: | ||
297 | * - IM3 header (first 0x800 bytes) is loaded at IRAM1_ORIG | ||
298 | * - IM3 body (decrypted RB bootloader) is loaded at IRAM0_ORIG | ||
299 | * The time needed to load the RB bootloader (~90 Kb) is estimated | ||
300 | * on 200~250 ms. Once executed, RB booloader moves itself from | ||
301 | * IRAM0_ORIG to IRAM1_ORIG+0x800, preserving current IM3 header | ||
302 | * that contains the NOR offset where the ONB (original NOR boot), | ||
303 | * is located (see dualboot.c for details). | ||
304 | * | ||
305 | * t1 = ~250 ms. | ||
306 | * If the PMU is hibernated, decrypted ONB (size 128Kb) is loaded | ||
307 | * and executed, it takes ~120 ms. Then the ONB restores the | ||
308 | * iPod to the state prior to hibernation. | ||
309 | * If not, initialize system and RB kernel, wait for t2. | ||
310 | * | ||
311 | * t2 = ~650 ms. | ||
312 | * Check user button selection. | ||
313 | * If OF, diagmode, or diskmode is selected then launch ONB. | ||
314 | * If not, wait for LCD initialization. | ||
315 | * | ||
316 | * t3 = ~700,~900 ms. (lcd_type_01,lcd_type_23) | ||
317 | * LCD is initialized, baclight ON. | ||
318 | * Wait for HDD spin-up. | ||
319 | * | ||
320 | * t4 = ~2600,~2800 ms. | ||
321 | * HDD is ready. | ||
322 | * If hold switch is locked, then load and launch ONB. | ||
323 | * If not, load rockbox.ipod file from HDD. | ||
324 | * | ||
325 | * t5 = ~2800,~3000 ms. | ||
326 | * rockbox.ipod is executed. | ||
327 | */ | ||
328 | void main(void) | ||
329 | { | ||
330 | int fw = FW_ROCKBOX; | ||
331 | int rc = 0; | ||
332 | unsigned char *loadbuffer; | ||
333 | int (*kernel_entry)(void); | ||
334 | |||
335 | usec_timer_init(); | ||
336 | |||
337 | /* Configure I2C0 */ | ||
338 | i2c_preinit(0); | ||
339 | |||
340 | if (pmu_is_hibernated()) { | ||
341 | fw = FW_APPLE; | ||
342 | rc = launch_onb(1); /* 27/2 = 13.5 MHz. */ | ||
343 | } | ||
344 | |||
345 | system_preinit(); | ||
346 | memory_init(); | ||
347 | /* | ||
348 | * XXX: BSS is initialized here, do not use .bss before this line | ||
349 | */ | ||
350 | bss_init(); | ||
351 | |||
352 | system_init(); | ||
353 | kernel_init(); | ||
354 | i2c_init(); | ||
355 | power_init(); | ||
356 | |||
357 | enable_irq(); | ||
358 | |||
359 | #ifdef HAVE_SERIAL | ||
360 | serial_setup(); | ||
361 | #endif | ||
362 | |||
363 | button_init(); | ||
364 | if (rc == 0) { | ||
365 | /* User button selection timeout */ | ||
366 | while (USEC_TIMER < 400000); | ||
367 | int btn = button_read_device(); | ||
368 | /* This prevents HDD spin-up when the user enters DFU */ | ||
369 | if (btn == (BUTTON_SELECT|BUTTON_MENU)) { | ||
370 | while (button_read_device() == (BUTTON_SELECT|BUTTON_MENU)) | ||
371 | sleep(HZ/10); | ||
372 | sleep(HZ); | ||
373 | btn = button_read_device(); | ||
374 | } | ||
375 | /* Enter OF, diagmode and diskmode using ONB */ | ||
376 | if ((btn == BUTTON_MENU) | ||
377 | || (btn == (BUTTON_SELECT|BUTTON_LEFT)) | ||
378 | || (btn == (BUTTON_SELECT|BUTTON_PLAY))) { | ||
379 | fw = FW_APPLE; | ||
380 | rc = kernel_launch_onb(); | ||
381 | } | ||
382 | } | ||
383 | |||
384 | lcd_init(); | ||
385 | lcd_set_foreground(LCD_WHITE); | ||
386 | lcd_set_background(LCD_BLACK); | ||
387 | lcd_clear_display(); | ||
388 | font_init(); | ||
389 | lcd_setfont(FONT_SYSFIXED); | ||
390 | lcd_update(); | ||
391 | sleep(HZ/40); | ||
392 | |||
393 | verbose = true; | ||
394 | |||
395 | printf("Rockbox boot loader"); | ||
396 | printf("Version: %s", rbversion); | ||
397 | |||
398 | backlight_init(); /* Turns on the backlight */ | ||
399 | |||
400 | if (rc == 0) { | ||
401 | /* Wait until there is enought power to spin-up HDD */ | ||
402 | battery_trap(); | ||
403 | |||
404 | rc = storage_init(); | ||
405 | if (rc != 0) { | ||
406 | printf("ATA error: %d", rc); | ||
407 | fatal_error(ERR_HDD); | ||
408 | } | ||
409 | |||
410 | filesystem_init(); | ||
411 | |||
412 | /* We wait until HDD spins up to check for hold button */ | ||
413 | if (button_hold()) { | ||
414 | fw = FW_APPLE; | ||
415 | printf("Executing OF..."); | ||
416 | ata_sleepnow(); | ||
417 | rc = kernel_launch_onb(); | ||
418 | } | ||
419 | } | ||
420 | |||
421 | if (rc != 0) { | ||
422 | printf("Load OF error: %d", rc); | ||
423 | fatal_error(ERR_OF); | ||
424 | } | ||
425 | |||
426 | #ifdef HAVE_BOOTLOADER_USB_MODE | ||
427 | /* Enter USB mode if SELECT+RIGHT are pressed */ | ||
428 | if (button_read_device() == (BUTTON_SELECT|BUTTON_RIGHT)) | ||
429 | usb_mode(); | ||
430 | #endif | ||
431 | |||
432 | rc = disk_mount_all(); | ||
433 | if (rc <= 0) { | ||
434 | printf("No partition found"); | ||
435 | fatal_error(ERR_RB); | ||
436 | } | ||
437 | |||
438 | printf("Loading Rockbox..."); | ||
439 | loadbuffer = (unsigned char *)DRAM_ORIG; | ||
440 | rc = load_firmware(loadbuffer, BOOTFILE, MAX_LOADSIZE); | ||
441 | |||
442 | if (rc <= EFILE_EMPTY) { | ||
443 | printf("Error!"); | ||
444 | printf("Can't load " BOOTFILE ": "); | ||
445 | printf(loader_strerror(rc)); | ||
446 | fatal_error(ERR_RB); | ||
447 | } | ||
448 | |||
449 | printf("Rockbox loaded."); | ||
450 | |||
451 | /* If we get here, we have a new firmware image at 0x08000000, run it */ | ||
452 | disable_irq(); | ||
453 | |||
454 | kernel_entry = (void*) loadbuffer; | ||
455 | commit_discard_idcache(); | ||
456 | rc = kernel_entry(); | ||
457 | |||
458 | /* End stop - should not get here */ | ||
459 | enable_irq(); | ||
460 | printf("ERR: Failed to boot"); | ||
461 | while(1); | ||
462 | } | ||
diff --git a/firmware/SOURCES b/firmware/SOURCES index 88e40fa74f..09716be40e 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -1597,12 +1597,12 @@ target/arm/s5l8700/ipodnano2g/piezo-nano2g.c | |||
1597 | #ifdef IPOD_6G | 1597 | #ifdef IPOD_6G |
1598 | target/arm/ipod/button-clickwheel.c | 1598 | target/arm/ipod/button-clickwheel.c |
1599 | target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c | 1599 | target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c |
1600 | target/arm/s5l8702/ipod6g/cscodec-ipod6g.c | ||
1601 | target/arm/s5l8702/ipod6g/backlight-ipod6g.c | 1600 | target/arm/s5l8702/ipod6g/backlight-ipod6g.c |
1602 | target/arm/s5l8702/ipod6g/powermgmt-ipod6g.c | 1601 | target/arm/s5l8702/ipod6g/powermgmt-ipod6g.c |
1603 | target/arm/s5l8702/ipod6g/power-ipod6g.c | 1602 | target/arm/s5l8702/ipod6g/power-ipod6g.c |
1604 | target/arm/s5l8702/kernel-s5l8702.c | 1603 | target/arm/s5l8702/kernel-s5l8702.c |
1605 | target/arm/s5l8702/system-s5l8702.c | 1604 | target/arm/s5l8702/system-s5l8702.c |
1605 | target/arm/s5l8702/timer-s5l8702.c | ||
1606 | target/arm/s5l8702/gpio-s5l8702.c | 1606 | target/arm/s5l8702/gpio-s5l8702.c |
1607 | target/arm/s5l8702/pl080.c | 1607 | target/arm/s5l8702/pl080.c |
1608 | target/arm/s5l8702/dma-s5l8702.c | 1608 | target/arm/s5l8702/dma-s5l8702.c |
@@ -1615,24 +1615,26 @@ target/arm/s5l8702/postmortemstub.S | |||
1615 | #endif | 1615 | #endif |
1616 | target/arm/s5l8702/ipod6g/pmu-ipod6g.c | 1616 | target/arm/s5l8702/ipod6g/pmu-ipod6g.c |
1617 | target/arm/s5l8702/ipod6g/rtc-ipod6g.c | 1617 | target/arm/s5l8702/ipod6g/rtc-ipod6g.c |
1618 | target/arm/s5l8702/ipod6g/adc-ipod6g.c | ||
1619 | #if !defined(BOOTLOADER) || defined(HAVE_BOOTLOADER_USB_MODE) | ||
1618 | target/arm/s5l8702/usb-s5l8702.c | 1620 | target/arm/s5l8702/usb-s5l8702.c |
1621 | #endif | ||
1619 | #ifdef HAVE_SERIAL | 1622 | #ifdef HAVE_SERIAL |
1620 | target/arm/uc870x.c | 1623 | target/arm/uc870x.c |
1621 | target/arm/s5l8702/uart-s5l8702.c | 1624 | target/arm/s5l8702/uart-s5l8702.c |
1622 | target/arm/s5l8702/ipod6g/serial-ipod6g.c | 1625 | target/arm/s5l8702/ipod6g/serial-ipod6g.c |
1623 | #endif | 1626 | #endif |
1624 | #ifndef BOOTLOADER | 1627 | #ifndef BOOTLOADER |
1625 | target/arm/s5l8702/timer-s5l8702.c | ||
1626 | target/arm/s5l8702/debug-s5l8702.c | 1628 | target/arm/s5l8702/debug-s5l8702.c |
1627 | target/arm/s5l8702/pcm-s5l8702.c | 1629 | target/arm/s5l8702/pcm-s5l8702.c |
1628 | target/arm/s5l8702/ipod6g/audio-ipod6g.c | 1630 | target/arm/s5l8702/ipod6g/audio-ipod6g.c |
1629 | target/arm/s5l8702/ipod6g/adc-ipod6g.c | 1631 | target/arm/s5l8702/ipod6g/cscodec-ipod6g.c |
1630 | #else | 1632 | #else |
1631 | target/arm/s5l8702/spi-s5l8702.c | 1633 | target/arm/s5l8702/spi-s5l8702.c |
1632 | target/arm/s5l8702/crypto-s5l8702.c | 1634 | target/arm/s5l8702/crypto-s5l8702.c |
1633 | target/arm/s5l8702/nor-s5l8702.c | 1635 | target/arm/s5l8702/nor-s5l8702.c |
1634 | #endif | 1636 | #endif /* BOOTLOADER */ |
1635 | #endif | 1637 | #endif /* IPOD_6G */ |
1636 | 1638 | ||
1637 | #if CONFIG_CPU == RK27XX | 1639 | #if CONFIG_CPU == RK27XX |
1638 | target/arm/rk27xx/audio-rk27xx.c | 1640 | target/arm/rk27xx/audio-rk27xx.c |
diff --git a/firmware/export/config.h b/firmware/export/config.h index e7cfc698df..efad75f1b2 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h | |||
@@ -872,8 +872,12 @@ Lyre prototype 1 */ | |||
872 | #ifdef HAVE_BOOTLOADER_USB_MODE | 872 | #ifdef HAVE_BOOTLOADER_USB_MODE |
873 | /* Priority in bootloader is wanted */ | 873 | /* Priority in bootloader is wanted */ |
874 | #define HAVE_PRIORITY_SCHEDULING | 874 | #define HAVE_PRIORITY_SCHEDULING |
875 | #if (CONFIG_CPU == S5L8702) | ||
876 | #define USB_DRIVER_CLOSE | ||
877 | #else | ||
875 | #define USB_STATUS_BY_EVENT | 878 | #define USB_STATUS_BY_EVENT |
876 | #define USB_DETECT_BY_REQUEST | 879 | #define USB_DETECT_BY_REQUEST |
880 | #endif | ||
877 | #if defined(HAVE_USBSTACK) && CONFIG_USBOTG == USBOTG_ARC | 881 | #if defined(HAVE_USBSTACK) && CONFIG_USBOTG == USBOTG_ARC |
878 | #define INCLUDE_TIMEOUT_API | 882 | #define INCLUDE_TIMEOUT_API |
879 | #define USB_DRIVER_CLOSE | 883 | #define USB_DRIVER_CLOSE |
diff --git a/firmware/export/config/ipod6g.h b/firmware/export/config/ipod6g.h index 01934a0cc2..5494cf387a 100644 --- a/firmware/export/config/ipod6g.h +++ b/firmware/export/config/ipod6g.h | |||
@@ -248,14 +248,27 @@ | |||
248 | #define USB_VENDOR_ID 0x05AC | 248 | #define USB_VENDOR_ID 0x05AC |
249 | #define USB_PRODUCT_ID 0x1261 | 249 | #define USB_PRODUCT_ID 0x1261 |
250 | #define USB_DEVBSS_ATTR __attribute__((aligned(32))) | 250 | #define USB_DEVBSS_ATTR __attribute__((aligned(32))) |
251 | #define HAVE_BOOTLOADER_USB_MODE | ||
252 | #ifdef BOOTLOADER | ||
253 | #define USBPOWER_BTN_IGNORE (~0) | ||
254 | #endif | ||
251 | 255 | ||
252 | #define USB_READ_BUFFER_SIZE (1024*24) | 256 | #define USB_READ_BUFFER_SIZE (1024*24) |
253 | 257 | ||
258 | /* Serial */ | ||
259 | #ifdef BOOTLOADER | ||
260 | #if 0 /* Enable/disable LOGF_SERIAL for bootloader */ | ||
261 | #define HAVE_SERIAL | ||
262 | #define ROCKBOX_HAS_LOGF | ||
263 | #define LOGF_SERIAL | ||
264 | #endif | ||
265 | #else /* !BOOTLOADER */ | ||
254 | #define HAVE_SERIAL | 266 | #define HAVE_SERIAL |
255 | /* Disable iAP when LOGF_SERIAL is enabled to avoid conflicts */ | 267 | /* Disable iAP when LOGF_SERIAL is enabled to avoid conflicts */ |
256 | #ifndef LOGF_SERIAL | 268 | #ifndef LOGF_SERIAL |
257 | #define IPOD_ACCESSORY_PROTOCOL | 269 | #define IPOD_ACCESSORY_PROTOCOL |
258 | #endif | 270 | #endif |
271 | #endif | ||
259 | 272 | ||
260 | /* Define this if you can switch on/off the accessory power supply */ | 273 | /* Define this if you can switch on/off the accessory power supply */ |
261 | #define HAVE_ACCESSORY_SUPPLY | 274 | #define HAVE_ACCESSORY_SUPPLY |
diff --git a/firmware/target/arm/s5l8702/boot.lds b/firmware/target/arm/s5l8702/boot.lds index 2885f77eda..61f23b9c22 100644 --- a/firmware/target/arm/s5l8702/boot.lds +++ b/firmware/target/arm/s5l8702/boot.lds | |||
@@ -1,5 +1,6 @@ | |||
1 | #define ASM | 1 | #define ASM |
2 | #include "config.h" | 2 | #include "config.h" |
3 | #include "cpu.h" | ||
3 | 4 | ||
4 | ENTRY(start) | 5 | ENTRY(start) |
5 | #ifdef ROCKBOX_LITTLE_ENDIAN | 6 | #ifdef ROCKBOX_LITTLE_ENDIAN |
@@ -10,13 +11,11 @@ OUTPUT_FORMAT(elf32-bigarm) | |||
10 | OUTPUT_ARCH(arm) | 11 | OUTPUT_ARCH(arm) |
11 | STARTUP(target/arm/s5l8702/crt0.o) | 12 | STARTUP(target/arm/s5l8702/crt0.o) |
12 | 13 | ||
14 | #define MAX_LOADSIZE 8M /* reserved for loading Rockbox binary */ | ||
15 | |||
13 | #ifdef IPOD_NANO2G | 16 | #ifdef IPOD_NANO2G |
14 | #define DRAMORIG 0x08000000 + ((MEMORYSIZE - 1) * 0x100000) | 17 | #define DRAMORIG 0x08000000 + ((MEMORYSIZE - 1) * 0x100000) |
15 | #define DRAMSIZE 0x00100000 | 18 | #define DRAMSIZE 0x00100000 |
16 | #else | ||
17 | #define DRAMORIG 0x08000000 | ||
18 | #define DRAMSIZE (DRAM_SIZE - TTB_SIZE) | ||
19 | #endif | ||
20 | 19 | ||
21 | #define IRAMORIG 0x22000000 | 20 | #define IRAMORIG 0x22000000 |
22 | #define IRAMSIZE 256K | 21 | #define IRAMSIZE 256K |
@@ -26,17 +25,47 @@ MEMORY | |||
26 | DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE | 25 | DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE |
27 | IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE | 26 | IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE |
28 | } | 27 | } |
29 | |||
30 | #define LOAD_AREA IRAM | 28 | #define LOAD_AREA IRAM |
29 | #define VECT_AREA IRAM | ||
30 | #define BSS_AREA DRAM | ||
31 | |||
32 | #elif defined(IPOD_6G) | ||
33 | MEMORY | ||
34 | { | ||
35 | DRAM : ORIGIN = DRAM_ORIG, LENGTH = DRAM_SIZE | ||
36 | IRAM : ORIGIN = IRAM_ORIG, LENGTH = IRAM_SIZE | ||
37 | |||
38 | /* s5l8702 maps address 0 to ROM, IRAM or DRAM */ | ||
39 | VECT_AREA : ORIGIN = 0, LENGTH = 1K | ||
40 | |||
41 | /* IRAM region where loaded IM3 body will be moved and executed, | ||
42 | preserving the loaded IM3 header (0x800 bytes) at IRAM1_ORIG */ | ||
43 | MOVE_AREA : ORIGIN = IRAM1_ORIG + 0x800, | ||
44 | LENGTH = IRAM1_SIZE - 0x800 | ||
45 | |||
46 | /* DRAM region for BSS */ | ||
47 | BSS_AREA : ORIGIN = DRAM_ORIG + MAX_LOADSIZE, | ||
48 | LENGTH = DRAM_SIZE - MAX_LOADSIZE - TTB_SIZE | ||
49 | } | ||
50 | #define LOAD_AREA MOVE_AREA | ||
51 | |||
52 | #else | ||
53 | #error No target defined! | ||
54 | #endif | ||
55 | |||
31 | 56 | ||
32 | SECTIONS | 57 | SECTIONS |
33 | { | 58 | { |
59 | _dfuloadaddr = IRAM0_ORIG ; | ||
60 | _movestart = LOADADDR(.text) ; | ||
61 | _moveend = LOADADDR(.data) + SIZEOF(.data) ; | ||
62 | |||
34 | #ifdef NEEDS_INTVECT_COPYING | 63 | #ifdef NEEDS_INTVECT_COPYING |
35 | .intvect : { | 64 | .intvect : { |
36 | _intvectstart = . ; | 65 | _intvectstart = . ; |
37 | *(.intvect) | 66 | *(.intvect) |
38 | _intvectend = _newstart ; | 67 | _intvectend = _newstart ; |
39 | } >IRAM AT> LOAD_AREA | 68 | } >VECT_AREA AT> LOAD_AREA |
40 | _intvectcopy = LOADADDR(.intvect) ; | 69 | _intvectcopy = LOADADDR(.intvect) ; |
41 | #endif | 70 | #endif |
42 | 71 | ||
@@ -61,10 +90,9 @@ SECTIONS | |||
61 | *(.idata*) | 90 | *(.idata*) |
62 | *(.data*) | 91 | *(.data*) |
63 | *(.ncdata*); | 92 | *(.ncdata*); |
64 | . = ALIGN(0x4); | 93 | . = ALIGN(0x20); /* align move size */ |
65 | _dataend = . ; | 94 | _dataend = . ; |
66 | } > IRAM AT> LOAD_AREA | 95 | } > LOAD_AREA |
67 | _datacopy = LOADADDR(.data) ; | ||
68 | 96 | ||
69 | .stack (NOLOAD) : | 97 | .stack (NOLOAD) : |
70 | { | 98 | { |
@@ -80,7 +108,7 @@ SECTIONS | |||
80 | _fiqstackbegin = .; | 108 | _fiqstackbegin = .; |
81 | . += 0x400; | 109 | . += 0x400; |
82 | _fiqstackend = .; | 110 | _fiqstackend = .; |
83 | } > IRAM | 111 | } > LOAD_AREA |
84 | 112 | ||
85 | .bss (NOLOAD) : { | 113 | .bss (NOLOAD) : { |
86 | _edata = .; | 114 | _edata = .; |
@@ -88,7 +116,7 @@ SECTIONS | |||
88 | *(.ibss*); | 116 | *(.ibss*); |
89 | *(.ncbss*); | 117 | *(.ncbss*); |
90 | *(COMMON); | 118 | *(COMMON); |
91 | . = ALIGN(0x4); | 119 | . = ALIGN(0x20); /* align bzero size */ |
92 | _end = .; | 120 | _end = .; |
93 | } > IRAM | 121 | } > BSS_AREA |
94 | } | 122 | } |
diff --git a/firmware/target/arm/s5l8702/crt0.S b/firmware/target/arm/s5l8702/crt0.S index 3d1ee2bdfd..915c3f680b 100644 --- a/firmware/target/arm/s5l8702/crt0.S +++ b/firmware/target/arm/s5l8702/crt0.S | |||
@@ -46,17 +46,20 @@ newstart2: | |||
46 | msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */ | 46 | msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */ |
47 | 47 | ||
48 | #ifdef BOOTLOADER | 48 | #ifdef BOOTLOADER |
49 | /* Relocate ourself to IRAM - we have been loaded to DRAM */ | 49 | /* Relocate ourself to IRAM1 - we have been loaded to IRAM0 */ |
50 | mov r0, #0x08000000 /* source (DRAM) */ | 50 | ldr r0, =_dfuloadaddr |
51 | mov r1, #0x22000000 /* dest (IRAM) */ | 51 | ldr r1, =_movestart |
52 | ldr r2, =_dataend | 52 | ldr r2, =_moveend |
53 | 1: | 53 | 1: |
54 | cmp r2, r1 | 54 | ldmia r0!, {r3-r10} |
55 | ldrhi r3, [r0], #4 | 55 | stmia r1!, {r3-r10} |
56 | strhi r3, [r1], #4 | 56 | cmp r1, r2 |
57 | bhi 1b | 57 | blt 1b |
58 | 58 | ||
59 | ldr pc, =start_loc /* jump to the relocated start_loc: */ | 59 | ldr pc, =start_loc /* jump to the relocated start_loc: */ |
60 | |||
61 | .section .init.text,"ax",%progbits | ||
62 | .global start_loc | ||
60 | start_loc: | 63 | start_loc: |
61 | #endif | 64 | #endif |
62 | 65 | ||
@@ -66,11 +69,11 @@ start_loc: | |||
66 | mcr p15, 0, r0, c1, c0, 0 /* disable caches and protection unit */ | 69 | mcr p15, 0, r0, c1, c0, 0 /* disable caches and protection unit */ |
67 | 70 | ||
68 | .cleancache: | 71 | .cleancache: |
69 | mrc p15, 0, r15,c7,c10,3 | 72 | mrc p15, 0, r15, c7, c10, 3 /* test and clean dcache */ |
70 | bne .cleancache | 73 | bne .cleancache |
71 | mov r0, #0 | 74 | mov r0, #0 |
72 | mcr p15, 0, r0,c7,c10,4 | 75 | mcr p15, 0, r0, c7, c10, 4 /* drain write buffer */ |
73 | mcr p15, 0, r0,c7,c5,0 | 76 | mcr p15, 0, r0, c7, c5, 0 /* invalidate icache */ |
74 | 77 | ||
75 | /* reset VIC controller */ | 78 | /* reset VIC controller */ |
76 | ldr r1, =0x38e00000 | 79 | ldr r1, =0x38e00000 |
@@ -86,7 +89,15 @@ start_loc: | |||
86 | str r0, [r1,#0x14] | 89 | str r0, [r1,#0x14] |
87 | str r0, [r2,#0x14] | 90 | str r0, [r2,#0x14] |
88 | 91 | ||
89 | #if !defined(BOOTLOADER) | 92 | #if defined(BOOTLOADER) |
93 | /* SPI speed is limited when icache is not active. Not worth | ||
94 | * activating dcache, it is almost useless on pre-init stage | ||
95 | * and the TLB needs 16Kb in detriment of the bootloader. | ||
96 | */ | ||
97 | mrc p15, 0, r0, c1, c0, 0 | ||
98 | orr r0, r0, #1<<12 /* enable icache */ | ||
99 | mcr p15, 0, r0, c1, c0, 0 | ||
100 | #else | ||
90 | bl memory_init | 101 | bl memory_init |
91 | 102 | ||
92 | /* Copy interrupt vectors to iram */ | 103 | /* Copy interrupt vectors to iram */ |
@@ -98,7 +109,6 @@ start_loc: | |||
98 | ldrhi r1, [r4], #4 | 109 | ldrhi r1, [r4], #4 |
99 | strhi r1, [r2], #4 | 110 | strhi r1, [r2], #4 |
100 | bhi 1b | 111 | bhi 1b |
101 | #endif | ||
102 | 112 | ||
103 | /* Initialise bss section to zero */ | 113 | /* Initialise bss section to zero */ |
104 | ldr r2, =_edata | 114 | ldr r2, =_edata |
@@ -109,7 +119,6 @@ start_loc: | |||
109 | strhi r4, [r2], #4 | 119 | strhi r4, [r2], #4 |
110 | bhi 1b | 120 | bhi 1b |
111 | 121 | ||
112 | #ifndef BOOTLOADER | ||
113 | /* Copy icode and data to ram */ | 122 | /* Copy icode and data to ram */ |
114 | ldr r2, =_iramstart | 123 | ldr r2, =_iramstart |
115 | ldr r3, =_iramend | 124 | ldr r3, =_iramend |
@@ -159,3 +168,33 @@ start_loc: | |||
159 | bhi 1b | 168 | bhi 1b |
160 | 169 | ||
161 | b main | 170 | b main |
171 | |||
172 | #ifdef BOOTLOADER | ||
173 | /* Initialise bss section to zero */ | ||
174 | .global bss_init | ||
175 | .type bss_init, %function | ||
176 | |||
177 | bss_init: | ||
178 | stmfd sp!, {r4-r9,lr} | ||
179 | |||
180 | ldr r0, =_edata | ||
181 | ldr r1, =_end | ||
182 | mov r2, #0 | ||
183 | mov r3, #0 | ||
184 | mov r4, #0 | ||
185 | mov r5, #0 | ||
186 | mov r6, #0 | ||
187 | mov r7, #0 | ||
188 | mov r8, #0 | ||
189 | mov r9, #0 | ||
190 | b 2f | ||
191 | .align 5 /* cache line size */ | ||
192 | 1: | ||
193 | stmia r0!, {r2-r9} | ||
194 | 2: | ||
195 | cmp r0, r1 | ||
196 | blt 1b | ||
197 | |||
198 | ldmpc regs=r4-r9 | ||
199 | .ltorg | ||
200 | #endif | ||