]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/arm/parent.c
sim: make nrun the default run program
[thirdparty/binutils-gdb.git] / sim / arm / parent.c
CommitLineData
c906108c
SS
1/* parent.c -- ARMulator RDP comms code: 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
3fd725ef 6 the Free Software Foundation; either version 3 of the License, or
c906108c
SS
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
51b318de 15 along with this program; if not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
16
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/*****************************************************************/
22
23#include <stdio.h>
24#include <sys/types.h>
25#include <signal.h>
26#include "time.h"
27#include "armdefs.h"
28#include "dbg_rdi.h"
29#include "communicate.h"
30
31/* The socket to the debugger */
32extern int debugsock;
33
34/* The pipes between the two processes */
35extern int mumkid[2];
36extern int kidmum[2];
37
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 */
41extern int DebuggerARMul[2];
42
43/* The maximum number of file descriptors */
44extern int nfds;
45
46/* The child process id. */
47extern pid_t child;
48
49void
50parent ()
51{
52 int i, j, k;
53 unsigned char message, CPnum, exreturn;
54 ARMword mask, nbytes, messagetype;
55 unsigned char c, d;
56 ARMword x, y;
57 int virgin = 1;
58 struct fd_set readfds;
59
60#ifdef DEBUG
61 fprintf (stderr, "parent ()...\n");
62#endif
dfcd3bfb
JM
63
64panic_error:
c906108c
SS
65
66 if (!virgin)
67 {
68#ifdef DEBUG
dfcd3bfb 69 fprintf (stderr, "Arghh! What is going on?\n");
c906108c
SS
70#endif
71 kill (child, SIGHUP);
dfcd3bfb 72 MYwrite_char (debugsock, RDP_Reset);
c906108c 73 }
dfcd3bfb 74
c906108c
SS
75 virgin = 0;
76
77 while (1)
78 {
c906108c 79
dfcd3bfb 80 /* Wait either for the ARMulator or the debugger */
c906108c 81
dfcd3bfb
JM
82 FD_ZERO (&readfds);
83 FD_SET (kidmum[0], &readfds); /* Wait for messages from ARMulator */
84 FD_SET (debugsock, &readfds); /* Wait for messages from debugger */
c906108c
SS
85
86#ifdef DEBUG
dfcd3bfb 87 fprintf (stderr, "Waiting for ARMulator or debugger... ");
c906108c 88#endif
dfcd3bfb
JM
89
90 while ((i = select (nfds, &readfds, (fd_set *) 0, (fd_set *) 0, 0)) < 0)
91 {
92 perror ("select");
93 }
94
c906108c 95#ifdef DEBUG
dfcd3bfb
JM
96 fprintf (stderr, "(%d/2)", i);
97#endif
98
99 if (FD_ISSET (debugsock, &readfds))
c906108c 100 {
c906108c 101#ifdef DEBUG
dfcd3bfb 102 fprintf (stderr, "->debugger\n");
c906108c 103#endif
c906108c 104
dfcd3bfb
JM
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
109 cases. */
110
111 if (MYread_char (debugsock, &message))
c906108c
SS
112 goto panic_error;
113
dfcd3bfb 114 switch (message)
c906108c 115 {
dfcd3bfb
JM
116 case RDP_Start:
117 /* Open and/or Initialise */
c906108c 118#ifdef DEBUG
dfcd3bfb 119 fprintf (stderr, "RDP Open\n");
c906108c 120#endif
dfcd3bfb
JM
121 if (MYread_char (debugsock, &c)) /* type */
122 goto panic_error;
123
124 if (MYread_word (debugsock, &x)) /* memory size */
125 goto panic_error;
126
127 MYwrite_char (mumkid[1], message);
128 MYwrite_char (mumkid[1], c);
129 MYwrite_word (mumkid[1], x);
130 if (c & 0x2)
131 {
132 passon (debugsock, mumkid[1], 1); /* speed */
133 }
134 break;
135
136 case RDP_End:
137 /* Close and Finalise */
c906108c 138#ifdef DEBUG
dfcd3bfb 139 fprintf (stderr, "RDP Close\n");
c906108c 140#endif
dfcd3bfb
JM
141 MYwrite_char (mumkid[1], message);
142 break;
143
144 case RDP_Read:
145 /* Read Memory Address */
c906108c 146#ifdef DEBUG
dfcd3bfb 147 fprintf (stderr, "RDP Read Memory\n");
c906108c 148#endif
dfcd3bfb
JM
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);
155 break;
156
157 case RDP_Write:
158 /* Write Memory Address */
c906108c 159#ifdef DEBUG
dfcd3bfb 160 fprintf (stderr, "RDP Write Memory\n");
c906108c 161#endif
dfcd3bfb
JM
162 if (MYread_word (debugsock, &x))
163 goto panic_error; /* address */
c906108c 164
dfcd3bfb
JM
165 if (MYread_word (debugsock, &y))
166 goto panic_error; /* nbytes */
c906108c 167
dfcd3bfb
JM
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 */
172 break;
c906108c 173
dfcd3bfb
JM
174 case RDP_CPUread:
175 /* Read CPU State */
c906108c 176#ifdef DEBUG
dfcd3bfb 177 fprintf (stderr, "RDP Read CPU\n");
c906108c 178#endif
dfcd3bfb
JM
179 if (MYread_char (debugsock, &c))
180 goto panic_error; /* mode */
181
182 if (MYread_word (debugsock, &mask))
183 goto panic_error; /* mask */
184
185 MYwrite_char (mumkid[1], message);
186 MYwrite_char (mumkid[1], c);
187 MYwrite_word (mumkid[1], mask);
188 break;
189
190 case RDP_CPUwrite:
191 /* Write CPU State */
c906108c 192#ifdef DEBUG
dfcd3bfb 193 fprintf (stderr, "RDP Write CPU\n");
c906108c 194#endif
dfcd3bfb
JM
195 if (MYread_char (debugsock, &c))
196 goto panic_error; /* mode */
c906108c 197
dfcd3bfb
JM
198 if (MYread_word (debugsock, &x))
199 goto panic_error; /* mask */
200
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))
206 goto panic_error;
207 break;
c906108c 208
dfcd3bfb
JM
209 case RDP_CPread:
210 /* Read Co-Processor State */
c906108c 211#ifdef DEBUG
dfcd3bfb 212 fprintf (stderr, "RDP Read CP state\n");
c906108c 213#endif
dfcd3bfb
JM
214 if (MYread_char (debugsock, &CPnum))
215 goto panic_error;
c906108c 216
dfcd3bfb
JM
217 if (MYread_word (debugsock, &mask))
218 goto panic_error;
c906108c 219
dfcd3bfb
JM
220 MYwrite_char (mumkid[1], message);
221 MYwrite_char (mumkid[1], CPnum);
222 MYwrite_word (mumkid[1], mask);
223 break;
224
225 case RDP_CPwrite:
226 /* Write Co-Processor State */
c906108c 227#ifdef DEBUG
dfcd3bfb 228 fprintf (stderr, "RDP Write CP state\n");
c906108c 229#endif
dfcd3bfb
JM
230 if (MYread_char (debugsock, &CPnum))
231 goto panic_error;
232
233 if (MYread_word (debugsock, &mask))
234 goto panic_error;
235
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++)
240 if (k & x)
241 {
242 if ((c == 1 || c == 2) && k <= 128)
243 {
244 /* FP register = 12 bytes + 4 bytes format */
245 if (passon (debugsock, mumkid[1], 16))
246 goto panic_error;
247 }
248 else
249 {
250 /* Normal register = 4 bytes */
251 if (passon (debugsock, mumkid[1], 4))
252 goto panic_error;
253 }
254 }
255 break;
256
257 case RDP_SetBreak:
258 /* Set Breakpoint */
c906108c 259#ifdef DEBUG
dfcd3bfb 260 fprintf (stderr, "RDP Set Breakpoint\n");
c906108c 261#endif
dfcd3bfb
JM
262 if (MYread_word (debugsock, &x))
263 goto panic_error; /* address */
264
265 if (MYread_char (debugsock, &c))
266 goto panic_error; /* type */
267
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 */
273 break;
274
275 case RDP_ClearBreak:
276 /* Clear Breakpoint */
c906108c 277#ifdef DEBUG
dfcd3bfb 278 fprintf (stderr, "RDP Clear Breakpoint\n");
c906108c 279#endif
dfcd3bfb
JM
280 MYwrite_char (mumkid[1], message);
281 if (passon (debugsock, mumkid[1], 4))
282 goto panic_error; /* point */
283 break;
284
285 case RDP_SetWatch:
286 /* Set Watchpoint */
c906108c 287#ifdef DEBUG
dfcd3bfb 288 fprintf (stderr, "RDP Set Watchpoint\n");
c906108c 289#endif
dfcd3bfb
JM
290 if (MYread_word (debugsock, &x))
291 goto panic_error; /* address */
292
293 if (MYread_char (debugsock, &c))
294 goto panic_error; /* type */
295
296 if (MYread_char (debugsock, &d))
297 goto panic_error; /* datatype */
298
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 */
305 break;
c906108c 306
dfcd3bfb
JM
307 case RDP_ClearWatch:
308 /* Clear Watchpoint */
c906108c 309#ifdef DEBUG
dfcd3bfb 310 fprintf (stderr, "RDP Clear Watchpoint\n");
c906108c 311#endif
dfcd3bfb
JM
312 MYwrite_char (mumkid[1], message);
313 if (passon (debugsock, mumkid[1], 4))
314 goto panic_error; /* point */
315 break;
316
317 case RDP_Execute:
318 /* Excecute */
c906108c 319#ifdef DEBUG
dfcd3bfb 320 fprintf (stderr, "RDP Execute\n");
c906108c
SS
321#endif
322
dfcd3bfb
JM
323 /* LEAVE THIS ONE 'TIL LATER... */
324 /* NEED TO WORK THINGS OUT */
325
326 /* NO ASCYNCHROUS RUNNING */
c906108c 327
dfcd3bfb
JM
328 if (MYread_char (debugsock, &c))
329 goto panic_error; /* return */
c906108c 330
dfcd3bfb
JM
331 /* Remember incase bit 7 is set and we have to send back a word */
332 exreturn = c;
333
334 MYwrite_char (mumkid[1], message);
335 MYwrite_char (mumkid[1], c);
336 break;
337
338 case RDP_Step:
339 /* Step */
c906108c 340#ifdef DEBUG
dfcd3bfb 341 fprintf (stderr, "RDP Step\n");
c906108c 342#endif
c906108c 343
dfcd3bfb
JM
344 if (MYread_char (debugsock, &c))
345 goto panic_error; /* return */
346
347 if (MYread_word (debugsock, &x))
348 goto panic_error; /* ninstr */
349
c906108c 350 MYwrite_char (mumkid[1], message);
dfcd3bfb
JM
351 MYwrite_char (mumkid[1], c);
352 MYwrite_word (mumkid[1], x);
c906108c 353 break;
dfcd3bfb
JM
354
355 case RDP_Info:
356 /* Info */
357#ifdef DEBUG
358 fprintf (stderr, "RDP Info\n");
359#endif
360 /* INFO TARGET, SET RDI LEVEL */
361 if (MYread_word (debugsock, &messagetype))
362 goto panic_error; /* info */
363
364 switch (messagetype)
365 {
366 case RDIInfo_Target:
367 MYwrite_char (mumkid[1], message);
368 MYwrite_word (mumkid[1], messagetype);
369 break;
370
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 */
376 break;
377
378 case RDISet_Cmdline:
379 /* Got to pass on a string argument */
380 MYwrite_char (mumkid[1], message);
381 MYwrite_word (mumkid[1], messagetype);
382 do
383 {
384 if (MYread_char (debugsock, &c))
385 goto panic_error;
386
387 MYwrite_char (mumkid[1], c);
388 }
389 while (c);
390 break;
391
392 case RDISignal_Stop:
393 kill (child, SIGUSR1);
394 MYwrite_char (debugsock, RDP_Return);
395 MYwrite_char (debugsock, RDIError_UserInterrupt);
396 break;
397
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);
403 break;
404
405 case RDIInfo_Step:
406 MYwrite_char (mumkid[1], message);
407 MYwrite_word (mumkid[1], messagetype);
408 break;
409
410 case RDIInfo_Points:
411 MYwrite_char (mumkid[1], message);
412 MYwrite_word (mumkid[1], messagetype);
413 break;
414
415 default:
416 fprintf (stderr, "Unrecognized RDIInfo request %d\n",
417 messagetype);
418 goto panic_error;
419 }
c906108c
SS
420 break;
421
dfcd3bfb
JM
422 case RDP_OSOpReply:
423 /* OS Operation Reply */
424#ifdef DEBUG
425 fprintf (stderr, "RDP OS Reply\n");
426#endif
427 MYwrite_char (mumkid[1], message);
428 if (MYread_char (debugsock, &message))
429 goto panic_error;
c906108c 430 MYwrite_char (mumkid[1], message);
dfcd3bfb 431 switch (message)
c906108c 432 {
dfcd3bfb
JM
433 case 0: /* return value i.e. nothing else. */
434 break;
435
436 case 1: /* returns a byte... */
c906108c
SS
437 if (MYread_char (debugsock, &c))
438 goto panic_error;
439
440 MYwrite_char (mumkid[1], c);
dfcd3bfb 441 break;
c906108c 442
dfcd3bfb
JM
443 case 2: /* returns a word... */
444 if (MYread_word (debugsock, &x))
445 goto panic_error;
c906108c 446
dfcd3bfb
JM
447 MYwrite_word (mumkid[1], x);
448 break;
449 }
c906108c
SS
450 break;
451
dfcd3bfb
JM
452 case RDP_Reset:
453 /* Reset */
c906108c 454#ifdef DEBUG
dfcd3bfb 455 fprintf (stderr, "RDP Reset\n");
c906108c 456#endif
dfcd3bfb 457 MYwrite_char (mumkid[1], message);
c906108c
SS
458 break;
459
dfcd3bfb
JM
460 default:
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);
c906108c
SS
465 break;
466 }
dfcd3bfb
JM
467 }
468
469 if (FD_ISSET (kidmum[0], &readfds))
470 {
c906108c 471#ifdef DEBUG
dfcd3bfb 472 fprintf (stderr, "->ARMulator\n");
c906108c 473#endif
dfcd3bfb
JM
474 /* Anything we get from the ARMulator has to go to the debugger... */
475 /* It is that simple! */
476
477 passon (kidmum[0], debugsock, 1);
c906108c
SS
478 }
479 }
c906108c 480}