Work-in-progress iriver iFP-7xx port by Tomasz Malesinski
[Rockbox.git] / firmware / system.c
blobda15ee11223161c23bc84dccdf4f44b3c6d7f8f4
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
19 #include <stdio.h>
20 #include "config.h"
21 #include <stdbool.h>
22 #include "lcd.h"
23 #include "font.h"
24 #include "system.h"
25 #include "kernel.h"
26 #include "timer.h"
28 #ifndef SIMULATOR
29 long cpu_frequency = CPU_FREQ;
30 #endif
32 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
33 int boost_counter = 0;
34 bool cpu_idle = false;
35 void cpu_boost(bool on_off)
37 if(on_off)
39 /* Boost the frequency if not already boosted */
40 if(boost_counter++ == 0)
42 set_cpu_frequency(CPUFREQ_MAX);
45 else
47 /* Lower the frequency if the counter reaches 0 */
48 if(--boost_counter == 0)
50 if(cpu_idle)
51 set_cpu_frequency(CPUFREQ_DEFAULT);
52 else
53 set_cpu_frequency(CPUFREQ_NORMAL);
56 /* Safety measure */
57 if(boost_counter < 0)
58 boost_counter = 0;
62 void cpu_idle_mode(bool on_off)
64 cpu_idle = on_off;
66 /* We need to adjust the frequency immediately if the CPU
67 isn't boosted */
68 if(boost_counter == 0)
70 if(cpu_idle)
71 set_cpu_frequency(CPUFREQ_DEFAULT);
72 else
73 set_cpu_frequency(CPUFREQ_NORMAL);
77 #endif
79 #if CONFIG_CPU == TCC730
81 void* volatile interrupt_vector[16] __attribute__ ((section(".idata")));
83 static void ddma_wait_idle(void) __attribute__ ((section (".icode")));
84 static void ddma_wait_idle(void)
86 /* TODO: power saving trick: set the CPU freq to 22MHz
87 while doing the busy wait after a disk dma access.
88 (Used by Archos) */
89 do {
90 } while ((DDMACOM & 3) != 0);
93 void ddma_transfer(int dir, int mem, void* intAddr, long extAddr, int num)
94 __attribute__ ((section (".icode")));
95 void ddma_transfer(int dir, int mem, void* intAddr, long extAddr, int num) {
96 int irq = set_irq_level(1);
97 ddma_wait_idle();
98 long externalAddress = (long) extAddr;
99 long internalAddress = ((long) intAddr) & 0xFFFF;
100 /* HW wants those two in word units. */
101 num /= 2;
102 externalAddress /= 2;
104 DDMACFG = (dir << 1) | (mem << 2);
105 DDMAIADR = internalAddress;
106 DDMAEADR = externalAddress;
107 DDMANUM = num;
108 DDMACOM |= 0x4; /* start */
110 ddma_wait_idle(); /* wait for completion */
111 set_irq_level(irq);
114 static void ddma_wait_idle_noicode(void)
116 do {
117 } while ((DDMACOM & 3) != 0);
120 static void ddma_transfer_noicode(int dir, int mem, long intAddr, long extAddr, int num) {
121 int irq = set_irq_level(1);
122 ddma_wait_idle_noicode();
123 long externalAddress = (long) extAddr;
124 long internalAddress = (long) intAddr;
125 /* HW wants those two in word units. */
126 num /= 2;
127 externalAddress /= 2;
129 DDMACFG = (dir << 1) | (mem << 2);
130 DDMAIADR = internalAddress;
131 DDMAEADR = externalAddress;
132 DDMANUM = num;
133 DDMACOM |= 0x4; /* start */
135 ddma_wait_idle_noicode(); /* wait for completion */
136 set_irq_level(irq);
139 /* Some linker-defined symbols */
140 extern int icodecopy;
141 extern int icodesize;
142 extern int icodestart;
144 /* change the a PLL frequency */
145 void set_pll_freq(int pll_index, long freq_out) {
146 volatile unsigned int* plldata;
147 volatile unsigned char* pllcon;
148 if (pll_index == 0) {
149 plldata = &PLL0DATA;
150 pllcon = &PLL0CON;
151 } else {
152 plldata = &PLL1DATA;
153 pllcon = &PLL1CON;
155 /* VC0 is 32768 Hz */
156 #define VC0FREQ (32768L)
157 unsigned m = (freq_out / VC0FREQ) - 2;
158 /* TODO: if m is too small here, use the divider bits [0,1] */
159 *plldata = m << 2;
160 *pllcon |= 0x1; /* activate */
161 do {
162 } while ((*pllcon & 0x2) == 0); /* wait for stabilization */
165 int smsc_version(void) {
166 int v;
167 int* smsc_ver_addr = (int*)0x4C20;
168 __asm__ ("ldc %0, @%1" : "=r"(v) : "a"(smsc_ver_addr));
169 v &= 0xFF;
170 if (v < 4 || v == 0xFF) {
171 return 3;
173 return v;
178 void smsc_delay() {
179 int i;
180 /* FIXME: tune the delay.
181 Delay doesn't depend on CPU speed in Archos' firmware.
183 for (i = 0; i < 100; i++) {
188 static void extra_init(void) {
189 /* Power on stuff */
190 P1 |= 0x07;
191 P1CON |= 0x1f;
193 /* P5 conf
194 * lines 0, 1 & 4 are digital, other analog. :
196 P5CON = 0xec;
198 P6CON = 0x19;
200 /* P7 conf
201 nothing to do: all are inputs
202 (reset value of the register is good)
205 /* SMSC chip config (?) */
206 P10CON |= 0x20;
207 P6 &= 0xF7;
208 P10 &= 0x20;
209 smsc_delay();
210 if (smsc_version() < 4) {
211 P6 |= 0x08;
212 P10 |= 0x20;
216 void set_cpu_frequency(long frequency) {
217 /* Enable SDRAM refresh, at least 15MHz */
218 if (frequency < cpu_frequency)
219 MIUDCNT = 0x800 | (frequency * 15/1000000L - 1);
221 set_pll_freq(0, frequency);
222 PLL0CON |= 0x4; /* use as CPU clock */
224 cpu_frequency = frequency;
225 /* wait states and such not changed by Archos. (!?) */
227 /* Enable SDRAM refresh, 15MHz. */
228 MIUDCNT = 0x800 | (frequency * 15/1000000L - 1);
230 tick_start(1000/HZ);
231 /* TODO: when uart is done; sync uart freq */
234 /* called by crt0 */
235 void system_init(void)
237 /* Disable watchdog */
238 WDTEN = 0xA5;
240 /****************
241 * GPIO ports
244 /* keep alive (?) -- clear the bit to prevent crash at start (??) */
245 P8 = 0x00;
246 P8CON = 0x01;
248 /* smsc chip init (?) */
249 P10 = 0x20;
250 P6 = 0x08;
252 P10CON = 0x20;
253 P6CON = 0x08;
255 /********
256 * CPU
260 /* PLL0 (cpu osc. frequency) */
261 /* set_cpu_frequency(CPU_FREQ); */
264 /*******************
265 * configure S(D)RAM
268 /************************
269 * Copy .icode section to icram
271 ddma_transfer_noicode(0, 0, 0x40, (long)&icodecopy, (int)&icodesize);
274 /***************************
275 * Interrupts
278 /* priorities ? */
280 /* mask */
281 IMR0 = 0;
282 IMR1 = 0;
285 /* IRQ0 BT INT */
286 /* IRQ1 RTC INT */
287 /* IRQ2 TA INT */
288 /* IRQ3 TAOV INT */
289 /* IRQ4 TB INT */
290 /* IRQ5 TBOV INT */
291 /* IRQ6 TC INT */
292 /* IRQ7 TCOV INT */
293 /* IRQ8 USB INT */
294 /* IRQ9 PPIC INT */
295 /* IRQ10 UART_Rx/UART_Err/ UART_tx INT */
296 /* IRQ11 IIC INT */
297 /* IRQ12 SIO INT */
298 /* IRQ13 IIS0 INT */
299 /* IRQ14 IIS1 INT */
300 /* IRQ15 ­ */
302 extra_init();
305 void system_reboot (void)
309 int system_memory_guard(int newmode)
311 (void)newmode;
312 return 0;
314 #elif defined(CPU_COLDFIRE)
316 #define default_interrupt(name) \
317 extern __attribute__((weak,alias("UIE"))) void name (void)
319 static const char* const irqname[] = {
320 "", "", "AccessErr","AddrErr","IllInstr", "", "","",
321 "PrivVio","Trace","Line-A", "Line-F","Debug","","FormErr","Uninit",
322 "","","","","","","","",
323 "Spurious","Level1","Level2","Level3","Level4","Level5","Level6","Level7",
324 "Trap0","Trap1","Trap2","Trap3","Trap4","Trap5","Trap6","Trap7",
325 "Trap8","Trap9","Trap10","Trap11","Trap12","Trap13","Trap14","Trap15",
326 "SWT","Timer0","Timer1","I2C","UART1","UART2","DMA0","DMA1",
327 "DMA2","DMA3","QSPI","","","","","",
328 "PDIR1FULL","PDIR2FULL","EBUTXEMPTY","IIS2TXEMPTY",
329 "IIS1TXEMPTY","PDIR3FULL","PDIR3RESYN","UQ2CHANERR",
330 "AUDIOTICK","PDIR2RESYN","PDIR2UNOV","PDIR1RESYN",
331 "PDIR1UNOV","UQ1CHANERR","IEC2BUFATTEN","IEC2PARERR",
332 "IEC2VALNOGOOD","IEC2CNEW","IEC1BUFATTEN","UCHANTXNF",
333 "UCHANTXUNDER","UCHANTXEMPTY","PDIR3UNOV","IEC1PARERR",
334 "IEC1VALNOGOOD","IEC1CNEW","EBUTXRESYN","EBUTXUNOV",
335 "IIS2TXRESYN","IIS2TXUNOV","IIS1TXRESYN","IIS1TXUNOV",
336 "GPIO0","GPI1","GPI2","GPI3","GPI4","GPI5","GPI6","GPI7",
337 "","","","","","","","SOFTINT0",
338 "SOFTINT1","SOFTINT2","SOFTINT3","",
339 "","CDROMCRCERR","CDROMNOSYNC","CDROMILSYNC",
340 "CDROMNEWBLK","","","","","","","",
341 "","","","","","","","",
342 "","","","","","","","",
343 "","","","","","","","",
344 "","","","","","","","",
345 "","","","","","","","",
346 "","","","","","","","",
347 "","","","","","","","",
348 "","","","","","","",""
351 default_interrupt (TRAP0); /* Trap #0 */
352 default_interrupt (TRAP1); /* Trap #1 */
353 default_interrupt (TRAP2); /* Trap #2 */
354 default_interrupt (TRAP3); /* Trap #3 */
355 default_interrupt (TRAP4); /* Trap #4 */
356 default_interrupt (TRAP5); /* Trap #5 */
357 default_interrupt (TRAP6); /* Trap #6 */
358 default_interrupt (TRAP7); /* Trap #7 */
359 default_interrupt (TRAP8); /* Trap #8 */
360 default_interrupt (TRAP9); /* Trap #9 */
361 default_interrupt (TRAP10); /* Trap #10 */
362 default_interrupt (TRAP11); /* Trap #11 */
363 default_interrupt (TRAP12); /* Trap #12 */
364 default_interrupt (TRAP13); /* Trap #13 */
365 default_interrupt (TRAP14); /* Trap #14 */
366 default_interrupt (TRAP15); /* Trap #15 */
367 default_interrupt (SWT); /* Software Watchdog Timer */
368 default_interrupt (TIMER0); /* Timer 0 */
369 default_interrupt (TIMER1); /* Timer 1 */
370 default_interrupt (I2C); /* I2C */
371 default_interrupt (UART1); /* UART 1 */
372 default_interrupt (UART2); /* UART 2 */
373 default_interrupt (DMA0); /* DMA 0 */
374 default_interrupt (DMA1); /* DMA 1 */
375 default_interrupt (DMA2); /* DMA 2 */
376 default_interrupt (DMA3); /* DMA 3 */
377 default_interrupt (QSPI); /* QSPI */
379 default_interrupt (PDIR1FULL); /* Processor data in 1 full */
380 default_interrupt (PDIR2FULL); /* Processor data in 2 full */
381 default_interrupt (EBUTXEMPTY); /* EBU transmit FIFO empty */
382 default_interrupt (IIS2TXEMPTY); /* IIS2 transmit FIFO empty */
383 default_interrupt (IIS1TXEMPTY); /* IIS1 transmit FIFO empty */
384 default_interrupt (PDIR3FULL); /* Processor data in 3 full */
385 default_interrupt (PDIR3RESYN); /* Processor data in 3 resync */
386 default_interrupt (UQ2CHANERR); /* IEC958-2 Rx U/Q channel error */
387 default_interrupt (AUDIOTICK); /* "tick" interrupt */
388 default_interrupt (PDIR2RESYN); /* Processor data in 2 resync */
389 default_interrupt (PDIR2UNOV); /* Processor data in 2 under/overrun */
390 default_interrupt (PDIR1RESYN); /* Processor data in 1 resync */
391 default_interrupt (PDIR1UNOV); /* Processor data in 1 under/overrun */
392 default_interrupt (UQ1CHANERR); /* IEC958-1 Rx U/Q channel error */
393 default_interrupt (IEC2BUFATTEN);/* IEC958-2 channel buffer full */
394 default_interrupt (IEC2PARERR); /* IEC958-2 Rx parity or symbol error */
395 default_interrupt (IEC2VALNOGOOD);/* IEC958-2 flag not good */
396 default_interrupt (IEC2CNEW); /* IEC958-2 New C-channel received */
397 default_interrupt (IEC1BUFATTEN);/* IEC958-1 channel buffer full */
398 default_interrupt (UCHANTXNF); /* U channel Tx reg next byte is first */
399 default_interrupt (UCHANTXUNDER);/* U channel Tx reg underrun */
400 default_interrupt (UCHANTXEMPTY);/* U channel Tx reg is empty */
401 default_interrupt (PDIR3UNOV); /* Processor data in 3 under/overrun */
402 default_interrupt (IEC1PARERR); /* IEC958-1 Rx parity or symbol error */
403 default_interrupt (IEC1VALNOGOOD);/* IEC958-1 flag not good */
404 default_interrupt (IEC1CNEW); /* IEC958-1 New C-channel received */
405 default_interrupt (EBUTXRESYN); /* EBU Tx FIFO resync */
406 default_interrupt (EBUTXUNOV); /* EBU Tx FIFO under/overrun */
407 default_interrupt (IIS2TXRESYN); /* IIS2 Tx FIFO resync */
408 default_interrupt (IIS2TXUNOV); /* IIS2 Tx FIFO under/overrun */
409 default_interrupt (IIS1TXRESYN); /* IIS1 Tx FIFO resync */
410 default_interrupt (IIS1TXUNOV); /* IIS1 Tx FIFO under/overrun */
411 default_interrupt (GPI0); /* GPIO interrupt 0 */
412 default_interrupt (GPI1); /* GPIO interrupt 1 */
413 default_interrupt (GPI2); /* GPIO interrupt 2 */
414 default_interrupt (GPI3); /* GPIO interrupt 3 */
415 default_interrupt (GPI4); /* GPIO interrupt 4 */
416 default_interrupt (GPI5); /* GPIO interrupt 5 */
417 default_interrupt (GPI6); /* GPIO interrupt 6 */
418 default_interrupt (GPI7); /* GPIO interrupt 7 */
420 default_interrupt (SOFTINT0); /* Software interrupt 0 */
421 default_interrupt (SOFTINT1); /* Software interrupt 1 */
422 default_interrupt (SOFTINT2); /* Software interrupt 2 */
423 default_interrupt (SOFTINT3); /* Software interrupt 3 */
425 default_interrupt (CDROMCRCERR); /* CD-ROM CRC error */
426 default_interrupt (CDROMNOSYNC); /* CD-ROM No sync */
427 default_interrupt (CDROMILSYNC); /* CD-ROM Illegal sync */
428 default_interrupt (CDROMNEWBLK); /* CD-ROM New block */
430 void UIE (void) /* Unexpected Interrupt or Exception */
432 unsigned int format_vector, pc;
433 int vector;
434 char str[32];
436 asm volatile ("move.l (52,%%sp),%0": "=r"(format_vector));
437 asm volatile ("move.l (56,%%sp),%0": "=r"(pc));
439 vector = (format_vector >> 18) & 0xff;
441 /* clear screen */
442 lcd_clear_display ();
443 #ifdef HAVE_LCD_BITMAP
444 lcd_setfont(FONT_SYSFIXED);
445 #endif
446 snprintf(str,sizeof(str),"I%02x:%s",vector,irqname[vector]);
447 lcd_puts(0,0,str);
448 snprintf(str,sizeof(str),"at %08x",pc);
449 lcd_puts(0,1,str);
450 lcd_update();
452 /* set cpu frequency to 11mhz (to prevent overheating) */
453 DCR = (DCR & ~0x01ff) | 1;
454 PLLCR = 0x10800000;
456 while (1)
458 /* check for the ON button (and !hold) */
459 if ((GPIO1_READ & 0x22) == 0)
460 SYPCR = 0xc0;
461 /* Start watchdog timer with 512 cycles timeout. Don't service it. */
463 /* We need a reset method that works in all cases. Calling system_reboot()
464 doesn't work when we're called from the debug interrupt, because then
465 the CPU is in emulator mode and the only ways leaving it are exexcuting
466 an rte instruction or performing a reset. Even disabling the breakpoint
467 logic and performing special rte magic doesn't make system_reboot()
468 reliable. The system restarts, but boot often fails with ata error -42. */
472 /* reset vectors are handled in crt0.S */
473 void (* const vbr[]) (void) __attribute__ ((section (".vectors"))) =
475 UIE,UIE,UIE,UIE,UIE,UIE,
476 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
477 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
478 UIE,UIE,UIE,TIMER0,TIMER1,UIE,UIE,UIE,
479 /* lvl 3 lvl 4 */
481 TRAP0,TRAP1,TRAP2,TRAP3,TRAP4,TRAP5,TRAP6,TRAP7,
482 TRAP8,TRAP9,TRAP10,TRAP11,TRAP12,TRAP13,TRAP14,TRAP15,
484 SWT,UIE,UIE,I2C,UART1,UART2,DMA0,DMA1,
485 DMA2,DMA3,QSPI,UIE,UIE,UIE,UIE,UIE,
486 PDIR1FULL,PDIR2FULL,EBUTXEMPTY,IIS2TXEMPTY,
487 IIS1TXEMPTY,PDIR3FULL,PDIR3RESYN,UQ2CHANERR,
488 AUDIOTICK,PDIR2RESYN,PDIR2UNOV,PDIR1RESYN,
489 PDIR1UNOV,UQ1CHANERR,IEC2BUFATTEN,IEC2PARERR,
490 IEC2VALNOGOOD,IEC2CNEW,IEC1BUFATTEN,UCHANTXNF,
491 UCHANTXUNDER,UCHANTXEMPTY,PDIR3UNOV,IEC1PARERR,
492 IEC1VALNOGOOD,IEC1CNEW,EBUTXRESYN,EBUTXUNOV,
493 IIS2TXRESYN,IIS2TXUNOV,IIS1TXRESYN,IIS1TXUNOV,
494 GPI0,GPI1,GPI2,GPI3,GPI4,GPI5,GPI6,GPI7,
495 UIE,UIE,UIE,UIE,UIE,UIE,UIE,SOFTINT0,
496 SOFTINT1,SOFTINT2,SOFTINT3,UIE,
497 UIE,CDROMCRCERR,CDROMNOSYNC,CDROMILSYNC,
498 CDROMNEWBLK,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
500 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
501 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
502 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
503 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
504 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
505 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
506 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
507 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE
510 void system_init(void)
512 /* Clear the accumulators. From here on it's the responsibility of
513 whoever uses them to clear them after use (use movclr instruction). */
514 asm volatile ("movclr.l %%acc0, %%d0\n\t"
515 "movclr.l %%acc1, %%d0\n\t"
516 "movclr.l %%acc2, %%d0\n\t"
517 "movclr.l %%acc3, %%d0\n\t"
518 : : : "d0");
521 void system_reboot (void)
523 set_cpu_frequency(0);
525 asm(" move.w #0x2700,%sr");
526 /* Reset the cookie for the crt0 crash check */
527 asm(" move.l #0,%d0");
528 asm(" move.l %d0,0x10017ffc");
529 asm(" movec.l %d0,%vbr");
530 asm(" move.l 0,%sp");
531 asm(" move.l 4,%a0");
532 asm(" jmp (%a0)");
535 /* Utilise the breakpoint hardware to catch invalid memory accesses. */
536 int system_memory_guard(int newmode)
538 static const unsigned long modes[MAXMEMGUARD][8] = {
539 { /* catch nothing */
540 0x2C870000, 0x00000000, /* TDR = 0x00000000 */
541 0x2C8D0000, 0x00000000, /* ABLR = 0x00000000 */
542 0x2C8C0000, 0x00000000, /* ABHR = 0x00000000 */
543 0x2C860000, 0x00050000, /* AATR = 0x0005 */
545 { /* catch flash ROM writes */
546 0x2C8D0000, 0x00000000, /* ABLR = 0x00000000 */
547 0x2C8C0FFF, 0xFFFF0000, /* ABHR = 0x0FFFFFFF */
548 0x2C860000, 0x6F050000, /* AATR = 0x6F05 */
549 0x2C878000, 0x20080000, /* TDR = 0x80002008 */
551 { /* catch all accesses to zero area */
552 0x2C8D0000, 0x00000000, /* ABLR = 0x00000000 */
553 0x2C8C0FFF, 0xFFFF0000, /* ABHR = 0x0FFFFFFF */
554 0x2C860000, 0xEF050000, /* AATR = 0xEF05 */
555 0x2C878000, 0x20080000, /* TDR = 0x80002008 */
557 /* Note: CPU space accesses (movec instruction), interrupt acknowledges
558 and emulator mode accesses are never caught. */
560 static int cur_mode = MEMGUARD_NONE;
562 int oldmode = cur_mode;
563 const unsigned long *ptr;
564 int i;
566 if (newmode == MEMGUARD_KEEP)
567 newmode = oldmode;
569 /* Always set the new mode, we don't know the old settings
570 as we cannot read back */
571 ptr = modes[newmode];
572 for (i = 0; i < 4; i++)
574 asm ( "wdebug (%0) \n" : : "a"(ptr));
575 ptr += 2;
577 cur_mode = newmode;
579 return oldmode;
582 #ifdef IRIVER_H100
583 #define MAX_REFRESH_TIMER 59
584 #define NORMAL_REFRESH_TIMER 21
585 #define DEFAULT_REFRESH_TIMER 4
586 #else
587 #define MAX_REFRESH_TIMER 29
588 #define NORMAL_REFRESH_TIMER 10
589 #define DEFAULT_REFRESH_TIMER 1
590 #endif
592 void set_cpu_frequency (long) __attribute__ ((section (".icode")));
593 void set_cpu_frequency(long frequency)
595 switch(frequency)
597 case CPUFREQ_MAX:
598 DCR = (0x8200 | DEFAULT_REFRESH_TIMER);
599 /* Refresh timer for bypass frequency */
600 PLLCR &= ~1; /* Bypass mode */
601 timers_adjust_prescale(CPUFREQ_DEFAULT_MULT, false);
602 PLLCR = 0x11856005;
603 CSCR0 = 0x00001180; /* Flash: 4 wait states */
604 CSCR1 = 0x00000980; /* LCD: 2 wait states */
605 while(!(PLLCR & 0x80000000)) {}; /* Wait until the PLL has locked.
606 This may take up to 10ms! */
607 timers_adjust_prescale(CPUFREQ_MAX_MULT, true);
608 DCR = (0x8200 | MAX_REFRESH_TIMER); /* Refresh timer */
609 cpu_frequency = CPUFREQ_MAX;
610 IDECONFIG1 = 0x106000 | (5 << 10); /* BUFEN2 enable + CS2Pre/CS2Post */
611 IDECONFIG2 = 0x40000 | (1 << 8); /* TA enable + CS2wait */
612 break;
614 case CPUFREQ_NORMAL:
615 DCR = (DCR & ~0x01ff) | DEFAULT_REFRESH_TIMER;
616 /* Refresh timer for bypass frequency */
617 PLLCR &= ~1; /* Bypass mode */
618 timers_adjust_prescale(CPUFREQ_DEFAULT_MULT, false);
619 PLLCR = 0x1385e005;
620 CSCR0 = 0x00000580; /* Flash: 1 wait state */
621 CSCR1 = 0x00000180; /* LCD: 0 wait states */
622 while(!(PLLCR & 0x80000000)) {}; /* Wait until the PLL has locked.
623 This may take up to 10ms! */
624 timers_adjust_prescale(CPUFREQ_NORMAL_MULT, true);
625 DCR = (0x8000 | NORMAL_REFRESH_TIMER); /* Refresh timer */
626 cpu_frequency = CPUFREQ_NORMAL;
627 IDECONFIG1 = 0x106000 | (5 << 10); /* BUFEN2 enable + CS2Pre/CS2Post */
628 IDECONFIG2 = 0x40000 | (0 << 8); /* TA enable + CS2wait */
629 break;
630 default:
631 DCR = (DCR & ~0x01ff) | DEFAULT_REFRESH_TIMER;
632 /* Refresh timer for bypass frequency */
633 PLLCR &= ~1; /* Bypass mode */
634 timers_adjust_prescale(CPUFREQ_DEFAULT_MULT, true);
635 PLLCR = 0x10800200; /* Power down PLL, but keep CLSEL and CRSEL */
636 CSCR0 = 0x00000180; /* Flash: 0 wait states */
637 CSCR1 = 0x00000180; /* LCD: 0 wait states */
638 DCR = (0x8000 | DEFAULT_REFRESH_TIMER); /* Refresh timer */
639 cpu_frequency = CPUFREQ_DEFAULT;
640 IDECONFIG1 = 0x106000 | (1 << 10); /* BUFEN2 enable + CS2Pre/CS2Post */
641 IDECONFIG2 = 0x40000 | (0 << 8); /* TA enable + CS2wait */
642 break;
647 #elif CONFIG_CPU == SH7034
648 #include "led.h"
649 #include "system.h"
650 #include "rolo.h"
652 #define default_interrupt(name,number) \
653 extern __attribute__((weak,alias("UIE" #number))) void name (void); void UIE##number (void)
654 #define reserve_interrupt(number) \
655 void UIE##number (void)
657 static const char* const irqname[] = {
658 "", "", "", "", "IllInstr", "", "IllSltIn","","",
659 "CPUAdrEr", "DMAAdrEr", "NMI", "UserBrk",
660 "","","","","","","","","","","","","","","","","","","",
661 "Trap32","Trap33","Trap34","Trap35","Trap36","Trap37","Trap38","Trap39",
662 "Trap40","Trap41","Trap42","Trap43","Trap44","Trap45","Trap46","Trap47",
663 "Trap48","Trap49","Trap50","Trap51","Trap52","Trap53","Trap54","Trap55",
664 "Trap56","Trap57","Trap58","Trap59","Trap60","Trap61","Trap62","Trap63",
665 "Irq0","Irq1","Irq2","Irq3","Irq4","Irq5","Irq6","Irq7",
666 "Dma0","","Dma1","","Dma2","","Dma3","",
667 "IMIA0","IMIB0","OVI0","", "IMIA1","IMIB1","OVI1","",
668 "IMIA2","IMIB2","OVI2","", "IMIA3","IMIB3","OVI3","",
669 "IMIA4","IMIB4","OVI4","",
670 "Ser0Err","Ser0Rx","Ser0Tx","Ser0TE",
671 "Ser1Err","Ser1Rx","Ser1Tx","Ser1TE",
672 "ParityEr","A/D conv","","","Watchdog","DRAMRefr"
675 reserve_interrupt ( 0);
676 reserve_interrupt ( 1);
677 reserve_interrupt ( 2);
678 reserve_interrupt ( 3);
679 default_interrupt (GII, 4);
680 reserve_interrupt ( 5);
681 default_interrupt (ISI, 6);
682 reserve_interrupt ( 7);
683 reserve_interrupt ( 8);
684 default_interrupt (CPUAE, 9);
685 default_interrupt (DMAAE, 10);
686 default_interrupt (NMI, 11);
687 default_interrupt (UB, 12);
688 reserve_interrupt ( 13);
689 reserve_interrupt ( 14);
690 reserve_interrupt ( 15);
691 reserve_interrupt ( 16); /* TCB #0 */
692 reserve_interrupt ( 17); /* TCB #1 */
693 reserve_interrupt ( 18); /* TCB #2 */
694 reserve_interrupt ( 19); /* TCB #3 */
695 reserve_interrupt ( 20); /* TCB #4 */
696 reserve_interrupt ( 21); /* TCB #5 */
697 reserve_interrupt ( 22); /* TCB #6 */
698 reserve_interrupt ( 23); /* TCB #7 */
699 reserve_interrupt ( 24); /* TCB #8 */
700 reserve_interrupt ( 25); /* TCB #9 */
701 reserve_interrupt ( 26); /* TCB #10 */
702 reserve_interrupt ( 27); /* TCB #11 */
703 reserve_interrupt ( 28); /* TCB #12 */
704 reserve_interrupt ( 29); /* TCB #13 */
705 reserve_interrupt ( 30); /* TCB #14 */
706 reserve_interrupt ( 31); /* TCB #15 */
707 default_interrupt (TRAPA32, 32);
708 default_interrupt (TRAPA33, 33);
709 default_interrupt (TRAPA34, 34);
710 default_interrupt (TRAPA35, 35);
711 default_interrupt (TRAPA36, 36);
712 default_interrupt (TRAPA37, 37);
713 default_interrupt (TRAPA38, 38);
714 default_interrupt (TRAPA39, 39);
715 default_interrupt (TRAPA40, 40);
716 default_interrupt (TRAPA41, 41);
717 default_interrupt (TRAPA42, 42);
718 default_interrupt (TRAPA43, 43);
719 default_interrupt (TRAPA44, 44);
720 default_interrupt (TRAPA45, 45);
721 default_interrupt (TRAPA46, 46);
722 default_interrupt (TRAPA47, 47);
723 default_interrupt (TRAPA48, 48);
724 default_interrupt (TRAPA49, 49);
725 default_interrupt (TRAPA50, 50);
726 default_interrupt (TRAPA51, 51);
727 default_interrupt (TRAPA52, 52);
728 default_interrupt (TRAPA53, 53);
729 default_interrupt (TRAPA54, 54);
730 default_interrupt (TRAPA55, 55);
731 default_interrupt (TRAPA56, 56);
732 default_interrupt (TRAPA57, 57);
733 default_interrupt (TRAPA58, 58);
734 default_interrupt (TRAPA59, 59);
735 default_interrupt (TRAPA60, 60);
736 default_interrupt (TRAPA61, 61);
737 default_interrupt (TRAPA62, 62);
738 default_interrupt (TRAPA63, 63);
739 default_interrupt (IRQ0, 64);
740 default_interrupt (IRQ1, 65);
741 default_interrupt (IRQ2, 66);
742 default_interrupt (IRQ3, 67);
743 default_interrupt (IRQ4, 68);
744 default_interrupt (IRQ5, 69);
745 default_interrupt (IRQ6, 70);
746 default_interrupt (IRQ7, 71);
747 default_interrupt (DEI0, 72);
748 reserve_interrupt ( 73);
749 default_interrupt (DEI1, 74);
750 reserve_interrupt ( 75);
751 default_interrupt (DEI2, 76);
752 reserve_interrupt ( 77);
753 default_interrupt (DEI3, 78);
754 reserve_interrupt ( 79);
755 default_interrupt (IMIA0, 80);
756 default_interrupt (IMIB0, 81);
757 default_interrupt (OVI0, 82);
758 reserve_interrupt ( 83);
759 default_interrupt (IMIA1, 84);
760 default_interrupt (IMIB1, 85);
761 default_interrupt (OVI1, 86);
762 reserve_interrupt ( 87);
763 default_interrupt (IMIA2, 88);
764 default_interrupt (IMIB2, 89);
765 default_interrupt (OVI2, 90);
766 reserve_interrupt ( 91);
767 default_interrupt (IMIA3, 92);
768 default_interrupt (IMIB3, 93);
769 default_interrupt (OVI3, 94);
770 reserve_interrupt ( 95);
771 default_interrupt (IMIA4, 96);
772 default_interrupt (IMIB4, 97);
773 default_interrupt (OVI4, 98);
774 reserve_interrupt ( 99);
775 default_interrupt (REI0, 100);
776 default_interrupt (RXI0, 101);
777 default_interrupt (TXI0, 102);
778 default_interrupt (TEI0, 103);
779 default_interrupt (REI1, 104);
780 default_interrupt (RXI1, 105);
781 default_interrupt (TXI1, 106);
782 default_interrupt (TEI1, 107);
783 reserve_interrupt ( 108);
784 default_interrupt (ADITI, 109);
786 /* reset vectors are handled in crt0.S */
787 void (*vbr[]) (void) __attribute__ ((section (".vectors"))) =
789 GII, /*** 4 General Illegal Instruction ***/
790 UIE5, /*** 5 Reserved ***/
791 ISI, /*** 6 Illegal Slot Instruction ***/
792 UIE7, /*** 7-8 Reserved ***/
793 UIE8,
794 CPUAE, /*** 9 CPU Address Error ***/
795 DMAAE, /*** 10 DMA Address Error ***/
796 NMI, /*** 11 NMI ***/
797 UB, /*** 12 User Break ***/
799 /*** 13-31 Reserved ***/
800 UIE13,UIE14,UIE15,UIE16,UIE17,UIE18,UIE19,UIE20,
801 UIE21,UIE22,UIE23,UIE24,UIE25,UIE26,UIE27,UIE28,
802 UIE29,UIE30,UIE31,
804 /*** 32-63 TRAPA #20...#3F ***/
805 TRAPA32,TRAPA33,TRAPA34,TRAPA35,TRAPA36,TRAPA37,TRAPA38,TRAPA39,
806 TRAPA40,TRAPA41,TRAPA42,TRAPA43,TRAPA44,TRAPA45,TRAPA46,TRAPA47,
807 TRAPA48,TRAPA49,TRAPA50,TRAPA51,TRAPA52,TRAPA53,TRAPA54,TRAPA55,
808 TRAPA56,TRAPA57,TRAPA58,TRAPA59,TRAPA60,TRAPA61,TRAPA62,TRAPA63,
810 /*** 64-71 IRQ0-7 ***/
811 IRQ0,IRQ1,IRQ2,IRQ3,IRQ4,IRQ5,IRQ6,IRQ7,
813 DEI0, /*** 72 DMAC0 ***/
814 UIE73, /*** 73 Reserved ***/
815 DEI1, /*** 74 DMAC1 ***/
816 UIE75, /*** 75 Reserved ***/
817 DEI2, /*** 76 DMAC2 ***/
818 UIE77, /*** 77 Reserved ***/
819 DEI3, /*** 78 DMAC3 ***/
820 UIE79, /*** 79 Reserved ***/
821 IMIA0, /*** 80-82 ITU0 ***/
822 IMIB0,
823 OVI0,
824 UIE83, /*** 83 Reserved ***/
825 IMIA1, /*** 84-86 ITU1 ***/
826 IMIB1,
827 OVI1,
828 UIE87, /*** 87 Reserved ***/
829 IMIA2, /*** 88-90 ITU2 ***/
830 IMIB2,
831 OVI2,
832 UIE91, /*** 91 Reserved ***/
833 IMIA3, /*** 92-94 ITU3 ***/
834 IMIB3,
835 OVI3,
836 UIE95, /*** 95 Reserved ***/
837 IMIA4, /*** 96-98 ITU4 ***/
838 IMIB4,
839 OVI4,
840 UIE99, /*** 99 Reserved ***/
842 /*** 100-103 SCI0 ***/
843 REI0,RXI0,TXI0,TEI0,
845 /*** 104-107 SCI1 ***/
846 REI1,RXI1,TXI1,TEI1,
848 UIE108, /*** 108 Parity Control Unit ***/
849 ADITI /*** 109 AD Converter ***/
853 void UIE (unsigned int pc) /* Unexpected Interrupt or Exception */
855 #if CONFIG_LED == LED_REAL
856 bool state = true;
857 #endif
858 unsigned int n;
859 char str[32];
861 asm volatile ("sts\tpr,%0" : "=r"(n));
863 /* clear screen */
864 lcd_clear_display ();
865 #ifdef HAVE_LCD_BITMAP
866 lcd_setfont(FONT_SYSFIXED);
867 #endif
868 /* output exception */
869 n = (n - (unsigned)UIE0 - 4)>>2; /* get exception or interrupt number */
870 snprintf(str,sizeof(str),"I%02x:%s",n,irqname[n]);
871 lcd_puts(0,0,str);
872 snprintf(str,sizeof(str),"at %08x",pc);
873 lcd_puts(0,1,str);
875 #ifdef HAVE_LCD_BITMAP
876 lcd_update ();
877 #endif
879 while (1)
881 #if CONFIG_LED == LED_REAL
882 volatile int i;
883 led (state);
884 state = !state;
886 for (i = 0; i < 240000; ++i);
887 #endif
889 /* try to restart firmware if ON is pressed */
890 #if CONFIG_KEYPAD == PLAYER_PAD
891 if (!(PADRL & 0x20))
892 #elif CONFIG_KEYPAD == RECORDER_PAD
893 #ifdef HAVE_FMADC
894 if (!(PCDR & 0x0008))
895 #else
896 if (!(PBDRH & 0x01))
897 #endif
898 #elif CONFIG_KEYPAD == ONDIO_PAD
899 if (!(PCDR & 0x0008))
900 #endif
902 /* enable the watchguard timer, but don't service it */
903 RSTCSR_W = 0x5a40; /* Reset enabled, power-on reset */
904 TCSR_W = 0xa560; /* Watchdog timer mode, timer enabled, sysclk/2 */
909 asm (
910 "_UIE0:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
911 "_UIE1:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
912 "_UIE2:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
913 "_UIE3:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
914 "_UIE4:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
915 "_UIE5:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
916 "_UIE6:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
917 "_UIE7:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
918 "_UIE8:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
919 "_UIE9:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
920 "_UIE10:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
921 "_UIE11:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
922 "_UIE12:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
923 "_UIE13:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
924 "_UIE14:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
925 "_UIE15:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
926 "_UIE16:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
927 "_UIE17:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
928 "_UIE18:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
929 "_UIE19:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
930 "_UIE20:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
931 "_UIE21:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
932 "_UIE22:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
933 "_UIE23:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
934 "_UIE24:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
935 "_UIE25:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
936 "_UIE26:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
937 "_UIE27:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
938 "_UIE28:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
939 "_UIE29:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
940 "_UIE30:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
941 "_UIE31:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
942 "_UIE32:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
943 "_UIE33:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
944 "_UIE34:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
945 "_UIE35:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
946 "_UIE36:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
947 "_UIE37:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
948 "_UIE38:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
949 "_UIE39:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
950 "_UIE40:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
951 "_UIE41:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
952 "_UIE42:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
953 "_UIE43:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
954 "_UIE44:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
955 "_UIE45:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
956 "_UIE46:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
957 "_UIE47:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
958 "_UIE48:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
959 "_UIE49:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
960 "_UIE50:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
961 "_UIE51:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
962 "_UIE52:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
963 "_UIE53:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
964 "_UIE54:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
965 "_UIE55:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
966 "_UIE56:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
967 "_UIE57:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
968 "_UIE58:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
969 "_UIE59:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
970 "_UIE60:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
971 "_UIE61:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
972 "_UIE62:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
973 "_UIE63:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
974 "_UIE64:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
975 "_UIE65:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
976 "_UIE66:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
977 "_UIE67:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
978 "_UIE68:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
979 "_UIE69:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
980 "_UIE70:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
981 "_UIE71:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
982 "_UIE72:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
983 "_UIE73:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
984 "_UIE74:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
985 "_UIE75:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
986 "_UIE76:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
987 "_UIE77:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
988 "_UIE78:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
989 "_UIE79:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
990 "_UIE80:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
991 "_UIE81:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
992 "_UIE82:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
993 "_UIE83:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
994 "_UIE84:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
995 "_UIE85:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
996 "_UIE86:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
997 "_UIE87:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
998 "_UIE88:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
999 "_UIE89:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
1000 "_UIE90:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
1001 "_UIE91:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
1002 "_UIE92:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
1003 "_UIE93:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
1004 "_UIE94:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
1005 "_UIE95:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
1006 "_UIE96:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
1007 "_UIE97:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
1008 "_UIE98:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
1009 "_UIE99:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
1010 "_UIE100:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
1011 "_UIE101:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
1012 "_UIE102:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
1013 "_UIE103:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
1014 "_UIE104:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
1015 "_UIE105:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
1016 "_UIE106:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
1017 "_UIE107:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
1018 "_UIE108:\tbsr\t_UIE\n\tmov.l\t@r15+,r4\t\n"
1019 "_UIE109:\tbsr\t_UIE\n\tmov.l\t@r15+,r4");
1021 void system_init(void)
1023 /* Disable all interrupts */
1024 IPRA = 0;
1025 IPRB = 0;
1026 IPRC = 0;
1027 IPRD = 0;
1028 IPRE = 0;
1030 /* NMI level low, falling edge on all interrupts */
1031 ICR = 0;
1033 /* Enable burst and RAS down mode on DRAM */
1034 DCR |= 0x5000;
1036 /* Activate Warp mode (simultaneous internal and external mem access) */
1037 BCR |= 0x2000;
1039 /* Bus state controller initializations. These are only necessary when
1040 running from flash. */
1041 WCR1 = 0x40FD; /* Long wait states for CS6 (ATA), short for the rest. */
1042 WCR3 = 0x8000; /* WAIT is pulled up, 1 state inserted for CS6 */
1045 void system_reboot (void)
1047 set_irq_level(HIGHEST_IRQ_LEVEL);
1049 asm volatile ("ldc\t%0,vbr" : : "r"(0));
1051 PACR2 |= 0x4000; /* for coldstart detection */
1052 IPRA = 0;
1053 IPRB = 0;
1054 IPRC = 0;
1055 IPRD = 0;
1056 IPRE = 0;
1057 ICR = 0;
1059 asm volatile ("jmp @%0; mov.l @%1,r15" : :
1060 "r"(*(int*)0),"r"(4));
1063 /* Utilise the user break controller to catch invalid memory accesses. */
1064 int system_memory_guard(int newmode)
1066 static const struct {
1067 unsigned long addr;
1068 unsigned long mask;
1069 unsigned short bbr;
1070 } modes[MAXMEMGUARD] = {
1071 /* catch nothing */
1072 { 0x00000000, 0x00000000, 0x0000 },
1073 /* catch writes to area 02 (flash ROM) */
1074 { 0x02000000, 0x00FFFFFF, 0x00F8 },
1075 /* catch all accesses to areas 00 (internal ROM) and 01 (free) */
1076 { 0x00000000, 0x01FFFFFF, 0x00FC }
1079 int oldmode = MEMGUARD_NONE;
1080 int i;
1082 /* figure out the old mode from what is in the UBC regs. If the register
1083 values don't match any mode, assume MEMGUARD_NONE */
1084 for (i = MEMGUARD_NONE; i < MAXMEMGUARD; i++)
1086 if (BAR == modes[i].addr && BAMR == modes[i].mask &&
1087 BBR == modes[i].bbr)
1089 oldmode = i;
1090 break;
1094 if (newmode == MEMGUARD_KEEP)
1095 newmode = oldmode;
1097 BBR = 0; /* switch off everything first */
1099 /* always set the UBC according to the mode, in case the old settings
1100 didn't match any valid mode */
1101 BAR = modes[newmode].addr;
1102 BAMR = modes[newmode].mask;
1103 BBR = modes[newmode].bbr;
1105 return oldmode;
1107 #elif CONFIG_CPU==PP5020
1109 #ifndef BOOTLOADER
1110 extern void TIMER1(void);
1111 extern void ipod_4g_button_int(void);
1113 void irq(void)
1115 if (PP5020_CPU_INT_STAT & PP5020_TIMER1_MASK)
1116 TIMER1();
1117 else if (PP5020_CPU_HI_INT_STAT & PP5020_I2C_MASK)
1118 ipod_4g_button_int();
1120 #endif
1122 /* TODO: The following two function have been lifted straight from IPL, and
1123 hence have a lot of numeric addresses used straight. I'd like to use
1124 #defines for these, but don't know what most of them are for or even what
1125 they should be named. Because of this I also have no way of knowing how
1126 to extend the funtions to do alternate cache configurations and/or
1127 some other CPU frequency scaling. */
1129 #ifndef BOOTLOADER
1130 static void ipod_init_cache(void)
1132 /* Initialising the cache in the iPod bootloader prevents Rockbox from starting */
1133 unsigned i;
1135 /* cache init mode? */
1136 outl(0x4, 0x6000C000);
1138 /* PP5002 has 8KB cache */
1139 for (i = 0xf0004000; i < 0xf0006000; i += 16) {
1140 outl(0x0, i);
1143 outl(0x0, 0xf000f040);
1144 outl(0x3fc0, 0xf000f044);
1146 /* enable cache */
1147 outl(0x1, 0x6000C000);
1149 for (i = 0x10000000; i < 0x10002000; i += 16)
1150 inb(i);
1153 static void ipod_set_cpu_speed(void)
1155 outl(inl(0x70000020) | (1<<30), 0x70000020);
1157 /* Set run state to 24MHz */
1158 outl((inl(0x60006020) & 0x0fffff0f) | 0x20000020, 0x60006020);
1160 /* 75 MHz (24/8)*25 */
1161 outl(0xaa021908, 0x60006034);
1162 udelay(2000);
1164 outl((inl(0x60006020) & 0x0fffff0f) | 0x20000070, 0x60006020);
1166 #endif
1168 void system_init(void)
1170 #ifndef BOOTLOADER
1171 /* disable all irqs */
1172 outl(-1, 0x60001138);
1173 outl(-1, 0x60001128);
1174 outl(-1, 0x6000111c);
1176 outl(-1, 0x60001038);
1177 outl(-1, 0x60001028);
1178 outl(-1, 0x6000101c);
1179 ipod_set_cpu_speed();
1180 ipod_init_cache();
1181 #endif
1184 void system_reboot(void)
1188 int system_memory_guard(int newmode)
1190 (void)newmode;
1191 return 0;
1194 #elif CONFIG_CPU==PNX0101
1196 interrupt_handler_t interrupt_vector[0x1d] __attribute__ ((section(".idata")));
1198 #define IRQ_REG(reg) (*(volatile unsigned long *)(0x80300000 + (reg)))
1200 static inline unsigned long irq_read(int reg)
1202 unsigned long v, v2;
1205 v = IRQ_REG(reg);
1206 v2 = IRQ_REG(reg);
1207 } while (v != v2);
1208 return v;
1211 #define IRQ_WRITE_WAIT(reg, val, cond) \
1212 do { unsigned long v, v2; \
1213 do { \
1214 IRQ_REG(reg) = (val); \
1215 v = IRQ_REG(reg); \
1216 v2 = IRQ_REG(reg); \
1217 } while ((v != v2) || !(cond)); \
1218 } while (0);
1220 static void UIE(void) {}
1222 void irq(void)
1224 int n = irq_read(0x100) >> 3;
1225 (*(interrupt_vector[n]))();
1228 void irq_enable_int(int n)
1230 IRQ_WRITE_WAIT(0x404 + n * 4, 0x4010000, v & 0x10000);
1233 void irq_set_int_handler(int n, interrupt_handler_t handler)
1235 interrupt_vector[n + 1] = handler;
1238 void system_init(void)
1240 int i;
1242 /* turn off watchdog */
1243 (*(volatile unsigned long *)0x80002804) = 0;
1246 IRQ_WRITE_WAIT(0x100, 0, v == 0);
1247 IRQ_WRITE_WAIT(0x104, 0, v == 0);
1248 IRQ_WRITE_WAIT(0, 0, v == 0);
1249 IRQ_WRITE_WAIT(4, 0, v == 0);
1252 for (i = 0; i < 0x1c; i++)
1254 IRQ_WRITE_WAIT(0x404 + i * 4, 0x1e000001, (v & 0x3010f) == 1);
1255 IRQ_WRITE_WAIT(0x404 + i * 4, 0x4000000, (v & 0x10000) == 0);
1256 IRQ_WRITE_WAIT(0x404 + i * 4, 0x10000001, (v & 0xf) == 1);
1257 interrupt_vector[i + 1] = UIE;
1259 interrupt_vector[0] = UIE;
1263 void system_reboot(void)
1265 (*(volatile unsigned long *)0x80002804) = 1;
1266 while (1);
1269 int system_memory_guard(int newmode)
1271 (void)newmode;
1272 return 0;
1275 #endif /* CONFIG_CPU */