summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2007-09-29 06:17:33 +0000
committerMichael Sevakis <jethead71@rockbox.org>2007-09-29 06:17:33 +0000
commitda55251a35d8ad6c0b8b9e62904798212caba46f (patch)
treeb629e5316ce26624d3307587e32985c18403ec27
parentaaf3e3269c9d1e3dc41255c9be5f47aba8acb515 (diff)
downloadrockbox-da55251a35d8ad6c0b8b9e62904798212caba46f.tar.gz
rockbox-da55251a35d8ad6c0b8b9e62904798212caba46f.zip
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
-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
13profile.c 13profile.c
14#endif /* RB_PROFILE */ 14#endif /* RB_PROFILE */
15kernel.c 15kernel.c
16#ifndef BOOTLOADER
16rolo.c 17rolo.c
18#endif /* BOOTLOADER */
17thread.c 19thread.c
18timer.c 20timer.c
19#endif /* SIMULATOR */ 21#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
197 } > IRAM 197 } > IRAM
198 198
199#ifdef CPU_PP 199#ifdef CPU_PP
200#if NUM_CORES > 1
201 .idle_stacks : 200 .idle_stacks :
202 { 201 {
202#if NUM_CORES > 1
203 *(.idle_stacks) 203 *(.idle_stacks)
204 cpu_idlestackbegin = .; 204 cpu_idlestackbegin = .;
205 . += 0x0080; 205 . += IDLE_STACK_SIZE;
206 cpu_idlestackend = .; 206 cpu_idlestackend = .;
207#endif
207 cop_idlestackbegin = .; 208 cop_idlestackbegin = .;
208 . += 0x0080; 209 . += IDLE_STACK_SIZE;
209 cop_idlestackend = .; 210 cop_idlestackend = .;
210 } > IRAM 211 } > IRAM
211#else
212 .cop_stack :
213 {
214 *(.cop_stack)
215 cop_stackbegin = .;
216 . += 0x0500;
217 cop_stackend = .;
218 } > IRAM
219#endif
220#endif 212#endif
221 213
222#else 214#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 @@
364#endif 364#endif
365 365
366/* Dual core support - not yet working on the 1G/2G and 3G iPod */ 366/* Dual core support - not yet working on the 1G/2G and 3G iPod */
367#if defined(CPU_PP) && CONFIG_CPU != PP5002 367#if defined(CPU_PP) && CONFIG_CPU != PP5002 && !defined(BOOTLOADER)
368#define NUM_CORES 2 368#define NUM_CORES 2
369#define CURRENT_CORE current_core() 369#define CURRENT_CORE current_core()
370/* Hopefully at some point we will learn how to mark areas of main memory as 370/* 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 @@
22/* Much info gleaned and/or copied from the iPodLinux project. */ 22/* Much info gleaned and/or copied from the iPodLinux project. */
23#define DRAM_START 0x28000000 23#define DRAM_START 0x28000000
24 24
25#define PROCESSOR_ID (*(volatile unsigned long *)(0xc4000000))
26
25#define IPOD_LCD_BASE 0xc0001000 27#define IPOD_LCD_BASE 0xc0001000
26 28
27#define IISCONFIG (*(volatile unsigned long *)(0xc0002500)) 29#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:
48 .equ WAKE, 0x0 48 .equ WAKE, 0x0
49 .equ SLEEPING, 0x80000000 49 .equ SLEEPING, 0x80000000
50 .equ CACHE_CTRL, 0x6000c000 50 .equ CACHE_CTRL, 0x6000c000
51 .equ CACHE_ENAB, 0x1
51#endif 52#endif
52 53
53 msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ */ 54 msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ */
54#ifndef E200R_INSTALLER 55#ifndef E200R_INSTALLER
55/* 1 - Copy the bootloader to IRAM */ 56/* 1 - Copy the bootloader to IRAM */
56 /* get the high part of our execute address */ 57 /* get the high part of our execute address */
57 ldr r7, =0xffffff00 58 bic r0, pc, #0xff /* r4 = pc & 0xffffff00 */
58 and r4, pc, r7
59 59
60 /* Copy bootloader to safe area - 0x40000000 (IRAM) */ 60 /* Copy bootloader to safe area - 0x40000000 (IRAM) */
61 mov r5, #0x40000000 61 mov r1, #0x40000000
62 ldr r6, = _dataend 62 ldr r2, =_dataend
631: 631:
64 cmp r5, r6 64 cmp r2, r1
65 ldrcc r2, [r4], #4 65 ldrhi r3, [r0], #4
66 strcc r2, [r5], #4 66 strhi r3, [r1], #4
67 bcc 1b 67 bhi 1b
68 68
69#ifndef IPOD_ARCH 69#ifndef IPOD_ARCH
70 /* For builds on targets with mi4 firmware, scramble writes data to 70 /* For builds on targets with mi4 firmware, scramble writes data to
71 0xe0-0xeb, so jump past that.*/ 71 0xe0-0xeb, so jump past that. pad_skip must then exist at an
72 address >= 0xec */
72 b pad_skip 73 b pad_skip
73 74
74.space 60*4 75.space 60*4
75 76
76pad_skip: 77pad_skip:
77#endif 78#endif /* IPOD_ARCH */
78 79
79 80
80/* 2 - Jump both CPU and COP there */ 81/* 2 - Jump both CPU and COP there */
@@ -82,89 +83,92 @@ pad_skip:
82#endif /* E200R_INSTALLER */ 83#endif /* E200R_INSTALLER */
83 84
84start_loc: 85start_loc:
85
86 /* Find out which processor we are */ 86 /* Find out which processor we are */
87 ldr r0, =PROC_ID 87 ldr r0, =PROC_ID
88 ldr r0, [r0] 88 ldrb r0, [r0]
89 and r0, r0, #0xff
90 cmp r0, #0x55 89 cmp r0, #0x55
91 beq cpu 90 beq cpu
92 91
92cop:
93 /* put us (co-processor) to sleep */ 93 /* put us (co-processor) to sleep */
94 ldr r4, =COP_CTRL 94 ldr r0, =COP_CTRL
95 mov r3, #SLEEP 95 mov r1, #SLEEP
96 str r3, [r4] 96 str r1, [r0]
97 ldr pc, =cop_wake_start 97
98 98#ifdef CPU_PP502x
99cop_wake_start: 99 /* COP: Invalidate cache if enabled */
100#if CONFIG_CPU != PP5002 100 ldr r2, =CACHE_CTRL
101 /* COP: Invalidate cache */ 101 ldr r1, [r2]
102 tst r1, #CACHE_ENAB
103 beq 2f
102 ldr r0, =0xf000f044 104 ldr r0, =0xf000f044
103 ldr r1, [r0] 105 ldr r1, [r0]
104 orr r1, r1, #0x6 106 orr r1, r1, #0x6
105 str r1, [r0] 107 str r1, [r0]
106
107 ldr r0, =CACHE_CTRL
1081: 1081:
109 ldr r1, [r0] 109 ldr r1, [r2]
110 tst r1, #0x8000 110 tst r1, #0x8000
111 bne 1b 111 bne 1b
112#endif 1122:
113#endif /* CPU_PP502x */
113 114
114 ldr r0, =startup_loc 115 ldr r0, =startup_loc
115 ldr pc, [r0] 116 ldr pc, [r0]
116 117
117cpu: 118cpu:
118 /* Wait for COP to be sleeping */ 119 /* Wait for COP to be sleeping */
119 ldr r4, =COP_STATUS 120 ldr r0, =COP_STATUS
1201: 1211:
121 ldr r3, [r4] 122 ldr r1, [r0]
122 ands r3, r3, #SLEEPING 123 tst r1, #SLEEPING
123 beq 1b 124 beq 1b
124 125
125 /* Initialise bss section to zero */ 126 /* Initialise bss section to zero */
126 ldr r2, =_edata 127 ldr r0, =_edata
127 ldr r3, =_end 128 ldr r1, =_end
128 mov r4, #0 129 mov r2, #0
1291: 1301:
130 cmp r3, r2 131 cmp r1, r0
131 strhi r4, [r2], #4 132 strhi r2, [r0], #4
132 bhi 1b 133 bhi 1b
133 134
134 /* Set up some stack and munge it with 0xdeadbeef */ 135 /* Set up some stack and munge it with 0xdeadbeef */
135 ldr sp, =stackend 136 ldr sp, =stackend
136 mov r3, sp 137 ldr r0, =stackbegin
137 ldr r2, =stackbegin 138 ldr r1, =0xdeadbeef
138 ldr r4, =0xdeadbeef
1391: 1391:
140 cmp r3, r2 140 cmp sp, r0
141 strhi r4, [r2], #4 141 strhi r1, [r0], #4
142 bhi 1b 142 bhi 1b
143 143
144 /* execute the loader - this will load an image to 0x10000000 */ 144 /* execute the loader - this will load an image to 0x10000000 */
145 bl main 145 bl main
146 146
147 /* store actual startup location returned by main() */
147 ldr r1, =startup_loc 148 ldr r1, =startup_loc
148 str r0, [r1] 149 str r0, [r1]
149 150
150#if CONFIG_CPU != PP5002 151#ifdef CPU_PP502x
151 /* Flush cache */ 152 /* Flush cache if enabled */
152 ldr r3, =0xf000f044 153 ldr r2, =CACHE_CTRL
153 ldr r4, [r3] 154 ldr r1, [r2]
154 orr r4, r4, #0x2 155 tst r1, #CACHE_ENAB
155 str r4, [r3] 156 beq 2f
156 157 ldr r0, =0xf000f044
157 ldr r3, =CACHE_CTRL 158 ldr r1, [r0]
159 orr r1, r1, #0x2
160 str r1, [r0]
1581: 1611:
159 ldr r4, [r3] 162 ldr r1, [r2]
160 tst r4, #0x8000 163 tst r1, #0x8000
161 bne 1b 164 bne 1b
162#endif 1652:
166#endif /* CPU_PP502x */
163 167
164 /* Wake up the coprocessor before executing the firmware */ 168 /* Wake up the coprocessor before executing the firmware */
165 ldr r4, =COP_CTRL 169 ldr r0, =COP_CTRL
166 mov r3, #WAKE 170 mov r1, #WAKE
167 str r3, [r4] 171 str r1, [r0]
168 172
169#ifdef SANSA_C200 173#ifdef SANSA_C200
170 /* Magic for loading the c200 OF */ 174 /* Magic for loading the c200 OF */
@@ -184,6 +188,7 @@ startup_loc:
184.align 8 /* starts at 0x100 */ 188.align 8 /* starts at 0x100 */
185.global boot_table 189.global boot_table
186boot_table: 190boot_table:
187 /* here comes the boot table, don't move its offset */ 191 /* here comes the boot table, don't move its offset - preceding
192 code+data must stay <= 256 bytes */
188 .space 400 193 .space 400
189#endif 194#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:
266 ldr r3, [r4] 266 ldr r3, [r4]
267 tst r3, #SLEEPING 267 tst r3, #SLEEPING
268 beq 1b 268 beq 1b
269#endif
269 270
270 /* Set up idle stack for COP and munge it with 0xdeadbeef */ 271 /* Set up idle stack for COP and munge it with 0xdeadbeef */
271 ldr r2, =cop_idlestackbegin
272 ldr sp, =cop_idlestackend 272 ldr sp, =cop_idlestackend
273#else 273 ldr r2, =cop_idlestackbegin
274 /* Setup stack for COP and munge it with 0xdeadbeef */
275 ldr r2, =cop_stackbegin
276 ldr sp, =cop_stackend
277#endif
278 ldr r4, =0xdeadbeef 274 ldr r4, =0xdeadbeef
2792: 2752:
280 cmp sp, r2 276 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)
53 53
54#endif 54#endif
55 55
56unsigned int current_core(void)
57{
58 if(((*(volatile unsigned long *)(0xc4000000)) & 0xff) == 0x55)
59 {
60 return CPU;
61 }
62 return COP;
63}
64
65
66/* TODO: The following two function have been lifted straight from IPL, and 56/* TODO: The following two function have been lifted straight from IPL, and
67 hence have a lot of numeric addresses used straight. I'd like to use 57 hence have a lot of numeric addresses used straight. I'd like to use
68 #defines for these, but don't know what most of them are for or even what 58 #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)
52 while (TIME_BEFORE(USEC_TIMER, stop)); 52 while (TIME_BEFORE(USEC_TIMER, stop));
53} 53}
54 54
55#ifdef CPU_PP502x
56static inline unsigned int current_core(void) 55static inline unsigned int current_core(void)
57{ 56{
58 /* 57 /*
@@ -63,14 +62,16 @@ static inline unsigned int current_core(void)
63 */ 62 */
64 unsigned int core; 63 unsigned int core;
65 asm volatile ( 64 asm volatile (
66 "mov %0, #0x60000000 \r\n" /* PROCESSOR_ID */ 65 "ldrb %0, [%1] \n" /* Just load the LSB */
67 "ldrb %0, [%0] \r\n" /* Just load the LSB */ 66 "mov %0, %0, lsr #7 \n" /* Bit 7 => index */
68 "mov %0, %0, lsr #7 \r\n" /* Bit 7 => index */ 67 : "=r"(core) /* CPU=0, COP=1 */
69 : "=&r"(core) /* CPU=0, COP=1 */ 68 : "r"(&PROCESSOR_ID)
70 ); 69 );
71 return core; 70 return core;
72} 71}
73 72
73#ifdef CPU_PP502x
74
74#ifndef BOOTLOADER 75#ifndef BOOTLOADER
75#define CACHE_FUNCTIONS_AS_CALL 76#define CACHE_FUNCTIONS_AS_CALL
76 77
@@ -81,8 +82,6 @@ void invalidate_icache(void);
81void flush_icache(void); 82void flush_icache(void);
82#endif 83#endif
83 84
84#else
85unsigned int current_core(void);
86#endif /* CPU_PP502x */ 85#endif /* CPU_PP502x */
87 86
88 87
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)
81 "ldr r4, [r0, #40] \n" /* start in r4 since it's non-volatile */ 81 "ldr r4, [r0, #40] \n" /* start in r4 since it's non-volatile */
82 "mov r1, #0 \n" /* Mark thread as running */ 82 "mov r1, #0 \n" /* Mark thread as running */
83 "str r1, [r0, #40] \n" 83 "str r1, [r0, #40] \n"
84#if NUM_CORES > 1 && !defined (BOOTLOADER) 84#if NUM_CORES > 1
85 "ldr r0, =invalidate_icache \n" /* Invalidate this core's cache. */ 85 "ldr r0, =invalidate_icache \n" /* Invalidate this core's cache. */
86 "mov lr, pc \n" /* This could be the first entry into */ 86 "mov lr, pc \n" /* This could be the first entry into */
87 "bx r0 \n" /* plugin or codec code for this core. */ 87 "bx r0 \n" /* plugin or codec code for this core. */
@@ -132,23 +132,11 @@ extern int cpu_idlestackbegin[];
132extern int cpu_idlestackend[]; 132extern int cpu_idlestackend[];
133extern int cop_idlestackbegin[]; 133extern int cop_idlestackbegin[];
134extern int cop_idlestackend[]; 134extern int cop_idlestackend[];
135#ifndef BOOTLOADER
136static int * const idle_stacks[NUM_CORES] NOCACHEDATA_ATTR = 135static int * const idle_stacks[NUM_CORES] NOCACHEDATA_ATTR =
137{ 136{
138 [CPU] = cpu_idlestackbegin, 137 [CPU] = cpu_idlestackbegin,
139 [COP] = cop_idlestackbegin 138 [COP] = cop_idlestackbegin
140}; 139};
141#endif /* BOOTLOADER */
142#else /* NUM_CORES == 1 */
143#ifndef BOOTLOADER
144extern int cop_stackbegin[];
145extern int cop_stackend[];
146#else
147/* The coprocessor stack is not set up in the bootloader code, but the threading
148 * is. No threads are run on the coprocessor, so set up some dummy stack */
149int *cop_stackbegin = stackbegin;
150int *cop_stackend = stackend;
151#endif /* BOOTLOADER */
152#endif /* NUM_CORES */ 140#endif /* NUM_CORES */
153 141
154static inline void core_sleep(void) 142static inline void core_sleep(void)
@@ -173,12 +161,10 @@ static inline void core_sleep(void)
173 */ 161 */
174static inline void switch_to_idle_stack(const unsigned int core) 162static inline void switch_to_idle_stack(const unsigned int core)
175{ 163{
176#ifndef BOOTLOADER
177 asm volatile ( 164 asm volatile (
178 "str sp, [%0] \n" /* save original stack pointer on idle stack */ 165 "str sp, [%0] \n" /* save original stack pointer on idle stack */
179 "mov sp, %0 \n" /* switch stacks */ 166 "mov sp, %0 \n" /* switch stacks */
180 : : "r"(&idle_stacks[core][IDLE_STACK_WORDS-1])); 167 : : "r"(&idle_stacks[core][IDLE_STACK_WORDS-1]));
181#endif
182 (void)core; 168 (void)core;
183} 169}
184#endif /* NUM_CORES */ 170#endif /* NUM_CORES */
@@ -1086,17 +1072,14 @@ void init_threads(void)
1086 /* Mark CPU initialized */ 1072 /* Mark CPU initialized */
1087 cores[CPU].kernel_running = true; 1073 cores[CPU].kernel_running = true;
1088 /* Do _not_ wait for the COP to init in the bootloader because it doesn't */ 1074 /* Do _not_ wait for the COP to init in the bootloader because it doesn't */
1089#ifndef BOOTLOADER
1090 /* TODO: HAL interface for this */ 1075 /* TODO: HAL interface for this */
1091 /* Wake up coprocessor and let it initialize kernel and threads */ 1076 /* Wake up coprocessor and let it initialize kernel and threads */
1092 COP_CTL = PROC_WAKE; 1077 COP_CTL = PROC_WAKE;
1093 /* Sleep until finished */ 1078 /* Sleep until finished */
1094 CPU_CTL = PROC_SLEEP; 1079 CPU_CTL = PROC_SLEEP;
1095#endif
1096 } 1080 }
1097 else 1081 else
1098 { 1082 {
1099#ifndef BOOTLOADER
1100 /* Initial stack is the COP idle stack */ 1083 /* Initial stack is the COP idle stack */
1101 threads[slot].stack = cop_idlestackbegin; 1084 threads[slot].stack = cop_idlestackbegin;
1102 threads[slot].stack_size = IDLE_STACK_SIZE; 1085 threads[slot].stack_size = IDLE_STACK_SIZE;
@@ -1107,7 +1090,6 @@ void init_threads(void)
1107 CPU_CTL = PROC_WAKE; 1090 CPU_CTL = PROC_WAKE;
1108 set_irq_level(0); 1091 set_irq_level(0);
1109 remove_thread(NULL); 1092 remove_thread(NULL);
1110#endif /* BOOTLOADER */
1111#endif /* NUM_CORES */ 1093#endif /* NUM_CORES */
1112 } 1094 }
1113} 1095}
@@ -1127,7 +1109,7 @@ int thread_stack_usage(const struct thread_entry *thread)
1127 thread->stack_size; 1109 thread->stack_size;
1128} 1110}
1129 1111
1130#if NUM_CORES > 1 && !defined (BOOTLOADER) 1112#if NUM_CORES > 1
1131/*--------------------------------------------------------------------------- 1113/*---------------------------------------------------------------------------
1132 * Returns the maximum percentage of the core's idle stack ever used during 1114 * Returns the maximum percentage of the core's idle stack ever used during
1133 * runtime. 1115 * runtime.