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/SOURCES | 1 + firmware/export/system.h | 119 +----------- firmware/system.c | 280 +-------------------------- firmware/target/coldfire/system-coldfire.c | 296 +++++++++++++++++++++++++++++ firmware/target/coldfire/system-target.h | 131 +++++++++++++ 5 files changed, 437 insertions(+), 390 deletions(-) create mode 100644 firmware/target/coldfire/system-coldfire.c create mode 100644 firmware/target/coldfire/system-target.h (limited to 'firmware') diff --git a/firmware/SOURCES b/firmware/SOURCES index e506a1bcf6..e9ce8f909b 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -45,6 +45,7 @@ target/coldfire/memcpy-coldfire.S target/coldfire/memmove-coldfire.S target/coldfire/memset-coldfire.S target/coldfire/memset16-coldfire.S +target/coldfire/system-coldfire.c #elif (CONFIG_CPU == SH7034) target/sh/memcpy-sh.S target/sh/memmove-sh.S diff --git a/firmware/export/system.h b/firmware/export/system.h index ce0c795fbd..4a33d80466 100644 --- a/firmware/export/system.h +++ b/firmware/export/system.h @@ -153,6 +153,11 @@ enum { MAXMEMGUARD }; +#ifndef SIMULATOR +#ifdef CPU_COLDFIRE +#include "system-target.h" +#endif +#endif #if CONFIG_CPU == SH7034 #define or_b(mask, address) \ @@ -176,46 +181,7 @@ enum { : /* %0 */ I_CONSTRAINT((char)(mask)), \ /* %1 */ "z"(address-GBR)) -#elif defined(CPU_COLDFIRE) -#define or_l(mask, address) \ - asm \ - ("or.l %0,(%1)" \ - : \ - : /* %0 */ "d"(mask), \ - /* %1 */ "a"(address)) - -#define and_l(mask, address) \ - asm \ - ("and.l %0,(%1)" \ - : \ - : /* %0 */ "d"(mask), \ - /* %1 */ "a"(address)) - -#define eor_l(mask, address) \ - asm \ - ("eor.l %0,(%1)" \ - : \ - : /* %0 */ "d"(mask), \ - /* %1 */ "a"(address)) - -#define EMAC_ROUND 0x10 -#define EMAC_FRACTIONAL 0x20 -#define EMAC_SATURATE 0x80 - -static inline void coldfire_set_macsr(unsigned long flags) -{ - asm volatile ("move.l %0, %%macsr" : : "i,r" (flags)); -} - -static inline unsigned long coldfire_get_macsr(void) -{ - unsigned long m; - - asm volatile ("move.l %%macsr, %0" : "=r" (m)); - return m; -} - -#endif +#endif /* CONFIG_CPU == SH7034 */ #ifndef SIMULATOR @@ -272,75 +238,6 @@ static inline unsigned long swap32(unsigned long value) #define invalidate_icache() -#elif defined(CPU_COLDFIRE) -#define HIGHEST_IRQ_LEVEL (7<<8) -static inline int set_irq_level(int level) -{ - int oldlevel; - /* Read the old level and set the new one */ - asm volatile ("move.w %%sr,%0\n" - "or.l #0x2000,%1\n" - "move.w %1,%%sr\n" : "=d" (oldlevel), "+d" (level) : ); - return oldlevel; -} - -static inline unsigned short swap16(unsigned short value) - /* - result[15..8] = value[ 7..0]; - result[ 7..0] = value[15..8]; - */ -{ - return (value >> 8) | (value << 8); -} - -static inline unsigned long SWAW32(unsigned long value) - /* - result[31..16] = value[15.. 0]; - result[15.. 0] = value[31..16]; - */ -{ - asm ("swap %%0" : "+r"(value)); - return value; -} - -static inline unsigned long swap32(unsigned long value) - /* - result[31..24] = value[ 7.. 0]; - result[23..16] = value[15.. 8]; - result[15.. 8] = value[23..16]; - result[ 7.. 0] = value[31..24]; - */ -{ - unsigned long mask = 0x00FF00FF; - asm ( /* val = ABCD */ - "and.l %[val],%[mask] \n" /* mask = .B.D */ - "eor.l %[mask],%[val] \n" /* val = A.C. */ - "lsl.l #8,%[mask] \n" /* mask = B.D. */ - "lsr.l #8,%[val] \n" /* val = .A.C */ - "or.l %[mask],%[val] \n" /* val = BADC */ - "swap %[val] \n" /* val = DCBA */ - : /* outputs */ - [val] "+d"(value), - [mask]"+d"(mask) - ); - return value; -} - -static inline void invalidate_icache(void) -{ - asm volatile ("move.l #0x01000000,%d0\n" - "movec.l %d0,%cacr\n" - "move.l #0x80000000,%d0\n" - "movec.l %d0,%cacr"); -} - -#define CPUFREQ_DEFAULT_MULT 1 -#define CPUFREQ_DEFAULT (CPUFREQ_DEFAULT_MULT * CPU_FREQ) -#define CPUFREQ_NORMAL_MULT 4 -#define CPUFREQ_NORMAL (CPUFREQ_NORMAL_MULT * CPU_FREQ) -#define CPUFREQ_MAX_MULT 11 -#define CPUFREQ_MAX (CPUFREQ_MAX_MULT * CPU_FREQ) - #elif defined(CPU_ARM) /* TODO: Implement set_irq_level and check CPU frequencies */ @@ -444,8 +341,8 @@ static inline int set_irq_level(int level) { int result; __asm__ ("ld %0, 0\n\t" - "tstsr ie\n\t" - "incc %0" : "=r"(result)); + "tstsr ie\n\t" + "incc %0" : "=r"(result)); if (level > 0) __asm__ volatile ("clrsr ie"); else diff --git a/firmware/system.c b/firmware/system.c index 4dbc41b515..242d84d16c 100644 --- a/firmware/system.c +++ b/firmware/system.c @@ -391,285 +391,7 @@ int system_memory_guard(int newmode) return 0; } #elif defined(CPU_COLDFIRE) -#include "pcf50606.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 (); -#ifdef HAVE_LCD_BITMAP - lcd_setfont(FONT_SYSFIXED); -#endif - 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; -} - -/* void set_cpu_frequency(long frequency) is in - target tree for all 3 coldfire targets */ - +/* system code is in target tree for all coldfire targets */ #elif CONFIG_CPU == SH7034 #include "led.h" #include "system.h" 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; +} diff --git a/firmware/target/coldfire/system-target.h b/firmware/target/coldfire/system-target.h new file mode 100644 index 0000000000..03852115ad --- /dev/null +++ b/firmware/target/coldfire/system-target.h @@ -0,0 +1,131 @@ +/*************************************************************************** + * __________ __ ___. + * 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. + * + ****************************************************************************/ +#ifndef SYSTEM_TARGET_H +#define SYSTEM_TARGET_H + +#define or_l(mask, address) \ + asm \ + ("or.l %0,(%1)" \ + : \ + : /* %0 */ "d"(mask), \ + /* %1 */ "a"(address)) + +#define and_l(mask, address) \ + asm \ + ("and.l %0,(%1)" \ + : \ + : /* %0 */ "d"(mask), \ + /* %1 */ "a"(address)) + +#define eor_l(mask, address) \ + asm \ + ("eor.l %0,(%1)" \ + : \ + : /* %0 */ "d"(mask), \ + /* %1 */ "a"(address)) + +#define EMAC_ROUND 0x10 +#define EMAC_FRACTIONAL 0x20 +#define EMAC_SATURATE 0x80 + +static inline void coldfire_set_macsr(unsigned long flags) +{ + asm volatile ("move.l %0, %%macsr" : : "i,r" (flags)); +} + +static inline unsigned long coldfire_get_macsr(void) +{ + unsigned long m; + + asm volatile ("move.l %%macsr, %0" : "=r" (m)); + return m; +} + +#define HIGHEST_IRQ_LEVEL (7<<8) +static inline int set_irq_level(int level) +{ + int oldlevel; + /* Read the old level and set the new one */ + asm volatile ("move.w %%sr,%0\n" + "or.l #0x2000,%1\n" + "move.w %1,%%sr\n" : "=d" (oldlevel), "+d" (level) : ); + return oldlevel; +} + +static inline unsigned short swap16(unsigned short value) + /* + result[15..8] = value[ 7..0]; + result[ 7..0] = value[15..8]; + */ +{ + return (value >> 8) | (value << 8); +} + +static inline unsigned long SWAW32(unsigned long value) + /* + result[31..16] = value[15.. 0]; + result[15.. 0] = value[31..16]; + */ +{ + asm ("swap %%0" : "+r"(value)); + return value; +} + +static inline unsigned long swap32(unsigned long value) + /* + result[31..24] = value[ 7.. 0]; + result[23..16] = value[15.. 8]; + result[15.. 8] = value[23..16]; + result[ 7.. 0] = value[31..24]; + */ +{ + unsigned long mask = 0x00FF00FF; + asm ( /* val = ABCD */ + "and.l %[val],%[mask] \n" /* mask = .B.D */ + "eor.l %[mask],%[val] \n" /* val = A.C. */ + "lsl.l #8,%[mask] \n" /* mask = B.D. */ + "lsr.l #8,%[val] \n" /* val = .A.C */ + "or.l %[mask],%[val] \n" /* val = BADC */ + "swap %[val] \n" /* val = DCBA */ + : /* outputs */ + [val] "+d"(value), + [mask]"+d"(mask) + ); + return value; +} + +static inline void invalidate_icache(void) +{ + asm volatile ("move.l #0x01000000,%d0\n" + "movec.l %d0,%cacr\n" + "move.l #0x80000000,%d0\n" + "movec.l %d0,%cacr"); +} + +/* 11.2896 MHz */ +#define CPUFREQ_DEFAULT_MULT 1 +#define CPUFREQ_DEFAULT (CPUFREQ_DEFAULT_MULT * CPU_FREQ) +/* 45.1584 MHz */ +#define CPUFREQ_NORMAL_MULT 4 +#define CPUFREQ_NORMAL (CPUFREQ_NORMAL_MULT * CPU_FREQ) +/* 124.1856 MHz */ +#define CPUFREQ_MAX_MULT 11 +#define CPUFREQ_MAX (CPUFREQ_MAX_MULT * CPU_FREQ) + +#endif /* SYSTEM_TARGET_H */ -- cgit v1.2.3