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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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 /**************************************************************/
60 kid_handlesignal (int sig)
63 fprintf (stderr, "Terminate ARMulator excecution\n");
67 fprintf (stderr, "Unsupported signal.\n");
70 armul_rdi.info (RDISignal_Stop, (unsigned long *) 0, (unsigned long *) 0);
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 /********************************************************************/
83 unsigned char c, d, message;
85 struct sigaction action;
87 Dbg_ConfigBlock config;
88 Dbg_HostosInterface hostif;
89 struct Dbg_MCState *MCState;
90 char command_line[256];
91 struct fd_set readfds;
93 /* Setup a signal handler for SIGUSR1 */
94 action.sa_handler = kid_handlesignal;
98 sigaction (SIGUSR1, &action, (struct sigaction *) 0);
104 FD_SET (mumkid[0], &readfds);
106 i = select (nfds, &readfds,
107 (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0);
114 if (read (mumkid[0], &message, 1) < 1)
122 /* Open and/or Initialise */
125 MYread_char (mumkid[0], &c); /* type */
126 MYread_word (mumkid[0], &x); /* memorysize */
128 MYread_char (mumkid[0], &d); /* speed */
129 config.processor = 0;
130 config.memorysize = x;
131 config.bytesex = (c & 0x4) ? RDISex_Big : RDISex_Little;
133 config.bytesex = RDISex_DontCare;
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";
147 /* we have restarted, so kill off the existing run. */
148 /* armul_rdi.close(); */
150 i = armul_rdi.open (c & 0x3, &config, &hostif, MCState);
153 MYwrite_char (kidmum[1], RDP_Return);
154 MYwrite_char (kidmum[1], (unsigned char) i);
157 armul_rdi.info (RDIVector_Catch, &x, 0);
162 /* Close and Finalise */
163 i = armul_rdi.close ();
165 MYwrite_char (kidmum[1], RDP_Return);
166 MYwrite_char (kidmum[1], (unsigned char) i);
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);
175 MYwrite_char (kidmum[1], RDP_Return);
176 for (k = 0; k < y; k++)
177 MYwrite_char (kidmum[1], p[k]);
179 MYwrite_char (kidmum[1], (unsigned char) i);
181 MYwrite_word (kidmum[1], y); /* number of bytes sent without error */
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);
193 MYwrite_char (kidmum[1], RDP_Return);
194 MYwrite_char (kidmum[1], (unsigned char) i);
196 MYwrite_word (kidmum[1], y); /* number of bytes sent without error */
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);
205 MYwrite_char (kidmum[1], RDP_Return);
206 for (k = 1, j = 0; k != 0x80000000; k *= 2)
208 MYwrite_word (kidmum[1], ((ARMword *) p)[j++]);
211 MYwrite_char (kidmum[1], (unsigned char) j);
212 MYwrite_char (kidmum[1], (unsigned char) i);
216 /* Write CPU State */
217 MYread_char (mumkid[0], &c); /* mode */
218 MYread_word (mumkid[0], &x); /* mask */
220 p = (char *) malloc (4 * RDINumCPURegs);
221 for (k = 1, j = 0; k != 0x80000000; k *= 2)
223 MYread_word (mumkid[0], &(((ARMword *) p)[j++]));
224 i = armul_rdi.CPUwrite (c, x, (ARMword *) p);
225 MYwrite_char (kidmum[1], RDP_Return);
226 MYwrite_char (kidmum[1], (unsigned char) i);
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++)
240 if ((c == 1 || c == 2) && k <= 128)
242 MYwrite_FPword (kidmum[1], q);
247 MYwrite_word (kidmum[1], *q);
253 MYwrite_char (kidmum[1], (unsigned char) j);
254 MYwrite_char (kidmum[1], (unsigned char) i);
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++)
265 if ((c == 1 || c == 2) && k <= 128)
267 MYread_FPword (kidmum[1], q);
272 MYread_word (mumkid[0], (ARMword *) q);
276 i = armul_rdi.CPwrite (c, x, (ARMword *) p);
277 MYwrite_char (kidmum[1], RDP_Return);
278 MYwrite_char (kidmum[1], (unsigned char) i);
284 MYread_word (mumkid[0], &x); /* address */
285 MYread_char (mumkid[0], &c); /* type */
287 MYread_word (mumkid[0], &y); /* bound */
288 i = armul_rdi.setbreak (x, c, y, &point);
290 BAG_putpair ((long) x, (long) point);
291 MYwrite_char (kidmum[1], RDP_Return);
293 MYwrite_word (kidmum[1], point);
294 MYwrite_char (kidmum[1], (unsigned char) i);
298 /* Clear Breakpoint */
299 MYread_word (mumkid[0], &point); /* PointHandle */
302 BAG_getsecond ((long) point, &outofthebag); /* swap pointhandle for address */
303 BAG_killpair_byfirst (outofthebag);
306 i = armul_rdi.clearbreak (point);
307 MYwrite_char (kidmum[1], RDP_Return);
308 MYwrite_char (kidmum[1], (unsigned char) i);
313 MYread_word (mumkid[0], &x); /* address */
314 MYread_char (mumkid[0], &c); /* type */
315 MYread_char (mumkid[0], &d); /* datatype */
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);
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);
335 MYread_char (mumkid[0], &c); /* return */
338 fprintf (stderr, "Starting execution\n");
340 i = armul_rdi.execute (&point);
342 fprintf (stderr, "Completed execution\n");
344 MYwrite_char (kidmum[1], RDP_Return);
346 MYwrite_word (kidmum[1], point);
347 MYwrite_char (kidmum[1], (unsigned char) i);
352 MYread_char (mumkid[0], &c); /* return */
353 MYread_word (mumkid[0], &x); /* ninstr */
355 i = armul_rdi.step (x, &point);
356 MYwrite_char (kidmum[1], RDP_Return);
358 MYwrite_word (kidmum[1], point);
359 MYwrite_char (kidmum[1], (unsigned char) i);
364 MYread_word (mumkid[0], &x);
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);
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)
380 MYwrite_char (kidmum[1], RDP_Return);
381 MYwrite_char (kidmum[1], (unsigned char) i);
385 for (p = command_line; MYread_char (mumkid[0], p), *p; p++)
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);
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);
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);
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);
415 fprintf (stderr, "Unsupported info code %d\n", x);
421 /* OS Operation Reply */
422 MYwrite_char (kidmum[1], RDP_Fatal);
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);
436 fprintf (stderr, "Oh dear: Something is seriously wrong :-(\n");
437 /* Hmm.. bad RDP operation */
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. */
448 wait_for_osreply (ARMword * reply)
452 unsigned char c, d, message;
454 struct sigaction action;
456 Dbg_ConfigBlock config;
457 Dbg_HostosInterface hostif;
458 struct Dbg_MCState *MCState;
459 char command_line[256];
460 struct fd_set readfds;
463 fprintf (stderr, "wait_for_osreply ().\n");
466 /* Setup a signal handler for SIGUSR1 */
467 action.sa_handler = kid_handlesignal;
471 sigaction (SIGUSR1, &action, (struct sigaction *) 0);
477 FD_SET (mumkid[0], &readfds);
479 i = select (nfds, &readfds,
480 (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0);
487 if (read (mumkid[0], &message, 1) < 1)
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]);
504 MYwrite_char (kidmum[1], (unsigned char) i);
506 MYwrite_word (kidmum[1], y); /* number of bytes sent without error */
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);
518 MYwrite_char (kidmum[1], RDP_Return);
519 MYwrite_char (kidmum[1], (unsigned char) i);
521 MYwrite_word (kidmum[1], y); /* number of bytes sent without error */
525 /* OS Operation Reply */
526 MYread_char (mumkid[0], &c);
528 MYread_char (mumkid[0], (char *) reply);
530 MYread_word (mumkid[0], reply);
536 "HELP! Unaccounted-for message during OS request. \n");
537 MYwrite_char (kidmum[1], RDP_Fatal);