/branches/arm/kernel/arch/arm32/include/interrupt.h |
---|
30,6 → 30,7 |
* @{ |
*/ |
/** @file |
* @brief Interrupt control routines declarations. |
*/ |
#ifndef KERN_arm32_INTERRUPT_H_ |
37,7 → 38,10 |
#include <arch/types.h> |
/** Initial size of exception dispatch table. */ |
#define IVT_ITEMS 6 |
/** Index of the first item in exception dispatch table. */ |
#define IVT_FIRST 0 |
/branches/arm/kernel/arch/arm32/include/exception.h |
---|
31,6 → 31,7 |
* @{ |
*/ |
/** @file |
* @brief Exception declarations |
*/ |
#ifndef KERN_arm32_EXCEPTION_H_ |
39,7 → 40,7 |
#include <arch/types.h> |
#include <arch/regutils.h> |
/** If defined, macro forces using of high exception vectors. */ |
#define HIGH_EXCEPTION_VECTORS |
#ifdef HIGH_EXCEPTION_VECTORS |
/branches/arm/kernel/arch/arm32/src/exception.c |
---|
44,18 → 44,37 |
#include <print.h> |
#include <syscall/syscall.h> |
/** Offset used in calculation of exception handler's relative address. |
* |
* @see install_handler() |
*/ |
#define PREFETCH_OFFSET 0x8 |
#define PREFETCH_OFFSET 0x8 |
#define BRANCH_OPCODE 0xea000000 |
/** LDR instruction's code */ |
#define LDR_OPCODE 0xe59ff000 |
#define VALID_BRANCH_MASK 0xff000000 |
#define EXC_VECTORS_SIZE 0x20 |
#define EXC_VECTORS 0x8 |
/** Number of exception vectors. */ |
#define EXC_VECTORS 8 |
/** Size of memory block occupied by exception vectors. */ |
#define EXC_VECTORS_SIZE (EXC_VECTORS * 4) |
/** Kernel stack pointer. |
* |
* It is set when thread switches to user mode, |
* and then used for exception handling. |
*/ |
extern uintptr_t supervisor_sp; |
/** Temporary exception stack pointer. |
* |
* Temporary stack is used in exceptions handling routines |
* before switching to thread's kernel stack. |
*/ |
extern uintptr_t exc_stack; |
/** Switches to kernel stack and saves all registers there. |
* |
* Temporary exception stack is used to save a few registers |
113,6 → 132,7 |
); |
} |
/** Returns from exception mode. |
* |
* Previously saved state of registers (including control register) |
148,6 → 168,39 |
); |
} |
/** Switch CPU to mode in which interrupts are serviced (currently it |
* is Undefined mode). |
* |
* The default mode for interrupt servicing (Interrupt Mode) |
* can not be used because of nested interrupts (which can occur |
* because interrupt are enabled in higher levels of interrupt handler). |
*/ |
inline static void switchToIrqServicingMode() |
{ |
/* switch to Undefined mode */ |
asm volatile( |
/* save regs used during switching */ |
"stmfd sp!, {r0-r3} \n" |
/* save stack pointer and link register to r1, r2 */ |
"mov r1, sp \n" |
"mov r2, lr \n" |
/* mode switch */ |
"mrs r0, cpsr \n" |
"bic r0, r0, #0x1f \n" |
"orr r0, r0, #0x1b \n" |
"msr cpsr_c, r0 \n" |
/* restore saved sp and lr */ |
"mov sp, r1 \n" |
"mov lr, r2 \n" |
/* restore original regs */ |
"ldmfd sp!, {r0-r3} \n" |
); |
} |
/** Calls exception dispatch routine. */ |
#define CALL_EXC_DISPATCH(exception) \ |
asm("mov r0, %0" : : "i" (exception)); \ |
154,7 → 207,7 |
asm("mov r1, r13"); \ |
asm("bl exc_dispatch"); |
/** General exception handler. |
* |
* Stores registers, dispatches the exception, |
242,19 → 295,9 |
{ |
asm("sub lr, lr, #4"); |
setup_stack_and_save_regs(); |
/* switch to Undefined mode */ |
asm("stmfd sp!, {r0-r3}"); |
asm("mov r1, sp"); |
asm("mov r2, lr"); |
asm("mrs r0, cpsr"); |
asm("bic r0, r0, #0x1f"); |
asm("orr r0, r0, #0x1b"); |
asm("msr cpsr_c, r0"); |
asm("mov sp, r1"); |
asm("mov lr, r2"); |
asm("ldmfd sp!, {r0-r3}"); |
switchToIrqServicingMode(); |
CALL_EXC_DISPATCH(EXC_IRQ) |
load_regs(); |
/branches/arm/kernel/arch/arm32/src/arm32.c |
---|
30,6 → 30,7 |
* @{ |
*/ |
/** @file |
* @brief ARM32 architecture specific functions. |
*/ |
49,11 → 50,18 |
#include <arch/machine.h> |
#include <userspace.h> |
/** Information about loaded tasks. */ |
bootinfo_t bootinfo; |
bootinfo_t bootinfo; |
/** Temporary exception stack pointer. |
* |
* Temporary stack is used in exceptions handling routines |
* before switching to thread's kernel stack. |
*/ |
extern uintptr_t supervisor_sp; |
/** Performs arm32 specific initialization before main_bsp() is called. */ |
void arch_pre_main(void) |
{ |
int i; |
67,7 → 75,7 |
} |
/** Performs arm32 specific initialization before mm is initialized. */ |
void arch_pre_mm_init(void) |
{ |
/* It is not assumed by default */ |
74,7 → 82,7 |
interrupts_disable(); |
} |
/** Performs arm32 specific initialization afterr mm is initialized. */ |
void arch_post_mm_init(void) |
{ |
machine_hw_map_init(); |
91,44 → 99,57 |
#endif |
} |
/** Performs arm32 specific tasks needed after cpu is initialized. |
* |
* Currently the function is empty. |
*/ |
void arch_post_cpu_init(void) |
{ |
} |
/** Performs arm32 specific tasks needed before the multiprocessing is |
* initialized. |
* |
* Currently the function is empty because SMP is not supported. |
*/ |
void arch_pre_smp_init(void) |
{ |
/* TODO */ |
} |
/** Performs arm32 specific tasks needed after the multiprocessing is |
* initialized. |
* |
* Currently the function is empty because SMP is not supported. |
*/ |
void arch_post_smp_init(void) |
{ |
/* TODO */ |
} |
/** Perform arm32 specific tasks needed before the new task is run. */ |
/** Performs arm32 specific tasks needed before the new task is run. */ |
void before_task_runs_arch(void) |
{ |
tlb_invalidate_all(); |
} |
/** Perform arm32 specific tasks needed before the new thread is scheduled. */ |
/** Performs arm32 specific tasks needed before the new thread is scheduled. |
* |
* It sets supervisor_sp. |
*/ |
void before_thread_runs_arch(void) |
{ |
supervisor_sp = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE-SP_DELTA]; |
} |
/** Performs arm32 specific tasks before a thread stops running. |
* |
* Currently the function is empty. |
*/ |
void after_thread_ran_arch(void) |
{ |
} |
/** Halts CPU. */ |
void cpu_halt(void) |
{ |
machine_cpu_halt(); |
/branches/arm/kernel/arch/arm32/src/context.S |
---|
1,5 → 1,5 |
# |
# Copyright (c) 2003-2004 Jakub Jermar |
# Copyright (c) 2003-2004 Jakub Jermar, 2007 Petr Stepan |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
/branches/arm/kernel/arch/arm32/src/interrupt.c |
---|
38,6 → 38,7 |
#include <arch/machine.h> |
#include <interrupt.h> |
/** Initial size of a table holding interrupt handlers. */ |
#define IRQ_COUNT 8 |