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 int simSetValue (unsigned int addr,char mem, int size, unsigned long val)
299 cachenr = getMemString(buffer,1,&addr,mem,size);
300 if ( cachenr < NMEM_CACHE )
302 invalidateCache(cachenr);
304 s = buffer + strlen(buffer) -1;
305 for ( i = 0 ; i < size ; i++ )
307 sprintf(s," 0x%x", val & 0xff);
313 waitForSim(100,NULL);
318 /*-----------------------------------------------------------------*/
319 /* simGetValue - get value @ address for mem space */
320 /*-----------------------------------------------------------------*/
321 unsigned long simGetValue (unsigned int addr,char mem, int size)
323 unsigned int b[4] = {0,0,0,0}; /* can be a max of four bytes long */
331 cachenr = getMemString(buffer,0,&addr,mem,size);
334 if ( cachenr < NMEM_CACHE )
336 resp = getMemCache(addr,cachenr,size);
340 /* create the simulator command */
342 waitForSim(100,NULL);
343 resp = simResponse();
345 /* got the response we need to parse it the response
347 [address] [v] [v] [v] ... special case in
348 case of bit variables which case it becomes
349 [address] [assembler bit address] [v] */
350 /* first skip thru white space */
351 while (isspace(*resp)) resp++ ;
353 if (strncmp(resp, "0x",2) == 0)
356 /* skip thru the address part */
357 while (isxdigit(*resp)) resp++;
360 /* make the branch for bit variables */
361 if ( cachenr == BIT_CACHE)
363 /* skip until newline */
364 while (*resp && *resp != '\n' ) resp++ ;
365 if ( *--resp != '0' )
370 for (i = 0 ; i < size ; i++ )
372 /* skip white space */
373 while (isspace(*resp)) resp++ ;
375 b[i] = strtol(resp,&resp,16);
379 return b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24 ;
383 /*-----------------------------------------------------------------*/
384 /* simSetBP - set break point for a given address */
385 /*-----------------------------------------------------------------*/
386 void simSetBP (unsigned int addr)
390 sprintf(buff,"break 0x%x\n",addr);
392 waitForSim(100,NULL);
395 /*-----------------------------------------------------------------*/
396 /* simClearBP - clear a break point */
397 /*-----------------------------------------------------------------*/
398 void simClearBP (unsigned int addr)
402 sprintf(buff,"clear 0x%x\n",addr);
404 waitForSim(100,NULL);
407 /*-----------------------------------------------------------------*/
408 /* simLoadFile - load the simulator file */
409 /*-----------------------------------------------------------------*/
410 void simLoadFile (char *s)
414 sprintf(buff,"l \"%s\"\n",s);
417 waitForSim(500,NULL);
420 /*-----------------------------------------------------------------*/
421 /* simGoTillBp - send 'go' to simulator till a bp then return addr */
422 /*-----------------------------------------------------------------*/
423 unsigned int simGoTillBp ( unsigned int gaddr)
430 invalidateCache(XMEM_CACHE);
431 invalidateCache(IMEM_CACHE);
432 invalidateCache(SREG_CACHE);
434 /* initial start, start & stop from address 0 */
437 // this program is setting up a bunch of breakpoints automatically
438 // at key places. Like at startup & main() and other function
439 // entry points. So we don't need to setup one here..
440 //sendSim("break 0x0\n");
444 sendSim("run 0x0\n");
445 } else if (gaddr == -1) { /* resume */
449 else if (gaddr == 1 ) { /* nexti or next */
453 else if (gaddr == 2 ) { /* stepi or step */
458 printf("Error, simGoTillBp > 0!\n");
462 waitForSim(wait_ms, NULL);
464 /* get the simulator response */
466 /* check for errors */
469 while ( *sr && *sr != 'E' ) sr++ ;
472 if ( ! strncmp(sr,"Error:",6))
480 /* better solution: ask pc */
482 waitForSim(100, NULL);
485 gaddr = strtol(sr+3,0,0);
489 /*-----------------------------------------------------------------*/
490 /* simReset - reset the simulator */
491 /*-----------------------------------------------------------------*/
494 invalidateCache(XMEM_CACHE);
495 invalidateCache(IMEM_CACHE);
496 invalidateCache(SREG_CACHE);
498 waitForSim(100,NULL);
502 /*-----------------------------------------------------------------*/
503 /* closeSimulator - close connection to simulator */
504 /*-----------------------------------------------------------------*/
505 void closeSimulator ()
507 if ( ! simin || ! simout || sock == -1 )
519 kill (simPid,SIGKILL);