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)
|