Prepare new maemo release
[maemo-rb.git] / bootloader / rk27xx.c
blobbcf1f8f764f3a7a51a5f03276e95519dacd00173
1 #include <stdio.h>
2 #include <system.h>
3 #include <inttypes.h>
4 #include "config.h"
5 #include "gcc_extensions.h"
6 #include "lcd.h"
7 #include "font.h"
8 #include "backlight.h"
9 #include "adc.h"
10 #include "button-target.h"
11 #include "button.h"
12 #include "common.h"
13 #include "storage.h"
14 #include "disk.h"
15 #include "panic.h"
16 #include "power.h"
17 #include "string.h"
18 #include "file.h"
19 #include "crc32-rkw.h"
20 #include "rkw-loader.h"
21 #include "version.h"
23 /* beginning of DRAM */
24 #define DRAM_ORIG 0x60000000
26 /* bootloader code runs from 0x60700000
27 * so we cannot load more code to not overwrite ourself
29 #define LOAD_SIZE 0x700000
31 extern void show_logo( void );
33 /* This function setup bare minimum
34 * and jumps to rom in order to activate
35 * hardcoded rkusb mode
37 static void enter_rkusb(void)
39 asm volatile (
40 /* Turn off cache */
41 "ldr r0, =0xefff0000 \n"
42 "ldrh r1, [r0] \n"
43 "strh r1, [r0] \n"
45 /* Turn off interrupts */
46 "mrs r0, cpsr \n"
47 "bic r0, r0, #0x1f \n"
48 "orr r0, r0, #0xd3 \n"
49 "msr cpsr, r0 \n"
51 /* Disable iram remap */
52 "mov r0, #0x18000000 \n"
53 "add r0, r0, #0x1c000 \n"
54 "mov r1, #0 \n"
55 "str r1, [r0, #4] \n"
57 /* Ungate all clocks */
58 "str r1, [r0, #0x18] \n"
60 /* Read SCU_ID to determine
61 * which version of bootrom we have
62 * 2706A has ID 0xa1000604
63 * 2706B and 2705 have ID 0xa10002b7
65 "ldr r1, [r0] \n"
66 "ldr r2, =0xa1000604 \n"
67 "cmp r1, r2 \n"
68 "bne rk27xx_new \n"
70 /* Setup stacks in unmapped
71 * iram just as rom will do.
73 * We know about two versions
74 * of bootrom which are very similar
75 * but memory addresses are slightly
76 * different.
78 "rk27xx_old: \n"
79 "ldr r1, =0x18200258 \n"
80 "ldr r0, =0xaf0 \n"
81 "b jump_to_rom \n"
83 "rk27xx_new: \n"
84 "ldr r1, =0x18200274 \n"
85 "ldr r0, =0xec0 \n"
87 "jump_to_rom: \n"
88 "msr cpsr, #0xd2 \n"
89 "add r1, r1, #0x200 \n"
90 "mov sp, r1 \n"
91 "msr cpsr, #0xd3 \n"
92 "add r1, r1, #0x400 \n"
93 "mov sp, r1 \n"
95 /* Finaly jump to rkusb handler
96 * in bootrom.
98 "bx r0 \n"
103 void main(void) NORETURN_ATTR;
104 void main(void)
106 char filename[MAX_PATH];
107 unsigned char* loadbuffer;
108 void(*kernel_entry)(void);
109 int ret;
110 enum {rb, of} boot = rb;
112 power_init();
113 system_init();
114 kernel_init();
115 enable_irq();
117 adc_init();
118 lcd_init();
119 backlight_init();
120 button_init_device();
122 font_init();
123 lcd_setfont(FONT_SYSFIXED);
125 show_logo();
127 int btn = button_read_device();
129 /* if there is some other button pressed
130 * besides POWER/PLAY we boot into OF
132 if ((btn & ~POWEROFF_BUTTON))
133 boot = of;
135 /* if we are woken up by USB insert boot into OF */
136 if (DEV_INFO & (1<<20))
137 boot = of;
139 lcd_clear_display();
141 ret = storage_init();
142 if(ret < 0)
143 error(EATA, ret, true);
145 while(!disk_init(IF_MV(0)))
146 panicf("disk_init failed!");
148 while((ret = disk_mount_all()) <= 0)
149 error(EDISK, ret, true);
151 loadbuffer = (unsigned char*)DRAM_ORIG; /* DRAM */
153 if (boot == rb)
154 snprintf(filename,sizeof(filename), BOOTDIR "/%s", BOOTFILE);
155 else if (boot == of)
156 snprintf(filename,sizeof(filename), BOOTDIR "/%s", "BASE.RKW");
158 printf("Bootloader version: %s", RBVERSION);
159 printf("Loading: %s", filename);
161 ret = load_rkw(loadbuffer, filename, LOAD_SIZE);
162 if (ret < 0)
164 printf(rkw_strerror(ret));
165 lcd_update();
166 sleep(5*HZ);
168 /* if we boot rockbox we shutdown on error
169 * if we boot OF we fall back to rkusb mode on error
171 if (boot == rb)
173 power_off();
175 else
177 /* give visual feedback what we are doing */
178 printf("Entering rockchip USB mode...");
179 lcd_update();
181 enter_rkusb();
184 else
186 /* print 'Loading OK' */
187 printf(rkw_strerror(0));
188 sleep(HZ);
191 /* jump to entrypoint */
192 kernel_entry = (void*) loadbuffer;
193 commit_discard_idcache();
195 printf("Executing");
196 kernel_entry();
198 /* this should never be reached actually */
199 printf("ERR: Failed to boot");
200 sleep(5*HZ);
202 if (boot == rb)
204 power_off();
206 else
208 /* give visual feedback what we are doing */
209 printf("Entering rockchip USB mode...");
210 lcd_update();
212 enter_rkusb();
215 /* hang */
216 while(1);