Allow ColdFire targets to be buildt with GCC >= 4.1.0.
[kugel-rb.git] / firmware / target / coldfire / system-coldfire.c
blobf33a44c3b4ecae19bc518c72a8830a1d27404081
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 "system.h"
22 #include "lcd.h"
23 #include "font.h"
25 #define default_interrupt(name) \
26 extern __attribute__((weak,alias("UIE"))) void name (void)
28 static const char* const irqname[] = {
29 "", "", "AccessErr","AddrErr","IllInstr", "DivX0", "","",
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 "","","","","","","",""
60 default_interrupt (TRAP0); /* Trap #0 */
61 default_interrupt (TRAP1); /* Trap #1 */
62 default_interrupt (TRAP2); /* Trap #2 */
63 default_interrupt (TRAP3); /* Trap #3 */
64 default_interrupt (TRAP4); /* Trap #4 */
65 default_interrupt (TRAP5); /* Trap #5 */
66 default_interrupt (TRAP6); /* Trap #6 */
67 default_interrupt (TRAP7); /* Trap #7 */
68 default_interrupt (TRAP8); /* Trap #8 */
69 default_interrupt (TRAP9); /* Trap #9 */
70 default_interrupt (TRAP10); /* Trap #10 */
71 default_interrupt (TRAP11); /* Trap #11 */
72 default_interrupt (TRAP12); /* Trap #12 */
73 default_interrupt (TRAP13); /* Trap #13 */
74 default_interrupt (TRAP14); /* Trap #14 */
75 default_interrupt (TRAP15); /* Trap #15 */
76 default_interrupt (SWT); /* Software Watchdog Timer */
77 default_interrupt (TIMER0); /* Timer 0 */
78 default_interrupt (TIMER1); /* Timer 1 */
79 default_interrupt (I2C); /* I2C */
80 default_interrupt (UART1); /* UART 1 */
81 default_interrupt (UART2); /* UART 2 */
82 default_interrupt (DMA0); /* DMA 0 */
83 default_interrupt (DMA1); /* DMA 1 */
84 default_interrupt (DMA2); /* DMA 2 */
85 default_interrupt (DMA3); /* DMA 3 */
86 default_interrupt (QSPI); /* QSPI */
88 default_interrupt (PDIR1FULL); /* Processor data in 1 full */
89 default_interrupt (PDIR2FULL); /* Processor data in 2 full */
90 default_interrupt (EBUTXEMPTY); /* EBU transmit FIFO empty */
91 default_interrupt (IIS2TXEMPTY); /* IIS2 transmit FIFO empty */
92 default_interrupt (IIS1TXEMPTY); /* IIS1 transmit FIFO empty */
93 default_interrupt (PDIR3FULL); /* Processor data in 3 full */
94 default_interrupt (PDIR3RESYN); /* Processor data in 3 resync */
95 default_interrupt (UQ2CHANERR); /* IEC958-2 Rx U/Q channel error */
96 default_interrupt (AUDIOTICK); /* "tick" interrupt */
97 default_interrupt (PDIR2RESYN); /* Processor data in 2 resync */
98 default_interrupt (PDIR2UNOV); /* Processor data in 2 under/overrun */
99 default_interrupt (PDIR1RESYN); /* Processor data in 1 resync */
100 default_interrupt (PDIR1UNOV); /* Processor data in 1 under/overrun */
101 default_interrupt (UQ1CHANERR); /* IEC958-1 Rx U/Q channel error */
102 default_interrupt (IEC2BUFATTEN);/* IEC958-2 channel buffer full */
103 default_interrupt (IEC2PARERR); /* IEC958-2 Rx parity or symbol error */
104 default_interrupt (IEC2VALNOGOOD);/* IEC958-2 flag not good */
105 default_interrupt (IEC2CNEW); /* IEC958-2 New C-channel received */
106 default_interrupt (IEC1BUFATTEN);/* IEC958-1 channel buffer full */
107 default_interrupt (UCHANTXNF); /* U channel Tx reg next byte is first */
108 default_interrupt (UCHANTXUNDER);/* U channel Tx reg underrun */
109 default_interrupt (UCHANTXEMPTY);/* U channel Tx reg is empty */
110 default_interrupt (PDIR3UNOV); /* Processor data in 3 under/overrun */
111 default_interrupt (IEC1PARERR); /* IEC958-1 Rx parity or symbol error */
112 default_interrupt (IEC1VALNOGOOD);/* IEC958-1 flag not good */
113 default_interrupt (IEC1CNEW); /* IEC958-1 New C-channel received */
114 default_interrupt (EBUTXRESYN); /* EBU Tx FIFO resync */
115 default_interrupt (EBUTXUNOV); /* EBU Tx FIFO under/overrun */
116 default_interrupt (IIS2TXRESYN); /* IIS2 Tx FIFO resync */
117 default_interrupt (IIS2TXUNOV); /* IIS2 Tx FIFO under/overrun */
118 default_interrupt (IIS1TXRESYN); /* IIS1 Tx FIFO resync */
119 default_interrupt (IIS1TXUNOV); /* IIS1 Tx FIFO under/overrun */
120 default_interrupt (GPI0); /* GPIO interrupt 0 */
121 default_interrupt (GPI1); /* GPIO interrupt 1 */
122 default_interrupt (GPI2); /* GPIO interrupt 2 */
123 default_interrupt (GPI3); /* GPIO interrupt 3 */
124 default_interrupt (GPI4); /* GPIO interrupt 4 */
125 default_interrupt (GPI5); /* GPIO interrupt 5 */
126 default_interrupt (GPI6); /* GPIO interrupt 6 */
127 default_interrupt (GPI7); /* GPIO interrupt 7 */
129 default_interrupt (SOFTINT0); /* Software interrupt 0 */
130 default_interrupt (SOFTINT1); /* Software interrupt 1 */
131 default_interrupt (SOFTINT2); /* Software interrupt 2 */
132 default_interrupt (SOFTINT3); /* Software interrupt 3 */
134 default_interrupt (CDROMCRCERR); /* CD-ROM CRC error */
135 default_interrupt (CDROMNOSYNC); /* CD-ROM No sync */
136 default_interrupt (CDROMILSYNC); /* CD-ROM Illegal sync */
137 default_interrupt (CDROMNEWBLK); /* CD-ROM New block */
139 #if defined(IAUDIO_X5) || defined(IAUDIO_M5)
140 #define EXCP_BUTTON_GPIO_READ GPIO_READ
141 #define EXCP_BUTTON_MASK 0x0c000000
142 #define EXCP_BUTTON_VALUE 0x08000000 /* On button and !hold */
143 #define EXCP_PLLCR 0x10400000
144 #else
145 #define EXCP_BUTTON_GPIO_READ GPIO1_READ
146 #define EXCP_BUTTON_MASK 0x00000022
147 #define EXCP_BUTTON_VALUE 0x00000000
148 #define EXCP_PLLCR 0x10800000
149 #endif
151 static void system_display_exception_info(unsigned long format,
152 unsigned long pc) __attribute__ ((noreturn, used));
153 static void system_display_exception_info(unsigned long format,
154 unsigned long pc)
156 int vector = (format >> 18) & 0xff;
157 char str[32];
159 /* clear screen */
160 lcd_clear_display ();
161 lcd_setfont(FONT_SYSFIXED);
163 snprintf(str, sizeof(str), "I%02x:%s", vector, irqname[vector]);
164 lcd_puts(0, 0, str);
165 snprintf(str, sizeof(str), "at %08x", pc);
166 lcd_puts(0, 1, str);
167 lcd_update();
169 /* set cpu frequency to 11mhz (to prevent overheating) */
170 DCR = (DCR & ~0x01ff) | 1;
171 PLLCR = EXCP_PLLCR;
173 while (1)
175 if ((EXCP_BUTTON_GPIO_READ & EXCP_BUTTON_MASK) == EXCP_BUTTON_VALUE)
176 SYPCR = 0xc0;
177 /* Start watchdog timer with 512 cycles timeout. Don't service it. */
180 /* We need a reset method that works in all cases. Calling system_reboot()
181 doesn't work when we're called from the debug interrupt, because then
182 the CPU is in emulator mode and the only ways leaving it are exexcuting
183 an rte instruction or performing a reset. Even disabling the breakpoint
184 logic and performing special rte magic doesn't make system_reboot()
185 reliable. The system restarts, but boot often fails with ata error -42. */
188 static void UIE(void) __attribute__ ((noreturn));
189 static void UIE(void)
191 asm volatile("subq.l #4,%sp"); /* phony return address - never used */
192 asm volatile("jmp system_display_exception_info");
193 while (1); /* loop to silence 'noreturn' function does return */
196 /* reset vectors are handled in crt0.S */
197 void (* const vbr[]) (void) __attribute__ ((section (".vectors"))) =
199 UIE,UIE,UIE,UIE,UIE,UIE,
200 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
201 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
202 UIE,UIE,UIE,TIMER0,TIMER1,UIE,UIE,UIE,
203 /* lvl 3 lvl 4 */
205 TRAP0,TRAP1,TRAP2,TRAP3,TRAP4,TRAP5,TRAP6,TRAP7,
206 TRAP8,TRAP9,TRAP10,TRAP11,TRAP12,TRAP13,TRAP14,TRAP15,
208 SWT,UIE,UIE,I2C,UART1,UART2,DMA0,DMA1,
209 DMA2,DMA3,QSPI,UIE,UIE,UIE,UIE,UIE,
210 PDIR1FULL,PDIR2FULL,EBUTXEMPTY,IIS2TXEMPTY,
211 IIS1TXEMPTY,PDIR3FULL,PDIR3RESYN,UQ2CHANERR,
212 AUDIOTICK,PDIR2RESYN,PDIR2UNOV,PDIR1RESYN,
213 PDIR1UNOV,UQ1CHANERR,IEC2BUFATTEN,IEC2PARERR,
214 IEC2VALNOGOOD,IEC2CNEW,IEC1BUFATTEN,UCHANTXNF,
215 UCHANTXUNDER,UCHANTXEMPTY,PDIR3UNOV,IEC1PARERR,
216 IEC1VALNOGOOD,IEC1CNEW,EBUTXRESYN,EBUTXUNOV,
217 IIS2TXRESYN,IIS2TXUNOV,IIS1TXRESYN,IIS1TXUNOV,
218 GPI0,GPI1,GPI2,GPI3,GPI4,GPI5,GPI6,GPI7,
219 UIE,UIE,UIE,UIE,UIE,UIE,UIE,SOFTINT0,
220 SOFTINT1,SOFTINT2,SOFTINT3,UIE,
221 UIE,CDROMCRCERR,CDROMNOSYNC,CDROMILSYNC,
222 CDROMNEWBLK,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
224 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
225 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
226 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
227 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
228 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
229 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
230 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,
231 UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE,UIE
234 void system_init(void)
236 /* Clear the accumulators. From here on it's the responsibility of
237 whoever uses them to clear them after use and before giving control
238 to "foreign" code (use movclr instruction). */
239 asm volatile ("movclr.l %%acc0, %%d0\n\t"
240 "movclr.l %%acc1, %%d0\n\t"
241 "movclr.l %%acc2, %%d0\n\t"
242 "movclr.l %%acc3, %%d0\n\t"
243 : : : "d0");
245 /* Set EMAC unit to fractional mode with saturation, since that's
246 what'll be the most useful for most things which the main thread
247 will do. */
248 coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE);
250 /* Set INTBASE and SPURVEC */
251 INTBASE = 64;
252 SPURVEC = 24;
254 MPARK = 0x81; /* PARK[1,0]=10 + BCR24BIT */
257 void system_reboot (void)
259 set_cpu_frequency(0);
261 asm(" move.w #0x2700,%sr");
262 /* Reset the cookie for the crt0 crash check */
263 asm(" move.l #0,%d0");
264 asm(" move.l %d0,0x10017ffc");
265 asm(" movec.l %d0,%vbr");
266 asm(" move.l 0,%sp");
267 asm(" move.l 4,%a0");
268 asm(" jmp (%a0)");
271 /* Utilise the breakpoint hardware to catch invalid memory accesses. */
272 int system_memory_guard(int newmode)
274 static const unsigned long modes[MAXMEMGUARD][8] = {
275 { /* catch nothing */
276 0x2C870000, 0x00000000, /* TDR = 0x00000000 */
277 0x2C8D0000, 0x00000000, /* ABLR = 0x00000000 */
278 0x2C8C0000, 0x00000000, /* ABHR = 0x00000000 */
279 0x2C860000, 0x00050000, /* AATR = 0x0005 */
281 { /* catch flash ROM writes */
282 0x2C8D0000, 0x00000000, /* ABLR = 0x00000000 */
283 0x2C8C0FFF, 0xFFFF0000, /* ABHR = 0x0FFFFFFF */
284 0x2C860000, 0x6F050000, /* AATR = 0x6F05 */
285 0x2C878000, 0x20080000, /* TDR = 0x80002008 */
287 { /* catch all accesses to zero area */
288 0x2C8D0000, 0x00000000, /* ABLR = 0x00000000 */
289 0x2C8C0FFF, 0xFFFF0000, /* ABHR = 0x0FFFFFFF */
290 0x2C860000, 0xEF050000, /* AATR = 0xEF05 */
291 0x2C878000, 0x20080000, /* TDR = 0x80002008 */
293 /* Note: CPU space accesses (movec instruction), interrupt acknowledges
294 and emulator mode accesses are never caught. */
296 static int cur_mode = MEMGUARD_NONE;
298 int oldmode = cur_mode;
299 const unsigned long *ptr;
300 int i;
302 if (newmode == MEMGUARD_KEEP)
303 newmode = oldmode;
305 /* Always set the new mode, we don't know the old settings
306 as we cannot read back */
307 ptr = modes[newmode];
308 for (i = 0; i < 4; i++)
310 asm ( "wdebug (%0) \n" : : "a"(ptr));
311 ptr += 2;
313 cur_mode = newmode;
315 return oldmode;
318 /* allow setting of audio clock related bits */
319 void coldfire_set_pllcr_audio_bits(long bits)
321 PLLCR = (PLLCR & ~0x70400000) | (bits & 0x70400000);
324 /* Set DATAINCONTROL without disturbing FIFO reset state */
325 void coldfire_set_dataincontrol(unsigned long value)
327 /* Have to be atomic against recording stop initiated by DMA1 */
328 int level = set_irq_level(DMA_IRQ_LEVEL);
329 DATAINCONTROL = (DATAINCONTROL & (1 << 9)) | value;
330 set_irq_level(level);