From: <rob...@us...> - 2005-01-09 11:40:56
|
Update of /cvsroot/gc-linux/ipl/ipl In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5953/ipl Added Files: flash.c ipl.c Log Message: Sorted all source files int / into the following directories: io, lowlevel, loadand ipl Did some cleaning in the source files, but there is still much to be done --- NEW FILE: flash.c --- /* * function to write to flash. Only works with modified IPL "ROM"s. */ #include <ipl.h> #include <vsprintf.h> int chip_erase(void) { rom_write(0xAAA, 0xAA); rom_write(0x555, 0x55); rom_write(0xAAA, 0x80); rom_write(0xAAA, 0xAA); rom_write(0x555, 0x55); rom_write(0xAAA, 0x10); printf("erasing..\n"); while (!(rom_read(0) & 0x80)); return 0; } int erase_sector(int addr) { rom_write(0xAAA, 0xAA); rom_write(0x555, 0x55); rom_write(0xAAA, 0x80); rom_write(0xAAA, 0xAA); rom_write(0x555, 0x55); rom_write(addr, 0x30); printf("\r%08x erase..\n", addr); // while (!(rom_read(addr) & 0x80)) ; while (rom_read(addr) != rom_read(addr)); return 0; } int is_eraseblock(int addr) { if (addr >= 0x10000) return !(addr & 0xFFFF); return ((addr == 0) || (addr == 0x4000) || (addr == 0x6000) || (addr == 0x8000)); } int do_flash(int target, unsigned char *src, int len) { ipl_set_config(0x0); // CFI query rom_write(0xAA, 0x98); printf("CFI data:\n"); int addr; for (addr = 0; addr < 0x100; addr += 0x10) { int i; for (i=0; i<0x10; i += 2) printf("%02x ", rom_read(addr + i)); for (i=0; i<0x10; i += 2) { int v = rom_read(addr + i); printf("%c", v >= 0x20 ? v : '.'); } printf("\n"); } printf("man id:\n"); int i; for (i=0; i<10; ++i) { rom_write(0, 0xF0); rom_write(0xAAA, 0xAA); rom_write(0x555, 0x55); rom_write(0xAAA, 0x90); printf("%02x ", rom_read(i * 2)); } printf("\n"); rom_write(0xAAA, 0xAA); rom_write(0x555, 0x55); rom_write(0xAAA, 0x20); printf("erasing...\n"); for (addr = target; addr < (target + len); ++addr) if (is_eraseblock(addr)) erase_sector(addr); printf("flashing...\n"); while (len) { rom_write(target, 0xA0); rom_write(target, *src); while (rom_read(target) != *src); ++src; ++target; --len; } printf("done!\n"); return 0; } --- NEW FILE: ipl.c --- /* * different stuff to access the IPL chips (including special functions) */ #include <exi.h> #include <time.h> #include <ipl.h> unsigned char sram_data[64] __attribute__((__aligned__(32))); void exi_sram_read(void *data) { unsigned long val; exi_select(0, 1, 3); val = 0x20000100; exi_write(0, &val, 4); exi_read(0, data, 64); exi_deselect(0); } void exi_sram_write(void *data) { unsigned long val; exi_select(0, 1, 3); val = 0xA0000100; exi_write(0, &val, 4); exi_write(0, data, 64); exi_deselect(0); } void exi_ipl_write(unsigned long addr, unsigned long val) { exi_select(0, 1, 3); exi_write(0, &addr, 4); exi_write(0, &val, 4); exi_deselect(0); } unsigned char rom_read(int addr) { addr <<= 6; unsigned long val; exi_select(0, 1, 3); exi_write(0, &addr, 4); exi_read(0, &val, 4); exi_deselect(0); return val >> 24; } void rom_readn(int addr, unsigned char *d, int len) { while (len) { int max = 1024 - (addr & 1023); if (len < max) max = len; addr <<= 6; exi_select(0, 1, 3); exi_write(0, &addr, 4); exi_read(0, d, max); exi_deselect(0); addr += max; len -= max; } } void rom_write(int addr, unsigned char c) { unsigned long val; addr <<= 6; addr |= 0x80000000; val = c << 24; exi_select(0, 1, 3); exi_write(0, &addr, 4); exi_write(0, &val, 4); exi_deselect(0); } void s_putc(unsigned char c) { unsigned long val, addr; addr = 0xA8000000; val = c << 24; exi_select(0, 1, 3); exi_write(0, &addr, 4); exi_write(0, &val, 4); exi_deselect(0); // udelay(1000000/115200*20); mdelay(1); } void ipl_read(void *dst, unsigned long addr, int len) { addr <<= 6; exi_select(0, 1, 3); exi_write(0, &addr, 4); exi_read(0, dst, len); exi_deselect(0); } void ipl_set_config(unsigned char c) { unsigned long val, addr; addr = 0xB0000000; val = c << 24; exi_select(0, 1, 3); exi_write(0, &addr, 4); exi_write(0, &val, 4); exi_deselect(0); } void ipl_boot(int what) { if (what < 0) ipl_set_config(0x2); // boot to original IPL else ipl_set_config(what << 4); // boot with prefix *(unsigned long*)0xcc003024=0; while (1); } //Test for rob's ipl int ipl_rob_test() { //request the dataflash's status. Test it multiple times, to make sure they are //not some randomly read values from some memory exi_select(0,1,4); exi_rw(0,0x40,1); //select dataflash exi_rw(0,0x40,1); //request status int i; for (i=0;i<20;i++) if ((exi_rw(0,-1,1) & 0x3c) != 0x1c) return 0; return 1; } void ipl_rob_read(void *dst, unsigned long addr, int len) { unsigned long page,byte,dfaddr; byte=addr % DATAFLASH_PAGE_SIZE; page=(addr-byte)/DATAFLASH_PAGE_SIZE; dfaddr=(page<<9) | byte; exi_select(0,1,4); exi_rw(0,0x40,1); //select dataflash exi_rw(0,0xE8000000|dfaddr,4); //send page and byte adress exi_rw(0,-1,4); //dummy exi_read(0,dst,len); exi_deselect(0); } |