1 /*-------------------------------------------------------------------------
2 simi.c - source file for simulator interaction
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
27 #ifdef HAVE_SYS_SOCKET_H
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <arpa/inet.h>
35 #error "Cannot build debugger without socket support"
37 FILE *simin ; /* stream for simulator input */
38 FILE *simout; /* stream for simulator output */
40 int sock = -1; /* socket descriptor to comm with simulator */
42 static char simibuff[MAX_SIM_BUFF]; /* sim buffer */
43 static char regBuff[MAX_SIM_BUFF];
44 static char *sbp = simibuff; /* simulator buffer pointer */
45 extern char **environ;
50 #define MS_SLEEP(_ms) usleep(_ms * 1000)
53 /*-----------------------------------------------------------------*/
54 /* waitForSim - wait till simulator is done its job */
55 /*-----------------------------------------------------------------*/
56 void waitForSim(int timeout_ms, char *expect)
61 Dprintf(D_simi, ("waitForSim start(%d)\n", timeout_ms));
64 // MS_SLEEP(timeout_ms); dont need, in blocking mode.
66 while ((ch = fgetc(simin)) > 0 ) {
70 Dprintf(D_simi, ("waitForSim(%d) got[%s]\n", timeout_ms, simibuff));
73 hmmmm, I guess we are not running non-blocking, we may still
74 need this code...Im not sure how the above works, it must block
75 until something gets into the buffer, then fgetc() reads down the
78 while ((ch = fgetc(simin))) {
82 printf("got1[%s]\n", simibuff);
88 if (strstr(expect, sbp)) {
91 } else if (sbp != simibuff) {
95 /* pull in data one more time after delay to try and
96 guarentee we pull in complete responce line */
97 if (timeout_ms <= 0) {
99 while ((ch = fgetc(simin))) {
103 printf("got2[%s]\n", simibuff);
106 while (timeout_ms > 0);
112 /*-----------------------------------------------------------------*/
113 /* openSimulator - create a pipe to talk to simulator */
114 /*-----------------------------------------------------------------*/
115 void openSimulator (char **args, int nargs)
117 struct sockaddr_in sin;
120 Dprintf(D_simi, ("openSimulator\n"));
122 /* fork and start the simulator as a subprocess */
123 if ((simPid = fork())) {
124 Dprintf(D_simi, ("simulator pid %d\n",(int) simPid));
127 /* we are in the child process : start the simulator */
128 if (execvp(args[0],args) < 0) {
129 perror("cannot exec simulator");
135 sock = socket(AF_INET,SOCK_STREAM,0);
137 memset(&sin,0,sizeof(sin));
138 sin.sin_family = AF_INET;
139 sin.sin_addr.s_addr = inet_addr("127.0.0.1");
140 sin.sin_port = htons(9756);
143 /* connect to the simulator */
144 if (connect(sock,(struct sockaddr *) &sin, sizeof(sin)) < 0) {
145 /* if failed then wait 1 second & try again
146 do this for 10 secs only */
152 perror("connect failed :");
155 /* go the socket now turn it into a file handle */
156 if (!(simin = fdopen(sock,"r"))) {
157 fprintf(stderr,"cannot open socket for read\n");
161 if (!(simout = fdopen(sock,"w"))) {
162 fprintf(stderr,"cannot open socket for write\n");
166 /* now that we have opened, wait for the prompt */
167 waitForSim(200,NULL);
170 /*-----------------------------------------------------------------*/
171 /* simResponse - returns buffer to simulator's response */
172 /*-----------------------------------------------------------------*/
178 /*-----------------------------------------------------------------*/
179 /* sendSim - sends a command to the simuator */
180 /*-----------------------------------------------------------------*/
181 void sendSim(char *s)
186 Dprintf(D_simi, ("sendSim-->%s", s)); // s has LF at end already
191 int simSetValue (unsigned int addr,char mem, int size, unsigned long val)
193 char buffer[40], *s,*prefix;
224 return; /* set registers !! */
230 sprintf(buffer,"set mem %s 0x%x",prefix,addr);
231 s = buffer + strlen(buffer);
232 for ( i = 0 ; i < size ; i++ )
234 sprintf(s," 0x%x", val & 0xff);
240 waitForSim(100,NULL);
244 /*-----------------------------------------------------------------*/
245 /* simGetValue - get value @ address for mem space */
246 /*-----------------------------------------------------------------*/
247 unsigned long simGetValue (unsigned int addr,char mem, int size)
249 unsigned int b[4] = {0,0,0,0}; /* can be a max of four bytes long */
289 /* create the simulator command */
290 sprintf(buffer,"%s 0x%x \n",prefix,addr);
292 waitForSim(100,NULL);
293 resp = simResponse();
295 /* got the response we need to parse it the response
297 [address] [v] [v] [v] ... special case in
298 case of bit variables which case it becomes
299 [address] [assembler bit address] [v] */
300 /* first skip thru white space */
301 while (isspace(*resp)) resp++ ;
303 if (strncmp(resp, "0x",2) == 0)
306 /* then make the branch for bit variables */
307 /* skip thru the address part */
308 while (isxdigit(*resp)) resp++;
310 if (!strcmp(prefix,"i r"))
313 for (i = 0 ; i < addr ; i++ )
315 while (isspace(*resp)) resp++ ;
317 while (isxdigit(*resp)) resp++;
321 if (!strcmp(prefix,"dump")) {
323 /* skip white space */
324 while (isspace(*resp)) resp++ ;
326 /* skip thru the assembler bit address */
327 while (!isspace(*resp)) resp++;
330 while (isspace(*resp)) resp++ ;
332 /* scan in the value */
333 sscanf(resp,"%d",&b[0]);
336 for (i = 0 ; i < size ; i++ ) {
337 /* skip white space */
338 while (isspace(*resp)) resp++ ;
340 sscanf(resp,"%x",&b[i]);
343 while (isxdigit(*resp)) resp++;
347 return b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24 ;
351 /*-----------------------------------------------------------------*/
352 /* simSetBP - set break point for a given address */
353 /*-----------------------------------------------------------------*/
354 void simSetBP (unsigned int addr)
358 sprintf(buff,"break 0x%x\n",addr);
360 waitForSim(100,NULL);
363 /*-----------------------------------------------------------------*/
364 /* simClearBP - clear a break point */
365 /*-----------------------------------------------------------------*/
366 void simClearBP (unsigned int addr)
370 sprintf(buff,"clear 0x%x\n",addr);
372 waitForSim(100,NULL);
375 /*-----------------------------------------------------------------*/
376 /* simLoadFile - load the simulator file */
377 /*-----------------------------------------------------------------*/
378 void simLoadFile (char *s)
382 sprintf(buff,"l \"%s\"\n",s);
385 waitForSim(500,NULL);
388 /*-----------------------------------------------------------------*/
389 /* simGoTillBp - send 'go' to simulator till a bp then return addr */
390 /*-----------------------------------------------------------------*/
391 unsigned int simGoTillBp ( unsigned int gaddr)
399 /* initial start, start & stop from address 0 */
402 // this program is setting up a bunch of breakpoints automatically
403 // at key places. Like at startup & main() and other function
404 // entry points. So we don't need to setup one here..
405 //sendSim("break 0x0\n");
409 sendSim("run 0x0\n");
410 } else if (gaddr == -1) { /* resume */
415 printf("Error, simGoTillBp > 0!\n");
419 waitForSim(wait_ms, NULL);
421 /* get the simulator response */
422 svr = sr = strdup(simResponse());
424 /* figure out the address of the break point the simulators
425 response in a break point situation is of the form
426 [... F* <addr> <disassembled instruction> ]
427 we will ignore till we get F* then parse the address */
429 if (strncmp(sr,"Stop at",7) == 0) {
435 if (*sr == 'F' && ( *(sr+1) == '*' || *(sr+1) == ' ')) {
444 fprintf(stderr, "Error?, simGoTillBp failed to Stop\n");
448 while (isspace(*sr)) sr++ ;
450 if (sscanf(sr,sfmt,&addr) != 1) {
451 fprintf(stderr, "Error?, simGoTillBp failed to get Addr\n");
458 /*-----------------------------------------------------------------*/
459 /* simReset - reset the simulator */
460 /*-----------------------------------------------------------------*/
464 waitForSim(100,NULL);
467 /*-----------------------------------------------------------------*/
468 /* getValueStr - read a value followed by a string = */
469 /*-----------------------------------------------------------------*/
470 static unsigned int getValueStr (char *src,char *cstr)
472 int i = strlen(cstr);
474 /* look for the string */
475 if (! (src = strstr(src,cstr)))
481 /* look for the digit */
482 while (*src && !isxdigit(*src)) src++;
483 sscanf(src,"%x",&rv);
487 /*-----------------------------------------------------------------*/
488 /* simRegs - returns value of registers */
489 /*-----------------------------------------------------------------*/
497 sendSim("info registers\n");
499 waitForSim(100,NULL);
501 resp = simResponse();
507 /*Take this out(2-09-02) cant see as its that useful to reformat, karl.*/
509 /* the response is of the form
510 XXXXXX R0 R1 R2 R3 R4 R5 R6 R7 ........
511 XXXXXX XX . ACC=0xxx dd cc B=0xxx dd cc DPTR= 0xxxxx @DPTR= 0xxx dd cc
512 XXXXXX XX . PSW= 0xxx CY=[1|0] AC=[0|1] OV=[0|1] P=[1|0]
515 0x00 00 00 00 00 00 00 00 00 ........
516 000000 00 . ACC= 0x00 0 . B= 0x00 DPTR= 0x0000 @DPTR= 0x00 0 .
517 000000 00 . PSW= 0x00 CY=0 AC=0 OV=0 P=0
518 F 0x006d 75 87 80 MOV PCON,#80
521 memset(regBuff,0,sizeof(regBuff));
522 /* skip the first numerics */
523 while (*resp && !isxdigit(*resp)) resp++;
525 if (strncmp(resp, "0x", 2)) {
526 fprintf(stderr, "Error: Format1A\n");
530 while (*resp && isxdigit(*resp)) resp++;
532 /* now get the eight registers */
533 for (i = 0 ; i < 7 ; i++) {
534 while (*resp && isspace(*resp)) resp++;
537 rv = strtol(resp,&resp,16);
538 sprintf(rb,"R%d : 0x%02X %d %c\n",i,rv,rv,(isprint(rv) ? rv : '.'));
542 if (!*resp) return regBuff;
544 /* skip till end of line */
545 while (*resp && *resp != '\n') resp++;
546 while (*resp && !isxdigit(*resp)) resp++;
547 while (*resp && isxdigit(*resp)) resp++;
549 /* accumulator value */
550 rv = getValueStr(resp,"ACC");
551 sprintf(rb,"ACC : 0x%02X %d %c\n",rv,rv,(isprint(rv) ? rv : '.'));
555 rv = getValueStr(resp,"B=");
556 sprintf(rb,"B : 0x%02X %d %c\n",rv,rv,(isprint(rv) ? rv : '.'));
559 rv = getValueStr(resp,"DPTR=");
560 sprintf(rb,"DPTR: 0x%04X %d\n",rv,rv);
563 rv = getValueStr(resp,"@DPTR=");
564 sprintf(rb,"@DPTR: 0x%02X %d %c\n", rv,rv,(isprint(rv) ? rv : '.'));
567 sprintf(rb,"PSW : 0x%02X | CY : %d | AC : %d | OV : %d | P : %d\n",
568 getValueStr(resp,"PSW="),
569 getValueStr(resp,"CY="),
570 getValueStr(resp,"AC="),
571 getValueStr(resp,"OV="),
572 getValueStr(resp,"P="));
579 /*-----------------------------------------------------------------*/
580 /* closeSimulator - close connection to simulator */
581 /*-----------------------------------------------------------------*/
582 void closeSimulator ()
584 if ( ! simin || ! simout || sock == -1 )
590 kill (simPid,SIGKILL);