source: mainline/kernel/arch/arm32/src/exception.c@ 646b996

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 646b996 was 646b996, checked in by Martin Decky <martin@…>, 16 years ago

cleanup some of the dirty hacks introduced into the arm32 port
add default configurations for the two supported arm32 variants

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/*
2 * Copyright (c) 2007 Petr Stepan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup arm32
30 * @{
31 */
32/** @file
33 * @brief Exception handlers and exception initialization routines.
34 */
35
36#include <arch/exception.h>
37#include <arch/memstr.h>
38#include <arch/regutils.h>
39#include <interrupt.h>
40#include <arch/mm/page_fault.h>
41#include <arch/barrier.h>
42#include <print.h>
43#include <syscall/syscall.h>
44
45#ifdef MACHINE_testarm
46 #include <arch/mach/testarm/testarm.h>
47#endif
48
49#ifdef MACHINE_integratorcp
50 #include <arch/mach/integratorcp/integratorcp.h>
51#endif
52
53/** Offset used in calculation of exception handler's relative address.
54 *
55 * @see install_handler()
56 */
57#define PREFETCH_OFFSET 0x8
58
59/** LDR instruction's code */
60#define LDR_OPCODE 0xe59ff000
61
62/** Number of exception vectors. */
63#define EXC_VECTORS 8
64
65/** Size of memory block occupied by exception vectors. */
66#define EXC_VECTORS_SIZE (EXC_VECTORS * 4)
67
68/** Updates specified exception vector to jump to given handler.
69 *
70 * Addresses of handlers are stored in memory following exception vectors.
71 */
72static void install_handler(unsigned handler_addr, unsigned *vector)
73{
74 /* relative address (related to exc. vector) of the word
75 * where handler's address is stored
76 */
77 volatile uint32_t handler_address_ptr = EXC_VECTORS_SIZE -
78 PREFETCH_OFFSET;
79
80 /* make it LDR instruction and store at exception vector */
81 *vector = handler_address_ptr | LDR_OPCODE;
82 smc_coherence(*vector);
83
84 /* store handler's address */
85 *(vector + EXC_VECTORS) = handler_addr;
86
87}
88
89/** Software Interrupt handler.
90 *
91 * Dispatches the syscall.
92 */
93static void swi_exception(int exc_no, istate_t *istate)
94{
95 istate->r0 = syscall_handler(istate->r0, istate->r1, istate->r2,
96 istate->r3, istate->r4, istate->r5, istate->r6);
97}
98
99/** Fills exception vectors with appropriate exception handlers. */
100void install_exception_handlers(void)
101{
102 install_handler((unsigned) reset_exception_entry,
103 (unsigned *) EXC_RESET_VEC);
104
105 install_handler((unsigned) undef_instr_exception_entry,
106 (unsigned *) EXC_UNDEF_INSTR_VEC);
107
108 install_handler((unsigned) swi_exception_entry,
109 (unsigned *) EXC_SWI_VEC);
110
111 install_handler((unsigned) prefetch_abort_exception_entry,
112 (unsigned *) EXC_PREFETCH_ABORT_VEC);
113
114 install_handler((unsigned) data_abort_exception_entry,
115 (unsigned *) EXC_DATA_ABORT_VEC);
116
117 install_handler((unsigned) irq_exception_entry,
118 (unsigned *) EXC_IRQ_VEC);
119
120 install_handler((unsigned) fiq_exception_entry,
121 (unsigned *) EXC_FIQ_VEC);
122}
123
124#ifdef HIGH_EXCEPTION_VECTORS
125/** Activates use of high exception vectors addresses. */
126static void high_vectors(void)
127{
128 uint32_t control_reg;
129
130 asm volatile (
131 "mrc p15, 0, %[control_reg], c1, c1"
132 : [control_reg] "=r" (control_reg)
133 );
134
135 /* switch on the high vectors bit */
136 control_reg |= CP15_R1_HIGH_VECTORS_BIT;
137
138 asm volatile (
139 "mcr p15, 0, %[control_reg], c1, c1"
140 :: [control_reg] "r" (control_reg)
141 );
142}
143#endif
144
145/** Interrupt Exception handler.
146 *
147 * Determines the sources of interrupt and calls their handlers.
148 */
149static void irq_exception(int exc_no, istate_t *istate)
150{
151 machine_irq_exception(exc_no, istate);
152}
153
154/** Initializes exception handling.
155 *
156 * Installs low-level exception handlers and then registers
157 * exceptions and their handlers to kernel exception dispatcher.
158 */
159void exception_init(void)
160{
161#ifdef HIGH_EXCEPTION_VECTORS
162 high_vectors();
163#endif
164 install_exception_handlers();
165
166 exc_register(EXC_IRQ, "interrupt", (iroutine) irq_exception);
167 exc_register(EXC_PREFETCH_ABORT, "prefetch abort",
168 (iroutine) prefetch_abort);
169 exc_register(EXC_DATA_ABORT, "data abort", (iroutine) data_abort);
170 exc_register(EXC_SWI, "software interrupt", (iroutine) swi_exception);
171}
172
173/** Prints #istate_t structure content.
174 *
175 * @param istate Structure to be printed.
176 */
177void print_istate(istate_t *istate)
178{
179 printf("istate dump:\n");
180
181 printf(" r0: %x r1: %x r2: %x r3: %x\n",
182 istate->r0, istate->r1, istate->r2, istate->r3);
183 printf(" r4: %x r5: %x r6: %x r7: %x\n",
184 istate->r4, istate->r5, istate->r6, istate->r7);
185 printf(" r8: %x r8: %x r10: %x r11: %x\n",
186 istate->r8, istate->r9, istate->r10, istate->r11);
187 printf(" r12: %x sp: %x lr: %x spsr: %x\n",
188 istate->r12, istate->sp, istate->lr, istate->spsr);
189
190 printf(" pc: %x\n", istate->pc);
191}
192
193/** @}
194 */
Note: See TracBrowser for help on using the repository browser.