123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481 |
- /* parent.c -- ARMulator RDP comms code: ARM6 Instruction Emulator.
- Copyright (C) 1994 Advanced RISC Machines Ltd.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>. */
- /*****************************************************************/
- /* The Parent process continues here... */
- /* It waits on the socket and passes on RDP messages down a pipe */
- /* to the ARMulator RDP to RDI interpreter. */
- /*****************************************************************/
- #include <stdio.h>
- #include <sys/types.h>
- #include <signal.h>
- #include "time.h"
- #include "armdefs.h"
- #include "dbg_rdi.h"
- #include "communicate.h"
- /* The socket to the debugger */
- extern int debugsock;
- /* The pipes between the two processes */
- extern int mumkid[2];
- extern int kidmum[2];
- /* A pipe for handling SWI return values that goes straight from the */
- /* parent to the ARMulator host interface, bypassing the child's RDP */
- /* to RDI interpreter */
- extern int DebuggerARMul[2];
- /* The maximum number of file descriptors */
- extern int nfds;
- /* The child process id. */
- extern pid_t child;
- void
- parent ()
- {
- int i, j, k;
- unsigned char message, CPnum, exreturn;
- ARMword mask, nbytes, messagetype;
- unsigned char c, d;
- ARMword x, y;
- int virgin = 1;
- struct fd_set readfds;
- #ifdef DEBUG
- fprintf (stderr, "parent ()...\n");
- #endif
- panic_error:
- if (!virgin)
- {
- #ifdef DEBUG
- fprintf (stderr, "Arghh! What is going on?\n");
- #endif
- kill (child, SIGHUP);
- MYwrite_char (debugsock, RDP_Reset);
- }
- virgin = 0;
- while (1)
- {
- /* Wait either for the ARMulator or the debugger */
- FD_ZERO (&readfds);
- FD_SET (kidmum[0], &readfds); /* Wait for messages from ARMulator */
- FD_SET (debugsock, &readfds); /* Wait for messages from debugger */
- #ifdef DEBUG
- fprintf (stderr, "Waiting for ARMulator or debugger... ");
- #endif
- while ((i = select (nfds, &readfds, (fd_set *) 0, (fd_set *) 0, 0)) < 0)
- {
- perror ("select");
- }
- #ifdef DEBUG
- fprintf (stderr, "(%d/2)", i);
- #endif
- if (FD_ISSET (debugsock, &readfds))
- {
- #ifdef DEBUG
- fprintf (stderr, "->debugger\n");
- #endif
- /* Inside this rather large if statement with simply pass on a complete
- message to the ARMulator. The reason we need to pass messages on one
- at a time is that we have to know whether the message is an OSOpReply
- or an info(stop), so that we can take different action in those
- cases. */
- if (MYread_char (debugsock, &message))
- goto panic_error;
- switch (message)
- {
- case RDP_Start:
- /* Open and/or Initialise */
- #ifdef DEBUG
- fprintf (stderr, "RDP Open\n");
- #endif
- if (MYread_char (debugsock, &c)) /* type */
- goto panic_error;
- if (MYread_word (debugsock, &x)) /* memory size */
- goto panic_error;
- MYwrite_char (mumkid[1], message);
- MYwrite_char (mumkid[1], c);
- MYwrite_word (mumkid[1], x);
- if (c & 0x2)
- {
- passon (debugsock, mumkid[1], 1); /* speed */
- }
- break;
- case RDP_End:
- /* Close and Finalise */
- #ifdef DEBUG
- fprintf (stderr, "RDP Close\n");
- #endif
- MYwrite_char (mumkid[1], message);
- break;
- case RDP_Read:
- /* Read Memory Address */
- #ifdef DEBUG
- fprintf (stderr, "RDP Read Memory\n");
- #endif
- MYwrite_char (mumkid[1], message);
- if (passon (debugsock, mumkid[1], 4))
- goto panic_error; /* address */
- if (MYread_word (debugsock, &nbytes))
- goto panic_error; /* nbytes */
- MYwrite_word (mumkid[1], nbytes);
- break;
- case RDP_Write:
- /* Write Memory Address */
- #ifdef DEBUG
- fprintf (stderr, "RDP Write Memory\n");
- #endif
- if (MYread_word (debugsock, &x))
- goto panic_error; /* address */
- if (MYread_word (debugsock, &y))
- goto panic_error; /* nbytes */
- MYwrite_char (mumkid[1], message);
- MYwrite_word (mumkid[1], x);
- MYwrite_word (mumkid[1], y);
- passon (debugsock, mumkid[1], y); /* actual data */
- break;
- case RDP_CPUread:
- /* Read CPU State */
- #ifdef DEBUG
- fprintf (stderr, "RDP Read CPU\n");
- #endif
- if (MYread_char (debugsock, &c))
- goto panic_error; /* mode */
- if (MYread_word (debugsock, &mask))
- goto panic_error; /* mask */
- MYwrite_char (mumkid[1], message);
- MYwrite_char (mumkid[1], c);
- MYwrite_word (mumkid[1], mask);
- break;
- case RDP_CPUwrite:
- /* Write CPU State */
- #ifdef DEBUG
- fprintf (stderr, "RDP Write CPU\n");
- #endif
- if (MYread_char (debugsock, &c))
- goto panic_error; /* mode */
- if (MYread_word (debugsock, &x))
- goto panic_error; /* mask */
- MYwrite_char (mumkid[1], message);
- MYwrite_char (mumkid[1], c);
- MYwrite_word (mumkid[1], x);
- for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
- if ((k & x) && passon (debugsock, mumkid[1], 4))
- goto panic_error;
- break;
- case RDP_CPread:
- /* Read Co-Processor State */
- #ifdef DEBUG
- fprintf (stderr, "RDP Read CP state\n");
- #endif
- if (MYread_char (debugsock, &CPnum))
- goto panic_error;
- if (MYread_word (debugsock, &mask))
- goto panic_error;
- MYwrite_char (mumkid[1], message);
- MYwrite_char (mumkid[1], CPnum);
- MYwrite_word (mumkid[1], mask);
- break;
- case RDP_CPwrite:
- /* Write Co-Processor State */
- #ifdef DEBUG
- fprintf (stderr, "RDP Write CP state\n");
- #endif
- if (MYread_char (debugsock, &CPnum))
- goto panic_error;
- if (MYread_word (debugsock, &mask))
- goto panic_error;
- MYwrite_char (mumkid[1], message);
- MYwrite_char (mumkid[1], c);
- MYwrite_char (mumkid[1], x);
- for (k = 1, j = 0; k != 0x80000000; k *= 2, j++)
- if (k & x)
- {
- if ((c == 1 || c == 2) && k <= 128)
- {
- /* FP register = 12 bytes + 4 bytes format */
- if (passon (debugsock, mumkid[1], 16))
- goto panic_error;
- }
- else
- {
- /* Normal register = 4 bytes */
- if (passon (debugsock, mumkid[1], 4))
- goto panic_error;
- }
- }
- break;
- case RDP_SetBreak:
- /* Set Breakpoint */
- #ifdef DEBUG
- fprintf (stderr, "RDP Set Breakpoint\n");
- #endif
- if (MYread_word (debugsock, &x))
- goto panic_error; /* address */
- if (MYread_char (debugsock, &c))
- goto panic_error; /* type */
- MYwrite_char (mumkid[1], message);
- MYwrite_word (mumkid[1], x);
- MYwrite_char (mumkid[1], c);
- if (((c & 0xf) >= 5) && passon (debugsock, mumkid[1], 4))
- goto panic_error; /* bound */
- break;
- case RDP_ClearBreak:
- /* Clear Breakpoint */
- #ifdef DEBUG
- fprintf (stderr, "RDP Clear Breakpoint\n");
- #endif
- MYwrite_char (mumkid[1], message);
- if (passon (debugsock, mumkid[1], 4))
- goto panic_error; /* point */
- break;
- case RDP_SetWatch:
- /* Set Watchpoint */
- #ifdef DEBUG
- fprintf (stderr, "RDP Set Watchpoint\n");
- #endif
- if (MYread_word (debugsock, &x))
- goto panic_error; /* address */
- if (MYread_char (debugsock, &c))
- goto panic_error; /* type */
- if (MYread_char (debugsock, &d))
- goto panic_error; /* datatype */
- MYwrite_char (mumkid[1], message);
- MYwrite_word (mumkid[1], x);
- MYwrite_char (mumkid[1], c);
- MYwrite_char (mumkid[1], d);
- if (((c & 0xf) >= 5) && passon (debugsock, mumkid[1], 4))
- goto panic_error; /* bound */
- break;
- case RDP_ClearWatch:
- /* Clear Watchpoint */
- #ifdef DEBUG
- fprintf (stderr, "RDP Clear Watchpoint\n");
- #endif
- MYwrite_char (mumkid[1], message);
- if (passon (debugsock, mumkid[1], 4))
- goto panic_error; /* point */
- break;
- case RDP_Execute:
- /* Excecute */
- #ifdef DEBUG
- fprintf (stderr, "RDP Execute\n");
- #endif
- /* LEAVE THIS ONE 'TIL LATER... */
- /* NEED TO WORK THINGS OUT */
- /* NO ASCYNCHROUS RUNNING */
- if (MYread_char (debugsock, &c))
- goto panic_error; /* return */
- /* Remember incase bit 7 is set and we have to send back a word */
- exreturn = c;
- MYwrite_char (mumkid[1], message);
- MYwrite_char (mumkid[1], c);
- break;
- case RDP_Step:
- /* Step */
- #ifdef DEBUG
- fprintf (stderr, "RDP Step\n");
- #endif
- if (MYread_char (debugsock, &c))
- goto panic_error; /* return */
- if (MYread_word (debugsock, &x))
- goto panic_error; /* ninstr */
- MYwrite_char (mumkid[1], message);
- MYwrite_char (mumkid[1], c);
- MYwrite_word (mumkid[1], x);
- break;
- case RDP_Info:
- /* Info */
- #ifdef DEBUG
- fprintf (stderr, "RDP Info\n");
- #endif
- /* INFO TARGET, SET RDI LEVEL */
- if (MYread_word (debugsock, &messagetype))
- goto panic_error; /* info */
- switch (messagetype)
- {
- case RDIInfo_Target:
- MYwrite_char (mumkid[1], message);
- MYwrite_word (mumkid[1], messagetype);
- break;
- case RDISet_RDILevel:
- MYwrite_char (mumkid[1], message);
- MYwrite_word (mumkid[1], messagetype);
- if (passon (debugsock, mumkid[1], 1))
- goto panic_error; /* argument */
- break;
- case RDISet_Cmdline:
- /* Got to pass on a string argument */
- MYwrite_char (mumkid[1], message);
- MYwrite_word (mumkid[1], messagetype);
- do
- {
- if (MYread_char (debugsock, &c))
- goto panic_error;
- MYwrite_char (mumkid[1], c);
- }
- while (c);
- break;
- case RDISignal_Stop:
- kill (child, SIGUSR1);
- MYwrite_char (debugsock, RDP_Return);
- MYwrite_char (debugsock, RDIError_UserInterrupt);
- break;
- case RDIVector_Catch:
- MYread_word (debugsock, &x);
- MYwrite_char (mumkid[1], message);
- MYwrite_word (mumkid[1], messagetype);
- MYwrite_word (mumkid[1], x);
- break;
- case RDIInfo_Step:
- MYwrite_char (mumkid[1], message);
- MYwrite_word (mumkid[1], messagetype);
- break;
- case RDIInfo_Points:
- MYwrite_char (mumkid[1], message);
- MYwrite_word (mumkid[1], messagetype);
- break;
- default:
- fprintf (stderr, "Unrecognized RDIInfo request %d\n",
- messagetype);
- goto panic_error;
- }
- break;
- case RDP_OSOpReply:
- /* OS Operation Reply */
- #ifdef DEBUG
- fprintf (stderr, "RDP OS Reply\n");
- #endif
- MYwrite_char (mumkid[1], message);
- if (MYread_char (debugsock, &message))
- goto panic_error;
- MYwrite_char (mumkid[1], message);
- switch (message)
- {
- case 0: /* return value i.e. nothing else. */
- break;
- case 1: /* returns a byte... */
- if (MYread_char (debugsock, &c))
- goto panic_error;
- MYwrite_char (mumkid[1], c);
- break;
- case 2: /* returns a word... */
- if (MYread_word (debugsock, &x))
- goto panic_error;
- MYwrite_word (mumkid[1], x);
- break;
- }
- break;
- case RDP_Reset:
- /* Reset */
- #ifdef DEBUG
- fprintf (stderr, "RDP Reset\n");
- #endif
- MYwrite_char (mumkid[1], message);
- break;
- default:
- /* Hmm.. bad RDP operation */
- fprintf (stderr, "RDP Bad RDP request (%d)\n", message);
- MYwrite_char (debugsock, RDP_Return);
- MYwrite_char (debugsock, RDIError_UnimplementedMessage);
- break;
- }
- }
- if (FD_ISSET (kidmum[0], &readfds))
- {
- #ifdef DEBUG
- fprintf (stderr, "->ARMulator\n");
- #endif
- /* Anything we get from the ARMulator has to go to the debugger... */
- /* It is that simple! */
- passon (kidmum[0], debugsock, 1);
- }
- }
- }
|