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