summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Ankers <dan@weirdo.org.uk>2007-02-27 22:55:12 +0000
committerDaniel Ankers <dan@weirdo.org.uk>2007-02-27 22:55:12 +0000
commitb856636f85c37b4a07cd00c7ef4395ba0b81e2ab (patch)
treee9d6656b7f743a3038de35af8d13bf473fd6346c
parente7469e2f43e43521d43b4955597ca48d9b39abd3 (diff)
downloadrockbox-b856636f85c37b4a07cd00c7ef4395ba0b81e2ab.zip
rockbox-b856636f85c37b4a07cd00c7ef4395ba0b81e2ab.tar.gz
rockbox-b856636f85c37b4a07cd00c7ef4395ba0b81e2ab.tar.bz2
rockbox-b856636f85c37b4a07cd00c7ef4395ba0b81e2ab.tar.xz
Improved RoLo support for PortalPlayer - handles the COP correctly
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12511 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/main.c9
-rw-r--r--firmware/export/config.h2
-rw-r--r--firmware/export/rolo.h4
-rw-r--r--firmware/rolo.c41
4 files changed, 54 insertions, 2 deletions
diff --git a/apps/main.c b/apps/main.c
index a912e07..0dec816 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -549,10 +549,15 @@ void cop_main(void)
so it should not be assumed that the coprocessor be usable even on
platforms which support it.
- At present all we do is send the COP to sleep if anything wakes it. */
- while(1) {
+ At present the COP sleeps unless it receives a message from the CPU telling
+ it that we are loading a new kernel, so must reboot */
+
+ extern volatile unsigned char cpu_message;
+
+ while(cpu_message != COP_REBOOT) {
COP_CTL = PROC_SLEEP;
}
+ rolo_restart_cop();
}
#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/rolo.h b/firmware/export/rolo.h
index e2dd814..b95a27e 100644
--- a/firmware/export/rolo.h
+++ b/firmware/export/rolo.h
@@ -21,4 +21,8 @@
void rolo_load(char* file);
+#ifdef CPU_PP
+void rolo_restart_cop(void);
+#endif
+
#endif
diff --git a/firmware/rolo.c b/firmware/rolo.c
index 84b3280..1489a8e 100644
--- a/firmware/rolo.c
+++ b/firmware/rolo.c
@@ -36,6 +36,38 @@
#define IRQ0_EDGE_TRIGGER 0x80
+#ifdef CPU_PP
+/* Handle the COP properly - it needs to jump to a function outside SDRAM while
+ * the new firmware is being loaded, and then jump to the start of SDRAM
+ * TODO: Use the mailboxes built into the PP processor for this
+ */
+
+volatile unsigned char IDATA_ATTR cpu_message = 0;
+volatile unsigned char IDATA_ATTR cpu_reply = 0;
+
+void rolo_restart_cop(void) ICODE_ATTR;
+void rolo_restart_cop(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"
+ );
+}
+#endif
+
static void rolo_error(const char *text)
{
lcd_clear_display();
@@ -78,6 +110,9 @@ void rolo_restart(const unsigned char* source, unsigned char* dest,
: : "a"(dest)
);
#elif (CONFIG_CPU==PP5020) || (CONFIG_CPU==PP5024)
+
+ cpu_message = 0;
+
/* Flush cache */
outl(inl(0xf000f044) | 0x2, 0xf000f044);
while ((inl(0x6000c000) & 0x8000) != 0) {}
@@ -89,6 +124,8 @@ void rolo_restart(const unsigned char* source, unsigned char* dest,
for (i=0;i<8;i++)
memmapregs[i]=0;
+ while(cpu_reply != 1) {}
+
asm volatile(
"mov r0, #0x10000000 \n"
"mov pc, r0 \n"
@@ -150,6 +187,10 @@ int rolo_load(const char* filename)
/* Rockbox checksums are big-endian */
file_checksum = betoh32(file_checksum);
+#ifdef CPU_PP
+ cpu_message = COP_REBOOT;
+ COP_CTL = PROC_WAKE;
+#endif
lseek(fd, FIRMWARE_OFFSET_FILE_DATA, SEEK_SET);