armv8: remove kernel printfs
[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 nosave_handle_irq(void) 
205 {
206     uint32_t irq = 0;
207     irq = platform_get_active_irq();
208
209     debug(SUBSYS_DISPATCH, "IRQ %"PRIu32" while %s\n", irq,
210       dcb_current ? (dcb_current->disabled ? "disabled": "enabled") :
211                     "in kernel");
212
213     static int first_timer_interrupt_fired = 0;
214     // Offer it to the timer
215     if (platform_is_timer_interrupt(irq)) {
216         if(!first_timer_interrupt_fired) {
217             printk(LOG_NOTE, "ARMv8-A: Timer interrupt received!\n");
218             first_timer_interrupt_fired = 1;
219         }
220         platform_acknowledge_irq(irq);
221 #ifndef CONFIG_ONESHOT_TIMER
222         // Set next trigger
223         systime_set_timer(kernel_timeslice);
224 #endif
225         wakeup_check(systime_now());
226         dispatch(schedule());
227     } else {
228         platform_acknowledge_irq(irq);
229         send_user_interrupt(irq);
230         panic("Unhandled IRQ %"PRIu32"\n", irq);
231     }
232 }
233
234 void save_handle_irq(arch_registers_state_t* save_area, uintptr_t fault_pc,
235                 uint64_t x0, uint64_t x1, uint64_t x2, uint64_t x3)
236 {
237
238     /* Save the FPU registers */
239     __asm volatile(
240         "   stp q0, q1, [%x0, #0]\n\t"
241         "   stp q2, q3, [%x0, #0x20]\n\t"
242         "   stp q4, q5, [%x0, #0x40]\n\t"
243         "   stp q6, q7, [%x0, #0x60]\n\t"
244         "   stp q8, q9, [%x0, #0x80]\n\t"
245         "   stp q10, q11, [%x0, #0xa0]\n\t"
246         "   stp q12, q13, [%x0, #0xc0]\n\t"
247         "   stp q14, q15, [%x0, #0xe0]\n\t"
248         "   stp q16, q17, [%x0, #0x100]\n\t"
249         "   stp q18, q19, [%x0, #0x120]\n\t"
250         "   stp q20, q21, [%x0, #0x140]\n\t"
251         "   stp q22, q23, [%x0, #0x160]\n\t"
252         "   stp q24, q25, [%x0, #0x180]\n\t"
253         "   stp q26, q27, [%x0, #0x1a0]\n\t"
254         "   stp q28, q29, [%x0, #0x1c0]\n\t"
255         "   stp q30, q31, [%x0, #0x1e0]\n\t"
256          :: "r" (&save_area->named.v));
257
258     /* The assembly stub leaves the first 4 registers, the stack pointer,
259      * the exception PC, and the SPSR for us to save, as it's run out of room for
260      * the necessary instructions. */
261     save_area->named.x0    = x0;
262     save_area->named.x1    = x1;
263     save_area->named.x2    = x2;
264     save_area->named.x3    = x3;
265     save_area->named.stack = armv8_SP_EL0_rd(NULL);
266     save_area->named.spsr  = armv8_SPSR_EL1_rd(NULL);
267     save_area->named.pc    = fault_pc;
268
269     if (dcb_current != NULL) {
270         dispatcher_handle_t handle = dcb_current->disp;
271         if (save_area == dispatcher_get_disabled_save_area(handle)) {
272             assert(dispatcher_is_disabled_ip(handle, fault_pc));
273             dcb_current->disabled = true;
274         } else {
275             assert(save_area == dispatcher_get_enabled_save_area(handle));
276             assert(!dispatcher_is_disabled_ip(handle, fault_pc));
277             dcb_current->disabled = false;
278         }
279     }
280
281     nosave_handle_irq();
282 }
283
284 #define STACK_DUMP_LIMIT 32
285
286 /* For unhandled faults, we print a register dump and panic. */
287 void fatal_kernel_fault(lvaddr_t epc, uint64_t spsr, uint64_t esr,
288                         uint64_t vector, arch_registers_state_t* save_area)
289 {
290     size_t i;
291     enum aarch64_exception_class exception_class = FIELD(26,6,esr);
292     /* int instruction_length = FIELD(25,1,esr); */
293     int iss                = FIELD(0,25,esr);
294
295     /* Save the FPU registers */
296     __asm volatile(
297         "   stp q0, q1, [%x0, #0]\n\t"
298         "   stp q2, q3, [%x0, #0x20]\n\t"
299         "   stp q4, q5, [%x0, #0x40]\n\t"
300         "   stp q6, q7, [%x0, #0x60]\n\t"
301         "   stp q8, q9, [%x0, #0x80]\n\t"
302         "   stp q10, q11, [%x0, #0xa0]\n\t"
303         "   stp q12, q13, [%x0, #0xc0]\n\t"
304         "   stp q14, q15, [%x0, #0xe0]\n\t"
305         "   stp q16, q17, [%x0, #0x100]\n\t"
306         "   stp q18, q19, [%x0, #0x120]\n\t"
307         "   stp q20, q21, [%x0, #0x140]\n\t"
308         "   stp q22, q23, [%x0, #0x160]\n\t"
309         "   stp q24, q25, [%x0, #0x180]\n\t"
310         "   stp q26, q27, [%x0, #0x1a0]\n\t"
311         "   stp q28, q29, [%x0, #0x1c0]\n\t"
312         "   stp q30, q31, [%x0, #0x1e0]\n\t"
313          :: "r" (&save_area->named.v));
314
315     printk(LOG_PANIC, "Fatal (unexpected) fault at 0x%"PRIx64 " (%#" PRIx64 ")\n\n", epc, epc - (uintptr_t)&kernel_first_byte);
316     printk(LOG_PANIC, "Register context saved at: %p\n", save_area);
317     printk(LOG_PANIC, "Vector: ");
318     switch(vector) {
319         case AARCH64_EVECTOR_UNDEF:
320             printk(LOG_PANIC, "UNDEF\n");
321             break;
322         case AARCH64_EVECTOR_EL0_SYNC:
323             printk(LOG_PANIC, "EL0_SYNC\n");
324             break;
325         case AARCH64_EVECTOR_EL0_IRQ:
326             printk(LOG_PANIC, "EL0_IRQ\n");
327             break;
328         case AARCH64_EVECTOR_EL0_FIQ:
329             printk(LOG_PANIC, "EL0_FIQ\n");
330             break;
331         case AARCH64_EVECTOR_EL0_SERROR:
332             printk(LOG_PANIC, "EL0_SERROR\n");
333             break;
334         case AARCH64_EVECTOR_EL1_SYNC:
335             printk(LOG_PANIC, "EL1_SYNC\n");
336             break;
337         case AARCH64_EVECTOR_EL1_IRQ:
338             printk(LOG_PANIC, "EL1_IRQ\n");
339             break;
340         case AARCH64_EVECTOR_EL1_FIQ:
341             printk(LOG_PANIC, "EL1_FIQ\n");
342             break;
343         case AARCH64_EVECTOR_EL1_SERROR:
344             printk(LOG_PANIC, "EL1_SERROR\n");
345             break;
346         case AARCH64_EVECTOR_EL2_SYNC:
347             printk(LOG_PANIC, "EL2_SYNC\n");
348             break;
349         case AARCH64_EVECTOR_EL2_IRQ:
350             printk(LOG_PANIC, "EL2_IRQ\n");
351             break;
352         case AARCH64_EVECTOR_EL2_FIQ:
353             printk(LOG_PANIC, "EL2_FIQ\n");
354             break;
355         case AARCH64_EVECTOR_EL2_SERROR:
356             printk(LOG_PANIC, "EL2_SERROR\n");
357             break;
358         case AARCH32_EVECTOR_EL0_SYNC:
359             printk(LOG_PANIC, "AARCH32_EL0_SYNC\n");
360             break;
361         case AARCH32_EVECTOR_EL0_IRQ:
362             printk(LOG_PANIC, "AARCH32_EL0_IRQ\n");
363             break;
364         case AARCH32_EVECTOR_EL0_FIQ:
365             printk(LOG_PANIC, "AARCH32_EL0_FIQ\n");
366             break;
367         case AARCH32_EVECTOR_EL0_SERROR:
368             printk(LOG_PANIC, "AARCH32_EL0_SERROR\n");
369             break;
370     }
371
372     for (i = 0; i < 31; i++) {
373         uint64_t reg = save_area->regs[i];
374         if (reg >= (uintptr_t)&kernel_first_byte && reg <= (uintptr_t)&kernel_text_final_byte) {
375             printk(LOG_PANIC, "x%d\t%"PRIx64" (%#" PRIx64 ")\n", i, reg, reg - (uintptr_t)&kernel_first_byte);
376         } else {
377             printk(LOG_PANIC, "x%d\t%"PRIx64"\n", i, reg);
378         }
379     }
380
381     printk(LOG_PANIC, "sp\t%"PRIx64"\n", save_area->regs[SP_REG]);
382     printk(LOG_PANIC, "pc\t%"PRIx64"\n", epc);
383     printk(LOG_PANIC, "spsr\t%"PRIx64"\n", spsr);
384     printk(LOG_PANIC, "instruction-specific syndrome\t%x\n", iss);
385
386     /* Skip the trap frame to dump the prior stack. */
387     uint64_t *kstack_base= (void *)save_area + (NUM_REGS * 8);
388
389     if((((uintptr_t)kstack_base) & MASK(3)) != 0) {
390         kstack_base= (uint64_t *)((uint64_t)kstack_base & ~MASK(3));
391         printk(LOG_PANIC,
392                "Kernel stack is misaligned, dumping from %p\n",
393                kstack_base);
394     }
395
396     uint64_t kstack_len =
397         (((uint64_t)kernel_stack + KERNEL_STACK_SIZE) -
398          (uint64_t)kstack_base) /
399         sizeof(uint64_t);
400
401     printk(LOG_PANIC,
402            "Kernel stack (0x%p - 0x%p):\n",
403            kstack_base,
404            (void *)kernel_stack + KERNEL_STACK_SIZE);
405
406     for(i= 0; i < kstack_len-2; i+=2) {
407         if(i > STACK_DUMP_LIMIT) {
408             printk(LOG_PANIC, "...\n");
409             break;
410         }
411
412         printk(LOG_PANIC,
413                "%016"PRIx64"  %016"PRIx64"  %016"PRIx64"\n",
414                (uint64_t)(kstack_base + i),
415                kstack_base[i],
416                kstack_base[i+1]);
417     }
418
419     switch(exception_class) {
420         case aarch64_ec_unknown:
421             panic("Unknown reason/instruction.\n");
422
423         case aarch64_ec_wfi:
424             panic("Trapped WFI/WFI.\n");
425
426         case aarch64_ec_mcr_cp15:
427         case aarch64_ec_mcrr_cp15:
428             panic("CP15 abort.\n");
429
430         case aarch64_ec_mcr_cp14:
431         case aarch64_ec_ldc_cp14:
432         case aarch64_ec_mcrr_cp14:
433             panic("CP14 abort.\n");
434
435         case aarch64_ec_fpen:
436         case aarch64_ec_fpu_aa32:
437         case aarch64_ec_fpu_aa64:
438             panic("FPU abort.\n");
439
440         case aarch64_ec_mcr_cp10:
441             panic("CP10 abort.\n");
442
443         case aarch64_ec_il:
444             panic("PSTATE.IL == 1.\n");
445
446         case aarch64_ec_svc_aa32:
447         case aarch64_ec_hvc_aa32:
448         case aarch64_ec_svc_aa64:
449         case aarch64_ec_hvc_aa64:
450         case aarch64_ec_smc_aa64:
451             panic("Unhandled system/hypervisor/monitor call.\n");
452
453         case aarch64_ec_mrs:
454             panic("Exception caused by MSR/MRS.\n");
455
456         case aarch64_ec_impl:
457             panic("Implementation-specific exception.\n");
458
459         case aarch64_ec_iabt_low:
460             panic("Instruction abort at user level.\n");
461
462         case aarch64_ec_iabt_high:
463             panic("Instruction abort in the kernel.\n");
464
465         case aarch64_ec_pc_align:
466             panic("Misaligned PC @0x%"PRIx64".\n",
467                   sysreg_read_far());
468
469         case aarch64_ec_dabt_low:
470             panic("Data abort at user level @0x%"PRIx64".\n",
471                   sysreg_read_far());
472
473         case aarch64_ec_dabt_high:
474             printk(LOG_PANIC,
475                    "Data abort in the kernel @0x%"PRIx64".\n",
476                    sysreg_read_far());
477             printk(LOG_PANIC, "Abort type: ");
478             switch(iss) {
479                 case aarch64_dsfc_size_l0:
480                     printk(LOG_PANIC, "address size fault, L0/TTBR\n");
481                     break;
482                 case aarch64_dsfc_size_l1:
483                     printk(LOG_PANIC, "address size fault, L1\n");
484                     break;
485                 case aarch64_dsfc_size_l2:
486                     printk(LOG_PANIC, "address size fault, L2\n");
487                     break;
488                 case aarch64_dsfc_size_l3:
489                     printk(LOG_PANIC, "address size fault, L3\n");
490                     break;
491                 case aarch64_dsfc_trans_l0:
492                     printk(LOG_PANIC, "translation fault, L0/TTBR\n");
493                     break;
494                 case aarch64_dsfc_trans_l1:
495                     printk(LOG_PANIC, "translation fault, L1\n");
496                     break;
497                 case aarch64_dsfc_trans_l2:
498                     printk(LOG_PANIC, "translation fault, L2\n");
499                     break;
500                 case aarch64_dsfc_trans_l3:
501                     printk(LOG_PANIC, "translation fault, L3\n");
502                     break;
503                 case aarch64_dsfc_flag_l1:
504                     printk(LOG_PANIC, "access flag fault, L1\n");
505                     break;
506                 case aarch64_dsfc_flag_l2:
507                     printk(LOG_PANIC, "access flag fault, L2\n");
508                     break;
509                 case aarch64_dsfc_flag_l3:
510                     printk(LOG_PANIC, "access flag fault, L3\n");
511                     break;
512                 case aarch64_dsfc_perm_l1:
513                     printk(LOG_PANIC, "permission fault, L1\n");
514                     break;
515                 case aarch64_dsfc_perm_l2:
516                     printk(LOG_PANIC, "permission fault, L2\n");
517                     break;
518                 case aarch64_dsfc_perm_l3:
519                     printk(LOG_PANIC, "permission fault, L3\n");
520                     break;
521                 case aarch64_dsfc_external:
522                     printk(LOG_PANIC, "external abort\n");
523                     break;
524                 case aarch64_dsfc_external_l0:
525                     printk(LOG_PANIC, "external abort on walk, L0/TTBR\n");
526                     break;
527                 case aarch64_dsfc_external_l1:
528                     printk(LOG_PANIC, "external abort on walk, L1\n");
529                     break;
530                 case aarch64_dsfc_external_l2:
531                     printk(LOG_PANIC, "external abort on walk, L2\n");
532                     break;
533                 case aarch64_dsfc_external_l3:
534                     printk(LOG_PANIC, "external abort on walk, L3\n");
535                     break;
536                 case aarch64_dsfc_parity:
537                     printk(LOG_PANIC, "parity error\n");
538                     break;
539                 case aarch64_dsfc_parity_l0:
540                     printk(LOG_PANIC, "parity error on walk, L0/TTBR\n");
541                     break;
542                 case aarch64_dsfc_parity_l1:
543                     printk(LOG_PANIC, "parity error on walk, L1\n");
544                     break;
545                 case aarch64_dsfc_parity_l2:
546                     printk(LOG_PANIC, "parity error on walk, L2\n");
547                     break;
548                 case aarch64_dsfc_parity_l3:
549                     printk(LOG_PANIC, "parity error on walk, L3\n");
550                     break;
551                 case aarch64_dsfc_alighment:
552                     printk(LOG_PANIC, "alignment fault\n");
553                     break;
554                 case aarch64_dsfc_tlb_confl:
555                     printk(LOG_PANIC, "TLB conflict\n");
556                     break;
557                 case aarch64_dsfc_impl1:
558                     printk(LOG_PANIC, "implementation-defined fault 1\n");
559                     break;
560                 case aarch64_dsfc_impl2:
561                     printk(LOG_PANIC, "implementation-defined fault 2\n");
562                     break;
563                 case aarch64_dsfc_sect_dom:
564                     printk(LOG_PANIC, "domain fault on section\n");
565                     break;
566                 case aarch64_dsfc_page_dom:
567                     printk(LOG_PANIC, "domain fault on page\n");
568                     break;
569                 default:
570                     printk(LOG_PANIC, "unknown\n");
571                     break;
572             }
573             panic("halting.\n");
574
575         case aarch64_ec_sp_align:
576             panic("Misaligned SP.\n");
577
578         case aarch64_ec_serror:
579             panic("Delayed memory abort.\n");
580
581         case aarch64_ec_bkpt_low:
582             panic("HW Breakpoint in user code.\n");
583
584         case aarch64_ec_bkpt_high:
585             panic("HW Breakpoint in the kernel.\n");
586
587         case aarch64_ec_step_low:
588             panic("Single step in user code.\n");
589
590         case aarch64_ec_step_high:
591             panic("Single step in the kernel.\n");
592
593         case aarch64_ec_wpt_low:
594             panic("HW Watchpoint in user code @0x%"PRIx64".\n",
595                   sysreg_read_far());
596
597         case aarch64_ec_wpt_high:
598             panic("HW Watchpoint in the kernel @0x%"PRIx64".\n",
599                   sysreg_read_far());
600
601         case aarch64_ec_bkpt_soft:
602             panic("AArch32 soft breakpoint.\n");
603
604         case aarch64_ec_bkpt_el2:
605             panic("AArch32 Breakpoint trapped to EL2.\n");
606
607         case aarch64_ec_brk:
608             panic("AArch64 soft breakpoint.\n");
609
610         default:
611             panic("Unrecognised exception.\n");
612     }
613 }