]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/arm/kid.c
import gdb-2000-02-04 snapshot
[thirdparty/binutils-gdb.git] / sim / arm / kid.c
CommitLineData
c906108c
SS
1/* kid.c -- ARMulator RDP/RDI interface: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18/*****************************************************************/
19/* The child process continues here... */
20/* It waits on a pipe from the parent and translates the RDP */
21/* messages into RDI calls to the ARMulator passing RDP replies */
22/* back up a pipe to the parent. */
23/*****************************************************************/
24
25#include <sys/types.h>
26#include <signal.h>
27
28#include "armdefs.h"
29#include "dbg_conf.h"
30#include "dbg_hif.h"
31#include "dbg_rdi.h"
32#include "gdbhost.h"
33#include "communicate.h"
34
35/* The pipes between the two processes */
36extern int mumkid[2];
37extern int kidmum[2];
38
39/* The maximum number of file descriptors */
40extern int nfds;
41
42/* The machine name */
43#define MAXHOSTNAMELENGTH 64
44extern char localhost[MAXHOSTNAMELENGTH + 1];
45
46/* The socket number */
47extern unsigned int socketnumber;
48
49/* RDI interface */
50extern const struct RDIProcVec armul_rdi;
51
52static int MYrdp_level = 0;
53
54static int rdi_state = 0;
55
56/**************************************************************/
57/* Signal handler that terminates excecution in the ARMulator */
58/**************************************************************/
dfcd3bfb
JM
59void
60kid_handlesignal (int sig)
61{
c906108c 62#ifdef DEBUG
dfcd3bfb 63 fprintf (stderr, "Terminate ARMulator excecution\n");
c906108c 64#endif
dfcd3bfb
JM
65 if (sig != SIGUSR1)
66 {
67 fprintf (stderr, "Unsupported signal.\n");
68 return;
69 }
70 armul_rdi.info (RDISignal_Stop, (unsigned long *) 0, (unsigned long *) 0);
c906108c
SS
71}
72
73/********************************************************************/
74/* Waits on a pipe from the socket demon for RDP and */
75/* acts as an RDP to RDI interpreter on the front of the ARMulator. */
76/********************************************************************/
dfcd3bfb
JM
77void
78kid ()
79{
c906108c
SS
80 char *p, *q;
81 int i, j, k;
82 long outofthebag;
83 unsigned char c, d, message;
84 ARMword x, y, z;
85 struct sigaction action;
86 PointHandle point;
87 Dbg_ConfigBlock config;
88 Dbg_HostosInterface hostif;
89 struct Dbg_MCState *MCState;
90 char command_line[256];
91 struct fd_set readfds;
dfcd3bfb 92
c906108c
SS
93 /* Setup a signal handler for SIGUSR1 */
94 action.sa_handler = kid_handlesignal;
95 action.sa_mask = 0;
96 action.sa_flags = 0;
dfcd3bfb
JM
97
98 sigaction (SIGUSR1, &action, (struct sigaction *) 0);
99
c906108c 100 while (1)
dfcd3bfb
JM
101 {
102 /* Wait for ever */
103 FD_ZERO (&readfds);
104 FD_SET (mumkid[0], &readfds);
105
106 i = select (nfds, &readfds,
107 (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0);
c906108c 108
dfcd3bfb
JM
109 if (i < 0)
110 {
111 perror ("select");
c906108c 112 }
dfcd3bfb
JM
113
114 if (read (mumkid[0], &message, 1) < 1)
115 {
116 perror ("read");
c906108c 117 }
c906108c 118
dfcd3bfb 119 switch (message)
c906108c 120 {
dfcd3bfb
JM
121 case RDP_Start:
122 /* Open and/or Initialise */
123 BAG_newbag ();
124
125 MYread_char (mumkid[0], &c); /* type */
126 MYread_word (mumkid[0], &x); /* memorysize */
127 if (c & 0x2)
128 MYread_char (mumkid[0], &d); /* speed */
129 config.processor = 0;
130 config.memorysize = x;
131 config.bytesex = (c & 0x4) ? RDISex_Big : RDISex_Little;
132 if (c & 0x8)
133 config.bytesex = RDISex_DontCare;
134
135 hostif.dbgprint = myprint;
136 hostif.dbgpause = mypause;
137 hostif.dbgarg = stdout;
138 hostif.writec = mywritec;
139 hostif.readc = myreadc;
140 hostif.write = mywrite;
141 hostif.gets = mygets;
142 hostif.reset = mypause; /* do nothing */
143 hostif.resetarg = "Do I love resetting or what!\n";
144
145 if (rdi_state)
146 {
147 /* we have restarted, so kill off the existing run. */
148 /* armul_rdi.close(); */
149 }
150 i = armul_rdi.open (c & 0x3, &config, &hostif, MCState);
151 rdi_state = 1;
152
c906108c 153 MYwrite_char (kidmum[1], RDP_Return);
c906108c 154 MYwrite_char (kidmum[1], (unsigned char) i);
dfcd3bfb
JM
155
156 x = ~0x4;
157 armul_rdi.info (RDIVector_Catch, &x, 0);
158
c906108c
SS
159 break;
160
dfcd3bfb
JM
161 case RDP_End:
162 /* Close and Finalise */
163 i = armul_rdi.close ();
164 rdi_state = 0;
c906108c
SS
165 MYwrite_char (kidmum[1], RDP_Return);
166 MYwrite_char (kidmum[1], (unsigned char) i);
167 break;
168
dfcd3bfb
JM
169 case RDP_Read:
170 /* Read Memory Address */
171 MYread_word (mumkid[0], &x); /* address */
172 MYread_word (mumkid[0], &y); /* nbytes */
173 p = (char *) malloc (y);
174 i = armul_rdi.read (x, p, (unsigned *) &y);
c906108c 175 MYwrite_char (kidmum[1], RDP_Return);
dfcd3bfb
JM
176 for (k = 0; k < y; k++)
177 MYwrite_char (kidmum[1], p[k]);
178 free (p);
c906108c 179 MYwrite_char (kidmum[1], (unsigned char) i);
dfcd3bfb
JM
180 if (i)
181 MYwrite_word (kidmum[1], y); /* number of bytes sent without error */
c906108c
SS
182 break;
183
dfcd3bfb
JM
184 case RDP_Write:
185 /* Write Memory Address */
186 MYread_word (mumkid[0], &x); /* address */
187 MYread_word (mumkid[0], &y); /* nbytes */
188 p = (char *) malloc (y);
189 for (k = 0; k < y; k++)
190 MYread_char (mumkid[0], &p[k]);
191 i = armul_rdi.write (p, x, (unsigned *) &y);
192 free (p);
c906108c 193 MYwrite_char (kidmum[1], RDP_Return);
c906108c 194 MYwrite_char (kidmum[1], (unsigned char) i);
dfcd3bfb
JM
195 if (i)
196 MYwrite_word (kidmum[1], y); /* number of bytes sent without error */
c906108c
SS
197 break;
198
dfcd3bfb
JM
199 case RDP_CPUread:
200 /* Read CPU State */
201 MYread_char (mumkid[0], &c); /* mode */
202 MYread_word (mumkid[0], &x); /* mask */
203 p = (char *) malloc (4 * RDINumCPURegs);
204 i = armul_rdi.CPUread (c, x, (ARMword *) p);
c906108c 205 MYwrite_char (kidmum[1], RDP_Return);
dfcd3bfb
JM
206 for (k = 1, j = 0; k != 0x80000000; k *= 2)
207 if (k & x)
208 MYwrite_word (kidmum[1], ((ARMword *) p)[j++]);
209 free (p);
210 if (i)
211 MYwrite_char (kidmum[1], (unsigned char) j);
212 MYwrite_char (kidmum[1], (unsigned char) i);
c906108c
SS
213 break;
214
dfcd3bfb
JM
215 case RDP_CPUwrite:
216 /* Write CPU State */
217 MYread_char (mumkid[0], &c); /* mode */
218 MYread_word (mumkid[0], &x); /* mask */
219
220 p = (char *) malloc (4 * RDINumCPURegs);
221 for (k = 1, j = 0; k != 0x80000000; k *= 2)
222 if (k & x)
223 MYread_word (mumkid[0], &(((ARMword *) p)[j++]));
224 i = armul_rdi.CPUwrite (c, x, (ARMword *) p);
c906108c 225 MYwrite_char (kidmum[1], RDP_Return);
c906108c 226 MYwrite_char (kidmum[1], (unsigned char) i);
dfcd3bfb 227 free (p);
c906108c
SS
228 break;
229
dfcd3bfb
JM
230 case RDP_CPread:
231 /* Read Co-Processor State */
232 MYread_char (mumkid[0], &c); /* CPnum */
233 MYread_word (mumkid[0], &x); /* mask */
234 p = q = (char *) malloc (16 * RDINumCPRegs);
235 i = armul_rdi.CPread (c, x, (ARMword *) p);
236 MYwrite_char (kidmum[1], RDP_Return);
237 for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
238 if (k & x)
239 {
240 if ((c == 1 || c == 2) && k <= 128)
241 {
242 MYwrite_FPword (kidmum[1], q);
243 q += 16;
244 }
245 else
246 {
247 MYwrite_word (kidmum[1], *q);
248 q += 4;
249 }
250 }
251 free (p);
252 if (i)
253 MYwrite_char (kidmum[1], (unsigned char) j);
254 MYwrite_char (kidmum[1], (unsigned char) i);
255 break;
256
257 case RDP_CPwrite:
258 /* Write Co-Processor State */
259 MYread_char (mumkid[0], &c); /* CPnum */
260 MYread_word (mumkid[0], &x); /* mask */
261 p = q = (char *) malloc (16 * RDINumCPURegs);
262 for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
263 if (k & x)
264 {
265 if ((c == 1 || c == 2) && k <= 128)
266 {
267 MYread_FPword (kidmum[1], q);
268 q += 16;
269 }
270 else
271 {
272 MYread_word (mumkid[0], (ARMword *) q);
273 q += 4;
274 }
275 }
276 i = armul_rdi.CPwrite (c, x, (ARMword *) p);
277 MYwrite_char (kidmum[1], RDP_Return);
278 MYwrite_char (kidmum[1], (unsigned char) i);
279 free (p);
280 break;
281
282 case RDP_SetBreak:
283 /* Set Breakpoint */
284 MYread_word (mumkid[0], &x); /* address */
285 MYread_char (mumkid[0], &c); /* type */
286 if ((c & 0xf) >= 5)
287 MYread_word (mumkid[0], &y); /* bound */
288 i = armul_rdi.setbreak (x, c, y, &point);
289 if (!MYrdp_level)
290 BAG_putpair ((long) x, (long) point);
291 MYwrite_char (kidmum[1], RDP_Return);
292 if (MYrdp_level)
293 MYwrite_word (kidmum[1], point);
294 MYwrite_char (kidmum[1], (unsigned char) i);
295 break;
296
297 case RDP_ClearBreak:
298 /* Clear Breakpoint */
299 MYread_word (mumkid[0], &point); /* PointHandle */
300 if (!MYrdp_level)
301 {
302 BAG_getsecond ((long) point, &outofthebag); /* swap pointhandle for address */
303 BAG_killpair_byfirst (outofthebag);
304 point = outofthebag;
305 }
306 i = armul_rdi.clearbreak (point);
307 MYwrite_char (kidmum[1], RDP_Return);
308 MYwrite_char (kidmum[1], (unsigned char) i);
309 break;
310
311 case RDP_SetWatch:
312 /* Set Watchpoint */
313 MYread_word (mumkid[0], &x); /* address */
314 MYread_char (mumkid[0], &c); /* type */
315 MYread_char (mumkid[0], &d); /* datatype */
316 if ((c & 0xf) >= 5)
317 MYread_word (mumkid[0], &y); /* bound */
318 i = armul_rdi.setwatch (x, c, d, y, &point);
319 MYwrite_char (kidmum[1], RDP_Return);
320 MYwrite_word (kidmum[1], point);
321 MYwrite_char (kidmum[1], (unsigned char) i);
322 break;
323
324 case RDP_ClearWatch:
325 /* Clear Watchpoint */
326 MYread_word (mumkid[0], &point); /* PointHandle */
327 i = armul_rdi.clearwatch (point);
328 MYwrite_char (kidmum[1], RDP_Return);
329 MYwrite_char (kidmum[1], (unsigned char) i);
330 break;
331
332 case RDP_Execute:
333 /* Excecute */
334
335 MYread_char (mumkid[0], &c); /* return */
336
337#ifdef DEBUG
338 fprintf (stderr, "Starting execution\n");
339#endif
340 i = armul_rdi.execute (&point);
341#ifdef DEBUG
342 fprintf (stderr, "Completed execution\n");
343#endif
344 MYwrite_char (kidmum[1], RDP_Return);
345 if (c & 0x80)
346 MYwrite_word (kidmum[1], point);
347 MYwrite_char (kidmum[1], (unsigned char) i);
348 break;
349
350 case RDP_Step:
351 /* Step */
352 MYread_char (mumkid[0], &c); /* return */
353 MYread_word (mumkid[0], &x); /* ninstr */
354 point = 0x87654321;
355 i = armul_rdi.step (x, &point);
356 MYwrite_char (kidmum[1], RDP_Return);
357 if (c & 0x80)
358 MYwrite_word (kidmum[1], point);
359 MYwrite_char (kidmum[1], (unsigned char) i);
360 break;
361
362 case RDP_Info:
363 /* Info */
364 MYread_word (mumkid[0], &x);
365 switch (x)
366 {
367 case RDIInfo_Target:
368 i = armul_rdi.info (RDIInfo_Target, &y, &z);
369 MYwrite_char (kidmum[1], RDP_Return);
370 MYwrite_word (kidmum[1], y); /* Loads of info... */
371 MYwrite_word (kidmum[1], z); /* Model */
372 MYwrite_char (kidmum[1], (unsigned char) i);
373 break;
374
375 case RDISet_RDILevel:
376 MYread_word (mumkid[0], &x); /* arg1, debug level */
377 i = armul_rdi.info (RDISet_RDILevel, &x, 0);
378 if (i == RDIError_NoError)
379 MYrdp_level = x;
380 MYwrite_char (kidmum[1], RDP_Return);
381 MYwrite_char (kidmum[1], (unsigned char) i);
382 break;
383
384 case RDISet_Cmdline:
385 for (p = command_line; MYread_char (mumkid[0], p), *p; p++)
386 ; /* String */
387 i = armul_rdi.info (RDISet_Cmdline,
388 (unsigned long *) command_line, 0);
389 MYwrite_char (kidmum[1], RDP_Return);
390 MYwrite_char (kidmum[1], (unsigned char) i);
391 break;
392
393 case RDIInfo_Step:
394 i = armul_rdi.info (RDIInfo_Step, &x, 0);
395 MYwrite_char (kidmum[1], RDP_Return);
396 MYwrite_word (kidmum[1], x);
397 MYwrite_char (kidmum[1], (unsigned char) i);
398 break;
399
400 case RDIVector_Catch:
401 MYread_word (mumkid[0], &x);
402 i = armul_rdi.info (RDIVector_Catch, &x, 0);
403 MYwrite_char (kidmum[1], RDP_Return);
404 MYwrite_char (kidmum[1], i);
405 break;
406
407 case RDIInfo_Points:
408 i = armul_rdi.info (RDIInfo_Points, &x, 0);
409 MYwrite_char (kidmum[1], RDP_Return);
410 MYwrite_word (kidmum[1], x);
411 MYwrite_char (kidmum[1], (unsigned char) i);
412 break;
413
414 default:
415 fprintf (stderr, "Unsupported info code %d\n", x);
416 break;
417 }
418 break;
419
420 case RDP_OSOpReply:
421 /* OS Operation Reply */
422 MYwrite_char (kidmum[1], RDP_Fatal);
423 break;
424
425 case RDP_Reset:
426 /* Reset */
427 for (i = 0; i < 50; i++)
428 MYwrite_char (kidmum[1], RDP_Reset);
429 p = (char *) malloc (MAXHOSTNAMELENGTH + 5 + 20);
430 sprintf (p, "Running on %s:%d\n", localhost, socketnumber);
431 MYwrite_string (kidmum[1], p);
432 free (p);
433
434 break;
c906108c 435 default:
dfcd3bfb
JM
436 fprintf (stderr, "Oh dear: Something is seriously wrong :-(\n");
437 /* Hmm.. bad RDP operation */
c906108c
SS
438 break;
439 }
c906108c 440 }
c906108c
SS
441}
442
443
444/* Handles memory read operations until an OS Operation Reply Message is */
445/* encounterd. It then returns the byte info value (0, 1, or 2) and fills */
446/* in 'putinr0' with the data if appropriate. */
dfcd3bfb
JM
447int
448wait_for_osreply (ARMword * reply)
c906108c
SS
449{
450 char *p, *q;
451 int i, j, k;
452 unsigned char c, d, message;
453 ARMword x, y, z;
454 struct sigaction action;
455 PointHandle point;
456 Dbg_ConfigBlock config;
457 Dbg_HostosInterface hostif;
458 struct Dbg_MCState *MCState;
459 char command_line[256];
460 struct fd_set readfds;
dfcd3bfb 461
c906108c 462#ifdef DEBUG
dfcd3bfb 463 fprintf (stderr, "wait_for_osreply ().\n");
c906108c
SS
464#endif
465
466 /* Setup a signal handler for SIGUSR1 */
467 action.sa_handler = kid_handlesignal;
468 action.sa_mask = 0;
469 action.sa_flags = 0;
dfcd3bfb
JM
470
471 sigaction (SIGUSR1, &action, (struct sigaction *) 0);
472
c906108c 473 while (1)
dfcd3bfb
JM
474 {
475 /* Wait for ever */
476 FD_ZERO (&readfds);
477 FD_SET (mumkid[0], &readfds);
478
479 i = select (nfds, &readfds,
480 (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0);
481
482 if (i < 0)
483 {
484 perror ("select");
485 }
486
487 if (read (mumkid[0], &message, 1) < 1)
488 {
489 perror ("read");
490 }
491
492 switch (message)
493 {
494 case RDP_Read:
495 /* Read Memory Address */
496 MYread_word (mumkid[0], &x); /* address */
497 MYread_word (mumkid[0], &y); /* nbytes */
498 p = (char *) malloc (y);
499 i = armul_rdi.read (x, p, (unsigned *) &y);
500 MYwrite_char (kidmum[1], RDP_Return);
501 for (k = 0; k < y; k++)
502 MYwrite_char (kidmum[1], p[k]);
503 free (p);
504 MYwrite_char (kidmum[1], (unsigned char) i);
505 if (i)
506 MYwrite_word (kidmum[1], y); /* number of bytes sent without error */
507 break;
508
509 case RDP_Write:
510 /* Write Memory Address */
511 MYread_word (mumkid[0], &x); /* address */
512 MYread_word (mumkid[0], &y); /* nbytes */
513 p = (char *) malloc (y);
514 for (k = 0; k < y; k++)
515 MYread_char (mumkid[0], &p[k]);
516 i = armul_rdi.write (p, x, (unsigned *) &y);
517 free (p);
518 MYwrite_char (kidmum[1], RDP_Return);
519 MYwrite_char (kidmum[1], (unsigned char) i);
520 if (i)
521 MYwrite_word (kidmum[1], y); /* number of bytes sent without error */
522 break;
523
524 case RDP_OSOpReply:
525 /* OS Operation Reply */
526 MYread_char (mumkid[0], &c);
527 if (c == 1)
528 MYread_char (mumkid[0], (char *) reply);
529 if (c == 2)
530 MYread_word (mumkid[0], reply);
531 return c;
532 break;
533
534 default:
535 fprintf (stderr,
536 "HELP! Unaccounted-for message during OS request. \n");
537 MYwrite_char (kidmum[1], RDP_Fatal);
538 }
c906108c 539 }
c906108c 540}