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