blob: d7942c958314ba09a7a78aa395a9d1201d9c2371 [file] [log] [blame]
Hristo Kovachev9dc0e622006-08-11 08:35:27 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2006 by Barry Wardell
11 *
12 * Based on Rockbox iriver bootloader by Linus Nielsen Feltzing
13 * and the ipodlinux bootloader by Daniel Palffy and Bernard Leach
14 *
15 * All files in this archive are subject to the GNU General Public License.
16 * See the file COPYING in the source tree root for full license agreement.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22#include "config.h"
23
24#include <stdlib.h>
25#include <stdio.h>
26#include <string.h>
27#include "cpu.h"
28#include "system.h"
29#include "lcd.h"
30#include "kernel.h"
31#include "thread.h"
32#include "ata.h"
33#include "fat.h"
34#include "disk.h"
35#include "font.h"
36#include "adc.h"
37#include "backlight.h"
38#include "button.h"
39#include "panic.h"
40#include "power.h"
41#include "file.h"
42
43/* Size of the buffer to store the loaded Rockbox/iriver image */
44#define MAX_LOADSIZE (5*1024*1024)
45
46/* This is identical to the function used in the iPod bootloader */
47static void memmove16(void *dest, const void *src, unsigned count)
48{
49 struct bufstr {
50 unsigned _buf[4];
51 } *d, *s;
52
53 if (src >= dest) {
54 count = (count + 15) >> 4;
55 d = (struct bufstr *) dest;
56 s = (struct bufstr *) src;
57 while (count--)
58 *d++ = *s++;
59 } else {
60 count = (count + 15) >> 4;
61 d = (struct bufstr *)(dest + (count <<4));
62 s = (struct bufstr *)(src + (count <<4));
63 while (count--)
64 *--d = *--s;
65 }
66}
67
68
Hristo Kovachev12041362006-08-11 09:51:04 +000069/* Load original iriver firmware. This function expects a file called
70 "H10_20GC.mi4" in the root directory of the player. It should be decrypted
71 and have the header stripped using mi4code. It reads the file in to a memory
72 buffer called buf. The rest of the loading is done in main()
Hristo Kovachev9dc0e622006-08-11 08:35:27 +000073*/
74int load_iriver(unsigned char* buf)
75{
76 int fd;
77 int rc;
78 int len;
79
80 fd = open("/H10_20GC.mi4", O_RDONLY);
81
82 len = filesize(fd);
83 rc = read(fd, buf, len);
84 if(rc < len)
85 return -4;
86
87 close(fd);
88 return len;
89}
90
91/* A buffer to load the iriver firmware or Rockbox into */
92unsigned char loadbuffer[MAX_LOADSIZE];
93
94void main(void)
95{
Hristo Kovachev12041362006-08-11 09:51:04 +000096 /* Attempt to load original iriver firmware. Successfully starts loading the
97 iriver firmware but then locks up once the "System Initialising" screen
98 is displayed.
99
100 The iriver firmware was decrypted and the header removed. It was then
101 appended to the end of bootloader.bin and an mi4 file was created from
102 the resulting file.
103
104 The original firmware starts at 0xd800 in the file and is of length
105 0x47da00.
106
107 The whole file (bootloader.bin + decrypted mi4) are loaded to memory by
108 the original iriver bootloader on startup. This copies the mi4 part to
109 the start of DRAM and passes execution to there.
110
111 memmove16((void*)DRAMORIG, (void*)(DRAMORIG + 0xd800), 0x47da00);
112 asm volatile(
113 "mov r0, #" SC(DRAMORIG) "\n"
114 "mov pc, r0 \n"
115 );
116 */
Hristo Kovachev9dc0e622006-08-11 08:35:27 +0000117
118 int i;
119 int rc;
Hristo Kovachev12041362006-08-11 09:51:04 +0000120 int btn;
121 int fd;
122 char buffer[24];
Hristo Kovachev9dc0e622006-08-11 08:35:27 +0000123
124 i=ata_init();
125 disk_init();
126 rc = disk_mount_all();
127
Hristo Kovachev12041362006-08-11 09:51:04 +0000128 /* Load original iriver firmware. Uses load_iriver(buf) to load the
129 decrypted mi4 file from disk to DRAM. This then copies that part of DRAM
130 to the start of DRAM and passes
131 execution to there.
132
133 rc=load_iriver(loadbuffer);
134 memcpy((void*)DRAMORIG,loadbuffer,rc);
135 asm volatile(
136 "mov r0, #" SC(DRAMORIG) "\n"
137 "mov pc, r0 \n"
138 );*/
139
140
141 /* This assumes that /test.txt exists */
142 fd=open("/test.txt",O_RDWR);
143
144
145 /*
146 for(i=0;i<100;i++){
147 btn = button_read_device();
148 switch(btn){
149 case BUTTON_LEFT:
150 snprintf(buffer, sizeof(buffer), "Left");
151 write(fd,buffer,sizeof(buffer));
152 break;
153 case BUTTON_RIGHT:
154 break;
155 case BUTTON_REW:
156 break;
157 case BUTTON_FF:
158 break;
159 case BUTTON_PLAY:
160 break;
161 default:
162 break;
163 }
164
Hristo Kovachev9dc0e622006-08-11 08:35:27 +0000165
Hristo Kovachev12041362006-08-11 09:51:04 +0000166 }
167 */
168
169
170
Hristo Kovachev9dc0e622006-08-11 08:35:27 +0000171 /* Investigate gpio
Hristo Kovachev12041362006-08-11 09:51:04 +0000172
173 unsigned int gpio_a, gpio_b, gpio_c, gpio_d;
Hristo Kovachev9dc0e622006-08-11 08:35:27 +0000174 unsigned int gpio_e, gpio_f, gpio_g, gpio_h;
175 unsigned int gpio_i, gpio_j, gpio_k, gpio_l;
176
Hristo Kovachev12041362006-08-11 09:51:04 +0000177 gpio_a = GPIOA_INPUT_VAL;
178 gpio_b = GPIOB_INPUT_VAL;
179 gpio_c = GPIOC_INPUT_VAL;
Hristo Kovachev9dc0e622006-08-11 08:35:27 +0000180
Hristo Kovachev12041362006-08-11 09:51:04 +0000181 gpio_g = GPIOG_INPUT_VAL;
182 gpio_h = GPIOH_INPUT_VAL;
183 gpio_i = GPIOI_INPUT_VAL;
Hristo Kovachev9dc0e622006-08-11 08:35:27 +0000184
Hristo Kovachev12041362006-08-11 09:51:04 +0000185 snprintf(buffer,sizeof(buffer),"GPIO_A: %02x GPIO_G: %02x\n",gpio_a,gpio_g);
186 write(fd,buffer,sizeof(buffer));
187 snprintf(buffer,sizeof(buffer),"GPIO_B: %02x GPIO_H: %02x\n",gpio_b,gpio_h);
188 write(fd,buffer,sizeof(buffer));
189 snprintf(buffer,sizeof(buffer),"GPIO_C: %02x GPIO_I: %02x\n",gpio_c,gpio_i);
190 write(fd,buffer,sizeof(buffer));
191
192 gpio_d = GPIOD_INPUT_VAL;
193 gpio_e = GPIOE_INPUT_VAL;
194 gpio_f = GPIOF_INPUT_VAL;
Hristo Kovachev9dc0e622006-08-11 08:35:27 +0000195
Hristo Kovachev12041362006-08-11 09:51:04 +0000196 gpio_j = GPIOJ_INPUT_VAL;
197 gpio_k = GPIOK_INPUT_VAL;
198 gpio_l = GPIOL_INPUT_VAL;
Hristo Kovachev9dc0e622006-08-11 08:35:27 +0000199
Hristo Kovachev12041362006-08-11 09:51:04 +0000200 snprintf(buffer,sizeof(buffer),"GPIO_D: %02x GPIO_J: %02x\n",gpio_d,gpio_j);
201 write(fd,buffer,sizeof(buffer));
202 snprintf(buffer,sizeof(buffer),"GPIO_E: %02x GPIO_K: %02x\n",gpio_e,gpio_k);
203 write(fd,buffer,sizeof(buffer));
204 snprintf(buffer,sizeof(buffer),"GPIO_F: %02x GPIO_L: %02x\n",gpio_f,gpio_l);
205 write(fd,buffer,sizeof(buffer));
206 */
207
208
209
210 /* Detect the scroller being touched
211
212 int j = 0;
213 for(j=0;j<1000;j++){
214 if(gpio_c!=0xF7){
215 snprintf(buffer, sizeof(buffer), "GPIO_C: %02x\n", gpio_c);
216 write(fd,buffer,sizeof(buffer));
217 }
218 if(gpio_d!=0xDD){
219 snprintf(buffer, sizeof(buffer), "GPIO_D: %02x\n", gpio_d);
220 write(fd,buffer,sizeof(buffer));
221 }
222 }*/
223
224
225 /* Apparently necessary for the data to be actually written to file */
226 fsync(fd);
227 udelay(1000000);
228
229 /* This causes the device to shut off instantly
230
231 GPIOF_OUTPUT_VAL = 0;
232 */
233
234 close(fd);
235 udelay(1000000);
Hristo Kovachev9dc0e622006-08-11 08:35:27 +0000236}
237
238/* These functions are present in the firmware library, but we reimplement
239 them here because the originals do a lot more than we want */
240
241void reset_poweroff_timer(void)
242{
243}
244
245int dbg_ports(void)
246{
247 return 0;
248}
249
250void mpeg_stop(void)
251{
252}
253
254void usb_acknowledge(void)
255{
256}
257
258void usb_wait_for_disconnect(void)
259{
260}
261
262void sys_poweroff(void)
263{
264}