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