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;
48 static memcache_t memCache[NMEM_CACHE];
50 /*-----------------------------------------------------------------*/
51 /* get data from memory cache/ load cache from simulator */
52 /*-----------------------------------------------------------------*/
53 static char *getMemCache(unsigned int addr,int cachenum, int size)
57 memcache_t *cache = &memCache[cachenum];
59 if ( cache->size <= 0 ||
61 cache->addr + cache->size < addr + size )
63 if ( cachenum == IMEM_CACHE )
65 sendSim("di 0x0 0xff\n");
69 laddr = addr & 0xffffffc0;
70 sprintf(cache->buffer,"dx 0x%x 0x%x\n",laddr,laddr+0xff );
71 sendSim(cache->buffer);
75 cache->addr = strtol(resp,0,0);
78 while ( *resp && *(resp+1) && *(resp+2))
80 /* cache is a stringbuffer with ascii data like
81 " 00 00 00 00 00 00 00 00"
85 /* skip thru the address part */
86 while (isxdigit(*resp)) resp++;
87 while ( *resp && *resp != '\n')
100 if ( cache->addr > addr ||
101 cache->addr + cache->size < addr + size )
104 return cache->buffer + (addr - cache->addr)*3;
107 /*-----------------------------------------------------------------*/
108 /* invalidate memory cache */
109 /*-----------------------------------------------------------------*/
110 static void invalidateCache( int cachenum )
112 memCache[cachenum].size = 0;
115 /*-----------------------------------------------------------------*/
116 /* waitForSim - wait till simulator is done its job */
117 /*-----------------------------------------------------------------*/
118 void waitForSim(int timeout_ms, char *expect)
123 Dprintf(D_simi, ("simi: waitForSim start(%d)\n", timeout_ms));
126 while ((ch = fgetc(simin)) > 0 ) {
130 Dprintf(D_simi, ("waitForSim(%d) got[%s]\n", timeout_ms, simibuff));
134 /*-----------------------------------------------------------------*/
135 /* openSimulator - create a pipe to talk to simulator */
136 /*-----------------------------------------------------------------*/
137 void openSimulator (char **args, int nargs)
139 struct sockaddr_in sin;
142 Dprintf(D_simi, ("simi: openSimulator\n"));
144 invalidateCache(XMEM_CACHE);
145 invalidateCache(IMEM_CACHE);
146 /* fork and start the simulator as a subprocess */
147 if ((simPid = fork())) {
148 Dprintf(D_simi, ("simi: simulator pid %d\n",(int) simPid));
151 /* we are in the child process : start the simulator */
152 signal(SIGHUP , SIG_IGN );
153 signal(SIGINT , SIG_IGN );
154 signal(SIGABRT, SIG_IGN );
155 signal(SIGCHLD, SIG_IGN );
157 if (execvp(args[0],args) < 0) {
158 perror("cannot exec simulator");
164 sock = socket(AF_INET,SOCK_STREAM,0);
166 memset(&sin,0,sizeof(sin));
167 sin.sin_family = AF_INET;
168 sin.sin_addr.s_addr = inet_addr("127.0.0.1");
169 sin.sin_port = htons(9756);
172 /* connect to the simulator */
173 if (connect(sock,(struct sockaddr *) &sin, sizeof(sin)) < 0) {
174 /* if failed then wait 1 second & try again
175 do this for 10 secs only */
181 perror("connect failed :");
184 /* go the socket now turn it into a file handle */
185 if (!(simin = fdopen(sock,"r"))) {
186 fprintf(stderr,"cannot open socket for read\n");
190 if (!(simout = fdopen(sock,"w"))) {
191 fprintf(stderr,"cannot open socket for write\n");
195 /* now that we have opened, wait for the prompt */
196 waitForSim(200,NULL);
199 /*-----------------------------------------------------------------*/
200 /* simResponse - returns buffer to simulator's response */
201 /*-----------------------------------------------------------------*/
207 /*-----------------------------------------------------------------*/
208 /* sendSim - sends a command to the simuator */
209 /*-----------------------------------------------------------------*/
210 void sendSim(char *s)
215 Dprintf(D_simi, ("simi: sendSim-->%s", s)); // s has LF at end already
221 static int getMemString(char *buffer, char wrflag,
222 unsigned int addr, char mem, int size )
224 int cachenr = NMEM_CACHE;
236 case 'A': /* External stack */
237 case 'F': /* External ram */
239 cachenr = XMEM_CACHE;
242 case 'D': /* Code / static segment */
245 case 'B': /* Internal stack */
246 case 'E': /* Internal ram (lower 128) bytes */
247 case 'G': /* Internal ram */
249 cachenr = IMEM_CACHE;
251 case 'H': /* Bit addressable */
252 case 'J': /* SBIT space */
258 sprintf(buffer,"%s 0x%x\n",cmd,addr);
261 case 'I': /* SFR space */
264 case 'R': /* Register space */
268 sprintf(buffer,"info reg\n");
272 /* get register bank */
273 cachenr = simGetValue (0xd0,'I',1);
274 addr += cachenr & 0x18 ;
275 cachenr = IMEM_CACHE;
278 case 'Z': /* undefined space code */
282 sprintf(buffer,"%s %s 0x%x\n",cmd,prefix,addr,addr);
284 sprintf(buffer,"%s %s 0x%x 0x%x\n",cmd,prefix,addr,addr+size-1);
288 int simSetValue (unsigned int addr,char mem, int size, unsigned long val)
297 cachenr = getMemString(buffer,1,addr,mem,size);
298 if ( cachenr < NMEM_CACHE )
300 invalidateCache(cachenr);
302 s = buffer + strlen(buffer) -1;
303 for ( i = 0 ; i < size ; i++ )
305 sprintf(s," 0x%x", val & 0xff);
311 waitForSim(100,NULL);
316 /*-----------------------------------------------------------------*/
317 /* simGetValue - get value @ address for mem space */
318 /*-----------------------------------------------------------------*/
319 unsigned long simGetValue (unsigned int addr,char mem, int size)
321 unsigned int b[4] = {0,0,0,0}; /* can be a max of four bytes long */
329 cachenr = getMemString(buffer,0,addr,mem,size);
332 if ( cachenr < NMEM_CACHE )
334 resp = getMemCache(addr,cachenr,size);
338 /* create the simulator command */
340 waitForSim(100,NULL);
341 resp = simResponse();
343 /* got the response we need to parse it the response
345 [address] [v] [v] [v] ... special case in
346 case of bit variables which case it becomes
347 [address] [assembler bit address] [v] */
348 /* first skip thru white space */
349 while (isspace(*resp)) resp++ ;
351 if (strncmp(resp, "0x",2) == 0)
354 /* skip thru the address part */
355 while (isxdigit(*resp)) resp++;
357 /* then make the branch for bit variables */
358 if ( cachenr == REG_CACHE )
361 for (i = 0 ; i < addr ; i++ )
363 while (isspace(*resp)) resp++ ;
365 while (isxdigit(*resp)) resp++;
369 /* make the branch for bit variables */
370 if ( cachenr == BIT_CACHE)
372 /* skip until newline */
373 while (*resp && *resp != '\n' ) resp++ ;
374 if ( *--resp != '0' )
379 for (i = 0 ; i < size ; i++ )
381 /* skip white space */
382 while (isspace(*resp)) resp++ ;
384 b[i] = strtol(resp,&resp,16);
388 return b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24 ;
392 /*-----------------------------------------------------------------*/
393 /* simSetBP - set break point for a given address */
394 /*-----------------------------------------------------------------*/
395 void simSetBP (unsigned int addr)
399 sprintf(buff,"break 0x%x\n",addr);
401 waitForSim(100,NULL);
404 /*-----------------------------------------------------------------*/
405 /* simClearBP - clear a break point */
406 /*-----------------------------------------------------------------*/
407 void simClearBP (unsigned int addr)
411 sprintf(buff,"clear 0x%x\n",addr);
413 waitForSim(100,NULL);
416 /*-----------------------------------------------------------------*/
417 /* simLoadFile - load the simulator file */
418 /*-----------------------------------------------------------------*/
419 void simLoadFile (char *s)
423 sprintf(buff,"l \"%s\"\n",s);
426 waitForSim(500,NULL);
429 /*-----------------------------------------------------------------*/
430 /* simGoTillBp - send 'go' to simulator till a bp then return addr */
431 /*-----------------------------------------------------------------*/
432 unsigned int simGoTillBp ( unsigned int gaddr)
439 invalidateCache(XMEM_CACHE);
440 invalidateCache(IMEM_CACHE);
442 /* initial start, start & stop from address 0 */
445 // this program is setting up a bunch of breakpoints automatically
446 // at key places. Like at startup & main() and other function
447 // entry points. So we don't need to setup one here..
448 //sendSim("break 0x0\n");
452 sendSim("run 0x0\n");
453 } else if (gaddr == -1) { /* resume */
457 else if (gaddr == 1 ) { /* nexti */
461 else if (gaddr == 2 ) { /* stepi */
466 printf("Error, simGoTillBp > 0!\n");
470 waitForSim(wait_ms, NULL);
472 /* get the simulator response */
473 svr = sr = strdup(simResponse());
475 if ( gaddr == 1 || gaddr == 2 )
478 for ( nl = 0; nl < 3 ; nl++ )
480 while (*sr && *sr != '\n') sr++ ;
485 gaddr = strtol(sr,0,0);
491 /* figure out the address of the break point the simulators
492 response in a break point situation is of the form
493 [... F* <addr> <disassembled instruction> ]
494 we will ignore till we get F* then parse the address */
496 if (strncmp(sr,"Stop at",7) == 0) {
502 if (*sr == 'F' && ( *(sr+1) == '*' || *(sr+1) == ' ')) {
511 fprintf(stderr, "Error?, simGoTillBp failed to Stop\n");
515 while (isspace(*sr)) sr++ ;
517 if (sscanf(sr,sfmt,&addr) != 1) {
518 fprintf(stderr, "Error?, simGoTillBp failed to get Addr\n");
525 /*-----------------------------------------------------------------*/
526 /* simReset - reset the simulator */
527 /*-----------------------------------------------------------------*/
530 invalidateCache(XMEM_CACHE);
531 invalidateCache(IMEM_CACHE);
533 waitForSim(100,NULL);
536 /*-----------------------------------------------------------------*/
537 /* getValueStr - read a value followed by a string = */
538 /*-----------------------------------------------------------------*/
539 static unsigned int getValueStr (char *src,char *cstr)
541 int i = strlen(cstr);
543 /* look for the string */
544 if (! (src = strstr(src,cstr)))
550 /* look for the digit */
551 while (*src && !isxdigit(*src)) src++;
552 sscanf(src,"%x",&rv);
556 /*-----------------------------------------------------------------*/
557 /* simRegs - returns value of registers */
558 /*-----------------------------------------------------------------*/
566 sendSim("info registers\n");
568 waitForSim(100,NULL);
570 resp = simResponse();
576 /*Take this out(2-09-02) cant see as its that useful to reformat, karl.*/
578 /* the response is of the form
579 XXXXXX R0 R1 R2 R3 R4 R5 R6 R7 ........
580 XXXXXX XX . ACC=0xxx dd cc B=0xxx dd cc DPTR= 0xxxxx @DPTR= 0xxx dd cc
581 XXXXXX XX . PSW= 0xxx CY=[1|0] AC=[0|1] OV=[0|1] P=[1|0]
584 0x00 00 00 00 00 00 00 00 00 ........
585 000000 00 . ACC= 0x00 0 . B= 0x00 DPTR= 0x0000 @DPTR= 0x00 0 .
586 000000 00 . PSW= 0x00 CY=0 AC=0 OV=0 P=0
587 F 0x006d 75 87 80 MOV PCON,#80
590 memset(regBuff,0,sizeof(regBuff));
591 /* skip the first numerics */
592 while (*resp && !isxdigit(*resp)) resp++;
594 if (strncmp(resp, "0x", 2)) {
595 fprintf(stderr, "Error: Format1A\n");
599 while (*resp && isxdigit(*resp)) resp++;
601 /* now get the eight registers */
602 for (i = 0 ; i < 7 ; i++) {
603 while (*resp && isspace(*resp)) resp++;
606 rv = strtol(resp,&resp,16);
607 sprintf(rb,"R%d : 0x%02X %d %c\n",i,rv,rv,(isprint(rv) ? rv : '.'));
611 if (!*resp) return regBuff;
613 /* skip till end of line */
614 while (*resp && *resp != '\n') resp++;
615 while (*resp && !isxdigit(*resp)) resp++;
616 while (*resp && isxdigit(*resp)) resp++;
618 /* accumulator value */
619 rv = getValueStr(resp,"ACC");
620 sprintf(rb,"ACC : 0x%02X %d %c\n",rv,rv,(isprint(rv) ? rv : '.'));
624 rv = getValueStr(resp,"B=");
625 sprintf(rb,"B : 0x%02X %d %c\n",rv,rv,(isprint(rv) ? rv : '.'));
628 rv = getValueStr(resp,"DPTR=");
629 sprintf(rb,"DPTR: 0x%04X %d\n",rv,rv);
632 rv = getValueStr(resp,"@DPTR=");
633 sprintf(rb,"@DPTR: 0x%02X %d %c\n", rv,rv,(isprint(rv) ? rv : '.'));
636 sprintf(rb,"PSW : 0x%02X | CY : %d | AC : %d | OV : %d | P : %d\n",
637 getValueStr(resp,"PSW="),
638 getValueStr(resp,"CY="),
639 getValueStr(resp,"AC="),
640 getValueStr(resp,"OV="),
641 getValueStr(resp,"P="));
648 /*-----------------------------------------------------------------*/
649 /* closeSimulator - close connection to simulator */
650 /*-----------------------------------------------------------------*/
651 void closeSimulator ()
653 if ( ! simin || ! simout || sock == -1 )
659 kill (simPid,SIGKILL);