From b856636f85c37b4a07cd00c7ef4395ba0b81e2ab Mon Sep 17 00:00:00 2001 From: Daniel Ankers Date: Tue, 27 Feb 2007 22:55:12 +0000 Subject: Improved RoLo support for PortalPlayer - handles the COP correctly git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12511 a1c6a512-1295-4272-9138-f99709370657 --- apps/main.c | 9 +++++++-- firmware/export/config.h | 2 ++ firmware/export/rolo.h | 4 ++++ 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) 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 1a3e0be325..ac2ee688e4 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 e2dd814c1a..b95a27e879 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 84b3280da5..1489a8e695 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); -- cgit v1.2.3