summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Ankers <dan@weirdo.org.uk>2006-08-03 16:29:42 +0000
committerDaniel Ankers <dan@weirdo.org.uk>2006-08-03 16:29:42 +0000
commitcec7cdc3bbf46379131e6951585951cf97444326 (patch)
tree0ea6c203ed51fad4d51a7dc0fb2090f3f1a55dbb
parent2fa5d81fcd66abd52cee622ba87787159d3cd2e7 (diff)
downloadrockbox-cec7cdc3bbf46379131e6951585951cf97444326.zip
rockbox-cec7cdc3bbf46379131e6951585951cf97444326.tar.gz
rockbox-cec7cdc3bbf46379131e6951585951cf97444326.tar.bz2
rockbox-cec7cdc3bbf46379131e6951585951cf97444326.tar.xz
Initial work for coprocessor support on iPods. FS#5755
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10437 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/main.c13
-rw-r--r--bootloader/ipod.c11
-rw-r--r--firmware/app.lds9
-rw-r--r--firmware/crt0.S67
-rw-r--r--firmware/export/pp5002.h5
-rw-r--r--firmware/export/pp5020.h3
6 files changed, 93 insertions, 15 deletions
diff --git a/apps/main.c b/apps/main.c
index 8ee6adf..f8c3604 100644
--- a/apps/main.c
+++ b/apps/main.c
@@ -451,6 +451,19 @@ void init(void)
#endif
}
+void cop_main(void)
+{
+/* This is the entry point for the coprocessor
+ Anyone not running an upgraded bootloader will never reach this point,
+ 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) {
+ COP_CTL = PROC_SLEEP;
+ }
+}
+
int main(void)
{
app_main();
diff --git a/bootloader/ipod.c b/bootloader/ipod.c
index 98ff484..26e5ae2 100644
--- a/bootloader/ipod.c
+++ b/bootloader/ipod.c
@@ -425,16 +425,7 @@ void* main(void)
lcd_puts(0, line++, "Rockbox loaded.");
lcd_update();
memcpy((void*)DRAM_START,loadbuffer,rc);
-
- /* Transfer execution directly to Rockbox - we don't want
- to run the rest of the bootloader startup code. */
- asm volatile(
- "mov r0, #" SC(DRAM_START) "\n"
- "mov pc, r0 \n"
- );
-
- /* We don't get here, but keep the compiler happy. */
- return (void*)0;
+ return (void*)DRAM_START;
}
}
diff --git a/firmware/app.lds b/firmware/app.lds
index 3416f5c..3d9be9b 100644
--- a/firmware/app.lds
+++ b/firmware/app.lds
@@ -257,6 +257,15 @@ SECTIONS
. += 0x2000;
stackend = .;
} > IRAM
+
+ .cop_stack :
+ {
+ *(.cop_stack)
+ cop_stackbegin = .;
+ . += 0x0500;
+ cop_stackend = .;
+ } > IRAM
+
#else
/* TRICK ALERT! We want 0x2000 bytes of stack, but we set the section
size smaller, and allow the stack to grow into the .iram copy */
diff --git a/firmware/crt0.S b/firmware/crt0.S
index 6477011..9831d74 100644
--- a/firmware/crt0.S
+++ b/firmware/crt0.S
@@ -36,11 +36,15 @@ start:
* Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
*
*/
+ .equ PP5002_PROC_ID, 0xc4000000
+ .equ PP5002_COP_CTRL, 0xcf004058
+ .equ PP5020_PROC_ID, 0x60000000
+ .equ PP5020_COP_CTRL, 0x60007004
msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ */
#ifndef BOOTLOADER
-#if CONFIG_CPU == PP5002 || CONFIG_CPU == PP5020
+#ifdef CPU_PP
b pad_skip
.space 50*4 /* (more than enough) space for exception vectors */
pad_skip:
@@ -81,6 +85,34 @@ remap_start:
L_post_remap: .word remap_end
remap_end:
+#ifdef CPU_PP
+ /* After doing the remapping, send the COP to sleep.
+ On wakeup it will go to cop_init */
+#if CONFIG_CPU == PP5002
+ ldr r0, =PP5002_PROC_ID
+#else
+ ldr r0, =PP5020_PROC_ID
+#endif
+ ldr r0, [r0]
+ and r0, r0, #0xff
+ cmp r0, #0x55
+ beq 1f
+
+ /* put us (co-processor) to sleep */
+#if CONFIG_CPU == PP5002
+ ldr r4, =PP5002_COP_CTRL
+ mov r3, #0xca
+#else
+ ldr r4, =PP5020_COP_CTRL
+ mov r3, #0x80000000
+#endif
+ str r3, [r4]
+
+ ldr pc, =cop_init
+
+1:
+#endif
+
#elif CONFIG_CPU == PNX0101
#ifndef DEBUG
@@ -167,10 +199,6 @@ remap_end:
#ifdef BOOTLOADER
#ifdef CPU_PP
- .equ PP5002_PROC_ID, 0xc4000000
- .equ PP5002_COP_CTRL, 0xcf004058
- .equ PP5020_PROC_ID, 0x60000000
- .equ PP5020_COP_CTRL, 0x60007004
/* TODO: the high part of the address is probably dependent on CONFIG_CPU.
Since we tend to use ifdefs for each chipset target
anyway, we might as well just hardcode it here.
@@ -306,6 +334,35 @@ boot_table:
bl main
/* main() should never return */
+#ifdef CPU_PP
+cop_init:
+ ldr sp, =cop_stackend
+ mov r3, sp
+ ldr r2, =cop_stackbegin
+ ldr r4, =0xdeadbeef
+2:
+ cmp r3, r2
+ strhi r4, [r2], #4
+ bhi 2b
+
+ ldr sp, =cop_stackend
+ bl cop_main
+#else
+ /* If we don't plan to use the COP, we have some code to catch it and send
+ it back to sleep if somebody wakes it. This means that the firmware
+ size doesn't grow too much while the COP is still unused, but it is
+ still handled cleanly. */
+#if CONFIG_CPU==PP5002
+ ldr r4, =PP5002_COP_CTRL
+ mov r3, #0xca
+#else
+ ldr r4, =PP5020_COP_CTRL
+ mov r3, #0x80000000
+#endif
+ str r3, [r4]
+ ldr pc, =cop_init
+#endif /* PP specific */
+
/* Exception handlers. Will be copied to address 0 after memory remapping */
.section .vectors,"aw"
ldr pc, [pc, #24]
diff --git a/firmware/export/pp5002.h b/firmware/export/pp5002.h
index b8f2d51..da35fd9 100644
--- a/firmware/export/pp5002.h
+++ b/firmware/export/pp5002.h
@@ -20,6 +20,8 @@
#define __PP5002_H__
/* All info gleaned and/or copied from the iPodLinux project. */
+#define CPU_CTL (*(volatile unsigned char *)(0xcf004054))
+#define COP_CTL (*(volatile unsigned char *)(0xcf004058))
#define GPIOA_ENABLE (*(volatile unsigned char *)(0xcf000000))
#define GPIOB_ENABLE (*(volatile unsigned char *)(0xcf000004))
@@ -98,4 +100,7 @@
#define SER1_MASK (1 << SER1_IRQ)
#define DMA_OUT_MASK (1 << DMA_OUT_IRQ)
+#define PROC_SLEEP 0xca
+#define PROC_WAKE 0xce
+
#endif
diff --git a/firmware/export/pp5020.h b/firmware/export/pp5020.h
index cfeb864..ccb49a0 100644
--- a/firmware/export/pp5020.h
+++ b/firmware/export/pp5020.h
@@ -165,4 +165,7 @@
#define IISFIFO_WR (*(volatile unsigned long*)(0x70002840))
#define IISFIFO_RD (*(volatile unsigned long*)(0x70002880))
+#define PROC_SLEEP 0x80000000
+#define PROC_WAKE 0x0
+
#endif