Rev 2284 | Rev 2304 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2284 | Rev 2286 | ||
---|---|---|---|
Line 39... | Line 39... | ||
39 | #include <arch/regutils.h> |
39 | #include <arch/regutils.h> |
40 | #include <interrupt.h> |
40 | #include <interrupt.h> |
41 | #include <arch/drivers/gxemul.h> |
41 | #include <arch/drivers/gxemul.h> |
42 | #include <arch/mm/page_fault.h> |
42 | #include <arch/mm/page_fault.h> |
43 | #include <print.h> |
43 | #include <print.h> |
- | 44 | #include <syscall/syscall.h> |
|
44 | 45 | ||
45 | #define PREFETCH_OFFSET 0x8 |
46 | #define PREFETCH_OFFSET 0x8 |
46 | #define BRANCH_OPCODE 0xea000000 |
47 | #define BRANCH_OPCODE 0xea000000 |
47 | #define LDR_OPCODE 0xe59ff000 |
48 | #define LDR_OPCODE 0xe59ff000 |
48 | #define VALID_BRANCH_MASK 0xff000000 |
49 | #define VALID_BRANCH_MASK 0xff000000 |
Line 62... | Line 63... | ||
62 | bne 1f \n\ |
63 | bne 1f \n\ |
63 | \n\ |
64 | \n\ |
64 | @prev mode was usermode \n\ |
65 | @prev mode was usermode \n\ |
65 | ldmfd r13!, {r0} \n\ |
66 | ldmfd r13!, {r0} \n\ |
66 | ldr r13, =supervisor_sp \n\ |
67 | ldr r13, =supervisor_sp \n\ |
- | 68 | stmfd r13!, {lr} \n\ |
|
67 | stmfd r13!, {r0-r12, r13, lr} \n\ |
69 | stmfd r13!, {r0-r12} \n\ |
68 | stmfd r13!, {r13, lr}^ \n\ |
70 | stmfd r13!, {r13, lr}^ \n\ |
69 | mrs r0, spsr \n\ |
71 | mrs r0, spsr \n\ |
70 | stmfd r13!, {r0} \n\ |
72 | stmfd r13!, {r0} \n\ |
71 | b 2f \n\ |
73 | b 2f \n\ |
72 | \n\ |
74 | \n\ |
Line 80... | Line 82... | ||
80 | mrs r0, cpsr \n\ |
82 | mrs r0, cpsr \n\ |
81 | msr cpsr_c, r1 \n\ |
83 | msr cpsr_c, r1 \n\ |
82 | \n\ |
84 | \n\ |
83 | mov r3, r13 \n\ |
85 | mov r3, r13 \n\ |
84 | stmfd r13!, {r2} \n\ |
86 | stmfd r13!, {r2} \n\ |
85 | stmfd r13!, {r3} \n\ |
- | |
86 | stmfd r13!, {r4-r12} \n\ |
- | |
87 | mov r2, lr \n\ |
87 | mov r2, lr \n\ |
- | 88 | stmfd r13!, {r4-r12} \n\ |
|
88 | mov r1, r13 \n\ |
89 | mov r1, r13 \n\ |
- | 90 | mov lr, #0 \n\ |
|
- | 91 | mov sp, #0 \n\ |
|
89 | msr cpsr_c, r0 \n\ |
92 | msr cpsr_c, r0 \n\ |
90 | \n\ |
93 | \n\ |
91 | ldmfd r13!, {r4, r5, r6, r7} \n\ |
94 | ldmfd r13!, {r4, r5, r6, r7} \n\ |
92 | stmfd r1!, {r4, r5, r6} \n\ |
95 | stmfd r1!, {r4, r5, r6} \n\ |
93 | stmfd r1!, {r7} \n\ |
96 | stmfd r1!, {r7} \n\ |
Line 125... | Line 128... | ||
125 | mov r13, r1 \n\ |
128 | mov r13, r1 \n\ |
126 | mov lr, r2 \n\ |
129 | mov lr, r2 \n\ |
127 | msr cpsr_c, r0 \n\ |
130 | msr cpsr_c, r0 \n\ |
128 | \n\ |
131 | \n\ |
129 | @actual return \n\ |
132 | @actual return \n\ |
130 | 4: \n\ |
133 | \n\ |
131 | ldmfd r13!, {r0-r12, r13, pc}^" |
134 | ldmfd r13, {r0-r12, pc}^ \n\ |
- | 135 | 4:" |
|
132 | ); |
136 | ); |
133 | } |
137 | } |
134 | 138 | ||
135 | 139 | ||
- | 140 | ||
136 | #define SAVE_REGS_TO_STACK \ |
141 | /*#define SAVE_REGS_TO_STACK \ |
137 | asm("stmfd r13!, {r0-r12, r13, lr}"); \ |
142 | asm("stmfd r13!, {r0-r12, r13, lr}"); \ |
138 | asm("mrs r14, spsr"); \ |
143 | asm("mrs r14, spsr"); \ |
139 | asm("stmfd r13!, {r14}"); |
144 | asm("stmfd r13!, {r14}"); |
140 | 145 | */ |
|
141 | 146 | ||
142 | 147 | ||
143 | #define CALL_EXC_DISPATCH(exception) \ |
148 | #define CALL_EXC_DISPATCH(exception) \ |
144 | asm("mov r0, %0" : : "i" (exception)); \ |
149 | asm("mov r0, %0" : : "i" (exception)); \ |
145 | asm("mov r1, r13"); \ |
150 | asm("mov r1, r13"); \ |
146 | asm("bl exc_dispatch"); |
151 | asm("bl exc_dispatch"); |
147 | 152 | ||
148 | 153 | ||
149 | /**Loads registers from the stack and resets SPSR before exitting exception |
154 | /**Loads registers from the stack and resets SPSR before exitting exception |
150 | * handler. |
155 | * handler. |
151 | */ |
156 | |
152 | #define LOAD_REGS_FROM_STACK \ |
157 | #define LOAD_REGS_FROM_STACK \ |
153 | asm("ldmfd r13!, {r14}"); \ |
158 | asm("ldmfd r13!, {r14}"); \ |
154 | asm("msr spsr, r14"); \ |
159 | asm("msr spsr, r14"); \ |
155 | asm("ldmfd r13!, {r0-r12, r13, pc}^"); |
160 | asm("ldmfd r13!, {r0-r12, r13, pc}^"); |
156 | 161 | */ |
|
157 | 162 | ||
158 | 163 | ||
159 | /** General exception handler. |
164 | /** General exception handler. |
160 | * Stores registers, dispatches the exception, |
165 | * Stores registers, dispatches the exception, |
161 | * and finally restores registers and returns from exception processing. |
166 | * and finally restores registers and returns from exception processing. |
Line 230... | Line 235... | ||
230 | 235 | ||
231 | /** Low-level Interrupt Exception handler */ |
236 | /** Low-level Interrupt Exception handler */ |
232 | static void irq_exception_entry() |
237 | static void irq_exception_entry() |
233 | { |
238 | { |
234 | asm("sub lr, lr, #4"); |
239 | asm("sub lr, lr, #4"); |
235 | // SAVE_REGS_TO_STACK |
- | |
236 | // CALL_EXC_DISPATCH(EXC_IRQ) |
- | |
237 | // LOAD_REGS_FROM_STACK; |
- | |
238 | PROCESS_EXCEPTION(EXC_IRQ); |
240 | PROCESS_EXCEPTION(EXC_IRQ); |
239 | } |
241 | } |
240 | 242 | ||
241 | // static void prefetch_abort_exception(int exc_no, istate_t* istate) |
243 | /** Software Interrupt handler. |
242 | // { |
244 | * |
243 | // dputs("(PREFETCH|DATA) ABORT exception caught, not processed.\n"); |
245 | * Dispatches the syscall. |
244 | // } |
246 | */ |
245 | - | ||
246 | static void swi_exception(int exc_no, istate_t* istate) |
247 | static void swi_exception(int exc_no, istate_t* istate) |
247 | { |
248 | { |
248 | dprintf("\nIstate dump:\n"); |
249 | istate->r0 = syscall_handler( |
249 | dprintf(" r0:%X r1:%X r2:%X r3:%X\n", istate->r0, istate->r1, istate->r2, istate->r3); |
250 | istate->r0, |
250 | dprintf(" r4:%X r5:%X r6:%X r7:%X\n", istate->r4, istate->r5, istate->r6, istate->r7); |
251 | istate->r1, |
251 | dprintf(" r8:%X r9:%X r10:%X r11:%X\n", istate->r8, istate->r9, istate->r10, istate->r11); |
252 | istate->r2, |
252 | dprintf(" r12:%X r13:%X lr:%X spsr:%X\n", istate->r12, istate->sp, istate->lr, istate->spsr); |
253 | istate->r3, |
253 | dprintf(" prev_lr:%X prev_sp:%X\n", istate->prev_lr, istate->prev_sp); |
254 | istate->r4); |
254 | } |
255 | } |
255 | 256 | ||
256 | /** Interrupt Exception handler. |
257 | /** Interrupt Exception handler. |
- | 258 | * |
|
257 | * Determines the sources of interrupt, and calls their handlers. |
259 | * Determines the sources of interrupt, and calls their handlers. |
258 | */ |
260 | */ |
259 | static void irq_exception(int exc_no, istate_t* istate) |
261 | static void irq_exception(int exc_no, istate_t* istate) |
260 | { |
262 | { |
261 | // TODO: move somewhere to gxemul.c and use machine_irq_exception (or some similar |
263 | // TODO: move somewhere to gxemul.c and use machine_irq_exception (or some similar |
Line 385... | Line 387... | ||
385 | 387 | ||
386 | /* TODO if you want to test other exceptions than IRQ, |
388 | /* TODO if you want to test other exceptions than IRQ, |
387 | make stack analogous to irq_stack (in start.S), |
389 | make stack analogous to irq_stack (in start.S), |
388 | and then set stack pointer here */ |
390 | and then set stack pointer here */ |
389 | 391 | ||
390 | current_status_reg_control_write( cspr); |
392 | current_status_reg_control_write(cspr); |
391 | 393 | ||
392 | } |
394 | } |
393 | 395 | ||
394 | /** @} |
396 | /** @} |
395 | */ |
397 | */ |