Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2406 → Rev 2407

/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