diff options
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/coldfire/system-coldfire.c | 53 |
1 files changed, 39 insertions, 14 deletions
diff --git a/firmware/target/coldfire/system-coldfire.c b/firmware/target/coldfire/system-coldfire.c index a3bae33a7e..c615d51217 100644 --- a/firmware/target/coldfire/system-coldfire.c +++ b/firmware/target/coldfire/system-coldfire.c | |||
@@ -26,7 +26,7 @@ | |||
26 | extern __attribute__((weak,alias("UIE"))) void name (void) | 26 | extern __attribute__((weak,alias("UIE"))) void name (void) |
27 | 27 | ||
28 | static const char* const irqname[] = { | 28 | static const char* const irqname[] = { |
29 | "", "", "AccessErr","AddrErr","IllInstr", "", "","", | 29 | "", "", "AccessErr","AddrErr","IllInstr", "DivX0", "","", |
30 | "PrivVio","Trace","Line-A", "Line-F","Debug","","FormErr","Uninit", | 30 | "PrivVio","Trace","Line-A", "Line-F","Debug","","FormErr","Uninit", |
31 | "","","","","","","","", | 31 | "","","","","","","","", |
32 | "Spurious","Level1","Level2","Level3","Level4","Level5","Level6","Level7", | 32 | "Spurious","Level1","Level2","Level3","Level4","Level5","Level6","Level7", |
@@ -136,29 +136,39 @@ default_interrupt (CDROMNOSYNC); /* CD-ROM No sync */ | |||
136 | default_interrupt (CDROMILSYNC); /* CD-ROM Illegal sync */ | 136 | default_interrupt (CDROMILSYNC); /* CD-ROM Illegal sync */ |
137 | default_interrupt (CDROMNEWBLK); /* CD-ROM New block */ | 137 | default_interrupt (CDROMNEWBLK); /* CD-ROM New block */ |
138 | 138 | ||
139 | void UIE (void) /* Unexpected Interrupt or Exception */ | 139 | static struct |
140 | { | 140 | { |
141 | unsigned int format_vector, pc; | 141 | unsigned long format; |
142 | int vector; | 142 | unsigned long pc; |
143 | char str[32]; | 143 | } __attribute__ ((packed)) system_exception_info; |
144 | |||
145 | asm volatile ("move.l (52,%%sp),%0": "=r"(format_vector)); | ||
146 | asm volatile ("move.l (56,%%sp),%0": "=r"(pc)); | ||
147 | 144 | ||
148 | vector = (format_vector >> 18) & 0xff; | 145 | static void system_display_exception_info(void) __attribute__ ((noreturn)); |
146 | static void system_display_exception_info(void) | ||
147 | { | ||
148 | int pc = system_exception_info.pc; | ||
149 | int vector = (system_exception_info.format >> 18) & 0xff; | ||
150 | char str[32]; | ||
149 | 151 | ||
150 | /* clear screen */ | 152 | /* clear screen */ |
151 | lcd_clear_display (); | 153 | lcd_clear_display (); |
152 | lcd_setfont(FONT_SYSFIXED); | 154 | lcd_setfont(FONT_SYSFIXED); |
153 | 155 | ||
154 | snprintf(str,sizeof(str),"I%02x:%s",vector,irqname[vector]); | 156 | snprintf(str, sizeof(str), "I%02x:%s", vector, irqname[vector]); |
155 | lcd_puts(0,0,str); | 157 | lcd_puts(0, 0, str); |
156 | snprintf(str,sizeof(str),"at %08x",pc); | 158 | snprintf(str, sizeof(str), "at %08x", pc); |
157 | lcd_puts(0,1,str); | 159 | lcd_puts(0, 1, str); |
158 | lcd_update(); | 160 | lcd_update(); |
159 | 161 | ||
160 | /* set cpu frequency to 11mhz (to prevent overheating) */ | 162 | /* set cpu frequency to 11mhz (to prevent overheating) */ |
161 | DCR = (DCR & ~0x01ff) | 1; | 163 | DCR = (DCR & ~0x01ff) | 1; |
164 | |||
165 | #ifdef IAUDIO_X5 | ||
166 | PLLCR = 0x10400000; | ||
167 | |||
168 | /* on key for 1s will shut down */ | ||
169 | asm("halt"); | ||
170 | while (1); /* loop to silence 'noreturn' function does return */ | ||
171 | #else | ||
162 | PLLCR = 0x10800000; | 172 | PLLCR = 0x10800000; |
163 | 173 | ||
164 | while (1) | 174 | while (1) |
@@ -167,6 +177,8 @@ void UIE (void) /* Unexpected Interrupt or Exception */ | |||
167 | if ((GPIO1_READ & 0x22) == 0) | 177 | if ((GPIO1_READ & 0x22) == 0) |
168 | SYPCR = 0xc0; | 178 | SYPCR = 0xc0; |
169 | /* Start watchdog timer with 512 cycles timeout. Don't service it. */ | 179 | /* Start watchdog timer with 512 cycles timeout. Don't service it. */ |
180 | } | ||
181 | #endif | ||
170 | 182 | ||
171 | /* We need a reset method that works in all cases. Calling system_reboot() | 183 | /* 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 | 184 | doesn't work when we're called from the debug interrupt, because then |
@@ -174,7 +186,20 @@ void UIE (void) /* Unexpected Interrupt or Exception */ | |||
174 | an rte instruction or performing a reset. Even disabling the breakpoint | 186 | an rte instruction or performing a reset. Even disabling the breakpoint |
175 | logic and performing special rte magic doesn't make system_reboot() | 187 | logic and performing special rte magic doesn't make system_reboot() |
176 | reliable. The system restarts, but boot often fails with ata error -42. */ | 188 | reliable. The system restarts, but boot often fails with ata error -42. */ |
177 | } | 189 | } |
190 | |||
191 | static void UIE(void) __attribute__ ((noreturn)); | ||
192 | static void UIE(void) | ||
193 | { | ||
194 | asm volatile ( | ||
195 | "movem.l (%%sp),%%d0-%%d1 \n" /* Copy exception frame */ | ||
196 | "lea.l %[info],%%a0 \n" | ||
197 | "movem.l %%d0-%%d1,(%%a0) \n" | ||
198 | : | ||
199 | : [info] "m" (system_exception_info) | ||
200 | ); | ||
201 | |||
202 | system_display_exception_info(); | ||
178 | } | 203 | } |
179 | 204 | ||
180 | /* reset vectors are handled in crt0.S */ | 205 | /* reset vectors are handled in crt0.S */ |