41,6 → 41,7 |
#include <arch/drivers/gxemul.h> |
#include <arch/mm/page_fault.h> |
#include <print.h> |
#include <syscall/syscall.h> |
|
#define PREFETCH_OFFSET 0x8 |
#define BRANCH_OPCODE 0xea000000 |
64,7 → 65,8 |
@prev mode was usermode \n\ |
ldmfd r13!, {r0} \n\ |
ldr r13, =supervisor_sp \n\ |
stmfd r13!, {r0-r12, r13, lr} \n\ |
stmfd r13!, {lr} \n\ |
stmfd r13!, {r0-r12} \n\ |
stmfd r13!, {r13, lr}^ \n\ |
mrs r0, spsr \n\ |
stmfd r13!, {r0} \n\ |
82,10 → 84,11 |
\n\ |
mov r3, r13 \n\ |
stmfd r13!, {r2} \n\ |
stmfd r13!, {r3} \n\ |
mov r2, lr \n\ |
stmfd r13!, {r4-r12} \n\ |
mov r2, lr \n\ |
mov r1, r13 \n\ |
mov lr, #0 \n\ |
mov sp, #0 \n\ |
msr cpsr_c, r0 \n\ |
\n\ |
ldmfd r13!, {r4, r5, r6, r7} \n\ |
127,19 → 130,21 |
msr cpsr_c, r0 \n\ |
\n\ |
@actual return \n\ |
4: \n\ |
ldmfd r13!, {r0-r12, r13, pc}^" |
\n\ |
ldmfd r13, {r0-r12, pc}^ \n\ |
4:" |
); |
} |
|
|
#define SAVE_REGS_TO_STACK \ |
|
/*#define SAVE_REGS_TO_STACK \ |
asm("stmfd r13!, {r0-r12, r13, lr}"); \ |
asm("mrs r14, spsr"); \ |
asm("stmfd r13!, {r14}"); |
*/ |
|
|
|
#define CALL_EXC_DISPATCH(exception) \ |
asm("mov r0, %0" : : "i" (exception)); \ |
asm("mov r1, r13"); \ |
148,13 → 153,13 |
|
/**Loads registers from the stack and resets SPSR before exitting exception |
* handler. |
*/ |
|
#define LOAD_REGS_FROM_STACK \ |
asm("ldmfd r13!, {r14}"); \ |
asm("msr spsr, r14"); \ |
asm("ldmfd r13!, {r0-r12, r13, pc}^"); |
*/ |
|
|
|
/** General exception handler. |
* Stores registers, dispatches the exception, |
232,28 → 237,25 |
static void irq_exception_entry() |
{ |
asm("sub lr, lr, #4"); |
// SAVE_REGS_TO_STACK |
// CALL_EXC_DISPATCH(EXC_IRQ) |
// LOAD_REGS_FROM_STACK; |
PROCESS_EXCEPTION(EXC_IRQ); |
} |
|
// static void prefetch_abort_exception(int exc_no, istate_t* istate) |
// { |
// dputs("(PREFETCH|DATA) ABORT exception caught, not processed.\n"); |
// } |
|
/** Software Interrupt handler. |
* |
* Dispatches the syscall. |
*/ |
static void swi_exception(int exc_no, istate_t* istate) |
{ |
dprintf("\nIstate dump:\n"); |
dprintf(" r0:%X r1:%X r2:%X r3:%X\n", istate->r0, istate->r1, istate->r2, istate->r3); |
dprintf(" r4:%X r5:%X r6:%X r7:%X\n", istate->r4, istate->r5, istate->r6, istate->r7); |
dprintf(" r8:%X r9:%X r10:%X r11:%X\n", istate->r8, istate->r9, istate->r10, istate->r11); |
dprintf(" r12:%X r13:%X lr:%X spsr:%X\n", istate->r12, istate->sp, istate->lr, istate->spsr); |
dprintf(" prev_lr:%X prev_sp:%X\n", istate->prev_lr, istate->prev_sp); |
istate->r0 = syscall_handler( |
istate->r0, |
istate->r1, |
istate->r2, |
istate->r3, |
istate->r4); |
} |
|
/** Interrupt Exception handler. |
* |
* Determines the sources of interrupt, and calls their handlers. |
*/ |
static void irq_exception(int exc_no, istate_t* istate) |
387,7 → 389,7 |
make stack analogous to irq_stack (in start.S), |
and then set stack pointer here */ |
|
current_status_reg_control_write( cspr); |
current_status_reg_control_write(cspr); |
|
} |
|