summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/SOURCES1
-rw-r--r--firmware/export/system.h119
-rw-r--r--firmware/system.c280
-rw-r--r--firmware/target/coldfire/system-coldfire.c296
-rw-r--r--firmware/target/coldfire/system-target.h131
5 files changed, 437 insertions, 390 deletions
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
45target/coldfire/memmove-coldfire.S 45target/coldfire/memmove-coldfire.S
46target/coldfire/memset-coldfire.S 46target/coldfire/memset-coldfire.S
47target/coldfire/memset16-coldfire.S 47target/coldfire/memset16-coldfire.S
48target/coldfire/system-coldfire.c
48#elif (CONFIG_CPU == SH7034) 49#elif (CONFIG_CPU == SH7034)
49target/sh/memcpy-sh.S 50target/sh/memcpy-sh.S
50target/sh/memmove-sh.S 51target/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 {
153 MAXMEMGUARD 153 MAXMEMGUARD
154}; 154};
155 155
156#ifndef SIMULATOR
157#ifdef CPU_COLDFIRE
158#include "system-target.h"
159#endif
160#endif
156 161
157#if CONFIG_CPU == SH7034 162#if CONFIG_CPU == SH7034
158#define or_b(mask, address) \ 163#define or_b(mask, address) \
@@ -176,46 +181,7 @@ enum {
176 : /* %0 */ I_CONSTRAINT((char)(mask)), \ 181 : /* %0 */ I_CONSTRAINT((char)(mask)), \
177 /* %1 */ "z"(address-GBR)) 182 /* %1 */ "z"(address-GBR))
178 183
179#elif defined(CPU_COLDFIRE) 184#endif /* CONFIG_CPU == SH7034 */
180#define or_l(mask, address) \
181 asm \
182 ("or.l %0,(%1)" \
183 : \
184 : /* %0 */ "d"(mask), \
185 /* %1 */ "a"(address))
186
187#define and_l(mask, address) \
188 asm \
189 ("and.l %0,(%1)" \
190 : \
191 : /* %0 */ "d"(mask), \
192 /* %1 */ "a"(address))
193
194#define eor_l(mask, address) \
195 asm \
196 ("eor.l %0,(%1)" \
197 : \
198 : /* %0 */ "d"(mask), \
199 /* %1 */ "a"(address))
200
201#define EMAC_ROUND 0x10
202#define EMAC_FRACTIONAL 0x20
203#define EMAC_SATURATE 0x80
204
205static inline void coldfire_set_macsr(unsigned long flags)
206{
207 asm volatile ("move.l %0, %%macsr" : : "i,r" (flags));
208}
209
210static inline unsigned long coldfire_get_macsr(void)
211{
212 unsigned long m;
213
214 asm volatile ("move.l %%macsr, %0" : "=r" (m));
215 return m;
216}
217
218#endif
219 185
220#ifndef SIMULATOR 186#ifndef SIMULATOR
221 187
@@ -272,75 +238,6 @@ static inline unsigned long swap32(unsigned long value)
272 238
273#define invalidate_icache() 239#define invalidate_icache()
274 240
275#elif defined(CPU_COLDFIRE)
276#define HIGHEST_IRQ_LEVEL (7<<8)
277static inline int set_irq_level(int level)
278{
279 int oldlevel;
280 /* Read the old level and set the new one */
281 asm volatile ("move.w %%sr,%0\n"
282 "or.l #0x2000,%1\n"
283 "move.w %1,%%sr\n" : "=d" (oldlevel), "+d" (level) : );
284 return oldlevel;
285}
286
287static inline unsigned short swap16(unsigned short value)
288 /*
289 result[15..8] = value[ 7..0];
290 result[ 7..0] = value[15..8];
291 */
292{
293 return (value >> 8) | (value << 8);
294}
295
296static inline unsigned long SWAW32(unsigned long value)
297 /*
298 result[31..16] = value[15.. 0];
299 result[15.. 0] = value[31..16];
300 */
301{
302 asm ("swap %%0" : "+r"(value));
303 return value;
304}
305
306static inline unsigned long swap32(unsigned long value)
307 /*
308 result[31..24] = value[ 7.. 0];
309 result[23..16] = value[15.. 8];
310 result[15.. 8] = value[23..16];
311 result[ 7.. 0] = value[31..24];
312 */
313{
314 unsigned long mask = 0x00FF00FF;
315 asm ( /* val = ABCD */
316 "and.l %[val],%[mask] \n" /* mask = .B.D */
317 "eor.l %[mask],%[val] \n" /* val = A.C. */
318 "lsl.l #8,%[mask] \n" /* mask = B.D. */
319 "lsr.l #8,%[val] \n" /* val = .A.C */
320 "or.l %[mask],%[val] \n" /* val = BADC */
321 "swap %[val] \n" /* val = DCBA */
322 : /* outputs */
323 [val] "+d"(value),
324 [mask]"+d"(mask)
325 );
326 return value;
327}
328
329static inline void invalidate_icache(void)
330{
331 asm volatile ("move.l #0x01000000,%d0\n"
332 "movec.l %d0,%cacr\n"
333 "move.l #0x80000000,%d0\n"
334 "movec.l %d0,%cacr");
335}
336
337#define CPUFREQ_DEFAULT_MULT 1
338#define CPUFREQ_DEFAULT (CPUFREQ_DEFAULT_MULT * CPU_FREQ)
339#define CPUFREQ_NORMAL_MULT 4
340#define CPUFREQ_NORMAL (CPUFREQ_NORMAL_MULT * CPU_FREQ)
341#define CPUFREQ_MAX_MULT 11
342#define CPUFREQ_MAX (CPUFREQ_MAX_MULT * CPU_FREQ)
343
344#elif defined(CPU_ARM) 241#elif defined(CPU_ARM)
345 242
346/* TODO: Implement set_irq_level and check CPU frequencies */ 243/* TODO: Implement set_irq_level and check CPU frequencies */
@@ -444,8 +341,8 @@ static inline int set_irq_level(int level)
444{ 341{
445 int result; 342 int result;
446 __asm__ ("ld %0, 0\n\t" 343 __asm__ ("ld %0, 0\n\t"
447 "tstsr ie\n\t" 344 "tstsr ie\n\t"
448 "incc %0" : "=r"(result)); 345 "incc %0" : "=r"(result));
449 if (level > 0) 346 if (level > 0)
450 __asm__ volatile ("clrsr ie"); 347 __asm__ volatile ("clrsr ie");
451 else 348 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)
391 return 0; 391 return 0;
392} 392}
393#elif defined(CPU_COLDFIRE) 393#elif defined(CPU_COLDFIRE)
394#include "pcf50606.h" 394/* system code is in target tree for all coldfire targets */
395
396#define default_interrupt(name) \
397 extern __attribute__((weak,alias("UIE"))) void name (void)
398
399static const char* const irqname[] = {
400 "", "", "AccessErr","AddrErr","IllInstr", "", "","",
401 "PrivVio","Trace","Line-A", "Line-F","Debug","","FormErr","Uninit",
402 "","","","","","","","",
403 "Spurious","Level1","Level2","Level3","Level4","Level5","Level6","Level7",
404 "Trap0","Trap1","Trap2","Trap3","Trap4","Trap5","Trap6","Trap7",
405 "Trap8","Trap9","Trap10","Trap11","Trap12","Trap13","Trap14","Trap15",
406 "SWT","Timer0","Timer1","I2C","UART1","UART2","DMA0","DMA1",
407 "DMA2","DMA3","QSPI","","","","","",
408 "PDIR1FULL","PDIR2FULL","EBUTXEMPTY","IIS2TXEMPTY",
409 "IIS1TXEMPTY","PDIR3FULL","PDIR3RESYN","UQ2CHANERR",
410 "AUDIOTICK","PDIR2RESYN","PDIR2UNOV","PDIR1RESYN",
411 "PDIR1UNOV","UQ1CHANERR","IEC2BUFATTEN","IEC2PARERR",
412 "IEC2VALNOGOOD","IEC2CNEW","IEC1BUFATTEN","UCHANTXNF",
413 "UCHANTXUNDER","UCHANTXEMPTY","PDIR3UNOV","IEC1PARERR",
414 "IEC1VALNOGOOD","IEC1CNEW","EBUTXRESYN","EBUTXUNOV",
415 "IIS2TXRESYN","IIS2TXUNOV","IIS1TXRESYN","IIS1TXUNOV",
416 "GPI0","GPI1","GPI2","GPI3","GPI4","GPI5","GPI6","GPI7",
417 "","","","","","","","SOFTINT0",
418 "SOFTINT1","SOFTINT2","SOFTINT3","",
419 "","CDROMCRCERR","CDROMNOSYNC","CDROMILSYNC",
420 "CDROMNEWBLK","","","","","","","",
421 "","","","","","","","",
422 "","","","","","","","",
423 "","","","","","","","",
424 "","","","","","","","",
425 "","","","","","","","",
426 "","","","","","","","",
427 "","","","","","","","",
428 "","","","","","","",""
429};
430
431default_interrupt (TRAP0); /* Trap #0 */
432default_interrupt (TRAP1); /* Trap #1 */
433default_interrupt (TRAP2); /* Trap #2 */
434default_interrupt (TRAP3); /* Trap #3 */
435default_interrupt (TRAP4); /* Trap #4 */
436default_interrupt (TRAP5); /* Trap #5 */
437default_interrupt (TRAP6); /* Trap #6 */
438default_interrupt (TRAP7); /* Trap #7 */
439default_interrupt (TRAP8); /* Trap #8 */
440default_interrupt (TRAP9); /* Trap #9 */
441default_interrupt (TRAP10); /* Trap #10 */
442default_interrupt (TRAP11); /* Trap #11 */
443default_interrupt (TRAP12); /* Trap #12 */
444default_interrupt (TRAP13); /* Trap #13 */
445default_interrupt (TRAP14); /* Trap #14 */
446default_interrupt (TRAP15); /* Trap #15 */
447default_interrupt (SWT); /* Software Watchdog Timer */
448default_interrupt (TIMER0); /* Timer 0 */
449default_interrupt (TIMER1); /* Timer 1 */
450default_interrupt (I2C); /* I2C */
451default_interrupt (UART1); /* UART 1 */
452default_interrupt (UART2); /* UART 2 */
453default_interrupt (DMA0); /* DMA 0 */
454default_interrupt (DMA1); /* DMA 1 */
455default_interrupt (DMA2); /* DMA 2 */
456default_interrupt (DMA3); /* DMA 3 */
457default_interrupt (QSPI); /* QSPI */
458
459default_interrupt (PDIR1FULL); /* Processor data in 1 full */
460default_interrupt (PDIR2FULL); /* Processor data in 2 full */
461default_interrupt (EBUTXEMPTY); /* EBU transmit FIFO empty */
462default_interrupt (IIS2TXEMPTY); /* IIS2 transmit FIFO empty */
463default_interrupt (IIS1TXEMPTY); /* IIS1 transmit FIFO empty */
464default_interrupt (PDIR3FULL); /* Processor data in 3 full */
465default_interrupt (PDIR3RESYN); /* Processor data in 3 resync */
466default_interrupt (UQ2CHANERR); /* IEC958-2 Rx U/Q channel error */
467default_interrupt (AUDIOTICK); /* "tick" interrupt */
468default_interrupt (PDIR2RESYN); /* Processor data in 2 resync */
469default_interrupt (PDIR2UNOV); /* Processor data in 2 under/overrun */
470default_interrupt (PDIR1RESYN); /* Processor data in 1 resync */
471default_interrupt (PDIR1UNOV); /* Processor data in 1 under/overrun */
472default_interrupt (UQ1CHANERR); /* IEC958-1 Rx U/Q channel error */
473default_interrupt (IEC2BUFATTEN);/* IEC958-2 channel buffer full */
474default_interrupt (IEC2PARERR); /* IEC958-2 Rx parity or symbol error */
475default_interrupt (IEC2VALNOGOOD);/* IEC958-2 flag not good */
476default_interrupt (IEC2CNEW); /* IEC958-2 New C-channel received */
477default_interrupt (IEC1BUFATTEN);/* IEC958-1 channel buffer full */
478default_interrupt (UCHANTXNF); /* U channel Tx reg next byte is first */
479default_interrupt (UCHANTXUNDER);/* U channel Tx reg underrun */
480default_interrupt (UCHANTXEMPTY);/* U channel Tx reg is empty */
481default_interrupt (PDIR3UNOV); /* Processor data in 3 under/overrun */
482default_interrupt (IEC1PARERR); /* IEC958-1 Rx parity or symbol error */
483default_interrupt (IEC1VALNOGOOD);/* IEC958-1 flag not good */
484default_interrupt (IEC1CNEW); /* IEC958-1 New C-channel received */
485default_interrupt (EBUTXRESYN); /* EBU Tx FIFO resync */
486default_interrupt (EBUTXUNOV); /* EBU Tx FIFO under/overrun */
487default_interrupt (IIS2TXRESYN); /* IIS2 Tx FIFO resync */
488default_interrupt (IIS2TXUNOV); /* IIS2 Tx FIFO under/overrun */
489default_interrupt (IIS1TXRESYN); /* IIS1 Tx FIFO resync */
490default_interrupt (IIS1TXUNOV); /* IIS1 Tx FIFO under/overrun */
491default_interrupt (GPI0); /* GPIO interrupt 0 */
492default_interrupt (GPI1); /* GPIO interrupt 1 */
493default_interrupt (GPI2); /* GPIO interrupt 2 */
494default_interrupt (GPI3); /* GPIO interrupt 3 */
495default_interrupt (GPI4); /* GPIO interrupt 4 */
496default_interrupt (GPI5); /* GPIO interrupt 5 */
497default_interrupt (GPI6); /* GPIO interrupt 6 */
498default_interrupt (GPI7); /* GPIO interrupt 7 */
499
500default_interrupt (SOFTINT0); /* Software interrupt 0 */
501default_interrupt (SOFTINT1); /* Software interrupt 1 */
502default_interrupt (SOFTINT2); /* Software interrupt 2 */
503default_interrupt (SOFTINT3); /* Software interrupt 3 */
504
505default_interrupt (CDROMCRCERR); /* CD-ROM CRC error */
506default_interrupt (CDROMNOSYNC); /* CD-ROM No sync */
507default_interrupt (CDROMILSYNC); /* CD-ROM Illegal sync */
508default_interrupt (CDROMNEWBLK); /* CD-ROM New block */
509
510void UIE (void) /* Unexpected Interrupt or Exception */
511{
512 unsigned int format_vector, pc;
513 int vector;
514 char str[32];
515
516 asm volatile ("move.l (52,%%sp),%0": "=r"(format_vector));
517 asm volatile ("move.l (56,%%sp),%0": "=r"(pc));
518
519 vector = (format_vector >> 18) & 0xff;
520
521 /* clear screen */
522 lcd_clear_display ();
523#ifdef HAVE_LCD_BITMAP
524 lcd_setfont(FONT_SYSFIXED);
525#endif
526 snprintf(str,sizeof(str),"I%02x:%s",vector,irqname[vector]);
527 lcd_puts(0,0,str);
528 snprintf(str,sizeof(str),"at %08x",pc);
529 lcd_puts(0,1,str);
530 lcd_update();
531
532 /* set cpu frequency to 11mhz (to prevent overheating) */
533 DCR = (DCR & ~0x01ff) | 1;
534 PLLCR = 0x10800000;
535
536 while (1)
537 {
538 /* check for the ON button (and !hold) */
539 if ((GPIO1_READ & 0x22) == 0)
540 SYPCR = 0xc0;
541 /* Start watchdog timer with 512 cycles timeout. Don't service it. */
542
543 /* We need a reset method that works in all cases. Calling system_reboot()
544 doesn't work when we're called from the debug interrupt, because then
545 the CPU is in emulator mode and the only ways leaving it are exexcuting
546 an rte instruction or performing a reset. Even disabling the breakpoint
547 logic and performing special rte magic doesn't make system_reboot()
548 reliable. The system restarts, but boot often fails with ata error -42. */
549 }
550}
551
552/* reset vectors are handled in crt0.S */
553void (* const vbr[]) (void) __attribute__ ((section (".vectors"))) =
554{
555 UIE,UIE,UIE,UIE,UIE,UIE,
556 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
557 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
558 UIE,UIE,UIE,TIMER0,TIMER1,UIE,UIE,UIE,
559 /* lvl 3 lvl 4 */
560
561 TRAP0,TRAP1,TRAP2,TRAP3,TRAP4,TRAP5,TRAP6,TRAP7,
562 TRAP8,TRAP9,TRAP10,TRAP11,TRAP12,TRAP13,TRAP14,TRAP15,
563
564 SWT,UIE,UIE,I2C,UART1,UART2,DMA0,DMA1,
565 DMA2,DMA3,QSPI,UIE,UIE,UIE,UIE,UIE,
566 PDIR1FULL,PDIR2FULL,EBUTXEMPTY,IIS2TXEMPTY,
567 IIS1TXEMPTY,PDIR3FULL,PDIR3RESYN,UQ2CHANERR,
568 AUDIOTICK,PDIR2RESYN,PDIR2UNOV,PDIR1RESYN,
569 PDIR1UNOV,UQ1CHANERR,IEC2BUFATTEN,IEC2PARERR,
570 IEC2VALNOGOOD,IEC2CNEW,IEC1BUFATTEN,UCHANTXNF,
571 UCHANTXUNDER,UCHANTXEMPTY,PDIR3UNOV,IEC1PARERR,
572 IEC1VALNOGOOD,IEC1CNEW,EBUTXRESYN,EBUTXUNOV,
573 IIS2TXRESYN,IIS2TXUNOV,IIS1TXRESYN,IIS1TXUNOV,
574 GPI0,GPI1,GPI2,GPI3,GPI4,GPI5,GPI6,GPI7,
575 UIE,UIE,UIE,UIE,UIE,UIE,UIE,SOFTINT0,
576 SOFTINT1,SOFTINT2,SOFTINT3,UIE,
577 UIE,CDROMCRCERR,CDROMNOSYNC,CDROMILSYNC,
578 CDROMNEWBLK,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
579
580 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
581 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
582 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
583 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
584 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
585 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
586 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
587 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE
588};
589
590void system_init(void)
591{
592 /* Clear the accumulators. From here on it's the responsibility of
593 whoever uses them to clear them after use (use movclr instruction). */
594 asm volatile ("movclr.l %%acc0, %%d0\n\t"
595 "movclr.l %%acc1, %%d0\n\t"
596 "movclr.l %%acc2, %%d0\n\t"
597 "movclr.l %%acc3, %%d0\n\t"
598 : : : "d0");
599 /* Set EMAC unit to saturating and rounding fractional mode, since that's
600 what'll be the most useful for most things which the main thread
601 will do. */
602 coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE | EMAC_ROUND);
603
604 /* Set INTBASE and SPURVEC */
605 INTBASE = 64;
606 SPURVEC = 24;
607}
608
609void system_reboot (void)
610{
611 set_cpu_frequency(0);
612
613 asm(" move.w #0x2700,%sr");
614 /* Reset the cookie for the crt0 crash check */
615 asm(" move.l #0,%d0");
616 asm(" move.l %d0,0x10017ffc");
617 asm(" movec.l %d0,%vbr");
618 asm(" move.l 0,%sp");
619 asm(" move.l 4,%a0");
620 asm(" jmp (%a0)");
621}
622
623/* Utilise the breakpoint hardware to catch invalid memory accesses. */
624int system_memory_guard(int newmode)
625{
626 static const unsigned long modes[MAXMEMGUARD][8] = {
627 { /* catch nothing */
628 0x2C870000, 0x00000000, /* TDR = 0x00000000 */
629 0x2C8D0000, 0x00000000, /* ABLR = 0x00000000 */
630 0x2C8C0000, 0x00000000, /* ABHR = 0x00000000 */
631 0x2C860000, 0x00050000, /* AATR = 0x0005 */
632 },
633 { /* catch flash ROM writes */
634 0x2C8D0000, 0x00000000, /* ABLR = 0x00000000 */
635 0x2C8C0FFF, 0xFFFF0000, /* ABHR = 0x0FFFFFFF */
636 0x2C860000, 0x6F050000, /* AATR = 0x6F05 */
637 0x2C878000, 0x20080000, /* TDR = 0x80002008 */
638 },
639 { /* catch all accesses to zero area */
640 0x2C8D0000, 0x00000000, /* ABLR = 0x00000000 */
641 0x2C8C0FFF, 0xFFFF0000, /* ABHR = 0x0FFFFFFF */
642 0x2C860000, 0xEF050000, /* AATR = 0xEF05 */
643 0x2C878000, 0x20080000, /* TDR = 0x80002008 */
644 }
645 /* Note: CPU space accesses (movec instruction), interrupt acknowledges
646 and emulator mode accesses are never caught. */
647 };
648 static int cur_mode = MEMGUARD_NONE;
649
650 int oldmode = cur_mode;
651 const unsigned long *ptr;
652 int i;
653
654 if (newmode == MEMGUARD_KEEP)
655 newmode = oldmode;
656
657 /* Always set the new mode, we don't know the old settings
658 as we cannot read back */
659 ptr = modes[newmode];
660 for (i = 0; i < 4; i++)
661 {
662 asm ( "wdebug (%0) \n" : : "a"(ptr));
663 ptr += 2;
664 }
665 cur_mode = newmode;
666
667 return oldmode;
668}
669
670/* void set_cpu_frequency(long frequency) is in
671 target tree for all 3 coldfire targets */
672
673#elif CONFIG_CPU == SH7034 395#elif CONFIG_CPU == SH7034
674#include "led.h" 396#include "led.h"
675#include "system.h" 397#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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Alan Korr
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include <stdio.h>
20#include "config.h"
21#include "system.h"
22#include "lcd.h"
23#include "font.h"
24
25#define default_interrupt(name) \
26 extern __attribute__((weak,alias("UIE"))) void name (void)
27
28static const char* const irqname[] = {
29 "", "", "AccessErr","AddrErr","IllInstr", "", "","",
30 "PrivVio","Trace","Line-A", "Line-F","Debug","","FormErr","Uninit",
31 "","","","","","","","",
32 "Spurious","Level1","Level2","Level3","Level4","Level5","Level6","Level7",
33 "Trap0","Trap1","Trap2","Trap3","Trap4","Trap5","Trap6","Trap7",
34 "Trap8","Trap9","Trap10","Trap11","Trap12","Trap13","Trap14","Trap15",
35 "SWT","Timer0","Timer1","I2C","UART1","UART2","DMA0","DMA1",
36 "DMA2","DMA3","QSPI","","","","","",
37 "PDIR1FULL","PDIR2FULL","EBUTXEMPTY","IIS2TXEMPTY",
38 "IIS1TXEMPTY","PDIR3FULL","PDIR3RESYN","UQ2CHANERR",
39 "AUDIOTICK","PDIR2RESYN","PDIR2UNOV","PDIR1RESYN",
40 "PDIR1UNOV","UQ1CHANERR","IEC2BUFATTEN","IEC2PARERR",
41 "IEC2VALNOGOOD","IEC2CNEW","IEC1BUFATTEN","UCHANTXNF",
42 "UCHANTXUNDER","UCHANTXEMPTY","PDIR3UNOV","IEC1PARERR",
43 "IEC1VALNOGOOD","IEC1CNEW","EBUTXRESYN","EBUTXUNOV",
44 "IIS2TXRESYN","IIS2TXUNOV","IIS1TXRESYN","IIS1TXUNOV",
45 "GPI0","GPI1","GPI2","GPI3","GPI4","GPI5","GPI6","GPI7",
46 "","","","","","","","SOFTINT0",
47 "SOFTINT1","SOFTINT2","SOFTINT3","",
48 "","CDROMCRCERR","CDROMNOSYNC","CDROMILSYNC",
49 "CDROMNEWBLK","","","","","","","",
50 "","","","","","","","",
51 "","","","","","","","",
52 "","","","","","","","",
53 "","","","","","","","",
54 "","","","","","","","",
55 "","","","","","","","",
56 "","","","","","","","",
57 "","","","","","","",""
58};
59
60default_interrupt (TRAP0); /* Trap #0 */
61default_interrupt (TRAP1); /* Trap #1 */
62default_interrupt (TRAP2); /* Trap #2 */
63default_interrupt (TRAP3); /* Trap #3 */
64default_interrupt (TRAP4); /* Trap #4 */
65default_interrupt (TRAP5); /* Trap #5 */
66default_interrupt (TRAP6); /* Trap #6 */
67default_interrupt (TRAP7); /* Trap #7 */
68default_interrupt (TRAP8); /* Trap #8 */
69default_interrupt (TRAP9); /* Trap #9 */
70default_interrupt (TRAP10); /* Trap #10 */
71default_interrupt (TRAP11); /* Trap #11 */
72default_interrupt (TRAP12); /* Trap #12 */
73default_interrupt (TRAP13); /* Trap #13 */
74default_interrupt (TRAP14); /* Trap #14 */
75default_interrupt (TRAP15); /* Trap #15 */
76default_interrupt (SWT); /* Software Watchdog Timer */
77default_interrupt (TIMER0); /* Timer 0 */
78default_interrupt (TIMER1); /* Timer 1 */
79default_interrupt (I2C); /* I2C */
80default_interrupt (UART1); /* UART 1 */
81default_interrupt (UART2); /* UART 2 */
82default_interrupt (DMA0); /* DMA 0 */
83default_interrupt (DMA1); /* DMA 1 */
84default_interrupt (DMA2); /* DMA 2 */
85default_interrupt (DMA3); /* DMA 3 */
86default_interrupt (QSPI); /* QSPI */
87
88default_interrupt (PDIR1FULL); /* Processor data in 1 full */
89default_interrupt (PDIR2FULL); /* Processor data in 2 full */
90default_interrupt (EBUTXEMPTY); /* EBU transmit FIFO empty */
91default_interrupt (IIS2TXEMPTY); /* IIS2 transmit FIFO empty */
92default_interrupt (IIS1TXEMPTY); /* IIS1 transmit FIFO empty */
93default_interrupt (PDIR3FULL); /* Processor data in 3 full */
94default_interrupt (PDIR3RESYN); /* Processor data in 3 resync */
95default_interrupt (UQ2CHANERR); /* IEC958-2 Rx U/Q channel error */
96default_interrupt (AUDIOTICK); /* "tick" interrupt */
97default_interrupt (PDIR2RESYN); /* Processor data in 2 resync */
98default_interrupt (PDIR2UNOV); /* Processor data in 2 under/overrun */
99default_interrupt (PDIR1RESYN); /* Processor data in 1 resync */
100default_interrupt (PDIR1UNOV); /* Processor data in 1 under/overrun */
101default_interrupt (UQ1CHANERR); /* IEC958-1 Rx U/Q channel error */
102default_interrupt (IEC2BUFATTEN);/* IEC958-2 channel buffer full */
103default_interrupt (IEC2PARERR); /* IEC958-2 Rx parity or symbol error */
104default_interrupt (IEC2VALNOGOOD);/* IEC958-2 flag not good */
105default_interrupt (IEC2CNEW); /* IEC958-2 New C-channel received */
106default_interrupt (IEC1BUFATTEN);/* IEC958-1 channel buffer full */
107default_interrupt (UCHANTXNF); /* U channel Tx reg next byte is first */
108default_interrupt (UCHANTXUNDER);/* U channel Tx reg underrun */
109default_interrupt (UCHANTXEMPTY);/* U channel Tx reg is empty */
110default_interrupt (PDIR3UNOV); /* Processor data in 3 under/overrun */
111default_interrupt (IEC1PARERR); /* IEC958-1 Rx parity or symbol error */
112default_interrupt (IEC1VALNOGOOD);/* IEC958-1 flag not good */
113default_interrupt (IEC1CNEW); /* IEC958-1 New C-channel received */
114default_interrupt (EBUTXRESYN); /* EBU Tx FIFO resync */
115default_interrupt (EBUTXUNOV); /* EBU Tx FIFO under/overrun */
116default_interrupt (IIS2TXRESYN); /* IIS2 Tx FIFO resync */
117default_interrupt (IIS2TXUNOV); /* IIS2 Tx FIFO under/overrun */
118default_interrupt (IIS1TXRESYN); /* IIS1 Tx FIFO resync */
119default_interrupt (IIS1TXUNOV); /* IIS1 Tx FIFO under/overrun */
120default_interrupt (GPI0); /* GPIO interrupt 0 */
121default_interrupt (GPI1); /* GPIO interrupt 1 */
122default_interrupt (GPI2); /* GPIO interrupt 2 */
123default_interrupt (GPI3); /* GPIO interrupt 3 */
124default_interrupt (GPI4); /* GPIO interrupt 4 */
125default_interrupt (GPI5); /* GPIO interrupt 5 */
126default_interrupt (GPI6); /* GPIO interrupt 6 */
127default_interrupt (GPI7); /* GPIO interrupt 7 */
128
129default_interrupt (SOFTINT0); /* Software interrupt 0 */
130default_interrupt (SOFTINT1); /* Software interrupt 1 */
131default_interrupt (SOFTINT2); /* Software interrupt 2 */
132default_interrupt (SOFTINT3); /* Software interrupt 3 */
133
134default_interrupt (CDROMCRCERR); /* CD-ROM CRC error */
135default_interrupt (CDROMNOSYNC); /* CD-ROM No sync */
136default_interrupt (CDROMILSYNC); /* CD-ROM Illegal sync */
137default_interrupt (CDROMNEWBLK); /* CD-ROM New block */
138
139void UIE (void) /* Unexpected Interrupt or Exception */
140{
141 unsigned int format_vector, pc;
142 int vector;
143 char str[32];
144
145 asm volatile ("move.l (52,%%sp),%0": "=r"(format_vector));
146 asm volatile ("move.l (56,%%sp),%0": "=r"(pc));
147
148 vector = (format_vector >> 18) & 0xff;
149
150 /* clear screen */
151 lcd_clear_display ();
152 lcd_setfont(FONT_SYSFIXED);
153
154 snprintf(str,sizeof(str),"I%02x:%s",vector,irqname[vector]);
155 lcd_puts(0,0,str);
156 snprintf(str,sizeof(str),"at %08x",pc);
157 lcd_puts(0,1,str);
158 lcd_update();
159
160 /* set cpu frequency to 11mhz (to prevent overheating) */
161 DCR = (DCR & ~0x01ff) | 1;
162 PLLCR = 0x10800000;
163
164 while (1)
165 {
166 /* check for the ON button (and !hold) */
167 if ((GPIO1_READ & 0x22) == 0)
168 SYPCR = 0xc0;
169 /* Start watchdog timer with 512 cycles timeout. Don't service it. */
170
171 /* We need a reset method that works in all cases. Calling system_reboot()
172 doesn't work when we're called from the debug interrupt, because then
173 the CPU is in emulator mode and the only ways leaving it are exexcuting
174 an rte instruction or performing a reset. Even disabling the breakpoint
175 logic and performing special rte magic doesn't make system_reboot()
176 reliable. The system restarts, but boot often fails with ata error -42. */
177 }
178}
179
180/* reset vectors are handled in crt0.S */
181void (* const vbr[]) (void) __attribute__ ((section (".vectors"))) =
182{
183 UIE,UIE,UIE,UIE,UIE,UIE,
184 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
185 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
186 UIE,UIE,UIE,TIMER0,TIMER1,UIE,UIE,UIE,
187 /* lvl 3 lvl 4 */
188
189 TRAP0,TRAP1,TRAP2,TRAP3,TRAP4,TRAP5,TRAP6,TRAP7,
190 TRAP8,TRAP9,TRAP10,TRAP11,TRAP12,TRAP13,TRAP14,TRAP15,
191
192 SWT,UIE,UIE,I2C,UART1,UART2,DMA0,DMA1,
193 DMA2,DMA3,QSPI,UIE,UIE,UIE,UIE,UIE,
194 PDIR1FULL,PDIR2FULL,EBUTXEMPTY,IIS2TXEMPTY,
195 IIS1TXEMPTY,PDIR3FULL,PDIR3RESYN,UQ2CHANERR,
196 AUDIOTICK,PDIR2RESYN,PDIR2UNOV,PDIR1RESYN,
197 PDIR1UNOV,UQ1CHANERR,IEC2BUFATTEN,IEC2PARERR,
198 IEC2VALNOGOOD,IEC2CNEW,IEC1BUFATTEN,UCHANTXNF,
199 UCHANTXUNDER,UCHANTXEMPTY,PDIR3UNOV,IEC1PARERR,
200 IEC1VALNOGOOD,IEC1CNEW,EBUTXRESYN,EBUTXUNOV,
201 IIS2TXRESYN,IIS2TXUNOV,IIS1TXRESYN,IIS1TXUNOV,
202 GPI0,GPI1,GPI2,GPI3,GPI4,GPI5,GPI6,GPI7,
203 UIE,UIE,UIE,UIE,UIE,UIE,UIE,SOFTINT0,
204 SOFTINT1,SOFTINT2,SOFTINT3,UIE,
205 UIE,CDROMCRCERR,CDROMNOSYNC,CDROMILSYNC,
206 CDROMNEWBLK,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
207
208 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
209 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
210 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
211 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
212 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
213 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
214 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
215 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE
216};
217
218void system_init(void)
219{
220 /* Clear the accumulators. From here on it's the responsibility of
221 whoever uses them to clear them after use (use movclr instruction). */
222 asm volatile ("movclr.l %%acc0, %%d0\n\t"
223 "movclr.l %%acc1, %%d0\n\t"
224 "movclr.l %%acc2, %%d0\n\t"
225 "movclr.l %%acc3, %%d0\n\t"
226 : : : "d0");
227 /* Set EMAC unit to saturating and rounding fractional mode, since that's
228 what'll be the most useful for most things which the main thread
229 will do. */
230 coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE | EMAC_ROUND);
231
232 /* Set INTBASE and SPURVEC */
233 INTBASE = 64;
234 SPURVEC = 24;
235}
236
237void system_reboot (void)
238{
239 set_cpu_frequency(0);
240
241 asm(" move.w #0x2700,%sr");
242 /* Reset the cookie for the crt0 crash check */
243 asm(" move.l #0,%d0");
244 asm(" move.l %d0,0x10017ffc");
245 asm(" movec.l %d0,%vbr");
246 asm(" move.l 0,%sp");
247 asm(" move.l 4,%a0");
248 asm(" jmp (%a0)");
249}
250
251/* Utilise the breakpoint hardware to catch invalid memory accesses. */
252int system_memory_guard(int newmode)
253{
254 static const unsigned long modes[MAXMEMGUARD][8] = {
255 { /* catch nothing */
256 0x2C870000, 0x00000000, /* TDR = 0x00000000 */
257 0x2C8D0000, 0x00000000, /* ABLR = 0x00000000 */
258 0x2C8C0000, 0x00000000, /* ABHR = 0x00000000 */
259 0x2C860000, 0x00050000, /* AATR = 0x0005 */
260 },
261 { /* catch flash ROM writes */
262 0x2C8D0000, 0x00000000, /* ABLR = 0x00000000 */
263 0x2C8C0FFF, 0xFFFF0000, /* ABHR = 0x0FFFFFFF */
264 0x2C860000, 0x6F050000, /* AATR = 0x6F05 */
265 0x2C878000, 0x20080000, /* TDR = 0x80002008 */
266 },
267 { /* catch all accesses to zero area */
268 0x2C8D0000, 0x00000000, /* ABLR = 0x00000000 */
269 0x2C8C0FFF, 0xFFFF0000, /* ABHR = 0x0FFFFFFF */
270 0x2C860000, 0xEF050000, /* AATR = 0xEF05 */
271 0x2C878000, 0x20080000, /* TDR = 0x80002008 */
272 }
273 /* Note: CPU space accesses (movec instruction), interrupt acknowledges
274 and emulator mode accesses are never caught. */
275 };
276 static int cur_mode = MEMGUARD_NONE;
277
278 int oldmode = cur_mode;
279 const unsigned long *ptr;
280 int i;
281
282 if (newmode == MEMGUARD_KEEP)
283 newmode = oldmode;
284
285 /* Always set the new mode, we don't know the old settings
286 as we cannot read back */
287 ptr = modes[newmode];
288 for (i = 0; i < 4; i++)
289 {
290 asm ( "wdebug (%0) \n" : : "a"(ptr));
291 ptr += 2;
292 }
293 cur_mode = newmode;
294
295 return oldmode;
296}
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Alan Korr
11 *
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.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#ifndef SYSTEM_TARGET_H
20#define SYSTEM_TARGET_H
21
22#define or_l(mask, address) \
23 asm \
24 ("or.l %0,(%1)" \
25 : \
26 : /* %0 */ "d"(mask), \
27 /* %1 */ "a"(address))
28
29#define and_l(mask, address) \
30 asm \
31 ("and.l %0,(%1)" \
32 : \
33 : /* %0 */ "d"(mask), \
34 /* %1 */ "a"(address))
35
36#define eor_l(mask, address) \
37 asm \
38 ("eor.l %0,(%1)" \
39 : \
40 : /* %0 */ "d"(mask), \
41 /* %1 */ "a"(address))
42
43#define EMAC_ROUND 0x10
44#define EMAC_FRACTIONAL 0x20
45#define EMAC_SATURATE 0x80
46
47static inline void coldfire_set_macsr(unsigned long flags)
48{
49 asm volatile ("move.l %0, %%macsr" : : "i,r" (flags));
50}
51
52static inline unsigned long coldfire_get_macsr(void)
53{
54 unsigned long m;
55
56 asm volatile ("move.l %%macsr, %0" : "=r" (m));
57 return m;
58}
59
60#define HIGHEST_IRQ_LEVEL (7<<8)
61static inline int set_irq_level(int level)
62{
63 int oldlevel;
64 /* Read the old level and set the new one */
65 asm volatile ("move.w %%sr,%0\n"
66 "or.l #0x2000,%1\n"
67 "move.w %1,%%sr\n" : "=d" (oldlevel), "+d" (level) : );
68 return oldlevel;
69}
70
71static inline unsigned short swap16(unsigned short value)
72 /*
73 result[15..8] = value[ 7..0];
74 result[ 7..0] = value[15..8];
75 */
76{
77 return (value >> 8) | (value << 8);
78}
79
80static inline unsigned long SWAW32(unsigned long value)
81 /*
82 result[31..16] = value[15.. 0];
83 result[15.. 0] = value[31..16];
84 */
85{
86 asm ("swap %%0" : "+r"(value));
87 return value;
88}
89
90static inline unsigned long swap32(unsigned long value)
91 /*
92 result[31..24] = value[ 7.. 0];
93 result[23..16] = value[15.. 8];
94 result[15.. 8] = value[23..16];
95 result[ 7.. 0] = value[31..24];
96 */
97{
98 unsigned long mask = 0x00FF00FF;
99 asm ( /* val = ABCD */
100 "and.l %[val],%[mask] \n" /* mask = .B.D */
101 "eor.l %[mask],%[val] \n" /* val = A.C. */
102 "lsl.l #8,%[mask] \n" /* mask = B.D. */
103 "lsr.l #8,%[val] \n" /* val = .A.C */
104 "or.l %[mask],%[val] \n" /* val = BADC */
105 "swap %[val] \n" /* val = DCBA */
106 : /* outputs */
107 [val] "+d"(value),
108 [mask]"+d"(mask)
109 );
110 return value;
111}
112
113static inline void invalidate_icache(void)
114{
115 asm volatile ("move.l #0x01000000,%d0\n"
116 "movec.l %d0,%cacr\n"
117 "move.l #0x80000000,%d0\n"
118 "movec.l %d0,%cacr");
119}
120
121/* 11.2896 MHz */
122#define CPUFREQ_DEFAULT_MULT 1
123#define CPUFREQ_DEFAULT (CPUFREQ_DEFAULT_MULT * CPU_FREQ)
124/* 45.1584 MHz */
125#define CPUFREQ_NORMAL_MULT 4
126#define CPUFREQ_NORMAL (CPUFREQ_NORMAL_MULT * CPU_FREQ)
127/* 124.1856 MHz */
128#define CPUFREQ_MAX_MULT 11
129#define CPUFREQ_MAX (CPUFREQ_MAX_MULT * CPU_FREQ)
130
131#endif /* SYSTEM_TARGET_H */