gdb/dink32-rom.c - gdb

Global variables defined

Functions defined

Source code

  1. /* Remote debugging interface for DINK32 (PowerPC) ROM monitor for
  2.    GDB, the GNU debugger.
  3.    Copyright (C) 1997-2015 Free Software Foundation, Inc.

  4.    This file is part of GDB.

  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.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.

  13.    You should have received a copy of the GNU General Public License
  14.    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

  15. #include "defs.h"
  16. #include "gdbcore.h"
  17. #include "target.h"
  18. #include "monitor.h"
  19. #include "serial.h"
  20. #include "symfile.h" /* For generic_load() */
  21. #include "inferior.h"
  22. #include "regcache.h"

  23. static void
  24. dink32_supply_register (struct regcache *regcache, char *regname,
  25.                         int regnamelen, char *val, int vallen)
  26. {
  27.   int regno = 0;

  28.   if (regnamelen < 2 || regnamelen > 4)
  29.     return;

  30.   switch (regname[0])
  31.     {
  32.     case 'R':
  33.       if (regname[1] < '0' || regname[1] > '9')
  34.         return;
  35.       if (regnamelen == 2)
  36.         regno = regname[1] - '0';
  37.       else if (regnamelen == 3 && regname[2] >= '0' && regname[2] <= '9')
  38.         regno = (regname[1] - '0') * 10 + (regname[2] - '0');
  39.       else
  40.         return;
  41.       break;
  42.     case 'F':
  43.       if (regname[1] != 'R' || regname[2] < '0' || regname[2] > '9')
  44.         return;
  45.       if (regnamelen == 3)
  46.         regno = 32 + regname[2] - '0';
  47.       else if (regnamelen == 4 && regname[3] >= '0' && regname[3] <= '9')
  48.         regno = 32 + (regname[2] - '0') * 10 + (regname[3] - '0');
  49.       else
  50.         return;
  51.       break;
  52.     case 'I':
  53.       if (regnamelen != 2 || regname[1] != 'P')
  54.         return;
  55.       regno = 64;
  56.       break;
  57.     case 'M':
  58.       if (regnamelen != 3 || regname[1] != 'S' || regname[2] != 'R')
  59.         return;
  60.       regno = 65;
  61.       break;
  62.     case 'C':
  63.       if (regnamelen != 2 || regname[1] != 'R')
  64.         return;
  65.       regno = 66;
  66.       break;
  67.     case 'S':
  68.       if (regnamelen != 4 || regname[1] != 'P' || regname[2] != 'R')
  69.         return;
  70.       else if (regname[3] == '8')
  71.         regno = 67;
  72.       else if (regname[3] == '9')
  73.         regno = 68;
  74.       else if (regname[3] == '1')
  75.         regno = 69;
  76.       else if (regname[3] == '0')
  77.         regno = 70;
  78.       else
  79.         return;
  80.       break;
  81.     default:
  82.       return;
  83.     }

  84.   monitor_supply_register (regcache, regno, val);
  85. }

  86. /* This array of registers needs to match the indexes used by GDB.
  87.    The whole reason this exists is because the various ROM monitors
  88.    use different names than GDB does, and don't support all the
  89.    registers either.  */

  90. static char *dink32_regnames[] =
  91. {
  92.   "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
  93.   "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
  94.   "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
  95.   "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",

  96.   "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
  97.   "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
  98.   "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
  99.   "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",

  100.   "srr0", "msr", "cr", "lr", "ctr", "xer", "xer"
  101. };

  102. static struct target_ops dink32_ops;

  103. static char *dink32_inits[] =
  104. {"\r", NULL};

  105. static struct monitor_ops dink32_cmds;

  106. static void
  107. dink32_open (const char *args, int from_tty)
  108. {
  109.   monitor_open (args, &dink32_cmds, from_tty);
  110. }

  111. extern initialize_file_ftype _initialize_dink32_rom; /* -Wmissing-prototypes */

  112. void
  113. _initialize_dink32_rom (void)
  114. {
  115.   dink32_cmds.flags = MO_HEX_PREFIX | MO_GETMEM_NEEDS_RANGE
  116.     | MO_FILL_USES_ADDR | MO_HANDLE_NL | MO_32_REGS_PAIRED
  117.     | MO_SETREG_INTERACTIVE | MO_SETMEM_INTERACTIVE
  118.     | MO_GETMEM_16_BOUNDARY | MO_CLR_BREAK_1_BASED | MO_SREC_ACK
  119.     | MO_SREC_ACK_ROTATE;
  120.   dink32_cmds.init = dink32_inits;
  121.   dink32_cmds.cont = "go +\r";
  122.   dink32_cmds.step = "tr +\r";
  123.   dink32_cmds.set_break = "bp 0x%x\r";
  124.   dink32_cmds.clr_break = "bp %d\r";
  125. #if 0                        /* Would need to follow strict alignment rules..  */
  126.   dink32_cmds.fill = "mf %x %x %x\r";
  127. #endif
  128.   dink32_cmds.setmem.cmdb = "mm -b %x\r";
  129.   dink32_cmds.setmem.cmdw = "mm -w %x\r";
  130.   dink32_cmds.setmem.cmdl = "mm %x\r";
  131.   dink32_cmds.setmem.term = " ?  ";
  132.   dink32_cmds.getmem.cmdb = "md %x\r";
  133.   dink32_cmds.getmem.resp_delim = "        ";
  134.   dink32_cmds.setreg.cmd = "rm %s\r";
  135.   dink32_cmds.setreg.term = " ?  ";
  136.   dink32_cmds.getreg.cmd = "rd %s\r";
  137.   dink32_cmds.getreg.resp_delim = ": ";
  138.   dink32_cmds.dump_registers = "rd r\r";
  139.   dink32_cmds.register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)";
  140.   dink32_cmds.supply_register = dink32_supply_register;
  141.   /* S-record download, via "keyboard port".  */
  142.   dink32_cmds.load = "dl -k\r";
  143.   dink32_cmds.loadresp = "Set Input Port : set to Keyboard Port\r";
  144.   dink32_cmds.prompt = "DINK32_603 >>";
  145.   dink32_cmds.line_term = "\r";
  146.   dink32_cmds.target = &dink32_ops;
  147.   dink32_cmds.stopbits = SERIAL_1_STOPBITS;
  148.   dink32_cmds.regnames = dink32_regnames;
  149.   dink32_cmds.magic = MONITOR_OPS_MAGIC;

  150.   init_monitor_ops (&dink32_ops);

  151.   dink32_ops.to_shortname = "dink32";
  152.   dink32_ops.to_longname = "DINK32 monitor";
  153.   dink32_ops.to_doc = "Debug using the DINK32 monitor.\n\
  154. Specify the serial device it is connected to (e.g. /dev/ttya).";
  155.   dink32_ops.to_open = dink32_open;

  156.   add_target (&dink32_ops);
  157. }