summaryrefslogtreecommitdiff
path: root/bootloader/gigabeat.c
diff options
context:
space:
mode:
authorKarl Kurbjun <kkurbjun@gmail.com>2007-04-21 04:48:20 +0000
committerKarl Kurbjun <kkurbjun@gmail.com>2007-04-21 04:48:20 +0000
commit8a1fd8c686d2a4b8be36754e545338a476150e6a (patch)
treef69fd8be012099a8de228bd197346e4b11cf8e4a /bootloader/gigabeat.c
parentdd0f1c7db1e73859805f9d9aa343bb6e04dd739e (diff)
downloadrockbox-8a1fd8c686d2a4b8be36754e545338a476150e6a.tar.gz
rockbox-8a1fd8c686d2a4b8be36754e545338a476150e6a.zip
Commit FS#6929 - Gigabeat bootloader improvements by Barry Wardell and myself. This build fixes the problems seen with the latest builds on the Gigabeat X. Added View IO Ports under the Debug menu for the Gigabeat. Make sure you grab the latest bootloader from the Wiki as the old bootloader will not work properly with new builds.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13225 a1c6a512-1295-4272-9138-f99709370657
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