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 ****************************************************************************/
26 #include "gcc_extensions.h"
28 static const char* const uiename
[] = {
29 "Undefined instruction",
35 /* Unexpected Interrupt or Exception handler. Currently only deals with
36 exceptions, but will deal with interrupts later.
38 void NORETURN_ATTR
UIE(unsigned int pc
, unsigned int num
)
41 lcd_set_backdrop(NULL
);
42 lcd_set_drawmode(DRMODE_SOLID
);
43 lcd_set_foreground(LCD_BLACK
);
44 lcd_set_background(LCD_WHITE
);
48 lcd_setfont(FONT_SYSFIXED
);
49 lcd_set_viewport(NULL
);
51 lcd_puts(0, line
++, uiename
[num
]);
52 lcd_putsf(0, line
++, "at %08x" IF_COP(" (%d)"), pc
53 IF_COP(, CURRENT_CORE
));
55 #if !defined(CPU_ARM7TDMI) /* arm7tdmi has no MPU/MMU */
56 if(num
== 1 || num
== 2) /* prefetch / data abort */
58 register unsigned status
;
61 /* ARMv6 has 2 different registers for prefetch & data aborts */
62 if(num
== 1) /* instruction prefetch abort */
63 asm volatile( "mrc p15, 0, %0, c5, c0, 1\n" : "=r"(status
));
66 asm volatile( "mrc p15, 0, %0, c5, c0, 0\n" : "=r"(status
));
68 lcd_putsf(0, line
++, "FSR 0x%x", status
);
70 unsigned int domain
= (status
>> 4) & 0xf;
71 unsigned int fault
= status
& 0xf;
73 fault
|= (status
& (1<<10)) >> 6; /* fault is 5 bits on armv6 */
75 lcd_putsf(0, line
++, "(domain %d, fault %d)", domain
, fault
);
77 if(num
== 2) /* data abort */
79 register unsigned address
;
80 /* read FAR (fault address register) */
81 asm volatile( "mrc p15, 0, %0, c6, c0\n" : "=r"(address
));
82 lcd_putsf(0, line
++, "address 0x%8x", address
);
84 lcd_putsf(0, line
++, (status
& (1<<11)) ? "(write)" : "(read)");
87 } /* num == 1 || num == 2 // prefetch/data abort */
88 #endif /* !defined(CPU_ARM7TDMI */
92 disable_interrupt(IRQ_FIQ_STATUS
);
94 system_exception_wait(); /* If this returns, try to reboot */
99 /* Needs to be here or gcc won't find it */
100 void __attribute__((naked
)) __div0(void)
104 "sub r0, r0, #4 \r\n"