Cort Dougan <cort@cs.nmt.edu>
[deliverable/binutils-gdb.git] / gdb / dink32-rom.c
1 /* Remote debugging interface for DINK32 (PowerPC) ROM monitor for
2 GDB, the GNU debugger.
3 Copyright 1997 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21 #include "defs.h"
22 #include "gdbcore.h"
23 #include "target.h"
24 #include "monitor.h"
25 #include "serial.h"
26
27 static void dink32_open PARAMS ((char *args, int from_tty));
28
29 static void
30 dink32_supply_register (regname, regnamelen, val, vallen)
31 char *regname;
32 int regnamelen;
33 char *val;
34 int vallen;
35 {
36 int regno = 0, base = 0;
37
38 if (regnamelen < 2 || regnamelen > 4)
39 return;
40
41 switch (regname[0])
42 {
43 case 'R':
44 if (regname[1] < '0' || regname[1] > '9')
45 return;
46 if (regnamelen == 2)
47 regno = regname[1] - '0';
48 else if (regnamelen == 3 && regname[2] >= '0' && regname[2] <= '9')
49 regno = (regname[1] - '0') * 10 + (regname[2] - '0');
50 else
51 return;
52 break;
53 case 'F':
54 if (regname[1] != 'R' || regname[2] < '0' || regname[2] > '9')
55 return;
56 if (regnamelen == 3)
57 regno = 32 + regname[2] - '0';
58 else if (regnamelen == 4 && regname[3] >= '0' && regname[3] <= '9')
59 regno = 32 + (regname[2] - '0') * 10 + (regname[3] - '0');
60 else
61 return;
62 break;
63 case 'I':
64 if (regnamelen != 2 || regname[1] != 'P')
65 return;
66 regno = 64;
67 break;
68 case 'M':
69 if (regnamelen != 3 || regname[1] != 'S' || regname[2] != 'R')
70 return;
71 regno = 65;
72 break;
73 case 'C':
74 if (regnamelen != 2 || regname[1] != 'R')
75 return;
76 regno = 66;
77 break;
78 case 'S':
79 if (regnamelen != 4 || regname[1] != 'P' || regname[2] != 'R')
80 return;
81 else if (regname[3] == '8')
82 regno = 67;
83 else if (regname[3] == '9')
84 regno = 68;
85 else if (regname[3] == '1')
86 regno = 69;
87 else if (regname[3] == '0')
88 regno = 70;
89 else
90 return;
91 break;
92 default:
93 return;
94 }
95
96 monitor_supply_register (regno, val);
97 }
98
99 static void
100 dink32_load (monops, filename, from_tty)
101 struct monitor_ops *monops;
102 char *filename;
103 int from_tty;
104 {
105 extern int inferior_pid;
106
107 generic_load (filename, from_tty);
108
109 /* Finally, make the PC point at the start address */
110 if (exec_bfd)
111 write_pc (bfd_get_start_address (exec_bfd));
112
113 inferior_pid = 0; /* No process now */
114 }
115
116
117 /* This array of registers needs to match the indexes used by GDB. The
118 whole reason this exists is because the various ROM monitors use
119 different names than GDB does, and don't support all the registers
120 either. */
121
122 static char *dink32_regnames[NUM_REGS] =
123 {
124 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
125 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
126 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
127 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
128
129 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
130 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
131 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
132 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
133
134 "srr0", "msr", "cr", "lr", "ctr", "xer", "xer"
135 };
136
137 static struct target_ops dink32_ops;
138
139 static char *dink32_inits[] = {"\r", NULL};
140
141 static struct monitor_ops dink32_cmds;
142
143 static void
144 dink32_open (args, from_tty)
145 char *args;
146 int from_tty;
147 {
148 monitor_open (args, &dink32_cmds, from_tty);
149 }
150
151 void
152 _initialize_dink32_rom ()
153 {
154 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;
155 dink32_cmds.init = dink32_inits;
156 dink32_cmds.cont = "go +\r";
157 dink32_cmds.step = "tr +\r";
158 dink32_cmds.set_break = "bp 0x%x\r";
159 dink32_cmds.clr_break = "bp %d\r";
160 #if 0 /* Would need to follow strict alignment rules.. */
161 dink32_cmds.fill = "mf %x %x %x\r";
162 #endif
163 dink32_cmds.setmem.cmdb = "mm -b %x\r";
164 dink32_cmds.setmem.cmdw = "mm -w %x\r";
165 dink32_cmds.setmem.cmdl = "mm %x\r";
166 dink32_cmds.setmem.term = " ? ";
167 dink32_cmds.getmem.cmdb = "md %x\r";
168 dink32_cmds.getmem.resp_delim = " ";
169 dink32_cmds.setreg.cmd = "rm %s\r";
170 dink32_cmds.setreg.term = " ? ";
171 dink32_cmds.getreg.cmd = "rd %s\r";
172 dink32_cmds.getreg.resp_delim = ": ";
173 dink32_cmds.dump_registers = "rd r\r";
174 dink32_cmds.register_pattern = "\\(\\w+\\) +=\\([0-9a-fA-F]+\\b\\)";
175 dink32_cmds.supply_register = dink32_supply_register;
176 /* S-record download, via "keyboard port". */
177 dink32_cmds.load = "dl -k\r";
178 dink32_cmds.loadresp = "Set Input Port : set to Keyboard Port\r";
179 #if 0 /* slow load routine not needed if S-records work... */
180 dink32_cmds.load_routine = dink32_load;
181 #endif
182 dink32_cmds.prompt = "DINK32_603 >>";
183 dink32_cmds.line_term = "\r";
184 dink32_cmds.target = &dink32_ops;
185 dink32_cmds.stopbits = SERIAL_1_STOPBITS;
186 dink32_cmds.regnames = dink32_regnames;
187 dink32_cmds.magic = MONITOR_OPS_MAGIC;
188
189 init_monitor_ops (&dink32_ops);
190
191 dink32_ops.to_shortname = "dink32";
192 dink32_ops.to_longname = "DINK32 monitor";
193 dink32_ops.to_doc = "Debug using the DINK32 monitor.\n\
194 Specify the serial device it is connected to (e.g. /dev/ttya).";
195 dink32_ops.to_open = dink32_open;
196
197 add_target (&dink32_ops);
198 }
This page took 0.035972 seconds and 4 git commands to generate.