Subversion Repositories HelenOS

Rev

Rev 2326 | Rev 2341 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2326 Rev 2329
Line 31... Line 31...
31
 */
31
 */
32
/** @file
32
/** @file
33
    @brief  Exception handlers and exception initialization routines.
33
    @brief  Exception handlers and exception initialization routines.
34
 */
34
 */
35
 
35
 
-
 
36
 
36
#include <arch/exception.h>
37
#include <arch/exception.h>
37
#include <arch/debug/print.h>
38
#include <arch/debug/print.h>
38
#include <arch/memstr.h>
39
#include <arch/memstr.h>
39
#include <arch/regutils.h>
40
#include <arch/regutils.h>
40
#include <interrupt.h>
41
#include <interrupt.h>
41
#include <arch/machine.h>
42
#include <arch/machine.h>
42
#include <arch/mm/page_fault.h>
43
#include <arch/mm/page_fault.h>
43
#include <print.h>
44
#include <print.h>
44
#include <syscall/syscall.h>
45
#include <syscall/syscall.h>
45
 
46
 
-
 
47
 
46
#define PREFETCH_OFFSET      0x8
48
#define PREFETCH_OFFSET      0x8
47
#define BRANCH_OPCODE        0xea000000
49
#define BRANCH_OPCODE        0xea000000
48
#define LDR_OPCODE           0xe59ff000
50
#define LDR_OPCODE           0xe59ff000
49
#define VALID_BRANCH_MASK    0xff000000
51
#define VALID_BRANCH_MASK    0xff000000
50
#define EXC_VECTORS_SIZE     0x20
52
#define EXC_VECTORS_SIZE     0x20
51
#define EXC_VECTORS          0x8
53
#define EXC_VECTORS          0x8
52
 
54
 
-
 
55
 
53
extern uintptr_t supervisor_sp;
56
extern uintptr_t supervisor_sp;
54
extern uintptr_t exc_stack;
57
extern uintptr_t exc_stack;
55
 
58
 
-
 
59
 
