| 1 | /* |
|---|
| 2 | * Operating system has died. Known functions will be killed |
|---|
| 3 | * after memmove. |
|---|
| 4 | * |
|---|
| 5 | * Make sure stack is not used. |
|---|
| 6 | */ |
|---|
| 7 | |
|---|
| 8 | #define DP (void*)0xC02200d4 // direct-print (blue) |
|---|
| 9 | #define GREEN (void*)0xC0220134 |
|---|
| 10 | #define DELAY 5000000 |
|---|
| 11 | |
|---|
| 12 | void __attribute__((noreturn)) copy_and_restart(void *dst_void, const void *src_void, long length) { |
|---|
| 13 | |
|---|
| 14 | volatile long *p = (void*)GREEN; // turned off later, so assumed to be power |
|---|
| 15 | |
|---|
| 16 | int counter; |
|---|
| 17 | |
|---|
| 18 | // DEBUG: blink led |
|---|
| 19 | //counter = DELAY; *p = 0x46; while (counter--) { asm("nop\n nop\n"); }; |
|---|
| 20 | //counter = DELAY; *p = 0x44; while (counter--) { asm("nop\n nop\n"); }; |
|---|
| 21 | |
|---|
| 22 | { |
|---|
| 23 | char *dst = dst_void; |
|---|
| 24 | const char *src = src_void; |
|---|
| 25 | |
|---|
| 26 | if (src < dst && dst < src + length) |
|---|
| 27 | { |
|---|
| 28 | /* Have to copy backwards */ |
|---|
| 29 | src += length; |
|---|
| 30 | dst += length; |
|---|
| 31 | while (length--) |
|---|
| 32 | { |
|---|
| 33 | *--dst = *--src; |
|---|
| 34 | } |
|---|
| 35 | } |
|---|
| 36 | else |
|---|
| 37 | { |
|---|
| 38 | while (length--) |
|---|
| 39 | { |
|---|
| 40 | *dst++ = *src++; |
|---|
| 41 | } |
|---|
| 42 | } |
|---|
| 43 | } |
|---|
| 44 | |
|---|
| 45 | //DEBUG: blink again |
|---|
| 46 | //counter = DELAY; *p = 0x46; while (counter--) { asm("nop\n nop\n"); }; |
|---|
| 47 | //counter = DELAY; *p = 0x44; while (counter--) { asm("nop\n nop\n"); }; |
|---|
| 48 | |
|---|
| 49 | // DEBUG: jump to regular firmware-boot (causing a boot loop) |
|---|
| 50 | //dst_void = (void*) 0xFF810000; |
|---|
| 51 | |
|---|
| 52 | // resetcode here: |
|---|
| 53 | asm volatile ( |
|---|
| 54 | "MRS R0, CPSR\n" |
|---|
| 55 | "BIC R0, R0, #0x3F\n" |
|---|
| 56 | "ORR R0, R0, #0xD3\n" |
|---|
| 57 | "MSR CPSR, R0\n" |
|---|
| 58 | "LDR R1, =0xC0200000\n" |
|---|
| 59 | "MOV R0, #0xFFFFFFFF\n" |
|---|
| 60 | "STR R0, [R1,#0x10C]\n" |
|---|
| 61 | "STR R0, [R1,#0xC]\n" |
|---|
| 62 | "STR R0, [R1,#0x1C]\n" |
|---|
| 63 | "STR R0, [R1,#0x2C]\n" |
|---|
| 64 | "STR R0, [R1,#0x3C]\n" |
|---|
| 65 | "STR R0, [R1,#0x4C]\n" |
|---|
| 66 | "STR R0, [R1,#0x5C]\n" |
|---|
| 67 | "STR R0, [R1,#0x6C]\n" |
|---|
| 68 | "STR R0, [R1,#0x7C]\n" |
|---|
| 69 | "STR R0, [R1,#0x8C]\n" |
|---|
| 70 | "STR R0, [R1,#0x9C]\n" |
|---|
| 71 | "STR R0, [R1,#0xAC]\n" |
|---|
| 72 | "STR R0, [R1,#0xBC]\n" |
|---|
| 73 | "STR R0, [R1,#0xCC]\n" |
|---|
| 74 | "STR R0, [R1,#0xDC]\n" |
|---|
| 75 | "STR R0, [R1,#0xEC]\n" |
|---|
| 76 | "CMP R4, #7\n" |
|---|
| 77 | "STR R0, [R1,#0xFC]\n" |
|---|
| 78 | "LDMEQFD SP!, {R4,PC}\n" |
|---|
| 79 | "MOV R0, #0x78\n" |
|---|
| 80 | "MCR p15, 0, R0,c1,c0\n" |
|---|
| 81 | "MOV R0, #0\n" |
|---|
| 82 | "MCR p15, 0, R0,c7,c10, 4\n" |
|---|
| 83 | "MCR p15, 0, R0,c7,c5\n" |
|---|
| 84 | "MCR p15, 0, R0,c7,c6\n" |
|---|
| 85 | "MOV R0, #0x40000006\n" |
|---|
| 86 | "MCR p15, 0, R0,c9,c1\n" |
|---|
| 87 | "MCR p15, 0, R0,c9,c1, 1\n" |
|---|
| 88 | "MRC p15, 0, R0,c1,c0\n" |
|---|
| 89 | "ORR R0, R0, #0x50000\n" |
|---|
| 90 | "MCR p15, 0, R0,c1,c0\n" |
|---|
| 91 | "LDR R0, =0x12345678\n" |
|---|
| 92 | "MOV R1, #0x40000000\n" |
|---|
| 93 | "STR R0, [R1,#0xFFC]\n" |
|---|
| 94 | //"LDR R0, =0xFF810000\n" // original jump-vector |
|---|
| 95 | "MOV R0, %0\n" // new jump-vector |
|---|
| 96 | "LDMFD SP!, {R4,LR}\n" |
|---|
| 97 | "BX R0\n" |
|---|
| 98 | : : "r"(dst_void) : "memory","r0","r1","r2","r3","r4"); |
|---|
| 99 | |
|---|
| 100 | while(1); |
|---|
| 101 | } |
|---|