1e5acd89cSAndrew Turner /*- 2e5acd89cSAndrew Turner * Copyright (c) 2014 Andrew Turner 3e5acd89cSAndrew Turner * All rights reserved. 4e5acd89cSAndrew Turner * 5e5acd89cSAndrew Turner * Redistribution and use in source and binary forms, with or without 6e5acd89cSAndrew Turner * modification, are permitted provided that the following conditions 7e5acd89cSAndrew Turner * are met: 8e5acd89cSAndrew Turner * 1. Redistributions of source code must retain the above copyright 9e5acd89cSAndrew Turner * notice, this list of conditions and the following disclaimer. 10e5acd89cSAndrew Turner * 2. Redistributions in binary form must reproduce the above copyright 11e5acd89cSAndrew Turner * notice, this list of conditions and the following disclaimer in the 12e5acd89cSAndrew Turner * documentation and/or other materials provided with the distribution. 13e5acd89cSAndrew Turner * 14e5acd89cSAndrew Turner * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15e5acd89cSAndrew Turner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16e5acd89cSAndrew Turner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17e5acd89cSAndrew Turner * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18e5acd89cSAndrew Turner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19e5acd89cSAndrew Turner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20e5acd89cSAndrew Turner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21e5acd89cSAndrew Turner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22e5acd89cSAndrew Turner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23e5acd89cSAndrew Turner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24e5acd89cSAndrew Turner * SUCH DAMAGE. 25e5acd89cSAndrew Turner * 26e5acd89cSAndrew Turner */ 27e5acd89cSAndrew Turner 28e5acd89cSAndrew Turner #include <sys/cdefs.h> 29e5acd89cSAndrew Turner __FBSDID("$FreeBSD$"); 30e5acd89cSAndrew Turner 31e5acd89cSAndrew Turner #include <sys/param.h> 32e5acd89cSAndrew Turner #include <sys/systm.h> 33e5acd89cSAndrew Turner #include <sys/kernel.h> 34e5acd89cSAndrew Turner #include <sys/lock.h> 35e5acd89cSAndrew Turner #include <sys/mutex.h> 36e5acd89cSAndrew Turner #include <sys/pioctl.h> 37e5acd89cSAndrew Turner #include <sys/proc.h> 38e5acd89cSAndrew Turner #include <sys/ptrace.h> 39e5acd89cSAndrew Turner #include <sys/syscall.h> 40e5acd89cSAndrew Turner #include <sys/sysent.h> 41e5acd89cSAndrew Turner #ifdef KDB 42e5acd89cSAndrew Turner #include <sys/kdb.h> 43e5acd89cSAndrew Turner #endif 44e5acd89cSAndrew Turner 45e5acd89cSAndrew Turner #include <vm/vm.h> 46e5acd89cSAndrew Turner #include <vm/pmap.h> 47e5acd89cSAndrew Turner #include <vm/vm_kern.h> 48e5acd89cSAndrew Turner #include <vm/vm_map.h> 49cb02f6b9SAndrew Turner #include <vm/vm_param.h> 50e5acd89cSAndrew Turner #include <vm/vm_extern.h> 51e5acd89cSAndrew Turner 52e5acd89cSAndrew Turner #include <machine/frame.h> 53e5acd89cSAndrew Turner #include <machine/pcb.h> 54e5acd89cSAndrew Turner #include <machine/pcpu.h> 55e5acd89cSAndrew Turner 56b78ee15eSRuslan Bukin #ifdef KDTRACE_HOOKS 57b78ee15eSRuslan Bukin #include <sys/dtrace_bsd.h> 58b78ee15eSRuslan Bukin #endif 59b78ee15eSRuslan Bukin 60e5acd89cSAndrew Turner #ifdef VFP 61e5acd89cSAndrew Turner #include <machine/vfp.h> 62e5acd89cSAndrew Turner #endif 63e5acd89cSAndrew Turner 64e5acd89cSAndrew Turner #ifdef KDB 65e5acd89cSAndrew Turner #include <machine/db_machdep.h> 66e5acd89cSAndrew Turner #endif 67e5acd89cSAndrew Turner 68e5acd89cSAndrew Turner #ifdef DDB 69e5acd89cSAndrew Turner #include <ddb/db_output.h> 70e5acd89cSAndrew Turner #endif 71e5acd89cSAndrew Turner 729d77aa2aSAndrew Turner extern register_t fsu_intr_fault; 73e5acd89cSAndrew Turner 74e5acd89cSAndrew Turner /* Called from exception.S */ 75e5acd89cSAndrew Turner void do_el1h_sync(struct trapframe *); 76e5acd89cSAndrew Turner void do_el0_sync(struct trapframe *); 77e5acd89cSAndrew Turner void do_el0_error(struct trapframe *); 780510aedcSKonstantin Belousov static void print_registers(struct trapframe *frame); 79e5acd89cSAndrew Turner 80b78ee15eSRuslan Bukin int (*dtrace_invop_jump_addr)(struct trapframe *); 81b78ee15eSRuslan Bukin 82e5acd89cSAndrew Turner static __inline void 83cb02f6b9SAndrew Turner call_trapsignal(struct thread *td, int sig, int code, void *addr) 84e5acd89cSAndrew Turner { 85e5acd89cSAndrew Turner ksiginfo_t ksi; 86e5acd89cSAndrew Turner 87e5acd89cSAndrew Turner ksiginfo_init_trap(&ksi); 88e5acd89cSAndrew Turner ksi.ksi_signo = sig; 89cb02f6b9SAndrew Turner ksi.ksi_code = code; 90cb02f6b9SAndrew Turner ksi.ksi_addr = addr; 91e5acd89cSAndrew Turner trapsignal(td, &ksi); 92e5acd89cSAndrew Turner } 93e5acd89cSAndrew Turner 94e5acd89cSAndrew Turner int 95e5acd89cSAndrew Turner cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa) 96e5acd89cSAndrew Turner { 97e5acd89cSAndrew Turner struct proc *p; 98e5acd89cSAndrew Turner register_t *ap; 99e5acd89cSAndrew Turner int nap; 100e5acd89cSAndrew Turner 101e5acd89cSAndrew Turner nap = 8; 102e5acd89cSAndrew Turner p = td->td_proc; 103e5acd89cSAndrew Turner ap = td->td_frame->tf_x; 104e5acd89cSAndrew Turner 105e5acd89cSAndrew Turner sa->code = td->td_frame->tf_x[8]; 106e5acd89cSAndrew Turner 107e5acd89cSAndrew Turner if (sa->code == SYS_syscall || sa->code == SYS___syscall) { 108e5acd89cSAndrew Turner sa->code = *ap++; 109e5acd89cSAndrew Turner nap--; 110e5acd89cSAndrew Turner } 111e5acd89cSAndrew Turner 112e5acd89cSAndrew Turner if (p->p_sysent->sv_mask) 113e5acd89cSAndrew Turner sa->code &= p->p_sysent->sv_mask; 114e5acd89cSAndrew Turner if (sa->code >= p->p_sysent->sv_size) 115e5acd89cSAndrew Turner sa->callp = &p->p_sysent->sv_table[0]; 116e5acd89cSAndrew Turner else 117e5acd89cSAndrew Turner sa->callp = &p->p_sysent->sv_table[sa->code]; 118e5acd89cSAndrew Turner 119e5acd89cSAndrew Turner sa->narg = sa->callp->sy_narg; 120e5acd89cSAndrew Turner memcpy(sa->args, ap, nap * sizeof(register_t)); 121e5acd89cSAndrew Turner if (sa->narg > nap) 1226bc3fe5fSPedro F. Giffuni panic("ARM64TODO: Could we have more than 8 args?"); 123e5acd89cSAndrew Turner 124e5acd89cSAndrew Turner td->td_retval[0] = 0; 125e5acd89cSAndrew Turner td->td_retval[1] = 0; 126e5acd89cSAndrew Turner 127e5acd89cSAndrew Turner return (0); 128e5acd89cSAndrew Turner } 129e5acd89cSAndrew Turner 130e5acd89cSAndrew Turner #include "../../kern/subr_syscall.c" 131e5acd89cSAndrew Turner 132e5acd89cSAndrew Turner static void 133e5acd89cSAndrew Turner svc_handler(struct trapframe *frame) 134e5acd89cSAndrew Turner { 135e5acd89cSAndrew Turner struct syscall_args sa; 136e5acd89cSAndrew Turner struct thread *td; 137e5acd89cSAndrew Turner int error; 138e5acd89cSAndrew Turner 139e5acd89cSAndrew Turner td = curthread; 140e5acd89cSAndrew Turner 141e5acd89cSAndrew Turner error = syscallenter(td, &sa); 142e5acd89cSAndrew Turner syscallret(td, error, &sa); 143e5acd89cSAndrew Turner } 144e5acd89cSAndrew Turner 145e5acd89cSAndrew Turner static void 1460510aedcSKonstantin Belousov data_abort(struct trapframe *frame, uint64_t esr, uint64_t far, int lower) 147e5acd89cSAndrew Turner { 148e5acd89cSAndrew Turner struct vm_map *map; 149e5acd89cSAndrew Turner struct thread *td; 150e5acd89cSAndrew Turner struct proc *p; 151e5acd89cSAndrew Turner struct pcb *pcb; 152e5acd89cSAndrew Turner vm_prot_t ftype; 153e5acd89cSAndrew Turner vm_offset_t va; 154cb02f6b9SAndrew Turner int error, sig, ucode; 155e5acd89cSAndrew Turner 1566ced3789SKonstantin Belousov /* 1576ced3789SKonstantin Belousov * According to the ARMv8-A rev. A.g, B2.10.5 "Load-Exclusive 1586ced3789SKonstantin Belousov * and Store-Exclusive instruction usage restrictions", state 1596ced3789SKonstantin Belousov * of the exclusive monitors after data abort exception is unknown. 1606ced3789SKonstantin Belousov */ 1616ced3789SKonstantin Belousov clrex(); 1626ced3789SKonstantin Belousov 1638f746773SAndrew Turner #ifdef KDB 1648f746773SAndrew Turner if (kdb_active) { 1658f746773SAndrew Turner kdb_reenter(); 1668f746773SAndrew Turner return; 1678f746773SAndrew Turner } 1688f746773SAndrew Turner #endif 1698f746773SAndrew Turner 170e5acd89cSAndrew Turner td = curthread; 171e5acd89cSAndrew Turner pcb = td->td_pcb; 172e5acd89cSAndrew Turner 173e5acd89cSAndrew Turner /* 174e5acd89cSAndrew Turner * Special case for fuswintr and suswintr. These can't sleep so 175e5acd89cSAndrew Turner * handle them early on in the trap handler. 176e5acd89cSAndrew Turner */ 1779d77aa2aSAndrew Turner if (__predict_false(pcb->pcb_onfault == (vm_offset_t)&fsu_intr_fault)) { 178e5acd89cSAndrew Turner frame->tf_elr = pcb->pcb_onfault; 179e5acd89cSAndrew Turner return; 180e5acd89cSAndrew Turner } 181e5acd89cSAndrew Turner 1820510aedcSKonstantin Belousov KASSERT(td->td_md.md_spinlock_count == 0, 1830510aedcSKonstantin Belousov ("data abort with spinlock held")); 1840510aedcSKonstantin Belousov if (td->td_critnest != 0 || WITNESS_CHECK(WARN_SLEEPOK | 1850510aedcSKonstantin Belousov WARN_GIANTOK, NULL, "Kernel page fault") != 0) { 1860510aedcSKonstantin Belousov print_registers(frame); 1871e888d78SAndrew Turner printf(" far: %16lx\n", far); 1881e888d78SAndrew Turner printf(" esr: %.8lx\n", esr); 1890510aedcSKonstantin Belousov panic("data abort in critical section or under mutex"); 1900510aedcSKonstantin Belousov } 191e5acd89cSAndrew Turner 1920510aedcSKonstantin Belousov p = td->td_proc; 193e5acd89cSAndrew Turner if (lower) 1940510aedcSKonstantin Belousov map = &p->p_vmspace->vm_map; 195e5acd89cSAndrew Turner else { 196e5acd89cSAndrew Turner /* The top bit tells us which range to use */ 197e5acd89cSAndrew Turner if ((far >> 63) == 1) 198e5acd89cSAndrew Turner map = kernel_map; 199e5acd89cSAndrew Turner else 2000510aedcSKonstantin Belousov map = &p->p_vmspace->vm_map; 201e5acd89cSAndrew Turner } 202e5acd89cSAndrew Turner 203e5acd89cSAndrew Turner va = trunc_page(far); 204e5acd89cSAndrew Turner ftype = ((esr >> 6) & 1) ? VM_PROT_READ | VM_PROT_WRITE : VM_PROT_READ; 205e5acd89cSAndrew Turner 2061fa67124SKonstantin Belousov /* Fault in the page. */ 207e5acd89cSAndrew Turner error = vm_fault(map, va, ftype, VM_FAULT_NORMAL); 208cb02f6b9SAndrew Turner if (error != KERN_SUCCESS) { 209e5acd89cSAndrew Turner if (lower) { 210e5acd89cSAndrew Turner sig = SIGSEGV; 211cb02f6b9SAndrew Turner if (error == KERN_PROTECTION_FAILURE) 212cb02f6b9SAndrew Turner ucode = SEGV_ACCERR; 213cb02f6b9SAndrew Turner else 214cb02f6b9SAndrew Turner ucode = SEGV_MAPERR; 215cb02f6b9SAndrew Turner call_trapsignal(td, sig, ucode, (void *)far); 216e5acd89cSAndrew Turner } else { 217e5acd89cSAndrew Turner if (td->td_intr_nesting_level == 0 && 218e5acd89cSAndrew Turner pcb->pcb_onfault != 0) { 219e5acd89cSAndrew Turner frame->tf_x[0] = error; 220e5acd89cSAndrew Turner frame->tf_elr = pcb->pcb_onfault; 221e5acd89cSAndrew Turner return; 222e5acd89cSAndrew Turner } 2231e888d78SAndrew Turner 2241e888d78SAndrew Turner printf("Fatal data abort:\n"); 2251e888d78SAndrew Turner print_registers(frame); 2261e888d78SAndrew Turner printf(" far: %16lx\n", far); 2271e888d78SAndrew Turner printf(" esr: %.8lx\n", esr); 2281e888d78SAndrew Turner 2298f746773SAndrew Turner #ifdef KDB 2308f746773SAndrew Turner if (debugger_on_panic || kdb_active) 2318f746773SAndrew Turner if (kdb_trap(ESR_ELx_EXCEPTION(esr), 0, frame)) 2328f746773SAndrew Turner return; 2338f746773SAndrew Turner #endif 234e5acd89cSAndrew Turner panic("vm_fault failed: %lx", frame->tf_elr); 235e5acd89cSAndrew Turner } 236e5acd89cSAndrew Turner } 237e5acd89cSAndrew Turner 238e5acd89cSAndrew Turner if (lower) 239e5acd89cSAndrew Turner userret(td, frame); 240e5acd89cSAndrew Turner } 241e5acd89cSAndrew Turner 242ccd285e7SEd Maste static void 243ccd285e7SEd Maste print_registers(struct trapframe *frame) 244ccd285e7SEd Maste { 245ccd285e7SEd Maste u_int reg; 246ccd285e7SEd Maste 247ccd285e7SEd Maste for (reg = 0; reg < 31; reg++) { 248ccd285e7SEd Maste printf(" %sx%d: %16lx\n", (reg < 10) ? " " : "", reg, 249ccd285e7SEd Maste frame->tf_x[reg]); 250ccd285e7SEd Maste } 251ccd285e7SEd Maste printf(" sp: %16lx\n", frame->tf_sp); 252ccd285e7SEd Maste printf(" lr: %16lx\n", frame->tf_lr); 253ccd285e7SEd Maste printf(" elr: %16lx\n", frame->tf_elr); 254ccd285e7SEd Maste printf("spsr: %16lx\n", frame->tf_spsr); 255ccd285e7SEd Maste } 256ccd285e7SEd Maste 257e5acd89cSAndrew Turner void 258e5acd89cSAndrew Turner do_el1h_sync(struct trapframe *frame) 259e5acd89cSAndrew Turner { 260e5acd89cSAndrew Turner uint32_t exception; 2610510aedcSKonstantin Belousov uint64_t esr, far; 262e5acd89cSAndrew Turner 263e5acd89cSAndrew Turner /* Read the esr register to get the exception details */ 264e5acd89cSAndrew Turner esr = READ_SPECIALREG(esr_el1); 265e5acd89cSAndrew Turner exception = ESR_ELx_EXCEPTION(esr); 266e5acd89cSAndrew Turner 267b78ee15eSRuslan Bukin #ifdef KDTRACE_HOOKS 268b78ee15eSRuslan Bukin if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame, exception)) 269b78ee15eSRuslan Bukin return; 270b78ee15eSRuslan Bukin #endif 271b78ee15eSRuslan Bukin 2723ad7e84eSAndrew Turner CTR4(KTR_TRAP, 2733ad7e84eSAndrew Turner "do_el1_sync: curthread: %p, esr %lx, elr: %lx, frame: %p", 2743ad7e84eSAndrew Turner curthread, esr, frame->tf_elr, frame); 2753ad7e84eSAndrew Turner 276e5acd89cSAndrew Turner switch(exception) { 277e5acd89cSAndrew Turner case EXCP_FP_SIMD: 278e5acd89cSAndrew Turner case EXCP_TRAP_FP: 279ccd285e7SEd Maste print_registers(frame); 2801e888d78SAndrew Turner printf(" esr: %.8lx\n", esr); 281e5acd89cSAndrew Turner panic("VFP exception in the kernel"); 282e5acd89cSAndrew Turner case EXCP_DATA_ABORT: 2830510aedcSKonstantin Belousov far = READ_SPECIALREG(far_el1); 2840510aedcSKonstantin Belousov intr_enable(); 2850510aedcSKonstantin Belousov data_abort(frame, esr, far, 0); 286e5acd89cSAndrew Turner break; 287e5acd89cSAndrew Turner case EXCP_BRK: 288b78ee15eSRuslan Bukin #ifdef KDTRACE_HOOKS 289b78ee15eSRuslan Bukin if ((esr & ESR_ELx_ISS_MASK) == 0x40d && \ 290b78ee15eSRuslan Bukin dtrace_invop_jump_addr != 0) { 291b78ee15eSRuslan Bukin dtrace_invop_jump_addr(frame); 292b78ee15eSRuslan Bukin break; 293b78ee15eSRuslan Bukin } 294b78ee15eSRuslan Bukin #endif 2958f746773SAndrew Turner /* FALLTHROUGH */ 296e5acd89cSAndrew Turner case EXCP_WATCHPT_EL1: 297e5acd89cSAndrew Turner case EXCP_SOFTSTP_EL1: 298e5acd89cSAndrew Turner #ifdef KDB 299e5acd89cSAndrew Turner kdb_trap(exception, 0, frame); 300e5acd89cSAndrew Turner #else 301e5acd89cSAndrew Turner panic("No debugger in kernel.\n"); 302e5acd89cSAndrew Turner #endif 303e5acd89cSAndrew Turner break; 304e5acd89cSAndrew Turner default: 305ccd285e7SEd Maste print_registers(frame); 306e5acd89cSAndrew Turner panic("Unknown kernel exception %x esr_el1 %lx\n", exception, 307e5acd89cSAndrew Turner esr); 308e5acd89cSAndrew Turner } 309e5acd89cSAndrew Turner } 310e5acd89cSAndrew Turner 311ccd285e7SEd Maste /* 3125a060174SEd Maste * The attempted execution of an instruction bit pattern that has no allocated 3138d5bb774SEd Maste * instruction results in an exception with an unknown reason. 314ccd285e7SEd Maste */ 315ccd285e7SEd Maste static void 316add8a9c2SAndrew Turner el0_excp_unknown(struct trapframe *frame, uint64_t far) 317ccd285e7SEd Maste { 318ccd285e7SEd Maste struct thread *td; 319ccd285e7SEd Maste 320ccd285e7SEd Maste td = curthread; 321ccd285e7SEd Maste call_trapsignal(td, SIGILL, ILL_ILLTRP, (void *)far); 322ccd285e7SEd Maste userret(td, frame); 323ccd285e7SEd Maste } 324ccd285e7SEd Maste 325e5acd89cSAndrew Turner void 326e5acd89cSAndrew Turner do_el0_sync(struct trapframe *frame) 327e5acd89cSAndrew Turner { 3280987c184SAndrew Turner struct thread *td; 329e5acd89cSAndrew Turner uint32_t exception; 3300510aedcSKonstantin Belousov uint64_t esr, far; 331e5acd89cSAndrew Turner 332e5acd89cSAndrew Turner /* Check we have a sane environment when entering from userland */ 333e5acd89cSAndrew Turner KASSERT((uintptr_t)get_pcpu() >= VM_MIN_KERNEL_ADDRESS, 334e5acd89cSAndrew Turner ("Invalid pcpu address from userland: %p (tpidr %lx)", 335e5acd89cSAndrew Turner get_pcpu(), READ_SPECIALREG(tpidr_el1))); 336e5acd89cSAndrew Turner 33787e19994SAndrew Turner td = curthread; 33887e19994SAndrew Turner td->td_frame = frame; 33987e19994SAndrew Turner 340e5acd89cSAndrew Turner esr = READ_SPECIALREG(esr_el1); 341e5acd89cSAndrew Turner exception = ESR_ELx_EXCEPTION(esr); 3420510aedcSKonstantin Belousov switch (exception) { 343add8a9c2SAndrew Turner case EXCP_UNKNOWN: 3440510aedcSKonstantin Belousov case EXCP_INSN_ABORT_L: 3450510aedcSKonstantin Belousov case EXCP_DATA_ABORT_L: 3460510aedcSKonstantin Belousov case EXCP_DATA_ABORT: 3470510aedcSKonstantin Belousov far = READ_SPECIALREG(far_el1); 3480510aedcSKonstantin Belousov } 3490510aedcSKonstantin Belousov intr_enable(); 350e5acd89cSAndrew Turner 3513ad7e84eSAndrew Turner CTR4(KTR_TRAP, 3523ad7e84eSAndrew Turner "do_el0_sync: curthread: %p, esr %lx, elr: %lx, frame: %p", 3533ad7e84eSAndrew Turner curthread, esr, frame->tf_elr, frame); 3543ad7e84eSAndrew Turner 355e5acd89cSAndrew Turner switch(exception) { 356e5acd89cSAndrew Turner case EXCP_FP_SIMD: 357e5acd89cSAndrew Turner case EXCP_TRAP_FP: 358e5acd89cSAndrew Turner #ifdef VFP 359e5acd89cSAndrew Turner vfp_restore_state(); 360e5acd89cSAndrew Turner #else 361e5acd89cSAndrew Turner panic("VFP exception in userland"); 362e5acd89cSAndrew Turner #endif 363e5acd89cSAndrew Turner break; 364e5acd89cSAndrew Turner case EXCP_SVC: 365e5acd89cSAndrew Turner svc_handler(frame); 366e5acd89cSAndrew Turner break; 367e5acd89cSAndrew Turner case EXCP_INSN_ABORT_L: 368e5acd89cSAndrew Turner case EXCP_DATA_ABORT_L: 3694cbca608SZbigniew Bodek case EXCP_DATA_ABORT: 3700510aedcSKonstantin Belousov data_abort(frame, esr, far, 1); 371e5acd89cSAndrew Turner break; 372ccd285e7SEd Maste case EXCP_UNKNOWN: 373add8a9c2SAndrew Turner el0_excp_unknown(frame, far); 374ccd285e7SEd Maste break; 375729ac0eeSAndrew Turner case EXCP_SP_ALIGN: 376729ac0eeSAndrew Turner call_trapsignal(td, SIGBUS, BUS_ADRALN, (void *)frame->tf_sp); 377729ac0eeSAndrew Turner userret(td, frame); 378729ac0eeSAndrew Turner break; 3798bdcc096SAndrew Turner case EXCP_PC_ALIGN: 3808bdcc096SAndrew Turner call_trapsignal(td, SIGBUS, BUS_ADRALN, (void *)frame->tf_elr); 3818bdcc096SAndrew Turner userret(td, frame); 3828bdcc096SAndrew Turner break; 3830987c184SAndrew Turner case EXCP_BRK: 3840987c184SAndrew Turner call_trapsignal(td, SIGTRAP, TRAP_BRKPT, (void *)frame->tf_elr); 3850987c184SAndrew Turner userret(td, frame); 3860987c184SAndrew Turner break; 38787e19994SAndrew Turner case EXCP_SOFTSTP_EL0: 38887e19994SAndrew Turner td->td_frame->tf_spsr &= ~PSR_SS; 38987e19994SAndrew Turner td->td_pcb->pcb_flags &= ~PCB_SINGLE_STEP; 39087e19994SAndrew Turner WRITE_SPECIALREG(MDSCR_EL1, 39187e19994SAndrew Turner READ_SPECIALREG(MDSCR_EL1) & ~DBG_MDSCR_SS); 39287e19994SAndrew Turner call_trapsignal(td, SIGTRAP, TRAP_TRACE, 39387e19994SAndrew Turner (void *)frame->tf_elr); 39487e19994SAndrew Turner userret(td, frame); 39587e19994SAndrew Turner break; 396e5acd89cSAndrew Turner default: 397ccd285e7SEd Maste print_registers(frame); 398e5acd89cSAndrew Turner panic("Unknown userland exception %x esr_el1 %lx\n", exception, 399e5acd89cSAndrew Turner esr); 400e5acd89cSAndrew Turner } 401e5acd89cSAndrew Turner } 402e5acd89cSAndrew Turner 403e5acd89cSAndrew Turner void 404e5acd89cSAndrew Turner do_el0_error(struct trapframe *frame) 405e5acd89cSAndrew Turner { 406e5acd89cSAndrew Turner 407c547d650SEd Maste panic("ARM64TODO: do_el0_error"); 408e5acd89cSAndrew Turner } 409e5acd89cSAndrew Turner 410