xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/riscv-none-tdep.c (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
1*6881a400Schristos /* Copyright (C) 2020-2023 Free Software Foundation, Inc.
2*6881a400Schristos 
3*6881a400Schristos    This file is part of GDB.
4*6881a400Schristos 
5*6881a400Schristos    This program is free software; you can redistribute it and/or modify
6*6881a400Schristos    it under the terms of the GNU General Public License as published by
7*6881a400Schristos    the Free Software Foundation; either version 3 of the License, or
8*6881a400Schristos    (at your option) any later version.
9*6881a400Schristos 
10*6881a400Schristos    This program is distributed in the hope that it will be useful,
11*6881a400Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
12*6881a400Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13*6881a400Schristos    GNU General Public License for more details.
14*6881a400Schristos 
15*6881a400Schristos    You should have received a copy of the GNU General Public License
16*6881a400Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17*6881a400Schristos 
18*6881a400Schristos /* This file contain code that is specific for bare-metal RISC-V targets.  */
19*6881a400Schristos 
20*6881a400Schristos #include "defs.h"
21*6881a400Schristos #include "arch-utils.h"
22*6881a400Schristos #include "regcache.h"
23*6881a400Schristos #include "riscv-tdep.h"
24*6881a400Schristos #include "elf-bfd.h"
25*6881a400Schristos #include "regset.h"
26*6881a400Schristos #include "user-regs.h"
27*6881a400Schristos #include "target-descriptions.h"
28*6881a400Schristos 
29*6881a400Schristos #ifdef HAVE_ELF
30*6881a400Schristos #include "elf-none-tdep.h"
31*6881a400Schristos #endif
32*6881a400Schristos 
33*6881a400Schristos /* Define the general register mapping.  This follows the same format as
34*6881a400Schristos    the RISC-V linux corefile.  The linux kernel puts the PC at offset 0,
35*6881a400Schristos    gdb puts it at offset 32.  Register x0 is always 0 and can be ignored.
36*6881a400Schristos    Registers x1 to x31 are in the same place.  */
37*6881a400Schristos 
38*6881a400Schristos static const struct regcache_map_entry riscv_gregmap[] =
39*6881a400Schristos {
40*6881a400Schristos   { 1,  RISCV_PC_REGNUM, 0 },
41*6881a400Schristos   { 31, RISCV_RA_REGNUM, 0 }, /* x1 to x31 */
42*6881a400Schristos   { 0 }
43*6881a400Schristos };
44*6881a400Schristos 
45*6881a400Schristos /* Define the FP register mapping.  This follows the same format as the
46*6881a400Schristos    RISC-V linux corefile.  The kernel puts the 32 FP regs first, and then
47*6881a400Schristos    FCSR.  */
48*6881a400Schristos 
49*6881a400Schristos static const struct regcache_map_entry riscv_fregmap[] =
50*6881a400Schristos {
51*6881a400Schristos   { 32, RISCV_FIRST_FP_REGNUM, 0 },
52*6881a400Schristos   { 1, RISCV_CSR_FCSR_REGNUM, 4 },	/* Always stored as 4-bytes.  */
53*6881a400Schristos   { 0 }
54*6881a400Schristos };
55*6881a400Schristos 
56*6881a400Schristos /* Define the general register regset.  */
57*6881a400Schristos 
58*6881a400Schristos static const struct regset riscv_gregset =
59*6881a400Schristos {
60*6881a400Schristos   riscv_gregmap, riscv_supply_regset, regcache_collect_regset
61*6881a400Schristos };
62*6881a400Schristos 
63*6881a400Schristos /* Define the FP register regset.  */
64*6881a400Schristos 
65*6881a400Schristos static const struct regset riscv_fregset =
66*6881a400Schristos {
67*6881a400Schristos   riscv_fregmap, riscv_supply_regset, regcache_collect_regset
68*6881a400Schristos };
69*6881a400Schristos 
70*6881a400Schristos /* Define the CSR regset, this is not constant as the regmap field is
71*6881a400Schristos    updated dynamically based on the current target description.  */
72*6881a400Schristos 
73*6881a400Schristos static struct regset riscv_csrset =
74*6881a400Schristos {
75*6881a400Schristos   nullptr, regcache_supply_regset, regcache_collect_regset
76*6881a400Schristos };
77*6881a400Schristos 
78*6881a400Schristos /* Update the regmap field of RISCV_CSRSET based on the CSRs available in
79*6881a400Schristos    the current target description.  */
80*6881a400Schristos 
81*6881a400Schristos static void
82*6881a400Schristos riscv_update_csrmap (struct gdbarch *gdbarch,
83*6881a400Schristos 		     const struct tdesc_feature *feature_csr)
84*6881a400Schristos {
85*6881a400Schristos   int i = 0;
86*6881a400Schristos 
87*6881a400Schristos   /* Release any previously defined map.  */
88*6881a400Schristos   delete[] ((struct regcache_map_entry *) riscv_csrset.regmap);
89*6881a400Schristos 
90*6881a400Schristos   /* Now create a register map for every csr found in the target
91*6881a400Schristos      description.  */
92*6881a400Schristos   struct regcache_map_entry *riscv_csrmap
93*6881a400Schristos     = new struct regcache_map_entry[feature_csr->registers.size() + 1];
94*6881a400Schristos   for (auto &csr : feature_csr->registers)
95*6881a400Schristos     {
96*6881a400Schristos       int regnum = user_reg_map_name_to_regnum (gdbarch, csr->name.c_str(),
97*6881a400Schristos 						csr->name.length());
98*6881a400Schristos       riscv_csrmap[i++] = {1, regnum, 0};
99*6881a400Schristos     }
100*6881a400Schristos 
101*6881a400Schristos   /* Mark the end of the array.  */
102*6881a400Schristos   riscv_csrmap[i] = {0};
103*6881a400Schristos   riscv_csrset.regmap = riscv_csrmap;
104*6881a400Schristos }
105*6881a400Schristos 
106*6881a400Schristos /* Implement the "iterate_over_regset_sections" gdbarch method.  */
107*6881a400Schristos 
108*6881a400Schristos static void
109*6881a400Schristos riscv_iterate_over_regset_sections (struct gdbarch *gdbarch,
110*6881a400Schristos 				    iterate_over_regset_sections_cb *cb,
111*6881a400Schristos 				    void *cb_data,
112*6881a400Schristos 				    const struct regcache *regcache)
113*6881a400Schristos {
114*6881a400Schristos   /* Write out the GPRs.  */
115*6881a400Schristos   int sz = 32 * riscv_isa_xlen (gdbarch);
116*6881a400Schristos   cb (".reg", sz, sz, &riscv_gregset, NULL, cb_data);
117*6881a400Schristos 
118*6881a400Schristos   /* Write out the FPRs, but only if present.  */
119*6881a400Schristos   if (riscv_isa_flen (gdbarch) > 0)
120*6881a400Schristos     {
121*6881a400Schristos       sz = (32 * riscv_isa_flen (gdbarch)
122*6881a400Schristos 	    + register_size (gdbarch, RISCV_CSR_FCSR_REGNUM));
123*6881a400Schristos       cb (".reg2", sz, sz, &riscv_fregset, NULL, cb_data);
124*6881a400Schristos     }
125*6881a400Schristos 
126*6881a400Schristos   /* Read or write the CSRs.  The set of CSRs is defined by the current
127*6881a400Schristos      target description.  The user is responsible for ensuring that the
128*6881a400Schristos      same target description is in use when reading the core file as was
129*6881a400Schristos      in use when writing the core file.  */
130*6881a400Schristos   const struct target_desc *tdesc = gdbarch_target_desc (gdbarch);
131*6881a400Schristos 
132*6881a400Schristos   /* Do not dump/load any CSRs if there is no target description or the target
133*6881a400Schristos      description does not contain any CSRs.  */
134*6881a400Schristos   if (tdesc != nullptr)
135*6881a400Schristos     {
136*6881a400Schristos       const struct tdesc_feature *feature_csr
137*6881a400Schristos         = tdesc_find_feature (tdesc, riscv_feature_name_csr);
138*6881a400Schristos       if (feature_csr != nullptr && feature_csr->registers.size () > 0)
139*6881a400Schristos 	{
140*6881a400Schristos 	  riscv_update_csrmap (gdbarch, feature_csr);
141*6881a400Schristos 	  cb (".reg-riscv-csr",
142*6881a400Schristos 	      (feature_csr->registers.size() * riscv_isa_xlen (gdbarch)),
143*6881a400Schristos 	      (feature_csr->registers.size() * riscv_isa_xlen (gdbarch)),
144*6881a400Schristos 	      &riscv_csrset, NULL, cb_data);
145*6881a400Schristos 	}
146*6881a400Schristos     }
147*6881a400Schristos }
148*6881a400Schristos 
149*6881a400Schristos /* Initialize RISC-V bare-metal ABI info.  */
150*6881a400Schristos 
151*6881a400Schristos static void
152*6881a400Schristos riscv_none_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
153*6881a400Schristos {
154*6881a400Schristos #ifdef HAVE_ELF
155*6881a400Schristos   elf_none_init_abi (gdbarch);
156*6881a400Schristos #endif
157*6881a400Schristos 
158*6881a400Schristos   /* Iterate over registers for reading and writing bare metal RISC-V core
159*6881a400Schristos      files.  */
160*6881a400Schristos   set_gdbarch_iterate_over_regset_sections
161*6881a400Schristos     (gdbarch, riscv_iterate_over_regset_sections);
162*6881a400Schristos 
163*6881a400Schristos }
164*6881a400Schristos 
165*6881a400Schristos /* Initialize RISC-V bare-metal target support.  */
166*6881a400Schristos 
167*6881a400Schristos void _initialize_riscv_none_tdep ();
168*6881a400Schristos void
169*6881a400Schristos _initialize_riscv_none_tdep ()
170*6881a400Schristos {
171*6881a400Schristos   gdbarch_register_osabi (bfd_arch_riscv, 0, GDB_OSABI_NONE,
172*6881a400Schristos 			  riscv_none_init_abi);
173*6881a400Schristos }
174