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 */ 33extern int debugsock; 34 35/* The pipes between the two processes */ 36extern int mumkid[2]; 37extern 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 */ 42extern int DebuggerARMul[2]; 43 44/* The maximum number of file descriptors */ 45extern int nfds; 46 47/* The child process id. */ 48extern pid_t child; 49 50void 51parent () 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 65panic_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} 482