56
inline static void setup_stack_and_save_regs()
60
inline static void setup_stack_and_save_regs()
57
{
61
{
58
asm volatile(   "ldr r13, =exc_stack        \n\
62
asm volatile(   "ldr r13, =exc_stack        \n\
59
    stmfd r13!, {r0}            \n\
63
    stmfd r13!, {r0}            \n\
60
    mrs r0, spsr                \n\
64
    mrs r0, spsr                \n\
Line 162... Line 166...
162
 
166
 
163
   
167
   
164
/** General exception handler.
168
/** General exception handler.
165
 *  Stores registers, dispatches the exception,
169
 *  Stores registers, dispatches the exception,
166
 *  and finally restores registers and returns from exception processing.
170
 *  and finally restores registers and returns from exception processing.
-
 
171
 *
-
 
172
 *  @param exception Exception number.
167
 */
173
 */
168
 
-
 
169
#define PROCESS_EXCEPTION(exception)        \
174
#define PROCESS_EXCEPTION(exception)        \
170
    setup_stack_and_save_regs();        \
175
    setup_stack_and_save_regs();        \
171
    CALL_EXC_DISPATCH(exception)        \
176
    CALL_EXC_DISPATCH(exception)        \
172
    load_regs();
177
    load_regs();
173
 
178
 
174
/* #define PROCESS_EXCEPTION(exception)     \
179
/* #define PROCESS_EXCEPTION(exception)     \
175
    SAVE_REGS_TO_STACK      \
180
    SAVE_REGS_TO_STACK      \
176
    CALL_EXC_DISPATCH(exception)        \
181
    CALL_EXC_DISPATCH(exception)        \
177
    LOAD_REGS_FROM_STACK*/
182
    LOAD_REGS_FROM_STACK*/
178
 
183
 
-
 
184
 
179
/** Updates specified exception vector to jump to given handler.
185
/** Updates specified exception vector to jump to given handler.
180
 * Addresses of handlers are stored in memory following exception vectors.
186
 *  Addresses of handlers are stored in memory following exception vectors.
181
 */
187
 */
182
static void install_handler (unsigned handler_addr, unsigned* vector)
188
static void install_handler (unsigned handler_addr, unsigned* vector)
183
{
189
{
184
    /* relative address (related to exc. vector) of the word
190
    /* relative address (related to exc. vector) of the word
185
     * where handler's address is stored
191
     * where handler's address is stored
Line 193... Line 199...
193
    *(vector + EXC_VECTORS) = handler_addr;
199
    *(vector + EXC_VECTORS) = handler_addr;
194
 
200
 
195
}
201
}
196
 
202
 
197
 
203
 
-
 
204
/** Low-level Reset Exception handler. */
198
static void reset_exception_entry()
205
static void reset_exception_entry()
199
{
206
{
200
    PROCESS_EXCEPTION(EXC_RESET);
207
    PROCESS_EXCEPTION(EXC_RESET);
201
}
208
}
202
 
209
 
-
 
210
 
203
/** Low-level Software Interrupt Exception handler */
211
/** Low-level Software Interrupt Exception handler. */
204
static void swi_exception_entry()
212
static void swi_exception_entry()
205
{
213
{
206
    PROCESS_EXCEPTION(EXC_SWI);
214
    PROCESS_EXCEPTION(EXC_SWI);
207
}
215
}
208
 
216
 
-
 
217
 
209
/** Low-level Undefined Instruction Exception handler */
218
/** Low-level Undefined Instruction Exception handler. */
210
static void undef_instr_exception_entry()
219
static void undef_instr_exception_entry()
211
{
220
{
212
    PROCESS_EXCEPTION(EXC_UNDEF_INSTR);
221
    PROCESS_EXCEPTION(EXC_UNDEF_INSTR);
213
}
222
}
214
 
223
 
-
 
224
 
215
/** Low-level Fast Interrupt Exception handler */
225
/** Low-level Fast Interrupt Exception handler. */
216
static void fiq_exception_entry()
226
static void fiq_exception_entry()
217
{
227
{
218
    PROCESS_EXCEPTION(EXC_FIQ);
228
    PROCESS_EXCEPTION(EXC_FIQ);
219
}
229
}
220
 
230
 
-
 
231
 
221
/** Low-level Prefetch Abort Exception handler */
232
/** Low-level Prefetch Abort Exception handler. */
222
static void prefetch_abort_exception_entry()
233
static void prefetch_abort_exception_entry()
223
{
234
{
224
    asm("sub lr, lr, #4");
235
    asm("sub lr, lr, #4");
225
    PROCESS_EXCEPTION(EXC_PREFETCH_ABORT);
236
    PROCESS_EXCEPTION(EXC_PREFETCH_ABORT);
226
}
237
}
227
 
238
 
-
 
239
 
228
/** Low-level Data Abort Exception handler */
240
/** Low-level Data Abort Exception handler. */
229
static void data_abort_exception_entry()
241
static void data_abort_exception_entry()
230
{
242
{
231
    asm("sub lr, lr, #8");
243
    asm("sub lr, lr, #8");
232
    PROCESS_EXCEPTION(EXC_DATA_ABORT);
244
    PROCESS_EXCEPTION(EXC_DATA_ABORT);
233
}
245
}
234
 
246
 
235
 
247
 
236
/** Low-level Interrupt Exception handler */
248
/** Low-level Interrupt Exception handler. */
237
static void irq_exception_entry()
249
static void irq_exception_entry()
238
{
250
{
239
    asm("sub lr, lr, #4");
251
    asm("sub lr, lr, #4");
240
    PROCESS_EXCEPTION(EXC_IRQ);
252
    PROCESS_EXCEPTION(EXC_IRQ);
241
}
253
}
242
 
254
 
-
 
255
 
243
/** Software Interrupt handler.
256
/** Software Interrupt handler.
244
 *
257
 *
245
 * Dispatches the syscall.
258
 * Dispatches the syscall.
246
 */
259
 */
247
static void swi_exception(int exc_no, istate_t *istate)
260
static void swi_exception(int exc_no, istate_t *istate)
Line 255... Line 268...
255
        istate->r2,
268
        istate->r2,
256
        istate->r3,
269
        istate->r3,
257
        istate->r4);
270
        istate->r4);
258
}
271
}
259
 
272
 
-
 
273
 
260
/** Interrupt Exception handler.
274
/** Interrupt Exception handler.
261
 *
275
 *
262
 * Determines the sources of interrupt, and calls their handlers.
276
 * Determines the sources of interrupt, and calls their handlers.
263
 */
277
 */
264
static void irq_exception(int exc_no, istate_t *istate)
278
static void irq_exception(int exc_no, istate_t *istate)
265
{
279
{
266
    machine_irq_exception(exc_no, istate);
280
    machine_irq_exception(exc_no, istate);
267
}
281
}
268
 
282
 
-
 
283
 
269
/** Fills exception vectors with appropriate exception handlers.
284
/** Fills exception vectors with appropriate exception handlers. */
270
*/
-
 
271
void install_exception_handlers(void)
285
void install_exception_handlers(void)
272
{
286
{
273
    install_handler((unsigned)reset_exception_entry,
287
    install_handler((unsigned)reset_exception_entry,
274
             (unsigned*)EXC_RESET_VEC);
288
             (unsigned*)EXC_RESET_VEC);
275
   
289
   
Line 290... Line 304...
290
   
304
   
291
    install_handler((unsigned)fiq_exception_entry,
305
    install_handler((unsigned)fiq_exception_entry,
292
             (unsigned*)EXC_FIQ_VEC);
306
             (unsigned*)EXC_FIQ_VEC);
293
}
307
}
294
 
308
 
-
 
309
 
295
#ifdef HIGH_EXCEPTION_VECTORS
310
#ifdef HIGH_EXCEPTION_VECTORS
296
/** Activates using high exception vectors addresses. */
311
/** Activates use of high exception vectors addresses. */
297
 static void high_vectors()
312
static void high_vectors()
298
{
313
{
299
    uint32_t control_reg;
314
    uint32_t control_reg;
300
   
315
   
301
    asm volatile( "mrc p15, 0, %0, c1, c1": "=r" (control_reg));
316
    asm volatile( "mrc p15, 0, %0, c1, c1": "=r" (control_reg));
302
   
317
   
Line 326... Line 341...
326
    exc_register(EXC_SWI, "software interrupt", (iroutine) swi_exception);
341
    exc_register(EXC_SWI, "software interrupt", (iroutine) swi_exception);
327
    /* TODO add next */
342
    /* TODO add next */
328
}
343
}
329
 
344
 
330
 
345
 
331
/** Sets stack pointers in all supported exception modes.
346
/** Sets stack pointers in all supported exception modes. */
332
 */
-
 
333
void setup_exception_stacks()
347
void setup_exception_stacks()
334
{
348
{
335
        /* switch to particular mode and set "r13" there */
349
        /* switch to particular mode and set "r13" there */
336
 
350
 
337
        uint32_t cspr = current_status_reg_read();
351
        uint32_t cspr = current_status_reg_read();