198944Sobrien/* Remote debugging interface to dBUG ROM monitor for GDB, the GNU debugger.
298944Sobrien   Copyright 1996, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
398944Sobrien
498944Sobrien   Written by Stan Shebs of Cygnus Support.
598944Sobrien
698944Sobrien   This file is part of GDB.
798944Sobrien
898944Sobrien   This program is free software; you can redistribute it and/or modify
998944Sobrien   it under the terms of the GNU General Public License as published by
1098944Sobrien   the Free Software Foundation; either version 2 of the License, or
1198944Sobrien   (at your option) any later version.
1298944Sobrien
1398944Sobrien   This program is distributed in the hope that it will be useful,
1498944Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1598944Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1698944Sobrien   GNU General Public License for more details.
1798944Sobrien
1898944Sobrien   You should have received a copy of the GNU General Public License
1998944Sobrien   along with this program; if not, write to the Free Software
2098944Sobrien   Foundation, Inc., 59 Temple Place - Suite 330,
2198944Sobrien   Boston, MA 02111-1307, USA.  */
2298944Sobrien
2398944Sobrien/* dBUG is a monitor supplied on various Motorola boards, including
2498944Sobrien   m68k, ColdFire, and PowerPC-based designs.  The code here assumes
2598944Sobrien   the ColdFire, and (as of 9/25/96) has only been tested with a
2698944Sobrien   ColdFire IDP board.  */
2798944Sobrien
2898944Sobrien#include "defs.h"
2998944Sobrien#include "gdbcore.h"
3098944Sobrien#include "target.h"
3198944Sobrien#include "monitor.h"
3298944Sobrien#include "serial.h"
3398944Sobrien#include "regcache.h"
3498944Sobrien
35130803Smarcel#include "m68k-tdep.h"
36130803Smarcel
3798944Sobrienstatic void dbug_open (char *args, int from_tty);
3898944Sobrien
3998944Sobrienstatic void
4098944Sobriendbug_supply_register (char *regname, int regnamelen, char *val, int vallen)
4198944Sobrien{
4298944Sobrien  int regno;
4398944Sobrien
4498944Sobrien  if (regnamelen != 2)
4598944Sobrien    return;
4698944Sobrien
4798944Sobrien  switch (regname[0])
4898944Sobrien    {
4998944Sobrien    case 'S':
5098944Sobrien      if (regname[1] != 'R')
5198944Sobrien	return;
5298944Sobrien      regno = PS_REGNUM;
5398944Sobrien      break;
5498944Sobrien    case 'P':
5598944Sobrien      if (regname[1] != 'C')
5698944Sobrien	return;
5798944Sobrien      regno = PC_REGNUM;
5898944Sobrien      break;
5998944Sobrien    case 'D':
6098944Sobrien      if (regname[1] < '0' || regname[1] > '7')
6198944Sobrien	return;
62130803Smarcel      regno = regname[1] - '0' + M68K_D0_REGNUM;
6398944Sobrien      break;
6498944Sobrien    case 'A':
6598944Sobrien      if (regname[1] < '0' || regname[1] > '7')
6698944Sobrien	return;
67130803Smarcel      regno = regname[1] - '0' + M68K_A0_REGNUM;
6898944Sobrien      break;
6998944Sobrien    default:
7098944Sobrien      return;
7198944Sobrien    }
7298944Sobrien
7398944Sobrien  monitor_supply_register (regno, val);
7498944Sobrien}
7598944Sobrien
7698944Sobrien/* This array of registers needs to match the indexes used by GDB. The
7798944Sobrien   whole reason this exists is because the various ROM monitors use
7898944Sobrien   different names than GDB does, and don't support all the registers
7998944Sobrien   either. So, typing "info reg sp" becomes an "A7". */
8098944Sobrien
81130803Smarcelstatic const char *
82130803Smarceldbug_regname (int index)
8398944Sobrien{
84130803Smarcel  static char *regnames[] =
85130803Smarcel  {
86130803Smarcel    "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
87130803Smarcel    "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
88130803Smarcel    "SR", "PC"
89130803Smarcel    /* no float registers */
90130803Smarcel  };
91130803Smarcel
92130803Smarcel  if ((index >= (sizeof (regnames) / sizeof (regnames[0])))
93130803Smarcel      || (index < 0) || (index >= NUM_REGS))
94130803Smarcel    return NULL;
95130803Smarcel  else
96130803Smarcel    return regnames[index];
97130803Smarcel
98130803Smarcel}
99130803Smarcel
10098944Sobrienstatic struct target_ops dbug_ops;
10198944Sobrienstatic struct monitor_ops dbug_cmds;
10298944Sobrien
10398944Sobrienstatic char *dbug_inits[] =
10498944Sobrien{"\r", NULL};
10598944Sobrien
10698944Sobrien
10798944Sobrienstatic void
10898944Sobrieninit_dbug_cmds (void)
10998944Sobrien{
11098944Sobrien  dbug_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_GETMEM_NEEDS_RANGE | MO_FILL_USES_ADDR;
11198944Sobrien  dbug_cmds.init = dbug_inits;	/* Init strings */
11298944Sobrien  dbug_cmds.cont = "go\r";	/* continue command */
11398944Sobrien  dbug_cmds.step = "trace\r";	/* single step */
11498944Sobrien  dbug_cmds.stop = NULL;	/* interrupt command */
11598944Sobrien  dbug_cmds.set_break = "br %x\r";	/* set a breakpoint */
11698944Sobrien  dbug_cmds.clr_break = "br -r %x\r";	/* clear a breakpoint */
11798944Sobrien  dbug_cmds.clr_all_break = "br -r\r";	/* clear all breakpoints */
11898944Sobrien  dbug_cmds.fill = "bf.b %x %x %x\r";	/* fill (start end val) */
11998944Sobrien  dbug_cmds.setmem.cmdb = "mm.b %x %x\r";	/* setmem.cmdb (addr, value) */
12098944Sobrien  dbug_cmds.setmem.cmdw = "mm.w %x %x\r";	/* setmem.cmdw (addr, value) */
12198944Sobrien  dbug_cmds.setmem.cmdl = "mm.l %x %x\r";	/* setmem.cmdl (addr, value) */
12298944Sobrien  dbug_cmds.setmem.cmdll = NULL;	/* setmem.cmdll (addr, value) */
12398944Sobrien  dbug_cmds.setmem.resp_delim = NULL;	/* setmem.resp_delim */
12498944Sobrien  dbug_cmds.setmem.term = NULL;	/* setmem.term */
12598944Sobrien  dbug_cmds.setmem.term_cmd = NULL;	/* setmem.term_cmd */
12698944Sobrien  dbug_cmds.getmem.cmdb = "md.b %x %x\r";	/* getmem.cmdb (addr, addr2) */
12798944Sobrien  dbug_cmds.getmem.cmdw = "md.w %x %x\r";	/* getmem.cmdw (addr, addr2) */
12898944Sobrien  dbug_cmds.getmem.cmdl = "md.l %x %x\r";	/* getmem.cmdl (addr, addr2) */
12998944Sobrien  dbug_cmds.getmem.cmdll = NULL;	/* getmem.cmdll (addr, addr2) */
13098944Sobrien  dbug_cmds.getmem.resp_delim = ":";	/* getmem.resp_delim */
13198944Sobrien  dbug_cmds.getmem.term = NULL;	/* getmem.term */
13298944Sobrien  dbug_cmds.getmem.term_cmd = NULL;	/* getmem.term_cmd */
13398944Sobrien  dbug_cmds.setreg.cmd = "rm %s %x\r";	/* setreg.cmd (name, value) */
13498944Sobrien  dbug_cmds.setreg.resp_delim = NULL;	/* setreg.resp_delim */
13598944Sobrien  dbug_cmds.setreg.term = NULL;	/* setreg.term */
13698944Sobrien  dbug_cmds.setreg.term_cmd = NULL;	/* setreg.term_cmd */
13798944Sobrien  dbug_cmds.getreg.cmd = "rd %s\r";	/* getreg.cmd (name) */
13898944Sobrien  dbug_cmds.getreg.resp_delim = ":";	/* getreg.resp_delim */
13998944Sobrien  dbug_cmds.getreg.term = NULL;	/* getreg.term */
14098944Sobrien  dbug_cmds.getreg.term_cmd = NULL;	/* getreg.term_cmd */
14198944Sobrien  dbug_cmds.dump_registers = "rd\r";	/* dump_registers */
14298944Sobrien  dbug_cmds.register_pattern = "\\(\\w+\\) +:\\([0-9a-fA-F]+\\b\\)";	/* register_pattern */
14398944Sobrien  dbug_cmds.supply_register = dbug_supply_register;	/* supply_register */
14498944Sobrien  dbug_cmds.load_routine = NULL;	/* load_routine (defaults to SRECs) */
14598944Sobrien  dbug_cmds.load = "dl\r";	/* download command */
14698944Sobrien  dbug_cmds.loadresp = "\n";	/* load response */
14798944Sobrien  dbug_cmds.prompt = "dBUG>";	/* monitor command prompt */
14898944Sobrien  dbug_cmds.line_term = "\r";	/* end-of-line terminator */
14998944Sobrien  dbug_cmds.cmd_end = NULL;	/* optional command terminator */
15098944Sobrien  dbug_cmds.target = &dbug_ops;	/* target operations */
15198944Sobrien  dbug_cmds.stopbits = SERIAL_1_STOPBITS;	/* number of stop bits */
152130803Smarcel  dbug_cmds.regnames = NULL;	/* registers names */
153130803Smarcel  dbug_cmds.regname = dbug_regname;
15498944Sobrien  dbug_cmds.magic = MONITOR_OPS_MAGIC;	/* magic */
15598944Sobrien}				/* init_debug_ops */
15698944Sobrien
15798944Sobrienstatic void
15898944Sobriendbug_open (char *args, int from_tty)
15998944Sobrien{
16098944Sobrien  monitor_open (args, &dbug_cmds, from_tty);
16198944Sobrien}
16298944Sobrien
163130803Smarcelextern initialize_file_ftype _initialize_dbug_rom; /* -Wmissing-prototypes */
164130803Smarcel
16598944Sobrienvoid
16698944Sobrien_initialize_dbug_rom (void)
16798944Sobrien{
16898944Sobrien  init_dbug_cmds ();
16998944Sobrien  init_monitor_ops (&dbug_ops);
17098944Sobrien
17198944Sobrien  dbug_ops.to_shortname = "dbug";
17298944Sobrien  dbug_ops.to_longname = "dBUG monitor";
17398944Sobrien  dbug_ops.to_doc = "Debug via the dBUG monitor.\n\
17498944SobrienSpecify the serial device it is connected to (e.g. /dev/ttya).";
17598944Sobrien  dbug_ops.to_open = dbug_open;
17698944Sobrien
17798944Sobrien  add_target (&dbug_ops);
17898944Sobrien}
179