fb7525f185e31ab01de801ee3605cc9872c326d3
[barrelfish] / kernel / arch / armv8 / exn.c
1 /*
2  * Copyright (c) 2009-2013 ETH Zurich.
3  * Copyright (c) 2015, Hewlett Packard Enterprise Development LP.
4  * All rights reserved.
5  *
6  * This file is distributed under the terms in the attached LICENSE file.
7  * If you do not find this file, copies can be found by writing to:
8  * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
9  */
10
11 #include <kernel.h>
12 #include <dispatch.h>
13 #include <systime.h>
14 #include <arm_hal.h>
15 #include <sysreg.h>
16 #include <exceptions.h>
17 #include <exec.h>
18 #include <misc.h>
19 #include <stdio.h>
20 #include <wakeup.h>
21 #include <irq.h>
22 #include <arch/arm/arm.h>
23 #include <arch/arm/gic.h>
24 #include <arch/arm/platform.h>
25 #include <dev/armv8_dev.h>
26
27 void handle_user_page_fault(lvaddr_t                fault_address,
28                             arch_registers_state_t* save_area,
29                             union registers_aarch64 *resume_area)
30 {
31     lvaddr_t handler;
32     struct dispatcher_shared_aarch64 *disp =
33         get_dispatcher_shared_aarch64(dcb_current->disp);
34     uintptr_t saved_pc = save_area->named.pc;
35
36     disp->d.disabled = dispatcher_is_disabled_ip(dcb_current->disp, saved_pc);
37     bool disabled = (disp->d.disabled != 0);
38
39     assert(dcb_current->disp_cte.cap.type == ObjType_Frame);
40
41     printk(LOG_WARN, "user page fault%s in '%.*s': addr %"PRIxLVADDR
42                       " IP %"PRIxPTR"\n",
43            disabled ? " WHILE DISABLED" : "", DISP_NAME_LEN,
44            disp->d.name, fault_address, saved_pc);
45
46     if (disabled) {
47         assert(save_area == &disp->trap_save_area);
48         handler = disp->d.dispatcher_pagefault_disabled;
49         dcb_current->faults_taken++;
50     }
51     else {
52         assert(save_area == &disp->enabled_save_area);
53         handler = disp->d.dispatcher_pagefault;
54     }
55
56     if (dcb_current->faults_taken > 2) {
57         printk(LOG_WARN, "handle_user_page_fault: too many faults, "
58                "making domain unrunnable\n");
59         dcb_current->faults_taken = 0; // just in case it gets restarted
60         scheduler_remove(dcb_current);
61         dispatch(schedule());
62     }
63     else {
64         //
65         // Upcall to dispatcher
66         //
67         // NB System might be cleaner with a prototype
68         // dispatch context that has R0-R3 to be overwritten
69         // plus initial stack, thread, and gic registers. Could do
70         // a faster resume_for_upcall().
71         //
72
73         struct dispatcher_shared_generic *disp_gen =
74             get_dispatcher_shared_generic(dcb_current->disp);
75
76         /* XXX - This code leaks the contents of the kernel stack to the
77          * user-level fault handler. */
78
79         resume_area->named.x0   = disp_gen->udisp;
80         resume_area->named.x1   = fault_address;
81         resume_area->named.x2   = 0;
82         resume_area->named.x3   = saved_pc;
83         /* Why does the kernel do this? */
84         resume_area->named.x10  = disp->got_base;
85         resume_area->named.pc   = handler;
86         resume_area->named.spsr = CPSR_F_MASK | AARCH64_MODE_USR;
87
88         // SP is set by handler routine.
89
90         // Upcall user to save area
91         disp->d.disabled = true;
92                 printk(LOG_WARN, "page fault at %p calling handler %p\n",
93                fault_address, handler);
94     }
95 }
96
97 void handle_user_undef(lvaddr_t fault_address, enum aarch64_exception_class cause,
98                        arch_registers_state_t* save_area,
99                        union registers_aarch64 *resume_area)
100 {
101     struct dispatcher_shared_aarch64 *disp =
102         get_dispatcher_shared_aarch64(dcb_current->disp);
103
104     bool disabled =
105         dispatcher_is_disabled_ip(dcb_current->disp, save_area->named.pc);
106     disp->d.disabled = disabled;
107
108     assert(dcb_current->disp_cte.cap.type == ObjType_Frame);
109     if (disabled) {
110         //        assert(save_area == &disp->trap_save_area);
111     }
112     else {
113         assert(save_area == &disp->enabled_save_area);
114     }
115
116     printk(LOG_WARN, "user undef fault (0x%lx)%s in '%.*s': IP 0x%lx x29:%lx x30:%lx sp:%lx\n",
117            cause, disabled ? " WHILE DISABLED" : "", DISP_NAME_LEN,
118            disp->d.name, fault_address, save_area->named.x29, save_area->named.x30, save_area->named.stack);
119
120     struct dispatcher_shared_generic *disp_gen =
121         get_dispatcher_shared_generic(dcb_current->disp);
122
123     resume_area->named.x0   = disp_gen->udisp;
124     resume_area->named.x1   = AARCH64_EVECTOR_UNDEF;
125     resume_area->named.x2   = 0;
126     resume_area->named.x3   = fault_address;
127     /* Why does the kernel do this? */
128     resume_area->named.x10  = disp->got_base;
129     resume_area->named.pc   = disp->d.dispatcher_trap;
130     resume_area->named.spsr = CPSR_F_MASK | AARCH64_MODE_USR;
131
132     // Upcall user to save area
133     disp->d.disabled = true;
134 }
135
136 void handle_user_fault(lvaddr_t fault_address, uintptr_t cause,
137                        arch_registers_state_t* save_area)
138 {
139     union registers_aarch64 resume_area;
140
141     switch(cause) {
142         case aarch64_ec_unknown :
143         case aarch64_ec_wfi :
144         case aarch64_ec_mcr_cp15 :
145         case aarch64_ec_mcrr_cp15 :
146         case aarch64_ec_mcr_cp14 :
147         case aarch64_ec_ldc_cp14 :
148         case aarch64_ec_fpen :
149         case aarch64_ec_mcr_cp10 :
150         case aarch64_ec_mcrr_cp14 :
151         case aarch64_ec_il :
152             handle_user_undef(fault_address, cause, save_area, &resume_area);
153             break;
154         case aarch64_ec_svc_aa32 :
155         case aarch64_ec_hvc_aa32 :
156         case aarch64_ec_smc_aa32 :
157         case aarch64_ec_svc_aa64 :
158         case aarch64_ec_hvc_aa64 :
159         case aarch64_ec_smc_aa64 :
160             panic("syscall ended up in exception handler ? Yuck.");
161             break;
162         case aarch64_ec_mrs :
163         case aarch64_ec_impl :
164             handle_user_undef(fault_address, cause, save_area, &resume_area);
165             break;
166         case aarch64_ec_iabt_low  :
167             handle_user_page_fault(fault_address, save_area, &resume_area);
168             break;
169         case aarch64_ec_iabt_high :
170             panic("pagefault while in kernel? Yuck.");
171             break;
172         case aarch64_ec_pc_align :
173             handle_user_undef(fault_address, cause, save_area, &resume_area);
174             break;
175         case aarch64_ec_dabt_low :
176             handle_user_page_fault(fault_address, save_area, &resume_area);
177             break;
178         case aarch64_ec_dabt_high :
179             panic("pagefault while in kernel? Yuck.");
180             break;
181         case aarch64_ec_sp_align :
182         case aarch64_ec_fpu_aa32 :
183         case aarch64_ec_fpu_aa64 :
184         case aarch64_ec_serror :
185         case aarch64_ec_bkpt_low :
186         case aarch64_ec_bkpt_high :
187         case aarch64_ec_step_low :
188         case aarch64_ec_step_high :
189         case aarch64_ec_wpt_low :
190         case aarch64_ec_wpt_high :
191         case aarch64_ec_bkpt_soft :
192         case aarch64_ec_bkpt_el2 :
193         case aarch64_ec_brk :
194             handle_user_undef(fault_address, cause, save_area, &resume_area);
195             break;
196         default:
197             panic("Unknown exception syndrome: %u", cause);
198         break;
199     }
200
201     resume(&resume_area);
202 }
203
204 void handle_irq(arch_registers_state_t* save_area, uintptr_t fault_pc,
205                 uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3)
206 {
207     uint32_t irq = 0;
208
209     /* Save the FPU registers */
210     __asm volatile(
211         "   stp q0, q1, [%x0, #0]\n\t"
212         "   stp q2, q3, [%x0, #0x20]\n\t"
213         "   stp q4, q5, [%x0, #0x40]\n\t"
214         "   stp q6, q7, [%x0, #0x60]\n\t"
215         "   stp q8, q9, [%x0, #0x80]\n\t"
216         "   stp q10, q11, [%x0, #0xa0]\n\t"
217         "   stp q12, q13, [%x0, #0xc0]\n\t"
218         "   stp q14, q15, [%x0, #0xe0]\n\t"
219         "   stp q16, q17, [%x0, #0x100]\n\t"
220         "   stp q18, q19, [%x0, #0x120]\n\t"
221         "   stp q20, q21, [%x0, #0x140]\n\t"
222         "   stp q22, q23, [%x0, #0x160]\n\t"
223         "   stp q24, q25, [%x0, #0x180]\n\t"
224         "   stp q26, q27, [%x0, #0x1a0]\n\t"
225         "   stp q28, q29, [%x0, #0x1c0]\n\t"
226         "   stp q30, q31, [%x0, #0x1e0]\n\t"
227          :: "r" (&save_area->named.v));
228
229     /* The assembly stub leaves the first 4 registers, the stack pointer,
230      * the exception PC, and the SPSR for us to save, as it's run out of room for
231      * the necessary instructions. */
232     save_area->named.x0    = x0;
233     save_area->named.x1    = x1;
234     save_area->named.x2    = x2;
235     save_area->named.x3    = x3;
236     save_area->named.stack = armv8_SP_EL0_rd(NULL);
237     save_area->named.spsr  = armv8_SPSR_EL1_rd(NULL);
238     save_area->named.pc    = fault_pc;
239
240     irq = platform_get_active_irq();
241
242     debug(SUBSYS_DISPATCH, "IRQ %"PRIu32" while %s\n", irq,
243           dcb_current ? (dcb_current->disabled ? "disabled": "enabled") :
244                         "in kernel");
245
246     if (dcb_current != NULL) {
247         dispatcher_handle_t handle = dcb_current->disp;
248         if (save_area == dispatcher_get_disabled_save_area(handle)) {
249             assert(dispatcher_is_disabled_ip(handle, fault_pc));
250             dcb_current->disabled = true;
251         } else {
252 /*            debug(SUBSYS_DISPATCH,
253                   "save_area=%p, dispatcher_get_enabled_save_are(handle)=%p\n",
254                    save_area, dispatcher_get_enabled_save_area(handle));
255 */
256
257             assert(save_area == dispatcher_get_enabled_save_area(handle));
258             assert(!dispatcher_is_disabled_ip(handle, fault_pc));
259             dcb_current->disabled = false;
260         }
261     }
262     // Offer it to the timer
263     if (platform_is_timer_interrupt(irq)) {
264         platform_acknowledge_irq(irq);
265         wakeup_check(systime_now());
266 #ifndef CONFIG_ONESHOT_TIMER
267         // Set next trigger
268         systime_set_timer(kernel_timeslice);
269 #endif
270         dispatch(schedule());
271     } else {
272         printf("%s: %d\n", __func__, irq);
273         platform_acknowledge_irq(irq);
274         send_user_interrupt(irq);
275         panic("Unhandled IRQ %"PRIu32"\n", irq);
276     }
277
278 }
279
280 #define STACK_DUMP_LIMIT 32
281
282 /* For unhandled faults, we print a register dump and panic. */
283 void fatal_kernel_fault(lvaddr_t epc, uint64_t spsr, uint64_t esr,
284                         uint64_t vector, arch_registers_state_t* save_area)
285 {
286     size_t i;
287     enum aarch64_exception_class exception_class = FIELD(26,6,esr);
288     /* int instruction_length = FIELD(25,1,esr); */
289     int iss                = FIELD(0,25,esr);
290
291     /* Save the FPU registers */
292     __asm volatile(
293         "   stp q0, q1, [%x0, #0]\n\t"
294         "   stp q2, q3, [%x0, #0x20]\n\t"
295         "   stp q4, q5, [%x0, #0x40]\n\t"
296         "   stp q6, q7, [%x0, #0x60]\n\t"
297         "   stp q8, q9, [%x0, #0x80]\n\t"
298         "   stp q10, q11, [%x0, #0xa0]\n\t"
299         "   stp q12, q13, [%x0, #0xc0]\n\t"
300         "   stp q14, q15, [%x0, #0xe0]\n\t"
301         "   stp q16, q17, [%x0, #0x100]\n\t"
302         "   stp q18, q19, [%x0, #0x120]\n\t"
303         "   stp q20, q21, [%x0, #0x140]\n\t"
304         "   stp q22, q23, [%x0, #0x160]\n\t"
305         "   stp q24, q25, [%x0, #0x180]\n\t"
306         "   stp q26, q27, [%x0, #0x1a0]\n\t"
307         "   stp q28, q29, [%x0, #0x1c0]\n\t"
308         "   stp q30, q31, [%x0, #0x1e0]\n\t"
309          :: "r" (&save_area->named.v));
310
311     printk(LOG_PANIC, "Fatal (unexpected) fault at 0x%"PRIx64 " (%#" PRIx64 ")\n\n", epc, epc - (uintptr_t)&kernel_first_byte);
312     printk(LOG_PANIC, "Register context saved at: %p\n", save_area);
313     printk(LOG_PANIC, "Vector: ");
314     switch(vector) {
315         case AARCH64_EVECTOR_UNDEF:
316             printk(LOG_PANIC, "UNDEF\n");
317             break;
318         case AARCH64_EVECTOR_EL0_SYNC:
319             printk(LOG_PANIC, "EL0_SYNC\n");
320             break;
321         case AARCH64_EVECTOR_EL0_IRQ:
322             printk(LOG_PANIC, "EL0_IRQ\n");
323             break;
324         case AARCH64_EVECTOR_EL0_FIQ:
325             printk(LOG_PANIC, "EL0_FIQ\n");
326             break;
327         case AARCH64_EVECTOR_EL0_SERROR:
328             printk(LOG_PANIC, "EL0_SERROR\n");
329             break;
330         case AARCH64_EVECTOR_EL1_SYNC:
331             printk(LOG_PANIC, "EL1_SYNC\n");
332             break;
333         case AARCH64_EVECTOR_EL1_IRQ:
334             printk(LOG_PANIC, "EL1_IRQ\n");
335             break;
336         case AARCH64_EVECTOR_EL1_FIQ:
337             printk(LOG_PANIC, "EL1_FIQ\n");
338             break;
339         case AARCH64_EVECTOR_EL1_SERROR:
340             printk(LOG_PANIC, "EL1_SERROR\n");
341             break;
342         case AARCH64_EVECTOR_EL2_SYNC:
343             printk(LOG_PANIC, "EL2_SYNC\n");
344             break;
345         case AARCH64_EVECTOR_EL2_IRQ:
346             printk(LOG_PANIC, "EL2_IRQ\n");
347             break;
348         case AARCH64_EVECTOR_EL2_FIQ:
349             printk(LOG_PANIC, "EL2_FIQ\n");
350             break;
351         case AARCH64_EVECTOR_EL2_SERROR:
352             printk(LOG_PANIC, "EL2_SERROR\n");
353             break;
354         case AARCH32_EVECTOR_EL0_SYNC:
355             printk(LOG_PANIC, "AARCH32_EL0_SYNC\n");
356             break;
357         case AARCH32_EVECTOR_EL0_IRQ:
358             printk(LOG_PANIC, "AARCH32_EL0_IRQ\n");
359             break;
360         case AARCH32_EVECTOR_EL0_FIQ:
361             printk(LOG_PANIC, "AARCH32_EL0_FIQ\n");
362             break;
363         case AARCH32_EVECTOR_EL0_SERROR:
364             printk(LOG_PANIC, "AARCH32_EL0_SERROR\n");
365             break;
366     }
367
368     for (i = 0; i < 31; i++) {
369         uint64_t reg = save_area->regs[i];
370         if (reg >= (uintptr_t)&kernel_first_byte && reg <= (uintptr_t)&kernel_text_final_byte) {
371             printk(LOG_PANIC, "x%d\t%"PRIx64" (%#" PRIx64 ")\n", i, reg, reg - (uintptr_t)&kernel_first_byte);
372         } else {
373             printk(LOG_PANIC, "x%d\t%"PRIx64"\n", i, reg);
374         }
375     }
376
377     printk(LOG_PANIC, "sp\t%"PRIx64"\n", save_area->regs[SP_REG]);
378     printk(LOG_PANIC, "pc\t%"PRIx64"\n", epc);
379     printk(LOG_PANIC, "spsr\t%"PRIx64"\n", spsr);
380     printk(LOG_PANIC, "instruction-specific syndrome\t%x\n", iss);
381
382     /* Skip the trap frame to dump the prior stack. */
383     uint64_t *kstack_base= (void *)save_area + (NUM_REGS * 8);
384
385     if((((uintptr_t)kstack_base) & MASK(3)) != 0) {
386         kstack_base= (uint64_t *)((uint64_t)kstack_base & ~MASK(3));
387         printk(LOG_PANIC,
388                "Kernel stack is misaligned, dumping from %p\n",
389                kstack_base);
390     }
391
392     uint64_t kstack_len =
393         (((uint64_t)kernel_stack + KERNEL_STACK_SIZE) -
394          (uint64_t)kstack_base) /
395         sizeof(uint64_t);
396
397     printk(LOG_PANIC,
398            "Kernel stack (0x%p - 0x%p):\n",
399            kstack_base,
400            (void *)kernel_stack + KERNEL_STACK_SIZE);
401
402     for(i= 0; i < kstack_len-2; i+=2) {
403         if(i > STACK_DUMP_LIMIT) {
404             printk(LOG_PANIC, "...\n");
405             break;
406         }
407
408         printk(LOG_PANIC,
409                "%016"PRIx64"  %016"PRIx64"  %016"PRIx64"\n",
410                (uint64_t)(kstack_base + i),
411                kstack_base[i],
412                kstack_base[i+1]);
413     }
414
415     switch(exception_class) {
416         case aarch64_ec_unknown:
417             panic("Unknown reason/instruction.\n");
418
419         case aarch64_ec_wfi:
420             panic("Trapped WFI/WFI.\n");
421
422         case aarch64_ec_mcr_cp15:
423         case aarch64_ec_mcrr_cp15:
424             panic("CP15 abort.\n");
425
426         case aarch64_ec_mcr_cp14:
427         case aarch64_ec_ldc_cp14:
428         case aarch64_ec_mcrr_cp14:
429             panic("CP14 abort.\n");
430
431         case aarch64_ec_fpen:
432         case aarch64_ec_fpu_aa32:
433         case aarch64_ec_fpu_aa64:
434             panic("FPU abort.\n");
435
436         case aarch64_ec_mcr_cp10:
437             panic("CP10 abort.\n");
438
439         case aarch64_ec_il:
440             panic("PSTATE.IL == 1.\n");
441
442         case aarch64_ec_svc_aa32:
443         case aarch64_ec_hvc_aa32:
444         case aarch64_ec_svc_aa64:
445         case aarch64_ec_hvc_aa64:
446         case aarch64_ec_smc_aa64:
447             panic("Unhandled system/hypervisor/monitor call.\n");
448
449         case aarch64_ec_mrs:
450             panic("Exception caused by MSR/MRS.\n");
451
452         case aarch64_ec_impl:
453             panic("Implementation-specific exception.\n");
454
455         case aarch64_ec_iabt_low:
456             panic("Instruction abort at user level.\n");
457
458         case aarch64_ec_iabt_high:
459             panic("Instruction abort in the kernel.\n");
460
461         case aarch64_ec_pc_align:
462             panic("Misaligned PC @0x%"PRIx64".\n",
463                   sysreg_read_far());
464
465         case aarch64_ec_dabt_low:
466             panic("Data abort at user level @0x%"PRIx64".\n",
467                   sysreg_read_far());
468
469         case aarch64_ec_dabt_high:
470             printk(LOG_PANIC,
471                    "Data abort in the kernel @0x%"PRIx64".\n",
472                    sysreg_read_far());
473             printk(LOG_PANIC, "Abort type: ");
474             switch(iss) {
475                 case aarch64_dsfc_size_l0:
476                     printk(LOG_PANIC, "address size fault, L0/TTBR\n");
477                     break;
478                 case aarch64_dsfc_size_l1:
479                     printk(LOG_PANIC, "address size fault, L1\n");
480                     break;
481                 case aarch64_dsfc_size_l2:
482                     printk(LOG_PANIC, "address size fault, L2\n");
483                     break;
484                 case aarch64_dsfc_size_l3:
485                     printk(LOG_PANIC, "address size fault, L3\n");
486                     break;
487                 case aarch64_dsfc_trans_l0:
488                     printk(LOG_PANIC, "translation fault, L0/TTBR\n");
489                     break;
490                 case aarch64_dsfc_trans_l1:
491                     printk(LOG_PANIC, "translation fault, L1\n");
492                     break;
493                 case aarch64_dsfc_trans_l2:
494                     printk(LOG_PANIC, "translation fault, L2\n");
495                     break;
496                 case aarch64_dsfc_trans_l3:
497                     printk(LOG_PANIC, "translation fault, L3\n");
498                     break;
499                 case aarch64_dsfc_flag_l1:
500                     printk(LOG_PANIC, "access flag fault, L1\n");
501                     break;
502                 case aarch64_dsfc_flag_l2:
503                     printk(LOG_PANIC, "access flag fault, L2\n");
504                     break;
505                 case aarch64_dsfc_flag_l3:
506                     printk(LOG_PANIC, "access flag fault, L3\n");
507                     break;
508                 case aarch64_dsfc_perm_l1:
509                     printk(LOG_PANIC, "permission fault, L1\n");
510                     break;
511                 case aarch64_dsfc_perm_l2:
512                     printk(LOG_PANIC, "permission fault, L2\n");
513                     break;
514                 case aarch64_dsfc_perm_l3:
515                     printk(LOG_PANIC, "permission fault, L3\n");
516                     break;
517                 case aarch64_dsfc_external:
518                     printk(LOG_PANIC, "external abort\n");
519                     break;
520                 case aarch64_dsfc_external_l0:
521                     printk(LOG_PANIC, "external abort on walk, L0/TTBR\n");
522                     break;
523                 case aarch64_dsfc_external_l1:
524                     printk(LOG_PANIC, "external abort on walk, L1\n");
525                     break;
526                 case aarch64_dsfc_external_l2:
527                     printk(LOG_PANIC, "external abort on walk, L2\n");
528                     break;
529                 case aarch64_dsfc_external_l3:
530                     printk(LOG_PANIC, "external abort on walk, L3\n");
531                     break;
532                 case aarch64_dsfc_parity:
533                     printk(LOG_PANIC, "parity error\n");
534                     break;
535                 case aarch64_dsfc_parity_l0:
536                     printk(LOG_PANIC, "parity error on walk, L0/TTBR\n");
537                     break;
538                 case aarch64_dsfc_parity_l1:
539                     printk(LOG_PANIC, "parity error on walk, L1\n");
540                     break;
541                 case aarch64_dsfc_parity_l2:
542                     printk(LOG_PANIC, "parity error on walk, L2\n");
543                     break;
544                 case aarch64_dsfc_parity_l3:
545                     printk(LOG_PANIC, "parity error on walk, L3\n");
546                     break;
547                 case aarch64_dsfc_alighment:
548                     printk(LOG_PANIC, "alignment fault\n");
549                     break;
550                 case aarch64_dsfc_tlb_confl:
551                     printk(LOG_PANIC, "TLB conflict\n");
552                     break;
553                 case aarch64_dsfc_impl1:
554                     printk(LOG_PANIC, "implementation-defined fault 1\n");
555                     break;
556                 case aarch64_dsfc_impl2:
557                     printk(LOG_PANIC, "implementation-defined fault 2\n");
558                     break;
559                 case aarch64_dsfc_sect_dom:
560                     printk(LOG_PANIC, "domain fault on section\n");
561                     break;
562                 case aarch64_dsfc_page_dom:
563                     printk(LOG_PANIC, "domain fault on page\n");
564                     break;
565                 default:
566                     printk(LOG_PANIC, "unknown\n");
567                     break;
568             }
569             panic("halting.\n");
570
571         case aarch64_ec_sp_align:
572             panic("Misaligned SP.\n");
573
574         case aarch64_ec_serror:
575             panic("Delayed memory abort.\n");
576
577         case aarch64_ec_bkpt_low:
578             panic("HW Breakpoint in user code.\n");
579
580         case aarch64_ec_bkpt_high:
581             panic("HW Breakpoint in the kernel.\n");
582
583         case aarch64_ec_step_low:
584             panic("Single step in user code.\n");
585
586         case aarch64_ec_step_high:
587             panic("Single step in the kernel.\n");
588
589         case aarch64_ec_wpt_low:
590             panic("HW Watchpoint in user code @0x%"PRIx64".\n",
591                   sysreg_read_far());
592
593         case aarch64_ec_wpt_high:
594             panic("HW Watchpoint in the kernel @0x%"PRIx64".\n",
595                   sysreg_read_far());
596
597         case aarch64_ec_bkpt_soft:
598             panic("AArch32 soft breakpoint.\n");
599
600         case aarch64_ec_bkpt_el2:
601             panic("AArch32 Breakpoint trapped to EL2.\n");
602
603         case aarch64_ec_brk:
604             panic("AArch64 soft breakpoint.\n");
605
606         default:
607             panic("Unrecognised exception.\n");
608     }
609 }