Upload Tizen:Base source
[external/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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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         {
102 #ifdef DEBUG
103           fprintf (stderr, "->debugger\n");
104 #endif
105
106           /* Inside this rather large if statement with simply pass on a complete 
107              message to the ARMulator.  The reason we need to pass messages on one
108              at a time is that we have to know whether the message is an OSOpReply
109              or an info(stop), so that we can take different action in those
110              cases. */
111
112           if (MYread_char (debugsock, &message))
113             goto panic_error;
114
115           switch (message)
116             {
117             case RDP_Start:
118               /* Open and/or Initialise */
119 #ifdef DEBUG
120               fprintf (stderr, "RDP Open\n");
121 #endif
122               if (MYread_char (debugsock, &c))  /* type */
123                 goto panic_error;
124
125               if (MYread_word (debugsock, &x))  /* memory size */
126                 goto panic_error;
127
128               MYwrite_char (mumkid[1], message);
129               MYwrite_char (mumkid[1], c);
130               MYwrite_word (mumkid[1], x);
131               if (c & 0x2)
132                 {
133                   passon (debugsock, mumkid[1], 1);     /* speed */
134                 }
135               break;
136
137             case RDP_End:
138               /* Close and Finalise */
139 #ifdef DEBUG
140               fprintf (stderr, "RDP Close\n");
141 #endif
142               MYwrite_char (mumkid[1], message);
143               break;
144
145             case RDP_Read:
146               /* Read Memory Address */
147 #ifdef DEBUG
148               fprintf (stderr, "RDP Read Memory\n");
149 #endif
150               MYwrite_char (mumkid[1], message);
151               if (passon (debugsock, mumkid[1], 4))
152                 goto panic_error;       /* address */
153               if (MYread_word (debugsock, &nbytes))
154                 goto panic_error;       /* nbytes */
155               MYwrite_word (mumkid[1], nbytes);
156               break;
157
158             case RDP_Write:
159               /* Write Memory Address */
160 #ifdef DEBUG
161               fprintf (stderr, "RDP Write Memory\n");
162 #endif
163               if (MYread_word (debugsock, &x))
164                 goto panic_error;       /* address */
165
166               if (MYread_word (debugsock, &y))
167                 goto panic_error;       /* nbytes */
168
169               MYwrite_char (mumkid[1], message);
170               MYwrite_word (mumkid[1], x);
171               MYwrite_word (mumkid[1], y);
172               passon (debugsock, mumkid[1], y); /* actual data */
173               break;
174
175             case RDP_CPUread:
176               /* Read CPU State */
177 #ifdef DEBUG
178               fprintf (stderr, "RDP Read CPU\n");
179 #endif
180               if (MYread_char (debugsock, &c))
181                 goto panic_error;       /* mode */
182
183               if (MYread_word (debugsock, &mask))
184                 goto panic_error;       /* mask */
185
186               MYwrite_char (mumkid[1], message);
187               MYwrite_char (mumkid[1], c);
188               MYwrite_word (mumkid[1], mask);
189               break;
190
191             case RDP_CPUwrite:
192               /* Write CPU State */
193 #ifdef DEBUG
194               fprintf (stderr, "RDP Write CPU\n");
195 #endif
196               if (MYread_char (debugsock, &c))
197                 goto panic_error;       /* mode */
198
199               if (MYread_word (debugsock, &x))
200                 goto panic_error;       /* mask */
201
202               MYwrite_char (mumkid[1], message);
203               MYwrite_char (mumkid[1], c);
204               MYwrite_word (mumkid[1], x);
205               for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
206                 if ((k & x) && 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) && passon (debugsock, mumkid[1], 4))
273                 goto panic_error;       /* bound */
274               break;
275
276             case RDP_ClearBreak:
277               /* Clear Breakpoint */
278 #ifdef DEBUG
279               fprintf (stderr, "RDP Clear Breakpoint\n");
280 #endif
281               MYwrite_char (mumkid[1], message);
282               if (passon (debugsock, mumkid[1], 4))
283                 goto panic_error;       /* point */
284               break;
285
286             case RDP_SetWatch:
287               /* Set Watchpoint */
288 #ifdef DEBUG
289               fprintf (stderr, "RDP Set Watchpoint\n");
290 #endif
291               if (MYread_word (debugsock, &x))
292                 goto panic_error;       /* address */
293
294               if (MYread_char (debugsock, &c))
295                 goto panic_error;       /* type */
296
297               if (MYread_char (debugsock, &d))
298                 goto panic_error;       /* datatype */
299
300               MYwrite_char (mumkid[1], message);
301               MYwrite_word (mumkid[1], x);
302               MYwrite_char (mumkid[1], c);
303               MYwrite_char (mumkid[1], d);
304               if (((c & 0xf) >= 5) && passon (debugsock, mumkid[1], 4))
305                 goto panic_error;       /* bound */
306               break;
307
308             case RDP_ClearWatch:
309               /* Clear Watchpoint */
310 #ifdef DEBUG
311               fprintf (stderr, "RDP Clear Watchpoint\n");
312 #endif
313               MYwrite_char (mumkid[1], message);
314               if (passon (debugsock, mumkid[1], 4))
315                 goto panic_error;       /* point */
316               break;
317
318             case RDP_Execute:
319               /* Excecute */
320 #ifdef DEBUG
321               fprintf (stderr, "RDP Execute\n");
322 #endif
323
324               /* LEAVE THIS ONE 'TIL LATER... */
325               /* NEED TO WORK THINGS OUT */
326
327               /* NO ASCYNCHROUS RUNNING */
328
329               if (MYread_char (debugsock, &c))
330                 goto panic_error;       /* return */
331
332               /* Remember incase bit 7 is set and we have to send back a word */
333               exreturn = c;
334
335               MYwrite_char (mumkid[1], message);
336               MYwrite_char (mumkid[1], c);
337               break;
338
339             case RDP_Step:
340               /* Step */
341 #ifdef DEBUG
342               fprintf (stderr, "RDP Step\n");
343 #endif
344
345               if (MYread_char (debugsock, &c))
346                 goto panic_error;       /* return */
347
348               if (MYread_word (debugsock, &x))
349                 goto panic_error;       /* ninstr */
350
351               MYwrite_char (mumkid[1], message);
352               MYwrite_char (mumkid[1], c);
353               MYwrite_word (mumkid[1], x);
354               break;
355
356             case RDP_Info:
357               /* Info */
358 #ifdef DEBUG
359               fprintf (stderr, "RDP Info\n");
360 #endif
361               /* INFO TARGET, SET RDI LEVEL */
362               if (MYread_word (debugsock, &messagetype))
363                 goto panic_error;       /* info */
364
365               switch (messagetype)
366                 {
367                 case RDIInfo_Target:
368                   MYwrite_char (mumkid[1], message);
369                   MYwrite_word (mumkid[1], messagetype);
370                   break;
371
372                 case RDISet_RDILevel:
373                   MYwrite_char (mumkid[1], message);
374                   MYwrite_word (mumkid[1], messagetype);
375                   if (passon (debugsock, mumkid[1], 1))
376                     goto panic_error;   /* argument */
377                   break;
378
379                 case RDISet_Cmdline:
380                   /* Got to pass on a string argument */
381                   MYwrite_char (mumkid[1], message);
382                   MYwrite_word (mumkid[1], messagetype);
383                   do
384                     {
385                       if (MYread_char (debugsock, &c))
386                         goto panic_error;
387
388                       MYwrite_char (mumkid[1], c);
389                     }
390                   while (c);
391                   break;
392
393                 case RDISignal_Stop:
394                   kill (child, SIGUSR1);
395                   MYwrite_char (debugsock, RDP_Return);
396                   MYwrite_char (debugsock, RDIError_UserInterrupt);
397                   break;
398
399                 case RDIVector_Catch:
400                   MYread_word (debugsock, &x);
401                   MYwrite_char (mumkid[1], message);
402                   MYwrite_word (mumkid[1], messagetype);
403                   MYwrite_word (mumkid[1], x);
404                   break;
405
406                 case RDIInfo_Step:
407                   MYwrite_char (mumkid[1], message);
408                   MYwrite_word (mumkid[1], messagetype);
409                   break;
410
411                 case RDIInfo_Points:
412                   MYwrite_char (mumkid[1], message);
413                   MYwrite_word (mumkid[1], messagetype);
414                   break;
415
416                 default:
417                   fprintf (stderr, "Unrecognized RDIInfo request %d\n",
418                            messagetype);
419                   goto panic_error;
420                 }
421               break;
422
423             case RDP_OSOpReply:
424               /* OS Operation Reply */
425 #ifdef DEBUG
426               fprintf (stderr, "RDP OS Reply\n");
427 #endif
428               MYwrite_char (mumkid[1], message);
429               if (MYread_char (debugsock, &message))
430                 goto panic_error;
431               MYwrite_char (mumkid[1], message);
432               switch (message)
433                 {
434                 case 0: /* return value i.e. nothing else. */
435                   break;
436
437                 case 1: /* returns a byte... */
438                   if (MYread_char (debugsock, &c))
439                     goto panic_error;
440
441                   MYwrite_char (mumkid[1], c);
442                   break;
443
444                 case 2: /* returns a word... */
445                   if (MYread_word (debugsock, &x))
446                     goto panic_error;
447
448                   MYwrite_word (mumkid[1], x);
449                   break;
450                 }
451               break;
452
453             case RDP_Reset:
454               /* Reset */
455 #ifdef DEBUG
456               fprintf (stderr, "RDP Reset\n");
457 #endif
458               MYwrite_char (mumkid[1], message);
459               break;
460
461             default:
462               /* Hmm.. bad RDP operation */
463               fprintf (stderr, "RDP Bad RDP request (%d)\n", message);
464               MYwrite_char (debugsock, RDP_Return);
465               MYwrite_char (debugsock, RDIError_UnimplementedMessage);
466               break;
467             }
468         }
469
470       if (FD_ISSET (kidmum[0], &readfds))
471         {
472 #ifdef DEBUG
473           fprintf (stderr, "->ARMulator\n");
474 #endif
475           /* Anything we get from the ARMulator has to go to the debugger... */
476           /* It is that simple! */
477
478           passon (kidmum[0], debugsock, 1);
479         }
480     }
481 }