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");
67 else if ( cachenum == SREG_CACHE )
69 sendSim("ds 0x80 0xff\n");
73 laddr = addr & 0xffffffc0;
74 sprintf(cache->buffer,"dx 0x%x 0x%x\n",laddr,laddr+0xff );
75 sendSim(cache->buffer);
79 cache->addr = strtol(resp,0,0);
82 while ( *resp && *(resp+1) && *(resp+2))
84 /* cache is a stringbuffer with ascii data like
85 " 00 00 00 00 00 00 00 00"
89 /* skip thru the address part */
90 while (isxdigit(*resp)) resp++;
91 while ( *resp && *resp != '\n')
104 if ( cache->addr > addr ||
105 cache->addr + cache->size < addr + size )
108 return cache->buffer + (addr - cache->addr)*3;
111 /*-----------------------------------------------------------------*/
112 /* invalidate memory cache */
113 /*-----------------------------------------------------------------*/
114 static void invalidateCache( int cachenum )
116 memCache[cachenum].size = 0;
119 /*-----------------------------------------------------------------*/
120 /* waitForSim - wait till simulator is done its job */
121 /*-----------------------------------------------------------------*/
122 void waitForSim(int timeout_ms, char *expect)
127 Dprintf(D_simi, ("simi: waitForSim start(%d)\n", timeout_ms));
130 while ((ch = fgetc(simin)) > 0 ) {
134 Dprintf(D_simi, ("waitForSim(%d) got[%s]\n", timeout_ms, simibuff));
138 /*-----------------------------------------------------------------*/
139 /* openSimulator - create a pipe to talk to simulator */
140 /*-----------------------------------------------------------------*/
141 void openSimulator (char **args, int nargs)
143 struct sockaddr_in sin;
146 Dprintf(D_simi, ("simi: openSimulator\n"));
148 if (D_simi & sdcdbDebug)
150 printf("simi: openSimulator: ");
151 for (i=0; i < nargs; i++ )
153 printf("arg%d: %s ",i,args[i]);
158 invalidateCache(XMEM_CACHE);
159 invalidateCache(IMEM_CACHE);
160 invalidateCache(SREG_CACHE);
163 sock = socket(AF_INET,SOCK_STREAM,0);
165 memset(&sin,0,sizeof(sin));
166 sin.sin_family = AF_INET;
167 sin.sin_addr.s_addr = inet_addr("127.0.0.1");
168 sin.sin_port = htons(9756);
170 /* connect to the simulator */
171 if (connect(sock,(struct sockaddr *) &sin, sizeof(sin)) < 0) {
172 /* if failed then wait 1 second & try again
173 do this for 10 secs only */
177 /* fork and start the simulator as a subprocess */
178 if ((simPid = fork())) {
179 Dprintf(D_simi, ("simi: simulator pid %d\n",(int) simPid));
182 /* we are in the child process : start the simulator */
183 signal(SIGHUP , SIG_IGN );
184 signal(SIGINT , SIG_IGN );
185 signal(SIGABRT, SIG_IGN );
186 signal(SIGCHLD, SIG_IGN );
188 if (execvp(args[0],args) < 0) {
189 perror("cannot exec simulator");
198 perror("connect failed :");
201 /* go the socket now turn it into a file handle */
202 if (!(simin = fdopen(sock,"r"))) {
203 fprintf(stderr,"cannot open socket for read\n");
207 if (!(simout = fdopen(sock,"w"))) {
208 fprintf(stderr,"cannot open socket for write\n");
212 /* now that we have opened, wait for the prompt */
213 waitForSim(200,NULL);
216 /*-----------------------------------------------------------------*/
217 /* simResponse - returns buffer to simulator's response */
218 /*-----------------------------------------------------------------*/
224 /*-----------------------------------------------------------------*/
225 /* sendSim - sends a command to the simuator */
226 /*-----------------------------------------------------------------*/
227 void sendSim(char *s)
232 Dprintf(D_simi, ("simi: sendSim-->%s", s)); // s has LF at end already
238 static int getMemString(char *buffer, char wrflag,
239 unsigned int *addr, char mem, int size )
241 int cachenr = NMEM_CACHE;
253 case 'A': /* External stack */
254 case 'F': /* External ram */
256 cachenr = XMEM_CACHE;
259 case 'D': /* Code / static segment */
262 case 'B': /* Internal stack */
263 case 'E': /* Internal ram (lower 128) bytes */
264 case 'G': /* Internal ram */
266 cachenr = IMEM_CACHE;
268 case 'H': /* Bit addressable */
269 case 'J': /* SBIT space */
275 sprintf(buffer,"%s 0x%x\n",cmd,*addr);
278 case 'I': /* SFR space */
280 cachenr = SREG_CACHE;
282 case 'R': /* Register space */
284 /* get register bank */
285 cachenr = simGetValue (0xd0,'I',1);
286 *addr += cachenr & 0x18 ;
287 cachenr = IMEM_CACHE;
290 case 'Z': /* undefined space code */
294 sprintf(buffer,"%s %s 0x%x\n",cmd,prefix,*addr);
296 sprintf(buffer,"%s %s 0x%x 0x%x\n",cmd,prefix,*addr,*addr+size-1);
300 void simSetPC( unsigned int addr )
303 sprintf(buffer,"pc %d\n", addr);
305 waitForSim(100,NULL);
309 int simSetValue (unsigned int addr,char mem, int size, unsigned long val)
318 cachenr = getMemString(buffer,1,&addr,mem,size);
319 if ( cachenr < NMEM_CACHE )
321 invalidateCache(cachenr);
323 s = buffer + strlen(buffer) -1;
324 for ( i = 0 ; i < size ; i++ )
326 sprintf(s," 0x%x", val & 0xff);
332 waitForSim(100,NULL);
338 /*-----------------------------------------------------------------*/
339 /* simGetValue - get value @ address for mem space */
340 /*-----------------------------------------------------------------*/
341 unsigned long simGetValue (unsigned int addr,char mem, int size)
343 unsigned int b[4] = {0,0,0,0}; /* can be a max of four bytes long */
351 cachenr = getMemString(buffer,0,&addr,mem,size);
354 if ( cachenr < NMEM_CACHE )
356 resp = getMemCache(addr,cachenr,size);
360 /* create the simulator command */
362 waitForSim(100,NULL);
363 resp = simResponse();
365 /* got the response we need to parse it the response
367 [address] [v] [v] [v] ... special case in
368 case of bit variables which case it becomes
369 [address] [assembler bit address] [v] */
370 /* first skip thru white space */
371 while (isspace(*resp)) resp++ ;
373 if (strncmp(resp, "0x",2) == 0)
376 /* skip thru the address part */
377 while (isxdigit(*resp)) resp++;
380 /* make the branch for bit variables */
381 if ( cachenr == BIT_CACHE)
383 /* skip until newline */
384 while (*resp && *resp != '\n' ) resp++ ;
385 if ( *--resp != '0' )
390 for (i = 0 ; i < size ; i++ )
392 /* skip white space */
393 while (isspace(*resp)) resp++ ;
395 b[i] = strtol(resp,&resp,16);
399 return b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24 ;
403 /*-----------------------------------------------------------------*/
404 /* simSetBP - set break point for a given address */
405 /*-----------------------------------------------------------------*/
406 void simSetBP (unsigned int addr)
410 sprintf(buff,"break 0x%x\n",addr);
412 waitForSim(100,NULL);
415 /*-----------------------------------------------------------------*/
416 /* simClearBP - clear a break point */
417 /*-----------------------------------------------------------------*/
418 void simClearBP (unsigned int addr)
422 sprintf(buff,"clear 0x%x\n",addr);
424 waitForSim(100,NULL);
427 /*-----------------------------------------------------------------*/
428 /* simLoadFile - load the simulator file */
429 /*-----------------------------------------------------------------*/
430 void simLoadFile (char *s)
434 sprintf(buff,"file \"%s\"\n",s);
437 waitForSim(500,NULL);
440 /*-----------------------------------------------------------------*/
441 /* simGoTillBp - send 'go' to simulator till a bp then return addr */
442 /*-----------------------------------------------------------------*/
443 unsigned int simGoTillBp ( unsigned int gaddr)
450 invalidateCache(XMEM_CACHE);
451 invalidateCache(IMEM_CACHE);
452 invalidateCache(SREG_CACHE);
454 /* initial start, start & stop from address 0 */
457 // this program is setting up a bunch of breakpoints automatically
458 // at key places. Like at startup & main() and other function
459 // entry points. So we don't need to setup one here..
460 //sendSim("break 0x0\n");
465 waitForSim(wait_ms, NULL);
466 sendSim("run 0x0\n");
467 } else if (gaddr == -1) { /* resume */
471 else if (gaddr == 1 ) { /* nexti or next */
475 else if (gaddr == 2 ) { /* stepi or step */
480 printf("Error, simGoTillBp > 0!\n");
484 waitForSim(wait_ms, NULL);
486 /* get the simulator response */
488 /* check for errors */
491 while ( *sr && *sr != 'E' ) sr++ ;
494 if ( ! strncmp(sr,"Error:",6))
503 /* get answer of stop command */
505 waitForSim(wait_ms, NULL);
507 /* better solution: ask pc */
509 waitForSim(100, NULL);
513 gaddr = strtol(sr+3,0,0);
517 /*-----------------------------------------------------------------*/
518 /* simReset - reset the simulator */
519 /*-----------------------------------------------------------------*/
522 invalidateCache(XMEM_CACHE);
523 invalidateCache(IMEM_CACHE);
524 invalidateCache(SREG_CACHE);
526 waitForSim(100,NULL);
530 /*-----------------------------------------------------------------*/
531 /* closeSimulator - close connection to simulator */
532 /*-----------------------------------------------------------------*/
533 void closeSimulator ()
535 if ( ! simin || ! simout || sock == -1 )
548 kill (simPid,SIGKILL);