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 2 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, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
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 /*****************************************************************/
25 #include <sys/types.h>
33 #include "communicate.h"
35 /* The pipes between the two processes */
39 /* The maximum number of file descriptors */
42 /* The machine name */
43 #define MAXHOSTNAMELENGTH 64
44 extern char localhost
[MAXHOSTNAMELENGTH
+ 1];
46 /* The socket number */
47 extern unsigned int socketnumber
;
50 extern const struct RDIProcVec armul_rdi
;
52 static int MYrdp_level
= 0;
54 static int rdi_state
= 0;
56 /**************************************************************/
57 /* Signal handler that terminates excecution in the ARMulator */
58 /**************************************************************/
59 void kid_handlesignal(int sig
) {
61 fprintf(stderr
, "Terminate ARMulator excecution\n");
64 fprintf(stderr
, "Unsupported signal.\n");
67 armul_rdi
.info(RDISignal_Stop
, (unsigned long *) 0, (unsigned long *) 0);
70 /********************************************************************/
71 /* Waits on a pipe from the socket demon for RDP and */
72 /* acts as an RDP to RDI interpreter on the front of the ARMulator. */
73 /********************************************************************/
78 unsigned char c
, d
, message
;
80 struct sigaction action
;
82 Dbg_ConfigBlock config
;
83 Dbg_HostosInterface hostif
;
84 struct Dbg_MCState
*MCState
;
85 char command_line
[256];
86 struct fd_set readfds
;
88 /* Setup a signal handler for SIGUSR1 */
89 action
.sa_handler
= kid_handlesignal
;
93 sigaction(SIGUSR1
, &action
, (struct sigaction
*) 0);
99 FD_SET(mumkid
[0], &readfds
);
101 i
= select(nfds
, &readfds
,
104 (struct timeval
*) 0);
110 if (read(mumkid
[0], &message
, 1) < 1) {
116 /* Open and/or Initialise */
119 MYread_char(mumkid
[0], &c
); /* type */
120 MYread_word(mumkid
[0], &x
); /* memorysize */
121 if (c
& 0x2) MYread_char(mumkid
[0], &d
); /* speed */
122 config
.processor
= 0;
123 config
.memorysize
= x
;
124 config
.bytesex
= (c
& 0x4) ? RDISex_Big
: RDISex_Little
;
125 if (c
& 0x8) config
.bytesex
= RDISex_DontCare
;
127 hostif
.dbgprint
= myprint
;
128 hostif
.dbgpause
= mypause
;
129 hostif
.dbgarg
= stdout
;
130 hostif
.writec
= mywritec
;
131 hostif
.readc
= myreadc
;
132 hostif
.write
= mywrite
;
133 hostif
.gets
= mygets
;
134 hostif
.reset
= mypause
; /* do nothing */
135 hostif
.resetarg
= "Do I love resetting or what!\n";
139 /* we have restarted, so kill off the existing run. */
140 /* armul_rdi.close(); */
142 i
= armul_rdi
.open(c
& 0x3, &config
, &hostif
, MCState
);
145 MYwrite_char(kidmum
[1], RDP_Return
);
146 MYwrite_char(kidmum
[1], (unsigned char) i
);
149 armul_rdi
.info(RDIVector_Catch
, &x
, 0);
154 /* Close and Finalise */
155 i
= armul_rdi
.close();
157 MYwrite_char(kidmum
[1], RDP_Return
);
158 MYwrite_char(kidmum
[1], (unsigned char) i
);
162 /* Read Memory Address */
163 MYread_word(mumkid
[0], &x
); /* address */
164 MYread_word(mumkid
[0], &y
); /* nbytes */
165 p
= (char *) malloc(y
);
166 i
= armul_rdi
.read(x
, p
, (unsigned *) &y
);
167 MYwrite_char(kidmum
[1], RDP_Return
);
168 for (k
= 0; k
< y
; k
++)
169 MYwrite_char(kidmum
[1], p
[k
]);
171 MYwrite_char(kidmum
[1], (unsigned char) i
);
173 MYwrite_word(kidmum
[1], y
); /* number of bytes sent without error */
177 /* Write Memory Address */
178 MYread_word(mumkid
[0], &x
); /* address */
179 MYread_word(mumkid
[0], &y
); /* nbytes */
180 p
= (char *) malloc(y
);
181 for (k
= 0; k
< y
; k
++)
182 MYread_char(mumkid
[0], &p
[k
]);
183 i
= armul_rdi
.write(p
, x
, (unsigned *) &y
);
185 MYwrite_char(kidmum
[1], RDP_Return
);
186 MYwrite_char(kidmum
[1], (unsigned char) i
);
188 MYwrite_word(kidmum
[1], y
); /* number of bytes sent without error */
193 MYread_char(mumkid
[0], &c
); /* mode */
194 MYread_word(mumkid
[0], &x
); /* mask */
195 p
= (char *) malloc(4 * RDINumCPURegs
);
196 i
= armul_rdi
.CPUread(c
, x
, (ARMword
*) p
);
197 MYwrite_char(kidmum
[1], RDP_Return
);
198 for (k
= 1, j
= 0; k
!= 0x80000000; k
*= 2)
199 if (k
& x
) MYwrite_word(kidmum
[1], ((ARMword
*) p
)[j
++]);
201 if (i
) MYwrite_char(kidmum
[1], (unsigned char) j
);
202 MYwrite_char(kidmum
[1], (unsigned char) i
);
206 /* Write CPU State */
207 MYread_char(mumkid
[0], &c
); /* mode */
208 MYread_word(mumkid
[0], &x
); /* mask */
210 p
= (char *) malloc(4 * RDINumCPURegs
);
211 for (k
= 1, j
= 0; k
!= 0x80000000; k
*= 2)
212 if (k
& x
) MYread_word(mumkid
[0], &(((ARMword
*) p
)[j
++]));
213 i
= armul_rdi
.CPUwrite(c
, x
, (ARMword
*) p
);
214 MYwrite_char(kidmum
[1], RDP_Return
);
215 MYwrite_char(kidmum
[1], (unsigned char) i
);
220 /* Read Co-Processor State */
221 MYread_char(mumkid
[0], &c
); /* CPnum */
222 MYread_word(mumkid
[0], &x
); /* mask */
223 p
= q
= (char *) malloc(16 * RDINumCPRegs
);
224 i
= armul_rdi
.CPread(c
, x
, (ARMword
*) p
);
225 MYwrite_char(kidmum
[1], RDP_Return
);
226 for (k
= 1, j
= 0; k
!= 0x80000000; k
*= 2, j
++)
228 if ((c
== 1 || c
== 2) && k
<= 128) {
229 MYwrite_FPword(kidmum
[1], q
);
233 MYwrite_word(kidmum
[1], *q
);
238 if (i
) MYwrite_char(kidmum
[1], (unsigned char) j
);
239 MYwrite_char(kidmum
[1], (unsigned char) i
);
243 /* Write Co-Processor State */
244 MYread_char(mumkid
[0], &c
); /* CPnum */
245 MYread_word(mumkid
[0], &x
); /* mask */
246 p
= q
= (char *) malloc(16 * RDINumCPURegs
);
247 for (k
= 1, j
= 0; k
!= 0x80000000; k
*= 2, j
++)
249 if ((c
== 1 || c
== 2) && k
<= 128) {
250 MYread_FPword(kidmum
[1], q
);
254 MYread_word(mumkid
[0], (ARMword
*) q
);
258 i
= armul_rdi
.CPwrite(c
, x
, (ARMword
*) p
);
259 MYwrite_char(kidmum
[1], RDP_Return
);
260 MYwrite_char(kidmum
[1], (unsigned char) i
);
266 MYread_word(mumkid
[0], &x
); /* address */
267 MYread_char(mumkid
[0], &c
); /* type */
268 if ((c
& 0xf) >= 5) MYread_word(mumkid
[0], &y
); /* bound */
269 i
= armul_rdi
.setbreak(x
, c
, y
, &point
);
270 if (!MYrdp_level
) BAG_putpair((long) x
, (long) point
);
271 MYwrite_char(kidmum
[1], RDP_Return
);
272 if (MYrdp_level
) MYwrite_word(kidmum
[1], point
);
273 MYwrite_char(kidmum
[1], (unsigned char) i
);
276 case RDP_ClearBreak
:
277 /* Clear Breakpoint */
278 MYread_word(mumkid
[0], &point
); /* PointHandle */
280 BAG_getsecond((long) point
, &outofthebag
); /* swap pointhandle for address */
281 BAG_killpair_byfirst(outofthebag
);
284 i
= armul_rdi
.clearbreak(point
);
285 MYwrite_char(kidmum
[1], RDP_Return
);
286 MYwrite_char(kidmum
[1], (unsigned char) i
);
291 MYread_word(mumkid
[0], &x
); /* address */
292 MYread_char(mumkid
[0], &c
); /* type */
293 MYread_char(mumkid
[0], &d
); /* datatype */
294 if ((c
& 0xf) >= 5) MYread_word(mumkid
[0], &y
); /* bound */
295 i
= armul_rdi
.setwatch(x
, c
, d
, y
, &point
);
296 MYwrite_char(kidmum
[1], RDP_Return
);
297 MYwrite_word(kidmum
[1], point
);
298 MYwrite_char(kidmum
[1], (unsigned char) i
);
301 case RDP_ClearWatch
:
302 /* Clear Watchpoint */
303 MYread_word(mumkid
[0], &point
); /* PointHandle */
304 i
= armul_rdi
.clearwatch(point
);
305 MYwrite_char(kidmum
[1], RDP_Return
);
306 MYwrite_char(kidmum
[1], (unsigned char) i
);
312 MYread_char(mumkid
[0], &c
); /* return */
315 fprintf(stderr
, "Starting execution\n");
317 i
= armul_rdi
.execute(&point
);
319 fprintf(stderr
, "Completed execution\n");
321 MYwrite_char(kidmum
[1], RDP_Return
);
322 if (c
& 0x80) MYwrite_word(kidmum
[1], point
);
323 MYwrite_char(kidmum
[1], (unsigned char) i
);
328 MYread_char(mumkid
[0], &c
); /* return */
329 MYread_word(mumkid
[0], &x
); /* ninstr */
331 i
= armul_rdi
.step(x
, &point
);
332 MYwrite_char(kidmum
[1], RDP_Return
);
333 if (c
& 0x80) MYwrite_word(kidmum
[1], point
);
334 MYwrite_char(kidmum
[1], (unsigned char) i
);
339 MYread_word (mumkid
[0], &x
);
343 i
= armul_rdi
.info (RDIInfo_Target
, &y
, &z
);
344 MYwrite_char (kidmum
[1], RDP_Return
);
345 MYwrite_word (kidmum
[1], y
); /* Loads of info... */
346 MYwrite_word (kidmum
[1], z
); /* Model */
347 MYwrite_char (kidmum
[1], (unsigned char) i
);
350 case RDISet_RDILevel
:
351 MYread_word (mumkid
[0], &x
); /* arg1, debug level */
352 i
= armul_rdi
.info (RDISet_RDILevel
, &x
, 0);
353 if (i
== RDIError_NoError
)
355 MYwrite_char (kidmum
[1], RDP_Return
);
356 MYwrite_char (kidmum
[1], (unsigned char) i
);
360 for (p
= command_line
; MYread_char (mumkid
[0], p
), *p
; p
++)
362 i
= armul_rdi
.info (RDISet_Cmdline
,
363 (unsigned long *) command_line
, 0);
364 MYwrite_char (kidmum
[1], RDP_Return
);
365 MYwrite_char (kidmum
[1], (unsigned char) i
);
369 i
= armul_rdi
.info (RDIInfo_Step
, &x
, 0);
370 MYwrite_char (kidmum
[1], RDP_Return
);
371 MYwrite_word (kidmum
[1], x
);
372 MYwrite_char (kidmum
[1], (unsigned char) i
);
375 case RDIVector_Catch
:
376 MYread_word (mumkid
[0], &x
);
377 i
= armul_rdi
.info (RDIVector_Catch
, &x
, 0);
378 MYwrite_char (kidmum
[1], RDP_Return
);
379 MYwrite_char (kidmum
[1], i
);
383 i
= armul_rdi
.info (RDIInfo_Points
, &x
, 0);
384 MYwrite_char (kidmum
[1], RDP_Return
);
385 MYwrite_word (kidmum
[1], x
);
386 MYwrite_char (kidmum
[1], (unsigned char) i
);
390 fprintf (stderr
, "Unsupported info code %d\n", x
);
396 /* OS Operation Reply */
397 MYwrite_char (kidmum
[1], RDP_Fatal
);
402 for (i
= 0; i
< 50; i
++)
403 MYwrite_char(kidmum
[1], RDP_Reset
);
404 p
= (char *) malloc(MAXHOSTNAMELENGTH
+ 5 + 20);
405 sprintf(p
, "Running on %s:%d\n", localhost
, socketnumber
);
406 MYwrite_string(kidmum
[1], p
);
411 fprintf (stderr
, "Oh dear: Something is seriously wrong :-(\n");
412 /* Hmm.. bad RDP operation */
419 /* Handles memory read operations until an OS Operation Reply Message is */
420 /* encounterd. It then returns the byte info value (0, 1, or 2) and fills */
421 /* in 'putinr0' with the data if appropriate. */
422 int wait_for_osreply(ARMword
*reply
)
426 unsigned char c
, d
, message
;
428 struct sigaction action
;
430 Dbg_ConfigBlock config
;
431 Dbg_HostosInterface hostif
;
432 struct Dbg_MCState
*MCState
;
433 char command_line
[256];
434 struct fd_set readfds
;
437 fprintf(stderr
, "wait_for_osreply ().\n");
440 /* Setup a signal handler for SIGUSR1 */
441 action
.sa_handler
= kid_handlesignal
;
445 sigaction(SIGUSR1
, &action
, (struct sigaction
*) 0);
451 FD_SET(mumkid
[0], &readfds
);
453 i
= select(nfds
, &readfds
,
456 (struct timeval
*) 0);
462 if (read(mumkid
[0], &message
, 1) < 1) {
468 /* Read Memory Address */
469 MYread_word(mumkid
[0], &x
); /* address */
470 MYread_word(mumkid
[0], &y
); /* nbytes */
471 p
= (char *) malloc(y
);
472 i
= armul_rdi
.read(x
, p
, (unsigned *) &y
);
473 MYwrite_char(kidmum
[1], RDP_Return
);
474 for (k
= 0; k
< y
; k
++)
475 MYwrite_char(kidmum
[1], p
[k
]);
477 MYwrite_char(kidmum
[1], (unsigned char) i
);
479 MYwrite_word(kidmum
[1], y
); /* number of bytes sent without error */
483 /* Write Memory Address */
484 MYread_word(mumkid
[0], &x
); /* address */
485 MYread_word(mumkid
[0], &y
); /* nbytes */
486 p
= (char *) malloc(y
);
487 for (k
= 0; k
< y
; k
++)
488 MYread_char(mumkid
[0], &p
[k
]);
489 i
= armul_rdi
.write(p
, x
, (unsigned *) &y
);
491 MYwrite_char(kidmum
[1], RDP_Return
);
492 MYwrite_char(kidmum
[1], (unsigned char) i
);
494 MYwrite_word(kidmum
[1], y
); /* number of bytes sent without error */
498 /* OS Operation Reply */
499 MYread_char(mumkid
[0], &c
);
500 if (c
== 1) MYread_char(mumkid
[0], (char *) reply
);
501 if (c
== 2) MYread_word(mumkid
[0], reply
);
506 fprintf(stderr
, "HELP! Unaccounted-for message during OS request. \n");
507 MYwrite_char(kidmum
[1], RDP_Fatal
);