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