Remote protocol for d10v. Mainly responsible for translating GDB d10v
[deliverable/binutils-gdb.git] / gdb / remote-d10v.c
CommitLineData
0c3ab0a1
AC
1/* Remote target communications for d10v connected via a serial line.
2 Copyright 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997 Free
3 Software Foundation, Inc.
4
5This file is part of GDB.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21#include "defs.h"
22#include "gdb_string.h"
23#include <fcntl.h>
24#include "frame.h"
25#include "inferior.h"
26#include "bfd.h"
27#include "symfile.h"
28#include "target.h"
29#include "wait.h"
30/*#include "terminal.h"*/
31#include "gdbcmd.h"
32#include "objfiles.h"
33#include "gdb-stabs.h"
34#include "gdbthread.h"
35
36#include "dcache.h"
37
38#ifdef USG
39#include <sys/types.h>
40#endif
41
42#include <signal.h>
43#include "serial.h"
44
45/* Prototypes for local functions */
46
47static int remote_d10v_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
48 int len, int should_write,
49 struct target_ops *target));
50
51static void remote_d10v_open PARAMS ((char *name, int from_tty));
52
53static void remote_d10v_mourn PARAMS ((void));
54
55static void initialize_remote_d10v_ops PARAMS ((int copy_remote));
56
57/* Define the target subroutine names */
58
59struct target_ops remote_d10v_ops;
60extern struct target_ops remote_ops;
61extern struct target_ops extended_remote_ops;
62struct target_ops *inherited_ops = &extended_remote_ops;
63
64void
65init_remote_d10v_ops (copy_remote)
66 int copy_remote;
67{
68 printf_filtered ("Opening d10v ...\n");
69 if (copy_remote)
70 memcpy (&remote_d10v_ops, inherited_ops, sizeof remote_d10v_ops);
71 remote_d10v_ops.to_shortname = "d10v";
72 remote_d10v_ops.to_longname = "Remote d10v serial target in gdb-specific protocol";
73 remote_d10v_ops.to_doc = "Use a remote d10v via a serial line, using a gdb-specific protocol.\n\
74Specify the serial device it is connected to (e.g. /dev/ttya).";
75 remote_d10v_ops.to_open = remote_d10v_open;
76 remote_d10v_ops.to_xfer_memory = remote_d10v_xfer_memory;
77 remote_d10v_ops.to_mourn_inferior = remote_d10v_mourn;
78 remote_d10v_ops.to_magic = OPS_MAGIC;
79}
80
81
82/* Open a connection to a remote debugger.
83 NAME is the filename used for communication. */
84
85static void
86remote_d10v_open (name, from_tty)
87 char *name;
88 int from_tty;
89{
90 init_remote_d10v_ops (1);
91 open_remote_target (name, from_tty, &remote_d10v_ops,
92 inherited_ops == &extended_remote_ops);
93}
94
95
96/* Worker function for remote_mourn. */
97static void
98remote_d10v_mourn ()
99{
100 if (inherited_ops == &remote_ops)
101 {
102 unpush_target (&remote_d10v_ops);
103 generic_mourn_inferior ();
104 }
105 /* see remote.c:extended_remote_mourn() for why an extended remote
106 target doesn't mourn */
107}
108
109
110/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
111 to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
112 nonzero. Returns length of data written or read; 0 for error. */
113
114/* ARGSUSED */
115static int
116remote_d10v_xfer_memory(memaddr, myaddr, nr_bytes, write_p, target)
117 CORE_ADDR memaddr;
118 char *myaddr;
119 int nr_bytes;
120 int write_p;
121 struct target_ops *target; /* ignored */
122{
123 CORE_ADDR phys;
124 CORE_ADDR seg;
125 CORE_ADDR off;
126 char *from = "unknown";
127 char *to = "unknown";
128 unsigned short imap0 = read_register (IMAP0_REGNUM);
129 unsigned short imap1 = read_register (IMAP1_REGNUM);
130 unsigned short dmap = read_register (DMAP_REGNUM);
131
132 /* GDB interprets addresses as:
133
134 0x00xxxxxx: Logical data address segment (DMAP translated memory)
135 0x01xxxxxx: Logical instruction address segment (IMAP translated memory)
136 0x10xxxxxx: Physical data memory segment (On-chip data memory)
137 0x11xxxxxx: Physical instruction memory segment (On-chip insn memory)
138 0x12xxxxxx: Phisical unified memory segment (Unified memory)
139
140 The remote d10v board interprets addresses as:
141
142 0x00xxxxxx: Phisical unified memory segment (Unified memory)
143 0x01xxxxxx: Physical instruction memory segment (On-chip insn memory)
144 0x02xxxxxx: Physical data memory segment (On-chip data memory)
145
146 Translate according to current IMAP/dmap registers */
147
148 enum {
149 targ_unified = 0x00000000,
150 targ_insn = 0x01000000,
151 targ_data = 0x02000000,
152 };
153
154 seg = (memaddr >> 24);
155 off = (memaddr & 0xffffffL);
156
157 switch (seg)
158 {
159 case 0x00: /* in logical data address segment */
160 {
161 from = "logical-data";
162 if (off <= 0x7fffL)
163 {
164 /* On chip data */
165 phys = targ_data + off;
166 if (off + nr_bytes > 0x7fffL)
167 /* don't cross VM boundary */
168 nr_bytes = 0x7fffL - off + 1;
169 to = "chip-data";
170 }
171 else if (off <= 0xbfffL)
172 {
173 short map = dmap;
174 if (map & 0x1000)
175 {
176 /* Instruction memory */
177 phys = targ_insn | ((map & 0xf) << 14) | (off & 0x3fff);
178 to = "chip-insn";
179 }
180 else
181 {
182 /* Unified memory */
183 phys = targ_unified | ((map & 0x3ff) << 14) | (off & 0x3fff);
184 to = "unified";
185 }
186 if (off + nr_bytes > 0xbfffL)
187 /* don't cross VM boundary */
188 nr_bytes = (0xbfffL - off + 1);
189 }
190 else
191 {
192 /* Logical address out side of data segments, not supported */
193 return (0);
194 }
195 break;
196 }
197
198 case 0x01: /* in logical instruction address segment */
199 {
200 short map;
201 from = "logical-insn";
202 if (off <= 0x1ffffL)
203 {
204 map = imap0;
205 }
206 else if (off <= 0x3ffffL)
207 {
208 map = imap1;
209 }
210 else
211 {
212 /* Logical address outside of IMAP[01] segment, not
213 supported */
214 return (0);
215 }
216 if ((off & 0x1ffff) + nr_bytes > 0x1ffffL)
217 {
218 /* don't cross VM boundary */
219 nr_bytes = 0x1ffffL - (off & 0x1ffffL) + 1;
220 }
221 if (map & 0x1000)
222 /* Instruction memory */
223 {
224 phys = targ_insn | off;
225 to = "chip-insn";
226 }
227 else
228 {
229 phys = ((map & 0x7fL) << 17) + (off & 0x1ffffL);
230 if (phys > 0xffffffL)
231 /* Address outside of unified address segment */
232 return (0);
233 phys |= targ_unified;
234 to = "unified";
235 }
236 break;
237 }
238
239 case 0x10: /* Physical data memory segment */
240 from = "phys-data";
241 phys = targ_data | off;
242 to = "chip-data";
243 break;
244
245 case 0x11: /* Physical instruction memory */
246 from = "phys-insn";
247 phys = targ_insn | off;
248 to = "chip-insn";
249 break;
250
251 case 0x12: /* Physical unified memory */
252 from = "phys-unified";
253 phys = targ_unified | off;
254 to = "unified";
255 break;
256
257 default:
258 return (0);
259 }
260
261
262 printf_unfiltered ("%s-xfer: 0x%08lx -> 0x%08lx imap0=%04x imap1=%04x, dmap=%04x, %s->%s, %d bytes\n",
263 (write_p ? "wr" : "rd"),
264 (long) memaddr,
265 (long) phys,
266 (int) imap0, (int) imap1, (int) dmap,
267 from, to,
268 (int) nr_bytes);
269
270 return inherited_ops->to_xfer_memory (phys, myaddr, nr_bytes, write_p, target);
271}
272
273
274void
275_initialize_remote_d10v ()
276{
277 init_remote_d10v_ops (0);
278 add_target (&remote_d10v_ops);
279}
This page took 0.044754 seconds and 4 git commands to generate.