1 /* parent.c -- ARMulator RDP comms code: 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 Parent process continues here... */
19 /* It waits on the socket and passes on RDP messages down a pipe */
20 /* to the ARMulator RDP to RDI interpreter. */
21 /*****************************************************************/
24 #include <sys/types.h>
29 #include "communicate.h"
31 /* The socket to the debugger */
34 /* The pipes between the two processes */
38 /* A pipe for handling SWI return values that goes straight from the */
39 /* parent to the ARMulator host interface, bypassing the child's RDP */
40 /* to RDI interpreter */
41 extern int DebuggerARMul
[2];
43 /* The maximum number of file descriptors */
46 /* The child process id. */
53 unsigned char message
, CPnum
, exreturn
;
54 ARMword mask
, nbytes
, messagetype
;
58 struct fd_set readfds
;
61 fprintf (stderr
, "parent ()...\n");
69 fprintf (stderr
, "Arghh! What is going on?\n");
72 MYwrite_char (debugsock
, RDP_Reset
);
80 /* Wait either for the ARMulator or the debugger */
83 FD_SET (kidmum
[0], &readfds
); /* Wait for messages from ARMulator */
84 FD_SET (debugsock
, &readfds
); /* Wait for messages from debugger */
87 fprintf (stderr
, "Waiting for ARMulator or debugger... ");
90 while ((i
= select (nfds
, &readfds
, (fd_set
*) 0, (fd_set
*) 0, 0)) < 0)
96 fprintf (stderr
, "(%d/2)", i
);
99 if (FD_ISSET (debugsock
, &readfds
))
102 fprintf (stderr
, "->debugger\n");
105 /* Inside this rather large if statement with simply pass on a complete
106 message to the ARMulator. The reason we need to pass messages on one
107 at a time is that we have to know whether the message is an OSOpReply
108 or an info(stop), so that we can take different action in those
111 if (MYread_char (debugsock
, &message
))
117 /* Open and/or Initialise */
119 fprintf (stderr
, "RDP Open\n");
121 if (MYread_char (debugsock
, &c
)) /* type */
124 if (MYread_word (debugsock
, &x
)) /* memory size */
127 MYwrite_char (mumkid
[1], message
);
128 MYwrite_char (mumkid
[1], c
);
129 MYwrite_word (mumkid
[1], x
);
132 passon (debugsock
, mumkid
[1], 1); /* speed */
137 /* Close and Finalise */
139 fprintf (stderr
, "RDP Close\n");
141 MYwrite_char (mumkid
[1], message
);
145 /* Read Memory Address */
147 fprintf (stderr
, "RDP Read Memory\n");
149 MYwrite_char (mumkid
[1], message
);
150 if (passon (debugsock
, mumkid
[1], 4))
151 goto panic_error
; /* address */
152 if (MYread_word (debugsock
, &nbytes
))
153 goto panic_error
; /* nbytes */
154 MYwrite_word (mumkid
[1], nbytes
);
158 /* Write Memory Address */
160 fprintf (stderr
, "RDP Write Memory\n");
162 if (MYread_word (debugsock
, &x
))
163 goto panic_error
; /* address */
165 if (MYread_word (debugsock
, &y
))
166 goto panic_error
; /* nbytes */
168 MYwrite_char (mumkid
[1], message
);
169 MYwrite_word (mumkid
[1], x
);
170 MYwrite_word (mumkid
[1], y
);
171 passon (debugsock
, mumkid
[1], y
); /* actual data */
177 fprintf (stderr
, "RDP Read CPU\n");
179 if (MYread_char (debugsock
, &c
))
180 goto panic_error
; /* mode */
182 if (MYread_word (debugsock
, &mask
))
183 goto panic_error
; /* mask */
185 MYwrite_char (mumkid
[1], message
);
186 MYwrite_char (mumkid
[1], c
);
187 MYwrite_word (mumkid
[1], mask
);
191 /* Write CPU State */
193 fprintf (stderr
, "RDP Write CPU\n");
195 if (MYread_char (debugsock
, &c
))
196 goto panic_error
; /* mode */
198 if (MYread_word (debugsock
, &x
))
199 goto panic_error
; /* mask */
201 MYwrite_char (mumkid
[1], message
);
202 MYwrite_char (mumkid
[1], c
);
203 MYwrite_word (mumkid
[1], x
);
204 for (k
= 1, j
= 0; k
!= 0x80000000; k
*= 2, j
++)
205 if ((k
& x
) && passon (debugsock
, mumkid
[1], 4))
210 /* Read Co-Processor State */
212 fprintf (stderr
, "RDP Read CP state\n");
214 if (MYread_char (debugsock
, &CPnum
))
217 if (MYread_word (debugsock
, &mask
))
220 MYwrite_char (mumkid
[1], message
);
221 MYwrite_char (mumkid
[1], CPnum
);
222 MYwrite_word (mumkid
[1], mask
);
226 /* Write Co-Processor State */
228 fprintf (stderr
, "RDP Write CP state\n");
230 if (MYread_char (debugsock
, &CPnum
))
233 if (MYread_word (debugsock
, &mask
))
236 MYwrite_char (mumkid
[1], message
);
237 MYwrite_char (mumkid
[1], c
);
238 MYwrite_char (mumkid
[1], x
);
239 for (k
= 1, j
= 0; k
!= 0x80000000; k
*= 2, j
++)
242 if ((c
== 1 || c
== 2) && k
<= 128)
244 /* FP register = 12 bytes + 4 bytes format */
245 if (passon (debugsock
, mumkid
[1], 16))
250 /* Normal register = 4 bytes */
251 if (passon (debugsock
, mumkid
[1], 4))
260 fprintf (stderr
, "RDP Set Breakpoint\n");
262 if (MYread_word (debugsock
, &x
))
263 goto panic_error
; /* address */
265 if (MYread_char (debugsock
, &c
))
266 goto panic_error
; /* type */
268 MYwrite_char (mumkid
[1], message
);
269 MYwrite_word (mumkid
[1], x
);
270 MYwrite_char (mumkid
[1], c
);
271 if (((c
& 0xf) >= 5) && passon (debugsock
, mumkid
[1], 4))
272 goto panic_error
; /* bound */
276 /* Clear Breakpoint */
278 fprintf (stderr
, "RDP Clear Breakpoint\n");
280 MYwrite_char (mumkid
[1], message
);
281 if (passon (debugsock
, mumkid
[1], 4))
282 goto panic_error
; /* point */
288 fprintf (stderr
, "RDP Set Watchpoint\n");
290 if (MYread_word (debugsock
, &x
))
291 goto panic_error
; /* address */
293 if (MYread_char (debugsock
, &c
))
294 goto panic_error
; /* type */
296 if (MYread_char (debugsock
, &d
))
297 goto panic_error
; /* datatype */
299 MYwrite_char (mumkid
[1], message
);
300 MYwrite_word (mumkid
[1], x
);
301 MYwrite_char (mumkid
[1], c
);
302 MYwrite_char (mumkid
[1], d
);
303 if (((c
& 0xf) >= 5) && passon (debugsock
, mumkid
[1], 4))
304 goto panic_error
; /* bound */
308 /* Clear Watchpoint */
310 fprintf (stderr
, "RDP Clear Watchpoint\n");
312 MYwrite_char (mumkid
[1], message
);
313 if (passon (debugsock
, mumkid
[1], 4))
314 goto panic_error
; /* point */
320 fprintf (stderr
, "RDP Execute\n");
323 /* LEAVE THIS ONE 'TIL LATER... */
324 /* NEED TO WORK THINGS OUT */
326 /* NO ASCYNCHROUS RUNNING */
328 if (MYread_char (debugsock
, &c
))
329 goto panic_error
; /* return */
331 /* Remember incase bit 7 is set and we have to send back a word */
334 MYwrite_char (mumkid
[1], message
);
335 MYwrite_char (mumkid
[1], c
);
341 fprintf (stderr
, "RDP Step\n");
344 if (MYread_char (debugsock
, &c
))
345 goto panic_error
; /* return */
347 if (MYread_word (debugsock
, &x
))
348 goto panic_error
; /* ninstr */
350 MYwrite_char (mumkid
[1], message
);
351 MYwrite_char (mumkid
[1], c
);
352 MYwrite_word (mumkid
[1], x
);
358 fprintf (stderr
, "RDP Info\n");
360 /* INFO TARGET, SET RDI LEVEL */
361 if (MYread_word (debugsock
, &messagetype
))
362 goto panic_error
; /* info */
367 MYwrite_char (mumkid
[1], message
);
368 MYwrite_word (mumkid
[1], messagetype
);
371 case RDISet_RDILevel
:
372 MYwrite_char (mumkid
[1], message
);
373 MYwrite_word (mumkid
[1], messagetype
);
374 if (passon (debugsock
, mumkid
[1], 1))
375 goto panic_error
; /* argument */
379 /* Got to pass on a string argument */
380 MYwrite_char (mumkid
[1], message
);
381 MYwrite_word (mumkid
[1], messagetype
);
384 if (MYread_char (debugsock
, &c
))
387 MYwrite_char (mumkid
[1], c
);
393 kill (child
, SIGUSR1
);
394 MYwrite_char (debugsock
, RDP_Return
);
395 MYwrite_char (debugsock
, RDIError_UserInterrupt
);
398 case RDIVector_Catch
:
399 MYread_word (debugsock
, &x
);
400 MYwrite_char (mumkid
[1], message
);
401 MYwrite_word (mumkid
[1], messagetype
);
402 MYwrite_word (mumkid
[1], x
);
406 MYwrite_char (mumkid
[1], message
);
407 MYwrite_word (mumkid
[1], messagetype
);
411 MYwrite_char (mumkid
[1], message
);
412 MYwrite_word (mumkid
[1], messagetype
);
416 fprintf (stderr
, "Unrecognized RDIInfo request %d\n",
423 /* OS Operation Reply */
425 fprintf (stderr
, "RDP OS Reply\n");
427 MYwrite_char (mumkid
[1], message
);
428 if (MYread_char (debugsock
, &message
))
430 MYwrite_char (mumkid
[1], message
);
433 case 0: /* return value i.e. nothing else. */
436 case 1: /* returns a byte... */
437 if (MYread_char (debugsock
, &c
))
440 MYwrite_char (mumkid
[1], c
);
443 case 2: /* returns a word... */
444 if (MYread_word (debugsock
, &x
))
447 MYwrite_word (mumkid
[1], x
);
455 fprintf (stderr
, "RDP Reset\n");
457 MYwrite_char (mumkid
[1], message
);
461 /* Hmm.. bad RDP operation */
462 fprintf (stderr
, "RDP Bad RDP request (%d)\n", message
);
463 MYwrite_char (debugsock
, RDP_Return
);
464 MYwrite_char (debugsock
, RDIError_UnimplementedMessage
);
469 if (FD_ISSET (kidmum
[0], &readfds
))
472 fprintf (stderr
, "->ARMulator\n");
474 /* Anything we get from the ARMulator has to go to the debugger... */
475 /* It is that simple! */
477 passon (kidmum
[0], debugsock
, 1);