xref: /openbmc/qemu/bsd-user/riscv/signal.c (revision 35ba77d2fcd10efd6db8318bbd4d21fa9402143b)
12931709eSMark Corbin /*
22931709eSMark Corbin  *  RISC-V signal definitions
32931709eSMark Corbin  *
42931709eSMark Corbin  *  Copyright (c) 2019 Mark Corbin
52931709eSMark Corbin  *
62931709eSMark Corbin  *  This program is free software; you can redistribute it and/or modify
72931709eSMark Corbin  *  it under the terms of the GNU General Public License as published by
82931709eSMark Corbin  *  the Free Software Foundation; either version 2 of the License, or
92931709eSMark Corbin  *  (at your option) any later version.
102931709eSMark Corbin  *
112931709eSMark Corbin  *  This program is distributed in the hope that it will be useful,
122931709eSMark Corbin  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
132931709eSMark Corbin  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
142931709eSMark Corbin  *  GNU General Public License for more details.
152931709eSMark Corbin  *
162931709eSMark Corbin  *  You should have received a copy of the GNU General Public License
172931709eSMark Corbin  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
182931709eSMark Corbin  */
192931709eSMark Corbin #include "qemu/osdep.h"
202931709eSMark Corbin 
212931709eSMark Corbin #include "qemu.h"
222931709eSMark Corbin 
232931709eSMark Corbin /*
242931709eSMark Corbin  * Compare with sendsig() in riscv/riscv/exec_machdep.c
252931709eSMark Corbin  * Assumes that target stack frame memory is locked.
262931709eSMark Corbin  */
272931709eSMark Corbin abi_long
set_sigtramp_args(CPURISCVState * regs,int sig,struct target_sigframe * frame,abi_ulong frame_addr,struct target_sigaction * ka)282931709eSMark Corbin set_sigtramp_args(CPURISCVState *regs, int sig, struct target_sigframe *frame,
292931709eSMark Corbin     abi_ulong frame_addr, struct target_sigaction *ka)
302931709eSMark Corbin {
312931709eSMark Corbin     /*
322931709eSMark Corbin      * Arguments to signal handler:
332931709eSMark Corbin      *  a0 (10) = signal number
342931709eSMark Corbin      *  a1 (11) = siginfo pointer
352931709eSMark Corbin      *  a2 (12) = ucontext pointer
362931709eSMark Corbin      *  pc      = signal pointer handler
372931709eSMark Corbin      *  sp (2)  = sigframe pointer
382931709eSMark Corbin      *  ra (1)  = sigtramp at base of user stack
392931709eSMark Corbin      */
402931709eSMark Corbin 
412931709eSMark Corbin      regs->gpr[xA0] = sig;
422931709eSMark Corbin      regs->gpr[xA1] = frame_addr +
432931709eSMark Corbin          offsetof(struct target_sigframe, sf_si);
442931709eSMark Corbin      regs->gpr[xA2] = frame_addr +
452931709eSMark Corbin          offsetof(struct target_sigframe, sf_uc);
462931709eSMark Corbin      regs->pc = ka->_sa_handler;
472931709eSMark Corbin      regs->gpr[xSP] = frame_addr;
482931709eSMark Corbin      regs->gpr[xRA] = TARGET_PS_STRINGS - TARGET_SZSIGCODE;
492931709eSMark Corbin      return 0;
502931709eSMark Corbin }
512931709eSMark Corbin 
522931709eSMark Corbin /*
532931709eSMark Corbin  * Compare to riscv/riscv/exec_machdep.c sendsig()
542931709eSMark Corbin  * Assumes that the memory is locked if frame points to user memory.
552931709eSMark Corbin  */
setup_sigframe_arch(CPURISCVState * env,abi_ulong frame_addr,struct target_sigframe * frame,int flags)562931709eSMark Corbin abi_long setup_sigframe_arch(CPURISCVState *env, abi_ulong frame_addr,
572931709eSMark Corbin                              struct target_sigframe *frame, int flags)
582931709eSMark Corbin {
592931709eSMark Corbin     target_mcontext_t *mcp = &frame->sf_uc.uc_mcontext;
602931709eSMark Corbin 
612931709eSMark Corbin     get_mcontext(env, mcp, flags);
622931709eSMark Corbin     return 0;
632931709eSMark Corbin }
64e185844fSMark Corbin 
65e185844fSMark Corbin /*
66e185844fSMark Corbin  * Compare with get_mcontext() in riscv/riscv/machdep.c
67e185844fSMark Corbin  * Assumes that the memory is locked if mcp points to user memory.
68e185844fSMark Corbin  */
get_mcontext(CPURISCVState * regs,target_mcontext_t * mcp,int flags)69e185844fSMark Corbin abi_long get_mcontext(CPURISCVState *regs, target_mcontext_t *mcp,
70e185844fSMark Corbin         int flags)
71e185844fSMark Corbin {
72e185844fSMark Corbin 
73e185844fSMark Corbin     mcp->mc_gpregs.gp_t[0] = tswap64(regs->gpr[5]);
74e185844fSMark Corbin     mcp->mc_gpregs.gp_t[1] = tswap64(regs->gpr[6]);
75e185844fSMark Corbin     mcp->mc_gpregs.gp_t[2] = tswap64(regs->gpr[7]);
76e185844fSMark Corbin     mcp->mc_gpregs.gp_t[3] = tswap64(regs->gpr[28]);
77e185844fSMark Corbin     mcp->mc_gpregs.gp_t[4] = tswap64(regs->gpr[29]);
78e185844fSMark Corbin     mcp->mc_gpregs.gp_t[5] = tswap64(regs->gpr[30]);
79e185844fSMark Corbin     mcp->mc_gpregs.gp_t[6] = tswap64(regs->gpr[31]);
80e185844fSMark Corbin 
81e185844fSMark Corbin     mcp->mc_gpregs.gp_s[0] = tswap64(regs->gpr[8]);
82e185844fSMark Corbin     mcp->mc_gpregs.gp_s[1] = tswap64(regs->gpr[9]);
83e185844fSMark Corbin     mcp->mc_gpregs.gp_s[2] = tswap64(regs->gpr[18]);
84e185844fSMark Corbin     mcp->mc_gpregs.gp_s[3] = tswap64(regs->gpr[19]);
85e185844fSMark Corbin     mcp->mc_gpregs.gp_s[4] = tswap64(regs->gpr[20]);
86e185844fSMark Corbin     mcp->mc_gpregs.gp_s[5] = tswap64(regs->gpr[21]);
87e185844fSMark Corbin     mcp->mc_gpregs.gp_s[6] = tswap64(regs->gpr[22]);
88e185844fSMark Corbin     mcp->mc_gpregs.gp_s[7] = tswap64(regs->gpr[23]);
89e185844fSMark Corbin     mcp->mc_gpregs.gp_s[8] = tswap64(regs->gpr[24]);
90e185844fSMark Corbin     mcp->mc_gpregs.gp_s[9] = tswap64(regs->gpr[25]);
91e185844fSMark Corbin     mcp->mc_gpregs.gp_s[10] = tswap64(regs->gpr[26]);
92e185844fSMark Corbin     mcp->mc_gpregs.gp_s[11] = tswap64(regs->gpr[27]);
93e185844fSMark Corbin 
94e185844fSMark Corbin     mcp->mc_gpregs.gp_a[0] = tswap64(regs->gpr[10]);
95e185844fSMark Corbin     mcp->mc_gpregs.gp_a[1] = tswap64(regs->gpr[11]);
96e185844fSMark Corbin     mcp->mc_gpregs.gp_a[2] = tswap64(regs->gpr[12]);
97e185844fSMark Corbin     mcp->mc_gpregs.gp_a[3] = tswap64(regs->gpr[13]);
98e185844fSMark Corbin     mcp->mc_gpregs.gp_a[4] = tswap64(regs->gpr[14]);
99e185844fSMark Corbin     mcp->mc_gpregs.gp_a[5] = tswap64(regs->gpr[15]);
100e185844fSMark Corbin     mcp->mc_gpregs.gp_a[6] = tswap64(regs->gpr[16]);
101e185844fSMark Corbin     mcp->mc_gpregs.gp_a[7] = tswap64(regs->gpr[17]);
102e185844fSMark Corbin 
103e185844fSMark Corbin     if (flags & TARGET_MC_GET_CLEAR_RET) {
104e185844fSMark Corbin         mcp->mc_gpregs.gp_a[0] = 0; /* a0 */
105e185844fSMark Corbin         mcp->mc_gpregs.gp_a[1] = 0; /* a1 */
106e185844fSMark Corbin         mcp->mc_gpregs.gp_t[0] = 0; /* clear syscall error */
107e185844fSMark Corbin     }
108e185844fSMark Corbin 
109e185844fSMark Corbin     mcp->mc_gpregs.gp_ra = tswap64(regs->gpr[1]);
110e185844fSMark Corbin     mcp->mc_gpregs.gp_sp = tswap64(regs->gpr[2]);
111e185844fSMark Corbin     mcp->mc_gpregs.gp_gp = tswap64(regs->gpr[3]);
112e185844fSMark Corbin     mcp->mc_gpregs.gp_tp = tswap64(regs->gpr[4]);
113e185844fSMark Corbin     mcp->mc_gpregs.gp_sepc = tswap64(regs->pc);
114e185844fSMark Corbin 
115e185844fSMark Corbin     return 0;
116e185844fSMark Corbin }
117*4c492b40SMark Corbin 
118*4c492b40SMark Corbin /* Compare with set_mcontext() in riscv/riscv/exec_machdep.c */
set_mcontext(CPURISCVState * regs,target_mcontext_t * mcp,int srflag)119*4c492b40SMark Corbin abi_long set_mcontext(CPURISCVState *regs, target_mcontext_t *mcp,
120*4c492b40SMark Corbin         int srflag)
121*4c492b40SMark Corbin {
122*4c492b40SMark Corbin 
123*4c492b40SMark Corbin     regs->gpr[5] = tswap64(mcp->mc_gpregs.gp_t[0]);
124*4c492b40SMark Corbin     regs->gpr[6] = tswap64(mcp->mc_gpregs.gp_t[1]);
125*4c492b40SMark Corbin     regs->gpr[7] = tswap64(mcp->mc_gpregs.gp_t[2]);
126*4c492b40SMark Corbin     regs->gpr[28] = tswap64(mcp->mc_gpregs.gp_t[3]);
127*4c492b40SMark Corbin     regs->gpr[29] = tswap64(mcp->mc_gpregs.gp_t[4]);
128*4c492b40SMark Corbin     regs->gpr[30] = tswap64(mcp->mc_gpregs.gp_t[5]);
129*4c492b40SMark Corbin     regs->gpr[31] = tswap64(mcp->mc_gpregs.gp_t[6]);
130*4c492b40SMark Corbin 
131*4c492b40SMark Corbin     regs->gpr[8] = tswap64(mcp->mc_gpregs.gp_s[0]);
132*4c492b40SMark Corbin     regs->gpr[9] = tswap64(mcp->mc_gpregs.gp_s[1]);
133*4c492b40SMark Corbin     regs->gpr[18] = tswap64(mcp->mc_gpregs.gp_s[2]);
134*4c492b40SMark Corbin     regs->gpr[19] = tswap64(mcp->mc_gpregs.gp_s[3]);
135*4c492b40SMark Corbin     regs->gpr[20] = tswap64(mcp->mc_gpregs.gp_s[4]);
136*4c492b40SMark Corbin     regs->gpr[21] = tswap64(mcp->mc_gpregs.gp_s[5]);
137*4c492b40SMark Corbin     regs->gpr[22] = tswap64(mcp->mc_gpregs.gp_s[6]);
138*4c492b40SMark Corbin     regs->gpr[23] = tswap64(mcp->mc_gpregs.gp_s[7]);
139*4c492b40SMark Corbin     regs->gpr[24] = tswap64(mcp->mc_gpregs.gp_s[8]);
140*4c492b40SMark Corbin     regs->gpr[25] = tswap64(mcp->mc_gpregs.gp_s[9]);
141*4c492b40SMark Corbin     regs->gpr[26] = tswap64(mcp->mc_gpregs.gp_s[10]);
142*4c492b40SMark Corbin     regs->gpr[27] = tswap64(mcp->mc_gpregs.gp_s[11]);
143*4c492b40SMark Corbin 
144*4c492b40SMark Corbin     regs->gpr[10] = tswap64(mcp->mc_gpregs.gp_a[0]);
145*4c492b40SMark Corbin     regs->gpr[11] = tswap64(mcp->mc_gpregs.gp_a[1]);
146*4c492b40SMark Corbin     regs->gpr[12] = tswap64(mcp->mc_gpregs.gp_a[2]);
147*4c492b40SMark Corbin     regs->gpr[13] = tswap64(mcp->mc_gpregs.gp_a[3]);
148*4c492b40SMark Corbin     regs->gpr[14] = tswap64(mcp->mc_gpregs.gp_a[4]);
149*4c492b40SMark Corbin     regs->gpr[15] = tswap64(mcp->mc_gpregs.gp_a[5]);
150*4c492b40SMark Corbin     regs->gpr[16] = tswap64(mcp->mc_gpregs.gp_a[6]);
151*4c492b40SMark Corbin     regs->gpr[17] = tswap64(mcp->mc_gpregs.gp_a[7]);
152*4c492b40SMark Corbin 
153*4c492b40SMark Corbin 
154*4c492b40SMark Corbin     regs->gpr[1] = tswap64(mcp->mc_gpregs.gp_ra);
155*4c492b40SMark Corbin     regs->gpr[2] = tswap64(mcp->mc_gpregs.gp_sp);
156*4c492b40SMark Corbin     regs->gpr[3] = tswap64(mcp->mc_gpregs.gp_gp);
157*4c492b40SMark Corbin     regs->gpr[4] = tswap64(mcp->mc_gpregs.gp_tp);
158*4c492b40SMark Corbin     regs->pc = tswap64(mcp->mc_gpregs.gp_sepc);
159*4c492b40SMark Corbin 
160*4c492b40SMark Corbin     return 0;
161*4c492b40SMark Corbin }
162*4c492b40SMark Corbin 
163*4c492b40SMark Corbin /* Compare with sys_sigreturn() in riscv/riscv/machdep.c */
get_ucontext_sigreturn(CPURISCVState * regs,abi_ulong target_sf,abi_ulong * target_uc)164*4c492b40SMark Corbin abi_long get_ucontext_sigreturn(CPURISCVState *regs,
165*4c492b40SMark Corbin                         abi_ulong target_sf, abi_ulong *target_uc)
166*4c492b40SMark Corbin {
167*4c492b40SMark Corbin 
168*4c492b40SMark Corbin     *target_uc = target_sf;
169*4c492b40SMark Corbin     return 0;
170*4c492b40SMark Corbin }
171