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