1*6881a400Schristos /* Native-dependent code for NetBSD/riscv. 2*6881a400Schristos 3*6881a400Schristos Copyright (C) 2018-2020 Free Software Foundation, Inc. 4*6881a400Schristos 5*6881a400Schristos This file is part of GDB. 6*6881a400Schristos 7*6881a400Schristos This program is free software; you can redistribute it and/or modify 8*6881a400Schristos it under the terms of the GNU General Public License as published by 9*6881a400Schristos the Free Software Foundation; either version 3 of the License, or 10*6881a400Schristos (at your option) any later version. 11*6881a400Schristos 12*6881a400Schristos This program is distributed in the hope that it will be useful, 13*6881a400Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 14*6881a400Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*6881a400Schristos GNU General Public License for more details. 16*6881a400Schristos 17*6881a400Schristos You should have received a copy of the GNU General Public License 18*6881a400Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19*6881a400Schristos 20*6881a400Schristos #include "defs.h" 21*6881a400Schristos #include "regcache.h" 22*6881a400Schristos #include "target.h" 23*6881a400Schristos 24*6881a400Schristos #include <sys/types.h> 25*6881a400Schristos #include <sys/ptrace.h> 26*6881a400Schristos #include <machine/reg.h> 27*6881a400Schristos 28*6881a400Schristos #include "netbsd-nat.h" 29*6881a400Schristos #include "riscv-tdep.h" 30*6881a400Schristos #include "riscv-netbsd-tdep.h" 31*6881a400Schristos #include "inf-ptrace.h" 32*6881a400Schristos 33*6881a400Schristos struct riscv_nbsd_nat_target final : public nbsd_nat_target 34*6881a400Schristos { 35*6881a400Schristos void fetch_registers (struct regcache *, int) override; 36*6881a400Schristos void store_registers (struct regcache *, int) override; 37*6881a400Schristos }; 38*6881a400Schristos 39*6881a400Schristos static riscv_nbsd_nat_target the_riscv_nbsd_nat_target; 40*6881a400Schristos 41*6881a400Schristos /* Determine if PT_GETREGS fetches REGNUM. */ 42*6881a400Schristos 43*6881a400Schristos static bool 44*6881a400Schristos getregs_supplies (int regnum) 45*6881a400Schristos { 46*6881a400Schristos return regnum >= RISCV_RA_REGNUM && regnum <= RISCV_PC_REGNUM; 47*6881a400Schristos } 48*6881a400Schristos 49*6881a400Schristos /* Determine if PT_GETFPREGS fetches REGNUM. */ 50*6881a400Schristos 51*6881a400Schristos static bool 52*6881a400Schristos getfpregs_supplies (int regnum) 53*6881a400Schristos { 54*6881a400Schristos return ((regnum >= RISCV_FIRST_FP_REGNUM && regnum <= RISCV_LAST_FP_REGNUM) 55*6881a400Schristos || regnum == RISCV_CSR_FCSR_REGNUM); 56*6881a400Schristos } 57*6881a400Schristos 58*6881a400Schristos /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this 59*6881a400Schristos for all registers. */ 60*6881a400Schristos 61*6881a400Schristos void 62*6881a400Schristos riscv_nbsd_nat_target::fetch_registers (struct regcache *regcache, 63*6881a400Schristos int regnum) 64*6881a400Schristos { 65*6881a400Schristos pid_t pid = regcache->ptid ().pid (); 66*6881a400Schristos int lwp = regcache->ptid ().lwp (); 67*6881a400Schristos 68*6881a400Schristos if (regnum == -1 || regnum == RISCV_ZERO_REGNUM) 69*6881a400Schristos regcache->raw_supply_zeroed (RISCV_ZERO_REGNUM); 70*6881a400Schristos if (regnum == -1 || getregs_supplies (regnum)) 71*6881a400Schristos { 72*6881a400Schristos struct reg regs; 73*6881a400Schristos 74*6881a400Schristos if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1) 75*6881a400Schristos perror_with_name (_("Couldn't get registers")); 76*6881a400Schristos 77*6881a400Schristos regcache->supply_regset (&riscv_nbsd_gregset, regnum, ®s, 78*6881a400Schristos sizeof (regs)); 79*6881a400Schristos } 80*6881a400Schristos 81*6881a400Schristos if (regnum == -1 || getfpregs_supplies (regnum)) 82*6881a400Schristos { 83*6881a400Schristos struct fpreg fpregs; 84*6881a400Schristos 85*6881a400Schristos if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) 86*6881a400Schristos perror_with_name (_("Couldn't get floating point status")); 87*6881a400Schristos 88*6881a400Schristos regcache->supply_regset (&riscv_nbsd_fpregset, regnum, &fpregs, 89*6881a400Schristos sizeof (fpregs)); 90*6881a400Schristos } 91*6881a400Schristos } 92*6881a400Schristos 93*6881a400Schristos /* Store register REGNUM back into the inferior. If REGNUM is -1, do 94*6881a400Schristos this for all registers. */ 95*6881a400Schristos 96*6881a400Schristos void 97*6881a400Schristos riscv_nbsd_nat_target::store_registers (struct regcache *regcache, 98*6881a400Schristos int regnum) 99*6881a400Schristos { 100*6881a400Schristos pid_t pid = regcache->ptid ().pid (); 101*6881a400Schristos int lwp = regcache->ptid ().lwp (); 102*6881a400Schristos 103*6881a400Schristos if (regnum == -1 || getregs_supplies (regnum)) 104*6881a400Schristos { 105*6881a400Schristos struct reg regs; 106*6881a400Schristos 107*6881a400Schristos if (ptrace (PT_GETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1) 108*6881a400Schristos perror_with_name (_("Couldn't get registers")); 109*6881a400Schristos 110*6881a400Schristos regcache->collect_regset (&riscv_nbsd_gregset, regnum, ®s, 111*6881a400Schristos sizeof (regs)); 112*6881a400Schristos 113*6881a400Schristos if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) ®s, lwp) == -1) 114*6881a400Schristos perror_with_name (_("Couldn't write registers")); 115*6881a400Schristos } 116*6881a400Schristos 117*6881a400Schristos if (regnum == -1 || getfpregs_supplies (regnum)) 118*6881a400Schristos { 119*6881a400Schristos struct fpreg fpregs; 120*6881a400Schristos 121*6881a400Schristos if (ptrace (PT_GETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1) 122*6881a400Schristos perror_with_name (_("Couldn't get floating point status")); 123*6881a400Schristos 124*6881a400Schristos regcache->collect_regset (&riscv_nbsd_fpregset, regnum, &fpregs, 125*6881a400Schristos sizeof (fpregs)); 126*6881a400Schristos 127*6881a400Schristos if (ptrace (PT_SETFPREGS, pid, (PTRACE_TYPE_ARG3) &fpregs, lwp) == -1) 128*6881a400Schristos perror_with_name (_("Couldn't write floating point status")); 129*6881a400Schristos } 130*6881a400Schristos } 131*6881a400Schristos 132*6881a400Schristos /* Initialize RISC-V NetBSD native support. */ 133*6881a400Schristos 134*6881a400Schristos void _initialize_riscv_nbsd_nat (); 135*6881a400Schristos void 136*6881a400Schristos _initialize_riscv_nbsd_nat () 137*6881a400Schristos { 138*6881a400Schristos add_inf_child_target (&the_riscv_nbsd_nat_target); 139*6881a400Schristos 140*6881a400Schristos // bsd_kvm_add_target (riscv_nbsd_supply_pcb); 141*6881a400Schristos } 142