From f29cae0d26e21e35f71845b6726aca3b81aa6a77 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Mon, 30 Oct 2006 14:17:14 +0000 Subject: Moved coldfire code in system.c and system.h into target tree. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11399 a1c6a512-1295-4272-9138-f99709370657 --- firmware/target/coldfire/system-coldfire.c | 296 +++++++++++++++++++++++++++++ 1 file changed, 296 insertions(+) create mode 100644 firmware/target/coldfire/system-coldfire.c (limited to 'firmware/target/coldfire/system-coldfire.c') diff --git a/firmware/target/coldfire/system-coldfire.c b/firmware/target/coldfire/system-coldfire.c new file mode 100644 index 0000000000..a3bae33a7e --- /dev/null +++ b/firmware/target/coldfire/system-coldfire.c @@ -0,0 +1,296 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 by Alan Korr + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include +#include "config.h" +#include "system.h" +#include "lcd.h" +#include "font.h" + +#define default_interrupt(name) \ + extern __attribute__((weak,alias("UIE"))) void name (void) + +static const char* const irqname[] = { + "", "", "AccessErr","AddrErr","IllInstr", "", "","", + "PrivVio","Trace","Line-A", "Line-F","Debug","","FormErr","Uninit", + "","","","","","","","", + "Spurious","Level1","Level2","Level3","Level4","Level5","Level6","Level7", + "Trap0","Trap1","Trap2","Trap3","Trap4","Trap5","Trap6","Trap7", + "Trap8","Trap9","Trap10","Trap11","Trap12","Trap13","Trap14","Trap15", + "SWT","Timer0","Timer1","I2C","UART1","UART2","DMA0","DMA1", + "DMA2","DMA3","QSPI","","","","","", + "PDIR1FULL","PDIR2FULL","EBUTXEMPTY","IIS2TXEMPTY", + "IIS1TXEMPTY","PDIR3FULL","PDIR3RESYN","UQ2CHANERR", + "AUDIOTICK","PDIR2RESYN","PDIR2UNOV","PDIR1RESYN", + "PDIR1UNOV","UQ1CHANERR","IEC2BUFATTEN","IEC2PARERR", + "IEC2VALNOGOOD","IEC2CNEW","IEC1BUFATTEN","UCHANTXNF", + "UCHANTXUNDER","UCHANTXEMPTY","PDIR3UNOV","IEC1PARERR", + "IEC1VALNOGOOD","IEC1CNEW","EBUTXRESYN","EBUTXUNOV", + "IIS2TXRESYN","IIS2TXUNOV","IIS1TXRESYN","IIS1TXUNOV", + "GPI0","GPI1","GPI2","GPI3","GPI4","GPI5","GPI6","GPI7", + "","","","","","","","SOFTINT0", + "SOFTINT1","SOFTINT2","SOFTINT3","", + "","CDROMCRCERR","CDROMNOSYNC","CDROMILSYNC", + "CDROMNEWBLK","","","","","","","", + "","","","","","","","", + "","","","","","","","", + "","","","","","","","", + "","","","","","","","", + "","","","","","","","", + "","","","","","","","", + "","","","","","","","", + "","","","","","","","" +}; + +default_interrupt (TRAP0); /* Trap #0 */ +default_interrupt (TRAP1); /* Trap #1 */ +default_interrupt (TRAP2); /* Trap #2 */ +default_interrupt (TRAP3); /* Trap #3 */ +default_interrupt (TRAP4); /* Trap #4 */ +default_interrupt (TRAP5); /* Trap #5 */ +default_interrupt (TRAP6); /* Trap #6 */ +default_interrupt (TRAP7); /* Trap #7 */ +default_interrupt (TRAP8); /* Trap #8 */ +default_interrupt (TRAP9); /* Trap #9 */ +default_interrupt (TRAP10); /* Trap #10 */ +default_interrupt (TRAP11); /* Trap #11 */ +default_interrupt (TRAP12); /* Trap #12 */ +default_interrupt (TRAP13); /* Trap #13 */ +default_interrupt (TRAP14); /* Trap #14 */ +default_interrupt (TRAP15); /* Trap #15 */ +default_interrupt (SWT); /* Software Watchdog Timer */ +default_interrupt (TIMER0); /* Timer 0 */ +default_interrupt (TIMER1); /* Timer 1 */ +default_interrupt (I2C); /* I2C */ +default_interrupt (UART1); /* UART 1 */ +default_interrupt (UART2); /* UART 2 */ +default_interrupt (DMA0); /* DMA 0 */ +default_interrupt (DMA1); /* DMA 1 */ +default_interrupt (DMA2); /* DMA 2 */ +default_interrupt (DMA3); /* DMA 3 */ +default_interrupt (QSPI); /* QSPI */ + +default_interrupt (PDIR1FULL); /* Processor data in 1 full */ +default_interrupt (PDIR2FULL); /* Processor data in 2 full */ +default_interrupt (EBUTXEMPTY); /* EBU transmit FIFO empty */ +default_interrupt (IIS2TXEMPTY); /* IIS2 transmit FIFO empty */ +default_interrupt (IIS1TXEMPTY); /* IIS1 transmit FIFO empty */ +default_interrupt (PDIR3FULL); /* Processor data in 3 full */ +default_interrupt (PDIR3RESYN); /* Processor data in 3 resync */ +default_interrupt (UQ2CHANERR); /* IEC958-2 Rx U/Q channel error */ +default_interrupt (AUDIOTICK); /* "tick" interrupt */ +default_interrupt (PDIR2RESYN); /* Processor data in 2 resync */ +default_interrupt (PDIR2UNOV); /* Processor data in 2 under/overrun */ +default_interrupt (PDIR1RESYN); /* Processor data in 1 resync */ +default_interrupt (PDIR1UNOV); /* Processor data in 1 under/overrun */ +default_interrupt (UQ1CHANERR); /* IEC958-1 Rx U/Q channel error */ +default_interrupt (IEC2BUFATTEN);/* IEC958-2 channel buffer full */ +default_interrupt (IEC2PARERR); /* IEC958-2 Rx parity or symbol error */ +default_interrupt (IEC2VALNOGOOD);/* IEC958-2 flag not good */ +default_interrupt (IEC2CNEW); /* IEC958-2 New C-channel received */ +default_interrupt (IEC1BUFATTEN);/* IEC958-1 channel buffer full */ +default_interrupt (UCHANTXNF); /* U channel Tx reg next byte is first */ +default_interrupt (UCHANTXUNDER);/* U channel Tx reg underrun */ +default_interrupt (UCHANTXEMPTY);/* U channel Tx reg is empty */ +default_interrupt (PDIR3UNOV); /* Processor data in 3 under/overrun */ +default_interrupt (IEC1PARERR); /* IEC958-1 Rx parity or symbol error */ +default_interrupt (IEC1VALNOGOOD);/* IEC958-1 flag not good */ +default_interrupt (IEC1CNEW); /* IEC958-1 New C-channel received */ +default_interrupt (EBUTXRESYN); /* EBU Tx FIFO resync */ +default_interrupt (EBUTXUNOV); /* EBU Tx FIFO under/overrun */ +default_interrupt (IIS2TXRESYN); /* IIS2 Tx FIFO resync */ +default_interrupt (IIS2TXUNOV); /* IIS2 Tx FIFO under/overrun */ +default_interrupt (IIS1TXRESYN); /* IIS1 Tx FIFO resync */ +default_interrupt (IIS1TXUNOV); /* IIS1 Tx FIFO under/overrun */ +default_interrupt (GPI0); /* GPIO interrupt 0 */ +default_interrupt (GPI1); /* GPIO interrupt 1 */ +default_interrupt (GPI2); /* GPIO interrupt 2 */ +default_interrupt (GPI3); /* GPIO interrupt 3 */ +default_interrupt (GPI4); /* GPIO interrupt 4 */ +default_interrupt (GPI5); /* GPIO interrupt 5 */ +default_interrupt (GPI6); /* GPIO interrupt 6 */ +default_interrupt (GPI7); /* GPIO interrupt 7 */ + +default_interrupt (SOFTINT0); /* Software interrupt 0 */ +default_interrupt (SOFTINT1); /* Software interrupt 1 */ +default_interrupt (SOFTINT2); /* Software interrupt 2 */ +default_interrupt (SOFTINT3); /* Software interrupt 3 */ + +default_interrupt (CDROMCRCERR); /* CD-ROM CRC error */ +default_interrupt (CDROMNOSYNC); /* CD-ROM No sync */ +default_interrupt (CDROMILSYNC); /* CD-ROM Illegal sync */ +default_interrupt (CDROMNEWBLK); /* CD-ROM New block */ + +void UIE (void) /* Unexpected Interrupt or Exception */ +{ + unsigned int format_vector, pc; + int vector; + char str[32]; + + asm volatile ("move.l (52,%%sp),%0": "=r"(format_vector)); + asm volatile ("move.l (56,%%sp),%0": "=r"(pc)); + + vector = (format_vector >> 18) & 0xff; + + /* clear screen */ + lcd_clear_display (); + lcd_setfont(FONT_SYSFIXED); + + snprintf(str,sizeof(str),"I%02x:%s",vector,irqname[vector]); + lcd_puts(0,0,str); + snprintf(str,sizeof(str),"at %08x",pc); + lcd_puts(0,1,str); + lcd_update(); + + /* set cpu frequency to 11mhz (to prevent overheating) */ + DCR = (DCR & ~0x01ff) | 1; + PLLCR = 0x10800000; + + while (1) + { + /* check for the ON button (and !hold) */ + if ((GPIO1_READ & 0x22) == 0) + SYPCR = 0xc0; + /* Start watchdog timer with 512 cycles timeout. Don't service it. */ + + /* We need a reset method that works in all cases. Calling system_reboot() + doesn't work when we're called from the debug interrupt, because then + the CPU is in emulator mode and the only ways leaving it are exexcuting + an rte instruction or performing a reset. Even disabling the breakpoint + logic and performing special rte magic doesn't make system_reboot() + reliable. The system restarts, but boot often fails with ata error -42. */ + } +} + +/* reset vectors are handled in crt0.S */ +void (* const vbr[]) (void) __attribute__ ((section (".vectors"))) = +{ + UIE,UIE,UIE,UIE,UIE,UIE, + UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE, + UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE, + UIE,UIE,UIE,TIMER0,TIMER1,UIE,UIE,UIE, + /* lvl 3 lvl 4 */ + + TRAP0,TRAP1,TRAP2,TRAP3,TRAP4,TRAP5,TRAP6,TRAP7, + TRAP8,TRAP9,TRAP10,TRAP11,TRAP12,TRAP13,TRAP14,TRAP15, + + SWT,UIE,UIE,I2C,UART1,UART2,DMA0,DMA1, + DMA2,DMA3,QSPI,UIE,UIE,UIE,UIE,UIE, + PDIR1FULL,PDIR2FULL,EBUTXEMPTY,IIS2TXEMPTY, + IIS1TXEMPTY,PDIR3FULL,PDIR3RESYN,UQ2CHANERR, + AUDIOTICK,PDIR2RESYN,PDIR2UNOV,PDIR1RESYN, + PDIR1UNOV,UQ1CHANERR,IEC2BUFATTEN,IEC2PARERR, + IEC2VALNOGOOD,IEC2CNEW,IEC1BUFATTEN,UCHANTXNF, + UCHANTXUNDER,UCHANTXEMPTY,PDIR3UNOV,IEC1PARERR, + IEC1VALNOGOOD,IEC1CNEW,EBUTXRESYN,EBUTXUNOV, + IIS2TXRESYN,IIS2TXUNOV,IIS1TXRESYN,IIS1TXUNOV, + GPI0,GPI1,GPI2,GPI3,GPI4,GPI5,GPI6,GPI7, + UIE,UIE,UIE,UIE,UIE,UIE,UIE,SOFTINT0, + SOFTINT1,SOFTINT2,SOFTINT3,UIE, + UIE,CDROMCRCERR,CDROMNOSYNC,CDROMILSYNC, + CDROMNEWBLK,UIE,UIE,UIE,UIE,UIE,UIE,UIE, + + UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE, + UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE, + UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE, + UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE, + UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE, + UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE, + UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE, + UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE +}; + +void system_init(void) +{ + /* Clear the accumulators. From here on it's the responsibility of + whoever uses them to clear them after use (use movclr instruction). */ + asm volatile ("movclr.l %%acc0, %%d0\n\t" + "movclr.l %%acc1, %%d0\n\t" + "movclr.l %%acc2, %%d0\n\t" + "movclr.l %%acc3, %%d0\n\t" + : : : "d0"); + /* Set EMAC unit to saturating and rounding fractional mode, since that's + what'll be the most useful for most things which the main thread + will do. */ + coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE | EMAC_ROUND); + + /* Set INTBASE and SPURVEC */ + INTBASE = 64; + SPURVEC = 24; +} + +void system_reboot (void) +{ + set_cpu_frequency(0); + + asm(" move.w #0x2700,%sr"); + /* Reset the cookie for the crt0 crash check */ + asm(" move.l #0,%d0"); + asm(" move.l %d0,0x10017ffc"); + asm(" movec.l %d0,%vbr"); + asm(" move.l 0,%sp"); + asm(" move.l 4,%a0"); + asm(" jmp (%a0)"); +} + +/* Utilise the breakpoint hardware to catch invalid memory accesses. */ +int system_memory_guard(int newmode) +{ + static const unsigned long modes[MAXMEMGUARD][8] = { + { /* catch nothing */ + 0x2C870000, 0x00000000, /* TDR = 0x00000000 */ + 0x2C8D0000, 0x00000000, /* ABLR = 0x00000000 */ + 0x2C8C0000, 0x00000000, /* ABHR = 0x00000000 */ + 0x2C860000, 0x00050000, /* AATR = 0x0005 */ + }, + { /* catch flash ROM writes */ + 0x2C8D0000, 0x00000000, /* ABLR = 0x00000000 */ + 0x2C8C0FFF, 0xFFFF0000, /* ABHR = 0x0FFFFFFF */ + 0x2C860000, 0x6F050000, /* AATR = 0x6F05 */ + 0x2C878000, 0x20080000, /* TDR = 0x80002008 */ + }, + { /* catch all accesses to zero area */ + 0x2C8D0000, 0x00000000, /* ABLR = 0x00000000 */ + 0x2C8C0FFF, 0xFFFF0000, /* ABHR = 0x0FFFFFFF */ + 0x2C860000, 0xEF050000, /* AATR = 0xEF05 */ + 0x2C878000, 0x20080000, /* TDR = 0x80002008 */ + } + /* Note: CPU space accesses (movec instruction), interrupt acknowledges + and emulator mode accesses are never caught. */ + }; + static int cur_mode = MEMGUARD_NONE; + + int oldmode = cur_mode; + const unsigned long *ptr; + int i; + + if (newmode == MEMGUARD_KEEP) + newmode = oldmode; + + /* Always set the new mode, we don't know the old settings + as we cannot read back */ + ptr = modes[newmode]; + for (i = 0; i < 4; i++) + { + asm ( "wdebug (%0) \n" : : "a"(ptr)); + ptr += 2; + } + cur_mode = newmode; + + return oldmode; +} -- cgit v1.2.3