146283Sdfr/* Remote debugging interface for DINK32 (PowerPC) ROM monitor for 246283Sdfr GDB, the GNU debugger. 398944Sobrien Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc. 446283Sdfr 598944Sobrien This file is part of GDB. 646283Sdfr 798944Sobrien This program is free software; you can redistribute it and/or modify 898944Sobrien it under the terms of the GNU General Public License as published by 998944Sobrien the Free Software Foundation; either version 2 of the License, or 1098944Sobrien (at your option) any later version. 1146283Sdfr 1298944Sobrien This program is distributed in the hope that it will be useful, 1398944Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1498944Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1598944Sobrien GNU General Public License for more details. 1646283Sdfr 1798944Sobrien You should have received a copy of the GNU General Public License 1898944Sobrien along with this program; if not, write to the Free Software 1998944Sobrien Foundation, Inc., 59 Temple Place - Suite 330, 2098944Sobrien Boston, MA 02111-1307, USA. */ 2146283Sdfr 2246283Sdfr#include "defs.h" 2346283Sdfr#include "gdbcore.h" 2446283Sdfr#include "target.h" 2546283Sdfr#include "monitor.h" 2646283Sdfr#include "serial.h" 2798944Sobrien#include "symfile.h" /* For generic_load() */ 2898944Sobrien#include "inferior.h" /* For write_pc() */ 2998944Sobrien#include "regcache.h" 3046283Sdfr 3198944Sobrienstatic void dink32_open (char *args, int from_tty); 3246283Sdfr 3346283Sdfrstatic void 3498944Sobriendink32_supply_register (char *regname, int regnamelen, char *val, int vallen) 3546283Sdfr{ 3698944Sobrien int regno = 0; 3746283Sdfr 3846283Sdfr if (regnamelen < 2 || regnamelen > 4) 3946283Sdfr return; 4046283Sdfr 4146283Sdfr switch (regname[0]) 4246283Sdfr { 4346283Sdfr case 'R': 4446283Sdfr if (regname[1] < '0' || regname[1] > '9') 4546283Sdfr return; 4646283Sdfr if (regnamelen == 2) 4746283Sdfr regno = regname[1] - '0'; 4846283Sdfr else if (regnamelen == 3 && regname[2] >= '0' && regname[2] <= '9') 4946283Sdfr regno = (regname[1] - '0') * 10 + (regname[2] - '0'); 5046283Sdfr else 5146283Sdfr return; 5246283Sdfr break; 5346283Sdfr case 'F': 5446283Sdfr if (regname[1] != 'R' || regname[2] < '0' || regname[2] > '9') 5546283Sdfr return; 5646283Sdfr if (regnamelen == 3) 5746283Sdfr regno = 32 + regname[2] - '0'; 5846283Sdfr else if (regnamelen == 4 && regname[3] >= '0' && regname[3] <= '9') 5946283Sdfr regno = 32 + (regname[2] - '0') * 10 + (regname[3] - '0'); 6046283Sdfr else 6146283Sdfr return; 6246283Sdfr break; 6346283Sdfr case 'I': 6446283Sdfr if (regnamelen != 2 || regname[1] != 'P') 6546283Sdfr return; 6646283Sdfr regno = 64; 6746283Sdfr break; 6846283Sdfr case 'M': 6946283Sdfr if (regnamelen != 3 || regname[1] != 'S' || regname[2] != 'R') 7046283Sdfr return; 7146283Sdfr regno = 65; 7246283Sdfr break; 7346283Sdfr case 'C': 7446283Sdfr if (regnamelen != 2 || regname[1] != 'R') 7546283Sdfr return; 7646283Sdfr regno = 66; 7746283Sdfr break; 7846283Sdfr case 'S': 7946283Sdfr if (regnamelen != 4 || regname[1] != 'P' || regname[2] != 'R') 8046283Sdfr return; 8146283Sdfr else if (regname[3] == '8') 8246283Sdfr regno = 67; 8346283Sdfr else if (regname[3] == '9') 8446283Sdfr regno = 68; 8546283Sdfr else if (regname[3] == '1') 8646283Sdfr regno = 69; 8746283Sdfr else if (regname[3] == '0') 8846283Sdfr regno = 70; 8946283Sdfr else 9046283Sdfr return; 9146283Sdfr break; 9246283Sdfr default: 9346283Sdfr return; 9446283Sdfr } 9546283Sdfr 9646283Sdfr monitor_supply_register (regno, val); 9746283Sdfr} 9846283Sdfr 9946283Sdfr/* This array of registers needs to match the indexes used by GDB. The 10046283Sdfr whole reason this exists is because the various ROM monitors use 10146283Sdfr different names than GDB does, and don't support all the registers 10246283Sdfr either. */ 10346283Sdfr 10498944Sobrienstatic char *dink32_regnames[] = 10546283Sdfr{ 10698944Sobrien "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 10798944Sobrien "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 10898944Sobrien "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 10998944Sobrien "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31", 11046283Sdfr 11198944Sobrien "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", 11298944Sobrien "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", 11398944Sobrien "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", 11498944Sobrien "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", 11546283Sdfr 11698944Sobrien "srr0", "msr", "cr", "lr", "ctr", "xer", "xer" 11746283Sdfr}; 11846283Sdfr 11946283Sdfrstatic struct target_ops dink32_ops; 12046283Sdfr 12198944Sobrienstatic char *dink32_inits[] = 12298944Sobrien{"\r", NULL}; 12346283Sdfr 12446283Sdfrstatic struct monitor_ops dink32_cmds; 12546283Sdfr 12646283Sdfrstatic void 12798944Sobriendink32_open (char *args, int from_tty) 12846283Sdfr{ 12946283Sdfr monitor_open (args, &dink32_cmds, from_tty); 13046283Sdfr} 13146283Sdfr 132130803Smarcelextern initialize_file_ftype _initialize_dink32_rom; /* -Wmissing-prototypes */ 133130803Smarcel 13446283Sdfrvoid 13598944Sobrien_initialize_dink32_rom (void) 13646283Sdfr{ 13746283Sdfr dink32_cmds.flags = MO_HEX_PREFIX | MO_GETMEM_NEEDS_RANGE | MO_FILL_USES_ADDR | MO_HANDLE_NL | MO_32_REGS_PAIRED | MO_SETREG_INTERACTIVE | MO_SETMEM_INTERACTIVE | MO_GETMEM_16_BOUNDARY | MO_CLR_BREAK_1_BASED | MO_SREC_ACK | MO_SREC_ACK_ROTATE; 13846283Sdfr dink32_cmds.init = dink32_inits; 13946283Sdfr dink32_cmds.cont = "go +\r"; 14046283Sdfr dink32_cmds.step = "tr +\r"; 14146283Sdfr dink32_cmds.set_break = "bp 0x%x\r"; 14246283Sdfr dink32_cmds.clr_break = "bp %d\r"; 14398944Sobrien#if 0 /* Would need to follow strict alignment rules.. */ 14446283Sdfr dink32_cmds.fill = "mf %x %x %x\r"; 14546283Sdfr#endif 14646283Sdfr dink32_cmds.setmem.cmdb = "mm -b %x\r"; 14746283Sdfr dink32_cmds.setmem.cmdw = "mm -w %x\r"; 14846283Sdfr dink32_cmds.setmem.cmdl = "mm %x\r"; 14946283Sdfr dink32_cmds.setmem.term = " ? "; 15046283Sdfr dink32_cmds.getmem.cmdb = "md %x\r"; 15146283Sdfr dink32_cmds.getmem.resp_delim = " "; 15246283Sdfr dink32_cmds.setreg.cmd = "rm %s\r"; 15346283Sdfr dink32_cmds.setreg.term = " ? "; 15446283Sdfr dink32_cmds.getreg.cmd = "rd %s\r"; 15546283Sdfr dink32_cmds.getreg.resp_delim = ": "; 15646283Sdfr dink32_cmds.dump_registers = "rd r\r"; 15746283Sdfr dink32_cmds.register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)"; 15846283Sdfr dink32_cmds.supply_register = dink32_supply_register; 15946283Sdfr /* S-record download, via "keyboard port". */ 16046283Sdfr dink32_cmds.load = "dl -k\r"; 16146283Sdfr dink32_cmds.loadresp = "Set Input Port : set to Keyboard Port\r"; 16246283Sdfr dink32_cmds.prompt = "DINK32_603 >>"; 16346283Sdfr dink32_cmds.line_term = "\r"; 16446283Sdfr dink32_cmds.target = &dink32_ops; 16546283Sdfr dink32_cmds.stopbits = SERIAL_1_STOPBITS; 16646283Sdfr dink32_cmds.regnames = dink32_regnames; 16746283Sdfr dink32_cmds.magic = MONITOR_OPS_MAGIC; 16846283Sdfr 16946283Sdfr init_monitor_ops (&dink32_ops); 17046283Sdfr 17146283Sdfr dink32_ops.to_shortname = "dink32"; 17246283Sdfr dink32_ops.to_longname = "DINK32 monitor"; 17346283Sdfr dink32_ops.to_doc = "Debug using the DINK32 monitor.\n\ 17446283SdfrSpecify the serial device it is connected to (e.g. /dev/ttya)."; 17546283Sdfr dink32_ops.to_open = dink32_open; 17646283Sdfr 17746283Sdfr add_target (&dink32_ops); 17846283Sdfr} 179