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