From da55251a35d8ad6c0b8b9e62904798212caba46f Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Sat, 29 Sep 2007 06:17:33 +0000 Subject: Compile Portal Player bootloaders as single core. Cleanup the startup code for bootloaders. Remove cop stack entirely and keep IRAM use down on all relevant targets - just use the 128-byte idle stack. Use the inline asm version of current_core for pp5002 as well. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14898 a1c6a512-1295-4272-9138-f99709370657 --- firmware/SOURCES | 2 + firmware/app.lds | 16 ++--- firmware/export/config.h | 2 +- firmware/export/pp5002.h | 2 + firmware/target/arm/crt0-pp-bl.S | 113 +++++++++++++++++++----------------- firmware/target/arm/crt0-pp.S | 8 +-- firmware/target/arm/system-pp5002.c | 10 ---- firmware/target/arm/system-target.h | 13 ++--- firmware/thread.c | 22 +------ 9 files changed, 78 insertions(+), 110 deletions(-) diff --git a/firmware/SOURCES b/firmware/SOURCES index 45bedd9dbe..58595a493a 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -13,7 +13,9 @@ logf.c profile.c #endif /* RB_PROFILE */ kernel.c +#ifndef BOOTLOADER rolo.c +#endif /* BOOTLOADER */ thread.c timer.c #endif /* SIMULATOR */ diff --git a/firmware/app.lds b/firmware/app.lds index 8df9aaf8e3..87b9613502 100644 --- a/firmware/app.lds +++ b/firmware/app.lds @@ -197,26 +197,18 @@ SECTIONS } > IRAM #ifdef CPU_PP -#if NUM_CORES > 1 .idle_stacks : { +#if NUM_CORES > 1 *(.idle_stacks) cpu_idlestackbegin = .; - . += 0x0080; + . += IDLE_STACK_SIZE; cpu_idlestackend = .; +#endif cop_idlestackbegin = .; - . += 0x0080; + . += IDLE_STACK_SIZE; cop_idlestackend = .; } > IRAM -#else - .cop_stack : - { - *(.cop_stack) - cop_stackbegin = .; - . += 0x0500; - cop_stackend = .; - } > IRAM -#endif #endif #else diff --git a/firmware/export/config.h b/firmware/export/config.h index 9346abbdc9..784856d2f2 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -364,7 +364,7 @@ #endif /* Dual core support - not yet working on the 1G/2G and 3G iPod */ -#if defined(CPU_PP) && CONFIG_CPU != PP5002 +#if defined(CPU_PP) && CONFIG_CPU != PP5002 && !defined(BOOTLOADER) #define NUM_CORES 2 #define CURRENT_CORE current_core() /* Hopefully at some point we will learn how to mark areas of main memory as diff --git a/firmware/export/pp5002.h b/firmware/export/pp5002.h index 9d757ead7d..f566b5cd04 100644 --- a/firmware/export/pp5002.h +++ b/firmware/export/pp5002.h @@ -22,6 +22,8 @@ /* Much info gleaned and/or copied from the iPodLinux project. */ #define DRAM_START 0x28000000 +#define PROCESSOR_ID (*(volatile unsigned long *)(0xc4000000)) + #define IPOD_LCD_BASE 0xc0001000 #define IISCONFIG (*(volatile unsigned long *)(0xc0002500)) diff --git a/firmware/target/arm/crt0-pp-bl.S b/firmware/target/arm/crt0-pp-bl.S index 7ac6295305..9ab33a78d3 100644 --- a/firmware/target/arm/crt0-pp-bl.S +++ b/firmware/target/arm/crt0-pp-bl.S @@ -48,33 +48,34 @@ start: .equ WAKE, 0x0 .equ SLEEPING, 0x80000000 .equ CACHE_CTRL, 0x6000c000 + .equ CACHE_ENAB, 0x1 #endif msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ */ #ifndef E200R_INSTALLER /* 1 - Copy the bootloader to IRAM */ /* get the high part of our execute address */ - ldr r7, =0xffffff00 - and r4, pc, r7 + bic r0, pc, #0xff /* r4 = pc & 0xffffff00 */ /* Copy bootloader to safe area - 0x40000000 (IRAM) */ - mov r5, #0x40000000 - ldr r6, = _dataend + mov r1, #0x40000000 + ldr r2, =_dataend 1: - cmp r5, r6 - ldrcc r2, [r4], #4 - strcc r2, [r5], #4 - bcc 1b + cmp r2, r1 + ldrhi r3, [r0], #4 + strhi r3, [r1], #4 + bhi 1b #ifndef IPOD_ARCH /* For builds on targets with mi4 firmware, scramble writes data to - 0xe0-0xeb, so jump past that.*/ + 0xe0-0xeb, so jump past that. pad_skip must then exist at an + address >= 0xec */ b pad_skip .space 60*4 pad_skip: -#endif +#endif /* IPOD_ARCH */ /* 2 - Jump both CPU and COP there */ @@ -82,89 +83,92 @@ pad_skip: #endif /* E200R_INSTALLER */ start_loc: - /* Find out which processor we are */ ldr r0, =PROC_ID - ldr r0, [r0] - and r0, r0, #0xff + ldrb r0, [r0] cmp r0, #0x55 beq cpu - + +cop: /* put us (co-processor) to sleep */ - ldr r4, =COP_CTRL - mov r3, #SLEEP - str r3, [r4] - ldr pc, =cop_wake_start - -cop_wake_start: -#if CONFIG_CPU != PP5002 - /* COP: Invalidate cache */ + ldr r0, =COP_CTRL + mov r1, #SLEEP + str r1, [r0] + +#ifdef CPU_PP502x + /* COP: Invalidate cache if enabled */ + ldr r2, =CACHE_CTRL + ldr r1, [r2] + tst r1, #CACHE_ENAB + beq 2f ldr r0, =0xf000f044 ldr r1, [r0] orr r1, r1, #0x6 str r1, [r0] - - ldr r0, =CACHE_CTRL 1: - ldr r1, [r0] + ldr r1, [r2] tst r1, #0x8000 bne 1b -#endif +2: +#endif /* CPU_PP502x */ ldr r0, =startup_loc ldr pc, [r0] cpu: /* Wait for COP to be sleeping */ - ldr r4, =COP_STATUS + ldr r0, =COP_STATUS 1: - ldr r3, [r4] - ands r3, r3, #SLEEPING + ldr r1, [r0] + tst r1, #SLEEPING beq 1b /* Initialise bss section to zero */ - ldr r2, =_edata - ldr r3, =_end - mov r4, #0 + ldr r0, =_edata + ldr r1, =_end + mov r2, #0 1: - cmp r3, r2 - strhi r4, [r2], #4 + cmp r1, r0 + strhi r2, [r0], #4 bhi 1b /* Set up some stack and munge it with 0xdeadbeef */ ldr sp, =stackend - mov r3, sp - ldr r2, =stackbegin - ldr r4, =0xdeadbeef + ldr r0, =stackbegin + ldr r1, =0xdeadbeef 1: - cmp r3, r2 - strhi r4, [r2], #4 + cmp sp, r0 + strhi r1, [r0], #4 bhi 1b /* execute the loader - this will load an image to 0x10000000 */ bl main + /* store actual startup location returned by main() */ ldr r1, =startup_loc str r0, [r1] -#if CONFIG_CPU != PP5002 - /* Flush cache */ - ldr r3, =0xf000f044 - ldr r4, [r3] - orr r4, r4, #0x2 - str r4, [r3] - - ldr r3, =CACHE_CTRL +#ifdef CPU_PP502x + /* Flush cache if enabled */ + ldr r2, =CACHE_CTRL + ldr r1, [r2] + tst r1, #CACHE_ENAB + beq 2f + ldr r0, =0xf000f044 + ldr r1, [r0] + orr r1, r1, #0x2 + str r1, [r0] 1: - ldr r4, [r3] - tst r4, #0x8000 + ldr r1, [r2] + tst r1, #0x8000 bne 1b -#endif +2: +#endif /* CPU_PP502x */ /* Wake up the coprocessor before executing the firmware */ - ldr r4, =COP_CTRL - mov r3, #WAKE - str r3, [r4] + ldr r0, =COP_CTRL + mov r1, #WAKE + str r1, [r0] #ifdef SANSA_C200 /* Magic for loading the c200 OF */ @@ -184,6 +188,7 @@ startup_loc: .align 8 /* starts at 0x100 */ .global boot_table boot_table: - /* here comes the boot table, don't move its offset */ + /* here comes the boot table, don't move its offset - preceding + code+data must stay <= 256 bytes */ .space 400 #endif diff --git a/firmware/target/arm/crt0-pp.S b/firmware/target/arm/crt0-pp.S index 971b9e0ac5..2708ee3ad4 100644 --- a/firmware/target/arm/crt0-pp.S +++ b/firmware/target/arm/crt0-pp.S @@ -266,15 +266,11 @@ cop_init: ldr r3, [r4] tst r3, #SLEEPING beq 1b +#endif /* Set up idle stack for COP and munge it with 0xdeadbeef */ - ldr r2, =cop_idlestackbegin ldr sp, =cop_idlestackend -#else - /* Setup stack for COP and munge it with 0xdeadbeef */ - ldr r2, =cop_stackbegin - ldr sp, =cop_stackend -#endif + ldr r2, =cop_idlestackbegin ldr r4, =0xdeadbeef 2: cmp sp, r2 diff --git a/firmware/target/arm/system-pp5002.c b/firmware/target/arm/system-pp5002.c index 1b5cbdc762..08783280be 100644 --- a/firmware/target/arm/system-pp5002.c +++ b/firmware/target/arm/system-pp5002.c @@ -53,16 +53,6 @@ void irq(void) #endif -unsigned int current_core(void) -{ - if(((*(volatile unsigned long *)(0xc4000000)) & 0xff) == 0x55) - { - return CPU; - } - return COP; -} - - /* TODO: The following two function have been lifted straight from IPL, and hence have a lot of numeric addresses used straight. I'd like to use #defines for these, but don't know what most of them are for or even what diff --git a/firmware/target/arm/system-target.h b/firmware/target/arm/system-target.h index 6dc317e427..ed8d90c627 100644 --- a/firmware/target/arm/system-target.h +++ b/firmware/target/arm/system-target.h @@ -52,7 +52,6 @@ static inline void udelay(unsigned usecs) while (TIME_BEFORE(USEC_TIMER, stop)); } -#ifdef CPU_PP502x static inline unsigned int current_core(void) { /* @@ -63,14 +62,16 @@ static inline unsigned int current_core(void) */ unsigned int core; asm volatile ( - "mov %0, #0x60000000 \r\n" /* PROCESSOR_ID */ - "ldrb %0, [%0] \r\n" /* Just load the LSB */ - "mov %0, %0, lsr #7 \r\n" /* Bit 7 => index */ - : "=&r"(core) /* CPU=0, COP=1 */ + "ldrb %0, [%1] \n" /* Just load the LSB */ + "mov %0, %0, lsr #7 \n" /* Bit 7 => index */ + : "=r"(core) /* CPU=0, COP=1 */ + : "r"(&PROCESSOR_ID) ); return core; } +#ifdef CPU_PP502x + #ifndef BOOTLOADER #define CACHE_FUNCTIONS_AS_CALL @@ -81,8 +82,6 @@ void invalidate_icache(void); void flush_icache(void); #endif -#else -unsigned int current_core(void); #endif /* CPU_PP502x */ diff --git a/firmware/thread.c b/firmware/thread.c index 1875650050..bb3c321ddf 100644 --- a/firmware/thread.c +++ b/firmware/thread.c @@ -81,7 +81,7 @@ static void start_thread(void) "ldr r4, [r0, #40] \n" /* start in r4 since it's non-volatile */ "mov r1, #0 \n" /* Mark thread as running */ "str r1, [r0, #40] \n" -#if NUM_CORES > 1 && !defined (BOOTLOADER) +#if NUM_CORES > 1 "ldr r0, =invalidate_icache \n" /* Invalidate this core's cache. */ "mov lr, pc \n" /* This could be the first entry into */ "bx r0 \n" /* plugin or codec code for this core. */ @@ -132,23 +132,11 @@ extern int cpu_idlestackbegin[]; extern int cpu_idlestackend[]; extern int cop_idlestackbegin[]; extern int cop_idlestackend[]; -#ifndef BOOTLOADER static int * const idle_stacks[NUM_CORES] NOCACHEDATA_ATTR = { [CPU] = cpu_idlestackbegin, [COP] = cop_idlestackbegin }; -#endif /* BOOTLOADER */ -#else /* NUM_CORES == 1 */ -#ifndef BOOTLOADER -extern int cop_stackbegin[]; -extern int cop_stackend[]; -#else -/* The coprocessor stack is not set up in the bootloader code, but the threading - * is. No threads are run on the coprocessor, so set up some dummy stack */ -int *cop_stackbegin = stackbegin; -int *cop_stackend = stackend; -#endif /* BOOTLOADER */ #endif /* NUM_CORES */ static inline void core_sleep(void) @@ -173,12 +161,10 @@ static inline void core_sleep(void) */ static inline void switch_to_idle_stack(const unsigned int core) { -#ifndef BOOTLOADER asm volatile ( "str sp, [%0] \n" /* save original stack pointer on idle stack */ "mov sp, %0 \n" /* switch stacks */ : : "r"(&idle_stacks[core][IDLE_STACK_WORDS-1])); -#endif (void)core; } #endif /* NUM_CORES */ @@ -1086,17 +1072,14 @@ void init_threads(void) /* Mark CPU initialized */ cores[CPU].kernel_running = true; /* Do _not_ wait for the COP to init in the bootloader because it doesn't */ -#ifndef BOOTLOADER /* TODO: HAL interface for this */ /* Wake up coprocessor and let it initialize kernel and threads */ COP_CTL = PROC_WAKE; /* Sleep until finished */ CPU_CTL = PROC_SLEEP; -#endif } else { -#ifndef BOOTLOADER /* Initial stack is the COP idle stack */ threads[slot].stack = cop_idlestackbegin; threads[slot].stack_size = IDLE_STACK_SIZE; @@ -1107,7 +1090,6 @@ void init_threads(void) CPU_CTL = PROC_WAKE; set_irq_level(0); remove_thread(NULL); -#endif /* BOOTLOADER */ #endif /* NUM_CORES */ } } @@ -1127,7 +1109,7 @@ int thread_stack_usage(const struct thread_entry *thread) thread->stack_size; } -#if NUM_CORES > 1 && !defined (BOOTLOADER) +#if NUM_CORES > 1 /*--------------------------------------------------------------------------- * Returns the maximum percentage of the core's idle stack ever used during * runtime. -- cgit v1.2.3