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) ®s, 0) == -1)
75*0cdd3313Sskrll perror_with_name (_("Couldn't get registers"));
76*0cdd3313Sskrll
77*0cdd3313Sskrll regcache->supply_regset (&riscv_nbsd_gregset, regnum, ®s,
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) ®s, 0) == -1)
108*0cdd3313Sskrll perror_with_name (_("Couldn't get registers"));
109*0cdd3313Sskrll
110*0cdd3313Sskrll regcache->collect_regset (&riscv_nbsd_gregset, regnum, ®s,
111*0cdd3313Sskrll sizeof (regs));
112*0cdd3313Sskrll
113*0cdd3313Sskrll if (ptrace (PT_SETREGS, pid, (PTRACE_TYPE_ARG3) ®s, 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