1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006 by Thom Johansen
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
27 static const char* const uiename
[] = {
28 "Undefined instruction",
34 /* Unexpected Interrupt or Exception handler. Currently only deals with
35 exceptions, but will deal with interrupts later.
37 void __attribute__((noreturn
)) UIE(unsigned int pc
, unsigned int num
)
40 lcd_set_backdrop(NULL
);
41 lcd_set_drawmode(DRMODE_SOLID
);
42 lcd_set_foreground(LCD_BLACK
);
43 lcd_set_background(LCD_WHITE
);
47 lcd_setfont(FONT_SYSFIXED
);
48 lcd_set_viewport(NULL
);
50 lcd_puts(0, line
++, uiename
[num
]);
51 lcd_putsf(0, line
++, "at %08x" IF_COP(" (%d)"), pc
52 IF_COP(, CURRENT_CORE
));
54 #if !defined(CPU_ARM7TDMI) /* arm7tdmi has no MPU/MMU */
55 if(num
== 1 || num
== 2) /* prefetch / data abort */
57 register unsigned status
;
60 /* ARMv6 has 2 different registers for prefetch & data aborts */
61 if(num
== 1) /* instruction prefetch abort */
62 asm volatile( "mrc p15, 0, %0, c5, c0, 1\n" : "=r"(status
));
65 asm volatile( "mrc p15, 0, %0, c5, c0, 0\n" : "=r"(status
));
67 lcd_putsf(0, line
++, "FSR 0x%x", status
);
69 unsigned int domain
= (status
>> 4) & 0xf;
70 unsigned int fault
= status
& 0xf;
72 fault
|= (status
& (1<<10)) >> 6; /* fault is 5 bits on armv6 */
74 lcd_putsf(0, line
++, "(domain %d, fault %d)", domain
, fault
);
76 if(num
== 2) /* data abort */
78 register unsigned address
;
79 /* read FAR (fault address register) */
80 asm volatile( "mrc p15, 0, %0, c6, c0\n" : "=r"(address
));
81 lcd_putsf(0, line
++, "address 0x%8x", address
);
83 lcd_putsf(0, line
++, (status
& (1<<11)) ? "(write)" : "(read)");
86 } /* num == 1 || num == 2 // prefetch/data abort */
87 #endif /* !defined(CPU_ARM7TDMI */
91 disable_interrupt(IRQ_FIQ_STATUS
);
93 system_exception_wait(); /* If this returns, try to reboot */
98 /* Needs to be here or gcc won't find it */
99 void __attribute__((naked
)) __div0(void)
103 "sub r0, r0, #4 \r\n"