diff --git a/apps/main.c b/apps/main.c index 8ee6adfe4f..f8c3604f6b 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 98ff4848bb..26e5ae2937 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 3416f5c6b6..3d9be9b32e 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 6477011064..9831d749eb 100644 --- a/firmware/crt0.S +++ b/firmware/crt0.S @@ -36,11 +36,15 @@ start: * Copyright (c) 2005, Bernard Leach * */ + .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 b8f2d519dd..da35fd9200 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 cfeb8642b8..ccb49a0d90 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