]>
Commit | Line | Data |
---|---|---|
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 | |
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 | |
380d9419 | 16 | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ |
c906108c SS |
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 | |
dfcd3bfb JM |
64 | |
65 | panic_error: | |
c906108c SS |
66 | |
67 | if (!virgin) | |
68 | { | |
69 | #ifdef DEBUG | |
dfcd3bfb | 70 | fprintf (stderr, "Arghh! What is going on?\n"); |
c906108c SS |
71 | #endif |
72 | kill (child, SIGHUP); | |
dfcd3bfb | 73 | MYwrite_char (debugsock, RDP_Reset); |
c906108c | 74 | } |
dfcd3bfb | 75 | |
c906108c SS |
76 | virgin = 0; |
77 | ||
78 | while (1) | |
79 | { | |
c906108c | 80 | |
dfcd3bfb | 81 | /* Wait either for the ARMulator or the debugger */ |
c906108c | 82 | |
dfcd3bfb JM |
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 */ | |
c906108c SS |
86 | |
87 | #ifdef DEBUG | |
dfcd3bfb | 88 | fprintf (stderr, "Waiting for ARMulator or debugger... "); |
c906108c | 89 | #endif |
dfcd3bfb JM |
90 | |
91 | while ((i = select (nfds, &readfds, (fd_set *) 0, (fd_set *) 0, 0)) < 0) | |
92 | { | |
93 | perror ("select"); | |
94 | } | |
95 | ||
c906108c | 96 | #ifdef DEBUG |
dfcd3bfb JM |
97 | fprintf (stderr, "(%d/2)", i); |
98 | #endif | |
99 | ||
100 | if (FD_ISSET (debugsock, &readfds)) | |
c906108c | 101 | { |
c906108c | 102 | #ifdef DEBUG |
dfcd3bfb | 103 | fprintf (stderr, "->debugger\n"); |
c906108c | 104 | #endif |
c906108c | 105 | |
dfcd3bfb JM |
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)) | |
c906108c SS |
113 | goto panic_error; |
114 | ||
dfcd3bfb | 115 | switch (message) |
c906108c | 116 | { |
dfcd3bfb JM |
117 | case RDP_Start: |
118 | /* Open and/or Initialise */ | |
c906108c | 119 | #ifdef DEBUG |
dfcd3bfb | 120 | fprintf (stderr, "RDP Open\n"); |
c906108c | 121 | #endif |
dfcd3bfb JM |
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 */ | |
c906108c | 139 | #ifdef DEBUG |
dfcd3bfb | 140 | fprintf (stderr, "RDP Close\n"); |
c906108c | 141 | #endif |
dfcd3bfb JM |
142 | MYwrite_char (mumkid[1], message); |
143 | break; | |
144 | ||
145 | case RDP_Read: | |
146 | /* Read Memory Address */ | |
c906108c | 147 | #ifdef DEBUG |
dfcd3bfb | 148 | fprintf (stderr, "RDP Read Memory\n"); |
c906108c | 149 | #endif |
dfcd3bfb JM |
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 */ | |
c906108c | 160 | #ifdef DEBUG |
dfcd3bfb | 161 | fprintf (stderr, "RDP Write Memory\n"); |
c906108c | 162 | #endif |
dfcd3bfb JM |
163 | if (MYread_word (debugsock, &x)) |
164 | goto panic_error; /* address */ | |
c906108c | 165 | |
dfcd3bfb JM |
166 | if (MYread_word (debugsock, &y)) |
167 | goto panic_error; /* nbytes */ | |
c906108c | 168 | |
dfcd3bfb JM |
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; | |
c906108c | 174 | |
dfcd3bfb JM |
175 | case RDP_CPUread: |
176 | /* Read CPU State */ | |
c906108c | 177 | #ifdef DEBUG |
dfcd3bfb | 178 | fprintf (stderr, "RDP Read CPU\n"); |
c906108c | 179 | #endif |
dfcd3bfb JM |
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 */ | |
c906108c | 193 | #ifdef DEBUG |
dfcd3bfb | 194 | fprintf (stderr, "RDP Write CPU\n"); |
c906108c | 195 | #endif |
dfcd3bfb JM |
196 | if (MYread_char (debugsock, &c)) |
197 | goto panic_error; /* mode */ | |
c906108c | 198 | |
dfcd3bfb JM |
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; | |
c906108c | 209 | |
dfcd3bfb JM |
210 | case RDP_CPread: |
211 | /* Read Co-Processor State */ | |
c906108c | 212 | #ifdef DEBUG |
dfcd3bfb | 213 | fprintf (stderr, "RDP Read CP state\n"); |
c906108c | 214 | #endif |
dfcd3bfb JM |
215 | if (MYread_char (debugsock, &CPnum)) |
216 | goto panic_error; | |
c906108c | 217 | |
dfcd3bfb JM |
218 | if (MYread_word (debugsock, &mask)) |
219 | goto panic_error; | |
c906108c | 220 | |
dfcd3bfb JM |
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 */ | |
c906108c | 228 | #ifdef DEBUG |
dfcd3bfb | 229 | fprintf (stderr, "RDP Write CP state\n"); |
c906108c | 230 | #endif |
dfcd3bfb JM |
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 */ | |
c906108c | 260 | #ifdef DEBUG |
dfcd3bfb | 261 | fprintf (stderr, "RDP Set Breakpoint\n"); |
c906108c | 262 | #endif |
dfcd3bfb JM |
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 */ | |
c906108c | 278 | #ifdef DEBUG |
dfcd3bfb | 279 | fprintf (stderr, "RDP Clear Breakpoint\n"); |
c906108c | 280 | #endif |
dfcd3bfb JM |
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 */ | |
c906108c | 288 | #ifdef DEBUG |
dfcd3bfb | 289 | fprintf (stderr, "RDP Set Watchpoint\n"); |
c906108c | 290 | #endif |
dfcd3bfb JM |
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; | |
c906108c | 307 | |
dfcd3bfb JM |
308 | case RDP_ClearWatch: |
309 | /* Clear Watchpoint */ | |
c906108c | 310 | #ifdef DEBUG |
dfcd3bfb | 311 | fprintf (stderr, "RDP Clear Watchpoint\n"); |
c906108c | 312 | #endif |
dfcd3bfb JM |
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 */ | |
c906108c | 320 | #ifdef DEBUG |
dfcd3bfb | 321 | fprintf (stderr, "RDP Execute\n"); |
c906108c SS |
322 | #endif |
323 | ||
dfcd3bfb JM |
324 | /* LEAVE THIS ONE 'TIL LATER... */ |
325 | /* NEED TO WORK THINGS OUT */ | |
326 | ||
327 | /* NO ASCYNCHROUS RUNNING */ | |
c906108c | 328 | |
dfcd3bfb JM |
329 | if (MYread_char (debugsock, &c)) |
330 | goto panic_error; /* return */ | |
c906108c | 331 | |
dfcd3bfb JM |
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 */ | |
c906108c | 341 | #ifdef DEBUG |
dfcd3bfb | 342 | fprintf (stderr, "RDP Step\n"); |
c906108c | 343 | #endif |
c906108c | 344 | |
dfcd3bfb JM |
345 | if (MYread_char (debugsock, &c)) |
346 | goto panic_error; /* return */ | |
347 | ||
348 | if (MYread_word (debugsock, &x)) | |
349 | goto panic_error; /* ninstr */ | |
350 | ||
c906108c | 351 | MYwrite_char (mumkid[1], message); |
dfcd3bfb JM |
352 | MYwrite_char (mumkid[1], c); |
353 | MYwrite_word (mumkid[1], x); | |
c906108c | 354 | break; |
dfcd3bfb JM |
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 | } | |
c906108c SS |
421 | break; |
422 | ||
dfcd3bfb JM |
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; | |
c906108c | 431 | MYwrite_char (mumkid[1], message); |
dfcd3bfb | 432 | switch (message) |
c906108c | 433 | { |
dfcd3bfb JM |
434 | case 0: /* return value i.e. nothing else. */ |
435 | break; | |
436 | ||
437 | case 1: /* returns a byte... */ | |
c906108c SS |
438 | if (MYread_char (debugsock, &c)) |
439 | goto panic_error; | |
440 | ||
441 | MYwrite_char (mumkid[1], c); | |
dfcd3bfb | 442 | break; |
c906108c | 443 | |
dfcd3bfb JM |
444 | case 2: /* returns a word... */ |
445 | if (MYread_word (debugsock, &x)) | |
446 | goto panic_error; | |
c906108c | 447 | |
dfcd3bfb JM |
448 | MYwrite_word (mumkid[1], x); |
449 | break; | |
450 | } | |
c906108c SS |
451 | break; |
452 | ||
dfcd3bfb JM |
453 | case RDP_Reset: |
454 | /* Reset */ | |
c906108c | 455 | #ifdef DEBUG |
dfcd3bfb | 456 | fprintf (stderr, "RDP Reset\n"); |
c906108c | 457 | #endif |
dfcd3bfb | 458 | MYwrite_char (mumkid[1], message); |
c906108c SS |
459 | break; |
460 | ||
dfcd3bfb JM |
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); | |
c906108c SS |
466 | break; |
467 | } | |
dfcd3bfb JM |
468 | } |
469 | ||
470 | if (FD_ISSET (kidmum[0], &readfds)) | |
471 | { | |
c906108c | 472 | #ifdef DEBUG |
dfcd3bfb | 473 | fprintf (stderr, "->ARMulator\n"); |
c906108c | 474 | #endif |
dfcd3bfb JM |
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); | |
c906108c SS |
479 | } |
480 | } | |
c906108c | 481 | } |