tizen 2.4 release
[external/binutils.git] / sim / arm / kid.c
1 /*  kid.c -- ARMulator RDP/RDI interface:  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 3 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, see <http://www.gnu.org/licenses/>. */
16
17 /*****************************************************************/
18 /* The child process continues here...                           */
19 /* It waits on a pipe from the parent and translates the RDP     */
20 /* messages into RDI calls to the ARMulator passing RDP replies  */
21 /* back up a pipe to the parent.                                 */
22 /*****************************************************************/
23
24 #include <sys/types.h>
25 #include <signal.h>
26
27 #include "armdefs.h"
28 #include "dbg_conf.h"
29 #include "dbg_hif.h"
30 #include "dbg_rdi.h"
31 #include "gdbhost.h"
32 #include "communicate.h"
33
34 /* The pipes between the two processes */
35 extern int mumkid[2];
36 extern int kidmum[2];
37
38 /* The maximum number of file descriptors */
39 extern int nfds;
40
41 /* The machine name */
42 #define MAXHOSTNAMELENGTH 64
43 extern char localhost[MAXHOSTNAMELENGTH + 1];
44
45 /* The socket number */
46 extern unsigned int socketnumber;
47
48 /* RDI interface */
49 extern const struct RDIProcVec armul_rdi;
50
51 static int MYrdp_level = 0;
52
53 static int rdi_state = 0;
54
55 /**************************************************************/
56 /* Signal handler that terminates excecution in the ARMulator */
57 /**************************************************************/
58 void
59 kid_handlesignal (int sig)
60 {
61 #ifdef DEBUG
62   fprintf (stderr, "Terminate ARMulator excecution\n");
63 #endif
64   if (sig != SIGUSR1)
65     {
66       fprintf (stderr, "Unsupported signal.\n");
67       return;
68     }
69   armul_rdi.info (RDISignal_Stop, (unsigned long *) 0, (unsigned long *) 0);
70 }
71
72 /********************************************************************/
73 /* Waits on a pipe from the socket demon for RDP and                */
74 /* acts as an RDP to RDI interpreter on the front of the ARMulator. */
75 /********************************************************************/
76 void
77 kid ()
78 {
79   char *p, *q;
80   int i, j, k;
81   long outofthebag;
82   unsigned char c, d, message;
83   ARMword x, y, z;
84   struct sigaction action;
85   PointHandle point;
86   Dbg_ConfigBlock config;
87   Dbg_HostosInterface hostif;
88   struct Dbg_MCState *MCState;
89   char command_line[256];
90   struct fd_set readfds;
91
92   /* Setup a signal handler for SIGUSR1 */
93   action.sa_handler = kid_handlesignal;
94   action.sa_mask = 0;
95   action.sa_flags = 0;
96
97   sigaction (SIGUSR1, &action, (struct sigaction *) 0);
98
99   while (1)
100     {
101       /* Wait for ever */
102       FD_ZERO (&readfds);
103       FD_SET (mumkid[0], &readfds);
104
105       i = select (nfds, &readfds,
106                   (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0);
107
108       if (i < 0)
109         {
110           perror ("select");
111         }
112
113       if (read (mumkid[0], &message, 1) < 1)
114         {
115           perror ("read");
116         }
117
118       switch (message)
119         {
120         case RDP_Start:
121           /* Open and/or Initialise */
122           BAG_newbag ();
123
124           MYread_char (mumkid[0], &c);  /* type */
125           MYread_word (mumkid[0], &x);  /* memorysize */
126           if (c & 0x2)
127             MYread_char (mumkid[0], &d);        /* speed */
128           config.processor = 0;
129           config.memorysize = x;
130           config.bytesex = (c & 0x4) ? RDISex_Big : RDISex_Little;
131           if (c & 0x8)
132             config.bytesex = RDISex_DontCare;
133
134           hostif.dbgprint = myprint;
135           hostif.dbgpause = mypause;
136           hostif.dbgarg = stdout;
137           hostif.writec = mywritec;
138           hostif.readc = myreadc;
139           hostif.write = mywrite;
140           hostif.gets = mygets;
141           hostif.reset = mypause;       /* do nothing */
142           hostif.resetarg = "Do I love resetting or what!\n";
143
144           if (rdi_state)
145             {
146               /* we have restarted, so kill off the existing run.  */
147               /* armul_rdi.close(); */
148             }
149           i = armul_rdi.open (c & 0x3, &config, &hostif, MCState);
150           rdi_state = 1;
151
152           MYwrite_char (kidmum[1], RDP_Return);
153           MYwrite_char (kidmum[1], (unsigned char) i);
154
155           x = ~0x4;
156           armul_rdi.info (RDIVector_Catch, &x, 0);
157
158           break;
159
160         case RDP_End:
161           /* Close and Finalise */
162           i = armul_rdi.close ();
163           rdi_state = 0;
164           MYwrite_char (kidmum[1], RDP_Return);
165           MYwrite_char (kidmum[1], (unsigned char) i);
166           break;
167
168         case RDP_Read:
169           /* Read Memory Address */
170           MYread_word (mumkid[0], &x);  /* address */
171           MYread_word (mumkid[0], &y);  /* nbytes */
172           p = (char *) malloc (y);
173           i = armul_rdi.read (x, p, (unsigned *) &y);
174           MYwrite_char (kidmum[1], RDP_Return);
175           for (k = 0; k < y; k++)
176             MYwrite_char (kidmum[1], p[k]);
177           free (p);
178           MYwrite_char (kidmum[1], (unsigned char) i);
179           if (i)
180             MYwrite_word (kidmum[1], y);        /* number of bytes sent without error */
181           break;
182
183         case RDP_Write:
184           /* Write Memory Address */
185           MYread_word (mumkid[0], &x);  /* address */
186           MYread_word (mumkid[0], &y);  /* nbytes */
187           p = (char *) malloc (y);
188           for (k = 0; k < y; k++)
189             MYread_char (mumkid[0], &p[k]);
190           i = armul_rdi.write (p, x, (unsigned *) &y);
191           free (p);
192           MYwrite_char (kidmum[1], RDP_Return);
193           MYwrite_char (kidmum[1], (unsigned char) i);
194           if (i)
195             MYwrite_word (kidmum[1], y);        /* number of bytes sent without error */
196           break;
197
198         case RDP_CPUread:
199           /* Read CPU State */
200           MYread_char (mumkid[0], &c);  /* mode */
201           MYread_word (mumkid[0], &x);  /* mask */
202           p = (char *) malloc (4 * RDINumCPURegs);
203           i = armul_rdi.CPUread (c, x, (ARMword *) p);
204           MYwrite_char (kidmum[1], RDP_Return);
205           for (k = 1, j = 0; k != 0x80000000; k *= 2)
206             if (k & x)
207               MYwrite_word (kidmum[1], ((ARMword *) p)[j++]);
208           free (p);
209           if (i)
210             MYwrite_char (kidmum[1], (unsigned char) j);
211           MYwrite_char (kidmum[1], (unsigned char) i);
212           break;
213
214         case RDP_CPUwrite:
215           /* Write CPU State */
216           MYread_char (mumkid[0], &c);  /* mode */
217           MYread_word (mumkid[0], &x);  /* mask */
218
219           p = (char *) malloc (4 * RDINumCPURegs);
220           for (k = 1, j = 0; k != 0x80000000; k *= 2)
221             if (k & x)
222               MYread_word (mumkid[0], &(((ARMword *) p)[j++]));
223           i = armul_rdi.CPUwrite (c, x, (ARMword *) p);
224           MYwrite_char (kidmum[1], RDP_Return);
225           MYwrite_char (kidmum[1], (unsigned char) i);
226           free (p);
227           break;
228
229         case RDP_CPread:
230           /* Read Co-Processor State */
231           MYread_char (mumkid[0], &c);  /* CPnum */
232           MYread_word (mumkid[0], &x);  /* mask */
233           p = q = (char *) malloc (16 * RDINumCPRegs);
234           i = armul_rdi.CPread (c, x, (ARMword *) p);
235           MYwrite_char (kidmum[1], RDP_Return);
236           for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
237             if (k & x)
238               {
239                 if ((c == 1 || c == 2) && k <= 128)
240                   {
241                     MYwrite_FPword (kidmum[1], q);
242                     q += 16;
243                   }
244                 else
245                   {
246                     MYwrite_word (kidmum[1], *q);
247                     q += 4;
248                   }
249               }
250           free (p);
251           if (i)
252             MYwrite_char (kidmum[1], (unsigned char) j);
253           MYwrite_char (kidmum[1], (unsigned char) i);
254           break;
255
256         case RDP_CPwrite:
257           /* Write Co-Processor State */
258           MYread_char (mumkid[0], &c);  /* CPnum */
259           MYread_word (mumkid[0], &x);  /* mask */
260           p = q = (char *) malloc (16 * RDINumCPURegs);
261           for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
262             if (k & x)
263               {
264                 if ((c == 1 || c == 2) && k <= 128)
265                   {
266                     MYread_FPword (kidmum[1], q);
267                     q += 16;
268                   }
269                 else
270                   {
271                     MYread_word (mumkid[0], (ARMword *) q);
272                     q += 4;
273                   }
274               }
275           i = armul_rdi.CPwrite (c, x, (ARMword *) p);
276           MYwrite_char (kidmum[1], RDP_Return);
277           MYwrite_char (kidmum[1], (unsigned char) i);
278           free (p);
279           break;
280
281         case RDP_SetBreak:
282           /* Set Breakpoint */
283           MYread_word (mumkid[0], &x);  /* address */
284           MYread_char (mumkid[0], &c);  /* type */
285           if ((c & 0xf) >= 5)
286             MYread_word (mumkid[0], &y);        /* bound */
287           i = armul_rdi.setbreak (x, c, y, &point);
288           if (!MYrdp_level)
289             BAG_putpair ((long) x, (long) point);
290           MYwrite_char (kidmum[1], RDP_Return);
291           if (MYrdp_level)
292             MYwrite_word (kidmum[1], point);
293           MYwrite_char (kidmum[1], (unsigned char) i);
294           break;
295
296         case RDP_ClearBreak:
297           /* Clear Breakpoint */
298           MYread_word (mumkid[0], &point);      /* PointHandle */
299           if (!MYrdp_level)
300             {
301               BAG_getsecond ((long) point, &outofthebag);       /* swap pointhandle for address */
302               BAG_killpair_byfirst (outofthebag);
303               point = outofthebag;
304             }
305           i = armul_rdi.clearbreak (point);
306           MYwrite_char (kidmum[1], RDP_Return);
307           MYwrite_char (kidmum[1], (unsigned char) i);
308           break;
309
310         case RDP_SetWatch:
311           /* Set Watchpoint */
312           MYread_word (mumkid[0], &x);  /* address */
313           MYread_char (mumkid[0], &c);  /* type */
314           MYread_char (mumkid[0], &d);  /* datatype */
315           if ((c & 0xf) >= 5)
316             MYread_word (mumkid[0], &y);        /* bound */
317           i = armul_rdi.setwatch (x, c, d, y, &point);
318           MYwrite_char (kidmum[1], RDP_Return);
319           MYwrite_word (kidmum[1], point);
320           MYwrite_char (kidmum[1], (unsigned char) i);
321           break;
322
323         case RDP_ClearWatch:
324           /* Clear Watchpoint */
325           MYread_word (mumkid[0], &point);      /* PointHandle */
326           i = armul_rdi.clearwatch (point);
327           MYwrite_char (kidmum[1], RDP_Return);
328           MYwrite_char (kidmum[1], (unsigned char) i);
329           break;
330
331         case RDP_Execute:
332           /* Excecute */
333
334           MYread_char (mumkid[0], &c);  /* return */
335
336 #ifdef DEBUG
337           fprintf (stderr, "Starting execution\n");
338 #endif
339           i = armul_rdi.execute (&point);
340 #ifdef DEBUG
341           fprintf (stderr, "Completed execution\n");
342 #endif
343           MYwrite_char (kidmum[1], RDP_Return);
344           if (c & 0x80)
345             MYwrite_word (kidmum[1], point);
346           MYwrite_char (kidmum[1], (unsigned char) i);
347           break;
348
349         case RDP_Step:
350           /* Step */
351           MYread_char (mumkid[0], &c);  /* return */
352           MYread_word (mumkid[0], &x);  /* ninstr */
353           point = 0x87654321;
354           i = armul_rdi.step (x, &point);
355           MYwrite_char (kidmum[1], RDP_Return);
356           if (c & 0x80)
357             MYwrite_word (kidmum[1], point);
358           MYwrite_char (kidmum[1], (unsigned char) i);
359           break;
360
361         case RDP_Info:
362           /* Info */
363           MYread_word (mumkid[0], &x);
364           switch (x)
365             {
366             case RDIInfo_Target:
367               i = armul_rdi.info (RDIInfo_Target, &y, &z);
368               MYwrite_char (kidmum[1], RDP_Return);
369               MYwrite_word (kidmum[1], y);      /* Loads of info... */
370               MYwrite_word (kidmum[1], z);      /* Model */
371               MYwrite_char (kidmum[1], (unsigned char) i);
372               break;
373
374             case RDISet_RDILevel:
375               MYread_word (mumkid[0], &x);      /* arg1, debug level */
376               i = armul_rdi.info (RDISet_RDILevel, &x, 0);
377               if (i == RDIError_NoError)
378                 MYrdp_level = x;
379               MYwrite_char (kidmum[1], RDP_Return);
380               MYwrite_char (kidmum[1], (unsigned char) i);
381               break;
382
383             case RDISet_Cmdline:
384               for (p = command_line; MYread_char (mumkid[0], p), *p; p++)
385                 ;               /* String */
386               i = armul_rdi.info (RDISet_Cmdline,
387                                   (unsigned long *) command_line, 0);
388               MYwrite_char (kidmum[1], RDP_Return);
389               MYwrite_char (kidmum[1], (unsigned char) i);
390               break;
391
392             case RDIInfo_Step:
393               i = armul_rdi.info (RDIInfo_Step, &x, 0);
394               MYwrite_char (kidmum[1], RDP_Return);
395               MYwrite_word (kidmum[1], x);
396               MYwrite_char (kidmum[1], (unsigned char) i);
397               break;
398
399             case RDIVector_Catch:
400               MYread_word (mumkid[0], &x);
401               i = armul_rdi.info (RDIVector_Catch, &x, 0);
402               MYwrite_char (kidmum[1], RDP_Return);
403               MYwrite_char (kidmum[1], i);
404               break;
405
406             case RDIInfo_Points:
407               i = armul_rdi.info (RDIInfo_Points, &x, 0);
408               MYwrite_char (kidmum[1], RDP_Return);
409               MYwrite_word (kidmum[1], x);
410               MYwrite_char (kidmum[1], (unsigned char) i);
411               break;
412
413             default:
414               fprintf (stderr, "Unsupported info code %d\n", x);
415               break;
416             }
417           break;
418
419         case RDP_OSOpReply:
420           /* OS Operation Reply */
421           MYwrite_char (kidmum[1], RDP_Fatal);
422           break;
423
424         case RDP_Reset:
425           /* Reset */
426           for (i = 0; i < 50; i++)
427             MYwrite_char (kidmum[1], RDP_Reset);
428           p = (char *) malloc (MAXHOSTNAMELENGTH + 5 + 20);
429           sprintf (p, "Running on %s:%d\n", localhost, socketnumber);
430           MYwrite_string (kidmum[1], p);
431           free (p);
432
433           break;
434         default:
435           fprintf (stderr, "Oh dear: Something is seriously wrong :-(\n");
436           /* Hmm.. bad RDP operation */
437           break;
438         }
439     }
440 }
441
442
443 /* Handles memory read operations until an OS Operation Reply Message is */
444 /* encounterd. It then returns the byte info value (0, 1, or 2) and fills  */
445 /* in 'putinr0' with the data if appropriate. */
446 int
447 wait_for_osreply (ARMword * reply)
448 {
449   char *p, *q;
450   int i, j, k;
451   unsigned char c, d, message;
452   ARMword x, y, z;
453   struct sigaction action;
454   PointHandle point;
455   Dbg_ConfigBlock config;
456   Dbg_HostosInterface hostif;
457   struct Dbg_MCState *MCState;
458   char command_line[256];
459   struct fd_set readfds;
460
461 #ifdef DEBUG
462   fprintf (stderr, "wait_for_osreply ().\n");
463 #endif
464
465   /* Setup a signal handler for SIGUSR1 */
466   action.sa_handler = kid_handlesignal;
467   action.sa_mask = 0;
468   action.sa_flags = 0;
469
470   sigaction (SIGUSR1, &action, (struct sigaction *) 0);
471
472   while (1)
473     {
474       /* Wait for ever */
475       FD_ZERO (&readfds);
476       FD_SET (mumkid[0], &readfds);
477
478       i = select (nfds, &readfds,
479                   (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0);
480
481       if (i < 0)
482         {
483           perror ("select");
484         }
485
486       if (read (mumkid[0], &message, 1) < 1)
487         {
488           perror ("read");
489         }
490
491       switch (message)
492         {
493         case RDP_Read:
494           /* Read Memory Address */
495           MYread_word (mumkid[0], &x);  /* address */
496           MYread_word (mumkid[0], &y);  /* nbytes */
497           p = (char *) malloc (y);
498           i = armul_rdi.read (x, p, (unsigned *) &y);
499           MYwrite_char (kidmum[1], RDP_Return);
500           for (k = 0; k < y; k++)
501             MYwrite_char (kidmum[1], p[k]);
502           free (p);
503           MYwrite_char (kidmum[1], (unsigned char) i);
504           if (i)
505             MYwrite_word (kidmum[1], y);        /* number of bytes sent without error */
506           break;
507
508         case RDP_Write:
509           /* Write Memory Address */
510           MYread_word (mumkid[0], &x);  /* address */
511           MYread_word (mumkid[0], &y);  /* nbytes */
512           p = (char *) malloc (y);
513           for (k = 0; k < y; k++)
514             MYread_char (mumkid[0], &p[k]);
515           i = armul_rdi.write (p, x, (unsigned *) &y);
516           free (p);
517           MYwrite_char (kidmum[1], RDP_Return);
518           MYwrite_char (kidmum[1], (unsigned char) i);
519           if (i)
520             MYwrite_word (kidmum[1], y);        /* number of bytes sent without error */
521           break;
522
523         case RDP_OSOpReply:
524           /* OS Operation Reply */
525           MYread_char (mumkid[0], &c);
526           if (c == 1)
527             MYread_char (mumkid[0], (char *) reply);
528           if (c == 2)
529             MYread_word (mumkid[0], reply);
530           return c;
531           break;
532
533         default:
534           fprintf (stderr,
535                    "HELP! Unaccounted-for message during OS request. \n");
536           MYwrite_char (kidmum[1], RDP_Fatal);
537         }
538     }
539 }