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 invalidateCache(XMEM_CACHE);
149 invalidateCache(IMEM_CACHE);
150 invalidateCache(SREG_CACHE);
153 sock = socket(AF_INET,SOCK_STREAM,0);
155 memset(&sin,0,sizeof(sin));
156 sin.sin_family = AF_INET;
157 sin.sin_addr.s_addr = inet_addr("127.0.0.1");
158 sin.sin_port = htons(9756);
160 /* connect to the simulator */
161 if (connect(sock,(struct sockaddr *) &sin, sizeof(sin)) < 0) {
162 /* if failed then wait 1 second & try again
163 do this for 10 secs only */
167 /* fork and start the simulator as a subprocess */
168 if ((simPid = fork())) {
169 Dprintf(D_simi, ("simi: simulator pid %d\n",(int) simPid));
172 /* we are in the child process : start the simulator */
173 signal(SIGHUP , SIG_IGN );
174 signal(SIGINT , SIG_IGN );
175 signal(SIGABRT, SIG_IGN );
176 signal(SIGCHLD, SIG_IGN );
178 if (execvp(args[0],args) < 0) {
179 perror("cannot exec simulator");
188 perror("connect failed :");
191 /* go the socket now turn it into a file handle */
192 if (!(simin = fdopen(sock,"r"))) {
193 fprintf(stderr,"cannot open socket for read\n");
197 if (!(simout = fdopen(sock,"w"))) {
198 fprintf(stderr,"cannot open socket for write\n");
202 /* now that we have opened, wait for the prompt */
203 waitForSim(200,NULL);
206 /*-----------------------------------------------------------------*/
207 /* simResponse - returns buffer to simulator's response */
208 /*-----------------------------------------------------------------*/
214 /*-----------------------------------------------------------------*/
215 /* sendSim - sends a command to the simuator */
216 /*-----------------------------------------------------------------*/
217 void sendSim(char *s)
222 Dprintf(D_simi, ("simi: sendSim-->%s", s)); // s has LF at end already
228 static int getMemString(char *buffer, char wrflag,
229 unsigned int *addr, char mem, int size )
231 int cachenr = NMEM_CACHE;
243 case 'A': /* External stack */
244 case 'F': /* External ram */
246 cachenr = XMEM_CACHE;
249 case 'D': /* Code / static segment */
252 case 'B': /* Internal stack */
253 case 'E': /* Internal ram (lower 128) bytes */
254 case 'G': /* Internal ram */
256 cachenr = IMEM_CACHE;
258 case 'H': /* Bit addressable */
259 case 'J': /* SBIT space */
265 sprintf(buffer,"%s 0x%x\n",cmd,*addr);
268 case 'I': /* SFR space */
270 cachenr = SREG_CACHE;
272 case 'R': /* Register space */
274 /* get register bank */
275 cachenr = simGetValue (0xd0,'I',1);
276 *addr += cachenr & 0x18 ;
277 cachenr = IMEM_CACHE;
280 case 'Z': /* undefined space code */
284 sprintf(buffer,"%s %s 0x%x\n",cmd,prefix,*addr);
286 sprintf(buffer,"%s %s 0x%x 0x%x\n",cmd,prefix,*addr,*addr+size-1);
290 void simSetPC( unsigned int addr )
293 sprintf(buffer,"pc %d\n", addr);
295 waitForSim(100,NULL);
299 int simSetValue (unsigned int addr,char mem, int size, unsigned long val)
308 cachenr = getMemString(buffer,1,&addr,mem,size);
309 if ( cachenr < NMEM_CACHE )
311 invalidateCache(cachenr);
313 s = buffer + strlen(buffer) -1;
314 for ( i = 0 ; i < size ; i++ )
316 sprintf(s," 0x%x", val & 0xff);
322 waitForSim(100,NULL);
328 /*-----------------------------------------------------------------*/
329 /* simGetValue - get value @ address for mem space */
330 /*-----------------------------------------------------------------*/
331 unsigned long simGetValue (unsigned int addr,char mem, int size)
333 unsigned int b[4] = {0,0,0,0}; /* can be a max of four bytes long */
341 cachenr = getMemString(buffer,0,&addr,mem,size);
344 if ( cachenr < NMEM_CACHE )
346 resp = getMemCache(addr,cachenr,size);
350 /* create the simulator command */
352 waitForSim(100,NULL);
353 resp = simResponse();
355 /* got the response we need to parse it the response
357 [address] [v] [v] [v] ... special case in
358 case of bit variables which case it becomes
359 [address] [assembler bit address] [v] */
360 /* first skip thru white space */
361 while (isspace(*resp)) resp++ ;
363 if (strncmp(resp, "0x",2) == 0)
366 /* skip thru the address part */
367 while (isxdigit(*resp)) resp++;
370 /* make the branch for bit variables */
371 if ( cachenr == BIT_CACHE)
373 /* skip until newline */
374 while (*resp && *resp != '\n' ) resp++ ;
375 if ( *--resp != '0' )
380 for (i = 0 ; i < size ; i++ )
382 /* skip white space */
383 while (isspace(*resp)) resp++ ;
385 b[i] = strtol(resp,&resp,16);
389 return b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24 ;
393 /*-----------------------------------------------------------------*/
394 /* simSetBP - set break point for a given address */
395 /*-----------------------------------------------------------------*/
396 void simSetBP (unsigned int addr)
400 sprintf(buff,"break 0x%x\n",addr);
402 waitForSim(100,NULL);
405 /*-----------------------------------------------------------------*/
406 /* simClearBP - clear a break point */
407 /*-----------------------------------------------------------------*/
408 void simClearBP (unsigned int addr)
412 sprintf(buff,"clear 0x%x\n",addr);
414 waitForSim(100,NULL);
417 /*-----------------------------------------------------------------*/
418 /* simLoadFile - load the simulator file */
419 /*-----------------------------------------------------------------*/
420 void simLoadFile (char *s)
424 sprintf(buff,"file \"%s\"\n",s);
427 waitForSim(500,NULL);
430 /*-----------------------------------------------------------------*/
431 /* simGoTillBp - send 'go' to simulator till a bp then return addr */
432 /*-----------------------------------------------------------------*/
433 unsigned int simGoTillBp ( unsigned int gaddr)
440 invalidateCache(XMEM_CACHE);
441 invalidateCache(IMEM_CACHE);
442 invalidateCache(SREG_CACHE);
444 /* initial start, start & stop from address 0 */
447 // this program is setting up a bunch of breakpoints automatically
448 // at key places. Like at startup & main() and other function
449 // entry points. So we don't need to setup one here..
450 //sendSim("break 0x0\n");
455 waitForSim(wait_ms, NULL);
456 sendSim("run 0x0\n");
457 } else if (gaddr == -1) { /* resume */
461 else if (gaddr == 1 ) { /* nexti or next */
465 else if (gaddr == 2 ) { /* stepi or step */
470 printf("Error, simGoTillBp > 0!\n");
474 waitForSim(wait_ms, NULL);
476 /* get the simulator response */
478 /* check for errors */
481 while ( *sr && *sr != 'E' ) sr++ ;
484 if ( ! strncmp(sr,"Error:",6))
493 /* get answer of stop command */
495 waitForSim(wait_ms, NULL);
497 /* better solution: ask pc */
499 waitForSim(100, NULL);
503 gaddr = strtol(sr+3,0,0);
507 /*-----------------------------------------------------------------*/
508 /* simReset - reset the simulator */
509 /*-----------------------------------------------------------------*/
512 invalidateCache(XMEM_CACHE);
513 invalidateCache(IMEM_CACHE);
514 invalidateCache(SREG_CACHE);
516 waitForSim(100,NULL);
520 /*-----------------------------------------------------------------*/
521 /* closeSimulator - close connection to simulator */
522 /*-----------------------------------------------------------------*/
523 void closeSimulator ()
525 if ( ! simin || ! simout || sock == -1 )
538 kill (simPid,SIGKILL);