summaryrefslogtreecommitdiff
path: root/bootloader/fiiom3k.c
diff options
context:
space:
mode:
Diffstat (limited to 'bootloader/fiiom3k.c')
-rw-r--r--bootloader/fiiom3k.c360
1 files changed, 0 insertions, 360 deletions
diff --git a/bootloader/fiiom3k.c b/bootloader/fiiom3k.c
deleted file mode 100644
index 42b3260e07..0000000000
--- a/bootloader/fiiom3k.c
+++ /dev/null
@@ -1,360 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "system.h"
23#include "core_alloc.h"
24#include "kernel/kernel-internal.h"
25#include "i2c.h"
26#include "power.h"
27#include "lcd.h"
28#include "font.h"
29#include "backlight.h"
30#include "backlight-target.h"
31#include "button.h"
32#include "storage.h"
33#include "file_internal.h"
34#include "disk.h"
35#include "usb.h"
36#include "rb-loader.h"
37#include "loader_strerror.h"
38#include "version.h"
39#include "installer-fiiom3k.h"
40#include "boot-x1000.h"
41#include "x1000/cpm.h"
42
43/* Load address where the binary needs to be placed */
44extern unsigned char loadaddress[];
45
46/* Fixed buffer to contain the loaded binary in memory */
47extern unsigned char loadbuffer[];
48extern unsigned char loadbufferend[];
49#define MAX_LOAD_SIZE (loadbufferend - loadbuffer)
50
51void exec(void* dst, const void* src, int bytes)
52 __attribute__((noreturn, section(".icode")));
53
54void exec(void* dst, const void* src, int bytes)
55{
56 memcpy(dst, src, bytes);
57 commit_discard_idcache();
58 __asm__ __volatile__ ("jr %0\n"
59 "nop\n"
60 :: "r"(dst));
61 __builtin_unreachable();
62}
63
64static bool lcd_inited = false;
65static bool usb_inited = false;
66static bool disk_inited = false;
67
68static void init_lcd(void)
69{
70 if(lcd_inited)
71 return;
72
73 lcd_init();
74 font_init();
75 lcd_setfont(FONT_SYSFIXED);
76
77 /* Clear screen before turning backlight on, otherwise we might
78 * display random garbage on the screen */
79 lcd_clear_display();
80 lcd_update();
81
82 backlight_init();
83
84 lcd_inited = true;
85}
86
87static void put_version(void)
88{
89 lcd_putsxy((LCD_WIDTH - (SYSFONT_WIDTH * strlen(rbversion))) / 2,
90 (LCD_HEIGHT - SYSFONT_HEIGHT), rbversion);
91}
92
93static void do_splash2(int delay, const char* msg, const char* msg2)
94{
95 init_lcd();
96 lcd_clear_display();
97 lcd_putsxy((LCD_WIDTH - (SYSFONT_WIDTH * strlen(msg))) / 2,
98 (LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg);
99 if(msg2) {
100 lcd_putsxy((LCD_WIDTH - (SYSFONT_WIDTH * strlen(msg2))) / 2,
101 (LCD_HEIGHT + 2*SYSFONT_HEIGHT) / 2, msg2);
102 }
103
104 put_version();
105 lcd_update();
106 sleep(delay);
107}
108
109static void do_splash(int delay, const char* msg)
110{
111 do_splash2(delay, msg, NULL);
112}
113
114static void do_usb(void)
115{
116 if(!usb_inited) {
117 usb_init();
118 usb_start_monitoring();
119 usb_inited = true;
120 }
121
122 do_splash2(0, "Waiting for USB", "Press POWER to go back");
123
124 int btn;
125 while(1) {
126 btn = button_get(true);
127 if(btn == SYS_USB_CONNECTED)
128 break;
129 else if(btn == BUTTON_POWER)
130 return;
131 }
132
133 do_splash(0, "USB mode");
134 usb_acknowledge(SYS_USB_CONNECTED_ACK);
135 while(button_get(true) != SYS_USB_DISCONNECTED);
136
137 do_splash(3*HZ, "USB disconnected");
138}
139
140static int init_disk(void)
141{
142 if(disk_inited)
143 return 0;
144
145 while(!storage_present(0)) {
146 do_splash2(0, "Insert SD card", "Press POWER for recovery");
147 int btn = button_get_w_tmo(HZ);
148 if(btn == BUTTON_POWER)
149 return 1;
150 }
151
152 if(disk_mount_all() <= 0) {
153 do_splash(5*HZ, "Cannot mount filesystem");
154 return 1;
155 }
156
157 disk_inited = true;
158 return 0;
159}
160
161static void do_boot(void)
162{
163 if(init_disk() != 0)
164 return;
165
166 int loadsize = load_firmware(loadbuffer, BOOTFILE, MAX_LOAD_SIZE);
167 if(loadsize <= 0) {
168 do_splash2(5*HZ, "Error loading Rockbox",
169 loader_strerror(loadsize));
170 do_usb();
171 return;
172 }
173
174 if(lcd_inited)
175 backlight_hw_off();
176
177 disable_irq();
178 exec(loadaddress, loadbuffer, loadsize);
179}
180
181#define INSTALL 0
182#define BACKUP 1
183#define RESTORE 2
184
185static void do_install(int which)
186{
187 int rc = init_disk();
188 if(rc != 0) {
189 do_splash2(5*HZ, "Install aborted", "No SD card present");
190 return;
191 }
192
193 const char* msg;
194 if(rc == INSTALL)
195 msg = "Installing";
196 else if(rc == BACKUP)
197 msg = "Backing up";
198 else
199 msg = "Restoring backup";
200
201 do_splash(0, msg);
202
203 if(which == INSTALL)
204 rc = install_boot("/bootloader.m3k");
205 else if(which == BACKUP)
206 rc = backup_boot("/fiiom3k-boot.bin");
207 else
208 rc = restore_boot("/fiiom3k-boot.bin");
209
210 char buf[32];
211 snprintf(buf, sizeof(buf), "Failed! Error: %d", rc);
212 const char* msg1 = rc == 0 ? "Success" : buf;
213 const char* msg2 = "Press POWER to continue";
214 do_splash2(0, msg1, msg2);
215
216 button_clear_queue();
217 while(button_get(true) != BUTTON_POWER);
218}
219
220static void recovery_menu(void)
221{
222 static const char* items[] = {
223 "--- Rockbox recovery menu ---",
224 "[System]",
225 " Start Rockbox",
226 " USB mode",
227 " Shutdown",
228 " Reboot",
229 "[Bootloader]",
230 " Install or update",
231 " Backup",
232 " Restore",
233 "",
234 "",
235 "",
236 "",
237 "",
238 "VOL+/VOL- move cursor",
239 "PLAY select item",
240 "POWER power off",
241 };
242
243 static const int nitems = sizeof(items) / sizeof(char*);
244
245 init_lcd();
246
247 int selection = 2;
248 do {
249 /* Draw menu */
250 lcd_clear_display();
251
252 for(int i = 0; i < nitems; ++i)
253 lcd_puts(0, i, items[i]);
254
255 if(items[selection][0] == ' ')
256 lcd_puts(0, selection, "=>");
257
258 put_version();
259 lcd_update();
260
261 /* Clear queue to avoid accidental input */
262 button_clear_queue();
263
264 /* Get the button */
265 int btn = button_get(true);
266
267 /* Process user input */
268 if(btn == BUTTON_VOL_UP) {
269 for(int i = selection-1; i >= 0; --i) {
270 if(items[i][0] == ' ') {
271 selection = i;
272 break;
273 }
274 }
275
276 continue;
277 } else if(btn == BUTTON_VOL_DOWN) {
278 for(int i = selection+1; i < nitems; ++i) {
279 if(items[i][0] == ' ') {
280 selection = i;
281 break;
282 }
283 }
284
285 continue;
286 } else if(btn == BUTTON_POWER) {
287 selection = 4; /* Shutdown */
288 } else if(btn != BUTTON_PLAY) {
289 continue;
290 }
291
292 /* User pressed PLAY so decide what action to take */
293 switch(selection) {
294 case 2: /* Start rockbox */
295 do_boot();
296 break;
297
298 case 3: /* USB mode */
299 do_usb();
300 break;
301
302 case 4: /* Shutdown */
303 do_splash(HZ, "Shutting down");
304 power_off();
305 break;
306
307 case 5: /* Reboot */
308 do_splash(HZ, "Rebooting");
309 system_reboot();
310 break;
311
312 case 7: /* Install bootloader */
313 do_install(INSTALL);
314 break;
315
316 case 8: /* Backup bootloader */
317 do_install(BACKUP);
318 break;
319
320 case 9: /* Restore bootloader */
321 do_install(RESTORE);
322 break;
323
324 default:
325 break;
326 }
327 } while(1);
328}
329
330void main(void)
331{
332 bool recovery_mode = false;
333
334 if(get_boot_flag(BOOT_FLAG_USB_BOOT))
335 recovery_mode = true;
336
337 system_init();
338 core_allocator_init();
339 kernel_init();
340 i2c_init();
341 power_init();
342 button_init();
343 enable_irq();
344
345 if(storage_init() < 0) {
346 do_splash(3*HZ, "Failed to init storage");
347 power_off();
348 }
349
350 filesystem_init();
351
352 if(button_read_device() & BUTTON_VOL_UP)
353 recovery_mode = true;
354
355 if(!recovery_mode)
356 do_boot();
357
358 /* If boot fails or user holds Vol+, go to recovery menu */
359 recovery_menu();
360}