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