diff options
-rw-r--r-- | apps/main.c | 9 | ||||
-rw-r--r-- | firmware/export/config.h | 2 | ||||
-rw-r--r-- | firmware/export/rolo.h | 4 | ||||
-rw-r--r-- | firmware/rolo.c | 41 |
4 files changed, 54 insertions, 2 deletions
diff --git a/apps/main.c b/apps/main.c index a912e07566..0dec816d77 100644 --- a/apps/main.c +++ b/apps/main.c | |||
@@ -549,10 +549,15 @@ void cop_main(void) | |||
549 | so it should not be assumed that the coprocessor be usable even on | 549 | so it should not be assumed that the coprocessor be usable even on |
550 | platforms which support it. | 550 | platforms which support it. |
551 | 551 | ||
552 | At present all we do is send the COP to sleep if anything wakes it. */ | 552 | At present the COP sleeps unless it receives a message from the CPU telling |
553 | while(1) { | 553 | it that we are loading a new kernel, so must reboot */ |
554 | |||
555 | extern volatile unsigned char cpu_message; | ||
556 | |||
557 | while(cpu_message != COP_REBOOT) { | ||
554 | COP_CTL = PROC_SLEEP; | 558 | COP_CTL = PROC_SLEEP; |
555 | } | 559 | } |
560 | rolo_restart_cop(); | ||
556 | } | 561 | } |
557 | #endif | 562 | #endif |
558 | 563 | ||
diff --git a/firmware/export/config.h b/firmware/export/config.h index 1a3e0be325..ac2ee688e4 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h | |||
@@ -280,6 +280,8 @@ | |||
280 | 280 | ||
281 | #define NUM_CORES 1 | 281 | #define NUM_CORES 1 |
282 | #define CURRENT_CORE 0 | 282 | #define CURRENT_CORE 0 |
283 | |||
284 | #define COP_REBOOT 0x00000001 | ||
283 | #else | 285 | #else |
284 | #define NUM_CORES 1 | 286 | #define NUM_CORES 1 |
285 | #define CURRENT_CORE 0 | 287 | #define CURRENT_CORE 0 |
diff --git a/firmware/export/rolo.h b/firmware/export/rolo.h index e2dd814c1a..b95a27e879 100644 --- a/firmware/export/rolo.h +++ b/firmware/export/rolo.h | |||
@@ -21,4 +21,8 @@ | |||
21 | 21 | ||
22 | void rolo_load(char* file); | 22 | void rolo_load(char* file); |
23 | 23 | ||
24 | #ifdef CPU_PP | ||
25 | void rolo_restart_cop(void); | ||
26 | #endif | ||
27 | |||
24 | #endif | 28 | #endif |
diff --git a/firmware/rolo.c b/firmware/rolo.c index 84b3280da5..1489a8e695 100644 --- a/firmware/rolo.c +++ b/firmware/rolo.c | |||
@@ -36,6 +36,38 @@ | |||
36 | 36 | ||
37 | #define IRQ0_EDGE_TRIGGER 0x80 | 37 | #define IRQ0_EDGE_TRIGGER 0x80 |
38 | 38 | ||
39 | #ifdef CPU_PP | ||
40 | /* Handle the COP properly - it needs to jump to a function outside SDRAM while | ||
41 | * the new firmware is being loaded, and then jump to the start of SDRAM | ||
42 | * TODO: Use the mailboxes built into the PP processor for this | ||
43 | */ | ||
44 | |||
45 | volatile unsigned char IDATA_ATTR cpu_message = 0; | ||
46 | volatile unsigned char IDATA_ATTR cpu_reply = 0; | ||
47 | |||
48 | void rolo_restart_cop(void) ICODE_ATTR; | ||
49 | void rolo_restart_cop(void) | ||
50 | { | ||
51 | /* Invalidate cache */ | ||
52 | outl(inl(0xf000f044) | 0x6, 0xf000f044); | ||
53 | while ((inl(0x6000c000) & 0x8000) != 0) {} | ||
54 | |||
55 | /* Disable cache */ | ||
56 | outl(0x0, 0x6000C000); | ||
57 | |||
58 | /* Wait while RoLo loads the image into SDRAM */ | ||
59 | /* TODO: Accept checksum failure gracefully */ | ||
60 | while(cpu_message == 1) {} | ||
61 | |||
62 | cpu_reply = 1; | ||
63 | |||
64 | asm volatile( | ||
65 | "mov r0, #0x10000000 \n" | ||
66 | "mov pc, r0 \n" | ||
67 | ); | ||
68 | } | ||
69 | #endif | ||
70 | |||
39 | static void rolo_error(const char *text) | 71 | static void rolo_error(const char *text) |
40 | { | 72 | { |
41 | lcd_clear_display(); | 73 | lcd_clear_display(); |
@@ -78,6 +110,9 @@ void rolo_restart(const unsigned char* source, unsigned char* dest, | |||
78 | : : "a"(dest) | 110 | : : "a"(dest) |
79 | ); | 111 | ); |
80 | #elif (CONFIG_CPU==PP5020) || (CONFIG_CPU==PP5024) | 112 | #elif (CONFIG_CPU==PP5020) || (CONFIG_CPU==PP5024) |
113 | |||
114 | cpu_message = 0; | ||
115 | |||
81 | /* Flush cache */ | 116 | /* Flush cache */ |
82 | outl(inl(0xf000f044) | 0x2, 0xf000f044); | 117 | outl(inl(0xf000f044) | 0x2, 0xf000f044); |
83 | while ((inl(0x6000c000) & 0x8000) != 0) {} | 118 | while ((inl(0x6000c000) & 0x8000) != 0) {} |
@@ -89,6 +124,8 @@ void rolo_restart(const unsigned char* source, unsigned char* dest, | |||
89 | for (i=0;i<8;i++) | 124 | for (i=0;i<8;i++) |
90 | memmapregs[i]=0; | 125 | memmapregs[i]=0; |
91 | 126 | ||
127 | while(cpu_reply != 1) {} | ||
128 | |||
92 | asm volatile( | 129 | asm volatile( |
93 | "mov r0, #0x10000000 \n" | 130 | "mov r0, #0x10000000 \n" |
94 | "mov pc, r0 \n" | 131 | "mov pc, r0 \n" |
@@ -150,6 +187,10 @@ int rolo_load(const char* filename) | |||
150 | 187 | ||
151 | /* Rockbox checksums are big-endian */ | 188 | /* Rockbox checksums are big-endian */ |
152 | file_checksum = betoh32(file_checksum); | 189 | file_checksum = betoh32(file_checksum); |
190 | #ifdef CPU_PP | ||
191 | cpu_message = COP_REBOOT; | ||
192 | COP_CTL = PROC_WAKE; | ||
193 | #endif | ||
153 | 194 | ||
154 | lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET); | 195 | lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET); |
155 | 196 | ||