1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 by Alan Korr
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
32 long cpu_frequency NOCACHEBSS_ATTR
= CPU_FREQ
;
35 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
36 static int boost_counter NOCACHEBSS_ATTR
= 0;
37 static bool cpu_idle NOCACHEBSS_ATTR
= false;
40 struct mutex boostctrl_mtx NOCACHEBSS_ATTR
;
43 int get_cpu_boost_counter(void)
47 #ifdef CPU_BOOST_LOGGING
48 #define MAX_BOOST_LOG 64
49 static char cpu_boost_calls
[MAX_BOOST_LOG
][MAX_PATH
];
50 static int cpu_boost_first
= 0;
51 static int cpu_boost_calls_count
= 0;
52 static int cpu_boost_track_message
= 0;
53 int cpu_boost_log_getcount(void)
55 return cpu_boost_calls_count
;
57 char * cpu_boost_log_getlog_first(void)
59 if (cpu_boost_calls_count
)
61 cpu_boost_track_message
= 1;
62 return cpu_boost_calls
[cpu_boost_first
];
66 char * cpu_boost_log_getlog_next(void)
68 int message
= (cpu_boost_track_message
+cpu_boost_first
)%MAX_BOOST_LOG
;
69 if (cpu_boost_track_message
< cpu_boost_calls_count
)
71 cpu_boost_track_message
++;
72 return cpu_boost_calls
[message
];
76 void cpu_boost_(bool on_off
, char* location
, int line
)
78 if (cpu_boost_calls_count
== MAX_BOOST_LOG
)
80 cpu_boost_first
= (cpu_boost_first
+1)%MAX_BOOST_LOG
;
81 cpu_boost_calls_count
--;
82 if (cpu_boost_calls_count
< 0)
83 cpu_boost_calls_count
= 0;
85 if (cpu_boost_calls_count
< MAX_BOOST_LOG
)
87 int message
= (cpu_boost_first
+cpu_boost_calls_count
)%MAX_BOOST_LOG
;
88 snprintf(cpu_boost_calls
[message
], MAX_PATH
,
89 "%c %s:%d",on_off
==true?'B':'U',location
,line
);
90 cpu_boost_calls_count
++;
93 void cpu_boost(bool on_off
)
98 /* Boost the frequency if not already boosted */
99 if(boost_counter
++ == 0)
100 set_cpu_frequency(CPUFREQ_MAX
);
104 /* Lower the frequency if the counter reaches 0 */
105 if(--boost_counter
== 0)
108 set_cpu_frequency(CPUFREQ_DEFAULT
);
110 set_cpu_frequency(CPUFREQ_NORMAL
);
114 if(boost_counter
< 0)
119 void cpu_idle_mode(bool on_off
)
123 /* We need to adjust the frequency immediately if the CPU
125 if(boost_counter
== 0)
128 set_cpu_frequency(CPUFREQ_DEFAULT
);
130 set_cpu_frequency(CPUFREQ_NORMAL
);
133 #endif /* HAVE_ADJUSTABLE_CPU_FREQ */
136 #ifdef HAVE_FLASHED_ROCKBOX
137 static bool detect_flash_header(uint8_t *addr
)
140 int oldmode
= system_memory_guard(MEMGUARD_NONE
);
142 struct flash_header hdr
;
143 memcpy(&hdr
, addr
, sizeof(struct flash_header
));
145 system_memory_guard(oldmode
);
147 return hdr
.magic
== FLASH_MAGIC
;
151 bool detect_flashed_romimage(void)
153 #ifdef HAVE_FLASHED_ROCKBOX
154 return detect_flash_header((uint8_t *)FLASH_ROMIMAGE_ENTRY
);
157 #endif /* HAVE_FLASHED_ROCKBOX */
160 bool detect_flashed_ramimage(void)
162 #ifdef HAVE_FLASHED_ROCKBOX
163 return detect_flash_header((uint8_t *)FLASH_RAMIMAGE_ENTRY
);
166 #endif /* HAVE_FLASHED_ROCKBOX */
169 bool detect_original_firmware(void)
171 return !(detect_flashed_ramimage() || detect_flashed_romimage());
174 #if CONFIG_CPU == SH7034
179 static const char* const irqname
[] = {
180 "", "", "", "", "IllInstr", "", "IllSltIn","","",
181 "CPUAdrEr", "DMAAdrEr", "NMI", "UserBrk",
182 "","","","","","","","","","","","","","","","","","","",
183 "Trap32","Trap33","Trap34","Trap35","Trap36","Trap37","Trap38","Trap39",
184 "Trap40","Trap41","Trap42","Trap43","Trap44","Trap45","Trap46","Trap47",
185 "Trap48","Trap49","Trap50","Trap51","Trap52","Trap53","Trap54","Trap55",
186 "Trap56","Trap57","Trap58","Trap59","Trap60","Trap61","Trap62","Trap63",
187 "Irq0","Irq1","Irq2","Irq3","Irq4","Irq5","Irq6","Irq7",
188 "Dma0","","Dma1","","Dma2","","Dma3","",
189 "IMIA0","IMIB0","OVI0","", "IMIA1","IMIB1","OVI1","",
190 "IMIA2","IMIB2","OVI2","", "IMIA3","IMIB3","OVI3","",
191 "IMIA4","IMIB4","OVI4","",
192 "Ser0Err","Ser0Rx","Ser0Tx","Ser0TE",
193 "Ser1Err","Ser1Rx","Ser1Tx","Ser1TE",
194 "ParityEr","A/D conv","","","Watchdog","DRAMRefr"
197 #define RESERVE_INTERRUPT(number) "\t.long\t_UIE" #number "\n"
198 #define DEFAULT_INTERRUPT(name, number) "\t.weak\t_" #name \
199 "\n\t.set\t_" #name ",_UIE" #number \
200 "\n\t.long\t_" #name "\n"
205 * Handled in asm because gcc 4.x doesn't allow weak aliases to symbols
206 * defined in an asm block -- silly.
207 * Reset vectors (0..3) are handled in crt0.S */
209 ".section\t.vectors,\"aw\",@progbits\n"
210 DEFAULT_INTERRUPT (GII
, 4)
211 RESERVE_INTERRUPT ( 5)
212 DEFAULT_INTERRUPT (ISI
, 6)
213 RESERVE_INTERRUPT ( 7)
214 RESERVE_INTERRUPT ( 8)
215 DEFAULT_INTERRUPT (CPUAE
, 9)
216 DEFAULT_INTERRUPT (DMAAE
, 10)
217 DEFAULT_INTERRUPT (NMI
, 11)
218 DEFAULT_INTERRUPT (UB
, 12)
219 RESERVE_INTERRUPT ( 13)
220 RESERVE_INTERRUPT ( 14)
221 RESERVE_INTERRUPT ( 15)
222 RESERVE_INTERRUPT ( 16) /* TCB #0 */
223 RESERVE_INTERRUPT ( 17) /* TCB #1 */
224 RESERVE_INTERRUPT ( 18) /* TCB #2 */
225 RESERVE_INTERRUPT ( 19) /* TCB #3 */
226 RESERVE_INTERRUPT ( 20) /* TCB #4 */
227 RESERVE_INTERRUPT ( 21) /* TCB #5 */
228 RESERVE_INTERRUPT ( 22) /* TCB #6 */
229 RESERVE_INTERRUPT ( 23) /* TCB #7 */
230 RESERVE_INTERRUPT ( 24) /* TCB #8 */
231 RESERVE_INTERRUPT ( 25) /* TCB #9 */
232 RESERVE_INTERRUPT ( 26) /* TCB #10 */
233 RESERVE_INTERRUPT ( 27) /* TCB #11 */
234 RESERVE_INTERRUPT ( 28) /* TCB #12 */
235 RESERVE_INTERRUPT ( 29) /* TCB #13 */
236 RESERVE_INTERRUPT ( 30) /* TCB #14 */
237 RESERVE_INTERRUPT ( 31) /* TCB #15 */
238 DEFAULT_INTERRUPT (TRAPA32
, 32)
239 DEFAULT_INTERRUPT (TRAPA33
, 33)
240 DEFAULT_INTERRUPT (TRAPA34
, 34)
241 DEFAULT_INTERRUPT (TRAPA35
, 35)
242 DEFAULT_INTERRUPT (TRAPA36
, 36)
243 DEFAULT_INTERRUPT (TRAPA37
, 37)
244 DEFAULT_INTERRUPT (TRAPA38
, 38)
245 DEFAULT_INTERRUPT (TRAPA39
, 39)
246 DEFAULT_INTERRUPT (TRAPA40
, 40)
247 DEFAULT_INTERRUPT (TRAPA41
, 41)
248 DEFAULT_INTERRUPT (TRAPA42
, 42)
249 DEFAULT_INTERRUPT (TRAPA43
, 43)
250 DEFAULT_INTERRUPT (TRAPA44
, 44)
251 DEFAULT_INTERRUPT (TRAPA45
, 45)
252 DEFAULT_INTERRUPT (TRAPA46
, 46)
253 DEFAULT_INTERRUPT (TRAPA47
, 47)
254 DEFAULT_INTERRUPT (TRAPA48
, 48)
255 DEFAULT_INTERRUPT (TRAPA49
, 49)
256 DEFAULT_INTERRUPT (TRAPA50
, 50)
257 DEFAULT_INTERRUPT (TRAPA51
, 51)
258 DEFAULT_INTERRUPT (TRAPA52
, 52)
259 DEFAULT_INTERRUPT (TRAPA53
, 53)
260 DEFAULT_INTERRUPT (TRAPA54
, 54)
261 DEFAULT_INTERRUPT (TRAPA55
, 55)
262 DEFAULT_INTERRUPT (TRAPA56
, 56)
263 DEFAULT_INTERRUPT (TRAPA57
, 57)
264 DEFAULT_INTERRUPT (TRAPA58
, 58)
265 DEFAULT_INTERRUPT (TRAPA59
, 59)
266 DEFAULT_INTERRUPT (TRAPA60
, 60)
267 DEFAULT_INTERRUPT (TRAPA61
, 61)
268 DEFAULT_INTERRUPT (TRAPA62
, 62)
269 DEFAULT_INTERRUPT (TRAPA63
, 63)
270 DEFAULT_INTERRUPT (IRQ0
, 64)
271 DEFAULT_INTERRUPT (IRQ1
, 65)
272 DEFAULT_INTERRUPT (IRQ2
, 66)
273 DEFAULT_INTERRUPT (IRQ3
, 67)
274 DEFAULT_INTERRUPT (IRQ4
, 68)
275 DEFAULT_INTERRUPT (IRQ5
, 69)
276 DEFAULT_INTERRUPT (IRQ6
, 70)
277 DEFAULT_INTERRUPT (IRQ7
, 71)
278 DEFAULT_INTERRUPT (DEI0
, 72)
279 RESERVE_INTERRUPT ( 73)
280 DEFAULT_INTERRUPT (DEI1
, 74)
281 RESERVE_INTERRUPT ( 75)
282 DEFAULT_INTERRUPT (DEI2
, 76)
283 RESERVE_INTERRUPT ( 77)
284 DEFAULT_INTERRUPT (DEI3
, 78)
285 RESERVE_INTERRUPT ( 79)
286 DEFAULT_INTERRUPT (IMIA0
, 80)
287 DEFAULT_INTERRUPT (IMIB0
, 81)
288 DEFAULT_INTERRUPT (OVI0
, 82)
289 RESERVE_INTERRUPT ( 83)
290 DEFAULT_INTERRUPT (IMIA1
, 84)
291 DEFAULT_INTERRUPT (IMIB1
, 85)
292 DEFAULT_INTERRUPT (OVI1
, 86)
293 RESERVE_INTERRUPT ( 87)
294 DEFAULT_INTERRUPT (IMIA2
, 88)
295 DEFAULT_INTERRUPT (IMIB2
, 89)
296 DEFAULT_INTERRUPT (OVI2
, 90)
297 RESERVE_INTERRUPT ( 91)
298 DEFAULT_INTERRUPT (IMIA3
, 92)
299 DEFAULT_INTERRUPT (IMIB3
, 93)
300 DEFAULT_INTERRUPT (OVI3
, 94)
301 RESERVE_INTERRUPT ( 95)
302 DEFAULT_INTERRUPT (IMIA4
, 96)
303 DEFAULT_INTERRUPT (IMIB4
, 97)
304 DEFAULT_INTERRUPT (OVI4
, 98)
305 RESERVE_INTERRUPT ( 99)
306 DEFAULT_INTERRUPT (REI0
, 100)
307 DEFAULT_INTERRUPT (RXI0
, 101)
308 DEFAULT_INTERRUPT (TXI0
, 102)
309 DEFAULT_INTERRUPT (TEI0
, 103)
310 DEFAULT_INTERRUPT (REI1
, 104)
311 DEFAULT_INTERRUPT (RXI1
, 105)
312 DEFAULT_INTERRUPT (TXI1
, 106)
313 DEFAULT_INTERRUPT (TEI1
, 107)
314 RESERVE_INTERRUPT ( 108)
315 DEFAULT_INTERRUPT (ADITI
, 109)
318 * Must go into the same section as the UIE() handler */
321 "_UIE4:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
322 "_UIE5:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
323 "_UIE6:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
324 "_UIE7:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
325 "_UIE8:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
326 "_UIE9:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
327 "_UIE10:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
328 "_UIE11:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
329 "_UIE12:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
330 "_UIE13:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
331 "_UIE14:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
332 "_UIE15:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
333 "_UIE16:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
334 "_UIE17:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
335 "_UIE18:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
336 "_UIE19:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
337 "_UIE20:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
338 "_UIE21:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
339 "_UIE22:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
340 "_UIE23:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
341 "_UIE24:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
342 "_UIE25:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
343 "_UIE26:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
344 "_UIE27:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
345 "_UIE28:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
346 "_UIE29:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
347 "_UIE30:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
348 "_UIE31:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
349 "_UIE32:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
350 "_UIE33:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
351 "_UIE34:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
352 "_UIE35:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
353 "_UIE36:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
354 "_UIE37:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
355 "_UIE38:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
356 "_UIE39:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
357 "_UIE40:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
358 "_UIE41:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
359 "_UIE42:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
360 "_UIE43:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
361 "_UIE44:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
362 "_UIE45:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
363 "_UIE46:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
364 "_UIE47:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
365 "_UIE48:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
366 "_UIE49:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
367 "_UIE50:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
368 "_UIE51:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
369 "_UIE52:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
370 "_UIE53:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
371 "_UIE54:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
372 "_UIE55:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
373 "_UIE56:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
374 "_UIE57:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
375 "_UIE58:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
376 "_UIE59:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
377 "_UIE60:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
378 "_UIE61:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
379 "_UIE62:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
380 "_UIE63:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
381 "_UIE64:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
382 "_UIE65:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
383 "_UIE66:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
384 "_UIE67:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
385 "_UIE68:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
386 "_UIE69:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
387 "_UIE70:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
388 "_UIE71:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
389 "_UIE72:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
390 "_UIE73:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
391 "_UIE74:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
392 "_UIE75:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
393 "_UIE76:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
394 "_UIE77:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
395 "_UIE78:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
396 "_UIE79:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
397 "_UIE80:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
398 "_UIE81:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
399 "_UIE82:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
400 "_UIE83:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
401 "_UIE84:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
402 "_UIE85:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
403 "_UIE86:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
404 "_UIE87:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
405 "_UIE88:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
406 "_UIE89:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
407 "_UIE90:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
408 "_UIE91:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
409 "_UIE92:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
410 "_UIE93:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
411 "_UIE94:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
412 "_UIE95:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
413 "_UIE96:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
414 "_UIE97:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
415 "_UIE98:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
416 "_UIE99:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
417 "_UIE100:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
418 "_UIE101:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
419 "_UIE102:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
420 "_UIE103:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
421 "_UIE104:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
422 "_UIE105:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
423 "_UIE106:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
424 "_UIE107:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
425 "_UIE108:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
426 "_UIE109:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\n"
430 extern void UIE4(void); /* needed for calculating the UIE number */
432 void UIE (unsigned int pc
) __attribute__((section(".text")));
433 void UIE (unsigned int pc
) /* Unexpected Interrupt or Exception */
435 #if CONFIG_LED == LED_REAL
442 asm volatile ("sts\tpr,%0" : "=r"(n
));
445 lcd_clear_display ();
446 #ifdef HAVE_LCD_BITMAP
447 lcd_setfont(FONT_SYSFIXED
);
449 /* output exception */
450 n
= (n
- (unsigned)UIE4
+ 12)>>2; /* get exception or interrupt number */
451 snprintf(str
,sizeof(str
),"I%02x:%s",n
,irqname
[n
]);
453 snprintf(str
,sizeof(str
),"at %08x",pc
);
459 #if CONFIG_LED == LED_REAL
468 /* try to restart firmware if ON is pressed */
469 #if CONFIG_KEYPAD == PLAYER_PAD
471 #elif CONFIG_KEYPAD == RECORDER_PAD
473 if (!(PCDR
& 0x0008))
477 #elif CONFIG_KEYPAD == ONDIO_PAD
478 if (!(PCDR
& 0x0008))
481 /* enable the watchguard timer, but don't service it */
482 RSTCSR_W
= 0x5a40; /* Reset enabled, power-on reset */
483 TCSR_W
= 0xa560; /* Watchdog timer mode, timer enabled, sysclk/2 */
488 void system_init(void)
490 /* Disable all interrupts */
497 /* NMI level low, falling edge on all interrupts */
500 /* Enable burst and RAS down mode on DRAM */
503 /* Activate Warp mode (simultaneous internal and external mem access) */
506 /* Bus state controller initializations. These are only necessary when
507 running from flash. */
508 WCR1
= 0x40FD; /* Long wait states for CS6 (ATA), short for the rest. */
509 WCR3
= 0x8000; /* WAIT is pulled up, 1 state inserted for CS6 */
512 void system_reboot (void)
514 set_irq_level(HIGHEST_IRQ_LEVEL
);
516 asm volatile ("ldc\t%0,vbr" : : "r"(0));
518 PACR2
|= 0x4000; /* for coldstart detection */
526 asm volatile ("jmp @%0; mov.l @%1,r15" : :
527 "r"(*(int*)0),"r"(4));
530 /* Utilise the user break controller to catch invalid memory accesses. */
531 int system_memory_guard(int newmode
)
533 static const struct {
537 } modes
[MAXMEMGUARD
] = {
539 { 0x00000000, 0x00000000, 0x0000 },
540 /* catch writes to area 02 (flash ROM) */
541 { 0x02000000, 0x00FFFFFF, 0x00F8 },
542 /* catch all accesses to areas 00 (internal ROM) and 01 (free) */
543 { 0x00000000, 0x01FFFFFF, 0x00FC }
546 int oldmode
= MEMGUARD_NONE
;
549 /* figure out the old mode from what is in the UBC regs. If the register
550 values don't match any mode, assume MEMGUARD_NONE */
551 for (i
= MEMGUARD_NONE
; i
< MAXMEMGUARD
; i
++)
553 if (BAR
== modes
[i
].addr
&& BAMR
== modes
[i
].mask
&&
561 if (newmode
== MEMGUARD_KEEP
)
564 BBR
= 0; /* switch off everything first */
566 /* always set the UBC according to the mode, in case the old settings
567 didn't match any valid mode */
568 BAR
= modes
[newmode
].addr
;
569 BAMR
= modes
[newmode
].mask
;
570 BBR
= modes
[newmode
].bbr
;
574 #elif defined(CPU_ARM)
576 static const char* const uiename
[] = {
577 "Undefined instruction", "Prefetch abort", "Data abort"
580 /* Unexpected Interrupt or Exception handler. Currently only deals with
581 exceptions, but will deal with interrupts later.
583 void UIE(unsigned int pc
, unsigned int num
)
588 #ifdef HAVE_LCD_BITMAP
589 lcd_setfont(FONT_SYSFIXED
);
591 lcd_puts(0, 0, uiename
[num
]);
592 snprintf(str
, sizeof(str
), "at %08x", pc
);
598 /* TODO: perhaps add button handling in here when we get a polling
604 #if CONFIG_CPU==PP5020 || CONFIG_CPU==PP5024
606 unsigned int ipod_hw_rev
;
609 extern void TIMER1(void);
610 extern void TIMER2(void);
612 #if defined(IPOD_MINI) /* mini 1 only, mini 2G uses iPod 4G code */
613 extern void ipod_mini_button_int(void);
617 if(CURRENT_CORE
== CPU
)
619 if (CPU_INT_STAT
& TIMER1_MASK
)
621 else if (CPU_INT_STAT
& TIMER2_MASK
)
623 else if (CPU_HI_INT_STAT
& GPIO_MASK
)
624 ipod_mini_button_int();
626 if (COP_INT_STAT
& TIMER1_MASK
)
628 else if (COP_INT_STAT
& TIMER2_MASK
)
630 else if (COP_HI_INT_STAT
& GPIO_MASK
)
631 ipod_mini_button_int();
634 #elif (defined IRIVER_H10) || (defined IRIVER_H10_5GB) || defined(ELIO_TPJ1022) \
635 || (defined SANSA_E200)
636 /* TODO: this should really be in the target tree, but moving it there caused
637 crt0.S not to find it while linking */
638 /* TODO: Even if it isn't in the target tree, this should be the default case */
641 if(CURRENT_CORE
== CPU
)
643 if (CPU_INT_STAT
& TIMER1_MASK
)
645 else if (CPU_INT_STAT
& TIMER2_MASK
)
648 if (COP_INT_STAT
& TIMER1_MASK
)
650 else if (COP_INT_STAT
& TIMER2_MASK
)
655 extern void ipod_4g_button_int(void);
659 if(CURRENT_CORE
== CPU
)
661 if (CPU_INT_STAT
& TIMER1_MASK
)
663 else if (CPU_INT_STAT
& TIMER2_MASK
)
665 else if (CPU_HI_INT_STAT
& I2C_MASK
)
666 ipod_4g_button_int();
668 if (COP_INT_STAT
& TIMER1_MASK
)
670 else if (COP_INT_STAT
& TIMER2_MASK
)
672 else if (COP_HI_INT_STAT
& I2C_MASK
)
673 ipod_4g_button_int();
677 #endif /* BOOTLOADER */
679 unsigned int current_core(void)
681 if((PROCESSOR_ID
& 0xff) == PROC_ID_CPU
)
689 /* TODO: The following two function have been lifted straight from IPL, and
690 hence have a lot of numeric addresses used straight. I'd like to use
691 #defines for these, but don't know what most of them are for or even what
692 they should be named. Because of this I also have no way of knowing how
693 to extend the funtions to do alternate cache configurations and/or
694 some other CPU frequency scaling. */
697 static void ipod_init_cache(void)
699 /* Initialising the cache in the iPod bootloader prevents Rockbox from starting */
702 /* cache init mode? */
703 CACHE_CTL
= CACHE_INIT
;
705 /* PP5002 has 8KB cache */
706 for (i
= 0xf0004000; i
< 0xf0006000; i
+= 16) {
710 outl(0x0, 0xf000f040);
711 outl(0x3fc0, 0xf000f044);
714 CACHE_CTL
= CACHE_ENABLE
;
716 for (i
= 0x10000000; i
< 0x10002000; i
+= 16)
721 /* Not all iPod targets support CPU freq. boosting yet */
722 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
723 void set_cpu_frequency(long frequency
)
725 unsigned long postmult
;
728 /* Using mutex or spinlock isn't safe here. */
729 while (test_and_set(&boostctrl_mtx
.locked
, 1)) ;
732 if (frequency
== CPUFREQ_NORMAL
)
733 postmult
= CPUFREQ_NORMAL_MULT
;
734 else if (frequency
== CPUFREQ_MAX
)
735 postmult
= CPUFREQ_MAX_MULT
;
737 postmult
= CPUFREQ_DEFAULT_MULT
;
738 cpu_frequency
= frequency
;
741 outl(inl(0x70000020) | (1<<30), 0x70000020);
743 /* Select 24MHz crystal as clock source? */
744 outl((inl(0x60006020) & 0x0fffff0f) | 0x20000020, 0x60006020);
746 /* Clock frequency = (24/8)*postmult */
747 outl(0xaa020000 | 8 | (postmult
<< 8), 0x60006034);
749 /* Wait for PLL relock? */
752 /* Select PLL as clock source? */
753 outl((inl(0x60006020) & 0x0fffff0f) | 0x20000070, 0x60006020);
755 # if defined(IPOD_COLOR) || defined(IPOD_4G) || defined(IPOD_MINI) || defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
756 /* We don't know why the timer interrupt gets disabled on the PP5020
757 based ipods, but without the following line, the 4Gs will freeze
758 when CPU frequency changing is enabled.
760 Note also that a simple "CPU_INT_EN = TIMER1_MASK;" (as used
761 elsewhere to enable interrupts) doesn't work, we need "|=".
763 It's not needed on the PP5021 and PP5022 ipods.
766 /* unmask interrupt source */
767 CPU_INT_EN
|= TIMER1_MASK
;
768 COP_INT_EN
|= TIMER1_MASK
;
772 boostctrl_mtx
.locked
= 0;
775 #elif !defined(BOOTLOADER)
776 void ipod_set_cpu_frequency(void)
779 outl(inl(0x70000020) | (1<<30), 0x70000020);
781 /* Select 24MHz crystal as clock source? */
782 outl((inl(0x60006020) & 0x0fffff0f) | 0x20000020, 0x60006020);
784 /* Clock frequency = (24/8)*25 = 75MHz */
785 outl(0xaa020000 | 8 | (25 << 8), 0x60006034);
786 /* Wait for PLL relock? */
789 /* Select PLL as clock source? */
790 outl((inl(0x60006020) & 0x0fffff0f) | 0x20000070, 0x60006020);
794 void system_init(void)
797 if (CURRENT_CORE
== CPU
)
799 /* Remap the flash ROM from 0x00000000 to 0x20000000. */
800 MMAP3_LOGICAL
= 0x20000000 | 0x3a00;
801 MMAP3_PHYSICAL
= 0x00000000 | 0x3f84;
803 /* The hw revision is written to the last 4 bytes of SDRAM by the
804 bootloader - we save it before Rockbox overwrites it. */
805 ipod_hw_rev
= (*((volatile unsigned long*)(0x01fffffc)));
807 /* disable all irqs */
808 outl(-1, 0x60001138);
809 outl(-1, 0x60001128);
810 outl(-1, 0x6000111c);
812 outl(-1, 0x60001038);
813 outl(-1, 0x60001028);
814 outl(-1, 0x6000101c);
816 # if NUM_CORES > 1 && defined(HAVE_ADJUSTABLE_CPU_FREQ)
817 spinlock_init(&boostctrl_mtx
);
820 #if (!defined HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES == 1)
821 ipod_set_cpu_frequency();
824 #if (!defined HAVE_ADJUSTABLE_CPU_FREQ) && (NUM_CORES > 1)
827 ipod_set_cpu_frequency();
834 void system_reboot(void)
837 DEV_RS
|= DEV_SYSTEM
;
840 int system_memory_guard(int newmode
)
845 #elif CONFIG_CPU==PP5002
846 unsigned int ipod_hw_rev
;
848 extern void TIMER1(void);
849 extern void TIMER2(void);
853 if(CURRENT_CORE
== CPU
)
855 if (CPU_INT_STAT
& TIMER1_MASK
)
857 else if (CPU_INT_STAT
& TIMER2_MASK
)
860 if (COP_INT_STAT
& TIMER1_MASK
)
862 else if (COP_INT_STAT
& TIMER2_MASK
)
869 unsigned int current_core(void)
871 if(((*(volatile unsigned long *)(0xc4000000)) & 0xff) == 0x55)
879 /* TODO: The following two function have been lifted straight from IPL, and
880 hence have a lot of numeric addresses used straight. I'd like to use
881 #defines for these, but don't know what most of them are for or even what
882 they should be named. Because of this I also have no way of knowing how
883 to extend the funtions to do alternate cache configurations and/or
884 some other CPU frequency scaling. */
887 static void ipod_init_cache(void)
890 /* Initialising the cache in the iPod bootloader prevents Rockbox from starting */
891 outl(inl(0xcf004050) & ~0x700, 0xcf004050);
892 outl(0x4000, 0xcf004020);
894 outl(0x2, 0xcf004024);
896 /* PP5002 has 8KB cache */
897 for (i
= 0xf0004000; i
< (int)(0xf0006000); i
+= 16) {
901 outl(0x0, 0xf000f020);
902 outl(0x3fc0, 0xf000f024);
904 outl(0x3, 0xcf004024);
909 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
910 void set_cpu_frequency(long frequency
)
912 unsigned long postmult
;
914 if (CURRENT_CORE
== CPU
)
916 if (frequency
== CPUFREQ_NORMAL
)
917 postmult
= CPUFREQ_NORMAL_MULT
;
918 else if (frequency
== CPUFREQ_MAX
)
919 postmult
= CPUFREQ_MAX_MULT
;
921 postmult
= CPUFREQ_DEFAULT_MULT
;
922 cpu_frequency
= frequency
;
924 outl(0x02, 0xcf005008);
925 outl(0x55, 0xcf00500c);
926 outl(0x6000, 0xcf005010);
928 /* Clock frequency = (24/8)*postmult */
930 outl(postmult
, 0xcf00501c);
932 outl(0xe000, 0xcf005010);
934 /* Wait for PLL relock? */
937 /* Select PLL as clock source? */
938 outl(0xa8, 0xcf00500c);
941 #elif !defined(BOOTLOADER)
942 static void ipod_set_cpu_speed(void)
944 outl(0x02, 0xcf005008);
945 outl(0x55, 0xcf00500c);
946 outl(0x6000, 0xcf005010);
948 // 75 MHz (24/24 * 75) (default)
949 outl(24, 0xcf005018);
950 outl(75, 0xcf00501c);
959 outl(0xe000, 0xcf005010);
963 outl(0xa8, 0xcf00500c);
967 void system_init(void)
970 if (CURRENT_CORE
== CPU
)
972 /* Remap the flash ROM from 0x00000000 to 0x20000000. */
973 MMAP3_LOGICAL
= 0x20000000 | 0x3a00;
974 MMAP3_PHYSICAL
= 0x00000000 | 0x3f84;
976 ipod_hw_rev
= (*((volatile unsigned long*)(0x01fffffc)));
977 outl(-1, 0xcf00101c);
978 outl(-1, 0xcf001028);
979 outl(-1, 0xcf001038);
980 #ifndef HAVE_ADJUSTABLE_CPU_FREQ
981 ipod_set_cpu_speed();
988 void system_reboot(void)
990 outl(inl(0xcf005030) | 0x4, 0xcf005030);
993 int system_memory_guard(int newmode
)
1000 #endif /* CONFIG_CPU */