1 /* kid.c -- ARMulator RDP/RDI interface: ARM6 Instruction Emulator.
2 Copyright (C) 1994 Advanced RISC Machines Ltd.
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 3 of the License, or
7 (at your option) any later version.
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.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, see <http://www.gnu.org/licenses/>. */
17 /*****************************************************************/
18 /* The child process continues here... */
19 /* It waits on a pipe from the parent and translates the RDP */
20 /* messages into RDI calls to the ARMulator passing RDP replies */
21 /* back up a pipe to the parent. */
22 /*****************************************************************/
24 #include <sys/types.h>
32 #include "communicate.h"
34 /* The pipes between the two processes */
38 /* The maximum number of file descriptors */
41 /* The machine name */
42 #define MAXHOSTNAMELENGTH 64
43 extern char localhost
[MAXHOSTNAMELENGTH
+ 1];
45 /* The socket number */
46 extern unsigned int socketnumber
;
49 extern const struct RDIProcVec armul_rdi
;
51 static int MYrdp_level
= 0;
53 static int rdi_state
= 0;
55 /**************************************************************/
56 /* Signal handler that terminates excecution in the ARMulator */
57 /**************************************************************/
59 kid_handlesignal (int sig
)
62 fprintf (stderr
, "Terminate ARMulator excecution\n");
66 fprintf (stderr
, "Unsupported signal.\n");
69 armul_rdi
.info (RDISignal_Stop
, (unsigned long *) 0, (unsigned long *) 0);
72 /********************************************************************/
73 /* Waits on a pipe from the socket demon for RDP and */
74 /* acts as an RDP to RDI interpreter on the front of the ARMulator. */
75 /********************************************************************/
82 unsigned char c
, d
, message
;
84 struct sigaction action
;
86 Dbg_ConfigBlock config
;
87 Dbg_HostosInterface hostif
;
88 struct Dbg_MCState
*MCState
;
89 char command_line
[256];
90 struct fd_set readfds
;
92 /* Setup a signal handler for SIGUSR1 */
93 action
.sa_handler
= kid_handlesignal
;
97 sigaction (SIGUSR1
, &action
, (struct sigaction
*) 0);
103 FD_SET (mumkid
[0], &readfds
);
105 i
= select (nfds
, &readfds
,
106 (fd_set
*) 0, (fd_set
*) 0, (struct timeval
*) 0);
113 if (read (mumkid
[0], &message
, 1) < 1)
121 /* Open and/or Initialise */
124 MYread_char (mumkid
[0], &c
); /* type */
125 MYread_word (mumkid
[0], &x
); /* memorysize */
127 MYread_char (mumkid
[0], &d
); /* speed */
128 config
.processor
= 0;
129 config
.memorysize
= x
;
130 config
.bytesex
= (c
& 0x4) ? RDISex_Big
: RDISex_Little
;
132 config
.bytesex
= RDISex_DontCare
;
134 hostif
.dbgprint
= myprint
;
135 hostif
.dbgpause
= mypause
;
136 hostif
.dbgarg
= stdout
;
137 hostif
.writec
= mywritec
;
138 hostif
.readc
= myreadc
;
139 hostif
.write
= mywrite
;
140 hostif
.gets
= mygets
;
141 hostif
.reset
= mypause
; /* do nothing */
142 hostif
.resetarg
= "Do I love resetting or what!\n";
146 /* we have restarted, so kill off the existing run. */
147 /* armul_rdi.close(); */
149 i
= armul_rdi
.open (c
& 0x3, &config
, &hostif
, MCState
);
152 MYwrite_char (kidmum
[1], RDP_Return
);
153 MYwrite_char (kidmum
[1], (unsigned char) i
);
156 armul_rdi
.info (RDIVector_Catch
, &x
, 0);
161 /* Close and Finalise */
162 i
= armul_rdi
.close ();
164 MYwrite_char (kidmum
[1], RDP_Return
);
165 MYwrite_char (kidmum
[1], (unsigned char) i
);
169 /* Read Memory Address */
170 MYread_word (mumkid
[0], &x
); /* address */
171 MYread_word (mumkid
[0], &y
); /* nbytes */
172 p
= (char *) malloc (y
);
173 i
= armul_rdi
.read (x
, p
, (unsigned *) &y
);
174 MYwrite_char (kidmum
[1], RDP_Return
);
175 for (k
= 0; k
< y
; k
++)
176 MYwrite_char (kidmum
[1], p
[k
]);
178 MYwrite_char (kidmum
[1], (unsigned char) i
);
180 MYwrite_word (kidmum
[1], y
); /* number of bytes sent without error */
184 /* Write Memory Address */
185 MYread_word (mumkid
[0], &x
); /* address */
186 MYread_word (mumkid
[0], &y
); /* nbytes */
187 p
= (char *) malloc (y
);
188 for (k
= 0; k
< y
; k
++)
189 MYread_char (mumkid
[0], &p
[k
]);
190 i
= armul_rdi
.write (p
, x
, (unsigned *) &y
);
192 MYwrite_char (kidmum
[1], RDP_Return
);
193 MYwrite_char (kidmum
[1], (unsigned char) i
);
195 MYwrite_word (kidmum
[1], y
); /* number of bytes sent without error */
200 MYread_char (mumkid
[0], &c
); /* mode */
201 MYread_word (mumkid
[0], &x
); /* mask */
202 p
= (char *) malloc (4 * RDINumCPURegs
);
203 i
= armul_rdi
.CPUread (c
, x
, (ARMword
*) p
);
204 MYwrite_char (kidmum
[1], RDP_Return
);
205 for (k
= 1, j
= 0; k
!= 0x80000000; k
*= 2)
207 MYwrite_word (kidmum
[1], ((ARMword
*) p
)[j
++]);
210 MYwrite_char (kidmum
[1], (unsigned char) j
);
211 MYwrite_char (kidmum
[1], (unsigned char) i
);
215 /* Write CPU State */
216 MYread_char (mumkid
[0], &c
); /* mode */
217 MYread_word (mumkid
[0], &x
); /* mask */
219 p
= (char *) malloc (4 * RDINumCPURegs
);
220 for (k
= 1, j
= 0; k
!= 0x80000000; k
*= 2)
222 MYread_word (mumkid
[0], &(((ARMword
*) p
)[j
++]));
223 i
= armul_rdi
.CPUwrite (c
, x
, (ARMword
*) p
);
224 MYwrite_char (kidmum
[1], RDP_Return
);
225 MYwrite_char (kidmum
[1], (unsigned char) i
);
230 /* Read Co-Processor State */
231 MYread_char (mumkid
[0], &c
); /* CPnum */
232 MYread_word (mumkid
[0], &x
); /* mask */
233 p
= q
= (char *) malloc (16 * RDINumCPRegs
);
234 i
= armul_rdi
.CPread (c
, x
, (ARMword
*) p
);
235 MYwrite_char (kidmum
[1], RDP_Return
);
236 for (k
= 1, j
= 0; k
!= 0x80000000; k
*= 2, j
++)
239 if ((c
== 1 || c
== 2) && k
<= 128)
241 MYwrite_FPword (kidmum
[1], q
);
246 MYwrite_word (kidmum
[1], *q
);
252 MYwrite_char (kidmum
[1], (unsigned char) j
);
253 MYwrite_char (kidmum
[1], (unsigned char) i
);
257 /* Write Co-Processor State */
258 MYread_char (mumkid
[0], &c
); /* CPnum */
259 MYread_word (mumkid
[0], &x
); /* mask */
260 p
= q
= (char *) malloc (16 * RDINumCPURegs
);
261 for (k
= 1, j
= 0; k
!= 0x80000000; k
*= 2, j
++)
264 if ((c
== 1 || c
== 2) && k
<= 128)
266 MYread_FPword (kidmum
[1], q
);
271 MYread_word (mumkid
[0], (ARMword
*) q
);
275 i
= armul_rdi
.CPwrite (c
, x
, (ARMword
*) p
);
276 MYwrite_char (kidmum
[1], RDP_Return
);
277 MYwrite_char (kidmum
[1], (unsigned char) i
);
283 MYread_word (mumkid
[0], &x
); /* address */
284 MYread_char (mumkid
[0], &c
); /* type */
286 MYread_word (mumkid
[0], &y
); /* bound */
287 i
= armul_rdi
.setbreak (x
, c
, y
, &point
);
289 BAG_putpair ((long) x
, (long) point
);
290 MYwrite_char (kidmum
[1], RDP_Return
);
292 MYwrite_word (kidmum
[1], point
);
293 MYwrite_char (kidmum
[1], (unsigned char) i
);
297 /* Clear Breakpoint */
298 MYread_word (mumkid
[0], &point
); /* PointHandle */
301 BAG_getsecond ((long) point
, &outofthebag
); /* swap pointhandle for address */
302 BAG_killpair_byfirst (outofthebag
);
305 i
= armul_rdi
.clearbreak (point
);
306 MYwrite_char (kidmum
[1], RDP_Return
);
307 MYwrite_char (kidmum
[1], (unsigned char) i
);
312 MYread_word (mumkid
[0], &x
); /* address */
313 MYread_char (mumkid
[0], &c
); /* type */
314 MYread_char (mumkid
[0], &d
); /* datatype */
316 MYread_word (mumkid
[0], &y
); /* bound */
317 i
= armul_rdi
.setwatch (x
, c
, d
, y
, &point
);
318 MYwrite_char (kidmum
[1], RDP_Return
);
319 MYwrite_word (kidmum
[1], point
);
320 MYwrite_char (kidmum
[1], (unsigned char) i
);
324 /* Clear Watchpoint */
325 MYread_word (mumkid
[0], &point
); /* PointHandle */
326 i
= armul_rdi
.clearwatch (point
);
327 MYwrite_char (kidmum
[1], RDP_Return
);
328 MYwrite_char (kidmum
[1], (unsigned char) i
);
334 MYread_char (mumkid
[0], &c
); /* return */
337 fprintf (stderr
, "Starting execution\n");
339 i
= armul_rdi
.execute (&point
);
341 fprintf (stderr
, "Completed execution\n");
343 MYwrite_char (kidmum
[1], RDP_Return
);
345 MYwrite_word (kidmum
[1], point
);
346 MYwrite_char (kidmum
[1], (unsigned char) i
);
351 MYread_char (mumkid
[0], &c
); /* return */
352 MYread_word (mumkid
[0], &x
); /* ninstr */
354 i
= armul_rdi
.step (x
, &point
);
355 MYwrite_char (kidmum
[1], RDP_Return
);
357 MYwrite_word (kidmum
[1], point
);
358 MYwrite_char (kidmum
[1], (unsigned char) i
);
363 MYread_word (mumkid
[0], &x
);
367 i
= armul_rdi
.info (RDIInfo_Target
, &y
, &z
);
368 MYwrite_char (kidmum
[1], RDP_Return
);
369 MYwrite_word (kidmum
[1], y
); /* Loads of info... */
370 MYwrite_word (kidmum
[1], z
); /* Model */
371 MYwrite_char (kidmum
[1], (unsigned char) i
);
374 case RDISet_RDILevel
:
375 MYread_word (mumkid
[0], &x
); /* arg1, debug level */
376 i
= armul_rdi
.info (RDISet_RDILevel
, &x
, 0);
377 if (i
== RDIError_NoError
)
379 MYwrite_char (kidmum
[1], RDP_Return
);
380 MYwrite_char (kidmum
[1], (unsigned char) i
);
384 for (p
= command_line
; MYread_char (mumkid
[0], p
), *p
; p
++)
386 i
= armul_rdi
.info (RDISet_Cmdline
,
387 (unsigned long *) command_line
, 0);
388 MYwrite_char (kidmum
[1], RDP_Return
);
389 MYwrite_char (kidmum
[1], (unsigned char) i
);
393 i
= armul_rdi
.info (RDIInfo_Step
, &x
, 0);
394 MYwrite_char (kidmum
[1], RDP_Return
);
395 MYwrite_word (kidmum
[1], x
);
396 MYwrite_char (kidmum
[1], (unsigned char) i
);
399 case RDIVector_Catch
:
400 MYread_word (mumkid
[0], &x
);
401 i
= armul_rdi
.info (RDIVector_Catch
, &x
, 0);
402 MYwrite_char (kidmum
[1], RDP_Return
);
403 MYwrite_char (kidmum
[1], i
);
407 i
= armul_rdi
.info (RDIInfo_Points
, &x
, 0);
408 MYwrite_char (kidmum
[1], RDP_Return
);
409 MYwrite_word (kidmum
[1], x
);
410 MYwrite_char (kidmum
[1], (unsigned char) i
);
414 fprintf (stderr
, "Unsupported info code %d\n", x
);
420 /* OS Operation Reply */
421 MYwrite_char (kidmum
[1], RDP_Fatal
);
426 for (i
= 0; i
< 50; i
++)
427 MYwrite_char (kidmum
[1], RDP_Reset
);
428 p
= (char *) malloc (MAXHOSTNAMELENGTH
+ 5 + 20);
429 sprintf (p
, "Running on %s:%d\n", localhost
, socketnumber
);
430 MYwrite_string (kidmum
[1], p
);
435 fprintf (stderr
, "Oh dear: Something is seriously wrong :-(\n");
436 /* Hmm.. bad RDP operation */
443 /* Handles memory read operations until an OS Operation Reply Message is */
444 /* encounterd. It then returns the byte info value (0, 1, or 2) and fills */
445 /* in 'putinr0' with the data if appropriate. */
447 wait_for_osreply (ARMword
* reply
)
451 unsigned char c
, d
, message
;
453 struct sigaction action
;
455 Dbg_ConfigBlock config
;
456 Dbg_HostosInterface hostif
;
457 struct Dbg_MCState
*MCState
;
458 char command_line
[256];
459 struct fd_set readfds
;
462 fprintf (stderr
, "wait_for_osreply ().\n");
465 /* Setup a signal handler for SIGUSR1 */
466 action
.sa_handler
= kid_handlesignal
;
470 sigaction (SIGUSR1
, &action
, (struct sigaction
*) 0);
476 FD_SET (mumkid
[0], &readfds
);
478 i
= select (nfds
, &readfds
,
479 (fd_set
*) 0, (fd_set
*) 0, (struct timeval
*) 0);
486 if (read (mumkid
[0], &message
, 1) < 1)
494 /* Read Memory Address */
495 MYread_word (mumkid
[0], &x
); /* address */
496 MYread_word (mumkid
[0], &y
); /* nbytes */
497 p
= (char *) malloc (y
);
498 i
= armul_rdi
.read (x
, p
, (unsigned *) &y
);
499 MYwrite_char (kidmum
[1], RDP_Return
);
500 for (k
= 0; k
< y
; k
++)
501 MYwrite_char (kidmum
[1], p
[k
]);
503 MYwrite_char (kidmum
[1], (unsigned char) i
);
505 MYwrite_word (kidmum
[1], y
); /* number of bytes sent without error */
509 /* Write Memory Address */
510 MYread_word (mumkid
[0], &x
); /* address */
511 MYread_word (mumkid
[0], &y
); /* nbytes */
512 p
= (char *) malloc (y
);
513 for (k
= 0; k
< y
; k
++)
514 MYread_char (mumkid
[0], &p
[k
]);
515 i
= armul_rdi
.write (p
, x
, (unsigned *) &y
);
517 MYwrite_char (kidmum
[1], RDP_Return
);
518 MYwrite_char (kidmum
[1], (unsigned char) i
);
520 MYwrite_word (kidmum
[1], y
); /* number of bytes sent without error */
524 /* OS Operation Reply */
525 MYread_char (mumkid
[0], &c
);
527 MYread_char (mumkid
[0], (char *) reply
);
529 MYread_word (mumkid
[0], reply
);
535 "HELP! Unaccounted-for message during OS request. \n");
536 MYwrite_char (kidmum
[1], RDP_Fatal
);