diff options
author | Linus Nielsen Feltzing <linus@haxx.se> | 2005-01-28 12:51:10 +0000 |
---|---|---|
committer | Linus Nielsen Feltzing <linus@haxx.se> | 2005-01-28 12:51:10 +0000 |
commit | d39714555498ffaed2b4d29459d58243691b16db (patch) | |
tree | 49c7ba78eb09c7db2f1c8a6c5b35e9d9c8e9c831 /bootloader/main.c | |
parent | 2b8c52d98c7e62f9a47e3c76f2796cfdbffadd20 (diff) | |
download | rockbox-d39714555498ffaed2b4d29459d58243691b16db.tar.gz rockbox-d39714555498ffaed2b4d29459d58243691b16db.zip |
iRiver Boot loader
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5694 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'bootloader/main.c')
-rw-r--r-- | bootloader/main.c | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/bootloader/main.c b/bootloader/main.c new file mode 100644 index 0000000000..5cc2edad2e --- /dev/null +++ b/bootloader/main.c | |||
@@ -0,0 +1,233 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2005 by Linus Nielsen Feltzing | ||
11 | * | ||
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. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "config.h" | ||
20 | |||
21 | #include <stdlib.h> | ||
22 | #include <stdio.h> | ||
23 | #include "cpu.h" | ||
24 | #include "system.h" | ||
25 | #include "lcd.h" | ||
26 | #include "kernel.h" | ||
27 | #include "thread.h" | ||
28 | #include "ata.h" | ||
29 | #include "disk.h" | ||
30 | #include "font.h" | ||
31 | #include "adc.h" | ||
32 | #include "backlight.h" | ||
33 | #include "button.h" | ||
34 | #include "panic.h" | ||
35 | #include "power.h" | ||
36 | #include "file.h" | ||
37 | |||
38 | int line = 0; | ||
39 | |||
40 | int usb_screen(void) | ||
41 | { | ||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | void start_iriver_fw(void) | ||
46 | { | ||
47 | asm(" move.w #0x2700,%sr"); | ||
48 | asm(" move.l #0,%d0"); | ||
49 | asm(" movec.l %d0,%vbr"); | ||
50 | asm(" move.l 0,%sp"); | ||
51 | asm(" lea.l 8,%a0"); | ||
52 | asm(" jmp (%a0)"); | ||
53 | } | ||
54 | |||
55 | int load_firmware(void) | ||
56 | { | ||
57 | int fd; | ||
58 | int rc; | ||
59 | int len; | ||
60 | unsigned long chksum; | ||
61 | unsigned long sum; | ||
62 | int i; | ||
63 | unsigned char *buf = (unsigned char *)0x30000000; | ||
64 | char str[80]; | ||
65 | |||
66 | fd = open("/rockbox.bin", O_RDONLY); | ||
67 | if(fd < 0) | ||
68 | return -1; | ||
69 | |||
70 | len = lseek(fd, 0, SEEK_END) - 8; | ||
71 | |||
72 | snprintf(str, 80, "Length: %x", len); | ||
73 | lcd_puts(0, line++, str); | ||
74 | lcd_update(); | ||
75 | |||
76 | lseek(fd, 0, SEEK_SET); | ||
77 | |||
78 | rc = read(fd, &chksum, 4); | ||
79 | if(rc < 4) | ||
80 | return -2; | ||
81 | |||
82 | snprintf(str, 80, "Checksum: %x", chksum); | ||
83 | lcd_puts(0, line++, str); | ||
84 | lcd_update(); | ||
85 | |||
86 | lseek(fd, 4, SEEK_CUR); | ||
87 | |||
88 | rc = read(fd, buf, len); | ||
89 | if(rc < len) | ||
90 | return -4; | ||
91 | |||
92 | close(fd); | ||
93 | |||
94 | sum = 0; | ||
95 | |||
96 | for(i = 0;i < len;i++) { | ||
97 | sum += buf[i]; | ||
98 | } | ||
99 | |||
100 | snprintf(str, 80, "Sum: %x", sum); | ||
101 | lcd_puts(0, line++, str); | ||
102 | lcd_update(); | ||
103 | |||
104 | if(sum != chksum) | ||
105 | return -5; | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | void start_firmware(void) | ||
111 | { | ||
112 | asm(" move.w #0x2700,%sr"); | ||
113 | asm(" move.l #0x30000000,%d0"); | ||
114 | asm(" movec.l %d0,%vbr"); | ||
115 | asm(" move.l 0x30000000,%sp"); | ||
116 | asm(" move.l 0x30000004,%a0"); | ||
117 | asm(" jmp (%a0)"); | ||
118 | } | ||
119 | |||
120 | int main(void) | ||
121 | { | ||
122 | int i; | ||
123 | int rc; | ||
124 | int button; | ||
125 | char buf[256]; | ||
126 | |||
127 | power_init(); | ||
128 | system_init(); | ||
129 | kernel_init(); | ||
130 | backlight_init(); | ||
131 | set_irq_level(0); | ||
132 | lcd_init(); | ||
133 | font_init(); | ||
134 | adc_init(); | ||
135 | button_init(); | ||
136 | |||
137 | lcd_setfont(FONT_SYSFIXED); | ||
138 | |||
139 | sleep(HZ/10); /* Allow the button driver to check the buttons */ | ||
140 | |||
141 | if(button_status() & BUTTON_REC) { | ||
142 | lcd_puts(0, 8, "Ninjax"); | ||
143 | lcd_update(); | ||
144 | sleep(HZ); | ||
145 | start_iriver_fw(); | ||
146 | } | ||
147 | |||
148 | GPIO_FUNCTION |= 0x40000040; | ||
149 | GPIO1_FUNCTION |= 0x00000062; | ||
150 | |||
151 | GPIO1_ENABLE |= 0x00000000; | ||
152 | |||
153 | IDECONFIG1 = 0x00107000; | ||
154 | IDECONFIG2 = 0x00040000; | ||
155 | |||
156 | /* Hard drive power */ | ||
157 | GPIO_OUT &= ~0x00000040; | ||
158 | GPIO_ENABLE |= 0x00040240; | ||
159 | GPIO_FUNCTION |= 0x00040200; | ||
160 | |||
161 | rc = ata_init(); | ||
162 | if(rc) | ||
163 | { | ||
164 | #ifdef HAVE_LCD_BITMAP | ||
165 | char str[32]; | ||
166 | lcd_clear_display(); | ||
167 | snprintf(str, 31, "ATA error: %d", rc); | ||
168 | lcd_puts(0, 1, str); | ||
169 | lcd_puts(0, 3, "Press ON to debug"); | ||
170 | lcd_update(); | ||
171 | while(!(button_get(true) & BUTTON_REL)); | ||
172 | #endif | ||
173 | panicf("ata: %d", rc); | ||
174 | } | ||
175 | |||
176 | disk_init(); | ||
177 | |||
178 | /* FixMe: the same kind of mounting happens in usb.c, share the code. */ | ||
179 | rc = disk_mount_all(); | ||
180 | if (rc<=0) | ||
181 | { | ||
182 | lcd_clear_display(); | ||
183 | lcd_puts(0, 0, "No partition"); | ||
184 | lcd_puts(0, 1, "found."); | ||
185 | while(button_get(true) != SYS_USB_CONNECTED) {}; | ||
186 | } | ||
187 | |||
188 | lcd_puts(0, line++, "Loading firmware"); | ||
189 | i = load_firmware(); | ||
190 | snprintf(buf, 256, "Result: %d", i); | ||
191 | lcd_puts(0, line++, buf); | ||
192 | lcd_update(); | ||
193 | |||
194 | if(i == 0) | ||
195 | start_firmware(); | ||
196 | |||
197 | while(1) { | ||
198 | button = button_get_w_tmo(HZ/2); | ||
199 | if(button) | ||
200 | { | ||
201 | if(button == (BUTTON_OFF | BUTTON_REPEAT)) | ||
202 | power_off(); | ||
203 | } | ||
204 | } | ||
205 | } | ||
206 | |||
207 | /* These functions are present in the firmware library, but we reimplement | ||
208 | them here because the originals do a lot more than we want */ | ||
209 | |||
210 | void reset_poweroff_timer(void) | ||
211 | { | ||
212 | } | ||
213 | |||
214 | void screen_dump(void) | ||
215 | { | ||
216 | } | ||
217 | |||
218 | int dbg_ports(void) | ||
219 | { | ||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | void mpeg_stop(void) | ||
224 | { | ||
225 | } | ||
226 | |||
227 | void usb_acknowledge(void) | ||
228 | { | ||
229 | } | ||
230 | |||
231 | void usb_wait_for_disconnect(void) | ||
232 | { | ||
233 | } | ||