From: Erik M. <er...@us...> - 2001-07-24 13:23:57
|
Update of /cvsroot/blob/blob/src In directory usw-pr-cvs1:/tmp/cvs-serv9911/src Modified Files: Tag: blob_1_0_9_hack main.c start.S time.c Log Message: - "reblob" command that allows you to start a just downloaded blob from RAM - updated documentation - start.S updated for reblob, it now finds out where it is running from - made msleep() function for Reboot() and Reblob() Index: main.c =================================================================== RCS file: /cvsroot/blob/blob/src/main.c,v retrieving revision 1.1.1.1.2.10 retrieving revision 1.1.1.1.2.11 diff -u -r1.1.1.1.2.10 -r1.1.1.1.2.11 --- main.c 2001/07/23 05:44:26 1.1.1.1.2.10 +++ main.c 2001/07/24 13:23:54 1.1.1.1.2.11 @@ -88,16 +88,11 @@ void Reload(char *commandline, blobStatus *status); void PrintSerialSpeed(eBauds speed); void Reboot(void); +void Reblob(void); -/* Hmm, the compiler complains that the 'noreturn' function - * returns. Looks like a compiler bug, should test with gcc-3.0 to see - * if it got fixed -- Erik - */ -/* void Reboot(void) __attribute__ ((noreturn)) ; */ - int main(void) { u32 blockSize = 0x00800000; @@ -200,6 +195,8 @@ Flash(commandline + 6, &status); } else if(MyStrNCmp(commandline, "help", 4) == 0) { PrintHelp(); + } else if(MyStrNCmp(commandline, "reblob", 6) == 0) { + Reblob(); } else if(MyStrNCmp(commandline, "reboot", 6) == 0) { Reboot(); } else if(MyStrNCmp(commandline, "reload ", 7) == 0) { @@ -409,6 +406,7 @@ SerialOutputString("* download {blob|kernel|ramdisk} Download kernel or ramdisk image to RAM\n"); SerialOutputString("* flash {blob|kernel|ramdisk} Copy kernel or ramdisk from RAM to flash\n"); SerialOutputString("* help Get this help\n"); + SerialOutputString("* reblob Restart blob from RAM\n"); SerialOutputString("* reboot Reboot system\n"); SerialOutputString("* reload {blob|kernel|ramdisk} Reload kernel or ramdisk from flash to RAM\n"); SerialOutputString("* reset Reset terminal\n"); @@ -604,20 +602,24 @@ void Reboot(void) { - u32 startTime, currentTime; - SerialOutputString("Rebooting...\n\n"); - /* sleep for half a second */ - TimerClearOverflow(); - startTime = TimerGetTime(); - - do { - currentTime = TimerGetTime(); - if(TimerDetectOverflow()) - break; - } while((currentTime - startTime) < TICKS_PER_SECOND/2); - + msleep(500); + RCSR = 0; RSRR = 1; +} + + + + +void Reblob(void) +{ + void (*blob)(void) = (void (*)(void))BLOB_RAM_BASE; + + SerialOutputString("Restarting blob from RAM...\n\n"); + + msleep(500); + + blob(); } Index: start.S =================================================================== RCS file: /cvsroot/blob/blob/src/start.S,v retrieving revision 1.1.1.1.2.11 retrieving revision 1.1.1.1.2.12 diff -u -r1.1.1.1.2.11 -r1.1.1.1.2.12 --- start.S 2001/07/22 22:54:26 1.1.1.1.2.11 +++ start.S 2001/07/24 13:23:54 1.1.1.1.2.12 @@ -166,12 +166,20 @@ subs r0, r0, #(8 * 4) bne clear_loop + + /* get a clue where we are running, so we know what to copy */ + and r0, pc, #0xff000000 /* we don't care about the low bits */ + /* relocate the second stage loader */ - mov r0, #0x400 /* skip first 1024 bytes */ + add r2, r0, #(128 * 1024) /* blob is 128kB */ + add r0, r0, #0x400 /* skip first 1024 bytes */ ldr r1, MEM_START - mov r2, #(128 * 1024) /* blob is 128kB */ + /* r0 = source address + * r1 = target address + * r2 = source end address + */ copy_loop: ldmia r0!, {r3-r10} stmia r1!, {r3-r10} Index: time.c =================================================================== RCS file: /cvsroot/blob/blob/src/time.c,v retrieving revision 1.1.1.1.2.2 retrieving revision 1.1.1.1.2.3 diff -u -r1.1.1.1.2.2 -r1.1.1.1.2.3 --- time.c 2001/07/22 22:54:26 1.1.1.1.2.2 +++ time.c 2001/07/24 13:23:54 1.1.1.1.2.3 @@ -100,3 +100,43 @@ OSSR = OSSR_M0; } + + + +void msleep(unsigned int msec) +{ + u32 ticks, start, end; + int will_overflow = 0; + int has_overflow = 0; + int reached = 0; + + if(msec == 0) + return; + + ticks = (TICKS_PER_SECOND * msec) / 1000; + + start = TimerGetTime(); + + /* this could overflow, but it nicely wraps around which is + * exactly what we want + */ + end = start + ticks; + + /* detect the overflow */ + if(end < start) { + TimerClearOverflow(); + will_overflow = 1; + } + + do { + if(will_overflow && !has_overflow) { + if(TimerDetectOverflow()) + has_overflow = 1; + + continue; + } + + if(TimerGetTime() >= end) + reached = 1; + } while(!reached); +} |