Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2244 → Rev 2245

/branches/arm/kernel/arch/arm32/src/exception.c
38,8 → 38,8
#include <arch/memstr.h>
#include <arch/regutils.h>
#include <interrupt.h>
#include <arch/drivers/gxemul.h>
 
 
#define PREFETCH_OFFSET 0x8
#define BRANCH_OPCODE 0xea000000
#define LDR_OPCODE 0xe59ff000
47,21 → 47,7
#define EXC_VECTORS_SIZE 0x20
#define EXC_VECTORS 0x8
 
/* GXEmul interrupt controller macros
TODO might go to drivers/ together with servicing functions
*/
/* IRQ Controller device is added in a special premium gxemul
* edition at www.ms.mff.cuni.cz/~stepp3am/mygxemul-0.4.4.1.tar.gz
* :)
*/
#define IRQ_CONTROLLER_CAUSE 0x0000000016000000
#define IRQ_CONTROLLER_MAX_IRQ 8
 
/* IRQs */
#define CONSOLE_IRQ 2
#define TIMER_IRQ 4
 
 
#define SAVE_REGS_TO_STACK \
asm("stmfd sp!, {r0-r12, sp, lr}"); \
asm("mrs r14, spsr"); \
157,15 → 143,22
*/
static void irq_exception(int exc_no, istate_t* istate)
{
/* TODO this will call interrupt dispatching routine
*
*/
 
uint32_t sources = *(uint32_t*) IRQ_CONTROLLER_CAUSE;
uint32_t sources = gxemul_irqc_get_sources();
int i = 0;
int noirq = 1;
for (; i < IRQ_CONTROLLER_MAX_IRQ; i++) {
for (; i < GXEMUL_IRQC_MAX_IRQ; i++) {
if (sources & (1 << i)) {
irq_t *irq = irq_dispatch_and_lock(i);
if (irq) {
/* The IRQ handler was found. */
irq->handler(irq, irq->arg);
spinlock_unlock(&irq->lock);
} else {
/* Spurious interrupt.*/
aux_printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, i);
}
}
}
/* TODO remove after testing the above code
noirq = 0;
if (i == CONSOLE_IRQ) {
char readchar = *(char*)0x10000000;
179,7 → 172,7
}
else if (i == TIMER_IRQ) {
aux_printf("\n.\n");
/* acknowledge */
//acknowledge
*(uint32_t*)0x15000110 = 0;
}
}
186,7 → 179,7
}
 
if (noirq)
aux_puts("IRQ exception without source\n");
aux_puts("IRQ exception without source\n");*/
}
 
/** Fills exception vectors with appropriate exception handlers.
215,9 → 208,15
(unsigned*)EXC_FIQ_VEC);
}
 
/** Registers exceptions and their handlers to kernel exception dispatcher. */
/** Initializes exception handling.
*
* Installs low-level exception handlers and then registers
* exceptions and their handlers to kernel exception dispatcher.
*/
void exception_init(void)
{
install_exception_handlers();
exc_register(EXC_IRQ, "interrupt", (iroutine) irq_exception);
/* TODO add next */
}
232,6 → 231,10
);
asm("ldr sp, =irq_stack");
current_status_reg_control_write( cspr);
/* TODO if you want to test other exceptions than IRQ,
make stack analogous to irq_stack (in start.S),
and then set stack pointer here */
}
 
/** @}