1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * !!! DON'T MESS WITH THIS CODE UNLESS YOU'RE ABSOLUTELY SURE WHAT YOU DO !!!
12 * Copyright (C) 2006 by Miika Pekkarinen
14 * All files in this archive are subject to the GNU General Public License.
15 * See the file COPYING in the source tree root for full license agreement.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
23 /* All CFI flash routines are copied and ported from firmware_flash.c */
25 #ifndef SIMULATOR /* only for target */
27 unsigned char *audiobuf
;
28 ssize_t audiobuf_size
;
30 #ifdef IRIVER_H100_SERIES
31 #define PLATFORM_ID ID_IRIVER_H100
33 #undef PLATFORM_ID /* this platform is not (yet) flashable */
40 #if CONFIG_KEYPAD == IRIVER_H100_PAD
41 #define KEY1 BUTTON_OFF
42 #define KEY2 BUTTON_ON
43 #define KEY3 BUTTON_SELECT
44 #define KEYNAME1 "[Stop]"
45 #define KEYNAME2 "[On]"
46 #define KEYNAME3 "[Select]"
57 static struct plugin_api
* rb
; /* here is a global api struct pointer */
59 #ifdef IRIVER_H100_SERIES
61 #define BOOTLOADER_ERASEGUARD (BOOTLOADER_ENTRYPOINT / SEC_SIZE)
67 static volatile uint16_t* FB
= (uint16_t*)0x00000000; /* Flash base address */
70 /* read the manufacturer and device ID */
71 bool cfi_read_id(volatile uint16_t* pBase
, uint8_t* pManufacturerID
, uint8_t* pDeviceID
)
73 uint8_t not_manu
, not_id
; /* read values before switching to ID mode */
74 uint8_t manu
, id
; /* read values when in ID mode */
76 pBase
= (uint16_t*)((uint32_t)pBase
& 0xFFF80000); /* down to 512k align */
78 /* read the normal content */
79 not_manu
= pBase
[0]; /* should be 'A' (0x41) and 'R' (0x52) */
80 not_id
= pBase
[1]; /* from the "ARCH" marker */
82 pBase
[0x5555] = 0xAA; /* enter command mode */
84 pBase
[0x5555] = 0x90; /* ID command */
85 rb
->sleep(HZ
/50); /* Atmel wants 20ms pause here */
90 pBase
[0] = 0xF0; /* reset flash (back to normal read mode) */
91 rb
->sleep(HZ
/50); /* Atmel wants 20ms pause here */
93 /* I assume success if the obtained values are different from
94 the normal flash content. This is not perfectly bulletproof, they
95 could theoretically be the same by chance, causing us to fail. */
96 if (not_manu
!= manu
|| not_id
!= id
) /* a value has changed */
98 *pManufacturerID
= manu
; /* return the results */
100 return true; /* success */
102 return false; /* fail */
106 /* erase the sector which contains the given address */
107 bool cfi_erase_sector(volatile uint16_t* pAddr
)
109 unsigned timeout
= 430000; /* the timeout loop should be no less than 25ms */
111 FB
[0x5555] = 0xAA; /* enter command mode */
113 FB
[0x5555] = 0x80; /* erase command */
114 FB
[0x5555] = 0xAA; /* enter command mode */
116 *pAddr
= 0x30; /* erase the sector */
118 /* I counted 7 instructions for this loop -> min. 0.58 us per round */
119 /* Plus memory waitstates it will be much more, gives margin */
120 while (*pAddr
!= 0xFFFF && --timeout
); /* poll for erased */
122 return (timeout
!= 0);
126 /* address must be in an erased location */
127 inline bool cfi_program_word(volatile uint16_t* pAddr
, uint16_t data
)
129 unsigned timeout
= 85; /* the timeout loop should be no less than 20us */
131 if (~*pAddr
& data
) /* just a safety feature, not really necessary */
132 return false; /* can't set any bit from 0 to 1 */
134 FB
[0x5555] = 0xAA; /* enter command mode */
136 FB
[0x5555] = 0xA0; /* byte program command */
140 /* I counted 7 instructions for this loop -> min. 0.58 us per round */
141 /* Plus memory waitstates it will be much more, gives margin */
142 while (*pAddr
!= data
&& --timeout
); /* poll for programmed */
144 return (timeout
!= 0);
148 /* this returns true if supported and fills the info struct */
149 bool cfi_get_flash_info(struct flash_info
* pInfo
)
151 rb
->memset(pInfo
, 0, sizeof(struct flash_info
));
153 if (!cfi_read_id(FB
, &pInfo
->manufacturer
, &pInfo
->id
))
156 if (pInfo
->manufacturer
== 0xBF) /* SST */
158 if (pInfo
->id
== 0xD6)
160 pInfo
->size
= 256* 1024; /* 256k */
161 rb
->strcpy(pInfo
->name
, "SST39VF020");
164 else if (pInfo
->id
== 0xD7)
166 pInfo
->size
= 512* 1024; /* 512k */
167 rb
->strcpy(pInfo
->name
, "SST39VF040");
170 else if (pInfo
->id
== 0x82)
172 pInfo
->size
= 2048* 1024; /* 2 MiB */
173 rb
->strcpy(pInfo
->name
, "SST39VF160");
183 /*********** Utility Functions ************/
186 /* Tool function to calculate a CRC32 across some buffer */
187 /* third argument is either 0xFFFFFFFF to start or value from last piece */
188 unsigned crc_32(const unsigned char* buf
, unsigned len
, unsigned crc32
)
190 /* CCITT standard polynomial 0x04C11DB7 */
191 static const unsigned crc32_lookup
[16] =
192 { /* lookup table for 4 bits at a time is affordable */
193 0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9,
194 0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005,
195 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61,
196 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD
204 byte
= *buf
++; /* get one byte of data */
206 /* upper nibble of our data */
207 t
= crc32
>> 28; /* extract the 4 most significant bits */
208 t
^= byte
>> 4; /* XOR in 4 bits of data into the extracted bits */
209 crc32
<<= 4; /* shift the CRC register left 4 bits */
210 crc32
^= crc32_lookup
[t
]; /* do the table lookup and XOR the result */
212 /* lower nibble of our data */
213 t
= crc32
>> 28; /* extract the 4 most significant bits */
214 t
^= byte
& 0x0F; /* XOR in 4 bits of data into the extracted bits */
215 crc32
<<= 4; /* shift the CRC register left 4 bits */
216 crc32
^= crc32_lookup
[t
]; /* do the table lookup and XOR the result */
223 /***************** User Interface Functions *****************/
224 int wait_for_button(void)
230 button
= rb
->button_get(true);
231 } while (button
& BUTTON_REL
);
236 /* helper for DoUserDialog() */
237 void ShowFlashInfo(struct flash_info
* pInfo
)
241 if (!pInfo
->manufacturer
)
243 rb
->lcd_puts(0, 0, "Flash: M=?? D=??");
244 rb
->lcd_puts(0, 1, "Impossible to program");
248 rb
->snprintf(buf
, sizeof(buf
), "Flash: M=%02x D=%02x",
249 pInfo
->manufacturer
, pInfo
->id
);
250 rb
->lcd_puts(0, 0, buf
);
255 rb
->lcd_puts(0, 1, pInfo
->name
);
256 rb
->snprintf(buf
, sizeof(buf
), "Size: %d KB", pInfo
->size
/ 1024);
257 rb
->lcd_puts(0, 2, buf
);
261 rb
->lcd_puts(0, 1, "Unsupported chip");
271 struct flash_info fi
;
273 rb
->lcd_clear_display();
274 cfi_get_flash_info(&fi
);
276 if (fi
.size
== 0) /* no valid chip */
278 rb
->splash(HZ
*3, "Sorry!");
279 return false; /* exit */
285 bool confirm(const char *msg
)
290 rb
->snprintf(buf
, sizeof buf
, "%s ([PLAY] to CONFIRM)", msg
);
293 ret
= (wait_for_button() == BUTTON_ON
);
299 int load_firmware_file(const char *filename
, uint32_t *checksum
)
306 fd
= rb
->open(filename
, O_RDONLY
);
310 len
= rb
->filesize(fd
);
312 if (audiobuf_size
< len
)
314 rb
->splash(HZ
*3, "Aborting: Out of memory!");
319 rb
->read(fd
, checksum
, 4);
320 rb
->lseek(fd
, FIRMWARE_OFFSET_FILE_DATA
, SEEK_SET
);
321 len
-= FIRMWARE_OFFSET_FILE_DATA
;
323 rc
= rb
->read(fd
, audiobuf
, len
);
327 rb
->splash(HZ
*3, "Aborting: Read failure");
331 /* Verify the checksum */
333 for (i
= 0; i
< len
; i
++)
336 if (sum
!= *checksum
)
338 rb
->splash(HZ
*3, "Aborting: Checksums mismatch!");
345 unsigned long valid_bootloaders
[][2] = {
347 #ifdef IRIVER_H120 /* Iriver H120/H140 checksums */
348 { 63788, 0x08ff01a9 }, /* 7-pre3, improved failsafe functions */
349 { 48764, 0xc674323e }, /* 7-pre4. Fixed audio thump & remote bootup */
352 { 48760, 0x2efc3323 }, /* 7-pre4 */
358 bool detect_valid_bootloader(const unsigned char *addr
, int len
)
363 /* Try to scan through all valid bootloaders. */
364 for (i
= 0; valid_bootloaders
[i
][0]; i
++)
366 if (len
> 0 && len
!= (long)valid_bootloaders
[i
][0])
369 crc32
= crc_32(addr
, valid_bootloaders
[i
][0], 0xffffffff);
370 if (crc32
== valid_bootloaders
[i
][1])
377 static int get_section_address(int section
)
379 if (section
== SECT_RAMIMAGE
)
380 return FLASH_RAMIMAGE_ENTRY
;
381 else if (section
== SECT_ROMIMAGE
)
382 return FLASH_ROMIMAGE_ENTRY
;
387 int flash_rockbox(const char *filename
, int section
)
389 struct flash_header hdr
;
392 unsigned long checksum
, sum
;
396 if (get_section_address(section
) < 0)
399 p8
= (char *)BOOTLOADER_ENTRYPOINT
;
400 if (!detect_valid_bootloader(p8
, 0))
402 rb
->splash(HZ
*3, "Incompatible bootloader");
406 if (!rb
->detect_original_firmware())
408 if (!confirm("Update Rockbox flash image?"))
413 if (!confirm("Erase original firmware?"))
417 len
= load_firmware_file(filename
, &checksum
);
421 pos
= get_section_address(section
);
423 /* Check if image relocation seems to be sane. */
424 if (section
== SECT_ROMIMAGE
)
426 uint32_t *p32
= (uint32_t *)audiobuf
;
428 if (pos
+sizeof(struct flash_header
) != *p32
)
430 rb
->snprintf(buf
, sizeof(buf
), "Incorrect relocation: 0x%08lx/0x%08lx",
431 *p32
, pos
+sizeof(struct flash_header
));
432 rb
->splash(HZ
*10, buf
);
438 /* Erase the program flash. */
439 for (i
= 0; i
+ pos
< BOOTLOADER_ENTRYPOINT
&& i
< len
+ 32; i
+= SEC_SIZE
)
441 /* Additional safety check. */
442 if (i
+ pos
< SEC_SIZE
)
445 rb
->snprintf(buf
, sizeof(buf
), "Erasing... %d%%",
446 (i
+SEC_SIZE
)*100/len
);
447 rb
->lcd_puts(0, 3, buf
);
450 rc
= cfi_erase_sector(FB
+ (i
+ pos
)/2);
453 /* Write the magic and size. */
454 rb
->memset(&hdr
, 0, sizeof(struct flash_header
));
455 hdr
.magic
= FLASH_MAGIC
;
457 // rb->strncpy(hdr.version, APPSVERSION, sizeof(hdr.version)-1);
458 p16
= (uint16_t *)&hdr
;
460 rb
->snprintf(buf
, sizeof(buf
), "Programming...");
461 rb
->lcd_puts(0, 4, buf
);
464 pos
= get_section_address(section
)/2;
465 for (i
= 0; i
< (long)sizeof(struct flash_header
)/2; i
++)
467 cfi_program_word(FB
+ pos
, p16
[i
]);
471 p16
= (uint16_t *)audiobuf
;
472 for (i
= 0; i
< len
/2 && pos
+ i
< (BOOTLOADER_ENTRYPOINT
/2); i
++)
474 if (i
% SEC_SIZE
== 0)
476 rb
->snprintf(buf
, sizeof(buf
), "Programming... %d%%",
478 rb
->lcd_puts(0, 4, buf
);
482 cfi_program_word(FB
+ pos
+ i
, p16
[i
]);
486 rb
->snprintf(buf
, sizeof(buf
), "Verifying");
487 rb
->lcd_puts(0, 5, buf
);
490 p8
= (char *)get_section_address(section
);
491 p8
+= sizeof(struct flash_header
);
493 for (i
= 0; i
< len
; i
++)
498 rb
->splash(HZ
*3, "Verify failed!");
499 /* Erase the magic sector so bootloader does not try to load
500 * rockbox from flash and crash. */
501 if (section
== SECT_RAMIMAGE
)
502 cfi_erase_sector(FB
+ FLASH_RAMIMAGE_ENTRY
/2);
504 cfi_erase_sector(FB
+ FLASH_ROMIMAGE_ENTRY
/2);
508 rb
->splash(HZ
*2, "Success");
513 void show_fatal_error(void)
515 rb
->splash(HZ
*30, "Disable idle poweroff, connect AC power and DON'T TURN PLAYER OFF!!");
516 rb
->splash(HZ
*30, "Contact Rockbox developers as soon as possible!");
517 rb
->splash(HZ
*30, "Your device won't be bricked unless you turn off the power");
518 rb
->splash(HZ
*30, "Don't use the device before further instructions from Rockbox developers");
521 int flash_bootloader(const char *filename
)
525 unsigned long checksum
, sum
;
529 bootsector
= audiobuf
;
530 audiobuf
+= SEC_SIZE
;
531 audiobuf_size
-= SEC_SIZE
;
533 if (!confirm("Update bootloader?"))
536 len
= load_firmware_file(filename
, &checksum
);
542 rb
->splash(HZ
*3, "Too big bootloader");
546 /* Verify the crc32 checksum also. */
547 if (!detect_valid_bootloader(audiobuf
, len
))
549 rb
->splash(HZ
*3, "Incompatible/Untested bootloader");
553 rb
->lcd_puts(0, 3, "Flashing...");
556 /* Backup the bootloader sector first. */
558 rb
->memcpy(bootsector
, p8
, SEC_SIZE
);
560 /* Erase the boot sector and write a proper reset vector. */
561 cfi_erase_sector(FB
);
562 p16
= (uint16_t *)audiobuf
;
563 for (i
= 0; i
< 8/2; i
++)
564 cfi_program_word(FB
+ i
, p16
[i
]);
566 /* And restore original content for original FW to function. */
567 p16
= (uint16_t *)bootsector
;
568 for (i
= 8/2; i
< SEC_SIZE
/2; i
++)
569 cfi_program_word(FB
+ i
, p16
[i
]);
571 /* Erase the bootloader flash section. */
572 for (i
= BOOTLOADER_ENTRYPOINT
/SEC_SIZE
; i
< 0x200; i
++)
573 rc
= cfi_erase_sector(FB
+ (SEC_SIZE
/2) * i
);
575 pos
= BOOTLOADER_ENTRYPOINT
/2;
576 p16
= (uint16_t *)audiobuf
;
577 for (i
= 0; i
< len
/2; i
++)
578 cfi_program_word(FB
+ pos
+ i
, p16
[i
]);
581 p8
= (char *)BOOTLOADER_ENTRYPOINT
;
583 for (i
= 0; i
< len
; i
++)
588 rb
->splash(HZ
*3, "Verify failed!");
594 for (i
= 0; i
< 8; i
++)
596 if (p8
[i
] != audiobuf
[i
])
598 rb
->splash(HZ
*3, "Bootvector corrupt!");
604 rb
->splash(HZ
*2, "Success");
609 int flash_original_fw(int len
)
611 unsigned char reset_vector
[8];
619 rb
->lcd_puts(0, 3, "Critical section...");
623 rb
->memcpy(reset_vector
, p8
, sizeof reset_vector
);
625 /* Erase the boot sector and write back the reset vector. */
626 cfi_erase_sector(FB
);
627 p16
= (uint16_t *)reset_vector
;
628 for (i
= 0; i
< (long)sizeof(reset_vector
)/2; i
++)
629 cfi_program_word(FB
+ i
, p16
[i
]);
631 rb
->lcd_puts(0, 4, "Flashing orig. FW");
634 /* Erase the program flash. */
635 for (i
= 1; i
< BOOTLOADER_ERASEGUARD
&& (i
-1)*4096 < len
; i
++)
637 rc
= cfi_erase_sector(FB
+ (SEC_SIZE
/2) * i
);
638 rb
->snprintf(buf
, sizeof(buf
), "Erase: 0x%03x (%d)", i
, rc
);
639 rb
->lcd_puts(0, 5, buf
);
643 rb
->snprintf(buf
, sizeof(buf
), "Programming");
644 rb
->lcd_puts(0, 6, buf
);
648 p16
= (uint16_t *)audiobuf
;
649 for (i
= 0; i
< len
/2 && pos
+ i
< (BOOTLOADER_ENTRYPOINT
/2); i
++)
650 cfi_program_word(FB
+ pos
+ i
, p16
[i
]);
652 rb
->snprintf(buf
, sizeof(buf
), "Verifying");
653 rb
->lcd_puts(0, 7, buf
);
656 /* Verify reset vectors. */
658 for (i
= 0; i
< 8; i
++)
660 if (p8
[i
] != reset_vector
[i
])
662 rb
->splash(HZ
*3, "Bootvector corrupt!");
669 p8
= (char *)0x00000008;
670 for (i
= 0; i
< len
; i
++)
672 if (p8
[i
] != audiobuf
[i
])
674 rb
->splash(HZ
*3, "Verify failed!");
675 rb
->snprintf(buf
, sizeof buf
, "at: 0x%08x", i
);
676 rb
->splash(HZ
*10, buf
);
681 rb
->splash(HZ
*2, "Success");
686 int load_original_bin(const char *filename
)
688 unsigned long magic
[2];
692 if (!confirm("Restore original firmware (bootloader will be kept)?"))
695 fd
= rb
->open(filename
, O_RDONLY
);
699 len
= rb
->filesize(fd
) - 0x228;
700 rb
->lseek(fd
, 0x220, SEEK_SET
);
701 rb
->read(fd
, magic
, 8);
702 if (magic
[1] != 0x00000008 || len
<= 0 || len
> audiobuf_size
)
704 rb
->splash(HZ
*2, "Not an original firmware file");
709 rc
= rb
->read(fd
, audiobuf
, len
);
714 rb
->splash(HZ
*2, "Read error");
721 return flash_original_fw(len
);
724 int load_romdump(const char *filename
)
729 if (!confirm("Restore firmware section (bootloader will be kept)?"))
732 fd
= rb
->open(filename
, O_RDONLY
);
736 len
= rb
->filesize(fd
) - 8;
740 rb
->lseek(fd
, 8, SEEK_SET
);
741 rc
= rb
->read(fd
, audiobuf
, len
);
746 rb
->splash(HZ
*2, "Read error");
753 if (len
> BOOTLOADER_ENTRYPOINT
- 8)
754 len
= BOOTLOADER_ENTRYPOINT
- 8;
756 return flash_original_fw(len
);
759 /* Kind of our main function, defines the application flow. */
760 void DoUserDialog(char* filename
)
762 /* this can only work if Rockbox runs in DRAM, not flash ROM */
763 if ((uint16_t*)rb
>= FB
&& (uint16_t*)rb
< FB
+ 4096*1024) /* 4 MB max */
764 { /* we're running from flash */
765 rb
->splash(HZ
*3, "Not from ROM");
769 /* refuse to work if the power may fail meanwhile */
770 if (!rb
->battery_level_safe())
772 rb
->splash(HZ
*3, "Battery too low!");
776 rb
->lcd_setfont(FONT_SYSFIXED
);
780 if (filename
== NULL
)
782 rb
->splash(HZ
*3, "Please use this plugin with \"Open with...\"");
786 audiobuf
= rb
->plugin_get_audio_buffer((size_t *)&audiobuf_size
);
788 if (rb
->strcasestr(filename
, "/rockbox.iriver"))
789 flash_rockbox(filename
, SECT_RAMIMAGE
);
790 else if (rb
->strcasestr(filename
, "/rombox.iriver"))
791 flash_rockbox(filename
, SECT_ROMIMAGE
);
792 else if (rb
->strcasestr(filename
, "/bootloader.iriver"))
793 flash_bootloader(filename
);
794 else if (rb
->strcasestr(filename
, "/ihp_120.bin"))
795 load_original_bin(filename
);
796 else if (rb
->strcasestr(filename
, "/internal_rom_000000-1FFFFF.bin"))
797 load_romdump(filename
);
799 rb
->splash(HZ
*3, "Unknown file type");
803 /***************** Plugin Entry Point *****************/
805 enum plugin_status
plugin_start(struct plugin_api
* api
, void* parameter
)
809 rb
= api
; /* copy to global api pointer */
811 /* now go ahead and have fun! */
812 oldmode
= rb
->system_memory_guard(MEMGUARD_NONE
); /*disable memory guard */
813 DoUserDialog((char*) parameter
);
814 rb
->system_memory_guard(oldmode
); /* re-enable memory guard */
819 #endif /* ifdef PLATFORM_ID */
820 #endif /* #ifndef SIMULATOR */