Prepare new maemo release
[maemo-rb.git] / firmware / target / arm / system-arm.c
blobe687e1d82b715b17efd2c8620708154432941a3e
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
21 #include "config.h"
22 #include "system.h"
23 #include <stdio.h>
24 #include "lcd.h"
25 #include "font.h"
26 #include "gcc_extensions.h"
28 #include <get_sp.h>
29 #include <backtrace.h>
31 static const char* const uiename[] = {
32 "Undefined instruction",
33 "Prefetch abort",
34 "Data abort",
35 "Divide by zero",
36 "SWI"
39 void __attribute__((weak,naked)) data_abort_handler(void)
41 asm volatile(
42 "sub r0, lr, #8 \n"
43 "mov r1, #2 \n"
44 "b UIE \n"
48 void __attribute__((weak,naked)) software_int_handler(void)
50 asm volatile(
51 "sub r0, lr, #4 \n"
52 "mov r1, #4 \n"
53 "b UIE \n"
57 void __attribute__((weak,naked)) reserved_handler(void)
59 asm volatile(
60 "sub r0, lr, #4 \n"
61 "mov r1, #4 \n"
62 "b UIE \n"
66 void __attribute__((weak,naked)) prefetch_abort_handler(void)
68 asm volatile(
69 "sub r0, lr, #4 \n"
70 "mov r1, #1 \n"
71 "b UIE \n"
75 void __attribute__((weak,naked)) undef_instr_handler(void)
77 asm volatile(
78 "sub r0, lr, #4 \n"
79 #ifdef USE_THUMB
80 "mrs r1, spsr \n"
81 "tst r1, #(1 << 5) \n" // T bit set ?
82 "subne r0, lr, #2 \n" // if yes, offset to THUMB instruction
83 #endif
84 "mov r1, #0 \n"
85 "b UIE \n"
89 /* Unexpected Interrupt or Exception handler. Currently only deals with
90 exceptions, but will deal with interrupts later.
92 void NORETURN_ATTR UIE(unsigned int pc, unsigned int num)
94 /* safe guard variable - we call backtrace() only on first
95 * UIE call. This prevent endless loop if backtrace() touches
96 * memory regions which cause abort
98 static bool triggered = false;
100 #if LCD_DEPTH > 1
101 lcd_set_backdrop(NULL);
102 lcd_set_drawmode(DRMODE_SOLID);
103 lcd_set_foreground(LCD_BLACK);
104 lcd_set_background(LCD_WHITE);
105 #endif
106 unsigned line = 0;
108 lcd_setfont(FONT_SYSFIXED);
109 lcd_set_viewport(NULL);
110 lcd_clear_display();
111 lcd_putsf(0, line++, "%s at %08x" IF_COP(" (%d)"), uiename[num], pc IF_COP(, CURRENT_CORE));
113 #if !defined(CPU_ARM7TDMI) && (CONFIG_CPU != RK27XX) /* arm7tdmi has no MPU/MMU */
114 if(num == 1 || num == 2) /* prefetch / data abort */
116 register unsigned status;
118 #if ARM_ARCH >= 6
119 /* ARMv6 has 2 different registers for prefetch & data aborts */
120 if(num == 1) /* instruction prefetch abort */
121 asm volatile( "mrc p15, 0, %0, c5, c0, 1\n" : "=r"(status));
122 else
123 #endif
124 asm volatile( "mrc p15, 0, %0, c5, c0, 0\n" : "=r"(status));
126 lcd_putsf(0, line++, "FSR 0x%x", status);
128 unsigned int domain = (status >> 4) & 0xf;
129 unsigned int fault = status & 0xf;
130 #if ARM_ARCH >= 6
131 fault |= (status & (1<<10)) >> 6; /* fault is 5 bits on armv6 */
132 #endif
133 lcd_putsf(0, line++, "(domain %d, fault %d)", domain, fault);
135 if(num == 2) /* data abort */
137 register unsigned address;
138 /* read FAR (fault address register) */
139 asm volatile( "mrc p15, 0, %0, c6, c0\n" : "=r"(address));
140 lcd_putsf(0, line++, "address 0x%8x", address);
141 #if ARM_ARCH >= 6
142 lcd_putsf(0, line++, (status & (1<<11)) ? "(write)" : "(read)");
143 #endif
145 } /* num == 1 || num == 2 // prefetch/data abort */
146 #endif /* !defined(CPU_ARM7TDMI */
148 if (!triggered)
150 triggered = true;
151 backtrace(pc, __get_sp(), &line);
154 lcd_update();
156 disable_interrupt(IRQ_FIQ_STATUS);
158 system_exception_wait(); /* If this returns, try to reboot */
159 system_reboot();
160 while (1); /* halt */
163 /* Needs to be here or gcc won't find it */
164 void __attribute__((naked)) __div0(void)
166 asm volatile (
167 "ldr r0, [sp] \r\n"
168 "sub r0, r0, #4 \r\n"
169 "mov r1, #3 \r\n"
170 "b UIE \r\n"