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 */
39 typedef void (*sighandler_t)(int);
41 int sock = -1; /* socket descriptor to comm with simulator */
43 static char simibuff[MAX_SIM_BUFF]; /* sim buffer */
44 static char regBuff[MAX_SIM_BUFF];
45 static char *sbp = simibuff; /* simulator buffer pointer */
46 extern char **environ;
49 static memcache_t memCache[NMEM_CACHE];
51 /*-----------------------------------------------------------------*/
52 /* get data from memory cache/ load cache from simulator */
53 /*-----------------------------------------------------------------*/
54 static char *getMemCache(unsigned int addr,int cachenum, int size)
58 memcache_t *cache = &memCache[cachenum];
60 if ( cache->size <= 0 ||
62 cache->addr + cache->size < addr + size )
64 if ( cachenum == IMEM_CACHE )
66 sendSim("di 0x0 0xff\n");
68 else if ( cachenum == SREG_CACHE )
70 sendSim("ds 0x80 0xff\n");
74 laddr = addr & 0xffffffc0;
75 sprintf(cache->buffer,"dx 0x%x 0x%x\n",laddr,laddr+0xff );
76 sendSim(cache->buffer);
80 cache->addr = strtol(resp,0,0);
83 while ( *resp && *(resp+1) && *(resp+2))
85 /* cache is a stringbuffer with ascii data like
86 " 00 00 00 00 00 00 00 00"
90 /* skip thru the address part */
91 while (isxdigit(*resp)) resp++;
92 while ( *resp && *resp != '\n')
105 if ( cache->addr > addr ||
106 cache->addr + cache->size < addr + size )
109 return cache->buffer + (addr - cache->addr)*3;
112 /*-----------------------------------------------------------------*/
113 /* invalidate memory cache */
114 /*-----------------------------------------------------------------*/
115 static void invalidateCache( int cachenum )
117 memCache[cachenum].size = 0;
120 /*-----------------------------------------------------------------*/
121 /* waitForSim - wait till simulator is done its job */
122 /*-----------------------------------------------------------------*/
123 void waitForSim(int timeout_ms, char *expect)
128 Dprintf(D_simi, ("simi: waitForSim start(%d)\n", timeout_ms));
131 while ((ch = fgetc(simin)) > 0 ) {
135 Dprintf(D_simi, ("waitForSim(%d) got[%s]\n", timeout_ms, simibuff));
139 /*-----------------------------------------------------------------*/
140 /* openSimulator - create a pipe to talk to simulator */
141 /*-----------------------------------------------------------------*/
142 void openSimulator (char **args, int nargs)
144 struct sockaddr_in sin;
147 Dprintf(D_simi, ("simi: openSimulator\n"));
149 invalidateCache(XMEM_CACHE);
150 invalidateCache(IMEM_CACHE);
151 invalidateCache(SREG_CACHE);
154 sock = socket(AF_INET,SOCK_STREAM,0);
156 memset(&sin,0,sizeof(sin));
157 sin.sin_family = AF_INET;
158 sin.sin_addr.s_addr = inet_addr("127.0.0.1");
159 sin.sin_port = htons(9756);
161 /* connect to the simulator */
162 if (connect(sock,(struct sockaddr *) &sin, sizeof(sin)) < 0) {
163 /* if failed then wait 1 second & try again
164 do this for 10 secs only */
168 /* fork and start the simulator as a subprocess */
169 if ((simPid = fork())) {
170 Dprintf(D_simi, ("simi: simulator pid %d\n",(int) simPid));
173 /* we are in the child process : start the simulator */
174 signal(SIGHUP , SIG_IGN );
175 signal(SIGINT , SIG_IGN );
176 signal(SIGABRT, SIG_IGN );
177 signal(SIGCHLD, SIG_IGN );
179 if (execvp(args[0],args) < 0) {
180 perror("cannot exec simulator");
189 perror("connect failed :");
192 /* go the socket now turn it into a file handle */
193 if (!(simin = fdopen(sock,"r"))) {
194 fprintf(stderr,"cannot open socket for read\n");
198 if (!(simout = fdopen(sock,"w"))) {
199 fprintf(stderr,"cannot open socket for write\n");
203 /* now that we have opened, wait for the prompt */
204 waitForSim(200,NULL);
207 /*-----------------------------------------------------------------*/
208 /* simResponse - returns buffer to simulator's response */
209 /*-----------------------------------------------------------------*/
215 /*-----------------------------------------------------------------*/
216 /* sendSim - sends a command to the simuator */
217 /*-----------------------------------------------------------------*/
218 void sendSim(char *s)
223 Dprintf(D_simi, ("simi: sendSim-->%s", s)); // s has LF at end already
229 static int getMemString(char *buffer, char wrflag,
230 unsigned int *addr, char mem, int size )
232 int cachenr = NMEM_CACHE;
244 case 'A': /* External stack */
245 case 'F': /* External ram */
247 cachenr = XMEM_CACHE;
250 case 'D': /* Code / static segment */
253 case 'B': /* Internal stack */
254 case 'E': /* Internal ram (lower 128) bytes */
255 case 'G': /* Internal ram */
257 cachenr = IMEM_CACHE;
259 case 'H': /* Bit addressable */
260 case 'J': /* SBIT space */
266 sprintf(buffer,"%s 0x%x\n",cmd,*addr);
269 case 'I': /* SFR space */
271 cachenr = SREG_CACHE;
273 case 'R': /* Register space */
275 /* get register bank */
276 cachenr = simGetValue (0xd0,'I',1);
277 *addr += cachenr & 0x18 ;
278 cachenr = IMEM_CACHE;
281 case 'Z': /* undefined space code */
285 sprintf(buffer,"%s %s 0x%x\n",cmd,prefix,*addr);
287 sprintf(buffer,"%s %s 0x%x 0x%x\n",cmd,prefix,*addr,*addr+size-1);
291 int simSetValue (unsigned int addr,char mem, int size, unsigned long val)
300 cachenr = getMemString(buffer,1,&addr,mem,size);
301 if ( cachenr < NMEM_CACHE )
303 invalidateCache(cachenr);
305 s = buffer + strlen(buffer) -1;
306 for ( i = 0 ; i < size ; i++ )
308 sprintf(s," 0x%x", val & 0xff);
314 waitForSim(100,NULL);
319 /*-----------------------------------------------------------------*/
320 /* simGetValue - get value @ address for mem space */
321 /*-----------------------------------------------------------------*/
322 unsigned long simGetValue (unsigned int addr,char mem, int size)
324 unsigned int b[4] = {0,0,0,0}; /* can be a max of four bytes long */
332 cachenr = getMemString(buffer,0,&addr,mem,size);
335 if ( cachenr < NMEM_CACHE )
337 resp = getMemCache(addr,cachenr,size);
341 /* create the simulator command */
343 waitForSim(100,NULL);
344 resp = simResponse();
346 /* got the response we need to parse it the response
348 [address] [v] [v] [v] ... special case in
349 case of bit variables which case it becomes
350 [address] [assembler bit address] [v] */
351 /* first skip thru white space */
352 while (isspace(*resp)) resp++ ;
354 if (strncmp(resp, "0x",2) == 0)
357 /* skip thru the address part */
358 while (isxdigit(*resp)) resp++;
361 /* make the branch for bit variables */
362 if ( cachenr == BIT_CACHE)
364 /* skip until newline */
365 while (*resp && *resp != '\n' ) resp++ ;
366 if ( *--resp != '0' )
371 for (i = 0 ; i < size ; i++ )
373 /* skip white space */
374 while (isspace(*resp)) resp++ ;
376 b[i] = strtol(resp,&resp,16);
380 return b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24 ;
384 /*-----------------------------------------------------------------*/
385 /* simSetBP - set break point for a given address */
386 /*-----------------------------------------------------------------*/
387 void simSetBP (unsigned int addr)
391 sprintf(buff,"break 0x%x\n",addr);
393 waitForSim(100,NULL);
396 /*-----------------------------------------------------------------*/
397 /* simClearBP - clear a break point */
398 /*-----------------------------------------------------------------*/
399 void simClearBP (unsigned int addr)
403 sprintf(buff,"clear 0x%x\n",addr);
405 waitForSim(100,NULL);
408 /*-----------------------------------------------------------------*/
409 /* simLoadFile - load the simulator file */
410 /*-----------------------------------------------------------------*/
411 void simLoadFile (char *s)
415 sprintf(buff,"l \"%s\"\n",s);
418 waitForSim(500,NULL);
421 /*-----------------------------------------------------------------*/
422 /* simGoTillBp - send 'go' to simulator till a bp then return addr */
423 /*-----------------------------------------------------------------*/
424 unsigned int simGoTillBp ( unsigned int gaddr)
432 invalidateCache(XMEM_CACHE);
433 invalidateCache(IMEM_CACHE);
434 invalidateCache(SREG_CACHE);
436 /* initial start, start & stop from address 0 */
439 // this program is setting up a bunch of breakpoints automatically
440 // at key places. Like at startup & main() and other function
441 // entry points. So we don't need to setup one here..
442 //sendSim("break 0x0\n");
447 waitForSim(wait_ms, NULL);
448 sendSim("run 0x0\n");
449 } else if (gaddr == -1) { /* resume */
453 else if (gaddr == 1 ) { /* nexti or next */
457 else if (gaddr == 2 ) { /* stepi or step */
462 printf("Error, simGoTillBp > 0!\n");
466 waitForSim(wait_ms, NULL);
468 /* get the simulator response */
470 /* check for errors */
473 while ( *sr && *sr != 'E' ) sr++ ;
476 if ( ! strncmp(sr,"Error:",6))
484 oldsig = signal(SIGINT,SIG_IGN);
485 /* get answer of stop command */
487 waitForSim(wait_ms, NULL);
489 /* better solution: ask pc */
491 waitForSim(100, NULL);
493 signal(SIGINT,oldsig);
495 gaddr = strtol(sr+3,0,0);
499 /*-----------------------------------------------------------------*/
500 /* simReset - reset the simulator */
501 /*-----------------------------------------------------------------*/
504 invalidateCache(XMEM_CACHE);
505 invalidateCache(IMEM_CACHE);
506 invalidateCache(SREG_CACHE);
508 waitForSim(100,NULL);
512 /*-----------------------------------------------------------------*/
513 /* closeSimulator - close connection to simulator */
514 /*-----------------------------------------------------------------*/
515 void closeSimulator ()
517 if ( ! simin || ! simout || sock == -1 )
529 kill (simPid,SIGKILL);