Index: firmware/export/rolo.h =================================================================== --- firmware/export/rolo.h (revision 17888) +++ firmware/export/rolo.h (working copy) @@ -27,4 +27,13 @@ void rolo_restart_cop(void); #endif +#ifdef IPOD_ARCH +#define ROM_ID(a,b,c,d) (unsigned int)( ((unsigned int)(d)) | \ + (((unsigned int)(c)) << 8) | \ + (((unsigned int)(b)) << 16) | \ + (((unsigned int)(a)) << 24) ) + +int rolo_load_rom(const unsigned int imageid); #endif + +#endif Index: firmware/rolo.c =================================================================== --- firmware/rolo.c (revision 17888) +++ firmware/rolo.c (working copy) @@ -369,3 +369,68 @@ } #endif /* !defined(IRIVER_IFP7XX_SERIES) */ + +#ifdef IPOD_ARCH + +/* Rolo an image from the ipod's flash ROM. Possible values for + imageid are: + + ROM_ID('d','i','s','k') - disk mode + ROM_ID('d','i','a','g') - diagnostics mode + + */ + +int rolo_load_rom(const unsigned int imageid) +{ + long length, offset; + int i; + unsigned long checksum,rom_checksum; + unsigned char* ramstart = (void*)&loadaddress; + unsigned char* romstart = (void*)0x20000000; + unsigned int* p = (unsigned int*)0x200ffe00; + + /* Clear the display - this is mainly for debugging, so we know if + rolo freezes - it is still (3 March 2007) not 100% reliable */ + lcd_clear_display(); + lcd_update(); + + /* Find the image in the directory */ + while ((p[0] == ROM_ID('f','l','s','h')) && (p[1] != imageid)) + p += 10; + + if (p[1] != imageid) { + lcd_puts(0, 0, "ROM image not found"); + return -1; + } + + audio_stop(); + + offset = p[3]; + length = p[4]; + rom_checksum = p[7]; + + checksum = 0; + for(i = offset;i < offset + length;i++) { + checksum += romstart[i]; + } + + /* Verify checksum against file header */ + if (checksum != rom_checksum) { + lcd_clear_display(); + lcd_puts(0, 0, "Checksum Error"); + lcd_update(); + return -1; + } + + rolo_restart_cop(); + /* Wait for COP to be in safe code */ + while(cpu_reply != 1); + COP_CTL = PROC_WAKE; + + set_irq_level(HIGHEST_IRQ_LEVEL); + + rolo_restart(romstart+offset, ramstart, length); + + return 0; /* this is never reached */ +} +#endif /* defined(IPOD_ARCH) */ Index: firmware/usb.c =================================================================== --- firmware/usb.c (revision 17888) +++ firmware/usb.c (working copy) @@ -46,6 +46,9 @@ #include "pcf50606.h" /* for pcf50606_usb_charging_... */ #endif #include "logf.h" +#ifdef IPOD_ARCH +#include "rolo.h" +#endif /* Conditions under which we want the entire driver */ #if !defined(BOOTLOADER) || \ @@ -145,6 +148,22 @@ static void try_reboot(void) { +#ifdef IPOD_ARCH + /* The diskmode code appears to check this string when + disconnected. Writing diskmode instead of retailos causes + the ipod to re-enter disk mode after reconnection. Writing + retailos here causes the ipod to load the firmware from the + firmware partition - which is what we want. + */ +#if CONFIG_CPU == PP5020 + memcpy((void *)0x40017f00, "retailos\0\0hotstuff\0\0\1", 21); +#elif CONFIG_CPU == PP5022 + memcpy((void *)0x4001ff00, "retailos\0\0hotstuff\0\0\1", 21); +#endif /* CONFIG_CPU */ + + rolo_load_rom(ROM_ID('d','i','s','k')); +#endif + #ifndef HAVE_FLASH_STORAGE ata_sleepnow(); /* Immediately spindown the disk. */ sleep(HZ*2);