summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/SOURCES2
-rw-r--r--firmware/app.lds16
-rw-r--r--firmware/export/config.h2
-rw-r--r--firmware/export/pp5002.h2
-rw-r--r--firmware/target/arm/crt0-pp-bl.S113
-rw-r--r--firmware/target/arm/crt0-pp.S8
-rw-r--r--firmware/target/arm/system-pp5002.c10
-rw-r--r--firmware/target/arm/system-target.h13
-rw-r--r--firmware/thread.c22
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.