blob: 4d52407655bc4ba9efb46feacf3778bc73608405 [file] [log] [blame]
Linus Nielsen Feltzingc5df4f82007-02-23 09:30:09 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by Greg White
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * 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.
Linus Nielsen Feltzingc5df4f82007-02-23 09:30:09 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
Marcoen Hirschberg0a068242006-08-12 08:27:48 +000021#include "config.h"
22
23#include <stdlib.h>
24#include <stdio.h>
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +000025#include "inttypes.h"
26#include "string.h"
Marcoen Hirschberg0a068242006-08-12 08:27:48 +000027#include "cpu.h"
28#include "system.h"
29#include "lcd.h"
Michael Sevakis4ea4cdf2014-08-08 02:28:11 -040030#include "../kernel-internal.h"
Frank Gevaerts2f8a0082008-11-01 16:14:28 +000031#include "storage.h"
Marcoen Hirschberg0a068242006-08-12 08:27:48 +000032#include "fat.h"
Michael Sevakis7d1a47c2013-08-05 22:02:45 -040033#include "file_internal.h"
Marcoen Hirschberg0a068242006-08-12 08:27:48 +000034#include "disk.h"
35#include "font.h"
36#include "adc.h"
37#include "backlight.h"
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +000038#include "backlight-target.h"
39#include "button.h"
Marcoen Hirschberg0a068242006-08-12 08:27:48 +000040#include "panic.h"
41#include "power.h"
42#include "file.h"
Linus Nielsen Feltzing46597c92007-02-22 15:09:49 +000043#include "common.h"
Marcin Bukat0b296912012-03-04 15:34:29 +010044#include "rb-loader.h"
45#include "loader_strerror.h"
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +000046#include "rbunicode.h"
47#include "usb.h"
Karl Kurbjun5a9a2b72007-10-23 03:29:15 +000048#include "mmu-arm.h"
Karl Kurbjunf32336e2008-11-12 05:11:18 +000049#include "rtc.h"
Rafaël Carré5d236b22010-05-27 09:41:46 +000050#include "version.h"
Marcoen Hirschberg29536762006-12-29 02:49:12 +000051
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +000052#include <stdarg.h>
Marcoen Hirschberg29536762006-12-29 02:49:12 +000053
Karl Kurbjunf32336e2008-11-12 05:11:18 +000054void shutdown(void)
55{
56 /* We need to gracefully spin down the disk to prevent clicks. */
57 if (ide_powered())
58 {
59 /* Make sure ATA has been initialized. */
60 ata_init();
61
62 /* And put the disk into sleep immediately. */
63 ata_sleepnow();
64 }
65
66 _backlight_off();
67
68 power_off();
69}
70
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +000071void main(void)
Marcoen Hirschberg29536762006-12-29 02:49:12 +000072{
Marcoen Hirschberg29536762006-12-29 02:49:12 +000073 unsigned char* loadbuffer;
74 int buffer_size;
Marcoen Hirschberg29536762006-12-29 02:49:12 +000075 int rc;
76 int(*kernel_entry)(void);
Marcoen Hirschberg0a068242006-08-12 08:27:48 +000077
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +000078 system_init();
Michael Sevakiscb061082008-12-08 23:31:05 +000079 kernel_init(); /* Need the kernel to sleep */
80
81 enable_interrupt(IRQ_FIQ_STATUS);
82
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +000083 lcd_init();
84 backlight_init();
Karl Kurbjunf32336e2008-11-12 05:11:18 +000085 button_init();
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +000086 font_init();
Karl Kurbjunf32336e2008-11-12 05:11:18 +000087 adc_init();
Marcoen Hirschberg0a068242006-08-12 08:27:48 +000088
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +000089 lcd_setfont(FONT_SYSFIXED);
Karl Kurbjunf32336e2008-11-12 05:11:18 +000090
91 /* These checks should only run if the bootloader is flashed */
92 if(GSTATUS3&0x02)
93 {
94 GSTATUS3&=0xFFFFFFFD;
95 if(!(GPGDAT&BUTTON_POWER) && charger_inserted())
96 {
97 while(!(GPGDAT&BUTTON_POWER) && charger_inserted())
98 {
99 char msg[20];
100 if(charging_state())
101 {
102 snprintf(msg,sizeof(msg),"Charging");
103 }
104 else
105 {
106 snprintf(msg,sizeof(msg),"Charge Complete");
107 }
108 reset_screen();
109 lcd_putsxy( (LCD_WIDTH - (SYSFONT_WIDTH * strlen(msg))) / 2,
110 (LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg);
111 lcd_update();
112
113#if defined(HAVE_RTC_ALARM)
114 /* Check if the alarm went off while charging */
115 if(rtc_check_alarm_flag())
116 {
117 GSTATUS3=1; /* Normally this is set in crt0.s */
118 break;
119 }
120#endif
121 }
122 if(!(GPGDAT&BUTTON_POWER)
123#if defined(HAVE_RTC_ALARM)
124 && !GSTATUS3
125#endif
126 )
127 {
128 shutdown();
129 }
130 }
Marcoen Hirschberg0a068242006-08-12 08:27:48 +0000131
Karl Kurbjunf32336e2008-11-12 05:11:18 +0000132 if(button_hold())
133 {
134 const char msg[] = "HOLD is enabled";
135 reset_screen();
136 lcd_putsxy( (LCD_WIDTH - (SYSFONT_WIDTH * strlen(msg))) / 2,
137 (LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg);
138 lcd_update();
139
140 sleep(2*HZ);
141
142 shutdown();
143 }
144 }
145
146 power_init();
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +0000147 usb_init();
148
149 /* Enter USB mode without USB thread */
Dave Chapman16723502007-09-04 08:03:07 +0000150 if(usb_detect() == USB_INSERTED)
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +0000151 {
152 const char msg[] = "Bootloader USB mode";
153 reset_screen();
154 lcd_putsxy( (LCD_WIDTH - (SYSFONT_WIDTH * strlen(msg))) / 2,
155 (LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg);
156 lcd_update();
157
Frank Gevaerts2f8a0082008-11-01 16:14:28 +0000158 storage_enable(false);
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +0000159 sleep(HZ/20);
160 usb_enable(true);
161
Dave Chapman16723502007-09-04 08:03:07 +0000162 while (usb_detect() == USB_INSERTED)
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +0000163 sleep(HZ);
164
165 usb_enable(false);
166
167 reset_screen();
168 lcd_update();
Greg White3b65fc22007-01-17 18:31:40 +0000169 }
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +0000170
Karl Kurbjunf32336e2008-11-12 05:11:18 +0000171 reset_screen();
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +0000172
173 /* Show debug messages if button is pressed */
Karl Kurbjun75be9c32009-04-21 04:36:46 +0000174 if(button_read_device()&BUTTON_A)
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +0000175 verbose = true;
176
177 printf("Rockbox boot loader");
Michael Sevakis95a4c3a2014-08-28 10:26:45 -0400178 printf("Version %s", rbversion);
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +0000179
Karl Kurbjun75103352008-04-22 04:34:25 +0000180 sleep(50); /* ATA seems to error without this pause */
181
Frank Gevaerts2f8a0082008-11-01 16:14:28 +0000182 rc = storage_init();
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +0000183 if(rc)
184 {
185 reset_screen();
Rafaël Carré1ec82122010-06-23 05:08:36 +0000186 error(EATA, rc, true);
Greg White8b3c8792007-01-17 01:49:19 +0000187 }
Marcoen Hirschberg29536762006-12-29 02:49:12 +0000188
Michael Sevakis7d1a47c2013-08-05 22:02:45 -0400189 filesystem_init();
Marcoen Hirschberg29536762006-12-29 02:49:12 +0000190
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +0000191 rc = disk_mount_all();
192 if (rc<=0)
193 {
Rafaël Carré1ec82122010-06-23 05:08:36 +0000194 error(EDISK, rc, true);
Marcoen Hirschberg29536762006-12-29 02:49:12 +0000195 }
196
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +0000197 printf("Loading firmware");
Marcoen Hirschberg29536762006-12-29 02:49:12 +0000198
Michael Sevakiscb061082008-12-08 23:31:05 +0000199 /* Flush out anything pending first */
Michael Sevakis6a677072011-12-17 07:27:24 +0000200 commit_discard_idcache();
Michael Sevakiscb061082008-12-08 23:31:05 +0000201
Karl Kurbjun75103352008-04-22 04:34:25 +0000202 loadbuffer = (unsigned char*) 0x31000000;
203 buffer_size = (unsigned char*)0x31400000 - loadbuffer;
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +0000204
205 rc = load_firmware(loadbuffer, BOOTFILE, buffer_size);
Marcin Bukat0b296912012-03-04 15:34:29 +0100206 if(rc <= EFILE_EMPTY)
Rafaël Carré1ec82122010-06-23 05:08:36 +0000207 error(EBOOTFILE, rc, true);
Karl Kurbjun8a1fd8c2007-04-21 04:48:20 +0000208
Michael Sevakiscb061082008-12-08 23:31:05 +0000209 storage_close();
210 system_prepare_fw_start();
211
Marcin Bukat0b296912012-03-04 15:34:29 +0100212 commit_discard_idcache();
213 kernel_entry = (void*) loadbuffer;
214 rc = kernel_entry();
Michael Sevakiscb061082008-12-08 23:31:05 +0000215
216#if 0
217 /* Halt */
218 while (1)
219 core_idle();
220#else
221 /* Return and restart */
222#endif
Marcoen Hirschberg0a068242006-08-12 08:27:48 +0000223}
224