summaryrefslogtreecommitdiff
path: root/bootloader/iriver_h300.c
diff options
context:
space:
mode:
authorJames Buren <braewoods+rb@braewoods.net>2020-11-14 14:57:47 +0000
committerWilliam Wilgus <me.theuser@yahoo.com>2020-11-14 23:20:43 +0000
commit7d9ac021b5bac5078778c4b2489d31c9f2892404 (patch)
tree34dbebfaf91d3b57a2fdc582cf727777e9e250d8 /bootloader/iriver_h300.c
parent33d42c20de9a66cbfec8b213d19b454794d63900 (diff)
downloadrockbox-7d9ac021b5bac5078778c4b2489d31c9f2892404.tar.gz
rockbox-7d9ac021b5bac5078778c4b2489d31c9f2892404.zip
h1x0/h300: bring the two bootloaders more in sync
The most major change here is the porting of the failsafe boot menu and eeprom settings support from the h1x0 bootloader to the h300 bootloader. This has been successfully tested already and indeed works about the same as it does on the h1x0 bootloader. The other major change is the addition of new code to both bootloaders that will retry the flash boot function after exitting disk mode. It still falls back to booting from disk if this either fails or is not configured to boot from flash. There were also various other modifications to bring the two closer in sync so there are fewer differences. Change-Id: I17a5724e03225b57e9d0071387294aa6cd025178
Diffstat (limited to 'bootloader/iriver_h300.c')
-rw-r--r--bootloader/iriver_h300.c251
1 files changed, 248 insertions, 3 deletions
diff --git a/bootloader/iriver_h300.c b/bootloader/iriver_h300.c
index ee344d4165..ff3c8de2af 100644
--- a/bootloader/iriver_h300.c
+++ b/bootloader/iriver_h300.c
@@ -43,11 +43,12 @@
43#include "power.h" 43#include "power.h"
44#include "powermgmt.h" 44#include "powermgmt.h"
45#include "file.h" 45#include "file.h"
46#include "eeprom_settings.h"
47#include "rbunicode.h"
46#include "pcf50606.h" 48#include "pcf50606.h"
47#include "common.h" 49#include "common.h"
48#include "rb-loader.h" 50#include "rb-loader.h"
49#include "loader_strerror.h" 51#include "loader_strerror.h"
50#include "rbunicode.h"
51#include "isp1362.h" 52#include "isp1362.h"
52#include "version.h" 53#include "version.h"
53 54
@@ -62,6 +63,8 @@
62extern int line; 63extern int line;
63extern int remote_line; 64extern int remote_line;
64 65
66static bool recovery_mode = false;
67
65/* Reset the cookie for the crt0 crash check */ 68/* Reset the cookie for the crt0 crash check */
66inline void __reset_cookie(void) 69inline void __reset_cookie(void)
67{ 70{
@@ -90,9 +93,57 @@ void start_firmware(void)
90 asm(" jmp (%a0)"); 93 asm(" jmp (%a0)");
91} 94}
92 95
96void start_flashed_romimage(void)
97{
98 uint8_t *src = (uint8_t *)FLASH_ROMIMAGE_ENTRY;
99 uint32_t *reset_vector;
100
101 if (!detect_flashed_romimage())
102 return ;
103
104 reset_vector = (uint32_t *)(&src[sizeof(struct flash_header)+sizeof(uint32_t)]);
105
106 asm(" move.w #0x2700,%sr");
107 __reset_cookie();
108
109 asm(" move.l %0,%%d0" :: "i"(DRAM_START));
110 asm(" movec.l %d0,%vbr");
111 asm(" move.l %0,%%sp" :: "m"(reset_vector[0]));
112 asm(" move.l %0,%%a0" :: "m"(reset_vector[1]));
113 asm(" jmp (%a0)");
114
115 /* Failure */
116 power_off();
117}
118
119void start_flashed_ramimage(void)
120{
121 struct flash_header hdr;
122 uint8_t *buf = (uint8_t *)DRAM_START;
123 uint8_t *src = (uint8_t *)FLASH_RAMIMAGE_ENTRY;
124
125 if (!detect_flashed_ramimage())
126 return;
127
128 /* Load firmware from flash */
129 cpu_boost(true);
130 memcpy(&hdr, src, sizeof(struct flash_header));
131 src += sizeof(struct flash_header);
132 memcpy(buf, src, hdr.length);
133 cpu_boost(false);
134
135 start_firmware();
136
137 /* Failure */
138 power_off();
139}
140
93void shutdown(void) 141void shutdown(void)
94{ 142{
95 printf("Shutting down..."); 143 printf("Shutting down...");
144 /* Reset the rockbox crash check. */
145 firmware_settings.bl_version = 0;
146 eeprom_settings_store();
96 147
97 /* We need to gracefully spin down the disk to prevent clicks. */ 148 /* We need to gracefully spin down the disk to prevent clicks. */
98 if (ide_powered()) 149 if (ide_powered())
@@ -106,6 +157,7 @@ void shutdown(void)
106 157
107 sleep(HZ*2); 158 sleep(HZ*2);
108 159
160 /* Backlight OFF */
109 backlight_hw_off(); 161 backlight_hw_off();
110 remote_backlight_hw_off(); 162 remote_backlight_hw_off();
111 163
@@ -131,6 +183,176 @@ void check_battery(void)
131 } 183 }
132} 184}
133 185
186void initialize_eeprom(void)
187{
188 if (detect_original_firmware())
189 return ;
190
191 if (!eeprom_settings_init())
192 {
193 recovery_mode = true;
194 return ;
195 }
196
197 /* If bootloader version has not been reset, disk might
198 * not be intact. */
199 if (firmware_settings.bl_version || !firmware_settings.disk_clean)
200 {
201 firmware_settings.disk_clean = false;
202 recovery_mode = true;
203 }
204
205 firmware_settings.bl_version = EEPROM_SETTINGS_BL_MINVER;
206 eeprom_settings_store();
207}
208
209void try_flashboot(void)
210{
211 if (!firmware_settings.initialized)
212 return ;
213
214 switch (firmware_settings.bootmethod)
215 {
216 case BOOT_DISK:
217 return;
218
219 case BOOT_ROM:
220 start_flashed_romimage();
221 recovery_mode = true;
222 break;
223
224 case BOOT_RAM:
225 start_flashed_ramimage();
226 recovery_mode = true;
227 break;
228
229 default:
230 recovery_mode = true;
231 return;
232 }
233}
234
235void failsafe_menu(void)
236{
237 static const char *options[] =
238 {
239 "Boot from disk",
240 "Boot RAM image",
241 "Boot ROM image",
242 "Shutdown"
243 };
244 const int FAILSAFE_OPTIONS = sizeof(options) / sizeof(*options);
245 const long TIMEOUT = 15 * HZ;
246 long start_tick = current_tick;
247 int option = 3;
248 int button;
249 int defopt = -1;
250 char buf[32];
251 int i;
252
253 reset_screen();
254 printf("Bootloader %s", rbversion);
255 check_battery();
256 printf("=========================");
257 line += FAILSAFE_OPTIONS;
258 printf("");
259 printf(" [NAVI] to confirm.");
260 printf(" [REC] to set as default.");
261 printf("");
262
263 if (firmware_settings.initialized)
264 {
265 defopt = firmware_settings.bootmethod;
266 if (defopt < 0 || defopt >= FAILSAFE_OPTIONS)
267 defopt = option;
268 }
269
270 while (current_tick - start_tick < TIMEOUT)
271 {
272 /* Draw the menu. */
273 line = 3;
274 for (i = 0; i < FAILSAFE_OPTIONS; i++)
275 {
276 char *def = "[DEF]";
277 char *arrow = "->";
278
279 if (i != defopt)
280 def = "";
281 if (i != option)
282 arrow = " ";
283
284 printf("%s %s %s", arrow, options[i], def);
285 }
286
287 snprintf(buf, sizeof(buf), "Time left: %lds",
288 (TIMEOUT - (current_tick - start_tick)) / HZ);
289 lcd_puts(0, 10, buf);
290 lcd_update();
291 button = button_get_w_tmo(HZ);
292
293 if (button == BUTTON_NONE || button & SYS_EVENT)
294 continue ;
295
296 start_tick = current_tick;
297
298 /* Ignore the ON/PLAY -button because it can cause trouble
299 with the RTC alarm mod. */
300 switch (button & ~(BUTTON_ON))
301 {
302 case BUTTON_UP:
303 case BUTTON_RC_REW:
304 if (option > 0)
305 option--;
306 break ;
307
308 case BUTTON_DOWN:
309 case BUTTON_RC_FF:
310 if (option < FAILSAFE_OPTIONS-1)
311 option++;
312 break ;
313
314 case BUTTON_SELECT:
315 case BUTTON_RC_ON:
316 goto execute;
317
318 case BUTTON_REC:
319 case BUTTON_RC_REC:
320 if (firmware_settings.initialized)
321 {
322 firmware_settings.bootmethod = option;
323 eeprom_settings_store();
324 defopt = option;
325 }
326 break ;
327 }
328 }
329
330 execute:
331
332 lcd_puts(0, 10, "Executing command...");
333 lcd_update();
334 sleep(HZ);
335 reset_screen();
336
337 switch (option)
338 {
339 case BOOT_DISK:
340 return ;
341
342 case BOOT_RAM:
343 start_flashed_ramimage();
344 printf("Image not found");
345 break;
346
347 case BOOT_ROM:
348 start_flashed_romimage();
349 printf("Image not found");
350 break;
351 }
352
353 shutdown();
354}
355
134/* From the pcf50606 driver */ 356/* From the pcf50606 driver */
135extern unsigned char pcf50606_intregs[3]; 357extern unsigned char pcf50606_intregs[3];
136 358
@@ -187,6 +409,7 @@ void main(void)
187 backlight_hw_init(); 409 backlight_hw_init();
188 backlight_hw_off(); 410 backlight_hw_off();
189 411
412 /* Remote backlight ON */
190 remote_backlight_hw_on(); 413 remote_backlight_hw_on();
191 414
192 system_init(); 415 system_init();
@@ -197,11 +420,20 @@ void main(void)
197 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS); 420 coldfire_set_pllcr_audio_bits(DEFAULT_PLLCR_AUDIO_BITS);
198 enable_irq(); 421 enable_irq();
199 422
423 initialize_eeprom();
424
200 isp1362_init(); 425 isp1362_init();
201 426
202 adc_init(); 427 adc_init();
203 button_init(); 428 button_init();
204 429
430 /* Power on the hard drive early, to speed up the loading. */
431 if (!hold_status && !recovery_mode)
432 ide_power_enable(true);
433
434 if (!hold_status && (usb_detect() != USB_INSERTED) && !recovery_mode)
435 try_flashboot();
436
205 lcd_init(); 437 lcd_init();
206 lcd_remote_init(); 438 lcd_remote_init();
207 font_init(); 439 font_init();
@@ -229,14 +461,16 @@ void main(void)
229 { 461 {
230 hold_status = true; 462 hold_status = true;
231 } 463 }
232 if (hold_status && !rtc_alarm && (usb_detect() != USB_INSERTED) && 464 if ((hold_status || recovery_mode) && !rtc_alarm &&
233 !charger_inserted()) 465 (usb_detect() != USB_INSERTED) && !charger_inserted())
234 { 466 {
235 if (detect_original_firmware()) 467 if (detect_original_firmware())
236 { 468 {
237 printf("Hold switch on"); 469 printf("Hold switch on");
238 shutdown(); 470 shutdown();
239 } 471 }
472
473 failsafe_menu();
240 } 474 }
241 475
242 /* Holding REC while starting runs the original firmware */ 476 /* Holding REC while starting runs the original firmware */
@@ -321,6 +555,12 @@ void main(void)
321 lcd_remote_puts(0, 3, msg); 555 lcd_remote_puts(0, 3, msg);
322 lcd_remote_update(); 556 lcd_remote_update();
323 557
558 if (firmware_settings.initialized)
559 {
560 firmware_settings.disk_clean = false;
561 eeprom_settings_store();
562 }
563
324 ide_power_enable(true); 564 ide_power_enable(true);
325 storage_enable(false); 565 storage_enable(false);
326 sleep(HZ/20); 566 sleep(HZ/20);
@@ -351,6 +591,11 @@ void main(void)
351 usb_charge = false; 591 usb_charge = false;
352 } 592 }
353 593
594 /* boot from flash if that is the default */
595 try_flashboot();
596 if (recovery_mode)
597 printf("Falling back to boot from disk");
598
354 rc = storage_init(); 599 rc = storage_init();
355 if(rc) 600 if(rc)
356 { 601 {