Some more style adjustments to the Ipod installation. Labels can be used even for...
[Rockbox.git] / bootloader / gigabeat.c
blobe4cf6f08fdc85a9739939b4bb4fee89622be4d8e
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2006 by Greg White
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
19 #include "config.h"
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include "cpu.h"
25 #include "system.h"
26 #include "lcd.h"
27 #include "kernel.h"
28 #include "thread.h"
29 #include "ata.h"
30 #include "fat.h"
31 #include "disk.h"
32 #include "font.h"
33 #include "adc.h"
34 #include "backlight.h"
35 #include "panic.h"
36 #include "power.h"
37 #include "file.h"
38 #include "button-target.h"
39 #include "common.h"
41 extern void map_memory(void);
43 char version[] = APPSVERSION;
45 static void go_usb_mode(void)
47 /* Drop into USB mode. This does not check for disconnection. */
48 int i;
50 GPBDAT &= 0x7EF;
51 GPBCON |= 1<<8;
53 GPGDAT &= 0xE7FF;
54 GPGDAT |= 1<<11;
56 for(i = 0; i < 10000000; i++) {
57 continue;
60 GPBCON &= 0x2FFCFF;
61 GPBDAT |= 1<<5;
62 GPBDAT |= 1<<6;
66 /* Restores a factory kernel/bootloader from a known location */
67 /* Restores the FWIMG01.DAT file back in the case of a bootloader failure */
68 /* The factory or "good" bootloader must be in /GBSYSTEM/FWIMG/FWIMG01.DAT.ORIG */
69 /* Returns non-zero on failure */
70 int restore_fwimg01dat(void)
72 int orig_file = 0, dest_file = 0;
73 int size = 0, size_read;
74 static char buf[4096];
76 orig_file = open("/GBSYSTEM/FWIMG/FWIMG01.DAT.ORIG", O_RDONLY);
77 if(orig_file < 0) {
78 /* Couldn't open source file */
79 printf("Couldn't open FWIMG01.DAT.ORIG for reading");
80 return(1);
83 printf("FWIMG01.DAT.ORIG opened for reading");
85 dest_file = open("/GBSYSTEM/FWIMG/FWIMG01.DAT", O_RDWR);
86 if(dest_file < 0) {
87 /* Couldn't open destination file */
88 printf("Couldn't open FWIMG01.DAT.ORIG for writing");
89 close(orig_file);
90 return(2);
93 printf("FWIMG01.DAT opened for writing");
95 do {
96 /* Copy in chunks */
97 size_read = read(orig_file, buf, sizeof(buf));
98 if(size_read != write(dest_file, buf, size_read)) {
99 close(orig_file);
100 close(dest_file);
101 return(3);
103 size += size_read;
105 } while(size_read > 0);
107 close(orig_file);
108 close(dest_file);
110 printf("Finished copying %ld bytes from", size);
111 printf("FWIMG01.DAT.ORIG to FWIMG01.DAT");
113 return(0);
116 char buf[256];
118 void display_instructions(void)
120 lcd_setfont(FONT_SYSFIXED);
121 printf("Hold MENU when booting for rescue mode.");
122 printf(" \"VOL+\" button to restore original kernel");
123 printf(" \"A\" button to load original firmware");
124 printf("");
125 printf("FRAME %x TTB %x", FRAME, TTB_BASE);
128 void * main(void)
130 int i;
131 struct partinfo* pinfo;
132 unsigned short* identify_info;
133 unsigned char* loadbuffer;
134 int buffer_size;
135 bool load_original = false;
136 int rc;
137 int(*kernel_entry)(void);
139 bool show_bootsplash = true;
141 if(GPGDAT & 2)
142 show_bootsplash = false;
144 if(!show_bootsplash) {
145 lcd_init();
146 display_instructions();
147 sleep(2*HZ);
149 if(GPGDAT & 2) {
150 lcd_init();
151 printf("Entering rescue mode..");
152 go_usb_mode();
153 while(1);
155 if(GPGDAT & 0x10) {
156 lcd_init();
157 load_original = true;
158 printf("Loading original firmware...");
161 i = ata_init();
162 i = disk_mount_all();
163 if(!show_bootsplash) {
164 printf("disk_mount_all: %d", i);
166 if(show_bootsplash) {
167 int fd = open("/bootsplash.raw", O_RDONLY);
168 if(fd < 0) {
169 show_bootsplash = false;
170 lcd_init();
171 display_instructions();
173 else {
174 read(fd, lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT*2);
175 close(fd);
176 lcd_update();
177 lcd_init();
180 /* hold VOL+ to enter rescue mode to copy old image */
181 /* needs to be after ata_init and disk_mount_all */
182 if(GPGDAT & 4) {
184 /* Try to restore the original kernel/bootloader if a copy is found */
185 printf("Restoring FWIMG01.DAT...");
187 if(!restore_fwimg01dat()) {
188 printf("Restoring FWIMG01.DAT successful.");
189 } else {
190 printf("Restoring FWIMG01.DAT failed.");
193 printf("Now power cycle to boot original");
194 while(1);
197 if(!show_bootsplash) {
198 identify_info = ata_get_identify();
200 for(i=0; i < 20; i++)
201 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
203 buf[40]=0;
205 /* kill trailing space */
206 for(i=39; i && buf[i]==' '; i--)
207 buf[i] = 0;
209 printf("Model");
210 printf(buf);
212 for(i=0; i < 4; i++)
213 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]);
215 buf[8]=0;
217 printf("Firmware");
218 printf(buf);
220 pinfo = disk_partinfo(0);
221 printf("Partition 0: 0x%02x %ld MB", pinfo->type, pinfo->size / 2048);
223 /* Load original firmware */
224 if(load_original) {
225 loadbuffer = (unsigned char*)0x30008000;
226 buffer_size =(unsigned char*)0x31000000 - loadbuffer;
227 rc = load_raw_firmware(loadbuffer, "/rockbox.gigabeat", buffer_size);
228 if(rc < EOK) {
229 printf("Error!");
230 printf("Failed to load original firmware:");
231 printf(strerror(rc));
232 printf("Loading rockbox");
233 sleep(2*HZ);
234 goto load_rockbox;
237 printf("Loaded: %d", rc);
238 sleep(2*HZ);
240 (*((int*)0x7000000)) = 333;
241 rc = *((int*)0x7000000+0x8000000);
242 printf("Bank0 mem test: %d", rc);
243 sleep(3*HZ);
245 printf("Woops, should not return from firmware!");
246 goto usb;
249 load_rockbox:
250 map_memory();
251 if(!show_bootsplash) {
252 printf("Loading Rockbox...");
255 loadbuffer = (unsigned char*) 0x100;
256 buffer_size = (unsigned char*)0x400000 - loadbuffer;
257 rc = load_raw_firmware(loadbuffer, "/.rockbox/rockbox.gigabeat", buffer_size);
258 if(rc < EOK) {
259 rc = load_raw_firmware(loadbuffer, "/rockbox.gigabeat", buffer_size);
261 if(rc < EOK) {
262 printf("Error!");
263 printf("Can't load rockbox.gigabeat:");
264 printf(strerror(rc));
265 } else {
266 if(!show_bootsplash) {
267 printf("Rockbox loaded.");
269 kernel_entry = (void*) loadbuffer;
270 rc = kernel_entry();
271 printf("Woops, should not return from firmware: %d", rc);
272 goto usb;
274 usb:
275 /* now wait in USB mode so the bootloader can be updated */
276 go_usb_mode();
277 while(1);
279 return((void *)0);