Rev 2927 | Rev 4345 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 2927 | Rev 3153 | ||
|---|---|---|---|
| Line 38... | Line 38... | ||
| 38 | #include <arch/memstr.h> |
38 | #include <arch/memstr.h> |
| 39 | #include <arch/regutils.h> |
39 | #include <arch/regutils.h> |
| 40 | #include <interrupt.h> |
40 | #include <interrupt.h> |
| 41 | #include <arch/machine.h> |
41 | #include <arch/machine.h> |
| 42 | #include <arch/mm/page_fault.h> |
42 | #include <arch/mm/page_fault.h> |
| - | 43 | #include <arch/barrier.h> |
|
| 43 | #include <print.h> |
44 | #include <print.h> |
| 44 | #include <syscall/syscall.h> |
45 | #include <syscall/syscall.h> |
| 45 | 46 | ||
| 46 | /** Offset used in calculation of exception handler's relative address. |
47 | /** Offset used in calculation of exception handler's relative address. |
| 47 | * |
48 | * |
| Line 207... | Line 208... | ||
| 207 | 208 | ||
| 208 | /** Updates specified exception vector to jump to given handler. |
209 | /** Updates specified exception vector to jump to given handler. |
| 209 | * |
210 | * |
| 210 | * Addresses of handlers are stored in memory following exception vectors. |
211 | * Addresses of handlers are stored in memory following exception vectors. |
| 211 | */ |
212 | */ |
| 212 | static void install_handler (unsigned handler_addr, unsigned* vector) |
213 | static void install_handler(unsigned handler_addr, unsigned *vector) |
| 213 | { |
214 | { |
| 214 | /* relative address (related to exc. vector) of the word |
215 | /* relative address (related to exc. vector) of the word |
| 215 | * where handler's address is stored |
216 | * where handler's address is stored |
| 216 | */ |
217 | */ |
| 217 | volatile uint32_t handler_address_ptr = EXC_VECTORS_SIZE - |
218 | volatile uint32_t handler_address_ptr = EXC_VECTORS_SIZE - |
| 218 | PREFETCH_OFFSET; |
219 | PREFETCH_OFFSET; |
| 219 | 220 | ||
| 220 | /* make it LDR instruction and store at exception vector */ |
221 | /* make it LDR instruction and store at exception vector */ |
| 221 | *vector = handler_address_ptr | LDR_OPCODE; |
222 | *vector = handler_address_ptr | LDR_OPCODE; |
| - | 223 | smc_coherence(*vector); |
|
| 222 | 224 | ||
| 223 | /* store handler's address */ |
225 | /* store handler's address */ |
| 224 | *(vector + EXC_VECTORS) = handler_addr; |
226 | *(vector + EXC_VECTORS) = handler_addr; |
| 225 | 227 | ||
| 226 | } |
228 | } |
| 227 | 229 | ||
| 228 | /** Low-level Reset Exception handler. */ |
230 | /** Low-level Reset Exception handler. */ |
| 229 | static void reset_exception_entry() |
231 | static void reset_exception_entry(void) |
| 230 | { |
232 | { |
| 231 | PROCESS_EXCEPTION(EXC_RESET); |
233 | PROCESS_EXCEPTION(EXC_RESET); |
| 232 | } |
234 | } |
| 233 | 235 | ||
| 234 | /** Low-level Software Interrupt Exception handler. */ |
236 | /** Low-level Software Interrupt Exception handler. */ |
| 235 | static void swi_exception_entry() |
237 | static void swi_exception_entry(void) |
| 236 | { |
238 | { |
| 237 | PROCESS_EXCEPTION(EXC_SWI); |
239 | PROCESS_EXCEPTION(EXC_SWI); |
| 238 | } |
240 | } |
| 239 | 241 | ||
| 240 | /** Low-level Undefined Instruction Exception handler. */ |
242 | /** Low-level Undefined Instruction Exception handler. */ |
| 241 | static void undef_instr_exception_entry() |
243 | static void undef_instr_exception_entry(void) |
| 242 | { |
244 | { |
| 243 | PROCESS_EXCEPTION(EXC_UNDEF_INSTR); |
245 | PROCESS_EXCEPTION(EXC_UNDEF_INSTR); |
| 244 | } |
246 | } |
| 245 | 247 | ||
| 246 | /** Low-level Fast Interrupt Exception handler. */ |
248 | /** Low-level Fast Interrupt Exception handler. */ |
| 247 | static void fiq_exception_entry() |
249 | static void fiq_exception_entry(void) |
| 248 | { |
250 | { |
| 249 | PROCESS_EXCEPTION(EXC_FIQ); |
251 | PROCESS_EXCEPTION(EXC_FIQ); |
| 250 | } |
252 | } |
| 251 | 253 | ||
| 252 | /** Low-level Prefetch Abort Exception handler. */ |
254 | /** Low-level Prefetch Abort Exception handler. */ |
| 253 | static void prefetch_abort_exception_entry() |
255 | static void prefetch_abort_exception_entry(void) |
| 254 | { |
256 | { |
| 255 | asm("sub lr, lr, #4"); |
257 | asm("sub lr, lr, #4"); |
| 256 | PROCESS_EXCEPTION(EXC_PREFETCH_ABORT); |
258 | PROCESS_EXCEPTION(EXC_PREFETCH_ABORT); |
| 257 | } |
259 | } |
| 258 | 260 | ||
| 259 | /** Low-level Data Abort Exception handler. */ |
261 | /** Low-level Data Abort Exception handler. */ |
| 260 | static void data_abort_exception_entry() |
262 | static void data_abort_exception_entry(void) |
| 261 | { |
263 | { |
| 262 | asm("sub lr, lr, #8"); |
264 | asm("sub lr, lr, #8"); |
| 263 | PROCESS_EXCEPTION(EXC_DATA_ABORT); |
265 | PROCESS_EXCEPTION(EXC_DATA_ABORT); |
| 264 | } |
266 | } |
| 265 | 267 | ||
| Line 267... | Line 269... | ||
| 267 | * |
269 | * |
| 268 | * CPU is switched to Undefined mode before further interrupt processing |
270 | * CPU is switched to Undefined mode before further interrupt processing |
| 269 | * because of possible occurence of nested interrupt exception, which |
271 | * because of possible occurence of nested interrupt exception, which |
| 270 | * would overwrite (and thus spoil) stack pointer. |
272 | * would overwrite (and thus spoil) stack pointer. |
| 271 | */ |
273 | */ |
| 272 | static void irq_exception_entry() |
274 | static void irq_exception_entry(void) |
| 273 | { |
275 | { |
| 274 | asm("sub lr, lr, #4"); |
276 | asm("sub lr, lr, #4"); |
| 275 | setup_stack_and_save_regs(); |
277 | setup_stack_and_save_regs(); |
| 276 | 278 | ||
| 277 | switch_to_irq_servicing_mode(); |
279 | switch_to_irq_servicing_mode(); |