rendered paste bodydiff --git a/apps/main.c b/apps/main.c
index a912e07..6edae5f 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -106,6 +106,8 @@
#include "cuesheet.h"
/*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */
+volatile unsigned char IDATA_ATTR CPU_MESSAGE=0;
+volatile unsigned char IDATA_ATTR CPU_REPLY=0;
const char appsversion[]=APPSVERSION;
@@ -542,6 +544,28 @@ static void init(void)
}
#ifdef CPU_PP
+void cop_rolo(void) ICODE_ATTR;
+void cop_rolo(void)
+{
+ /* Invalidate cache */
+ outl(inl(0xf000f044) | 0x6, 0xf000f044);
+ while ((inl(0x6000c000) & 0x8000) != 0) {}
+
+ /* Disable cache */
+ outl(0x0, 0x6000C000);
+
+ /* Wait while RoLo loads the image into SDRAM */
+ /* TODO: Accept checksum failure gracefully */
+ while(CPU_MESSAGE == 1) {}
+
+ CPU_REPLY = 1;
+
+ asm volatile(
+ "mov r0, #0x10000000 \n"
+ "mov pc, r0 \n"
+ );
+}
+
void cop_main(void)
{
/* This is the entry point for the coprocessor
@@ -550,9 +574,15 @@ void cop_main(void)
platforms which support it.
At present all we do is send the COP to sleep if anything wakes it. */
- while(1) {
+ long i;
+ unsigned long* memmapregs = (unsigned long*)0xf000f000;
+
+ (*(volatile unsigned long*)(0x60004134)) |= 0x10; /* Set mailbox interrupt */
+
+ while(CPU_MESSAGE != COP_REBOOT) {
COP_CTL = PROC_SLEEP;
}
+ cop_rolo();
}
#endif
diff --git a/firmware/export/config.h b/firmware/export/config.h
index 1a3e0be..ac2ee68 100644
--- a/firmware/export/config.h
+++ b/firmware/export/config.h
@@ -280,6 +280,8 @@
#define NUM_CORES 1
#define CURRENT_CORE 0
+
+#define COP_REBOOT 0x00000001
#else
#define NUM_CORES 1
#define CURRENT_CORE 0
diff --git a/firmware/export/pp5020.h b/firmware/export/pp5020.h
index d304895..1cc23e9 100644
--- a/firmware/export/pp5020.h
+++ b/firmware/export/pp5020.h
@@ -25,6 +25,17 @@
#define CPU_CTL (*(volatile unsigned long *)(0x60007000))
#define COP_CTL (*(volatile unsigned long *)(0x60007004))
+/* Mailboxes */
+/* Each processor has two mailboxes it can write to and two which
+ it can read from. We define the first to be for sending messages
+ and the second for replying to messages */
+#if 0
+#define CPU_MESSAGE (*(volatile unsigned long *)(0x60001000))
+#define COP_MESSAGE (*(volatile unsigned long *)(0x60001004))
+#define CPU_REPLY (*(volatile unsigned long *)(0x60001008))
+#define COP_REPLY (*(volatile unsigned long *)(0x6000100c))
+#endif
+
#define GPIOA_ENABLE (*(volatile unsigned long *)(0x6000d000))
#define GPIOB_ENABLE (*(volatile unsigned long *)(0x6000d004))
#define GPIOC_ENABLE (*(volatile unsigned long *)(0x6000d008))
diff --git a/firmware/rolo.c b/firmware/rolo.c
index 84b3280..4ce708b 100644
--- a/firmware/rolo.c
+++ b/firmware/rolo.c
@@ -63,6 +63,8 @@ void rolo_restart(const unsigned char* source, unsigned char* dest,
long i;
unsigned char* localdest = dest;
#if (CONFIG_CPU==PP5020) || (CONFIG_CPU==PP5024)
+ extern volatile unsigned char CPU_MESSAGE;
+ extern volatile unsigned char CPU_REPLY;
unsigned long* memmapregs = (unsigned long*)0xf000f000;
#endif
@@ -78,6 +80,10 @@ void rolo_restart(const unsigned char* source, unsigned char* dest,
: : "a"(dest)
);
#elif (CONFIG_CPU==PP5020) || (CONFIG_CPU==PP5024)
+
+ CPU_MESSAGE = 0;
+ COP_CTL = PROC_WAKE;
+
/* Flush cache */
outl(inl(0xf000f044) | 0x2, 0xf000f044);
while ((inl(0x6000c000) & 0x8000) != 0) {}
@@ -85,10 +91,13 @@ void rolo_restart(const unsigned char* source, unsigned char* dest,
/* Disable cache */
outl(0x0, 0x6000C000);
+
/* Reset the memory mapping registers to zero */
for (i=0;i<8;i++)
memmapregs[i]=0;
+ while(CPU_REPLY != 1) {}
+
asm volatile(
"mov r0, #0x10000000 \n"
"mov pc, r0 \n"
@@ -117,6 +126,9 @@ int rolo_load(const char* filename)
long file_length;
unsigned short checksum,file_checksum;
#endif
+#ifdef CPU_PP
+ extern volatile unsigned char CPU_MESSAGE;
+#endif
unsigned char* ramstart = (void*)&loadaddress;
lcd_clear_display();
@@ -150,6 +162,9 @@ int rolo_load(const char* filename)
/* Rockbox checksums are big-endian */
file_checksum = betoh32(file_checksum);
+#ifdef CPU_PP
+ CPU_MESSAGE = COP_REBOOT;
+#endif
lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET);