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