17dba5e10SStacey Son /*
27dba5e10SStacey Son * ARM AArch64 specific signal definitions for bsd-user
37dba5e10SStacey Son *
47dba5e10SStacey Son * Copyright (c) 2015 Stacey D. Son <sson at FreeBSD>
57dba5e10SStacey Son *
67dba5e10SStacey Son * This library is free software; you can redistribute it and/or
77dba5e10SStacey Son * modify it under the terms of the GNU Lesser General Public
87dba5e10SStacey Son * License as published by the Free Software Foundation; either
97dba5e10SStacey Son * version 2 of the License, or (at your option) any later version.
107dba5e10SStacey Son *
117dba5e10SStacey Son * This library is distributed in the hope that it will be useful,
127dba5e10SStacey Son * but WITHOUT ANY WARRANTY; without even the implied warranty of
137dba5e10SStacey Son * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
147dba5e10SStacey Son * Lesser General Public License for more details.
157dba5e10SStacey Son *
167dba5e10SStacey Son * You should have received a copy of the GNU Lesser General Public
177dba5e10SStacey Son * License along with this library; if not, see <http://www.gnu.org/licenses/>.
187dba5e10SStacey Son */
197dba5e10SStacey Son #include "qemu/osdep.h"
207dba5e10SStacey Son
217dba5e10SStacey Son #include "qemu.h"
227dba5e10SStacey Son
237dba5e10SStacey Son /*
24*ce6c541dSStacey Son * Compare to sendsig() in sys/arm64/arm64/exec_machdep.c
257dba5e10SStacey Son * Assumes that target stack frame memory is locked.
267dba5e10SStacey Son */
set_sigtramp_args(CPUARMState * regs,int sig,struct target_sigframe * frame,abi_ulong frame_addr,struct target_sigaction * ka)277dba5e10SStacey Son abi_long set_sigtramp_args(CPUARMState *regs, int sig,
287dba5e10SStacey Son struct target_sigframe *frame,
297dba5e10SStacey Son abi_ulong frame_addr,
307dba5e10SStacey Son struct target_sigaction *ka)
317dba5e10SStacey Son {
327dba5e10SStacey Son /*
337dba5e10SStacey Son * Arguments to signal handler:
347dba5e10SStacey Son * x0 = signal number
357dba5e10SStacey Son * x1 = siginfo pointer
367dba5e10SStacey Son * x2 = ucontext pointer
377dba5e10SStacey Son * pc/elr = signal handler pointer
387dba5e10SStacey Son * sp = sigframe struct pointer
397dba5e10SStacey Son * lr = sigtramp at base of user stack
407dba5e10SStacey Son */
417dba5e10SStacey Son
427dba5e10SStacey Son regs->xregs[0] = sig;
437dba5e10SStacey Son regs->xregs[1] = frame_addr +
447dba5e10SStacey Son offsetof(struct target_sigframe, sf_si);
457dba5e10SStacey Son regs->xregs[2] = frame_addr +
467dba5e10SStacey Son offsetof(struct target_sigframe, sf_uc);
477dba5e10SStacey Son
487dba5e10SStacey Son regs->pc = ka->_sa_handler;
497dba5e10SStacey Son regs->xregs[TARGET_REG_SP] = frame_addr;
507dba5e10SStacey Son regs->xregs[TARGET_REG_LR] = TARGET_PS_STRINGS - TARGET_SZSIGCODE;
517dba5e10SStacey Son
527dba5e10SStacey Son return 0;
537dba5e10SStacey Son }
549959fae5SStacey Son
559959fae5SStacey Son /*
569959fae5SStacey Son * Compare to get_mcontext() in arm64/arm64/machdep.c
579959fae5SStacey Son * Assumes that the memory is locked if mcp points to user memory.
589959fae5SStacey Son */
get_mcontext(CPUARMState * regs,target_mcontext_t * mcp,int flags)599959fae5SStacey Son abi_long get_mcontext(CPUARMState *regs, target_mcontext_t *mcp, int flags)
609959fae5SStacey Son {
619959fae5SStacey Son int err = 0, i;
629959fae5SStacey Son uint64_t *gr = mcp->mc_gpregs.gp_x;
639959fae5SStacey Son
649959fae5SStacey Son mcp->mc_gpregs.gp_spsr = pstate_read(regs);
659959fae5SStacey Son if (flags & TARGET_MC_GET_CLEAR_RET) {
669959fae5SStacey Son gr[0] = 0UL;
679959fae5SStacey Son mcp->mc_gpregs.gp_spsr &= ~CPSR_C;
689959fae5SStacey Son } else {
699959fae5SStacey Son gr[0] = tswap64(regs->xregs[0]);
709959fae5SStacey Son }
719959fae5SStacey Son
729959fae5SStacey Son for (i = 1; i < 30; i++) {
739959fae5SStacey Son gr[i] = tswap64(regs->xregs[i]);
749959fae5SStacey Son }
759959fae5SStacey Son
769959fae5SStacey Son mcp->mc_gpregs.gp_sp = tswap64(regs->xregs[TARGET_REG_SP]);
779959fae5SStacey Son mcp->mc_gpregs.gp_lr = tswap64(regs->xregs[TARGET_REG_LR]);
789959fae5SStacey Son mcp->mc_gpregs.gp_elr = tswap64(regs->pc);
799959fae5SStacey Son
809959fae5SStacey Son /* XXX FP? */
819959fae5SStacey Son
829959fae5SStacey Son return err;
839959fae5SStacey Son }
84c88f44d8SWarner Losh
85c88f44d8SWarner Losh /*
86c88f44d8SWarner Losh * Compare to arm64/arm64/exec_machdep.c sendsig()
87c88f44d8SWarner Losh * Assumes that the memory is locked if frame points to user memory.
88c88f44d8SWarner Losh */
setup_sigframe_arch(CPUARMState * env,abi_ulong frame_addr,struct target_sigframe * frame,int flags)89c88f44d8SWarner Losh abi_long setup_sigframe_arch(CPUARMState *env, abi_ulong frame_addr,
90c88f44d8SWarner Losh struct target_sigframe *frame, int flags)
91c88f44d8SWarner Losh {
92c88f44d8SWarner Losh target_mcontext_t *mcp = &frame->sf_uc.uc_mcontext;
93c88f44d8SWarner Losh
94c88f44d8SWarner Losh get_mcontext(env, mcp, flags);
95c88f44d8SWarner Losh return 0;
96c88f44d8SWarner Losh }
97c88f44d8SWarner Losh
98dadfc6d5SStacey Son /*
99dadfc6d5SStacey Son * Compare to set_mcontext() in arm64/arm64/machdep.c
100dadfc6d5SStacey Son * Assumes that the memory is locked if frame points to user memory.
101dadfc6d5SStacey Son */
set_mcontext(CPUARMState * regs,target_mcontext_t * mcp,int srflag)102dadfc6d5SStacey Son abi_long set_mcontext(CPUARMState *regs, target_mcontext_t *mcp, int srflag)
103dadfc6d5SStacey Son {
104dadfc6d5SStacey Son int err = 0, i;
105dadfc6d5SStacey Son const uint64_t *gr = mcp->mc_gpregs.gp_x;
106dadfc6d5SStacey Son
107dadfc6d5SStacey Son for (i = 0; i < 30; i++) {
108dadfc6d5SStacey Son regs->xregs[i] = tswap64(gr[i]);
109dadfc6d5SStacey Son }
110dadfc6d5SStacey Son
111dadfc6d5SStacey Son regs->xregs[TARGET_REG_SP] = tswap64(mcp->mc_gpregs.gp_sp);
112dadfc6d5SStacey Son regs->xregs[TARGET_REG_LR] = tswap64(mcp->mc_gpregs.gp_lr);
113dadfc6d5SStacey Son regs->pc = mcp->mc_gpregs.gp_elr;
114dadfc6d5SStacey Son pstate_write(regs, mcp->mc_gpregs.gp_spsr);
115dadfc6d5SStacey Son
116dadfc6d5SStacey Son /* XXX FP? */
117dadfc6d5SStacey Son
118dadfc6d5SStacey Son return err;
119dadfc6d5SStacey Son }
120*ce6c541dSStacey Son
121*ce6c541dSStacey Son /* Compare to sys_sigreturn() in arm64/arm64/machdep.c */
get_ucontext_sigreturn(CPUARMState * regs,abi_ulong target_sf,abi_ulong * target_uc)122*ce6c541dSStacey Son abi_long get_ucontext_sigreturn(CPUARMState *regs, abi_ulong target_sf,
123*ce6c541dSStacey Son abi_ulong *target_uc)
124*ce6c541dSStacey Son {
125*ce6c541dSStacey Son uint32_t pstate = pstate_read(regs);
126*ce6c541dSStacey Son
127*ce6c541dSStacey Son *target_uc = 0;
128*ce6c541dSStacey Son
129*ce6c541dSStacey Son if ((pstate & PSTATE_M) != PSTATE_MODE_EL0t ||
130*ce6c541dSStacey Son (pstate & (PSTATE_F | PSTATE_I | PSTATE_A | PSTATE_D)) != 0) {
131*ce6c541dSStacey Son return -TARGET_EINVAL;
132*ce6c541dSStacey Son }
133*ce6c541dSStacey Son
134*ce6c541dSStacey Son *target_uc = target_sf;
135*ce6c541dSStacey Son
136*ce6c541dSStacey Son return 0;
137*ce6c541dSStacey Son }
138