xref: /netbsd-src/external/gpl3/gdb/dist/gdbserver/linux-nios2-low.cc (revision 64f917f5a88990e32dd65fcd4348042fa7f852b9)
18dffb485Schristos /* GNU/Linux/Nios II specific low level interface, for the remote server for
28dffb485Schristos    GDB.
3*64f917f5Schristos    Copyright (C) 2008-2024 Free Software Foundation, Inc.
48dffb485Schristos 
58dffb485Schristos    Contributed by Mentor Graphics, Inc.
68dffb485Schristos 
78dffb485Schristos    This file is part of GDB.
88dffb485Schristos 
98dffb485Schristos    This program is free software; you can redistribute it and/or modify
108dffb485Schristos    it under the terms of the GNU General Public License as published by
118dffb485Schristos    the Free Software Foundation; either version 3 of the License, or
128dffb485Schristos    (at your option) any later version.
138dffb485Schristos 
148dffb485Schristos    This program is distributed in the hope that it will be useful,
158dffb485Schristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
168dffb485Schristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
178dffb485Schristos    GNU General Public License for more details.
188dffb485Schristos 
198dffb485Schristos    You should have received a copy of the GNU General Public License
208dffb485Schristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
218dffb485Schristos 
228dffb485Schristos #include "linux-low.h"
238dffb485Schristos #include "elf/common.h"
248dffb485Schristos #include "nat/gdb_ptrace.h"
258dffb485Schristos #include <endian.h>
268dffb485Schristos #include "gdb_proc_service.h"
278dffb485Schristos #include <asm/ptrace.h>
288dffb485Schristos 
298dffb485Schristos #ifndef PTRACE_GET_THREAD_AREA
308dffb485Schristos #define PTRACE_GET_THREAD_AREA 25
318dffb485Schristos #endif
328dffb485Schristos 
338dffb485Schristos /* Linux target op definitions for the NIOS II architecture.  */
348dffb485Schristos 
358dffb485Schristos class nios2_target : public linux_process_target
368dffb485Schristos {
378dffb485Schristos public:
388dffb485Schristos 
398dffb485Schristos   const regs_info *get_regs_info () override;
408dffb485Schristos 
418dffb485Schristos   const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override;
428dffb485Schristos 
438dffb485Schristos protected:
448dffb485Schristos 
458dffb485Schristos   void low_arch_setup () override;
468dffb485Schristos 
478dffb485Schristos   bool low_cannot_fetch_register (int regno) override;
488dffb485Schristos 
498dffb485Schristos   bool low_cannot_store_register (int regno) override;
508dffb485Schristos 
518dffb485Schristos   bool low_supports_breakpoints () override;
528dffb485Schristos 
538dffb485Schristos   CORE_ADDR low_get_pc (regcache *regcache) override;
548dffb485Schristos 
558dffb485Schristos   void low_set_pc (regcache *regcache, CORE_ADDR newpc) override;
568dffb485Schristos 
578dffb485Schristos   bool low_breakpoint_at (CORE_ADDR pc) override;
588dffb485Schristos };
598dffb485Schristos 
608dffb485Schristos /* The singleton target ops object.  */
618dffb485Schristos 
628dffb485Schristos static nios2_target the_nios2_target;
638dffb485Schristos 
648dffb485Schristos bool
658dffb485Schristos nios2_target::low_supports_breakpoints ()
668dffb485Schristos {
678dffb485Schristos   return true;
688dffb485Schristos }
698dffb485Schristos 
708dffb485Schristos CORE_ADDR
718dffb485Schristos nios2_target::low_get_pc (regcache *regcache)
728dffb485Schristos {
738dffb485Schristos   return linux_get_pc_32bit (regcache);
748dffb485Schristos }
758dffb485Schristos 
768dffb485Schristos void
778dffb485Schristos nios2_target::low_set_pc (regcache *regcache, CORE_ADDR pc)
788dffb485Schristos {
798dffb485Schristos   linux_set_pc_32bit (regcache, pc);
808dffb485Schristos }
818dffb485Schristos 
828dffb485Schristos /* The following definition must agree with the number of registers
838dffb485Schristos    defined in "struct user_regs" in GLIBC
848dffb485Schristos    (sysdeps/unix/sysv/linux/nios2/sys/user.h), and also with
858dffb485Schristos    NIOS2_NUM_REGS in GDB proper.  */
868dffb485Schristos 
878dffb485Schristos #define nios2_num_regs 49
888dffb485Schristos 
898dffb485Schristos /* Defined in auto-generated file nios2-linux.c.  */
908dffb485Schristos 
918dffb485Schristos void init_registers_nios2_linux (void);
928dffb485Schristos extern const struct target_desc *tdesc_nios2_linux;
938dffb485Schristos 
948dffb485Schristos /* This union is used to convert between int and byte buffer
958dffb485Schristos    representations of register contents.  */
968dffb485Schristos 
978dffb485Schristos union nios2_register
988dffb485Schristos {
998dffb485Schristos   unsigned char buf[4];
1008dffb485Schristos   int reg32;
1018dffb485Schristos };
1028dffb485Schristos 
1038dffb485Schristos /* Return the ptrace ``address'' of register REGNO. */
1048dffb485Schristos 
1058dffb485Schristos static int nios2_regmap[] = {
1068dffb485Schristos   -1,  1,  2,  3,  4,  5,  6,  7,
1078dffb485Schristos   8,  9,  10, 11, 12, 13, 14, 15,
1088dffb485Schristos   16, 17, 18, 19, 20, 21, 22, 23,
1098dffb485Schristos   24, 25, 26, 27, 28, 29, 30, 31,
1108dffb485Schristos   32, 33, 34, 35, 36, 37, 38, 39,
1118dffb485Schristos   40, 41, 42, 43, 44, 45, 46, 47,
1128dffb485Schristos   48,
1138dffb485Schristos   0
1148dffb485Schristos };
1158dffb485Schristos 
1168dffb485Schristos /* Implement the low_arch_setup linux target ops method.  */
1178dffb485Schristos 
1188dffb485Schristos void
1198dffb485Schristos nios2_target::low_arch_setup ()
1208dffb485Schristos {
1218dffb485Schristos   current_process ()->tdesc = tdesc_nios2_linux;
1228dffb485Schristos }
1238dffb485Schristos 
1248dffb485Schristos /* Implement the low_cannot_fetch_register linux target ops method.  */
1258dffb485Schristos 
1268dffb485Schristos bool
1278dffb485Schristos nios2_target::low_cannot_fetch_register (int regno)
1288dffb485Schristos {
1298dffb485Schristos   return (nios2_regmap[regno] == -1);
1308dffb485Schristos }
1318dffb485Schristos 
1328dffb485Schristos /* Implement the low_cannot_store_register linux target ops method.  */
1338dffb485Schristos 
1348dffb485Schristos bool
1358dffb485Schristos nios2_target::low_cannot_store_register (int regno)
1368dffb485Schristos {
1378dffb485Schristos   return (nios2_regmap[regno] == -1);
1388dffb485Schristos }
1398dffb485Schristos 
1408dffb485Schristos /* Breakpoint support.  Also see comments on nios2_breakpoint_from_pc
1418dffb485Schristos    in nios2-tdep.c.  */
1428dffb485Schristos 
1438dffb485Schristos #if defined(__nios2_arch__) && __nios2_arch__ == 2
1448dffb485Schristos #define NIOS2_BREAKPOINT 0xb7fd0020
1458dffb485Schristos #define CDX_BREAKPOINT 0xd7c9
1468dffb485Schristos #else
1478dffb485Schristos #define NIOS2_BREAKPOINT 0x003b6ffa
1488dffb485Schristos #endif
1498dffb485Schristos 
1508dffb485Schristos /* We only register the 4-byte breakpoint, even on R2 targets which also
1518dffb485Schristos    support 2-byte breakpoints.  Since there is no supports_z_point_type
1528dffb485Schristos    function provided, gdbserver never inserts software breakpoints itself
1538dffb485Schristos    and instead relies on GDB to insert the breakpoint of the correct length
1548dffb485Schristos    via a memory write.  */
1558dffb485Schristos static const unsigned int nios2_breakpoint = NIOS2_BREAKPOINT;
1568dffb485Schristos #define nios2_breakpoint_len 4
1578dffb485Schristos 
1588dffb485Schristos /* Implementation of target ops method "sw_breakpoint_from_kind".  */
1598dffb485Schristos 
1608dffb485Schristos const gdb_byte *
1618dffb485Schristos nios2_target::sw_breakpoint_from_kind (int kind, int *size)
1628dffb485Schristos {
1638dffb485Schristos   *size = nios2_breakpoint_len;
1648dffb485Schristos   return (const gdb_byte *) &nios2_breakpoint;
1658dffb485Schristos }
1668dffb485Schristos 
1678dffb485Schristos /* Implement the low_breakpoint_at linux target ops method.  */
1688dffb485Schristos 
1698dffb485Schristos bool
1708dffb485Schristos nios2_target::low_breakpoint_at (CORE_ADDR where)
1718dffb485Schristos {
1728dffb485Schristos   unsigned int insn;
1738dffb485Schristos 
1748dffb485Schristos   /* For R2, first check for the 2-byte CDX trap.n breakpoint encoding.  */
1758dffb485Schristos #if defined(__nios2_arch__) && __nios2_arch__ == 2
1768dffb485Schristos   read_memory (where, (unsigned char *) &insn, 2);
1778dffb485Schristos   if (insn == CDX_BREAKPOINT)
1788dffb485Schristos     return true;
1798dffb485Schristos #endif
1808dffb485Schristos 
1818dffb485Schristos   read_memory (where, (unsigned char *) &insn, 4);
1828dffb485Schristos   if (insn == nios2_breakpoint)
1838dffb485Schristos     return true;
1848dffb485Schristos   return false;
1858dffb485Schristos }
1868dffb485Schristos 
1878dffb485Schristos /* Fetch the thread-local storage pointer for libthread_db.  */
1888dffb485Schristos 
1898dffb485Schristos ps_err_e
1908dffb485Schristos ps_get_thread_area (struct ps_prochandle *ph,
1918dffb485Schristos 		    lwpid_t lwpid, int idx, void **base)
1928dffb485Schristos {
1938dffb485Schristos   if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
1948dffb485Schristos     return PS_ERR;
1958dffb485Schristos 
1968dffb485Schristos   /* IDX is the bias from the thread pointer to the beginning of the
1978dffb485Schristos      thread descriptor.  It has to be subtracted due to implementation
1988dffb485Schristos      quirks in libthread_db.  */
1998dffb485Schristos   *base = (void *) ((char *) *base - idx);
2008dffb485Schristos 
2018dffb485Schristos   return PS_OK;
2028dffb485Schristos }
2038dffb485Schristos 
2048dffb485Schristos /* Helper functions to collect/supply a single register REGNO.  */
2058dffb485Schristos 
2068dffb485Schristos static void
2078dffb485Schristos nios2_collect_register (struct regcache *regcache, int regno,
2088dffb485Schristos 			union nios2_register *reg)
2098dffb485Schristos {
2108dffb485Schristos   union nios2_register tmp_reg;
2118dffb485Schristos 
2128dffb485Schristos   collect_register (regcache, regno, &tmp_reg.reg32);
2138dffb485Schristos   reg->reg32 = tmp_reg.reg32;
2148dffb485Schristos }
2158dffb485Schristos 
2168dffb485Schristos static void
2178dffb485Schristos nios2_supply_register (struct regcache *regcache, int regno,
2188dffb485Schristos 		       const union nios2_register *reg)
2198dffb485Schristos {
2208dffb485Schristos   supply_register (regcache, regno, reg->buf);
2218dffb485Schristos }
2228dffb485Schristos 
2238dffb485Schristos /* We have only a single register set on Nios II.  */
2248dffb485Schristos 
2258dffb485Schristos static void
2268dffb485Schristos nios2_fill_gregset (struct regcache *regcache, void *buf)
2278dffb485Schristos {
2288dffb485Schristos   union nios2_register *regset = (union nios2_register *) buf;
2298dffb485Schristos   int i;
2308dffb485Schristos 
2318dffb485Schristos   for (i = 1; i < nios2_num_regs; i++)
2328dffb485Schristos     nios2_collect_register (regcache, i, regset + i);
2338dffb485Schristos }
2348dffb485Schristos 
2358dffb485Schristos static void
2368dffb485Schristos nios2_store_gregset (struct regcache *regcache, const void *buf)
2378dffb485Schristos {
2388dffb485Schristos   const union nios2_register *regset = (union nios2_register *) buf;
2398dffb485Schristos   int i;
2408dffb485Schristos 
2418dffb485Schristos   for (i = 0; i < nios2_num_regs; i++)
2428dffb485Schristos     nios2_supply_register (regcache, i, regset + i);
2438dffb485Schristos }
2448dffb485Schristos 
2458dffb485Schristos static struct regset_info nios2_regsets[] =
2468dffb485Schristos {
2478dffb485Schristos   { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PRSTATUS,
2488dffb485Schristos     nios2_num_regs * 4, GENERAL_REGS,
2498dffb485Schristos     nios2_fill_gregset, nios2_store_gregset },
2508dffb485Schristos   NULL_REGSET
2518dffb485Schristos };
2528dffb485Schristos 
2538dffb485Schristos static struct regsets_info nios2_regsets_info =
2548dffb485Schristos   {
2558dffb485Schristos     nios2_regsets, /* regsets */
2568dffb485Schristos     0, /* num_regsets */
2578dffb485Schristos     NULL, /* disabled_regsets */
2588dffb485Schristos   };
2598dffb485Schristos 
2608dffb485Schristos static struct usrregs_info nios2_usrregs_info =
2618dffb485Schristos   {
2628dffb485Schristos     nios2_num_regs,
2638dffb485Schristos     nios2_regmap,
2648dffb485Schristos   };
2658dffb485Schristos 
2668dffb485Schristos static struct regs_info myregs_info =
2678dffb485Schristos   {
2688dffb485Schristos     NULL, /* regset_bitmap */
2698dffb485Schristos     &nios2_usrregs_info,
2708dffb485Schristos     &nios2_regsets_info
2718dffb485Schristos   };
2728dffb485Schristos 
2738dffb485Schristos const regs_info *
2748dffb485Schristos nios2_target::get_regs_info ()
2758dffb485Schristos {
2768dffb485Schristos   return &myregs_info;
2778dffb485Schristos }
2788dffb485Schristos 
2798dffb485Schristos /* The linux target ops object.  */
2808dffb485Schristos 
2818dffb485Schristos linux_process_target *the_linux_target = &the_nios2_target;
2828dffb485Schristos 
2838dffb485Schristos void
2848dffb485Schristos initialize_low_arch (void)
2858dffb485Schristos {
2868dffb485Schristos   init_registers_nios2_linux ();
2878dffb485Schristos 
2888dffb485Schristos   initialize_regsets_info (&nios2_regsets_info);
2898dffb485Schristos }
290