diff --git a/sys/arm64/arm64/exec_machdep.c b/sys/arm64/arm64/exec_machdep.c index a00d616a6663..6a7fc64734e1 100644 --- a/sys/arm64/arm64/exec_machdep.c +++ b/sys/arm64/arm64/exec_machdep.c @@ -1,611 +1,640 @@ /*- * Copyright (c) 2014 Andrew Turner * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef VFP #include #endif static void get_fpcontext(struct thread *td, mcontext_t *mcp); static void set_fpcontext(struct thread *td, mcontext_t *mcp); int fill_regs(struct thread *td, struct reg *regs) { struct trapframe *frame; frame = td->td_frame; regs->sp = frame->tf_sp; regs->lr = frame->tf_lr; regs->elr = frame->tf_elr; regs->spsr = frame->tf_spsr; memcpy(regs->x, frame->tf_x, sizeof(regs->x)); #ifdef COMPAT_FREEBSD32 /* * We may be called here for a 32bits process, if we're using a * 64bits debugger. If so, put PC and SPSR where it expects it. */ if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) { regs->x[15] = frame->tf_elr; regs->x[16] = frame->tf_spsr; } #endif return (0); } int set_regs(struct thread *td, struct reg *regs) { struct trapframe *frame; frame = td->td_frame; frame->tf_sp = regs->sp; frame->tf_lr = regs->lr; - frame->tf_spsr &= ~PSR_FLAGS; memcpy(frame->tf_x, regs->x, sizeof(frame->tf_x)); #ifdef COMPAT_FREEBSD32 if (SV_PROC_FLAG(td->td_proc, SV_ILP32)) { /* * We may be called for a 32bits process if we're using * a 64bits debugger. If so, get PC and SPSR from where * it put it. */ frame->tf_elr = regs->x[15]; - frame->tf_spsr |= regs->x[16] & PSR_FLAGS; + frame->tf_spsr &= ~PSR_SETTABLE_32; + frame->tf_spsr |= regs->x[16] & PSR_SETTABLE_32; + /* Don't allow userspace to ask to continue single stepping. + * The SPSR.SS field doesn't exist when the EL1 is AArch32. + * As the SPSR.DIT field has moved in its place don't + * allow userspace to set the SPSR.SS field. + */ } else #endif { frame->tf_elr = regs->elr; - frame->tf_spsr |= regs->spsr & PSR_FLAGS; + frame->tf_spsr &= ~PSR_SETTABLE_64; + frame->tf_spsr |= regs->spsr & PSR_SETTABLE_64; + /* Enable single stepping if userspace asked fot it */ + if ((frame->tf_spsr & PSR_SS) != 0) { + td->td_pcb->pcb_flags |= PCB_SINGLE_STEP; + + WRITE_SPECIALREG(mdscr_el1, + READ_SPECIALREG(mdscr_el1) | MDSCR_SS); + isb(); + } } return (0); } int fill_fpregs(struct thread *td, struct fpreg *regs) { #ifdef VFP struct pcb *pcb; pcb = td->td_pcb; if ((pcb->pcb_fpflags & PCB_FP_STARTED) != 0) { /* * If we have just been running VFP instructions we will * need to save the state to memcpy it below. */ if (td == curthread) vfp_save_state(td, pcb); KASSERT(pcb->pcb_fpusaved == &pcb->pcb_fpustate, ("Called fill_fpregs while the kernel is using the VFP")); memcpy(regs->fp_q, pcb->pcb_fpustate.vfp_regs, sizeof(regs->fp_q)); regs->fp_cr = pcb->pcb_fpustate.vfp_fpcr; regs->fp_sr = pcb->pcb_fpustate.vfp_fpsr; } else #endif memset(regs, 0, sizeof(*regs)); return (0); } int set_fpregs(struct thread *td, struct fpreg *regs) { #ifdef VFP struct pcb *pcb; pcb = td->td_pcb; KASSERT(pcb->pcb_fpusaved == &pcb->pcb_fpustate, ("Called set_fpregs while the kernel is using the VFP")); memcpy(pcb->pcb_fpustate.vfp_regs, regs->fp_q, sizeof(regs->fp_q)); pcb->pcb_fpustate.vfp_fpcr = regs->fp_cr; pcb->pcb_fpustate.vfp_fpsr = regs->fp_sr; #endif return (0); } int fill_dbregs(struct thread *td, struct dbreg *regs) { struct debug_monitor_state *monitor; int i; uint8_t debug_ver, nbkpts, nwtpts; memset(regs, 0, sizeof(*regs)); extract_user_id_field(ID_AA64DFR0_EL1, ID_AA64DFR0_DebugVer_SHIFT, &debug_ver); extract_user_id_field(ID_AA64DFR0_EL1, ID_AA64DFR0_BRPs_SHIFT, &nbkpts); extract_user_id_field(ID_AA64DFR0_EL1, ID_AA64DFR0_WRPs_SHIFT, &nwtpts); /* * The BRPs field contains the number of breakpoints - 1. Armv8-A * allows the hardware to provide 2-16 breakpoints so this won't * overflow an 8 bit value. The same applies to the WRPs field. */ nbkpts++; nwtpts++; regs->db_debug_ver = debug_ver; regs->db_nbkpts = nbkpts; regs->db_nwtpts = nwtpts; monitor = &td->td_pcb->pcb_dbg_regs; if ((monitor->dbg_flags & DBGMON_ENABLED) != 0) { for (i = 0; i < nbkpts; i++) { regs->db_breakregs[i].dbr_addr = monitor->dbg_bvr[i]; regs->db_breakregs[i].dbr_ctrl = monitor->dbg_bcr[i]; } for (i = 0; i < nwtpts; i++) { regs->db_watchregs[i].dbw_addr = monitor->dbg_wvr[i]; regs->db_watchregs[i].dbw_ctrl = monitor->dbg_wcr[i]; } } return (0); } int set_dbregs(struct thread *td, struct dbreg *regs) { struct debug_monitor_state *monitor; uint64_t addr; uint32_t ctrl; int count; int i; monitor = &td->td_pcb->pcb_dbg_regs; count = 0; monitor->dbg_enable_count = 0; for (i = 0; i < DBG_BRP_MAX; i++) { addr = regs->db_breakregs[i].dbr_addr; ctrl = regs->db_breakregs[i].dbr_ctrl; /* * Don't let the user set a breakpoint on a kernel or * non-canonical user address. */ if (addr >= VM_MAXUSER_ADDRESS) return (EINVAL); /* * The lowest 2 bits are ignored, so record the effective * address. */ addr = rounddown2(addr, 4); /* * Some control fields are ignored, and other bits reserved. * Only unlinked, address-matching breakpoints are supported. * * XXX: fields that appear unvalidated, such as BAS, have * constrained undefined behaviour. If the user mis-programs * these, there is no risk to the system. */ ctrl &= DBGBCR_EN | DBGBCR_PMC | DBGBCR_BAS; if ((ctrl & DBGBCR_EN) != 0) { /* Only target EL0. */ if ((ctrl & DBGBCR_PMC) != DBGBCR_PMC_EL0) return (EINVAL); monitor->dbg_enable_count++; } monitor->dbg_bvr[i] = addr; monitor->dbg_bcr[i] = ctrl; } for (i = 0; i < DBG_WRP_MAX; i++) { addr = regs->db_watchregs[i].dbw_addr; ctrl = regs->db_watchregs[i].dbw_ctrl; /* * Don't let the user set a watchpoint on a kernel or * non-canonical user address. */ if (addr >= VM_MAXUSER_ADDRESS) return (EINVAL); /* * Some control fields are ignored, and other bits reserved. * Only unlinked watchpoints are supported. */ ctrl &= DBGWCR_EN | DBGWCR_PAC | DBGWCR_LSC | DBGWCR_BAS | DBGWCR_MASK; if ((ctrl & DBGWCR_EN) != 0) { /* Only target EL0. */ if ((ctrl & DBGWCR_PAC) != DBGWCR_PAC_EL0) return (EINVAL); /* Must set at least one of the load/store bits. */ if ((ctrl & DBGWCR_LSC) == 0) return (EINVAL); /* * When specifying the address range with BAS, the MASK * field must be zero. */ if ((ctrl & DBGWCR_BAS) != DBGWCR_BAS && (ctrl & DBGWCR_MASK) != 0) return (EINVAL); monitor->dbg_enable_count++; } monitor->dbg_wvr[i] = addr; monitor->dbg_wcr[i] = ctrl; } if (monitor->dbg_enable_count > 0) monitor->dbg_flags |= DBGMON_ENABLED; return (0); } #ifdef COMPAT_FREEBSD32 int fill_regs32(struct thread *td, struct reg32 *regs) { int i; struct trapframe *tf; tf = td->td_frame; for (i = 0; i < 13; i++) regs->r[i] = tf->tf_x[i]; /* For arm32, SP is r13 and LR is r14 */ regs->r_sp = tf->tf_x[13]; regs->r_lr = tf->tf_x[14]; regs->r_pc = tf->tf_elr; regs->r_cpsr = tf->tf_spsr; return (0); } int set_regs32(struct thread *td, struct reg32 *regs) { int i; struct trapframe *tf; tf = td->td_frame; for (i = 0; i < 13; i++) tf->tf_x[i] = regs->r[i]; /* For arm 32, SP is r13 an LR is r14 */ tf->tf_x[13] = regs->r_sp; tf->tf_x[14] = regs->r_lr; tf->tf_elr = regs->r_pc; - tf->tf_spsr &= ~PSR_FLAGS; - tf->tf_spsr |= regs->r_cpsr & PSR_FLAGS; + tf->tf_spsr &= ~PSR_SETTABLE_32; + tf->tf_spsr |= regs->r_cpsr & PSR_SETTABLE_32; return (0); } /* XXX fill/set dbregs/fpregs are stubbed on 32-bit arm. */ int fill_fpregs32(struct thread *td, struct fpreg32 *regs) { memset(regs, 0, sizeof(*regs)); return (0); } int set_fpregs32(struct thread *td, struct fpreg32 *regs) { return (0); } int fill_dbregs32(struct thread *td, struct dbreg32 *regs) { memset(regs, 0, sizeof(*regs)); return (0); } int set_dbregs32(struct thread *td, struct dbreg32 *regs) { return (0); } #endif void exec_setregs(struct thread *td, struct image_params *imgp, uintptr_t stack) { struct trapframe *tf = td->td_frame; struct pcb *pcb = td->td_pcb; memset(tf, 0, sizeof(struct trapframe)); tf->tf_x[0] = stack; tf->tf_sp = STACKALIGN(stack); tf->tf_lr = imgp->entry_addr; tf->tf_elr = imgp->entry_addr; td->td_pcb->pcb_tpidr_el0 = 0; td->td_pcb->pcb_tpidrro_el0 = 0; WRITE_SPECIALREG(tpidrro_el0, 0); WRITE_SPECIALREG(tpidr_el0, 0); #ifdef VFP vfp_reset_state(td, pcb); #endif /* * Clear debug register state. It is not applicable to the new process. */ bzero(&pcb->pcb_dbg_regs, sizeof(pcb->pcb_dbg_regs)); } /* Sanity check these are the same size, they will be memcpy'd to and from */ CTASSERT(sizeof(((struct trapframe *)0)->tf_x) == sizeof((struct gpregs *)0)->gp_x); CTASSERT(sizeof(((struct trapframe *)0)->tf_x) == sizeof((struct reg *)0)->x); int get_mcontext(struct thread *td, mcontext_t *mcp, int clear_ret) { struct trapframe *tf = td->td_frame; if (clear_ret & GET_MC_CLEAR_RET) { mcp->mc_gpregs.gp_x[0] = 0; mcp->mc_gpregs.gp_spsr = tf->tf_spsr & ~PSR_C; } else { mcp->mc_gpregs.gp_x[0] = tf->tf_x[0]; mcp->mc_gpregs.gp_spsr = tf->tf_spsr; } memcpy(&mcp->mc_gpregs.gp_x[1], &tf->tf_x[1], sizeof(mcp->mc_gpregs.gp_x[1]) * (nitems(mcp->mc_gpregs.gp_x) - 1)); mcp->mc_gpregs.gp_sp = tf->tf_sp; mcp->mc_gpregs.gp_lr = tf->tf_lr; mcp->mc_gpregs.gp_elr = tf->tf_elr; get_fpcontext(td, mcp); return (0); } int set_mcontext(struct thread *td, mcontext_t *mcp) { struct trapframe *tf = td->td_frame; uint32_t spsr; spsr = mcp->mc_gpregs.gp_spsr; if ((spsr & PSR_M_MASK) != PSR_M_EL0t || (spsr & PSR_AARCH32) != 0 || (spsr & PSR_DAIF) != (td->td_frame->tf_spsr & PSR_DAIF)) return (EINVAL); memcpy(tf->tf_x, mcp->mc_gpregs.gp_x, sizeof(tf->tf_x)); tf->tf_sp = mcp->mc_gpregs.gp_sp; tf->tf_lr = mcp->mc_gpregs.gp_lr; tf->tf_elr = mcp->mc_gpregs.gp_elr; tf->tf_spsr = mcp->mc_gpregs.gp_spsr; + if ((tf->tf_spsr & PSR_SS) != 0) { + td->td_pcb->pcb_flags |= PCB_SINGLE_STEP; + + WRITE_SPECIALREG(mdscr_el1, + READ_SPECIALREG(mdscr_el1) | MDSCR_SS); + isb(); + } set_fpcontext(td, mcp); return (0); } static void get_fpcontext(struct thread *td, mcontext_t *mcp) { #ifdef VFP struct pcb *curpcb; critical_enter(); curpcb = curthread->td_pcb; if ((curpcb->pcb_fpflags & PCB_FP_STARTED) != 0) { /* * If we have just been running VFP instructions we will * need to save the state to memcpy it below. */ vfp_save_state(td, curpcb); KASSERT(curpcb->pcb_fpusaved == &curpcb->pcb_fpustate, ("Called get_fpcontext while the kernel is using the VFP")); KASSERT((curpcb->pcb_fpflags & ~PCB_FP_USERMASK) == 0, ("Non-userspace FPU flags set in get_fpcontext")); memcpy(mcp->mc_fpregs.fp_q, curpcb->pcb_fpustate.vfp_regs, sizeof(mcp->mc_fpregs.fp_q)); mcp->mc_fpregs.fp_cr = curpcb->pcb_fpustate.vfp_fpcr; mcp->mc_fpregs.fp_sr = curpcb->pcb_fpustate.vfp_fpsr; mcp->mc_fpregs.fp_flags = curpcb->pcb_fpflags; mcp->mc_flags |= _MC_FP_VALID; } critical_exit(); #endif } static void set_fpcontext(struct thread *td, mcontext_t *mcp) { #ifdef VFP struct pcb *curpcb; critical_enter(); if ((mcp->mc_flags & _MC_FP_VALID) != 0) { curpcb = curthread->td_pcb; /* * Discard any vfp state for the current thread, we * are about to override it. */ vfp_discard(td); KASSERT(curpcb->pcb_fpusaved == &curpcb->pcb_fpustate, ("Called set_fpcontext while the kernel is using the VFP")); memcpy(curpcb->pcb_fpustate.vfp_regs, mcp->mc_fpregs.fp_q, sizeof(mcp->mc_fpregs.fp_q)); curpcb->pcb_fpustate.vfp_fpcr = mcp->mc_fpregs.fp_cr; curpcb->pcb_fpustate.vfp_fpsr = mcp->mc_fpregs.fp_sr; curpcb->pcb_fpflags = mcp->mc_fpregs.fp_flags & PCB_FP_USERMASK; } critical_exit(); #endif } int sys_sigreturn(struct thread *td, struct sigreturn_args *uap) { ucontext_t uc; int error; if (copyin(uap->sigcntxp, &uc, sizeof(uc))) return (EFAULT); error = set_mcontext(td, &uc.uc_mcontext); if (error != 0) return (error); /* Restore signal mask. */ kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0); return (EJUSTRETURN); } void sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) { struct thread *td; struct proc *p; struct trapframe *tf; struct sigframe *fp, frame; struct sigacts *psp; int onstack, sig; td = curthread; p = td->td_proc; PROC_LOCK_ASSERT(p, MA_OWNED); sig = ksi->ksi_signo; psp = p->p_sigacts; mtx_assert(&psp->ps_mtx, MA_OWNED); tf = td->td_frame; onstack = sigonstack(tf->tf_sp); CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm, catcher, sig); /* Allocate and validate space for the signal handler context. */ if ((td->td_pflags & TDP_ALTSTACK) != 0 && !onstack && SIGISMEMBER(psp->ps_sigonstack, sig)) { fp = (struct sigframe *)((uintptr_t)td->td_sigstk.ss_sp + td->td_sigstk.ss_size); #if defined(COMPAT_43) td->td_sigstk.ss_flags |= SS_ONSTACK; #endif } else { fp = (struct sigframe *)td->td_frame->tf_sp; } /* Make room, keeping the stack aligned */ fp--; fp = (struct sigframe *)STACKALIGN(fp); /* Fill in the frame to copy out */ bzero(&frame, sizeof(frame)); get_mcontext(td, &frame.sf_uc.uc_mcontext, 0); frame.sf_si = ksi->ksi_info; frame.sf_uc.uc_sigmask = *mask; frame.sf_uc.uc_stack = td->td_sigstk; frame.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK) != 0 ? (onstack ? SS_ONSTACK : 0) : SS_DISABLE; mtx_unlock(&psp->ps_mtx); PROC_UNLOCK(td->td_proc); /* Copy the sigframe out to the user's stack. */ if (copyout(&frame, fp, sizeof(*fp)) != 0) { /* Process has trashed its stack. Kill it. */ CTR2(KTR_SIG, "sendsig: sigexit td=%p fp=%p", td, fp); PROC_LOCK(p); sigexit(td, SIGILL); } tf->tf_x[0] = sig; tf->tf_x[1] = (register_t)&fp->sf_si; tf->tf_x[2] = (register_t)&fp->sf_uc; tf->tf_elr = (register_t)catcher; tf->tf_sp = (register_t)fp; tf->tf_lr = (register_t)p->p_sysent->sv_sigcode_base; + /* Clear the single step flag while in the signal handler */ + if ((td->td_pcb->pcb_flags & PCB_SINGLE_STEP) != 0) { + td->td_pcb->pcb_flags &= ~PCB_SINGLE_STEP; + WRITE_SPECIALREG(mdscr_el1, + READ_SPECIALREG(mdscr_el1) & ~MDSCR_SS); + isb(); + } + CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, tf->tf_elr, tf->tf_sp); PROC_LOCK(p); mtx_lock(&psp->ps_mtx); } diff --git a/sys/arm64/arm64/freebsd32_machdep.c b/sys/arm64/arm64/freebsd32_machdep.c index f87e4342cfbd..9d7b5effac0c 100644 --- a/sys/arm64/arm64/freebsd32_machdep.c +++ b/sys/arm64/arm64/freebsd32_machdep.c @@ -1,444 +1,472 @@ /*- * Copyright (c) 2018 Olivier Houchard * Copyright (c) 2017 Nuxi, https://nuxi.nl/ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #ifdef VFP #include #endif #include #include #include #include #include #include extern void freebsd32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask); /* * The first two fields of a ucontext_t are the signal mask and the machine * context. The next field is uc_link; we want to avoid destroying the link * when copying out contexts. */ #define UC32_COPY_SIZE offsetof(ucontext32_t, uc_link) #ifdef VFP static void get_fpcontext32(struct thread *td, mcontext32_vfp_t *); #endif /* * Stubs for machine dependent 32-bits system calls. */ int freebsd32_sysarch(struct thread *td, struct freebsd32_sysarch_args *uap) { int error; #define ARM_SYNC_ICACHE 0 #define ARM_DRAIN_WRITEBUF 1 #define ARM_SET_TP 2 #define ARM_GET_TP 3 #define ARM_GET_VFPSTATE 4 switch(uap->op) { case ARM_SET_TP: WRITE_SPECIALREG(tpidr_el0, uap->parms); WRITE_SPECIALREG(tpidrro_el0, uap->parms); return 0; case ARM_SYNC_ICACHE: { struct { uint32_t addr; uint32_t size; } args; if ((error = copyin(uap->parms, &args, sizeof(args))) != 0) return (error); if ((uint64_t)args.addr + (uint64_t)args.size > 0xffffffff) return (EINVAL); cpu_icache_sync_range_checked(args.addr, args.size); return 0; } case ARM_GET_VFPSTATE: { mcontext32_vfp_t mcontext_vfp; struct { uint32_t mc_vfp_size; uint32_t mc_vfp; } args; if ((error = copyin(uap->parms, &args, sizeof(args))) != 0) return (error); if (args.mc_vfp_size != sizeof(mcontext_vfp)) return (EINVAL); #ifdef VFP get_fpcontext32(td, &mcontext_vfp); #else bzero(&mcontext_vfp, sizeof(mcontext_vfp)); #endif error = copyout(&mcontext_vfp, (void *)(uintptr_t)args.mc_vfp, sizeof(mcontext_vfp)); return error; } } return (EINVAL); } #ifdef VFP static void get_fpcontext32(struct thread *td, mcontext32_vfp_t *mcp) { struct pcb *curpcb; int i; critical_enter(); curpcb = curthread->td_pcb; if ((curpcb->pcb_fpflags & PCB_FP_STARTED) != 0) { /* * If we have just been running VFP instructions we will * need to save the state to memcpy it below. */ vfp_save_state(td, curpcb); KASSERT(curpcb->pcb_fpusaved == &curpcb->pcb_fpustate, ("Called get_fpcontext while the kernel is using the VFP")); KASSERT((curpcb->pcb_fpflags & ~PCB_FP_USERMASK) == 0, ("Non-userspace FPU flags set in get_fpcontext")); for (i = 0; i < 32; i++) mcp->mcv_reg[i] = (uint64_t)curpcb->pcb_fpustate.vfp_regs[i]; mcp->mcv_fpscr = VFP_FPSCR_FROM_SRCR(curpcb->pcb_fpustate.vfp_fpcr, curpcb->pcb_fpustate.vfp_fpsr); } critical_exit(); } static void set_fpcontext32(struct thread *td, mcontext32_vfp_t *mcp) { struct pcb *pcb; int i; critical_enter(); pcb = td->td_pcb; if (td == curthread) vfp_discard(td); for (i = 0; i < 32; i++) pcb->pcb_fpustate.vfp_regs[i] = mcp->mcv_reg[i]; pcb->pcb_fpustate.vfp_fpsr = VFP_FPSR_FROM_FPSCR(mcp->mcv_fpscr); pcb->pcb_fpustate.vfp_fpcr = VFP_FPSR_FROM_FPSCR(mcp->mcv_fpscr); critical_exit(); } #endif static void get_mcontext32(struct thread *td, mcontext32_t *mcp, int flags) { struct pcb *pcb; struct trapframe *tf; int i; pcb = td->td_pcb; tf = td->td_frame; if ((flags & GET_MC_CLEAR_RET) != 0) { mcp->mc_gregset[0] = 0; mcp->mc_gregset[16] = tf->tf_spsr & ~PSR_C; } else { mcp->mc_gregset[0] = tf->tf_x[0]; mcp->mc_gregset[16] = tf->tf_spsr; } for (i = 1; i < 15; i++) mcp->mc_gregset[i] = tf->tf_x[i]; mcp->mc_gregset[15] = tf->tf_elr; mcp->mc_vfp_size = 0; mcp->mc_vfp_ptr = 0; memset(mcp->mc_spare, 0, sizeof(mcp->mc_spare)); } static int set_mcontext32(struct thread *td, mcontext32_t *mcp) { struct trapframe *tf; mcontext32_vfp_t mc_vfp; + uint32_t spsr; int i; tf = td->td_frame; + spsr = mcp->mc_gregset[16]; + /* + * There is no PSR_SS in the 32-bit kernel so ignore it if it's set + * as we will set it later if needed. + */ + if ((spsr & ~(PSR_SETTABLE_32 | PSR_SS)) != + (tf->tf_spsr & ~(PSR_SETTABLE_32 | PSR_SS))) + return (EINVAL); + + spsr &= PSR_SETTABLE_32; + spsr |= tf->tf_spsr & ~PSR_SETTABLE_32; + + if ((td->td_dbgflags & TDB_STEP) != 0) { + spsr |= PSR_SS; + td->td_pcb->pcb_flags |= PCB_SINGLE_STEP; + WRITE_SPECIALREG(mdscr_el1, + READ_SPECIALREG(mdscr_el1) | MDSCR_SS); + } + for (i = 0; i < 15; i++) tf->tf_x[i] = mcp->mc_gregset[i]; tf->tf_elr = mcp->mc_gregset[15]; - tf->tf_spsr = mcp->mc_gregset[16]; + tf->tf_spsr = spsr; #ifdef VFP if (mcp->mc_vfp_size == sizeof(mc_vfp) && mcp->mc_vfp_ptr != 0) { if (copyin((void *)(uintptr_t)mcp->mc_vfp_ptr, &mc_vfp, sizeof(mc_vfp)) != 0) return (EFAULT); set_fpcontext32(td, &mc_vfp); } #endif return (0); } #define UC_COPY_SIZE offsetof(ucontext32_t, uc_link) int freebsd32_getcontext(struct thread *td, struct freebsd32_getcontext_args *uap) { ucontext32_t uc; int ret; if (uap->ucp == NULL) ret = EINVAL; else { memset(&uc, 0, sizeof(uc)); get_mcontext32(td, &uc.uc_mcontext, GET_MC_CLEAR_RET); PROC_LOCK(td->td_proc); uc.uc_sigmask = td->td_sigmask; PROC_UNLOCK(td->td_proc); ret = copyout(&uc, uap->ucp, UC_COPY_SIZE); } return (ret); } int freebsd32_setcontext(struct thread *td, struct freebsd32_setcontext_args *uap) { ucontext32_t uc; int ret; if (uap->ucp == NULL) ret = EINVAL; else { ret = copyin(uap->ucp, &uc, UC_COPY_SIZE); if (ret == 0) { ret = set_mcontext32(td, &uc.uc_mcontext); if (ret == 0) kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0); } } return (ret); } int freebsd32_sigreturn(struct thread *td, struct freebsd32_sigreturn_args *uap) { ucontext32_t uc; int error; if (uap == NULL) return (EFAULT); if (copyin(uap->sigcntxp, &uc, sizeof(uc))) return (EFAULT); error = set_mcontext32(td, &uc.uc_mcontext); if (error != 0) return (0); /* Restore signal mask. */ kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0); return (EJUSTRETURN); } int freebsd32_swapcontext(struct thread *td, struct freebsd32_swapcontext_args *uap) { ucontext32_t uc; int ret; if (uap->oucp == NULL || uap->ucp == NULL) ret = EINVAL; else { bzero(&uc, sizeof(uc)); get_mcontext32(td, &uc.uc_mcontext, GET_MC_CLEAR_RET); PROC_LOCK(td->td_proc); uc.uc_sigmask = td->td_sigmask; PROC_UNLOCK(td->td_proc); ret = copyout(&uc, uap->oucp, UC32_COPY_SIZE); if (ret == 0) { ret = copyin(uap->ucp, &uc, UC32_COPY_SIZE); if (ret == 0) { ret = set_mcontext32(td, &uc.uc_mcontext); kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0); } } } return (ret); } void freebsd32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) { struct thread *td; struct proc *p; struct trapframe *tf; struct sigframe32 *fp, frame; struct sigacts *psp; struct siginfo32 siginfo; struct sysentvec *sysent; int onstack; int sig; int code; siginfo_to_siginfo32(&ksi->ksi_info, &siginfo); td = curthread; p = td->td_proc; PROC_LOCK_ASSERT(p, MA_OWNED); sig = ksi->ksi_signo; code = ksi->ksi_code; psp = p->p_sigacts; mtx_assert(&psp->ps_mtx, MA_OWNED); tf = td->td_frame; onstack = sigonstack(tf->tf_x[13]); CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm, catcher, sig); /* Allocate and validate space for the signal handler context. */ if ((td->td_pflags & TDP_ALTSTACK) != 0 && !(onstack) && SIGISMEMBER(psp->ps_sigonstack, sig)) { fp = (struct sigframe32 *)((uintptr_t)td->td_sigstk.ss_sp + td->td_sigstk.ss_size); #if defined(COMPAT_43) td->td_sigstk.ss_flags |= SS_ONSTACK; #endif } else fp = (struct sigframe32 *)td->td_frame->tf_x[13]; /* make room on the stack */ fp--; /* make the stack aligned */ fp = (struct sigframe32 *)((unsigned long)(fp) &~ (8 - 1)); /* Populate the siginfo frame. */ get_mcontext32(td, &frame.sf_uc.uc_mcontext, 0); #ifdef VFP get_fpcontext32(td, &frame.sf_vfp); frame.sf_uc.uc_mcontext.mc_vfp_size = sizeof(fp->sf_vfp); frame.sf_uc.uc_mcontext.mc_vfp_ptr = (uint32_t)(uintptr_t)&fp->sf_vfp; #else frame.sf_uc.uc_mcontext.mc_vfp_size = 0; frame.sf_uc.uc_mcontext.mc_vfp_ptr = (uint32_t)NULL; #endif frame.sf_si = siginfo; frame.sf_uc.uc_sigmask = *mask; frame.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK ) ? ((onstack) ? SS_ONSTACK : 0) : SS_DISABLE; frame.sf_uc.uc_stack.ss_sp = (uintptr_t)td->td_sigstk.ss_sp; frame.sf_uc.uc_stack.ss_size = td->td_sigstk.ss_size; mtx_unlock(&psp->ps_mtx); PROC_UNLOCK(td->td_proc); /* Copy the sigframe out to the user's stack. */ if (copyout(&frame, fp, sizeof(*fp)) != 0) { /* Process has trashed its stack. Kill it. */ CTR2(KTR_SIG, "sendsig: sigexit td=%p fp=%p", td, fp); PROC_LOCK(p); sigexit(td, SIGILL); } /* * Build context to run handler in. We invoke the handler * directly, only returning via the trampoline. Note the * trampoline version numbers are coordinated with machine- * dependent code in libc. */ tf->tf_x[0] = sig; tf->tf_x[1] = (register_t)&fp->sf_si; tf->tf_x[2] = (register_t)&fp->sf_uc; /* the trampoline uses r5 as the uc address */ tf->tf_x[5] = (register_t)&fp->sf_uc; tf->tf_elr = (register_t)catcher; tf->tf_x[13] = (register_t)fp; sysent = p->p_sysent; if (sysent->sv_sigcode_base != 0) tf->tf_x[14] = (register_t)sysent->sv_sigcode_base; else tf->tf_x[14] = (register_t)(PROC_PS_STRINGS(p) - *(sysent->sv_szsigcode)); /* Set the mode to enter in the signal handler */ if ((register_t)catcher & 1) tf->tf_spsr |= PSR_T; else tf->tf_spsr &= ~PSR_T; + /* Clear the single step flag while in the signal handler */ + if ((td->td_pcb->pcb_flags & PCB_SINGLE_STEP) != 0) { + td->td_pcb->pcb_flags &= ~PCB_SINGLE_STEP; + WRITE_SPECIALREG(mdscr_el1, + READ_SPECIALREG(mdscr_el1) & ~MDSCR_SS); + isb(); + } + CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, tf->tf_x[14], tf->tf_x[13]); PROC_LOCK(p); mtx_lock(&psp->ps_mtx); } #ifdef COMPAT_43 /* * COMPAT_FREEBSD32 assumes we have this system call when COMPAT_43 is defined. * FreeBSD/arm provies a similar getpagesize() syscall. */ #define ARM32_PAGE_SIZE 4096 int ofreebsd32_getpagesize(struct thread *td, struct ofreebsd32_getpagesize_args *uap) { td->td_retval[0] = ARM32_PAGE_SIZE; return (0); } /* * Mirror the osigreturn definition in kern_sig.c for !i386 platforms. This * mirrors what's connected to the FreeBSD/arm syscall. */ int ofreebsd32_sigreturn(struct thread *td, struct ofreebsd32_sigreturn_args *uap) { return (nosys(td, (struct nosys_args *)uap)); } #endif diff --git a/sys/arm64/arm64/ptrace_machdep.c b/sys/arm64/arm64/ptrace_machdep.c index dd49aaa4fcec..144ff29aff47 100644 --- a/sys/arm64/arm64/ptrace_machdep.c +++ b/sys/arm64/arm64/ptrace_machdep.c @@ -1,74 +1,78 @@ /*- * Copyright (c) 2014 Andrew Turner * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int ptrace_set_pc(struct thread *td, u_long addr) { td->td_frame->tf_elr = addr; return (0); } int ptrace_single_step(struct thread *td) { - - td->td_frame->tf_spsr |= PSR_SS; - td->td_pcb->pcb_flags |= PCB_SINGLE_STEP; + PROC_LOCK_ASSERT(td->td_proc, MA_OWNED); + if ((td->td_frame->tf_spsr & PSR_SS) == 0) { + td->td_frame->tf_spsr |= PSR_SS; + td->td_pcb->pcb_flags |= PCB_SINGLE_STEP; + td->td_dbgflags |= TDB_STEP; + } return (0); } int ptrace_clear_single_step(struct thread *td) { - + PROC_LOCK_ASSERT(td->td_proc, MA_OWNED); td->td_frame->tf_spsr &= ~PSR_SS; td->td_pcb->pcb_flags &= ~PCB_SINGLE_STEP; + td->td_dbgflags &= ~TDB_STEP; return (0); } diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c index 6524679a64ba..a8d29ffaa9a7 100644 --- a/sys/arm64/arm64/trap.c +++ b/sys/arm64/arm64/trap.c @@ -1,658 +1,662 @@ /*- * Copyright (c) 2014 Andrew Turner * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include "opt_ddb.h" #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #ifdef KDB #include #endif #include #include #include #include #include #include #include #include #include #include #include #ifdef KDTRACE_HOOKS #include #endif #ifdef VFP #include #endif #ifdef KDB #include #endif #ifdef DDB #include #include #endif /* Called from exception.S */ void do_el1h_sync(struct thread *, struct trapframe *); void do_el0_sync(struct thread *, struct trapframe *); void do_el0_error(struct trapframe *); void do_serror(struct trapframe *); void unhandled_exception(struct trapframe *); static void print_gp_register(const char *name, uint64_t value); static void print_registers(struct trapframe *frame); int (*dtrace_invop_jump_addr)(struct trapframe *); typedef void (abort_handler)(struct thread *, struct trapframe *, uint64_t, uint64_t, int); static abort_handler align_abort; static abort_handler data_abort; static abort_handler external_abort; static abort_handler *abort_handlers[] = { [ISS_DATA_DFSC_TF_L0] = data_abort, [ISS_DATA_DFSC_TF_L1] = data_abort, [ISS_DATA_DFSC_TF_L2] = data_abort, [ISS_DATA_DFSC_TF_L3] = data_abort, [ISS_DATA_DFSC_AFF_L1] = data_abort, [ISS_DATA_DFSC_AFF_L2] = data_abort, [ISS_DATA_DFSC_AFF_L3] = data_abort, [ISS_DATA_DFSC_PF_L1] = data_abort, [ISS_DATA_DFSC_PF_L2] = data_abort, [ISS_DATA_DFSC_PF_L3] = data_abort, [ISS_DATA_DFSC_ALIGN] = align_abort, [ISS_DATA_DFSC_EXT] = external_abort, [ISS_DATA_DFSC_EXT_L0] = external_abort, [ISS_DATA_DFSC_EXT_L1] = external_abort, [ISS_DATA_DFSC_EXT_L2] = external_abort, [ISS_DATA_DFSC_EXT_L3] = external_abort, [ISS_DATA_DFSC_ECC] = external_abort, [ISS_DATA_DFSC_ECC_L0] = external_abort, [ISS_DATA_DFSC_ECC_L1] = external_abort, [ISS_DATA_DFSC_ECC_L2] = external_abort, [ISS_DATA_DFSC_ECC_L3] = external_abort, }; static __inline void call_trapsignal(struct thread *td, int sig, int code, void *addr, int trapno) { ksiginfo_t ksi; ksiginfo_init_trap(&ksi); ksi.ksi_signo = sig; ksi.ksi_code = code; ksi.ksi_addr = addr; ksi.ksi_trapno = trapno; trapsignal(td, &ksi); } int cpu_fetch_syscall_args(struct thread *td) { struct proc *p; register_t *ap, *dst_ap; struct syscall_args *sa; p = td->td_proc; sa = &td->td_sa; ap = td->td_frame->tf_x; dst_ap = &sa->args[0]; sa->code = td->td_frame->tf_x[8]; if (__predict_false(sa->code == SYS_syscall || sa->code == SYS___syscall)) { sa->code = *ap++; } else { *dst_ap++ = *ap++; } if (__predict_false(sa->code >= p->p_sysent->sv_size)) sa->callp = &p->p_sysent->sv_table[0]; else sa->callp = &p->p_sysent->sv_table[sa->code]; KASSERT(sa->callp->sy_narg <= nitems(sa->args), ("Syscall %d takes too many arguments", sa->code)); memcpy(dst_ap, ap, (MAXARGS - 1) * sizeof(register_t)); td->td_retval[0] = 0; td->td_retval[1] = 0; return (0); } #include "../../kern/subr_syscall.c" /* * Test for fault generated by given access instruction in * bus_peek_ or bus_poke_ bus function. */ extern uint32_t generic_bs_peek_1f, generic_bs_peek_2f; extern uint32_t generic_bs_peek_4f, generic_bs_peek_8f; extern uint32_t generic_bs_poke_1f, generic_bs_poke_2f; extern uint32_t generic_bs_poke_4f, generic_bs_poke_8f; static bool test_bs_fault(void *addr) { return (addr == &generic_bs_peek_1f || addr == &generic_bs_peek_2f || addr == &generic_bs_peek_4f || addr == &generic_bs_peek_8f || addr == &generic_bs_poke_1f || addr == &generic_bs_poke_2f || addr == &generic_bs_poke_4f || addr == &generic_bs_poke_8f); } static void svc_handler(struct thread *td, struct trapframe *frame) { if ((frame->tf_esr & ESR_ELx_ISS_MASK) == 0) { syscallenter(td); syscallret(td); } else { call_trapsignal(td, SIGILL, ILL_ILLOPN, (void *)frame->tf_elr, ESR_ELx_EXCEPTION(frame->tf_esr)); userret(td, frame); } } static void align_abort(struct thread *td, struct trapframe *frame, uint64_t esr, uint64_t far, int lower) { if (!lower) { print_registers(frame); print_gp_register("far", far); printf(" esr: %.8lx\n", esr); panic("Misaligned access from kernel space!"); } call_trapsignal(td, SIGBUS, BUS_ADRALN, (void *)frame->tf_elr, ESR_ELx_EXCEPTION(frame->tf_esr)); userret(td, frame); } static void external_abort(struct thread *td, struct trapframe *frame, uint64_t esr, uint64_t far, int lower) { /* * Try to handle synchronous external aborts caused by * bus_space_peek() and/or bus_space_poke() functions. */ if (!lower && test_bs_fault((void *)frame->tf_elr)) { frame->tf_elr = (uint64_t)generic_bs_fault; return; } print_registers(frame); print_gp_register("far", far); panic("Unhandled EL%d external data abort", lower ? 0: 1); } static void data_abort(struct thread *td, struct trapframe *frame, uint64_t esr, uint64_t far, int lower) { struct vm_map *map; struct proc *p; struct pcb *pcb; vm_prot_t ftype; int error, sig, ucode; #ifdef KDB bool handled; #endif /* * According to the ARMv8-A rev. A.g, B2.10.5 "Load-Exclusive * and Store-Exclusive instruction usage restrictions", state * of the exclusive monitors after data abort exception is unknown. */ clrex(); #ifdef KDB if (kdb_active) { kdb_reenter(); return; } #endif pcb = td->td_pcb; p = td->td_proc; if (lower) map = &p->p_vmspace->vm_map; else { intr_enable(); /* We received a TBI/PAC/etc. fault from the kernel */ if (!ADDR_IS_CANONICAL(far)) { error = KERN_INVALID_ADDRESS; goto bad_far; } /* The top bit tells us which range to use */ if (ADDR_IS_KERNEL(far)) { map = kernel_map; } else { map = &p->p_vmspace->vm_map; if (map == NULL) map = kernel_map; } } /* * Try to handle translation, access flag, and permission faults. * Translation faults may occur as a result of the required * break-before-make sequence used when promoting or demoting * superpages. Such faults must not occur while holding the pmap lock, * or pmap_fault() will recurse on that lock. */ if ((lower || map == kernel_map || pcb->pcb_onfault != 0) && pmap_fault(map->pmap, esr, far) == KERN_SUCCESS) return; KASSERT(td->td_md.md_spinlock_count == 0, ("data abort with spinlock held")); if (td->td_critnest != 0 || WITNESS_CHECK(WARN_SLEEPOK | WARN_GIANTOK, NULL, "Kernel page fault") != 0) { print_registers(frame); print_gp_register("far", far); printf(" esr: %.8lx\n", esr); panic("data abort in critical section or under mutex"); } switch (ESR_ELx_EXCEPTION(esr)) { case EXCP_INSN_ABORT: case EXCP_INSN_ABORT_L: ftype = VM_PROT_EXECUTE; break; default: ftype = (esr & ISS_DATA_WnR) == 0 ? VM_PROT_READ : VM_PROT_WRITE; break; } /* Fault in the page. */ error = vm_fault_trap(map, far, ftype, VM_FAULT_NORMAL, &sig, &ucode); if (error != KERN_SUCCESS) { bad_far: if (lower) { call_trapsignal(td, sig, ucode, (void *)far, ESR_ELx_EXCEPTION(esr)); } else { if (td->td_intr_nesting_level == 0 && pcb->pcb_onfault != 0) { frame->tf_x[0] = error; frame->tf_elr = pcb->pcb_onfault; return; } printf("Fatal data abort:\n"); print_registers(frame); print_gp_register("far", far); printf(" esr: %.8lx\n", esr); #ifdef KDB if (debugger_on_trap) { kdb_why = KDB_WHY_TRAP; handled = kdb_trap(ESR_ELx_EXCEPTION(esr), 0, frame); kdb_why = KDB_WHY_UNSET; if (handled) return; } #endif panic("vm_fault failed: %lx", frame->tf_elr); } } if (lower) userret(td, frame); } static void print_gp_register(const char *name, uint64_t value) { #if defined(DDB) c_db_sym_t sym; const char *sym_name; db_expr_t sym_value; db_expr_t offset; #endif printf(" %s: %16lx", name, value); #if defined(DDB) /* If this looks like a kernel address try to find the symbol */ if (value >= VM_MIN_KERNEL_ADDRESS) { sym = db_search_symbol(value, DB_STGY_ANY, &offset); if (sym != C_DB_SYM_NULL) { db_symbol_values(sym, &sym_name, &sym_value); printf(" (%s + %lx)", sym_name, offset); } } #endif printf("\n"); } static void print_registers(struct trapframe *frame) { char name[4]; u_int reg; for (reg = 0; reg < nitems(frame->tf_x); reg++) { snprintf(name, sizeof(name), "%sx%d", (reg < 10) ? " " : "", reg); print_gp_register(name, frame->tf_x[reg]); } printf(" sp: %16lx\n", frame->tf_sp); print_gp_register(" lr", frame->tf_lr); print_gp_register("elr", frame->tf_elr); printf("spsr: %8x\n", frame->tf_spsr); } void do_el1h_sync(struct thread *td, struct trapframe *frame) { uint32_t exception; uint64_t esr, far; int dfsc; /* Read the esr register to get the exception details */ esr = frame->tf_esr; exception = ESR_ELx_EXCEPTION(esr); #ifdef KDTRACE_HOOKS if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame, exception)) return; #endif CTR4(KTR_TRAP, "do_el1_sync: curthread: %p, esr %lx, elr: %lx, frame: %p", td, esr, frame->tf_elr, frame); /* * Enable debug exceptions if we aren't already handling one. They will * be masked again in the exception handler's epilogue. */ if (exception != EXCP_BRK && exception != EXCP_WATCHPT_EL1 && exception != EXCP_SOFTSTP_EL1) dbg_enable(); switch (exception) { case EXCP_FP_SIMD: case EXCP_TRAP_FP: #ifdef VFP if ((td->td_pcb->pcb_fpflags & PCB_FP_KERN) != 0) { vfp_restore_state(); } else #endif { print_registers(frame); printf(" esr: %.8lx\n", esr); panic("VFP exception in the kernel"); } break; case EXCP_INSN_ABORT: case EXCP_DATA_ABORT: far = READ_SPECIALREG(far_el1); dfsc = esr & ISS_DATA_DFSC_MASK; if (dfsc < nitems(abort_handlers) && abort_handlers[dfsc] != NULL) { abort_handlers[dfsc](td, frame, esr, far, 0); } else { print_registers(frame); print_gp_register("far", far); printf(" esr: %.8lx\n", esr); panic("Unhandled EL1 %s abort: %x", exception == EXCP_INSN_ABORT ? "instruction" : "data", dfsc); } break; case EXCP_BRK: #ifdef KDTRACE_HOOKS if ((esr & ESR_ELx_ISS_MASK) == 0x40d && \ dtrace_invop_jump_addr != 0) { dtrace_invop_jump_addr(frame); break; } #endif #ifdef KDB kdb_trap(exception, 0, frame); #else panic("No debugger in kernel."); #endif break; case EXCP_WATCHPT_EL1: case EXCP_SOFTSTP_EL1: #ifdef KDB kdb_trap(exception, 0, frame); #else panic("No debugger in kernel."); #endif break; case EXCP_UNKNOWN: if (undef_insn(1, frame)) break; /* FALLTHROUGH */ default: print_registers(frame); print_gp_register("far", READ_SPECIALREG(far_el1)); panic("Unknown kernel exception %x esr_el1 %lx", exception, esr); } } void do_el0_sync(struct thread *td, struct trapframe *frame) { pcpu_bp_harden bp_harden; uint32_t exception; uint64_t esr, far; int dfsc; /* Check we have a sane environment when entering from userland */ KASSERT((uintptr_t)get_pcpu() >= VM_MIN_KERNEL_ADDRESS, ("Invalid pcpu address from userland: %p (tpidr %lx)", get_pcpu(), READ_SPECIALREG(tpidr_el1))); esr = frame->tf_esr; exception = ESR_ELx_EXCEPTION(esr); switch (exception) { case EXCP_INSN_ABORT_L: far = READ_SPECIALREG(far_el1); /* * Userspace may be trying to train the branch predictor to * attack the kernel. If we are on a CPU affected by this * call the handler to clear the branch predictor state. */ if (far > VM_MAXUSER_ADDRESS) { bp_harden = PCPU_GET(bp_harden); if (bp_harden != NULL) bp_harden(); } break; case EXCP_UNKNOWN: case EXCP_DATA_ABORT_L: case EXCP_DATA_ABORT: case EXCP_WATCHPT_EL0: far = READ_SPECIALREG(far_el1); break; } intr_enable(); CTR4(KTR_TRAP, "do_el0_sync: curthread: %p, esr %lx, elr: %lx, frame: %p", td, esr, frame->tf_elr, frame); switch (exception) { case EXCP_FP_SIMD: case EXCP_TRAP_FP: #ifdef VFP vfp_restore_state(); #else panic("VFP exception in userland"); #endif break; case EXCP_SVC32: case EXCP_SVC64: svc_handler(td, frame); break; case EXCP_INSN_ABORT_L: case EXCP_DATA_ABORT_L: case EXCP_DATA_ABORT: dfsc = esr & ISS_DATA_DFSC_MASK; if (dfsc < nitems(abort_handlers) && abort_handlers[dfsc] != NULL) abort_handlers[dfsc](td, frame, esr, far, 1); else { print_registers(frame); print_gp_register("far", far); printf(" esr: %.8lx\n", esr); panic("Unhandled EL0 %s abort: %x", exception == EXCP_INSN_ABORT_L ? "instruction" : "data", dfsc); } break; case EXCP_UNKNOWN: if (!undef_insn(0, frame)) call_trapsignal(td, SIGILL, ILL_ILLTRP, (void *)far, exception); userret(td, frame); break; case EXCP_SP_ALIGN: call_trapsignal(td, SIGBUS, BUS_ADRALN, (void *)frame->tf_sp, exception); userret(td, frame); break; case EXCP_PC_ALIGN: call_trapsignal(td, SIGBUS, BUS_ADRALN, (void *)frame->tf_elr, exception); userret(td, frame); break; case EXCP_BRKPT_EL0: case EXCP_BRK: call_trapsignal(td, SIGTRAP, TRAP_BRKPT, (void *)frame->tf_elr, exception); userret(td, frame); break; case EXCP_WATCHPT_EL0: call_trapsignal(td, SIGTRAP, TRAP_TRACE, (void *)far, exception); userret(td, frame); break; case EXCP_MSR: /* * The CPU can raise EXCP_MSR when userspace executes an mrs * instruction to access a special register userspace doesn't * have access to. */ if (!undef_insn(0, frame)) call_trapsignal(td, SIGILL, ILL_PRVOPC, (void *)frame->tf_elr, exception); userret(td, frame); break; case EXCP_SOFTSTP_EL0: - td->td_frame->tf_spsr &= ~PSR_SS; - td->td_pcb->pcb_flags &= ~PCB_SINGLE_STEP; - WRITE_SPECIALREG(mdscr_el1, - READ_SPECIALREG(mdscr_el1) & ~MDSCR_SS); + PROC_LOCK(td->td_proc); + if ((td->td_dbgflags & TDB_STEP) != 0) { + td->td_frame->tf_spsr &= ~PSR_SS; + td->td_pcb->pcb_flags &= ~PCB_SINGLE_STEP; + WRITE_SPECIALREG(mdscr_el1, + READ_SPECIALREG(mdscr_el1) & ~MDSCR_SS); + } + PROC_UNLOCK(td->td_proc); call_trapsignal(td, SIGTRAP, TRAP_TRACE, (void *)frame->tf_elr, exception); userret(td, frame); break; default: call_trapsignal(td, SIGBUS, BUS_OBJERR, (void *)frame->tf_elr, exception); userret(td, frame); break; } KASSERT((td->td_pcb->pcb_fpflags & ~PCB_FP_USERMASK) == 0, ("Kernel VFP flags set while entering userspace")); KASSERT( td->td_pcb->pcb_fpusaved == &td->td_pcb->pcb_fpustate, ("Kernel VFP state in use when entering userspace")); } /* * TODO: We will need to handle these later when we support ARMv8.2 RAS. */ void do_serror(struct trapframe *frame) { uint64_t esr, far; far = READ_SPECIALREG(far_el1); esr = frame->tf_esr; print_registers(frame); print_gp_register("far", far); printf(" esr: %.8lx\n", esr); panic("Unhandled System Error"); } void unhandled_exception(struct trapframe *frame) { uint64_t esr, far; far = READ_SPECIALREG(far_el1); esr = frame->tf_esr; print_registers(frame); print_gp_register("far", far); printf(" esr: %.8lx\n", esr); panic("Unhandled exception"); } diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h index 773f0b8d9402..1404ca8cd727 100644 --- a/sys/arm64/include/armreg.h +++ b/sys/arm64/include/armreg.h @@ -1,1455 +1,1458 @@ /*- * Copyright (c) 2013, 2014 Andrew Turner * Copyright (c) 2015,2021 The FreeBSD Foundation * * Portions of this software were developed by Andrew Turner * under sponsorship from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _MACHINE_ARMREG_H_ #define _MACHINE_ARMREG_H_ #define INSN_SIZE 4 #define MRS_MASK 0xfff00000 #define MRS_VALUE 0xd5300000 #define MRS_SPECIAL(insn) ((insn) & 0x000fffe0) #define MRS_REGISTER(insn) ((insn) & 0x0000001f) #define MRS_Op0_SHIFT 19 #define MRS_Op0_MASK 0x00080000 #define MRS_Op1_SHIFT 16 #define MRS_Op1_MASK 0x00070000 #define MRS_CRn_SHIFT 12 #define MRS_CRn_MASK 0x0000f000 #define MRS_CRm_SHIFT 8 #define MRS_CRm_MASK 0x00000f00 #define MRS_Op2_SHIFT 5 #define MRS_Op2_MASK 0x000000e0 #define MRS_Rt_SHIFT 0 #define MRS_Rt_MASK 0x0000001f #define __MRS_REG(op0, op1, crn, crm, op2) \ (((op0) << MRS_Op0_SHIFT) | ((op1) << MRS_Op1_SHIFT) | \ ((crn) << MRS_CRn_SHIFT) | ((crm) << MRS_CRm_SHIFT) | \ ((op2) << MRS_Op2_SHIFT)) #define MRS_REG(reg) \ __MRS_REG(reg##_op0, reg##_op1, reg##_CRn, reg##_CRm, reg##_op2) #define READ_SPECIALREG(reg) \ ({ uint64_t _val; \ __asm __volatile("mrs %0, " __STRING(reg) : "=&r" (_val)); \ _val; \ }) #define WRITE_SPECIALREG(reg, _val) \ __asm __volatile("msr " __STRING(reg) ", %0" : : "r"((uint64_t)_val)) #define UL(x) UINT64_C(x) /* CNTHCTL_EL2 - Counter-timer Hypervisor Control register */ #define CNTHCTL_EVNTI_MASK (0xf << 4) /* Bit to trigger event stream */ #define CNTHCTL_EVNTDIR (1 << 3) /* Control transition trigger bit */ #define CNTHCTL_EVNTEN (1 << 2) /* Enable event stream */ #define CNTHCTL_EL1PCEN (1 << 1) /* Allow EL0/1 physical timer access */ #define CNTHCTL_EL1PCTEN (1 << 0) /*Allow EL0/1 physical counter access*/ /* CNTP_CTL_EL0 - Counter-timer Physical Timer Control register */ #define CNTP_CTL_ENABLE (1 << 0) #define CNTP_CTL_IMASK (1 << 1) #define CNTP_CTL_ISTATUS (1 << 2) /* CPACR_EL1 */ #define CPACR_FPEN_MASK (0x3 << 20) #define CPACR_FPEN_TRAP_ALL1 (0x0 << 20) /* Traps from EL0 and EL1 */ #define CPACR_FPEN_TRAP_EL0 (0x1 << 20) /* Traps from EL0 */ #define CPACR_FPEN_TRAP_ALL2 (0x2 << 20) /* Traps from EL0 and EL1 */ #define CPACR_FPEN_TRAP_NONE (0x3 << 20) /* No traps */ #define CPACR_TTA (0x1 << 28) /* CTR_EL0 - Cache Type Register */ #define CTR_RES1 (1 << 31) #define CTR_TminLine_SHIFT 32 #define CTR_TminLine_MASK (UL(0x3f) << CTR_TminLine_SHIFT) #define CTR_TminLine_VAL(reg) ((reg) & CTR_TminLine_MASK) #define CTR_DIC_SHIFT 29 #define CTR_DIC_MASK (0x1 << CTR_DIC_SHIFT) #define CTR_DIC_VAL(reg) ((reg) & CTR_DIC_MASK) #define CTR_IDC_SHIFT 28 #define CTR_IDC_MASK (0x1 << CTR_IDC_SHIFT) #define CTR_IDC_VAL(reg) ((reg) & CTR_IDC_MASK) #define CTR_CWG_SHIFT 24 #define CTR_CWG_MASK (0xf << CTR_CWG_SHIFT) #define CTR_CWG_VAL(reg) ((reg) & CTR_CWG_MASK) #define CTR_CWG_SIZE(reg) (4 << (CTR_CWG_VAL(reg) >> CTR_CWG_SHIFT)) #define CTR_ERG_SHIFT 20 #define CTR_ERG_MASK (0xf << CTR_ERG_SHIFT) #define CTR_ERG_VAL(reg) ((reg) & CTR_ERG_MASK) #define CTR_ERG_SIZE(reg) (4 << (CTR_ERG_VAL(reg) >> CTR_ERG_SHIFT)) #define CTR_DLINE_SHIFT 16 #define CTR_DLINE_MASK (0xf << CTR_DLINE_SHIFT) #define CTR_DLINE_VAL(reg) ((reg) & CTR_DLINE_MASK) #define CTR_DLINE_SIZE(reg) (4 << (CTR_DLINE_VAL(reg) >> CTR_DLINE_SHIFT)) #define CTR_L1IP_SHIFT 14 #define CTR_L1IP_MASK (0x3 << CTR_L1IP_SHIFT) #define CTR_L1IP_VAL(reg) ((reg) & CTR_L1IP_MASK) #define CTR_L1IP_VPIPT (0 << CTR_L1IP_SHIFT) #define CTR_L1IP_AIVIVT (1 << CTR_L1IP_SHIFT) #define CTR_L1IP_VIPT (2 << CTR_L1IP_SHIFT) #define CTR_L1IP_PIPT (3 << CTR_L1IP_SHIFT) #define CTR_ILINE_SHIFT 0 #define CTR_ILINE_MASK (0xf << CTR_ILINE_SHIFT) #define CTR_ILINE_VAL(reg) ((reg) & CTR_ILINE_MASK) #define CTR_ILINE_SIZE(reg) (4 << (CTR_ILINE_VAL(reg) >> CTR_ILINE_SHIFT)) /* DAIFSet/DAIFClear */ #define DAIF_D (1 << 3) #define DAIF_A (1 << 2) #define DAIF_I (1 << 1) #define DAIF_F (1 << 0) #define DAIF_ALL (DAIF_D | DAIF_A | DAIF_I | DAIF_F) #define DAIF_INTR (DAIF_I) /* All exceptions that pass */ /* through the intr framework */ /* DBGBCR_EL1 - Debug Breakpoint Control Registers */ #define DBGBCR_EN 0x1 #define DBGBCR_PMC_SHIFT 1 #define DBGBCR_PMC (0x3 << DBGBCR_PMC_SHIFT) #define DBGBCR_PMC_EL1 (0x1 << DBGBCR_PMC_SHIFT) #define DBGBCR_PMC_EL0 (0x2 << DBGBCR_PMC_SHIFT) #define DBGBCR_BAS_SHIFT 5 #define DBGBCR_BAS (0xf << DBGBCR_BAS_SHIFT) #define DBGBCR_HMC_SHIFT 13 #define DBGBCR_HMC (0x1 << DBGBCR_HMC_SHIFT) #define DBGBCR_SSC_SHIFT 14 #define DBGBCR_SSC (0x3 << DBGBCR_SSC_SHIFT) #define DBGBCR_LBN_SHIFT 16 #define DBGBCR_LBN (0xf << DBGBCR_LBN_SHIFT) #define DBGBCR_BT_SHIFT 20 #define DBGBCR_BT (0xf << DBGBCR_BT_SHIFT) /* DBGWCR_EL1 - Debug Watchpoint Control Registers */ #define DBGWCR_EN 0x1 #define DBGWCR_PAC_SHIFT 1 #define DBGWCR_PAC (0x3 << DBGWCR_PAC_SHIFT) #define DBGWCR_PAC_EL1 (0x1 << DBGWCR_PAC_SHIFT) #define DBGWCR_PAC_EL0 (0x2 << DBGWCR_PAC_SHIFT) #define DBGWCR_LSC_SHIFT 3 #define DBGWCR_LSC (0x3 << DBGWCR_LSC_SHIFT) #define DBGWCR_BAS_SHIFT 5 #define DBGWCR_BAS (0xff << DBGWCR_BAS_SHIFT) #define DBGWCR_HMC_SHIFT 13 #define DBGWCR_HMC (0x1 << DBGWCR_HMC_SHIFT) #define DBGWCR_SSC_SHIFT 14 #define DBGWCR_SSC (0x3 << DBGWCR_SSC_SHIFT) #define DBGWCR_LBN_SHIFT 16 #define DBGWCR_LBN (0xf << DBGWCR_LBN_SHIFT) #define DBGWCR_WT_SHIFT 20 #define DBGWCR_WT (0x1 << DBGWCR_WT_SHIFT) #define DBGWCR_MASK_SHIFT 24 #define DBGWCR_MASK (0x1f << DBGWCR_MASK_SHIFT) /* DCZID_EL0 - Data Cache Zero ID register */ #define DCZID_DZP (1 << 4) /* DC ZVA prohibited if non-0 */ #define DCZID_BS_SHIFT 0 #define DCZID_BS_MASK (0xf << DCZID_BS_SHIFT) #define DCZID_BS_SIZE(reg) (((reg) & DCZID_BS_MASK) >> DCZID_BS_SHIFT) /* ESR_ELx */ #define ESR_ELx_ISS_MASK 0x01ffffff #define ISS_INSN_FnV (0x01 << 10) #define ISS_INSN_EA (0x01 << 9) #define ISS_INSN_S1PTW (0x01 << 7) #define ISS_INSN_IFSC_MASK (0x1f << 0) #define ISS_MSR_DIR_SHIFT 0 #define ISS_MSR_DIR (0x01 << ISS_MSR_DIR_SHIFT) #define ISS_MSR_Rt_SHIFT 5 #define ISS_MSR_Rt_MASK (0x1f << ISS_MSR_Rt_SHIFT) #define ISS_MSR_Rt(x) (((x) & ISS_MSR_Rt_MASK) >> ISS_MSR_Rt_SHIFT) #define ISS_MSR_CRm_SHIFT 1 #define ISS_MSR_CRm_MASK (0xf << ISS_MSR_CRm_SHIFT) #define ISS_MSR_CRm(x) (((x) & ISS_MSR_CRm_MASK) >> ISS_MSR_CRm_SHIFT) #define ISS_MSR_CRn_SHIFT 10 #define ISS_MSR_CRn_MASK (0xf << ISS_MSR_CRn_SHIFT) #define ISS_MSR_CRn(x) (((x) & ISS_MSR_CRn_MASK) >> ISS_MSR_CRn_SHIFT) #define ISS_MSR_OP1_SHIFT 14 #define ISS_MSR_OP1_MASK (0x7 << ISS_MSR_OP1_SHIFT) #define ISS_MSR_OP1(x) (((x) & ISS_MSR_OP1_MASK) >> ISS_MSR_OP1_SHIFT) #define ISS_MSR_OP2_SHIFT 17 #define ISS_MSR_OP2_MASK (0x7 << ISS_MSR_OP2_SHIFT) #define ISS_MSR_OP2(x) (((x) & ISS_MSR_OP2_MASK) >> ISS_MSR_OP2_SHIFT) #define ISS_MSR_OP0_SHIFT 20 #define ISS_MSR_OP0_MASK (0x3 << ISS_MSR_OP0_SHIFT) #define ISS_MSR_OP0(x) (((x) & ISS_MSR_OP0_MASK) >> ISS_MSR_OP0_SHIFT) #define ISS_MSR_REG_MASK \ (ISS_MSR_OP0_MASK | ISS_MSR_OP2_MASK | ISS_MSR_OP1_MASK | \ ISS_MSR_CRn_MASK | ISS_MSR_CRm_MASK) #define ISS_DATA_ISV_SHIFT 24 #define ISS_DATA_ISV (0x01 << ISS_DATA_ISV_SHIFT) #define ISS_DATA_SAS_SHIFT 22 #define ISS_DATA_SAS_MASK (0x03 << ISS_DATA_SAS_SHIFT) #define ISS_DATA_SSE_SHIFT 21 #define ISS_DATA_SSE (0x01 << ISS_DATA_SSE_SHIFT) #define ISS_DATA_SRT_SHIFT 16 #define ISS_DATA_SRT_MASK (0x1f << ISS_DATA_SRT_SHIFT) #define ISS_DATA_SF (0x01 << 15) #define ISS_DATA_AR (0x01 << 14) #define ISS_DATA_FnV (0x01 << 10) #define ISS_DATA_EA (0x01 << 9) #define ISS_DATA_CM (0x01 << 8) #define ISS_DATA_S1PTW (0x01 << 7) #define ISS_DATA_WnR_SHIFT 6 #define ISS_DATA_WnR (0x01 << ISS_DATA_WnR_SHIFT) #define ISS_DATA_DFSC_MASK (0x3f << 0) #define ISS_DATA_DFSC_ASF_L0 (0x00 << 0) #define ISS_DATA_DFSC_ASF_L1 (0x01 << 0) #define ISS_DATA_DFSC_ASF_L2 (0x02 << 0) #define ISS_DATA_DFSC_ASF_L3 (0x03 << 0) #define ISS_DATA_DFSC_TF_L0 (0x04 << 0) #define ISS_DATA_DFSC_TF_L1 (0x05 << 0) #define ISS_DATA_DFSC_TF_L2 (0x06 << 0) #define ISS_DATA_DFSC_TF_L3 (0x07 << 0) #define ISS_DATA_DFSC_AFF_L1 (0x09 << 0) #define ISS_DATA_DFSC_AFF_L2 (0x0a << 0) #define ISS_DATA_DFSC_AFF_L3 (0x0b << 0) #define ISS_DATA_DFSC_PF_L1 (0x0d << 0) #define ISS_DATA_DFSC_PF_L2 (0x0e << 0) #define ISS_DATA_DFSC_PF_L3 (0x0f << 0) #define ISS_DATA_DFSC_EXT (0x10 << 0) #define ISS_DATA_DFSC_EXT_L0 (0x14 << 0) #define ISS_DATA_DFSC_EXT_L1 (0x15 << 0) #define ISS_DATA_DFSC_EXT_L2 (0x16 << 0) #define ISS_DATA_DFSC_EXT_L3 (0x17 << 0) #define ISS_DATA_DFSC_ECC (0x18 << 0) #define ISS_DATA_DFSC_ECC_L0 (0x1c << 0) #define ISS_DATA_DFSC_ECC_L1 (0x1d << 0) #define ISS_DATA_DFSC_ECC_L2 (0x1e << 0) #define ISS_DATA_DFSC_ECC_L3 (0x1f << 0) #define ISS_DATA_DFSC_ALIGN (0x21 << 0) #define ISS_DATA_DFSC_TLB_CONFLICT (0x30 << 0) #define ESR_ELx_IL (0x01 << 25) #define ESR_ELx_EC_SHIFT 26 #define ESR_ELx_EC_MASK (0x3f << 26) #define ESR_ELx_EXCEPTION(esr) (((esr) & ESR_ELx_EC_MASK) >> ESR_ELx_EC_SHIFT) #define EXCP_UNKNOWN 0x00 /* Unkwn exception */ #define EXCP_TRAP_WFI_WFE 0x01 /* Trapped WFI or WFE */ #define EXCP_FP_SIMD 0x07 /* VFP/SIMD trap */ #define EXCP_ILL_STATE 0x0e /* Illegal execution state */ #define EXCP_SVC32 0x11 /* SVC trap for AArch32 */ #define EXCP_SVC64 0x15 /* SVC trap for AArch64 */ #define EXCP_HVC 0x16 /* HVC trap */ #define EXCP_MSR 0x18 /* MSR/MRS trap */ #define EXCP_INSN_ABORT_L 0x20 /* Instruction abort, from lower EL */ #define EXCP_INSN_ABORT 0x21 /* Instruction abort, from same EL */ #define EXCP_PC_ALIGN 0x22 /* PC alignment fault */ #define EXCP_DATA_ABORT_L 0x24 /* Data abort, from lower EL */ #define EXCP_DATA_ABORT 0x25 /* Data abort, from same EL */ #define EXCP_SP_ALIGN 0x26 /* SP slignment fault */ #define EXCP_TRAP_FP 0x2c /* Trapped FP exception */ #define EXCP_SERROR 0x2f /* SError interrupt */ #define EXCP_BRKPT_EL0 0x30 /* Hardware breakpoint, from same EL */ #define EXCP_SOFTSTP_EL0 0x32 /* Software Step, from lower EL */ #define EXCP_SOFTSTP_EL1 0x33 /* Software Step, from same EL */ #define EXCP_WATCHPT_EL0 0x34 /* Watchpoint, from lower EL */ #define EXCP_WATCHPT_EL1 0x35 /* Watchpoint, from same EL */ #define EXCP_BRK 0x3c /* Breakpoint */ /* ICC_CTLR_EL1 */ #define ICC_CTLR_EL1_EOIMODE (1U << 1) /* ICC_IAR1_EL1 */ #define ICC_IAR1_EL1_SPUR (0x03ff) /* ICC_IGRPEN0_EL1 */ #define ICC_IGRPEN0_EL1_EN (1U << 0) /* ICC_PMR_EL1 */ #define ICC_PMR_EL1_PRIO_MASK (0xFFUL) /* ICC_SGI1R_EL1 */ #define ICC_SGI1R_EL1_TL_MASK 0xffffUL #define ICC_SGI1R_EL1_AFF1_SHIFT 16 #define ICC_SGI1R_EL1_SGIID_SHIFT 24 #define ICC_SGI1R_EL1_AFF2_SHIFT 32 #define ICC_SGI1R_EL1_AFF3_SHIFT 48 #define ICC_SGI1R_EL1_SGIID_MASK 0xfUL #define ICC_SGI1R_EL1_IRM (0x1UL << 40) /* ICC_SRE_EL1 */ #define ICC_SRE_EL1_SRE (1U << 0) /* ID_AA64DFR0_EL1 */ #define ID_AA64DFR0_EL1 MRS_REG(ID_AA64DFR0_EL1) #define ID_AA64DFR0_EL1_op0 0x3 #define ID_AA64DFR0_EL1_op1 0x0 #define ID_AA64DFR0_EL1_CRn 0x0 #define ID_AA64DFR0_EL1_CRm 0x5 #define ID_AA64DFR0_EL1_op2 0x0 #define ID_AA64DFR0_DebugVer_SHIFT 0 #define ID_AA64DFR0_DebugVer_MASK (UL(0xf) << ID_AA64DFR0_DebugVer_SHIFT) #define ID_AA64DFR0_DebugVer_VAL(x) ((x) & ID_AA64DFR0_DebugVer_MASK) #define ID_AA64DFR0_DebugVer_8 (UL(0x6) << ID_AA64DFR0_DebugVer_SHIFT) #define ID_AA64DFR0_DebugVer_8_VHE (UL(0x7) << ID_AA64DFR0_DebugVer_SHIFT) #define ID_AA64DFR0_DebugVer_8_2 (UL(0x8) << ID_AA64DFR0_DebugVer_SHIFT) #define ID_AA64DFR0_DebugVer_8_4 (UL(0x9) << ID_AA64DFR0_DebugVer_SHIFT) #define ID_AA64DFR0_TraceVer_SHIFT 4 #define ID_AA64DFR0_TraceVer_MASK (UL(0xf) << ID_AA64DFR0_TraceVer_SHIFT) #define ID_AA64DFR0_TraceVer_VAL(x) ((x) & ID_AA64DFR0_TraceVer_MASK) #define ID_AA64DFR0_TraceVer_NONE (UL(0x0) << ID_AA64DFR0_TraceVer_SHIFT) #define ID_AA64DFR0_TraceVer_IMPL (UL(0x1) << ID_AA64DFR0_TraceVer_SHIFT) #define ID_AA64DFR0_PMUVer_SHIFT 8 #define ID_AA64DFR0_PMUVer_MASK (UL(0xf) << ID_AA64DFR0_PMUVer_SHIFT) #define ID_AA64DFR0_PMUVer_VAL(x) ((x) & ID_AA64DFR0_PMUVer_MASK) #define ID_AA64DFR0_PMUVer_NONE (UL(0x0) << ID_AA64DFR0_PMUVer_SHIFT) #define ID_AA64DFR0_PMUVer_3 (UL(0x1) << ID_AA64DFR0_PMUVer_SHIFT) #define ID_AA64DFR0_PMUVer_3_1 (UL(0x4) << ID_AA64DFR0_PMUVer_SHIFT) #define ID_AA64DFR0_PMUVer_3_4 (UL(0x5) << ID_AA64DFR0_PMUVer_SHIFT) #define ID_AA64DFR0_PMUVer_3_5 (UL(0x6) << ID_AA64DFR0_PMUVer_SHIFT) #define ID_AA64DFR0_PMUVer_IMPL (UL(0xf) << ID_AA64DFR0_PMUVer_SHIFT) #define ID_AA64DFR0_BRPs_SHIFT 12 #define ID_AA64DFR0_BRPs_MASK (UL(0xf) << ID_AA64DFR0_BRPs_SHIFT) #define ID_AA64DFR0_BRPs_VAL(x) \ ((((x) >> ID_AA64DFR0_BRPs_SHIFT) & 0xf) + 1) #define ID_AA64DFR0_WRPs_SHIFT 20 #define ID_AA64DFR0_WRPs_MASK (UL(0xf) << ID_AA64DFR0_WRPs_SHIFT) #define ID_AA64DFR0_WRPs_VAL(x) \ ((((x) >> ID_AA64DFR0_WRPs_SHIFT) & 0xf) + 1) #define ID_AA64DFR0_CTX_CMPs_SHIFT 28 #define ID_AA64DFR0_CTX_CMPs_MASK (UL(0xf) << ID_AA64DFR0_CTX_CMPs_SHIFT) #define ID_AA64DFR0_CTX_CMPs_VAL(x) \ ((((x) >> ID_AA64DFR0_CTX_CMPs_SHIFT) & 0xf) + 1) #define ID_AA64DFR0_PMSVer_SHIFT 32 #define ID_AA64DFR0_PMSVer_MASK (UL(0xf) << ID_AA64DFR0_PMSVer_SHIFT) #define ID_AA64DFR0_PMSVer_VAL(x) ((x) & ID_AA64DFR0_PMSVer_MASK) #define ID_AA64DFR0_PMSVer_NONE (UL(0x0) << ID_AA64DFR0_PMSVer_SHIFT) #define ID_AA64DFR0_PMSVer_SPE (UL(0x1) << ID_AA64DFR0_PMSVer_SHIFT) #define ID_AA64DFR0_PMSVer_SPE_8_3 (UL(0x2) << ID_AA64DFR0_PMSVer_SHIFT) #define ID_AA64DFR0_DoubleLock_SHIFT 36 #define ID_AA64DFR0_DoubleLock_MASK (UL(0xf) << ID_AA64DFR0_DoubleLock_SHIFT) #define ID_AA64DFR0_DoubleLock_VAL(x) ((x) & ID_AA64DFR0_DoubleLock_MASK) #define ID_AA64DFR0_DoubleLock_IMPL (UL(0x0) << ID_AA64DFR0_DoubleLock_SHIFT) #define ID_AA64DFR0_DoubleLock_NONE (UL(0xf) << ID_AA64DFR0_DoubleLock_SHIFT) #define ID_AA64DFR0_TraceFilt_SHIFT 40 #define ID_AA64DFR0_TraceFilt_MASK (UL(0xf) << ID_AA64DFR0_TraceFilt_SHIFT) #define ID_AA64DFR0_TraceFilt_VAL(x) ((x) & ID_AA64DFR0_TraceFilt_MASK) #define ID_AA64DFR0_TraceFilt_NONE (UL(0x0) << ID_AA64DFR0_TraceFilt_SHIFT) #define ID_AA64DFR0_TraceFilt_8_4 (UL(0x1) << ID_AA64DFR0_TraceFilt_SHIFT) /* ID_AA64ISAR0_EL1 */ #define ID_AA64ISAR0_EL1 MRS_REG(ID_AA64ISAR0_EL1) #define ID_AA64ISAR0_EL1_op0 0x3 #define ID_AA64ISAR0_EL1_op1 0x0 #define ID_AA64ISAR0_EL1_CRn 0x0 #define ID_AA64ISAR0_EL1_CRm 0x6 #define ID_AA64ISAR0_EL1_op2 0x0 #define ID_AA64ISAR0_AES_SHIFT 4 #define ID_AA64ISAR0_AES_MASK (UL(0xf) << ID_AA64ISAR0_AES_SHIFT) #define ID_AA64ISAR0_AES_VAL(x) ((x) & ID_AA64ISAR0_AES_MASK) #define ID_AA64ISAR0_AES_NONE (UL(0x0) << ID_AA64ISAR0_AES_SHIFT) #define ID_AA64ISAR0_AES_BASE (UL(0x1) << ID_AA64ISAR0_AES_SHIFT) #define ID_AA64ISAR0_AES_PMULL (UL(0x2) << ID_AA64ISAR0_AES_SHIFT) #define ID_AA64ISAR0_SHA1_SHIFT 8 #define ID_AA64ISAR0_SHA1_MASK (UL(0xf) << ID_AA64ISAR0_SHA1_SHIFT) #define ID_AA64ISAR0_SHA1_VAL(x) ((x) & ID_AA64ISAR0_SHA1_MASK) #define ID_AA64ISAR0_SHA1_NONE (UL(0x0) << ID_AA64ISAR0_SHA1_SHIFT) #define ID_AA64ISAR0_SHA1_BASE (UL(0x1) << ID_AA64ISAR0_SHA1_SHIFT) #define ID_AA64ISAR0_SHA2_SHIFT 12 #define ID_AA64ISAR0_SHA2_MASK (UL(0xf) << ID_AA64ISAR0_SHA2_SHIFT) #define ID_AA64ISAR0_SHA2_VAL(x) ((x) & ID_AA64ISAR0_SHA2_MASK) #define ID_AA64ISAR0_SHA2_NONE (UL(0x0) << ID_AA64ISAR0_SHA2_SHIFT) #define ID_AA64ISAR0_SHA2_BASE (UL(0x1) << ID_AA64ISAR0_SHA2_SHIFT) #define ID_AA64ISAR0_SHA2_512 (UL(0x2) << ID_AA64ISAR0_SHA2_SHIFT) #define ID_AA64ISAR0_CRC32_SHIFT 16 #define ID_AA64ISAR0_CRC32_MASK (UL(0xf) << ID_AA64ISAR0_CRC32_SHIFT) #define ID_AA64ISAR0_CRC32_VAL(x) ((x) & ID_AA64ISAR0_CRC32_MASK) #define ID_AA64ISAR0_CRC32_NONE (UL(0x0) << ID_AA64ISAR0_CRC32_SHIFT) #define ID_AA64ISAR0_CRC32_BASE (UL(0x1) << ID_AA64ISAR0_CRC32_SHIFT) #define ID_AA64ISAR0_Atomic_SHIFT 20 #define ID_AA64ISAR0_Atomic_MASK (UL(0xf) << ID_AA64ISAR0_Atomic_SHIFT) #define ID_AA64ISAR0_Atomic_VAL(x) ((x) & ID_AA64ISAR0_Atomic_MASK) #define ID_AA64ISAR0_Atomic_NONE (UL(0x0) << ID_AA64ISAR0_Atomic_SHIFT) #define ID_AA64ISAR0_Atomic_IMPL (UL(0x2) << ID_AA64ISAR0_Atomic_SHIFT) #define ID_AA64ISAR0_RDM_SHIFT 28 #define ID_AA64ISAR0_RDM_MASK (UL(0xf) << ID_AA64ISAR0_RDM_SHIFT) #define ID_AA64ISAR0_RDM_VAL(x) ((x) & ID_AA64ISAR0_RDM_MASK) #define ID_AA64ISAR0_RDM_NONE (UL(0x0) << ID_AA64ISAR0_RDM_SHIFT) #define ID_AA64ISAR0_RDM_IMPL (UL(0x1) << ID_AA64ISAR0_RDM_SHIFT) #define ID_AA64ISAR0_SHA3_SHIFT 32 #define ID_AA64ISAR0_SHA3_MASK (UL(0xf) << ID_AA64ISAR0_SHA3_SHIFT) #define ID_AA64ISAR0_SHA3_VAL(x) ((x) & ID_AA64ISAR0_SHA3_MASK) #define ID_AA64ISAR0_SHA3_NONE (UL(0x0) << ID_AA64ISAR0_SHA3_SHIFT) #define ID_AA64ISAR0_SHA3_IMPL (UL(0x1) << ID_AA64ISAR0_SHA3_SHIFT) #define ID_AA64ISAR0_SM3_SHIFT 36 #define ID_AA64ISAR0_SM3_MASK (UL(0xf) << ID_AA64ISAR0_SM3_SHIFT) #define ID_AA64ISAR0_SM3_VAL(x) ((x) & ID_AA64ISAR0_SM3_MASK) #define ID_AA64ISAR0_SM3_NONE (UL(0x0) << ID_AA64ISAR0_SM3_SHIFT) #define ID_AA64ISAR0_SM3_IMPL (UL(0x1) << ID_AA64ISAR0_SM3_SHIFT) #define ID_AA64ISAR0_SM4_SHIFT 40 #define ID_AA64ISAR0_SM4_MASK (UL(0xf) << ID_AA64ISAR0_SM4_SHIFT) #define ID_AA64ISAR0_SM4_VAL(x) ((x) & ID_AA64ISAR0_SM4_MASK) #define ID_AA64ISAR0_SM4_NONE (UL(0x0) << ID_AA64ISAR0_SM4_SHIFT) #define ID_AA64ISAR0_SM4_IMPL (UL(0x1) << ID_AA64ISAR0_SM4_SHIFT) #define ID_AA64ISAR0_DP_SHIFT 44 #define ID_AA64ISAR0_DP_MASK (UL(0xf) << ID_AA64ISAR0_DP_SHIFT) #define ID_AA64ISAR0_DP_VAL(x) ((x) & ID_AA64ISAR0_DP_MASK) #define ID_AA64ISAR0_DP_NONE (UL(0x0) << ID_AA64ISAR0_DP_SHIFT) #define ID_AA64ISAR0_DP_IMPL (UL(0x1) << ID_AA64ISAR0_DP_SHIFT) #define ID_AA64ISAR0_FHM_SHIFT 48 #define ID_AA64ISAR0_FHM_MASK (UL(0xf) << ID_AA64ISAR0_FHM_SHIFT) #define ID_AA64ISAR0_FHM_VAL(x) ((x) & ID_AA64ISAR0_FHM_MASK) #define ID_AA64ISAR0_FHM_NONE (UL(0x0) << ID_AA64ISAR0_FHM_SHIFT) #define ID_AA64ISAR0_FHM_IMPL (UL(0x1) << ID_AA64ISAR0_FHM_SHIFT) #define ID_AA64ISAR0_TS_SHIFT 52 #define ID_AA64ISAR0_TS_MASK (UL(0xf) << ID_AA64ISAR0_TS_SHIFT) #define ID_AA64ISAR0_TS_VAL(x) ((x) & ID_AA64ISAR0_TS_MASK) #define ID_AA64ISAR0_TS_NONE (UL(0x0) << ID_AA64ISAR0_TS_SHIFT) #define ID_AA64ISAR0_TS_CondM_8_4 (UL(0x1) << ID_AA64ISAR0_TS_SHIFT) #define ID_AA64ISAR0_TS_CondM_8_5 (UL(0x2) << ID_AA64ISAR0_TS_SHIFT) #define ID_AA64ISAR0_TLB_SHIFT 56 #define ID_AA64ISAR0_TLB_MASK (UL(0xf) << ID_AA64ISAR0_TLB_SHIFT) #define ID_AA64ISAR0_TLB_VAL(x) ((x) & ID_AA64ISAR0_TLB_MASK) #define ID_AA64ISAR0_TLB_NONE (UL(0x0) << ID_AA64ISAR0_TLB_SHIFT) #define ID_AA64ISAR0_TLB_TLBIOS (UL(0x1) << ID_AA64ISAR0_TLB_SHIFT) #define ID_AA64ISAR0_TLB_TLBIOSR (UL(0x2) << ID_AA64ISAR0_TLB_SHIFT) #define ID_AA64ISAR0_RNDR_SHIFT 60 #define ID_AA64ISAR0_RNDR_MASK (UL(0xf) << ID_AA64ISAR0_RNDR_SHIFT) #define ID_AA64ISAR0_RNDR_VAL(x) ((x) & ID_AA64ISAR0_RNDR_MASK) #define ID_AA64ISAR0_RNDR_NONE (UL(0x0) << ID_AA64ISAR0_RNDR_SHIFT) #define ID_AA64ISAR0_RNDR_IMPL (UL(0x1) << ID_AA64ISAR0_RNDR_SHIFT) /* ID_AA64ISAR1_EL1 */ #define ID_AA64ISAR1_EL1 MRS_REG(ID_AA64ISAR1_EL1) #define ID_AA64ISAR1_EL1_op0 0x3 #define ID_AA64ISAR1_EL1_op1 0x0 #define ID_AA64ISAR1_EL1_CRn 0x0 #define ID_AA64ISAR1_EL1_CRm 0x6 #define ID_AA64ISAR1_EL1_op2 0x1 #define ID_AA64ISAR1_DPB_SHIFT 0 #define ID_AA64ISAR1_DPB_MASK (UL(0xf) << ID_AA64ISAR1_DPB_SHIFT) #define ID_AA64ISAR1_DPB_VAL(x) ((x) & ID_AA64ISAR1_DPB_MASK) #define ID_AA64ISAR1_DPB_NONE (UL(0x0) << ID_AA64ISAR1_DPB_SHIFT) #define ID_AA64ISAR1_DPB_DCCVAP (UL(0x1) << ID_AA64ISAR1_DPB_SHIFT) #define ID_AA64ISAR1_DPB_DCCVADP (UL(0x2) << ID_AA64ISAR1_DPB_SHIFT) #define ID_AA64ISAR1_APA_SHIFT 4 #define ID_AA64ISAR1_APA_MASK (UL(0xf) << ID_AA64ISAR1_APA_SHIFT) #define ID_AA64ISAR1_APA_VAL(x) ((x) & ID_AA64ISAR1_APA_MASK) #define ID_AA64ISAR1_APA_NONE (UL(0x0) << ID_AA64ISAR1_APA_SHIFT) #define ID_AA64ISAR1_APA_PAC (UL(0x1) << ID_AA64ISAR1_APA_SHIFT) #define ID_AA64ISAR1_APA_EPAC (UL(0x2) << ID_AA64ISAR1_APA_SHIFT) #define ID_AA64ISAR1_API_SHIFT 8 #define ID_AA64ISAR1_API_MASK (UL(0xf) << ID_AA64ISAR1_API_SHIFT) #define ID_AA64ISAR1_API_VAL(x) ((x) & ID_AA64ISAR1_API_MASK) #define ID_AA64ISAR1_API_NONE (UL(0x0) << ID_AA64ISAR1_API_SHIFT) #define ID_AA64ISAR1_API_PAC (UL(0x1) << ID_AA64ISAR1_API_SHIFT) #define ID_AA64ISAR1_API_EPAC (UL(0x2) << ID_AA64ISAR1_API_SHIFT) #define ID_AA64ISAR1_JSCVT_SHIFT 12 #define ID_AA64ISAR1_JSCVT_MASK (UL(0xf) << ID_AA64ISAR1_JSCVT_SHIFT) #define ID_AA64ISAR1_JSCVT_VAL(x) ((x) & ID_AA64ISAR1_JSCVT_MASK) #define ID_AA64ISAR1_JSCVT_NONE (UL(0x0) << ID_AA64ISAR1_JSCVT_SHIFT) #define ID_AA64ISAR1_JSCVT_IMPL (UL(0x1) << ID_AA64ISAR1_JSCVT_SHIFT) #define ID_AA64ISAR1_FCMA_SHIFT 16 #define ID_AA64ISAR1_FCMA_MASK (UL(0xf) << ID_AA64ISAR1_FCMA_SHIFT) #define ID_AA64ISAR1_FCMA_VAL(x) ((x) & ID_AA64ISAR1_FCMA_MASK) #define ID_AA64ISAR1_FCMA_NONE (UL(0x0) << ID_AA64ISAR1_FCMA_SHIFT) #define ID_AA64ISAR1_FCMA_IMPL (UL(0x1) << ID_AA64ISAR1_FCMA_SHIFT) #define ID_AA64ISAR1_LRCPC_SHIFT 20 #define ID_AA64ISAR1_LRCPC_MASK (UL(0xf) << ID_AA64ISAR1_LRCPC_SHIFT) #define ID_AA64ISAR1_LRCPC_VAL(x) ((x) & ID_AA64ISAR1_LRCPC_MASK) #define ID_AA64ISAR1_LRCPC_NONE (UL(0x0) << ID_AA64ISAR1_LRCPC_SHIFT) #define ID_AA64ISAR1_LRCPC_RCPC_8_3 (UL(0x1) << ID_AA64ISAR1_LRCPC_SHIFT) #define ID_AA64ISAR1_LRCPC_RCPC_8_4 (UL(0x2) << ID_AA64ISAR1_LRCPC_SHIFT) #define ID_AA64ISAR1_GPA_SHIFT 24 #define ID_AA64ISAR1_GPA_MASK (UL(0xf) << ID_AA64ISAR1_GPA_SHIFT) #define ID_AA64ISAR1_GPA_VAL(x) ((x) & ID_AA64ISAR1_GPA_MASK) #define ID_AA64ISAR1_GPA_NONE (UL(0x0) << ID_AA64ISAR1_GPA_SHIFT) #define ID_AA64ISAR1_GPA_IMPL (UL(0x1) << ID_AA64ISAR1_GPA_SHIFT) #define ID_AA64ISAR1_GPI_SHIFT 28 #define ID_AA64ISAR1_GPI_MASK (UL(0xf) << ID_AA64ISAR1_GPI_SHIFT) #define ID_AA64ISAR1_GPI_VAL(x) ((x) & ID_AA64ISAR1_GPI_MASK) #define ID_AA64ISAR1_GPI_NONE (UL(0x0) << ID_AA64ISAR1_GPI_SHIFT) #define ID_AA64ISAR1_GPI_IMPL (UL(0x1) << ID_AA64ISAR1_GPI_SHIFT) #define ID_AA64ISAR1_FRINTTS_SHIFT 32 #define ID_AA64ISAR1_FRINTTS_MASK (UL(0xf) << ID_AA64ISAR1_FRINTTS_SHIFT) #define ID_AA64ISAR1_FRINTTS_VAL(x) ((x) & ID_AA64ISAR1_FRINTTS_MASK) #define ID_AA64ISAR1_FRINTTS_NONE (UL(0x0) << ID_AA64ISAR1_FRINTTS_SHIFT) #define ID_AA64ISAR1_FRINTTS_IMPL (UL(0x1) << ID_AA64ISAR1_FRINTTS_SHIFT) #define ID_AA64ISAR1_SB_SHIFT 36 #define ID_AA64ISAR1_SB_MASK (UL(0xf) << ID_AA64ISAR1_SB_SHIFT) #define ID_AA64ISAR1_SB_VAL(x) ((x) & ID_AA64ISAR1_SB_MASK) #define ID_AA64ISAR1_SB_NONE (UL(0x0) << ID_AA64ISAR1_SB_SHIFT) #define ID_AA64ISAR1_SB_IMPL (UL(0x1) << ID_AA64ISAR1_SB_SHIFT) #define ID_AA64ISAR1_SPECRES_SHIFT 40 #define ID_AA64ISAR1_SPECRES_MASK (UL(0xf) << ID_AA64ISAR1_SPECRES_SHIFT) #define ID_AA64ISAR1_SPECRES_VAL(x) ((x) & ID_AA64ISAR1_SPECRES_MASK) #define ID_AA64ISAR1_SPECRES_NONE (UL(0x0) << ID_AA64ISAR1_SPECRES_SHIFT) #define ID_AA64ISAR1_SPECRES_IMPL (UL(0x1) << ID_AA64ISAR1_SPECRES_SHIFT) #define ID_AA64ISAR1_BF16_SHIFT 44 #define ID_AA64ISAR1_BF16_MASK (UL(0xf) << ID_AA64ISAR1_BF16_SHIFT) #define ID_AA64ISAR1_BF16_VAL(x) ((x) & ID_AA64ISAR1_BF16_MASK) #define ID_AA64ISAR1_BF16_NONE (UL(0x0) << ID_AA64ISAR1_BF16_SHIFT) #define ID_AA64ISAR1_BF16_IMPL (UL(0x1) << ID_AA64ISAR1_BF16_SHIFT) #define ID_AA64ISAR1_DGH_SHIFT 48 #define ID_AA64ISAR1_DGH_MASK (UL(0xf) << ID_AA64ISAR1_DGH_SHIFT) #define ID_AA64ISAR1_DGH_VAL(x) ((x) & ID_AA64ISAR1_DGH_MASK) #define ID_AA64ISAR1_DGH_NONE (UL(0x0) << ID_AA64ISAR1_DGH_SHIFT) #define ID_AA64ISAR1_DGH_IMPL (UL(0x1) << ID_AA64ISAR1_DGH_SHIFT) #define ID_AA64ISAR1_I8MM_SHIFT 52 #define ID_AA64ISAR1_I8MM_MASK (UL(0xf) << ID_AA64ISAR1_I8MM_SHIFT) #define ID_AA64ISAR1_I8MM_VAL(x) ((x) & ID_AA64ISAR1_I8MM_MASK) #define ID_AA64ISAR1_I8MM_NONE (UL(0x0) << ID_AA64ISAR1_I8MM_SHIFT) #define ID_AA64ISAR1_I8MM_IMPL (UL(0x1) << ID_AA64ISAR1_I8MM_SHIFT) /* ID_AA64MMFR0_EL1 */ #define ID_AA64MMFR0_EL1 MRS_REG(ID_AA64MMFR0_EL1) #define ID_AA64MMFR0_EL1_op0 0x3 #define ID_AA64MMFR0_EL1_op1 0x0 #define ID_AA64MMFR0_EL1_CRn 0x0 #define ID_AA64MMFR0_EL1_CRm 0x7 #define ID_AA64MMFR0_EL1_op2 0x0 #define ID_AA64MMFR0_PARange_SHIFT 0 #define ID_AA64MMFR0_PARange_MASK (UL(0xf) << ID_AA64MMFR0_PARange_SHIFT) #define ID_AA64MMFR0_PARange_VAL(x) ((x) & ID_AA64MMFR0_PARange_MASK) #define ID_AA64MMFR0_PARange_4G (UL(0x0) << ID_AA64MMFR0_PARange_SHIFT) #define ID_AA64MMFR0_PARange_64G (UL(0x1) << ID_AA64MMFR0_PARange_SHIFT) #define ID_AA64MMFR0_PARange_1T (UL(0x2) << ID_AA64MMFR0_PARange_SHIFT) #define ID_AA64MMFR0_PARange_4T (UL(0x3) << ID_AA64MMFR0_PARange_SHIFT) #define ID_AA64MMFR0_PARange_16T (UL(0x4) << ID_AA64MMFR0_PARange_SHIFT) #define ID_AA64MMFR0_PARange_256T (UL(0x5) << ID_AA64MMFR0_PARange_SHIFT) #define ID_AA64MMFR0_PARange_4P (UL(0x6) << ID_AA64MMFR0_PARange_SHIFT) #define ID_AA64MMFR0_ASIDBits_SHIFT 4 #define ID_AA64MMFR0_ASIDBits_MASK (UL(0xf) << ID_AA64MMFR0_ASIDBits_SHIFT) #define ID_AA64MMFR0_ASIDBits_VAL(x) ((x) & ID_AA64MMFR0_ASIDBits_MASK) #define ID_AA64MMFR0_ASIDBits_8 (UL(0x0) << ID_AA64MMFR0_ASIDBits_SHIFT) #define ID_AA64MMFR0_ASIDBits_16 (UL(0x2) << ID_AA64MMFR0_ASIDBits_SHIFT) #define ID_AA64MMFR0_BigEnd_SHIFT 8 #define ID_AA64MMFR0_BigEnd_MASK (UL(0xf) << ID_AA64MMFR0_BigEnd_SHIFT) #define ID_AA64MMFR0_BigEnd_VAL(x) ((x) & ID_AA64MMFR0_BigEnd_MASK) #define ID_AA64MMFR0_BigEnd_FIXED (UL(0x0) << ID_AA64MMFR0_BigEnd_SHIFT) #define ID_AA64MMFR0_BigEnd_MIXED (UL(0x1) << ID_AA64MMFR0_BigEnd_SHIFT) #define ID_AA64MMFR0_SNSMem_SHIFT 12 #define ID_AA64MMFR0_SNSMem_MASK (UL(0xf) << ID_AA64MMFR0_SNSMem_SHIFT) #define ID_AA64MMFR0_SNSMem_VAL(x) ((x) & ID_AA64MMFR0_SNSMem_MASK) #define ID_AA64MMFR0_SNSMem_NONE (UL(0x0) << ID_AA64MMFR0_SNSMem_SHIFT) #define ID_AA64MMFR0_SNSMem_DISTINCT (UL(0x1) << ID_AA64MMFR0_SNSMem_SHIFT) #define ID_AA64MMFR0_BigEndEL0_SHIFT 16 #define ID_AA64MMFR0_BigEndEL0_MASK (UL(0xf) << ID_AA64MMFR0_BigEndEL0_SHIFT) #define ID_AA64MMFR0_BigEndEL0_VAL(x) ((x) & ID_AA64MMFR0_BigEndEL0_MASK) #define ID_AA64MMFR0_BigEndEL0_FIXED (UL(0x0) << ID_AA64MMFR0_BigEndEL0_SHIFT) #define ID_AA64MMFR0_BigEndEL0_MIXED (UL(0x1) << ID_AA64MMFR0_BigEndEL0_SHIFT) #define ID_AA64MMFR0_TGran16_SHIFT 20 #define ID_AA64MMFR0_TGran16_MASK (UL(0xf) << ID_AA64MMFR0_TGran16_SHIFT) #define ID_AA64MMFR0_TGran16_VAL(x) ((x) & ID_AA64MMFR0_TGran16_MASK) #define ID_AA64MMFR0_TGran16_NONE (UL(0x0) << ID_AA64MMFR0_TGran16_SHIFT) #define ID_AA64MMFR0_TGran16_IMPL (UL(0x1) << ID_AA64MMFR0_TGran16_SHIFT) #define ID_AA64MMFR0_TGran64_SHIFT 24 #define ID_AA64MMFR0_TGran64_MASK (UL(0xf) << ID_AA64MMFR0_TGran64_SHIFT) #define ID_AA64MMFR0_TGran64_VAL(x) ((x) & ID_AA64MMFR0_TGran64_MASK) #define ID_AA64MMFR0_TGran64_IMPL (UL(0x0) << ID_AA64MMFR0_TGran64_SHIFT) #define ID_AA64MMFR0_TGran64_NONE (UL(0xf) << ID_AA64MMFR0_TGran64_SHIFT) #define ID_AA64MMFR0_TGran4_SHIFT 28 #define ID_AA64MMFR0_TGran4_MASK (UL(0xf) << ID_AA64MMFR0_TGran4_SHIFT) #define ID_AA64MMFR0_TGran4_VAL(x) ((x) & ID_AA64MMFR0_TGran4_MASK) #define ID_AA64MMFR0_TGran4_IMPL (UL(0x0) << ID_AA64MMFR0_TGran4_SHIFT) #define ID_AA64MMFR0_TGran4_NONE (UL(0xf) << ID_AA64MMFR0_TGran4_SHIFT) #define ID_AA64MMFR0_TGran16_2_SHIFT 32 #define ID_AA64MMFR0_TGran16_2_MASK (UL(0xf) << ID_AA64MMFR0_TGran16_2_SHIFT) #define ID_AA64MMFR0_TGran16_2_VAL(x) ((x) & ID_AA64MMFR0_TGran16_2_MASK) #define ID_AA64MMFR0_TGran16_2_TGran16 (UL(0x0) << ID_AA64MMFR0_TGran16_2_SHIFT) #define ID_AA64MMFR0_TGran16_2_NONE (UL(0x1) << ID_AA64MMFR0_TGran16_2_SHIFT) #define ID_AA64MMFR0_TGran16_2_IMPL (UL(0x2) << ID_AA64MMFR0_TGran16_2_SHIFT) #define ID_AA64MMFR0_TGran64_2_SHIFT 36 #define ID_AA64MMFR0_TGran64_2_MASK (UL(0xf) << ID_AA64MMFR0_TGran64_2_SHIFT) #define ID_AA64MMFR0_TGran64_2_VAL(x) ((x) & ID_AA64MMFR0_TGran64_2_MASK) #define ID_AA64MMFR0_TGran64_2_TGran64 (UL(0x0) << ID_AA64MMFR0_TGran64_2_SHIFT) #define ID_AA64MMFR0_TGran64_2_NONE (UL(0x1) << ID_AA64MMFR0_TGran64_2_SHIFT) #define ID_AA64MMFR0_TGran64_2_IMPL (UL(0x2) << ID_AA64MMFR0_TGran64_2_SHIFT) #define ID_AA64MMFR0_TGran4_2_SHIFT 40 #define ID_AA64MMFR0_TGran4_2_MASK (UL(0xf) << ID_AA64MMFR0_TGran4_2_SHIFT) #define ID_AA64MMFR0_TGran4_2_VAL(x) ((x) & ID_AA64MMFR0_TGran4_2_MASK) #define ID_AA64MMFR0_TGran4_2_TGran4 (UL(0x0) << ID_AA64MMFR0_TGran4_2_SHIFT) #define ID_AA64MMFR0_TGran4_2_NONE (UL(0x1) << ID_AA64MMFR0_TGran4_2_SHIFT) #define ID_AA64MMFR0_TGran4_2_IMPL (UL(0x2) << ID_AA64MMFR0_TGran4_2_SHIFT) #define ID_AA64MMFR0_ExS_SHIFT 44 #define ID_AA64MMFR0_ExS_MASK (UL(0xf) << ID_AA64MMFR0_ExS_SHIFT) #define ID_AA64MMFR0_ExS_VAL(x) ((x) & ID_AA64MMFR0_ExS_MASK) #define ID_AA64MMFR0_ExS_ALL (UL(0x0) << ID_AA64MMFR0_ExS_SHIFT) #define ID_AA64MMFR0_ExS_IMPL (UL(0x1) << ID_AA64MMFR0_ExS_SHIFT) /* ID_AA64MMFR1_EL1 */ #define ID_AA64MMFR1_EL1 MRS_REG(ID_AA64MMFR1_EL1) #define ID_AA64MMFR1_EL1_op0 0x3 #define ID_AA64MMFR1_EL1_op1 0x0 #define ID_AA64MMFR1_EL1_CRn 0x0 #define ID_AA64MMFR1_EL1_CRm 0x7 #define ID_AA64MMFR1_EL1_op2 0x1 #define ID_AA64MMFR1_HAFDBS_SHIFT 0 #define ID_AA64MMFR1_HAFDBS_MASK (UL(0xf) << ID_AA64MMFR1_HAFDBS_SHIFT) #define ID_AA64MMFR1_HAFDBS_VAL(x) ((x) & ID_AA64MMFR1_HAFDBS_MASK) #define ID_AA64MMFR1_HAFDBS_NONE (UL(0x0) << ID_AA64MMFR1_HAFDBS_SHIFT) #define ID_AA64MMFR1_HAFDBS_AF (UL(0x1) << ID_AA64MMFR1_HAFDBS_SHIFT) #define ID_AA64MMFR1_HAFDBS_AF_DBS (UL(0x2) << ID_AA64MMFR1_HAFDBS_SHIFT) #define ID_AA64MMFR1_VMIDBits_SHIFT 4 #define ID_AA64MMFR1_VMIDBits_MASK (UL(0xf) << ID_AA64MMFR1_VMIDBits_SHIFT) #define ID_AA64MMFR1_VMIDBits_VAL(x) ((x) & ID_AA64MMFR1_VMIDBits_MASK) #define ID_AA64MMFR1_VMIDBits_8 (UL(0x0) << ID_AA64MMFR1_VMIDBits_SHIFT) #define ID_AA64MMFR1_VMIDBits_16 (UL(0x2) << ID_AA64MMFR1_VMIDBits_SHIFT) #define ID_AA64MMFR1_VH_SHIFT 8 #define ID_AA64MMFR1_VH_MASK (UL(0xf) << ID_AA64MMFR1_VH_SHIFT) #define ID_AA64MMFR1_VH_VAL(x) ((x) & ID_AA64MMFR1_VH_MASK) #define ID_AA64MMFR1_VH_NONE (UL(0x0) << ID_AA64MMFR1_VH_SHIFT) #define ID_AA64MMFR1_VH_IMPL (UL(0x1) << ID_AA64MMFR1_VH_SHIFT) #define ID_AA64MMFR1_HPDS_SHIFT 12 #define ID_AA64MMFR1_HPDS_MASK (UL(0xf) << ID_AA64MMFR1_HPDS_SHIFT) #define ID_AA64MMFR1_HPDS_VAL(x) ((x) & ID_AA64MMFR1_HPDS_MASK) #define ID_AA64MMFR1_HPDS_NONE (UL(0x0) << ID_AA64MMFR1_HPDS_SHIFT) #define ID_AA64MMFR1_HPDS_HPD (UL(0x1) << ID_AA64MMFR1_HPDS_SHIFT) #define ID_AA64MMFR1_HPDS_TTPBHA (UL(0x2) << ID_AA64MMFR1_HPDS_SHIFT) #define ID_AA64MMFR1_LO_SHIFT 16 #define ID_AA64MMFR1_LO_MASK (UL(0xf) << ID_AA64MMFR1_LO_SHIFT) #define ID_AA64MMFR1_LO_VAL(x) ((x) & ID_AA64MMFR1_LO_MASK) #define ID_AA64MMFR1_LO_NONE (UL(0x0) << ID_AA64MMFR1_LO_SHIFT) #define ID_AA64MMFR1_LO_IMPL (UL(0x1) << ID_AA64MMFR1_LO_SHIFT) #define ID_AA64MMFR1_PAN_SHIFT 20 #define ID_AA64MMFR1_PAN_MASK (UL(0xf) << ID_AA64MMFR1_PAN_SHIFT) #define ID_AA64MMFR1_PAN_VAL(x) ((x) & ID_AA64MMFR1_PAN_MASK) #define ID_AA64MMFR1_PAN_NONE (UL(0x0) << ID_AA64MMFR1_PAN_SHIFT) #define ID_AA64MMFR1_PAN_IMPL (UL(0x1) << ID_AA64MMFR1_PAN_SHIFT) #define ID_AA64MMFR1_PAN_ATS1E1 (UL(0x2) << ID_AA64MMFR1_PAN_SHIFT) #define ID_AA64MMFR1_SpecSEI_SHIFT 24 #define ID_AA64MMFR1_SpecSEI_MASK (UL(0xf) << ID_AA64MMFR1_SpecSEI_SHIFT) #define ID_AA64MMFR1_SpecSEI_VAL(x) ((x) & ID_AA64MMFR1_SpecSEI_MASK) #define ID_AA64MMFR1_SpecSEI_NONE (UL(0x0) << ID_AA64MMFR1_SpecSEI_SHIFT) #define ID_AA64MMFR1_SpecSEI_IMPL (UL(0x1) << ID_AA64MMFR1_SpecSEI_SHIFT) #define ID_AA64MMFR1_XNX_SHIFT 28 #define ID_AA64MMFR1_XNX_MASK (UL(0xf) << ID_AA64MMFR1_XNX_SHIFT) #define ID_AA64MMFR1_XNX_VAL(x) ((x) & ID_AA64MMFR1_XNX_MASK) #define ID_AA64MMFR1_XNX_NONE (UL(0x0) << ID_AA64MMFR1_XNX_SHIFT) #define ID_AA64MMFR1_XNX_IMPL (UL(0x1) << ID_AA64MMFR1_XNX_SHIFT) /* ID_AA64MMFR2_EL1 */ #define ID_AA64MMFR2_EL1 MRS_REG(ID_AA64MMFR2_EL1) #define ID_AA64MMFR2_EL1_op0 0x3 #define ID_AA64MMFR2_EL1_op1 0x0 #define ID_AA64MMFR2_EL1_CRn 0x0 #define ID_AA64MMFR2_EL1_CRm 0x7 #define ID_AA64MMFR2_EL1_op2 0x2 #define ID_AA64MMFR2_CnP_SHIFT 0 #define ID_AA64MMFR2_CnP_MASK (UL(0xf) << ID_AA64MMFR2_CnP_SHIFT) #define ID_AA64MMFR2_CnP_VAL(x) ((x) & ID_AA64MMFR2_CnP_MASK) #define ID_AA64MMFR2_CnP_NONE (UL(0x0) << ID_AA64MMFR2_CnP_SHIFT) #define ID_AA64MMFR2_CnP_IMPL (UL(0x1) << ID_AA64MMFR2_CnP_SHIFT) #define ID_AA64MMFR2_UAO_SHIFT 4 #define ID_AA64MMFR2_UAO_MASK (UL(0xf) << ID_AA64MMFR2_UAO_SHIFT) #define ID_AA64MMFR2_UAO_VAL(x) ((x) & ID_AA64MMFR2_UAO_MASK) #define ID_AA64MMFR2_UAO_NONE (UL(0x0) << ID_AA64MMFR2_UAO_SHIFT) #define ID_AA64MMFR2_UAO_IMPL (UL(0x1) << ID_AA64MMFR2_UAO_SHIFT) #define ID_AA64MMFR2_LSM_SHIFT 8 #define ID_AA64MMFR2_LSM_MASK (UL(0xf) << ID_AA64MMFR2_LSM_SHIFT) #define ID_AA64MMFR2_LSM_VAL(x) ((x) & ID_AA64MMFR2_LSM_MASK) #define ID_AA64MMFR2_LSM_NONE (UL(0x0) << ID_AA64MMFR2_LSM_SHIFT) #define ID_AA64MMFR2_LSM_IMPL (UL(0x1) << ID_AA64MMFR2_LSM_SHIFT) #define ID_AA64MMFR2_IESB_SHIFT 12 #define ID_AA64MMFR2_IESB_MASK (UL(0xf) << ID_AA64MMFR2_IESB_SHIFT) #define ID_AA64MMFR2_IESB_VAL(x) ((x) & ID_AA64MMFR2_IESB_MASK) #define ID_AA64MMFR2_IESB_NONE (UL(0x0) << ID_AA64MMFR2_IESB_SHIFT) #define ID_AA64MMFR2_IESB_IMPL (UL(0x1) << ID_AA64MMFR2_IESB_SHIFT) #define ID_AA64MMFR2_VARange_SHIFT 16 #define ID_AA64MMFR2_VARange_MASK (UL(0xf) << ID_AA64MMFR2_VARange_SHIFT) #define ID_AA64MMFR2_VARange_VAL(x) ((x) & ID_AA64MMFR2_VARange_MASK) #define ID_AA64MMFR2_VARange_48 (UL(0x0) << ID_AA64MMFR2_VARange_SHIFT) #define ID_AA64MMFR2_VARange_52 (UL(0x1) << ID_AA64MMFR2_VARange_SHIFT) #define ID_AA64MMFR2_CCIDX_SHIFT 20 #define ID_AA64MMFR2_CCIDX_MASK (UL(0xf) << ID_AA64MMFR2_CCIDX_SHIFT) #define ID_AA64MMFR2_CCIDX_VAL(x) ((x) & ID_AA64MMFR2_CCIDX_MASK) #define ID_AA64MMFR2_CCIDX_32 (UL(0x0) << ID_AA64MMFR2_CCIDX_SHIFT) #define ID_AA64MMFR2_CCIDX_64 (UL(0x1) << ID_AA64MMFR2_CCIDX_SHIFT) #define ID_AA64MMFR2_NV_SHIFT 24 #define ID_AA64MMFR2_NV_MASK (UL(0xf) << ID_AA64MMFR2_NV_SHIFT) #define ID_AA64MMFR2_NV_VAL(x) ((x) & ID_AA64MMFR2_NV_MASK) #define ID_AA64MMFR2_NV_NONE (UL(0x0) << ID_AA64MMFR2_NV_SHIFT) #define ID_AA64MMFR2_NV_8_3 (UL(0x1) << ID_AA64MMFR2_NV_SHIFT) #define ID_AA64MMFR2_NV_8_4 (UL(0x2) << ID_AA64MMFR2_NV_SHIFT) #define ID_AA64MMFR2_ST_SHIFT 28 #define ID_AA64MMFR2_ST_MASK (UL(0xf) << ID_AA64MMFR2_ST_SHIFT) #define ID_AA64MMFR2_ST_VAL(x) ((x) & ID_AA64MMFR2_ST_MASK) #define ID_AA64MMFR2_ST_NONE (UL(0x0) << ID_AA64MMFR2_ST_SHIFT) #define ID_AA64MMFR2_ST_IMPL (UL(0x1) << ID_AA64MMFR2_ST_SHIFT) #define ID_AA64MMFR2_AT_SHIFT 32 #define ID_AA64MMFR2_AT_MASK (UL(0xf) << ID_AA64MMFR2_AT_SHIFT) #define ID_AA64MMFR2_AT_VAL(x) ((x) & ID_AA64MMFR2_AT_MASK) #define ID_AA64MMFR2_AT_NONE (UL(0x0) << ID_AA64MMFR2_AT_SHIFT) #define ID_AA64MMFR2_AT_IMPL (UL(0x1) << ID_AA64MMFR2_AT_SHIFT) #define ID_AA64MMFR2_IDS_SHIFT 36 #define ID_AA64MMFR2_IDS_MASK (UL(0xf) << ID_AA64MMFR2_IDS_SHIFT) #define ID_AA64MMFR2_IDS_VAL(x) ((x) & ID_AA64MMFR2_IDS_MASK) #define ID_AA64MMFR2_IDS_NONE (UL(0x0) << ID_AA64MMFR2_IDS_SHIFT) #define ID_AA64MMFR2_IDS_IMPL (UL(0x1) << ID_AA64MMFR2_IDS_SHIFT) #define ID_AA64MMFR2_FWB_SHIFT 40 #define ID_AA64MMFR2_FWB_MASK (UL(0xf) << ID_AA64MMFR2_FWB_SHIFT) #define ID_AA64MMFR2_FWB_VAL(x) ((x) & ID_AA64MMFR2_FWB_MASK) #define ID_AA64MMFR2_FWB_NONE (UL(0x0) << ID_AA64MMFR2_FWB_SHIFT) #define ID_AA64MMFR2_FWB_IMPL (UL(0x1) << ID_AA64MMFR2_FWB_SHIFT) #define ID_AA64MMFR2_TTL_SHIFT 48 #define ID_AA64MMFR2_TTL_MASK (UL(0xf) << ID_AA64MMFR2_TTL_SHIFT) #define ID_AA64MMFR2_TTL_VAL(x) ((x) & ID_AA64MMFR2_TTL_MASK) #define ID_AA64MMFR2_TTL_NONE (UL(0x0) << ID_AA64MMFR2_TTL_SHIFT) #define ID_AA64MMFR2_TTL_IMPL (UL(0x1) << ID_AA64MMFR2_TTL_SHIFT) #define ID_AA64MMFR2_BBM_SHIFT 52 #define ID_AA64MMFR2_BBM_MASK (UL(0xf) << ID_AA64MMFR2_BBM_SHIFT) #define ID_AA64MMFR2_BBM_VAL(x) ((x) & ID_AA64MMFR2_BBM_MASK) #define ID_AA64MMFR2_BBM_LEVEL0 (UL(0x0) << ID_AA64MMFR2_BBM_SHIFT) #define ID_AA64MMFR2_BBM_LEVEL1 (UL(0x1) << ID_AA64MMFR2_BBM_SHIFT) #define ID_AA64MMFR2_BBM_LEVEL2 (UL(0x2) << ID_AA64MMFR2_BBM_SHIFT) #define ID_AA64MMFR2_EVT_SHIFT 56 #define ID_AA64MMFR2_EVT_MASK (UL(0xf) << ID_AA64MMFR2_EVT_SHIFT) #define ID_AA64MMFR2_EVT_VAL(x) ((x) & ID_AA64MMFR2_EVT_MASK) #define ID_AA64MMFR2_EVT_NONE (UL(0x0) << ID_AA64MMFR2_EVT_SHIFT) #define ID_AA64MMFR2_EVT_8_2 (UL(0x1) << ID_AA64MMFR2_EVT_SHIFT) #define ID_AA64MMFR2_EVT_8_5 (UL(0x2) << ID_AA64MMFR2_EVT_SHIFT) #define ID_AA64MMFR2_E0PD_SHIFT 60 #define ID_AA64MMFR2_E0PD_MASK (UL(0xf) << ID_AA64MMFR2_E0PD_SHIFT) #define ID_AA64MMFR2_E0PD_VAL(x) ((x) & ID_AA64MMFR2_E0PD_MASK) #define ID_AA64MMFR2_E0PD_NONE (UL(0x0) << ID_AA64MMFR2_E0PD_SHIFT) #define ID_AA64MMFR2_E0PD_IMPL (UL(0x1) << ID_AA64MMFR2_E0PD_SHIFT) /* ID_AA64PFR0_EL1 */ #define ID_AA64PFR0_EL1 MRS_REG(ID_AA64PFR0_EL1) #define ID_AA64PFR0_EL1_op0 0x3 #define ID_AA64PFR0_EL1_op1 0x0 #define ID_AA64PFR0_EL1_CRn 0x0 #define ID_AA64PFR0_EL1_CRm 0x4 #define ID_AA64PFR0_EL1_op2 0x0 #define ID_AA64PFR0_EL0_SHIFT 0 #define ID_AA64PFR0_EL0_MASK (UL(0xf) << ID_AA64PFR0_EL0_SHIFT) #define ID_AA64PFR0_EL0_VAL(x) ((x) & ID_AA64PFR0_EL0_MASK) #define ID_AA64PFR0_EL0_64 (UL(0x1) << ID_AA64PFR0_EL0_SHIFT) #define ID_AA64PFR0_EL0_64_32 (UL(0x2) << ID_AA64PFR0_EL0_SHIFT) #define ID_AA64PFR0_EL1_SHIFT 4 #define ID_AA64PFR0_EL1_MASK (UL(0xf) << ID_AA64PFR0_EL1_SHIFT) #define ID_AA64PFR0_EL1_VAL(x) ((x) & ID_AA64PFR0_EL1_MASK) #define ID_AA64PFR0_EL1_64 (UL(0x1) << ID_AA64PFR0_EL1_SHIFT) #define ID_AA64PFR0_EL1_64_32 (UL(0x2) << ID_AA64PFR0_EL1_SHIFT) #define ID_AA64PFR0_EL2_SHIFT 8 #define ID_AA64PFR0_EL2_MASK (UL(0xf) << ID_AA64PFR0_EL2_SHIFT) #define ID_AA64PFR0_EL2_VAL(x) ((x) & ID_AA64PFR0_EL2_MASK) #define ID_AA64PFR0_EL2_NONE (UL(0x0) << ID_AA64PFR0_EL2_SHIFT) #define ID_AA64PFR0_EL2_64 (UL(0x1) << ID_AA64PFR0_EL2_SHIFT) #define ID_AA64PFR0_EL2_64_32 (UL(0x2) << ID_AA64PFR0_EL2_SHIFT) #define ID_AA64PFR0_EL3_SHIFT 12 #define ID_AA64PFR0_EL3_MASK (UL(0xf) << ID_AA64PFR0_EL3_SHIFT) #define ID_AA64PFR0_EL3_VAL(x) ((x) & ID_AA64PFR0_EL3_MASK) #define ID_AA64PFR0_EL3_NONE (UL(0x0) << ID_AA64PFR0_EL3_SHIFT) #define ID_AA64PFR0_EL3_64 (UL(0x1) << ID_AA64PFR0_EL3_SHIFT) #define ID_AA64PFR0_EL3_64_32 (UL(0x2) << ID_AA64PFR0_EL3_SHIFT) #define ID_AA64PFR0_FP_SHIFT 16 #define ID_AA64PFR0_FP_MASK (UL(0xf) << ID_AA64PFR0_FP_SHIFT) #define ID_AA64PFR0_FP_VAL(x) ((x) & ID_AA64PFR0_FP_MASK) #define ID_AA64PFR0_FP_IMPL (UL(0x0) << ID_AA64PFR0_FP_SHIFT) #define ID_AA64PFR0_FP_HP (UL(0x1) << ID_AA64PFR0_FP_SHIFT) #define ID_AA64PFR0_FP_NONE (UL(0xf) << ID_AA64PFR0_FP_SHIFT) #define ID_AA64PFR0_AdvSIMD_SHIFT 20 #define ID_AA64PFR0_AdvSIMD_MASK (UL(0xf) << ID_AA64PFR0_AdvSIMD_SHIFT) #define ID_AA64PFR0_AdvSIMD_VAL(x) ((x) & ID_AA64PFR0_AdvSIMD_MASK) #define ID_AA64PFR0_AdvSIMD_IMPL (UL(0x0) << ID_AA64PFR0_AdvSIMD_SHIFT) #define ID_AA64PFR0_AdvSIMD_HP (UL(0x1) << ID_AA64PFR0_AdvSIMD_SHIFT) #define ID_AA64PFR0_AdvSIMD_NONE (UL(0xf) << ID_AA64PFR0_AdvSIMD_SHIFT) #define ID_AA64PFR0_GIC_BITS 0x4 /* Number of bits in GIC field */ #define ID_AA64PFR0_GIC_SHIFT 24 #define ID_AA64PFR0_GIC_MASK (UL(0xf) << ID_AA64PFR0_GIC_SHIFT) #define ID_AA64PFR0_GIC_VAL(x) ((x) & ID_AA64PFR0_GIC_MASK) #define ID_AA64PFR0_GIC_CPUIF_NONE (UL(0x0) << ID_AA64PFR0_GIC_SHIFT) #define ID_AA64PFR0_GIC_CPUIF_EN (UL(0x1) << ID_AA64PFR0_GIC_SHIFT) #define ID_AA64PFR0_RAS_SHIFT 28 #define ID_AA64PFR0_RAS_MASK (UL(0xf) << ID_AA64PFR0_RAS_SHIFT) #define ID_AA64PFR0_RAS_VAL(x) ((x) & ID_AA64PFR0_RAS_MASK) #define ID_AA64PFR0_RAS_NONE (UL(0x0) << ID_AA64PFR0_RAS_SHIFT) #define ID_AA64PFR0_RAS_IMPL (UL(0x1) << ID_AA64PFR0_RAS_SHIFT) #define ID_AA64PFR0_RAS_8_4 (UL(0x2) << ID_AA64PFR0_RAS_SHIFT) #define ID_AA64PFR0_SVE_SHIFT 32 #define ID_AA64PFR0_SVE_MASK (UL(0xf) << ID_AA64PFR0_SVE_SHIFT) #define ID_AA64PFR0_SVE_VAL(x) ((x) & ID_AA64PFR0_SVE_MASK) #define ID_AA64PFR0_SVE_NONE (UL(0x0) << ID_AA64PFR0_SVE_SHIFT) #define ID_AA64PFR0_SVE_IMPL (UL(0x1) << ID_AA64PFR0_SVE_SHIFT) #define ID_AA64PFR0_SEL2_SHIFT 36 #define ID_AA64PFR0_SEL2_MASK (UL(0xf) << ID_AA64PFR0_SEL2_SHIFT) #define ID_AA64PFR0_SEL2_VAL(x) ((x) & ID_AA64PFR0_SEL2_MASK) #define ID_AA64PFR0_SEL2_NONE (UL(0x0) << ID_AA64PFR0_SEL2_SHIFT) #define ID_AA64PFR0_SEL2_IMPL (UL(0x1) << ID_AA64PFR0_SEL2_SHIFT) #define ID_AA64PFR0_MPAM_SHIFT 40 #define ID_AA64PFR0_MPAM_MASK (UL(0xf) << ID_AA64PFR0_MPAM_SHIFT) #define ID_AA64PFR0_MPAM_VAL(x) ((x) & ID_AA64PFR0_MPAM_MASK) #define ID_AA64PFR0_MPAM_NONE (UL(0x0) << ID_AA64PFR0_MPAM_SHIFT) #define ID_AA64PFR0_MPAM_IMPL (UL(0x1) << ID_AA64PFR0_MPAM_SHIFT) #define ID_AA64PFR0_AMU_SHIFT 44 #define ID_AA64PFR0_AMU_MASK (UL(0xf) << ID_AA64PFR0_AMU_SHIFT) #define ID_AA64PFR0_AMU_VAL(x) ((x) & ID_AA64PFR0_AMU_MASK) #define ID_AA64PFR0_AMU_NONE (UL(0x0) << ID_AA64PFR0_AMU_SHIFT) #define ID_AA64PFR0_AMU_V1 (UL(0x1) << ID_AA64PFR0_AMU_SHIFT) #define ID_AA64PFR0_DIT_SHIFT 48 #define ID_AA64PFR0_DIT_MASK (UL(0xf) << ID_AA64PFR0_DIT_SHIFT) #define ID_AA64PFR0_DIT_VAL(x) ((x) & ID_AA64PFR0_DIT_MASK) #define ID_AA64PFR0_DIT_NONE (UL(0x0) << ID_AA64PFR0_DIT_SHIFT) #define ID_AA64PFR0_DIT_PSTATE (UL(0x1) << ID_AA64PFR0_DIT_SHIFT) #define ID_AA64PFR0_CSV2_SHIFT 56 #define ID_AA64PFR0_CSV2_MASK (UL(0xf) << ID_AA64PFR0_CSV2_SHIFT) #define ID_AA64PFR0_CSV2_VAL(x) ((x) & ID_AA64PFR0_CSV2_MASK) #define ID_AA64PFR0_CSV2_NONE (UL(0x0) << ID_AA64PFR0_CSV2_SHIFT) #define ID_AA64PFR0_CSV2_ISOLATED (UL(0x1) << ID_AA64PFR0_CSV2_SHIFT) #define ID_AA64PFR0_CSV2_SCXTNUM (UL(0x2) << ID_AA64PFR0_CSV2_SHIFT) #define ID_AA64PFR0_CSV3_SHIFT 60 #define ID_AA64PFR0_CSV3_MASK (UL(0xf) << ID_AA64PFR0_CSV3_SHIFT) #define ID_AA64PFR0_CSV3_VAL(x) ((x) & ID_AA64PFR0_CSV3_MASK) #define ID_AA64PFR0_CSV3_NONE (UL(0x0) << ID_AA64PFR0_CSV3_SHIFT) #define ID_AA64PFR0_CSV3_ISOLATED (UL(0x1) << ID_AA64PFR0_CSV3_SHIFT) /* ID_AA64PFR1_EL1 */ #define ID_AA64PFR1_EL1 MRS_REG(ID_AA64PFR1_EL1) #define ID_AA64PFR1_EL1_op0 0x3 #define ID_AA64PFR1_EL1_op1 0x0 #define ID_AA64PFR1_EL1_CRn 0x0 #define ID_AA64PFR1_EL1_CRm 0x4 #define ID_AA64PFR1_EL1_op2 0x1 #define ID_AA64PFR1_BT_SHIFT 0 #define ID_AA64PFR1_BT_MASK (UL(0xf) << ID_AA64PFR1_BT_SHIFT) #define ID_AA64PFR1_BT_VAL(x) ((x) & ID_AA64PFR1_BT_MASK) #define ID_AA64PFR1_BT_NONE (UL(0x0) << ID_AA64PFR1_BT_SHIFT) #define ID_AA64PFR1_BT_IMPL (UL(0x1) << ID_AA64PFR1_BT_SHIFT) #define ID_AA64PFR1_SSBS_SHIFT 4 #define ID_AA64PFR1_SSBS_MASK (UL(0xf) << ID_AA64PFR1_SSBS_SHIFT) #define ID_AA64PFR1_SSBS_VAL(x) ((x) & ID_AA64PFR1_SSBS_MASK) #define ID_AA64PFR1_SSBS_NONE (UL(0x0) << ID_AA64PFR1_SSBS_SHIFT) #define ID_AA64PFR1_SSBS_PSTATE (UL(0x1) << ID_AA64PFR1_SSBS_SHIFT) #define ID_AA64PFR1_SSBS_PSTATE_MSR (UL(0x2) << ID_AA64PFR1_SSBS_SHIFT) #define ID_AA64PFR1_MTE_SHIFT 8 #define ID_AA64PFR1_MTE_MASK (UL(0xf) << ID_AA64PFR1_MTE_SHIFT) #define ID_AA64PFR1_MTE_VAL(x) ((x) & ID_AA64PFR1_MTE_MASK) #define ID_AA64PFR1_MTE_NONE (UL(0x0) << ID_AA64PFR1_MTE_SHIFT) #define ID_AA64PFR1_MTE_IMPL_EL0 (UL(0x1) << ID_AA64PFR1_MTE_SHIFT) #define ID_AA64PFR1_MTE_IMPL (UL(0x2) << ID_AA64PFR1_MTE_SHIFT) #define ID_AA64PFR1_RAS_frac_SHIFT 12 #define ID_AA64PFR1_RAS_frac_MASK (UL(0xf) << ID_AA64PFR1_RAS_frac_SHIFT) #define ID_AA64PFR1_RAS_frac_VAL(x) ((x) & ID_AA64PFR1_RAS_frac_MASK) #define ID_AA64PFR1_RAS_frac_V1 (UL(0x0) << ID_AA64PFR1_RAS_frac_SHIFT) #define ID_AA64PFR1_RAS_frac_V2 (UL(0x1) << ID_AA64PFR1_RAS_frac_SHIFT) /* ID_ISAR5_EL1 */ #define ID_ISAR5_EL1 MRS_REG(ID_ISAR5_EL1) #define ID_ISAR5_EL1_op0 0x3 #define ID_ISAR5_EL1_op1 0x0 #define ID_ISAR5_EL1_CRn 0x0 #define ID_ISAR5_EL1_CRm 0x2 #define ID_ISAR5_EL1_op2 0x5 #define ID_ISAR5_SEVL_SHIFT 0 #define ID_ISAR5_SEVL_MASK (UL(0xf) << ID_ISAR5_SEVL_SHIFT) #define ID_ISAR5_SEVL_VAL(x) ((x) & ID_ISAR5_SEVL_MASK) #define ID_ISAR5_SEVL_NOP (UL(0x0) << ID_ISAR5_SEVL_SHIFT) #define ID_ISAR5_SEVL_IMPL (UL(0x1) << ID_ISAR5_SEVL_SHIFT) #define ID_ISAR5_AES_SHIFT 4 #define ID_ISAR5_AES_MASK (UL(0xf) << ID_ISAR5_AES_SHIFT) #define ID_ISAR5_AES_VAL(x) ((x) & ID_ISAR5_AES_MASK) #define ID_ISAR5_AES_NONE (UL(0x0) << ID_ISAR5_AES_SHIFT) #define ID_ISAR5_AES_BASE (UL(0x1) << ID_ISAR5_AES_SHIFT) #define ID_ISAR5_AES_VMULL (UL(0x2) << ID_ISAR5_AES_SHIFT) #define ID_ISAR5_SHA1_SHIFT 8 #define ID_ISAR5_SHA1_MASK (UL(0xf) << ID_ISAR5_SHA1_SHIFT) #define ID_ISAR5_SHA1_VAL(x) ((x) & ID_ISAR5_SHA1_MASK) #define ID_ISAR5_SHA1_NONE (UL(0x0) << ID_ISAR5_SHA1_SHIFT) #define ID_ISAR5_SHA1_IMPL (UL(0x1) << ID_ISAR5_SHA1_SHIFT) #define ID_ISAR5_SHA2_SHIFT 12 #define ID_ISAR5_SHA2_MASK (UL(0xf) << ID_ISAR5_SHA2_SHIFT) #define ID_ISAR5_SHA2_VAL(x) ((x) & ID_ISAR5_SHA2_MASK) #define ID_ISAR5_SHA2_NONE (UL(0x0) << ID_ISAR5_SHA2_SHIFT) #define ID_ISAR5_SHA2_IMPL (UL(0x1) << ID_ISAR5_SHA2_SHIFT) #define ID_ISAR5_CRC32_SHIFT 16 #define ID_ISAR5_CRC32_MASK (UL(0xf) << ID_ISAR5_CRC32_SHIFT) #define ID_ISAR5_CRC32_VAL(x) ((x) & ID_ISAR5_CRC32_MASK) #define ID_ISAR5_CRC32_NONE (UL(0x0) << ID_ISAR5_CRC32_SHIFT) #define ID_ISAR5_CRC32_IMPL (UL(0x1) << ID_ISAR5_CRC32_SHIFT) #define ID_ISAR5_RDM_SHIFT 24 #define ID_ISAR5_RDM_MASK (UL(0xf) << ID_ISAR5_RDM_SHIFT) #define ID_ISAR5_RDM_VAL(x) ((x) & ID_ISAR5_RDM_MASK) #define ID_ISAR5_RDM_NONE (UL(0x0) << ID_ISAR5_RDM_SHIFT) #define ID_ISAR5_RDM_IMPL (UL(0x1) << ID_ISAR5_RDM_SHIFT) #define ID_ISAR5_VCMA_SHIFT 28 #define ID_ISAR5_VCMA_MASK (UL(0xf) << ID_ISAR5_VCMA_SHIFT) #define ID_ISAR5_VCMA_VAL(x) ((x) & ID_ISAR5_VCMA_MASK) #define ID_ISAR5_VCMA_NONE (UL(0x0) << ID_ISAR5_VCMA_SHIFT) #define ID_ISAR5_VCMA_IMPL (UL(0x1) << ID_ISAR5_VCMA_SHIFT) /* PMBIDR_EL1 */ #define PMBIDR_EL1 MRS_REG(PMBIDR_EL1) #define PMBIDR_EL1_op0 0x3 #define PMBIDR_EL1_op1 0x0 #define PMBIDR_EL1_CRn 0x9 #define PMBIDR_EL1_CRm 0xa #define PMBIDR_EL1_op2 0x7 #define PMBIDR_Align_SHIFT 0 #define PMBIDR_Align_MASK (UL(0xf) << PMBIDR_Align_SHIFT) #define PMBIDR_P_SHIFT 4 #define PMBIDR_P (UL(0x1) << PMBIDR_P_SHIFT) #define PMBIDR_F_SHIFT 5 #define PMBIDR_F (UL(0x1) << PMBIDR_F_SHIFT) /* PMBLIMITR_EL1 */ #define PMBLIMITR_EL1 MRS_REG(PMBLIMITR_EL1) #define PMBLIMITR_EL1_op0 0x3 #define PMBLIMITR_EL1_op1 0x0 #define PMBLIMITR_EL1_CRn 0x9 #define PMBLIMITR_EL1_CRm 0xa #define PMBLIMITR_EL1_op2 0x0 #define PMBLIMITR_E_SHIFT 0 #define PMBLIMITR_E (UL(0x1) << PMBLIMITR_E_SHIFT) #define PMBLIMITR_FM_SHIFT 1 #define PMBLIMITR_FM_MASK (UL(0x3) << PMBLIMITR_FM_SHIFT) #define PMBLIMITR_PMFZ_SHIFT 5 #define PMBLIMITR_PMFZ (UL(0x1) << PMBLIMITR_PMFZ_SHIFT) #define PMBLIMITR_LIMIT_SHIFT 12 #define PMBLIMITR_LIMIT_MASK \ (UL(0xfffffffffffff) << PMBLIMITR_LIMIT_SHIFT) /* PMBPTR_EL1 */ #define PMBPTR_EL1 MRS_REG(PMBPTR_EL1) #define PMBPTR_EL1_op0 0x3 #define PMBPTR_EL1_op1 0x0 #define PMBPTR_EL1_CRn 0x9 #define PMBPTR_EL1_CRm 0xa #define PMBPTR_EL1_op2 0x1 #define PMBPTR_PTR_SHIFT 0 #define PMBPTR_PTR_MASK \ (UL(0xffffffffffffffff) << PMBPTR_PTR_SHIFT) /* PMBSR_EL1 */ #define PMBSR_EL1 MRS_REG(PMBSR_EL1) #define PMBSR_EL1_op0 0x3 #define PMBSR_EL1_op1 0x0 #define PMBSR_EL1_CRn 0x9 #define PMBSR_EL1_CRm 0xa #define PMBSR_EL1_op2 0x3 #define PMBSR_MSS_SHIFT 0 #define PMBSR_MSS_MASK (UL(0xffff) << PMBSR_MSS_SHIFT) #define PMBSR_COLL_SHIFT 16 #define PMBSR_COLL (UL(0x1) << PMBSR_COLL_SHIFT) #define PMBSR_S_SHIFT 17 #define PMBSR_S (UL(0x1) << PMBSR_S_SHIFT) #define PMBSR_EA_SHIFT 18 #define PMBSR_EA (UL(0x1) << PMBSR_EA_SHIFT) #define PMBSR_DL_SHIFT 19 #define PMBSR_DL (UL(0x1) << PMBSR_DL_SHIFT) #define PMBSR_EC_SHIFT 26 #define PMBSR_EC_MASK (UL(0x3f) << PMBSR_EC_SHIFT) /* PMSCR_EL1 */ #define PMSCR_EL1 MRS_REG(PMSCR_EL1) #define PMSCR_EL1_op0 0x3 #define PMSCR_EL1_op1 0x0 #define PMSCR_EL1_CRn 0x9 #define PMSCR_EL1_CRm 0x9 #define PMSCR_EL1_op2 0x0 #define PMSCR_E0SPE_SHIFT 0 #define PMSCR_E0SPE (UL(0x1) << PMSCR_E0SPE_SHIFT) #define PMSCR_E1SPE_SHIFT 1 #define PMSCR_E1SPE (UL(0x1) << PMSCR_E1SPE_SHIFT) #define PMSCR_CX_SHIFT 3 #define PMSCR_CX (UL(0x1) << PMSCR_CX_SHIFT) #define PMSCR_PA_SHIFT 4 #define PMSCR_PA (UL(0x1) << PMSCR_PA_SHIFT) #define PMSCR_TS_SHIFT 5 #define PMSCR_TS (UL(0x1) << PMSCR_TS_SHIFT) #define PMSCR_PCT_SHIFT 6 #define PMSCR_PCT_MASK (UL(0x3) << PMSCR_PCT_SHIFT) /* PMSEVFR_EL1 */ #define PMSEVFR_EL1 MRS_REG(PMSEVFR_EL1) #define PMSEVFR_EL1_op0 0x3 #define PMSEVFR_EL1_op1 0x0 #define PMSEVFR_EL1_CRn 0x9 #define PMSEVFR_EL1_CRm 0x9 #define PMSEVFR_EL1_op2 0x5 /* PMSFCR_EL1 */ #define PMSFCR_EL1 MRS_REG(PMSFCR_EL1) #define PMSFCR_EL1_op0 0x3 #define PMSFCR_EL1_op1 0x0 #define PMSFCR_EL1_CRn 0x9 #define PMSFCR_EL1_CRm 0x9 #define PMSFCR_EL1_op2 0x4 #define PMSFCR_FE_SHIFT 0 #define PMSFCR_FE (UL(0x1) << PMSFCR_FE_SHIFT) #define PMSFCR_FT_SHIFT 1 #define PMSFCR_FT (UL(0x1) << PMSFCR_FT_SHIFT) #define PMSFCR_FL_SHIFT 2 #define PMSFCR_FL (UL(0x1) << PMSFCR_FL_SHIFT) #define PMSFCR_FnE_SHIFT 3 #define PMSFCR_FnE (UL(0x1) << PMSFCR_FnE_SHIFT) #define PMSFCR_B_SHIFT 16 #define PMSFCR_B (UL(0x1) << PMSFCR_B_SHIFT) #define PMSFCR_LD_SHIFT 17 #define PMSFCR_LD (UL(0x1) << PMSFCR_LD_SHIFT) #define PMSFCR_ST_SHIFT 18 #define PMSFCR_ST (UL(0x1) << PMSFCR_ST_SHIFT) /* PMSICR_EL1 */ #define PMSICR_EL1 MRS_REG(PMSICR_EL1) #define PMSICR_EL1_op0 0x3 #define PMSICR_EL1_op1 0x0 #define PMSICR_EL1_CRn 0x9 #define PMSICR_EL1_CRm 0x9 #define PMSICR_EL1_op2 0x2 #define PMSICR_COUNT_SHIFT 0 #define PMSICR_COUNT_MASK (UL(0xffffffff) << PMSICR_COUNT_SHIFT) #define PMSICR_ECOUNT_SHIFT 56 #define PMSICR_ECOUNT_MASK (UL(0xff) << PMSICR_ECOUNT_SHIFT) /* PMSIDR_EL1 */ #define PMSIDR_EL1 MRS_REG(PMSIDR_EL1) #define PMSIDR_EL1_op0 0x3 #define PMSIDR_EL1_op1 0x0 #define PMSIDR_EL1_CRn 0x9 #define PMSIDR_EL1_CRm 0x9 #define PMSIDR_EL1_op2 0x7 #define PMSIDR_FE_SHIFT 0 #define PMSIDR_FE (UL(0x1) << PMSIDR_FE_SHIFT) #define PMSIDR_FT_SHIFT 1 #define PMSIDR_FT (UL(0x1) << PMSIDR_FT_SHIFT) #define PMSIDR_FL_SHIFT 2 #define PMSIDR_FL (UL(0x1) << PMSIDR_FL_SHIFT) #define PMSIDR_ArchInst_SHIFT 3 #define PMSIDR_ArchInst (UL(0x1) << PMSIDR_ArchInst_SHIFT) #define PMSIDR_LDS_SHIFT 4 #define PMSIDR_LDS (UL(0x1) << PMSIDR_LDS_SHIFT) #define PMSIDR_ERnd_SHIFT 5 #define PMSIDR_ERnd (UL(0x1) << PMSIDR_ERnd_SHIFT) #define PMSIDR_FnE_SHIFT 6 #define PMSIDR_FnE (UL(0x1) << PMSIDR_FnE_SHIFT) #define PMSIDR_Interval_SHIFT 8 #define PMSIDR_Interval_MASK (UL(0xf) << PMSIDR_Interval_SHIFT) #define PMSIDR_MaxSize_SHIFT 12 #define PMSIDR_MaxSize_MASK (UL(0xf) << PMSIDR_MaxSize_SHIFT) #define PMSIDR_CountSize_SHIFT 16 #define PMSIDR_CountSize_MASK (UL(0xf) << PMSIDR_CountSize_SHIFT) #define PMSIDR_Format_SHIFT 20 #define PMSIDR_Format_MASK (UL(0xf) << PMSIDR_Format_SHIFT) #define PMSIDR_PBT_SHIFT 24 #define PMSIDR_PBT (UL(0x1) << PMSIDR_PBT_SHIFT) /* PMSIRR_EL1 */ #define PMSIRR_EL1 MRS_REG(PMSIRR_EL1) #define PMSIRR_EL1_op0 0x3 #define PMSIRR_EL1_op1 0x0 #define PMSIRR_EL1_CRn 0x9 #define PMSIRR_EL1_CRm 0x9 #define PMSIRR_EL1_op2 0x3 #define PMSIRR_RND_SHIFT 0 #define PMSIRR_RND (UL(0x1) << PMSIRR_RND_SHIFT) #define PMSIRR_INTERVAL_SHIFT 8 #define PMSIRR_INTERVAL_MASK (UL(0xffffff) << PMSIRR_INTERVAL_SHIFT) /* PMSLATFR_EL1 */ #define PMSLATFR_EL1 MRS_REG(PMSLATFR_EL1) #define PMSLATFR_EL1_op0 0x3 #define PMSLATFR_EL1_op1 0x0 #define PMSLATFR_EL1_CRn 0x9 #define PMSLATFR_EL1_CRm 0x9 #define PMSLATFR_EL1_op2 0x6 #define PMSLATFR_MINLAT_SHIFT 0 #define PMSLATFR_MINLAT_MASK (UL(0xfff) << PMSLATFR_MINLAT_SHIFT) /* PMSNEVFR_EL1 */ #define PMSNEVFR_EL1 MRS_REG(PMSNEVFR_EL1) #define PMSNEVFR_EL1_op0 0x3 #define PMSNEVFR_EL1_op1 0x0 #define PMSNEVFR_EL1_CRn 0x9 #define PMSNEVFR_EL1_CRm 0x9 #define PMSNEVFR_EL1_op2 0x1 /* MAIR_EL1 - Memory Attribute Indirection Register */ #define MAIR_ATTR_MASK(idx) (0xff << ((n)* 8)) #define MAIR_ATTR(attr, idx) ((attr) << ((idx) * 8)) #define MAIR_DEVICE_nGnRnE 0x00 #define MAIR_NORMAL_NC 0x44 #define MAIR_NORMAL_WT 0xbb #define MAIR_NORMAL_WB 0xff /* MDSCR_EL1 - Monitor Debug System Control Register */ #define MDSCR_SS_SHIFT 0 #define MDSCR_SS (UL(0x1) << MDSCR_SS_SHIFT) #define MDSCR_KDE_SHIFT 13 #define MDSCR_KDE (UL(0x1) << MDSCR_KDE_SHIFT) #define MDSCR_MDE_SHIFT 15 #define MDSCR_MDE (UL(0x1) << MDSCR_MDE_SHIFT) /* MVFR0_EL1 */ #define MVFR0_EL1 MRS_REG(MVFR0_EL1) #define MVFR0_EL1_op0 0x3 #define MVFR0_EL1_op1 0x0 #define MVFR0_EL1_CRn 0x0 #define MVFR0_EL1_CRm 0x3 #define MVFR0_EL1_op2 0x0 #define MVFR0_SIMDReg_SHIFT 0 #define MVFR0_SIMDReg_MASK (UL(0xf) << MVFR0_SIMDReg_SHIFT) #define MVFR0_SIMDReg_VAL(x) ((x) & MVFR0_SIMDReg_MASK) #define MVFR0_SIMDReg_NONE (UL(0x0) << MVFR0_SIMDReg_SHIFT) #define MVFR0_SIMDReg_FP (UL(0x1) << MVFR0_SIMDReg_SHIFT) #define MVFR0_SIMDReg_AdvSIMD (UL(0x2) << MVFR0_SIMDReg_SHIFT) #define MVFR0_FPSP_SHIFT 4 #define MVFR0_FPSP_MASK (UL(0xf) << MVFR0_FPSP_SHIFT) #define MVFR0_FPSP_VAL(x) ((x) & MVFR0_FPSP_MASK) #define MVFR0_FPSP_NONE (UL(0x0) << MVFR0_FPSP_SHIFT) #define MVFR0_FPSP_VFP_v2 (UL(0x1) << MVFR0_FPSP_SHIFT) #define MVFR0_FPSP_VFP_v3_v4 (UL(0x2) << MVFR0_FPSP_SHIFT) #define MVFR0_FPDP_SHIFT 8 #define MVFR0_FPDP_MASK (UL(0xf) << MVFR0_FPDP_SHIFT) #define MVFR0_FPDP_VAL(x) ((x) & MVFR0_FPDP_MASK) #define MVFR0_FPDP_NONE (UL(0x0) << MVFR0_FPDP_SHIFT) #define MVFR0_FPDP_VFP_v2 (UL(0x1) << MVFR0_FPDP_SHIFT) #define MVFR0_FPDP_VFP_v3_v4 (UL(0x2) << MVFR0_FPDP_SHIFT) #define MVFR0_FPTrap_SHIFT 12 #define MVFR0_FPTrap_MASK (UL(0xf) << MVFR0_FPTrap_SHIFT) #define MVFR0_FPTrap_VAL(x) ((x) & MVFR0_FPTrap_MASK) #define MVFR0_FPTrap_NONE (UL(0x0) << MVFR0_FPTrap_SHIFT) #define MVFR0_FPTrap_IMPL (UL(0x1) << MVFR0_FPTrap_SHIFT) #define MVFR0_FPDivide_SHIFT 16 #define MVFR0_FPDivide_MASK (UL(0xf) << MVFR0_FPDivide_SHIFT) #define MVFR0_FPDivide_VAL(x) ((x) & MVFR0_FPDivide_MASK) #define MVFR0_FPDivide_NONE (UL(0x0) << MVFR0_FPDivide_SHIFT) #define MVFR0_FPDivide_IMPL (UL(0x1) << MVFR0_FPDivide_SHIFT) #define MVFR0_FPSqrt_SHIFT 20 #define MVFR0_FPSqrt_MASK (UL(0xf) << MVFR0_FPSqrt_SHIFT) #define MVFR0_FPSqrt_VAL(x) ((x) & MVFR0_FPSqrt_MASK) #define MVFR0_FPSqrt_NONE (UL(0x0) << MVFR0_FPSqrt_SHIFT) #define MVFR0_FPSqrt_IMPL (UL(0x1) << MVFR0_FPSqrt_SHIFT) #define MVFR0_FPShVec_SHIFT 24 #define MVFR0_FPShVec_MASK (UL(0xf) << MVFR0_FPShVec_SHIFT) #define MVFR0_FPShVec_VAL(x) ((x) & MVFR0_FPShVec_MASK) #define MVFR0_FPShVec_NONE (UL(0x0) << MVFR0_FPShVec_SHIFT) #define MVFR0_FPShVec_IMPL (UL(0x1) << MVFR0_FPShVec_SHIFT) #define MVFR0_FPRound_SHIFT 28 #define MVFR0_FPRound_MASK (UL(0xf) << MVFR0_FPRound_SHIFT) #define MVFR0_FPRound_VAL(x) ((x) & MVFR0_FPRound_MASK) #define MVFR0_FPRound_NONE (UL(0x0) << MVFR0_FPRound_SHIFT) #define MVFR0_FPRound_IMPL (UL(0x1) << MVFR0_FPRound_SHIFT) /* MVFR1_EL1 */ #define MVFR1_EL1 MRS_REG(MVFR1_EL1) #define MVFR1_EL1_op0 0x3 #define MVFR1_EL1_op1 0x0 #define MVFR1_EL1_CRn 0x0 #define MVFR1_EL1_CRm 0x3 #define MVFR1_EL1_op2 0x1 #define MVFR1_FPFtZ_SHIFT 0 #define MVFR1_FPFtZ_MASK (UL(0xf) << MVFR1_FPFtZ_SHIFT) #define MVFR1_FPFtZ_VAL(x) ((x) & MVFR1_FPFtZ_MASK) #define MVFR1_FPFtZ_NONE (UL(0x0) << MVFR1_FPFtZ_SHIFT) #define MVFR1_FPFtZ_IMPL (UL(0x1) << MVFR1_FPFtZ_SHIFT) #define MVFR1_FPDNaN_SHIFT 4 #define MVFR1_FPDNaN_MASK (UL(0xf) << MVFR1_FPDNaN_SHIFT) #define MVFR1_FPDNaN_VAL(x) ((x) & MVFR1_FPDNaN_MASK) #define MVFR1_FPDNaN_NONE (UL(0x0) << MVFR1_FPDNaN_SHIFT) #define MVFR1_FPDNaN_IMPL (UL(0x1) << MVFR1_FPDNaN_SHIFT) #define MVFR1_SIMDLS_SHIFT 8 #define MVFR1_SIMDLS_MASK (UL(0xf) << MVFR1_SIMDLS_SHIFT) #define MVFR1_SIMDLS_VAL(x) ((x) & MVFR1_SIMDLS_MASK) #define MVFR1_SIMDLS_NONE (UL(0x0) << MVFR1_SIMDLS_SHIFT) #define MVFR1_SIMDLS_IMPL (UL(0x1) << MVFR1_SIMDLS_SHIFT) #define MVFR1_SIMDInt_SHIFT 12 #define MVFR1_SIMDInt_MASK (UL(0xf) << MVFR1_SIMDInt_SHIFT) #define MVFR1_SIMDInt_VAL(x) ((x) & MVFR1_SIMDInt_MASK) #define MVFR1_SIMDInt_NONE (UL(0x0) << MVFR1_SIMDInt_SHIFT) #define MVFR1_SIMDInt_IMPL (UL(0x1) << MVFR1_SIMDInt_SHIFT) #define MVFR1_SIMDSP_SHIFT 16 #define MVFR1_SIMDSP_MASK (UL(0xf) << MVFR1_SIMDSP_SHIFT) #define MVFR1_SIMDSP_VAL(x) ((x) & MVFR1_SIMDSP_MASK) #define MVFR1_SIMDSP_NONE (UL(0x0) << MVFR1_SIMDSP_SHIFT) #define MVFR1_SIMDSP_IMPL (UL(0x1) << MVFR1_SIMDSP_SHIFT) #define MVFR1_SIMDHP_SHIFT 20 #define MVFR1_SIMDHP_MASK (UL(0xf) << MVFR1_SIMDHP_SHIFT) #define MVFR1_SIMDHP_VAL(x) ((x) & MVFR1_SIMDHP_MASK) #define MVFR1_SIMDHP_NONE (UL(0x0) << MVFR1_SIMDHP_SHIFT) #define MVFR1_SIMDHP_CONV_SP (UL(0x1) << MVFR1_SIMDHP_SHIFT) #define MVFR1_SIMDHP_ARITH (UL(0x2) << MVFR1_SIMDHP_SHIFT) #define MVFR1_FPHP_SHIFT 24 #define MVFR1_FPHP_MASK (UL(0xf) << MVFR1_FPHP_SHIFT) #define MVFR1_FPHP_VAL(x) ((x) & MVFR1_FPHP_MASK) #define MVFR1_FPHP_NONE (UL(0x0) << MVFR1_FPHP_SHIFT) #define MVFR1_FPHP_CONV_SP (UL(0x1) << MVFR1_FPHP_SHIFT) #define MVFR1_FPHP_CONV_DP (UL(0x2) << MVFR1_FPHP_SHIFT) #define MVFR1_FPHP_ARITH (UL(0x3) << MVFR1_FPHP_SHIFT) #define MVFR1_SIMDFMAC_SHIFT 28 #define MVFR1_SIMDFMAC_MASK (UL(0xf) << MVFR1_SIMDFMAC_SHIFT) #define MVFR1_SIMDFMAC_VAL(x) ((x) & MVFR1_SIMDFMAC_MASK) #define MVFR1_SIMDFMAC_NONE (UL(0x0) << MVFR1_SIMDFMAC_SHIFT) #define MVFR1_SIMDFMAC_IMPL (UL(0x1) << MVFR1_SIMDFMAC_SHIFT) /* PAR_EL1 - Physical Address Register */ #define PAR_F_SHIFT 0 #define PAR_F (0x1 << PAR_F_SHIFT) #define PAR_SUCCESS(x) (((x) & PAR_F) == 0) /* When PAR_F == 0 (success) */ #define PAR_LOW_MASK 0xfff #define PAR_SH_SHIFT 7 #define PAR_SH_MASK (0x3 << PAR_SH_SHIFT) #define PAR_NS_SHIFT 9 #define PAR_NS_MASK (0x3 << PAR_NS_SHIFT) #define PAR_PA_SHIFT 12 #define PAR_PA_MASK 0x0000fffffffff000 #define PAR_ATTR_SHIFT 56 #define PAR_ATTR_MASK (0xff << PAR_ATTR_SHIFT) /* When PAR_F == 1 (aborted) */ #define PAR_FST_SHIFT 1 #define PAR_FST_MASK (0x3f << PAR_FST_SHIFT) #define PAR_PTW_SHIFT 8 #define PAR_PTW_MASK (0x1 << PAR_PTW_SHIFT) #define PAR_S_SHIFT 9 #define PAR_S_MASK (0x1 << PAR_S_SHIFT) /* SCTLR_EL1 - System Control Register */ #define SCTLR_RES1 0x30d00800 /* Reserved ARMv8.0, write 1 */ #define SCTLR_M (UL(0x1) << 0) #define SCTLR_A (UL(0x1) << 1) #define SCTLR_C (UL(0x1) << 2) #define SCTLR_SA (UL(0x1) << 3) #define SCTLR_SA0 (UL(0x1) << 4) #define SCTLR_CP15BEN (UL(0x1) << 5) #define SCTLR_nAA (UL(0x1) << 6) #define SCTLR_ITD (UL(0x1) << 7) #define SCTLR_SED (UL(0x1) << 8) #define SCTLR_UMA (UL(0x1) << 9) #define SCTLR_EnRCTX (UL(0x1) << 10) #define SCTLR_EOS (UL(0x1) << 11) #define SCTLR_I (UL(0x1) << 12) #define SCTLR_EnDB (UL(0x1) << 13) #define SCTLR_DZE (UL(0x1) << 14) #define SCTLR_UCT (UL(0x1) << 15) #define SCTLR_nTWI (UL(0x1) << 16) /* Bit 17 is reserved */ #define SCTLR_nTWE (UL(0x1) << 18) #define SCTLR_WXN (UL(0x1) << 19) #define SCTLR_TSCXT (UL(0x1) << 20) #define SCTLR_IESB (UL(0x1) << 21) #define SCTLR_EIS (UL(0x1) << 22) #define SCTLR_SPAN (UL(0x1) << 23) #define SCTLR_E0E (UL(0x1) << 24) #define SCTLR_EE (UL(0x1) << 25) #define SCTLR_UCI (UL(0x1) << 26) #define SCTLR_EnDA (UL(0x1) << 27) #define SCTLR_nTLSMD (UL(0x1) << 28) #define SCTLR_LSMAOE (UL(0x1) << 29) #define SCTLR_EnIB (UL(0x1) << 30) #define SCTLR_EnIA (UL(0x1) << 31) /* Bits 34:32 are reserved */ #define SCTLR_BT0 (UL(0x1) << 35) #define SCTLR_BT1 (UL(0x1) << 36) #define SCTLR_ITFSB (UL(0x1) << 37) #define SCTLR_TCF0_MASK (UL(0x3) << 38) #define SCTLR_TCF_MASK (UL(0x3) << 40) #define SCTLR_ATA0 (UL(0x1) << 42) #define SCTLR_ATA (UL(0x1) << 43) #define SCTLR_DSSBS (UL(0x1) << 44) #define SCTLR_TWEDEn (UL(0x1) << 45) #define SCTLR_TWEDEL_MASK (UL(0xf) << 46) /* Bits 53:50 are reserved */ #define SCTLR_EnASR (UL(0x1) << 54) #define SCTLR_EnAS0 (UL(0x1) << 55) #define SCTLR_EnALS (UL(0x1) << 56) #define SCTLR_EPAN (UL(0x1) << 57) /* SPSR_EL1 */ /* * When the exception is taken in AArch64: * M[3:2] is the exception level * M[1] is unused * M[0] is the SP select: * 0: always SP0 * 1: current ELs SP */ #define PSR_M_EL0t 0x00000000 #define PSR_M_EL1t 0x00000004 #define PSR_M_EL1h 0x00000005 #define PSR_M_EL2t 0x00000008 #define PSR_M_EL2h 0x00000009 #define PSR_M_64 0x00000000 #define PSR_M_32 0x00000010 #define PSR_M_MASK 0x0000000f #define PSR_T 0x00000020 #define PSR_AARCH32 0x00000010 #define PSR_F 0x00000040 #define PSR_I 0x00000080 #define PSR_A 0x00000100 #define PSR_D 0x00000200 #define PSR_DAIF (PSR_D | PSR_A | PSR_I | PSR_F) /* The default DAIF mask. These bits are valid in spsr_el1 and daif */ #define PSR_DAIF_DEFAULT (PSR_F) #define PSR_IL 0x00100000 #define PSR_SS 0x00200000 #define PSR_V 0x10000000 #define PSR_C 0x20000000 #define PSR_Z 0x40000000 #define PSR_N 0x80000000 #define PSR_FLAGS 0xf0000000 +/* PSR fields that can be set from 32-bit and 64-bit processes */ +#define PSR_SETTABLE_32 PSR_FLAGS +#define PSR_SETTABLE_64 (PSR_FLAGS | PSR_SS) /* TCR_EL1 - Translation Control Register */ /* Bits 63:59 are reserved */ #define TCR_TCMA1_SHIFT 58 #define TCR_TCMA1 (1UL << TCR_TCMA1_SHIFT) #define TCR_TCMA0_SHIFT 57 #define TCR_TCMA0 (1UL << TCR_TCMA0_SHIFT) #define TCR_E0PD1_SHIFT 56 #define TCR_E0PD1 (1UL << TCR_E0PD1_SHIFT) #define TCR_E0PD0_SHIFT 55 #define TCR_E0PD0 (1UL << TCR_E0PD0_SHIFT) #define TCR_NFD1_SHIFT 54 #define TCR_NFD1 (1UL << TCR_NFD1_SHIFT) #define TCR_NFD0_SHIFT 53 #define TCR_NFD0 (1UL << TCR_NFD0_SHIFT) #define TCR_TBID1_SHIFT 52 #define TCR_TBID1 (1UL << TCR_TBID1_SHIFT) #define TCR_TBID0_SHIFT 51 #define TCR_TBID0 (1UL << TCR_TBID0_SHIFT) #define TCR_HWU162_SHIFT 50 #define TCR_HWU162 (1UL << TCR_HWU162_SHIFT) #define TCR_HWU161_SHIFT 49 #define TCR_HWU161 (1UL << TCR_HWU161_SHIFT) #define TCR_HWU160_SHIFT 48 #define TCR_HWU160 (1UL << TCR_HWU160_SHIFT) #define TCR_HWU159_SHIFT 47 #define TCR_HWU159 (1UL << TCR_HWU159_SHIFT) #define TCR_HWU1 \ (TCR_HWU159 | TCR_HWU160 | TCR_HWU161 | TCR_HWU162) #define TCR_HWU062_SHIFT 46 #define TCR_HWU062 (1UL << TCR_HWU062_SHIFT) #define TCR_HWU061_SHIFT 45 #define TCR_HWU061 (1UL << TCR_HWU061_SHIFT) #define TCR_HWU060_SHIFT 44 #define TCR_HWU060 (1UL << TCR_HWU060_SHIFT) #define TCR_HWU059_SHIFT 43 #define TCR_HWU059 (1UL << TCR_HWU059_SHIFT) #define TCR_HWU0 \ (TCR_HWU059 | TCR_HWU060 | TCR_HWU061 | TCR_HWU062) #define TCR_HPD1_SHIFT 42 #define TCR_HPD1 (1UL << TCR_HPD1_SHIFT) #define TCR_HPD0_SHIFT 41 #define TCR_HPD0 (1UL << TCR_HPD0_SHIFT) #define TCR_HD_SHIFT 40 #define TCR_HD (1UL << TCR_HD_SHIFT) #define TCR_HA_SHIFT 39 #define TCR_HA (1UL << TCR_HA_SHIFT) #define TCR_TBI1_SHIFT 38 #define TCR_TBI1 (1UL << TCR_TBI1_SHIFT) #define TCR_TBI0_SHIFT 37 #define TCR_TBI0 (1U << TCR_TBI0_SHIFT) #define TCR_ASID_SHIFT 36 #define TCR_ASID_WIDTH 1 #define TCR_ASID_16 (1UL << TCR_ASID_SHIFT) /* Bit 35 is reserved */ #define TCR_IPS_SHIFT 32 #define TCR_IPS_WIDTH 3 #define TCR_IPS_32BIT (0UL << TCR_IPS_SHIFT) #define TCR_IPS_36BIT (1UL << TCR_IPS_SHIFT) #define TCR_IPS_40BIT (2UL << TCR_IPS_SHIFT) #define TCR_IPS_42BIT (3UL << TCR_IPS_SHIFT) #define TCR_IPS_44BIT (4UL << TCR_IPS_SHIFT) #define TCR_IPS_48BIT (5UL << TCR_IPS_SHIFT) #define TCR_TG1_SHIFT 30 #define TCR_TG1_16K (1UL << TCR_TG1_SHIFT) #define TCR_TG1_4K (2UL << TCR_TG1_SHIFT) #define TCR_TG1_64K (3UL << TCR_TG1_SHIFT) #define TCR_SH1_SHIFT 28 #define TCR_SH1_IS (3UL << TCR_SH1_SHIFT) #define TCR_ORGN1_SHIFT 26 #define TCR_ORGN1_WBWA (1UL << TCR_ORGN1_SHIFT) #define TCR_IRGN1_SHIFT 24 #define TCR_IRGN1_WBWA (1UL << TCR_IRGN1_SHIFT) #define TCR_EPD1_SHIFT 23 #define TCR_EPD1 (1UL << TCR_EPD1_SHIFT) #define TCR_A1_SHIFT 22 #define TCR_A1 (0x1UL << TCR_A1_SHIFT) #define TCR_T1SZ_SHIFT 16 #define TCR_T1SZ(x) ((x) << TCR_T1SZ_SHIFT) #define TCR_TG0_SHIFT 14 #define TCR_TG0_16K (1UL << TCR_TG0_SHIFT) #define TCR_TG0_4K (2UL << TCR_TG0_SHIFT) #define TCR_TG0_64K (3UL << TCR_TG0_SHIFT) #define TCR_SH0_SHIFT 12 #define TCR_SH0_IS (3UL << TCR_SH0_SHIFT) #define TCR_ORGN0_SHIFT 10 #define TCR_ORGN0_WBWA (1UL << TCR_ORGN0_SHIFT) #define TCR_IRGN0_SHIFT 8 #define TCR_IRGN0_WBWA (1UL << TCR_IRGN0_SHIFT) #define TCR_EPD0_SHIFT 7 #define TCR_EPD0 (1UL << TCR_EPD1_SHIFT) /* Bit 6 is reserved */ #define TCR_T0SZ_SHIFT 0 #define TCR_T0SZ_MASK 0x3f #define TCR_T0SZ(x) ((x) << TCR_T0SZ_SHIFT) #define TCR_TxSZ(x) (TCR_T1SZ(x) | TCR_T0SZ(x)) #define TCR_CACHE_ATTRS ((TCR_IRGN0_WBWA | TCR_IRGN1_WBWA) |\ (TCR_ORGN0_WBWA | TCR_ORGN1_WBWA)) #ifdef SMP #define TCR_SMP_ATTRS (TCR_SH0_IS | TCR_SH1_IS) #else #define TCR_SMP_ATTRS 0 #endif /* TTBR0_EL1 & TTBR1_EL1 - Translation Table Base Register 0 & 1 */ #define TTBR_ASID_SHIFT 48 #define TTBR_ASID_MASK (0xfffful << TTBR_ASID_SHIFT) #define TTBR_BADDR 0x0000fffffffffffeul #define TTBR_CnP_SHIFT 0 #define TTBR_CnP (1ul << TTBR_CnP_SHIFT) /* Perfomance Monitoring Counters */ #define PMCR_E (1 << 0) /* Enable all counters */ #define PMCR_P (1 << 1) /* Reset all counters */ #define PMCR_C (1 << 2) /* Clock counter reset */ #define PMCR_D (1 << 3) /* CNTR counts every 64 clk cycles */ #define PMCR_X (1 << 4) /* Export to ext. monitoring (ETM) */ #define PMCR_DP (1 << 5) /* Disable CCNT if non-invasive debug*/ #define PMCR_LC (1 << 6) /* Long cycle count enable */ #define PMCR_IMP_SHIFT 24 /* Implementer code */ #define PMCR_IMP_MASK (0xff << PMCR_IMP_SHIFT) #define PMCR_IMP_ARM 0x41 #define PMCR_IDCODE_SHIFT 16 /* Identification code */ #define PMCR_IDCODE_MASK (0xff << PMCR_IDCODE_SHIFT) #define PMCR_IDCODE_CORTEX_A57 0x01 #define PMCR_IDCODE_CORTEX_A72 0x02 #define PMCR_IDCODE_CORTEX_A53 0x03 #define PMCR_IDCODE_CORTEX_A73 0x04 #define PMCR_IDCODE_CORTEX_A35 0x0a #define PMCR_IDCODE_CORTEX_A76 0x0b #define PMCR_IDCODE_NEOVERSE_N1 0x0c #define PMCR_IDCODE_CORTEX_A77 0x10 #define PMCR_IDCODE_CORTEX_A55 0x45 #define PMCR_IDCODE_NEOVERSE_E1 0x46 #define PMCR_IDCODE_CORTEX_A75 0x4a #define PMCR_N_SHIFT 11 /* Number of counters implemented */ #define PMCR_N_MASK (0x1f << PMCR_N_SHIFT) #endif /* !_MACHINE_ARMREG_H_ */ diff --git a/tests/sys/kern/basic_signal.c b/tests/sys/kern/basic_signal.c index b94ebeb1ba23..1dcb9ff064fc 100644 --- a/tests/sys/kern/basic_signal.c +++ b/tests/sys/kern/basic_signal.c @@ -1,159 +1,225 @@ /*- * Copyright (c) 2021 M. Warner Losh * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #include +#if defined(__aarch64__) +#include +#define SET_TRACE_FLAG(ucp) (ucp)->uc_mcontext.mc_gpregs.gp_spsr |= PSR_SS +#define CLR_TRACE_FLAG(ucp) (ucp)->uc_mcontext.mc_gpregs.gp_spsr &= ~PSR_SS +#elif defined(__amd64__) +#include +#define SET_TRACE_FLAG(ucp) (ucp)->uc_mcontext.mc_rflags |= PSL_T +#define CLR_TRACE_FLAG(ucp) (ucp)->uc_mcontext.mc_rflags &= ~PSL_T +#elif defined(__i386__) +#include +#define SET_TRACE_FLAG(ucp) (ucp)->uc_mcontext.mc_eflags |= PSL_T +#define CLR_TRACE_FLAG(ucp) (ucp)->uc_mcontext.mc_eflags &= ~PSL_T +#endif + static volatile sig_atomic_t signal_fired = 0; static void sig_handler(int signo, siginfo_t *info __unused, void *ucp __unused) { signal_fired++; } ATF_TC(signal_test); ATF_TC_HEAD(signal_test, tc) { atf_tc_set_md_var(tc, "descr", "Testing delivery of a signal"); } ATF_TC_BODY(signal_test, tc) { /* * Setup the signal handlers */ struct sigaction sa = { .sa_sigaction = sig_handler, .sa_flags = SA_SIGINFO, }; ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); ATF_REQUIRE(sigaction(SIGUSR1, &sa, NULL) == 0); ATF_REQUIRE(sigaction(SIGUSR2, &sa, NULL) == 0); ATF_REQUIRE(sigaction(SIGALRM, &sa, NULL) == 0); /* * Fire SIGUSR1 */ ATF_CHECK(signal_fired == 0); ATF_REQUIRE(raise(SIGUSR1) == 0); ATF_CHECK(signal_fired == 1); /* * Fire SIGUSR2 */ ATF_REQUIRE(raise(SIGUSR2) == 0); ATF_CHECK(signal_fired == 2); /* * Fire SIGALRM after a timeout */ ATF_REQUIRE(alarm(1) == 0); ATF_REQUIRE(pause() == -1); ATF_REQUIRE(errno == EINTR); ATF_CHECK(signal_fired == 3); } +/* + * Check setting the machine dependent single step flag works when supported. + */ +#ifdef SET_TRACE_FLAG +static volatile sig_atomic_t trap_signal_fired = 0; + +static void +trap_sig_handler(int signo, siginfo_t *info __unused, void *_ucp) +{ + ucontext_t *ucp = _ucp; + + if (trap_signal_fired < 9) { + SET_TRACE_FLAG(ucp); + } else { + CLR_TRACE_FLAG(ucp); + } + trap_signal_fired++; +} + +ATF_TC(trap_signal_test); + +ATF_TC_HEAD(trap_signal_test, tc) +{ + + atf_tc_set_md_var(tc, "descr", + "Testing signal handler setting the MD single step flag"); +} + +ATF_TC_BODY(trap_signal_test, tc) +{ + /* + * Setup the signal handlers + */ + struct sigaction sa = { + .sa_sigaction = trap_sig_handler, + .sa_flags = SA_SIGINFO, + }; + ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); + ATF_REQUIRE(sigaction(SIGTRAP, &sa, NULL) == 0); + + /* + * Fire SIGTRAP + */ + ATF_CHECK(trap_signal_fired == 0); + ATF_REQUIRE(raise(SIGTRAP) == 0); + ATF_CHECK(trap_signal_fired == 10); +} +#endif + /* * Special tests for 32-bit arm. We can call thumb code (really just t32) from * normal (a32) mode and vice versa. Likewise, signals can interrupt a T32 * context with A32 code and vice versa. Make sure these all work with a simple * test that raises the signal and ensures that it executed. No other platform * has these requirements. Also note: we only support thumb2, so there's no T16 * vs T32 issues we have to test for. */ #ifdef __arm__ #define a32_isa __attribute__((target("arm"))) #define t32_isa __attribute__((target("thumb"))) static volatile sig_atomic_t t32_fired = 0; static volatile sig_atomic_t a32_fired = 0; a32_isa static void sig_a32(int signo, siginfo_t *info __unused, void *ucp __unused) { a32_fired++; } t32_isa static void sig_t32(int signo, siginfo_t *info __unused, void *ucp __unused) { t32_fired++; } ATF_TC(signal_test_T32_to_A32); ATF_TC_HEAD(signal_test_T32_to_A32, tc) { atf_tc_set_md_var(tc, "descr", "Testing delivery of a signal from T32 to A32"); } t32_isa ATF_TC_BODY(signal_test_T32_to_A32, tc) { /* * Setup the signal handlers */ struct sigaction sa = { .sa_sigaction = sig_a32, .sa_flags = SA_SIGINFO, }; ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); ATF_REQUIRE(sigaction(SIGUSR1, &sa, NULL) == 0); ATF_REQUIRE((((uintptr_t)sig_a32) & 1) == 0); /* Make sure compiled as not thumb */ ATF_CHECK(a32_fired == 0); ATF_REQUIRE(raise(SIGUSR1) == 0); ATF_CHECK(a32_fired == 1); } ATF_TC(signal_test_A32_to_T32); ATF_TC_HEAD(signal_test_A32_to_T32, tc) { atf_tc_set_md_var(tc, "descr", "Testing delivery of a signal from A32 to T32"); } a32_isa ATF_TC_BODY(signal_test_A32_to_T32, tc) { /* * Setup the signal handlers */ struct sigaction sa = { .sa_sigaction = sig_t32, .sa_flags = SA_SIGINFO, }; ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); ATF_REQUIRE(sigaction(SIGUSR1, &sa, NULL) == 0); ATF_REQUIRE((((uintptr_t)sig_t32) & 1) == 1); /* Make sure compiled as thumb */ ATF_CHECK(t32_fired == 0); ATF_REQUIRE(raise(SIGUSR1) == 0); ATF_CHECK(t32_fired == 1); } #endif ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, signal_test); +#ifdef SET_TRACE_FLAG + ATF_TP_ADD_TC(tp, trap_signal_test); +#endif #ifdef __arm__ ATF_TP_ADD_TC(tp, signal_test_T32_to_A32); ATF_TP_ADD_TC(tp, signal_test_A32_to_T32); #endif return (atf_no_error()); }