| Index: embios/trunk/target/ipodnano2g/mmu.c | 
| — | — | @@ -62,3 +62,12 @@ | 
| 63 | 63 | "MOV PC, LR                \n\t" | 
| 64 | 64 | ); | 
| 65 | 65 | } | 
|  | 66 | + | 
|  | 67 | +void invalidate_icache() | 
|  | 68 | +{ | 
|  | 69 | +    asm volatile( | 
|  | 70 | +        "MOV R0, #0                \n\t" | 
|  | 71 | +        "MCR p15, 0, R0,c7,c5,0    \n\t" | 
|  | 72 | +        "MOV PC, LR                \n\t" | 
|  | 73 | +    ); | 
|  | 74 | +} | 
| Index: embios/trunk/target/ipodnano2g/ls.x | 
| — | — | @@ -14,10 +14,12 @@ | 
| 15 | 15 | { | 
| 16 | 16 | .init : | 
| 17 | 17 | { | 
|  | 18 | +        _initstart = .; | 
| 18 | 19 | *(.initcode*) | 
| 19 | 20 | *(.initrodata*) | 
| 20 | 21 | *(.initdata*) | 
| 21 | 22 | . = ALIGN(0x4); | 
|  | 23 | +        _initend = .; | 
| 22 | 24 | } > INIT | 
| 23 | 25 |  | 
| 24 | 26 | .sram : | 
| Index: embios/trunk/target/ipodnano2g/mmu.h | 
| — | — | @@ -30,6 +30,7 @@ | 
| 31 | 31 |  | 
| 32 | 32 | void clean_dcache() __attribute__((naked, noinline)) ICODE_ATTR; | 
| 33 | 33 | void invalidate_dcache() __attribute__((naked, noinline)) ICODE_ATTR; | 
|  | 34 | +void invalidate_icache() __attribute__((naked, noinline)) ICODE_ATTR; | 
| 34 | 35 |  | 
| 35 | 36 |  | 
| 36 | 37 | #endif | 
| Index: embios/trunk/usb/usb.c | 
| — | — | @@ -33,6 +33,7 @@ | 
| 34 | 34 | #include "strlen.h" | 
| 35 | 35 | #include "contextswitch.h" | 
| 36 | 36 | #include "pmu.h" | 
|  | 37 | +#include "mmu.h" | 
| 37 | 38 | #include "shutdown.h" | 
| 38 | 39 |  | 
| 39 | 40 |  | 
| — | — | @@ -76,7 +77,10 @@ | 
| 77 | 78 |  | 
| 78 | 79 | static const char dbgconoverflowstr[] = "\n\n[overflowed]\n\n"; | 
| 79 | 80 |  | 
|  | 81 | +extern int _initstart;   // These aren't ints at all, but gcc complains about void types being | 
|  | 82 | +extern int _sdramstart;  // used here, and we only need the address, so forget about it... | 
| 80 | 83 |  | 
|  | 84 | + | 
| 81 | 85 | static struct usb_device_descriptor CACHEALIGN_ATTR device_descriptor = | 
| 82 | 86 | { | 
| 83 | 87 | .bLength            = sizeof(struct usb_device_descriptor), | 
| — | — | @@ -328,6 +332,10 @@ | 
| 329 | 333 | dbgsendbuf[2] = usb_drv_get_max_out_size(); | 
| 330 | 334 | dbgsendbuf[3] = usb_drv_get_max_in_size(); | 
| 331 | 335 | break; | 
|  | 336 | +            case 2:  // GET USER MEMORY INFO | 
|  | 337 | +                dbgsendbuf[1] = (uint32_t)&_initstart; | 
|  | 338 | +                dbgsendbuf[2] = (uint32_t)&_sdramstart; | 
|  | 339 | +                break; | 
| 332 | 340 | default: | 
| 333 | 341 | dbgsendbuf[0] = 2; | 
| 334 | 342 | } | 
| — | — | @@ -463,6 +471,30 @@ | 
| 464 | 472 | dbgsendbuf[0] = 1; | 
| 465 | 473 | size = 16; | 
| 466 | 474 | break; | 
|  | 475 | +        case 17:  // SUSPEND THREAD | 
|  | 476 | +            if (dbgrecvbuf[1]) thread_suspend(dbgrecvbuf[2]); | 
|  | 477 | +            else thread_resume(dbgrecvbuf[2]); | 
|  | 478 | +            dbgsendbuf[0] = 1; | 
|  | 479 | +            size = 16; | 
|  | 480 | +            break; | 
|  | 481 | +        case 18:  // KILL THREAD | 
|  | 482 | +            thread_terminate(dbgrecvbuf[1]); | 
|  | 483 | +            dbgsendbuf[0] = 1; | 
|  | 484 | +            size = 16; | 
|  | 485 | +            break; | 
|  | 486 | +        case 19:  // KILL THREAD | 
|  | 487 | +            dbgsendbuf[0] = 1; | 
|  | 488 | +            dbgsendbuf[1] = thread_create((const char*)dbgsendbuf[1], (const void*)dbgsendbuf[2], | 
|  | 489 | +                                          (char*)dbgsendbuf[3], dbgsendbuf[4], dbgsendbuf[5], | 
|  | 490 | +                                          dbgsendbuf[6], dbgsendbuf[7]); | 
|  | 491 | +            size = 16; | 
|  | 492 | +            break; | 
|  | 493 | +        case 20:  // FLUSH CACHE | 
|  | 494 | +            clean_dcache(); | 
|  | 495 | +            invalidate_icache(); | 
|  | 496 | +            dbgsendbuf[0] = 1; | 
|  | 497 | +            size = 16; | 
|  | 498 | +            break; | 
| 467 | 499 | default: | 
| 468 | 500 | dbgsendbuf[0] = 2; | 
| 469 | 501 | size = 16; | 
| — | — | @@ -496,8 +528,12 @@ | 
| 497 | 529 | if (scheduler_threads[i].state == THREAD_DEFUNCT) | 
| 498 | 530 | { | 
| 499 | 531 | if (scheduler_threads[i].block_type == THREAD_DEFUNCT_STKOV) | 
| 500 |  | -                    cprintf(1, "\n*PANIC*\nStack overflow! (%s)\n",
 | 
| 501 |  | -                            scheduler_threads[i].name);
 | 
|  | 532 | +                { | 
|  | 533 | +                    if (scheduler_threads[i].name) | 
|  | 534 | +                        cprintf(1, "\n*PANIC*\nStack overflow! (%s)\n", | 
|  | 535 | +                                scheduler_threads[i].name); | 
|  | 536 | +                    else cprintf(1, "\n*PANIC*\nStack overflow! (ID %d)\n", i); | 
|  | 537 | +                } | 
| 502 | 538 | scheduler_threads[i].state = THREAD_DEFUNCT_ACK; | 
| 503 | 539 | } | 
| 504 | 540 | if (dbgaction != DBGACTION_IDLE) |