1130812Smarcel/* Remote debugging interface for PPCbug (PowerPC) Rom monitor 2130812Smarcel for GDB, the GNU debugger. 3130812Smarcel Copyright 1995, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. 4130812Smarcel 5130812Smarcel Written by Stu Grossman of Cygnus Support 6130812Smarcel 7130812Smarcel This file is part of GDB. 8130812Smarcel 9130812Smarcel This program is free software; you can redistribute it and/or modify 10130812Smarcel it under the terms of the GNU General Public License as published by 11130812Smarcel the Free Software Foundation; either version 2 of the License, or 12130812Smarcel (at your option) any later version. 13130812Smarcel 14130812Smarcel This program is distributed in the hope that it will be useful, 15130812Smarcel but WITHOUT ANY WARRANTY; without even the implied warranty of 16130812Smarcel MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17130812Smarcel GNU General Public License for more details. 18130812Smarcel 19130812Smarcel You should have received a copy of the GNU General Public License 20130812Smarcel along with this program; if not, write to the Free Software 21130812Smarcel Foundation, Inc., 59 Temple Place - Suite 330, 22130812Smarcel Boston, MA 02111-1307, USA. */ 23130812Smarcel 24130812Smarcel#include "defs.h" 25130812Smarcel#include "gdbcore.h" 26130812Smarcel#include "target.h" 27130812Smarcel#include "monitor.h" 28130812Smarcel#include "serial.h" 29130812Smarcel#include "regcache.h" 30130812Smarcel 31130812Smarcelstatic void 32130812Smarcelppcbug_supply_register (char *regname, int regnamelen, char *val, int vallen) 33130812Smarcel{ 34130812Smarcel int regno = 0; 35130812Smarcel 36130812Smarcel if (regnamelen < 2 || regnamelen > 4) 37130812Smarcel return; 38130812Smarcel 39130812Smarcel switch (regname[0]) 40130812Smarcel { 41130812Smarcel case 'R': 42130812Smarcel if (regname[1] < '0' || regname[1] > '9') 43130812Smarcel return; 44130812Smarcel if (regnamelen == 2) 45130812Smarcel regno = regname[1] - '0'; 46130812Smarcel else if (regnamelen == 3 && regname[2] >= '0' && regname[2] <= '9') 47130812Smarcel regno = (regname[1] - '0') * 10 + (regname[2] - '0'); 48130812Smarcel else 49130812Smarcel return; 50130812Smarcel break; 51130812Smarcel case 'F': 52130812Smarcel if (regname[1] != 'R' || regname[2] < '0' || regname[2] > '9') 53130812Smarcel return; 54130812Smarcel if (regnamelen == 3) 55130812Smarcel regno = 32 + regname[2] - '0'; 56130812Smarcel else if (regnamelen == 4 && regname[3] >= '0' && regname[3] <= '9') 57130812Smarcel regno = 32 + (regname[2] - '0') * 10 + (regname[3] - '0'); 58130812Smarcel else 59130812Smarcel return; 60130812Smarcel break; 61130812Smarcel case 'I': 62130812Smarcel if (regnamelen != 2 || regname[1] != 'P') 63130812Smarcel return; 64130812Smarcel regno = 64; 65130812Smarcel break; 66130812Smarcel case 'M': 67130812Smarcel if (regnamelen != 3 || regname[1] != 'S' || regname[2] != 'R') 68130812Smarcel return; 69130812Smarcel regno = 65; 70130812Smarcel break; 71130812Smarcel case 'C': 72130812Smarcel if (regnamelen != 2 || regname[1] != 'R') 73130812Smarcel return; 74130812Smarcel regno = 66; 75130812Smarcel break; 76130812Smarcel case 'S': 77130812Smarcel if (regnamelen != 4 || regname[1] != 'P' || regname[2] != 'R') 78130812Smarcel return; 79130812Smarcel else if (regname[3] == '8') 80130812Smarcel regno = 67; 81130812Smarcel else if (regname[3] == '9') 82130812Smarcel regno = 68; 83130812Smarcel else if (regname[3] == '1') 84130812Smarcel regno = 69; 85130812Smarcel else if (regname[3] == '0') 86130812Smarcel regno = 70; 87130812Smarcel else 88130812Smarcel return; 89130812Smarcel break; 90130812Smarcel default: 91130812Smarcel return; 92130812Smarcel } 93130812Smarcel 94130812Smarcel monitor_supply_register (regno, val); 95130812Smarcel} 96130812Smarcel 97130812Smarcel/* 98130812Smarcel * This array of registers needs to match the indexes used by GDB. The 99130812Smarcel * whole reason this exists is because the various ROM monitors use 100130812Smarcel * different names than GDB does, and don't support all the 101130812Smarcel * registers either. So, typing "info reg sp" becomes an "A7". 102130812Smarcel */ 103130812Smarcel 104130812Smarcelstatic char *ppcbug_regnames[] = 105130812Smarcel{ 106130812Smarcel "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 107130812Smarcel "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 108130812Smarcel "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 109130812Smarcel "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 110130812Smarcel 111130812Smarcel "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "fr6", "fr7", 112130812Smarcel "fr8", "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15", 113130812Smarcel "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23", 114130812Smarcel "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31", 115130812Smarcel 116130812Smarcel/* pc ps cnd lr cnt xer mq */ 117130812Smarcel "ip", "msr", "cr", "spr8", "spr9", "spr1", "spr0" 118130812Smarcel}; 119130812Smarcel 120130812Smarcel/* 121130812Smarcel * Define the monitor command strings. Since these are passed directly 122130812Smarcel * through to a printf style function, we need can include formatting 123130812Smarcel * strings. We also need a CR or LF on the end. 124130812Smarcel */ 125130812Smarcel 126130812Smarcelstatic struct target_ops ppcbug_ops0; 127130812Smarcelstatic struct target_ops ppcbug_ops1; 128130812Smarcel 129130812Smarcelstatic char *ppcbug_inits[] = 130130812Smarcel{"\r", NULL}; 131130812Smarcel 132130812Smarcelstatic void 133130812Smarcelinit_ppc_cmds (char *LOAD_CMD, 134130812Smarcel struct monitor_ops *OPS, 135130812Smarcel struct target_ops *targops) 136130812Smarcel{ 137130812Smarcel OPS->flags = MO_CLR_BREAK_USES_ADDR | MO_HANDLE_NL; 138130812Smarcel OPS->init = ppcbug_inits; /* Init strings */ 139130812Smarcel OPS->cont = "g\r"; /* continue command */ 140130812Smarcel OPS->step = "t\r"; /* single step */ 141130812Smarcel OPS->stop = NULL; /* interrupt command */ 142130812Smarcel OPS->set_break = "br %x\r"; /* set a breakpoint */ 143130812Smarcel OPS->clr_break = "nobr %x\r"; /* clear a breakpoint */ 144130812Smarcel OPS->clr_all_break = "nobr\r"; /* clear all breakpoints */ 145130812Smarcel OPS->fill = "bf %x:%x %x;b\r"; /* fill (start count val) */ 146130812Smarcel OPS->setmem.cmdb = "ms %x %02x\r"; /* setmem.cmdb (addr, value) */ 147130812Smarcel OPS->setmem.cmdw = "ms %x %04x\r"; /* setmem.cmdw (addr, value) */ 148130812Smarcel OPS->setmem.cmdl = "ms %x %08x\r"; /* setmem.cmdl (addr, value) */ 149130812Smarcel OPS->setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ 150130812Smarcel OPS->setmem.resp_delim = NULL; /* setreg.resp_delim */ 151130812Smarcel OPS->setmem.term = NULL; /* setreg.term */ 152130812Smarcel OPS->setmem.term_cmd = NULL; /* setreg.term_cmd */ 153130812Smarcel OPS->getmem.cmdb = "md %x:%x;b\r"; /* getmem.cmdb (addr, len) */ 154130812Smarcel OPS->getmem.cmdw = "md %x:%x;b\r"; /* getmem.cmdw (addr, len) */ 155130812Smarcel OPS->getmem.cmdl = "md %x:%x;b\r"; /* getmem.cmdl (addr, len) */ 156130812Smarcel OPS->getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */ 157130812Smarcel OPS->getmem.resp_delim = " "; /* getmem.resp_delim */ 158130812Smarcel OPS->getmem.term = NULL; /* getmem.term */ 159130812Smarcel OPS->getmem.term_cmd = NULL; /* getmem.term_cmd */ 160130812Smarcel OPS->setreg.cmd = "rs %s %x\r"; /* setreg.cmd (name, value) */ 161130812Smarcel OPS->setreg.resp_delim = NULL; /* setreg.resp_delim */ 162130812Smarcel OPS->setreg.term = NULL; /* setreg.term */ 163130812Smarcel OPS->setreg.term_cmd = NULL; /* setreg.term_cmd */ 164130812Smarcel OPS->getreg.cmd = "rs %s\r"; /* getreg.cmd (name) */ 165130812Smarcel OPS->getreg.resp_delim = "="; /* getreg.resp_delim */ 166130812Smarcel OPS->getreg.term = NULL; /* getreg.term */ 167130812Smarcel OPS->getreg.term_cmd = NULL; /* getreg.term_cmd */ 168130812Smarcel OPS->register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)"; /* register_pattern */ 169130812Smarcel OPS->supply_register = ppcbug_supply_register; /* supply_register */ 170130812Smarcel OPS->dump_registers = "rd\r"; /* dump all registers */ 171130812Smarcel OPS->load_routine = NULL; /* load_routine (defaults to SRECs) */ 172130812Smarcel OPS->load = LOAD_CMD; /* download command */ 173130812Smarcel OPS->loadresp = NULL; /* load response */ 174130812Smarcel OPS->prompt = "PPC1-Bug>"; /* monitor command prompt */ 175130812Smarcel OPS->line_term = "\r"; /* end-of-line terminator */ 176130812Smarcel OPS->cmd_end = NULL; /* optional command terminator */ 177130812Smarcel OPS->target = targops; /* target operations */ 178130812Smarcel OPS->stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ 179130812Smarcel OPS->regnames = ppcbug_regnames; /* registers names */ 180130812Smarcel OPS->magic = MONITOR_OPS_MAGIC; /* magic */ 181130812Smarcel} 182130812Smarcel 183130812Smarcel 184130812Smarcelstatic struct monitor_ops ppcbug_cmds0; 185130812Smarcelstatic struct monitor_ops ppcbug_cmds1; 186130812Smarcel 187130812Smarcelstatic void 188130812Smarcelppcbug_open0 (char *args, int from_tty) 189130812Smarcel{ 190130812Smarcel monitor_open (args, &ppcbug_cmds0, from_tty); 191130812Smarcel} 192130812Smarcel 193130812Smarcelstatic void 194130812Smarcelppcbug_open1 (char *args, int from_tty) 195130812Smarcel{ 196130812Smarcel monitor_open (args, &ppcbug_cmds1, from_tty); 197130812Smarcel} 198130812Smarcel 199130812Smarcelextern initialize_file_ftype _initialize_ppcbug_rom; /* -Wmissing-prototypes */ 200130812Smarcel 201130812Smarcelvoid 202130812Smarcel_initialize_ppcbug_rom (void) 203130812Smarcel{ 204130812Smarcel init_ppc_cmds ("lo 0\r", &ppcbug_cmds0, &ppcbug_ops0); 205130812Smarcel init_ppc_cmds ("lo 1\r", &ppcbug_cmds1, &ppcbug_ops1); 206130812Smarcel init_monitor_ops (&ppcbug_ops0); 207130812Smarcel 208130812Smarcel ppcbug_ops0.to_shortname = "ppcbug"; 209130812Smarcel ppcbug_ops0.to_longname = "PowerPC PPCBug monitor on port 0"; 210130812Smarcel ppcbug_ops0.to_doc = "Debug via the PowerPC PPCBug monitor using port 0.\n\ 211130812SmarcelSpecify the serial device it is connected to (e.g. /dev/ttya)."; 212130812Smarcel ppcbug_ops0.to_open = ppcbug_open0; 213130812Smarcel 214130812Smarcel add_target (&ppcbug_ops0); 215130812Smarcel 216130812Smarcel init_monitor_ops (&ppcbug_ops1); 217130812Smarcel 218130812Smarcel ppcbug_ops1.to_shortname = "ppcbug1"; 219130812Smarcel ppcbug_ops1.to_longname = "PowerPC PPCBug monitor on port 1"; 220130812Smarcel ppcbug_ops1.to_doc = "Debug via the PowerPC PPCBug monitor using port 1.\n\ 221130812SmarcelSpecify the serial device it is connected to (e.g. /dev/ttya)."; 222130812Smarcel ppcbug_ops1.to_open = ppcbug_open1; 223130812Smarcel 224130812Smarcel add_target (&ppcbug_ops1); 225130812Smarcel} 226