blob: d808fc8aa95af7e66466e0eb79cd55b0b38e7a23 [file] [log] [blame]
Amaury Pouly08fb3f62011-05-01 13:02:46 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2011 by amaury Pouly
11 *
12 * Based on Rockbox iriver bootloader by Linus Nielsen Feltzing
13 * and the ipodlinux bootloader by Daniel Palffy and Bernard Leach
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24
25#include <stdio.h>
26#include <system.h>
27#include <inttypes.h>
28#include "config.h"
29#include "gcc_extensions.h"
30#include "lcd.h"
31#include "backlight.h"
32#include "button-target.h"
33#include "common.h"
34#include "storage.h"
35#include "disk.h"
36#include "panic.h"
37#include "power.h"
Amaury Pouly86e8c282011-05-11 22:38:09 +000038#include "system-target.h"
Amaury Pouly5a268112011-07-09 17:14:05 +000039#include "fmradio_i2c.h"
Amaury Pouly0b885f22011-12-26 19:13:29 +000040#include "version.h"
Amaury Pouly2cf33132011-06-17 22:30:58 +000041
42#include "usb.h"
Amaury Pouly7d4fed52011-09-05 11:29:32 +000043
Amaury Poulyd945c362011-09-13 23:38:08 +000044extern char loadaddress[];
45extern char loadaddressend[];
Amaury Pouly7d4fed52011-09-05 11:29:32 +000046
47#ifdef HAVE_BOOTLOADER_USB_MODE
48static void usb_mode(int connect_timeout)
49{
50 int button;
51
52 usb_init();
53 usb_start_monitoring();
54
55 /* Wait for threads to connect or cable is pulled */
56 printf("USB: Connecting");
57
58 long end_tick = current_tick + connect_timeout;
59
60 while(1)
61 {
62 button = button_get_w_tmo(HZ/10);
63
64 if(button == SYS_USB_CONNECTED)
65 break; /* Hit */
66
67 if(TIME_AFTER(current_tick, end_tick))
68 {
69 /* Timed out waiting for the connect - will happen when connected
70 * to a charger through the USB port */
71 printf("USB: Timed out");
72 break;
73 }
74
Rafaël Carré2115eac2011-12-31 18:43:59 +000075 if(usb_detect() == USB_EXTRACTED)
Amaury Pouly7d4fed52011-09-05 11:29:32 +000076 break; /* Cable pulled */
77 }
78
79 if(button == SYS_USB_CONNECTED)
80 {
81 /* Got the message - wait for disconnect */
82 printf("Bootloader USB mode");
83
84 usb_acknowledge(SYS_USB_CONNECTED_ACK);
85
86 while(1)
87 {
88 button = button_get_w_tmo(HZ/2);
89 if(button == SYS_USB_DISCONNECTED)
90 break;
91 }
92 }
93
94 /* Put drivers initialized for USB connection into a known state */
95 usb_close();
Amaury Pouly7d4fed52011-09-05 11:29:32 +000096}
97#else /* !HAVE_BOOTLOADER_USB_MODE */
98static void usb_mode(int connect_timeout)
99{
100 (void) connect_timeout;
101}
102#endif /* HAVE_BOOTLOADER_USB_MODE */
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000103
Amaury Pouly1322b582011-09-23 20:40:52 +0000104void main(uint32_t arg, uint32_t addr) NORETURN_ATTR;
105void main(uint32_t arg, uint32_t addr)
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000106{
107 unsigned char* loadbuffer;
108 int buffer_size;
109 void(*kernel_entry)(void);
110 int ret;
111
112 system_init();
113 kernel_init();
114
Amaury Pouly7d4fed52011-09-05 11:29:32 +0000115 power_init();
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000116 enable_irq();
117
118 lcd_init();
Amaury Pouly82ecc752011-07-02 02:12:10 +0000119 lcd_clear_display();
120 lcd_update();
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000121
122 backlight_init();
123
Amaury Pouly7d4fed52011-09-05 11:29:32 +0000124 button_init();
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000125
Amaury Pouly2cf33132011-06-17 22:30:58 +0000126 //button_debug_screen();
Amaury Pouly0b885f22011-12-26 19:13:29 +0000127 printf("Boot version: %s", RBVERSION);
Amaury Pouly1322b582011-09-23 20:40:52 +0000128 printf("arg=%x addr=%x", arg, addr);
Amaury Pouly7d4fed52011-09-05 11:29:32 +0000129
130#ifdef SANSA_FUZEPLUS
131 extern void imx233_mmc_disable_window(void);
132 if(arg == 0xfee1dead)
133 {
134 printf("Disable MMC window.");
135 imx233_mmc_disable_window();
136 }
137#endif
Amaury Pouly86e8c282011-05-11 22:38:09 +0000138
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000139 ret = storage_init();
140 if(ret < 0)
141 error(EATA, ret, true);
142
Amaury Pouly333b9ed2011-09-05 18:32:40 +0000143 /* NOTE: allow disk_init and disk_mount_all to fail since we can do USB after.
144 * We need this order to determine the correct logical sector size */
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000145 while(!disk_init(IF_MV(0)))
Amaury Pouly7d4fed52011-09-05 11:29:32 +0000146 printf("disk_init failed!");
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000147
Amaury Pouly7d4fed52011-09-05 11:29:32 +0000148 if((ret = disk_mount_all()) <= 0)
149 error(EDISK, ret, false);
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000150
Rafaël Carré2115eac2011-12-31 18:43:59 +0000151 if(usb_detect() == USB_INSERTED)
Amaury Pouly25f00602011-09-05 13:58:29 +0000152 usb_mode(HZ);
Amaury Pouly82f70b82011-07-22 15:45:58 +0000153
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000154 printf("Loading firmware");
155
Amaury Poulyd945c362011-09-13 23:38:08 +0000156 loadbuffer = (unsigned char*)loadaddress;
157 buffer_size = (int)(loadaddressend - loadaddress);
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000158
159 while((ret = load_firmware(loadbuffer, BOOTFILE, buffer_size)) < 0)
160 {
161 error(EBOOTFILE, ret, true);
162 }
163
164 kernel_entry = (void*) loadbuffer;
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000165 printf("Executing");
Amaury Poulyd945c362011-09-13 23:38:08 +0000166 disable_interrupt(IRQ_FIQ_STATUS);
167 commit_discard_idcache();
Amaury Pouly08fb3f62011-05-01 13:02:46 +0000168 kernel_entry();
169 printf("ERR: Failed to boot");
170
171 /* never returns */
172 while(1) ;
173}