summaryrefslogtreecommitdiff
path: root/bootloader/gigabeat.c
diff options
context:
space:
mode:
Diffstat (limited to 'bootloader/gigabeat.c')
-rw-r--r--bootloader/gigabeat.c278
1 files changed, 64 insertions, 214 deletions
diff --git a/bootloader/gigabeat.c b/bootloader/gigabeat.c
index e4cf6f08fd..e482c70d16 100644
--- a/bootloader/gigabeat.c
+++ b/bootloader/gigabeat.c
@@ -20,7 +20,8 @@
20 20
21#include <stdlib.h> 21#include <stdlib.h>
22#include <stdio.h> 22#include <stdio.h>
23#include <string.h> 23#include "inttypes.h"
24#include "string.h"
24#include "cpu.h" 25#include "cpu.h"
25#include "system.h" 26#include "system.h"
26#include "lcd.h" 27#include "lcd.h"
@@ -32,250 +33,99 @@
32#include "font.h" 33#include "font.h"
33#include "adc.h" 34#include "adc.h"
34#include "backlight.h" 35#include "backlight.h"
36#include "backlight-target.h"
37#include "button.h"
35#include "panic.h" 38#include "panic.h"
36#include "power.h" 39#include "power.h"
37#include "file.h" 40#include "file.h"
38#include "button-target.h"
39#include "common.h" 41#include "common.h"
42#include "rbunicode.h"
43#include "usb.h"
44#include "mmu-meg-fx.h"
40 45
41extern void map_memory(void); 46#include <stdarg.h>
42 47
43char version[] = APPSVERSION; 48char version[] = APPSVERSION;
44 49
45static void go_usb_mode(void) 50void main(void)
46{ 51{
47 /* Drop into USB mode. This does not check for disconnection. */
48 int i;
49
50 GPBDAT &= 0x7EF;
51 GPBCON |= 1<<8;
52
53 GPGDAT &= 0xE7FF;
54 GPGDAT |= 1<<11;
55
56 for(i = 0; i < 10000000; i++) {
57 continue;
58 }
59
60 GPBCON &= 0x2FFCFF;
61 GPBDAT |= 1<<5;
62 GPBDAT |= 1<<6;
63}
64
65
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 */
70int restore_fwimg01dat(void)
71{
72 int orig_file = 0, dest_file = 0;
73 int size = 0, size_read;
74 static char buf[4096];
75
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);
81 }
82
83 printf("FWIMG01.DAT.ORIG opened for reading");
84
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);
91 }
92
93 printf("FWIMG01.DAT opened for writing");
94
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);
102 }
103 size += size_read;
104
105 } while(size_read > 0);
106
107 close(orig_file);
108 close(dest_file);
109
110 printf("Finished copying %ld bytes from", size);
111 printf("FWIMG01.DAT.ORIG to FWIMG01.DAT");
112
113 return(0);
114}
115
116char buf[256];
117
118void display_instructions(void)
119{
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);
126}
127
128void * main(void)
129{
130 int i;
131 struct partinfo* pinfo;
132 unsigned short* identify_info;
133 unsigned char* loadbuffer; 52 unsigned char* loadbuffer;
134 int buffer_size; 53 int buffer_size;
135 bool load_original = false;
136 int rc; 54 int rc;
137 int(*kernel_entry)(void); 55 int(*kernel_entry)(void);
138 56
139 bool show_bootsplash = true; 57 memory_init();
140 58 power_init();
141 if(GPGDAT & 2) 59 system_init();
142 show_bootsplash = false; 60 lcd_init();
61 backlight_init();
62 font_init();
143 63
144 if(!show_bootsplash) { 64 lcd_setfont(FONT_SYSFIXED);
145 lcd_init();
146 display_instructions();
147 sleep(2*HZ);
148 }
149 if(GPGDAT & 2) {
150 lcd_init();
151 printf("Entering rescue mode..");
152 go_usb_mode();
153 while(1);
154 }
155 if(GPGDAT & 0x10) {
156 lcd_init();
157 load_original = true;
158 printf("Loading original firmware...");
159 }
160
161 i = ata_init();
162 i = disk_mount_all();
163 if(!show_bootsplash) {
164 printf("disk_mount_all: %d", i);
165 }
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();
172 }
173 else {
174 read(fd, lcd_framebuffer, LCD_WIDTH*LCD_HEIGHT*2);
175 close(fd);
176 lcd_update();
177 lcd_init();
178 }
179 }
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) {
183
184 /* Try to restore the original kernel/bootloader if a copy is found */
185 printf("Restoring FWIMG01.DAT...");
186
187 if(!restore_fwimg01dat()) {
188 printf("Restoring FWIMG01.DAT successful.");
189 } else {
190 printf("Restoring FWIMG01.DAT failed.");
191 }
192
193 printf("Now power cycle to boot original");
194 while(1);
195 }
196
197 if(!show_bootsplash) {
198 identify_info = ata_get_identify();
199
200 for(i=0; i < 20; i++)
201 ((unsigned short*)buf)[i]=htobe16(identify_info[i+27]);
202
203 buf[40]=0;
204 65
205 /* kill trailing space */ 66 usb_init();
206 for(i=39; i && buf[i]==' '; i--)
207 buf[i] = 0;
208 67
209 printf("Model"); 68 /* Enter USB mode without USB thread */
210 printf(buf); 69 if(usb_detect())
70 {
71 const char msg[] = "Bootloader USB mode";
72 reset_screen();
73 lcd_putsxy( (LCD_WIDTH - (SYSFONT_WIDTH * strlen(msg))) / 2,
74 (LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg);
75 lcd_update();
211 76
212 for(i=0; i < 4; i++) 77 ata_enable(false);
213 ((unsigned short*)buf)[i]=htobe16(identify_info[i+23]); 78 sleep(HZ/20);
79 usb_enable(true);
214 80
215 buf[8]=0; 81 while (usb_detect())
82 sleep(HZ);
216 83
217 printf("Firmware"); 84 usb_enable(false);
218 printf(buf);
219 85
220 pinfo = disk_partinfo(0); 86 reset_screen();
221 printf("Partition 0: 0x%02x %ld MB", pinfo->type, pinfo->size / 2048); 87 lcd_update();
88 }
89
90 kernel_init();
91 adc_init();
92 button_init();
93
94 /* Show debug messages if button is pressed */
95 if(button_read_device())
96 verbose = true;
97
98 printf("Rockbox boot loader");
99 printf("Version %s", version);
100
101 rc = ata_init();
102 if(rc)
103 {
104 reset_screen();
105 error(EATA, rc);
222 } 106 }
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;
235 }
236
237 printf("Loaded: %d", rc);
238 sleep(2*HZ);
239 107
240 (*((int*)0x7000000)) = 333; 108 disk_init();
241 rc = *((int*)0x7000000+0x8000000);
242 printf("Bank0 mem test: %d", rc);
243 sleep(3*HZ);
244 109
245 printf("Woops, should not return from firmware!"); 110 rc = disk_mount_all();
246 goto usb; 111 if (rc<=0)
112 {
113 error(EDISK,rc);
247 } 114 }
248 115
249load_rockbox: 116 printf("Loading firmware");
250 map_memory();
251 if(!show_bootsplash) {
252 printf("Loading Rockbox...");
253 }
254 117
255 loadbuffer = (unsigned char*) 0x100; 118 loadbuffer = (unsigned char*) 0x100;
256 buffer_size = (unsigned char*)0x400000 - loadbuffer; 119 buffer_size = (unsigned char*)0x400000 - loadbuffer;
257 rc = load_raw_firmware(loadbuffer, "/.rockbox/rockbox.gigabeat", buffer_size); 120
258 if(rc < EOK) { 121 rc = load_firmware(loadbuffer, BOOTFILE, buffer_size);
259 rc = load_raw_firmware(loadbuffer, "/rockbox.gigabeat", buffer_size); 122 if(rc < 0)
260 } 123 error(EBOOTFILE, rc);
261 if(rc < EOK) { 124
262 printf("Error!"); 125 if (rc == EOK)
263 printf("Can't load rockbox.gigabeat:"); 126 {
264 printf(strerror(rc));
265 } else {
266 if(!show_bootsplash) {
267 printf("Rockbox loaded.");
268 }
269 kernel_entry = (void*) loadbuffer; 127 kernel_entry = (void*) loadbuffer;
270 rc = kernel_entry(); 128 rc = kernel_entry();
271 printf("Woops, should not return from firmware: %d", rc);
272 goto usb;
273 } 129 }
274usb:
275 /* now wait in USB mode so the bootloader can be updated */
276 go_usb_mode();
277 while(1);
278
279 return((void *)0);
280} 130}
281 131