summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bootloader/SOURCES2
-rw-r--r--bootloader/ipod6g.c462
-rw-r--r--firmware/SOURCES12
-rw-r--r--firmware/export/config.h4
-rw-r--r--firmware/export/config/ipod6g.h13
-rw-r--r--firmware/target/arm/s5l8702/boot.lds54
-rw-r--r--firmware/target/arm/s5l8702/crt0.S67
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)
4ipodnano2g.c 4ipodnano2g.c
5#elif defined(IPOD_6G)
6ipod6g.c
5#elif defined(IPOD_ARCH) 7#elif defined(IPOD_ARCH)
6ipod.c 8ipod.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
79extern void bss_init(void);
80extern uint32_t _movestart;
81extern uint32_t start_loc;
82
83extern int line;
84
85#ifdef HAVE_BOOTLOADER_USB_MODE
86static 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
147void 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
183static 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
243static 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 */
275static 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
283static 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 */
328void 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
1598target/arm/ipod/button-clickwheel.c 1598target/arm/ipod/button-clickwheel.c
1599target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c 1599target/arm/s5l8702/ipod6g/storage_ata-ipod6g.c
1600target/arm/s5l8702/ipod6g/cscodec-ipod6g.c
1601target/arm/s5l8702/ipod6g/backlight-ipod6g.c 1600target/arm/s5l8702/ipod6g/backlight-ipod6g.c
1602target/arm/s5l8702/ipod6g/powermgmt-ipod6g.c 1601target/arm/s5l8702/ipod6g/powermgmt-ipod6g.c
1603target/arm/s5l8702/ipod6g/power-ipod6g.c 1602target/arm/s5l8702/ipod6g/power-ipod6g.c
1604target/arm/s5l8702/kernel-s5l8702.c 1603target/arm/s5l8702/kernel-s5l8702.c
1605target/arm/s5l8702/system-s5l8702.c 1604target/arm/s5l8702/system-s5l8702.c
1605target/arm/s5l8702/timer-s5l8702.c
1606target/arm/s5l8702/gpio-s5l8702.c 1606target/arm/s5l8702/gpio-s5l8702.c
1607target/arm/s5l8702/pl080.c 1607target/arm/s5l8702/pl080.c
1608target/arm/s5l8702/dma-s5l8702.c 1608target/arm/s5l8702/dma-s5l8702.c
@@ -1615,24 +1615,26 @@ target/arm/s5l8702/postmortemstub.S
1615#endif 1615#endif
1616target/arm/s5l8702/ipod6g/pmu-ipod6g.c 1616target/arm/s5l8702/ipod6g/pmu-ipod6g.c
1617target/arm/s5l8702/ipod6g/rtc-ipod6g.c 1617target/arm/s5l8702/ipod6g/rtc-ipod6g.c
1618target/arm/s5l8702/ipod6g/adc-ipod6g.c
1619#if !defined(BOOTLOADER) || defined(HAVE_BOOTLOADER_USB_MODE)
1618target/arm/s5l8702/usb-s5l8702.c 1620target/arm/s5l8702/usb-s5l8702.c
1621#endif
1619#ifdef HAVE_SERIAL 1622#ifdef HAVE_SERIAL
1620target/arm/uc870x.c 1623target/arm/uc870x.c
1621target/arm/s5l8702/uart-s5l8702.c 1624target/arm/s5l8702/uart-s5l8702.c
1622target/arm/s5l8702/ipod6g/serial-ipod6g.c 1625target/arm/s5l8702/ipod6g/serial-ipod6g.c
1623#endif 1626#endif
1624#ifndef BOOTLOADER 1627#ifndef BOOTLOADER
1625target/arm/s5l8702/timer-s5l8702.c
1626target/arm/s5l8702/debug-s5l8702.c 1628target/arm/s5l8702/debug-s5l8702.c
1627target/arm/s5l8702/pcm-s5l8702.c 1629target/arm/s5l8702/pcm-s5l8702.c
1628target/arm/s5l8702/ipod6g/audio-ipod6g.c 1630target/arm/s5l8702/ipod6g/audio-ipod6g.c
1629target/arm/s5l8702/ipod6g/adc-ipod6g.c 1631target/arm/s5l8702/ipod6g/cscodec-ipod6g.c
1630#else 1632#else
1631target/arm/s5l8702/spi-s5l8702.c 1633target/arm/s5l8702/spi-s5l8702.c
1632target/arm/s5l8702/crypto-s5l8702.c 1634target/arm/s5l8702/crypto-s5l8702.c
1633target/arm/s5l8702/nor-s5l8702.c 1635target/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
1638target/arm/rk27xx/audio-rk27xx.c 1640target/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
4ENTRY(start) 5ENTRY(start)
5#ifdef ROCKBOX_LITTLE_ENDIAN 6#ifdef ROCKBOX_LITTLE_ENDIAN
@@ -10,13 +11,11 @@ OUTPUT_FORMAT(elf32-bigarm)
10OUTPUT_ARCH(arm) 11OUTPUT_ARCH(arm)
11STARTUP(target/arm/s5l8702/crt0.o) 12STARTUP(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)
33MEMORY
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
32SECTIONS 57SECTIONS
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
531: 531:
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
60start_loc: 63start_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
177bss_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 */
1921:
193 stmia r0!, {r2-r9}
1942:
195 cmp r0, r1
196 blt 1b
197
198 ldmpc regs=r4-r9
199 .ltorg
200#endif