OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [stable_0_2_0_rc2/] [or1ksim/] [toplevel.c] - Blame information for rev 206

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 cvs
/* toplevel.c -- Top level simulator source file
2
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
3
 
4
This file is part of OpenRISC 1000 Architectural Simulator.
5
 
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
 
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.
15
 
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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
 
20
/* Simulator commands. Help and version output. SIGINT processing.
21
Stdout redirection is specific to linux (I need to fix this). */
22
 
23 16 jrydberg
#include "config.h"
24
 
25 2 cvs
#include <stdio.h>
26
#include <ctype.h>
27
#include <string.h>
28
#include <stdlib.h>
29 46 lampret
#include <unistd.h>
30 2 cvs
#include <signal.h>
31
#include <stdarg.h>
32 123 markom
/* Added by CZ 24/05/01 */
33
#include <sys/stat.h>
34
#include <sys/types.h>
35
#include <sys/socket.h>
36
#include <netinet/in.h>
37
#include <sys/select.h>
38
#include <sys/poll.h>
39
#include <fcntl.h>
40
#include <netdb.h>
41
#include <netinet/tcp.h>
42 127 chris
#include <inttypes.h>
43 2 cvs
 
44 16 jrydberg
#ifdef HAVE_LIBREADLINE
45 7 jrydberg
#include <readline/readline.h>
46
#include <readline/history.h>
47 16 jrydberg
#endif /* HAVE_LIBREADLINE */
48 7 jrydberg
 
49 2 cvs
#include "arch.h"
50
#include "parse.h"
51
#include "abstract.h"
52
#include "trace.h"
53
#include "execute.h"
54 69 lampret
#include "sim-config.h"
55 103 lampret
#include "spr_defs.h"
56 2 cvs
 
57 28 lampret
#include "coff.h"
58
 
59 123 markom
/* Added by CZ 24/05/01 */
60 127 chris
#include "gdb.h"
61 123 markom
#include <signal.h>
62
#include <errno.h>
63
typedef enum {
64
  false = 0,
65
  true = 1,
66
} Boolean;
67
unsigned int serverIP = 0;
68
unsigned int serverPort = 0;
69
unsigned int server_fd = 0;
70
unsigned int gdb_fd = 0;
71
void HandleServerSocket(Boolean);
72
void JTAGRequest(void);
73
void GDBRequest(void);
74 127 chris
void ProtocolClean(int,int32_t);
75
static int gdb_read(void*,int);
76
static int gdb_write(void*,int);
77
void BlockJTAG(void);
78
 
79 167 markom
#ifndef DEBUGMOD_OFF
80 206 chris
int NewStyleExceptions = 1;  /* Start off with the new style exception handlers */
81
                              /* This means GDB will expect the PC at 0xD00 when a
82
                                 a breakpoint occurs, and will intercept AFTER the
83
                                 exception vector is taken. */
84 123 markom
int GlobalMode = 0;   /* Start off in the orginal mode */
85 167 markom
#else  /* no DEBUGMOD_OFF */
86
#define GlobalMode 0
87
#endif /* no DEBUGMOD_OFF */
88 123 markom
 
89 2 cvs
/* CVS revision number. */
90 206 chris
const char rcsrev[] = "$Revision: 1.24 $";
91 2 cvs
 
92
/* Continuos run versus single step tracing switch. */
93
int cont_run;
94
 
95
/* History of execution */
96
int histexec[HISTEXEC_LEN];
97
 
98 7 jrydberg
char *sim_commands [] = {
99
  "q",
100
  "t",
101
  "help",
102 21 cmchen
  "de",
103 7 jrydberg
  "dm",
104
  "run",
105
  "pr",
106
  "pm",
107
  "pc",
108 18 lampret
  "reset",
109
  "break",
110 7 jrydberg
  "hist",
111
  "stats",
112 181 chris
  "stall"
113 7 jrydberg
  "info",
114
  "r",
115 54 lampret
  "dv",
116 7 jrydberg
 
117
};
118
 
119 167 markom
inline void debug(const char *format, ...)
120 2 cvs
{
121 167 markom
#ifndef DEBUGMOD_OFF
122 7 jrydberg
  char *p;
123
  va_list ap;
124 2 cvs
 
125 69 lampret
  if (config.simdebug) {
126
    if ((p = malloc(1000)) == NULL)
127
      return;
128
    va_start(ap, format);
129
    (void) vsnprintf(p, 1000, format, ap);
130
    va_end(ap);
131
    printf("%s\n", p);
132
    fflush(stdout);
133
    free(p);
134
  } else {
135
#if DEBUG
136 7 jrydberg
  if ((p = malloc(1000)) == NULL)
137
    return;
138
  va_start(ap, format);
139
  (void) vsnprintf(p, 1000, format, ap);
140
  va_end(ap);
141
  printf("%s\n", p);
142
  fflush(stdout);
143
  free(p);
144 2 cvs
#endif
145 69 lampret
  }
146 167 markom
#endif /* no DEBUGMOD_OFF */
147 2 cvs
}
148
 
149 30 lampret
/* Strip whitespace from the start and end of STRING.  Return a pointer
150
   into STRING. */
151
#ifndef whitespace
152
#define whitespace(a)   ((a) == '\t' ? 1 : ((a) == ' '? 1 : 0))
153
#endif
154
 
155
char *
156
stripwhite (string)
157
     char *string;
158
{
159
  register char *s, *t;
160
 
161
  for (s = string; whitespace (*s); s++)
162
    ;
163
 
164
  if (*s == 0)
165
    return (s);
166
 
167
  t = s + strlen (s) - 1;
168
  while (t > s && whitespace (*t))
169
    t--;
170
  *++t = '\0';
171
 
172
  return s;
173
}
174
 
175 7 jrydberg
void
176
ctrl_c(signum)
177
     int signum;
178 2 cvs
{
179 181 chris
  extern int cpu_stalled;  /* CZ from debug_interface */
180
  cont_run = cpu_stalled ? 0 : 1;
181
  config.iprompt = 1;
182
  cpu_stalled = 0;
183 7 jrydberg
  signal(SIGINT, ctrl_c);
184 2 cvs
}
185
 
186 7 jrydberg
void
187
version()
188 2 cvs
{
189 7 jrydberg
        printf ("\n");
190 18 lampret
        printf ("OpenRISC 1000 (OR16+OR32) Architectural Simulator, %s\n", rcsrev);
191
        printf ("Copyright (C) 1999 Damjan Lampret, lampret@opencores.org\n");
192
        printf ("Copyright (C) 2000 Damjan Lampret, lampret@opencores.org\n");
193 21 cmchen
        printf ("                   Jimmy Chen-Min Chen, jimmy@ee.nctu.edu.tw\n");
194 18 lampret
        printf ("                   Johan Rydberg, johan.rydberg@insight.se\n");
195 7 jrydberg
        printf ("Visit http://www.opencores.org for more information about ");
196
        printf ("OpenRISC 1000 and\nother open source cores.\n\n");
197
        printf ("This software comes with ABSOLUTELY NO WARRANTY; for ");
198
        printf ("details see COPYING.\nThis is free software, and you ");
199
        printf ("are welcome to redistribute it under certain\nconditions; ");
200
        printf ("for details see COPYING.\n");
201 2 cvs
}
202
 
203 7 jrydberg
void
204
help()
205 2 cvs
{
206
        printf("q                        - quit simulator\n");
207
        printf("r                        - display all registers\n");
208
        printf("t                        - execute next instruction\n");
209
        printf("run <cycles> [<hush>]    - execute <cycles> instructions, no reg dump if hush\n");
210
        printf("pr <r> <value>           - patch register <r> with <value>\n");
211
        printf("dm <fromaddr> [<toaddr>] - display memory from <fromaddr> to <toaddr>\n");
212 21 cmchen
        printf("de                       - debug insn memory\n");
213 2 cvs
        printf("pm <addr> <value>        - patch memory location <addr> with <value>\n");
214
        printf("pc <value>               - patch PC register with <value>\n");
215 18 lampret
        printf("break <addr>             - toggle breakpoint at address <addr>\n");
216
        printf("reset                    - simulator reset\n");
217 2 cvs
        printf("hist                     - execution history\n");
218 181 chris
        printf("stall                    - stalls the processor and gives control to the debugger\n");
219 6 lampret
        printf("stats <num|clear>        - execution statistics num or clear it.\n");
220
        printf("info                     - configuration info (caches etc.)\n");
221 54 lampret
        printf("dv <fromaddr> [<toaddr>] [<modname>] - dumps memory as verilog (use redirect)\n");
222 86 lampret
        printf("dh <fromaddr> [<toaddr>] - dumps memory as hex code (use redirect)\n");
223 2 cvs
        printf("<cmd> > <filename>       - redirect simulator stdout to <filename> (and not emulated printf)\n");
224 69 lampret
        printf("debug                    - toggles simulator debug mode\n");
225 2 cvs
        printf("help                     - available commands (this list)\n");
226
}
227
 
228 21 cmchen
void debugmem();
229
 
230 7 jrydberg
main(argc, argv)
231
     int argc;
232
     char *argv[];
233 2 cvs
{
234 7 jrydberg
        char *linestr;
235 167 markom
        char item1[500], b2[500], prev_str[500] = "";
236 2 cvs
        char *redirstr;
237
        int hush;
238 123 markom
        unsigned long endaddr = 0xFFFFFFFF;
239
        int first_prompt = 1;
240 181 chris
        int trace_fd = 0;
241 206 chris
        unsigned char trace_reg[32];
242 123 markom
 
243 206 chris
        memset(trace_reg,'\0',sizeof(trace_reg));
244 103 lampret
        srand(getpid());
245
        init_defconfig();
246 123 markom
        if (parse_args(argc, argv)) {
247 206 chris
        printf("Usage: %s [options] <filename>\n", argv[0]);
248 103 lampret
                printf("Options:\n");
249
                printf(" -v: version and copyright note\n");
250
                printf(" -i: enable interactive command prompt\n");
251
                printf(" -bpb: disable branch prediction buffer analysis\n");
252
                printf(" -btic: disable branch prediction target insn cache analysis\n");
253
                printf(" -hazards: disable dependency hazards analysis\n");
254
                printf(" -history: disable instruction stream history analysis\n");
255
                printf(" -superscalar: disable superscalar analysis\n");
256 123 markom
                printf(" -fast: disable BPB, BTIC, SLP, dependency hazards, history"
257
                       " analysis etc.\n");
258 173 markom
                printf(" -profile: generates profiling data.\n"); /* MM */
259 103 lampret
                printf(" -upr <n>: set UPR to n\n");
260
                printf(" -ver <n>: set VR[VER] to n\n");
261
                printf(" -rev <n>: set VR[REV] to n\n");
262 123 markom
                printf(" -loadmem[@<n>] <filename>: load memory with file, "
263
                       "optionally at address <n>\n"); /* (CZ) */
264
                printf(" -nosrv: do not launch JTAG proxy server\n"); /* (CZ) */
265
                printf(" -srv <n>: launch JTAG proxy server on port <n>\n"); /* (CZ) */
266
                printf(" -initmem <n | random>: initialize memory to value "
267
                       "<n> or random\n"); /* (CZ) */
268 103 lampret
                exit(-1);
269
        }
270 7 jrydberg
 
271 16 jrydberg
#ifdef HAVE_LIBREADLINE
272 7 jrydberg
  initialize_readline ();       /* Bind our completer. */
273 16 jrydberg
#endif  
274 123 markom
 
275
  if(!config.inhibit_server)
276
    {
277
      serverPort = config.server_port;
278
      if(server_fd = GetServerSocket("or1ksim","tcp",serverPort))
279
        printf("JTAG Proxy server started on port %d\n",serverPort);
280
    }
281 16 jrydberg
 
282 173 markom
  if(config.profile) {
283
    config.fprof = fopen("sim-profile","wt+");
284
    if(!config.fprof) {
285
      config.profile = 0;
286
      printf("Problems opening profile file. Profiling disabled. \n");
287
    } else
288
      fprintf(config.fprof, "+00000000 FFFFFFFF FFFFFFFF main\n");
289
  }
290
 
291 103 lampret
        print_config();
292 2 cvs
        signal(SIGINT, ctrl_c);
293
        initstats();
294 138 markom
        build_automata();
295 123 markom
 
296
        /* Modified by CZ on 24/05/01 ... if a filename is
297
           specified, behave as the simulator always has. This way,
298
           no existing test suites should be broken. If a filename
299
           is not specified, default to the new style behavior. Let
300
           the simulator start up and execute garbage, the same way
301
           a real CPU would. This should maximize the reality of
302
           the capabilities. In this mode, we will expect that
303
           someone will attach to us over the JTAG Proxy interface
304
           and begin debugging that way. */
305
 
306
        if(config.filename)
307
          {
308
            endaddr = loadcode(config.filename, MEMORY_START, 0);
309
            if (endaddr == -1) {
310
              printf("Problems loading boot code.\n");
311
              exit(1);
312
            }
313
          }
314
        else
315
          {
316
            if(config.random_mem)
317
              {
318
                int n = 0;
319
                int len = sizeof(mem);
320
                unsigned int* mptr = (unsigned int*)mem;
321
                unsigned int val = 0;
322
                int seed = time(NULL);
323
 
324
                srandom(seed);
325
                /* Print out the seed just in case we ever need to debug */
326
                printf("Seeding random generator with value %d\n",seed);
327
 
328
                for(n=0;n<len;n+=sizeof(unsigned int))
329
                  {
330
                    val = random();
331
                    if(random() > RAND_MAX/2)
332
                      val |= 0x80000000;
333
                    *mptr++ = val;
334
                  }
335
              }
336
            else if(config.pattern_mem)
337
              {
338
                int n = 0;
339
                int len = sizeof(mem);
340
                unsigned int* mptr = (unsigned int*)mem;
341
 
342
                for(n=0;n<len;n+=sizeof(unsigned int))
343
                  *mptr++ = config.pattern_mem;
344
              }
345
            else
346
              memset(mem,0,sizeof(mem));
347
 
348
            if(config.memory)
349
              {
350
                MemoryBlock* block = config.memory;
351
 
352
                while(block)
353
                  {
354
                    int fd = open(block->file,O_RDONLY);
355
                    int len,i;
356
                    struct stat buf;
357
                    char *mptr = (char*)mem;
358
                    char buffer[8192];
359
 
360
                    if(fd < 0)
361
                      {
362
                        perror(block->file);
363
                        exit(1);
364
                      }
365
                    if(fstat(fd,&buf) < 0)
366
                      {
367
                        char sTemp[256];
368
 
369
                        sprintf(sTemp,"stat(\"%s\")",block->file);
370
                        perror(sTemp);
371
                        exit(1);
372
                      }
373
                    if(!S_ISREG(buf.st_mode))
374
                      {
375
                        fprintf(stderr,"File \"%s\" is not a regular file.\n",
376
                                block->file);
377
                        exit(1);
378
                      }
379
 
380
                    len = buf.st_size;
381
                    mptr += block->address;
382
                    for(i=0;i<len;)
383
                      {
384
                        int n = read(fd,buffer,sizeof(buffer));
385
 
386
                        switch(n)
387
                          {
388
                          case -1:
389
                            if(errno == EINTR)
390
                              continue;
391
                            perror(block->file);
392
                            exit(1);
393
                          case 0:
394
                            fprintf(stderr,"File \"%s\": premature end of file.\n",
395
                                    block->file);
396
                            exit(1);
397
                          default:
398
                            memcpy(mptr,buffer,n);
399
                            i+= n;
400
                            break;
401
                          }
402
                      }
403
                    close(fd);
404
                  }
405
              }
406
          }
407 167 markom
#ifndef DEBUGMOD_OFF
408 123 markom
        GlobalMode = config.filename == NULL; /* Old mode = 0, New mode = 1 */
409 167 markom
#endif
410 123 markom
 
411 30 lampret
        uart_reset();
412 92 lampret
        tick_reset();
413 103 lampret
        pm_reset();
414
        pic_reset();
415 206 chris
        mtspr(2,0x20);  /* We are emulating a 32 bit processor/no FP */
416 2 cvs
        reset();
417 123 markom
        if(!GlobalMode)  /* Only in old mode */
418 138 markom
          set_reg32(3, endaddr);
419 7 jrydberg
 
420 103 lampret
        while(1) {
421
                if (config.iprompt) {
422 123 markom
                  if(server_fd)
423
                    {
424
                      printf ("(sim) ");
425
                      fflush(stdout);
426
                      HandleServerSocket(true);  /* block & check_stdin = true */
427
                    }
428 16 jrydberg
#ifdef HAVE_LIBREADLINE
429 123 markom
                  /* Must disable readline in new mode. It isn't compatible
430
                     with non blocking environments */
431
                  if(!server_fd)
432
                    linestr = readline("(sim) ");
433
                  else
434
                    linestr = fgets(b2, sizeof b2, stdin);
435 16 jrydberg
#else
436 123 markom
                  if(!server_fd)
437
                    printf ("(sim) ");
438
                  linestr = fgets(b2, sizeof b2, stdin);
439 16 jrydberg
#endif
440 103 lampret
                } else
441 173 markom
                        strcpy(linestr = b2, "run -1 hush");
442 7 jrydberg
 
443 103 lampret
                if (!linestr)
444
                        break;
445
                linestr = stripwhite (linestr);
446 7 jrydberg
 
447 16 jrydberg
#ifdef HAVE_LIBREADLINE
448 123 markom
                /* Readline only works in the old mode */
449
                if(!server_fd)
450
                  {
451
                    if (strlen(linestr) == 0) {
452
                      char *l = repeat_last_command ();
453
 
454
                      if (l) {
455
                        free (linestr);
456
                        linestr = l;
457
                      }
458
                    }
459
 
460
                    if (*linestr) {
461
                      add_history (linestr);
462
                    }
463
                  }
464 16 jrydberg
#endif /* HAVE_LIBREADLINE */
465 2 cvs
 
466 103 lampret
                if (redirstr = strstr(linestr, ">")) {
467
                        *redirstr = '\0';
468
                        strtoken(&redirstr[1], item1, 1);
469
                        freopen(item1, "w+", stdout);
470
                }
471 2 cvs
 
472 167 markom
                if (linestr[0] == '\n')
473
                  strcpy (linestr, &prev_str[0]);
474
                else
475
                  strcpy (&prev_str[0], linestr);
476
 
477 2 cvs
                strtoken(linestr, item1, 1);
478 167 markom
                if (strcmp(item1, "q") == 0) {   /* quit */
479
                  printf ("\n");
480 173 markom
                  if (config.profile) {
481
                    extern int cycles;
482
                    fprintf(config.fprof,"-%08X FFFFFFFF\n", cycles);
483
                    fclose(config.fprof);
484
                  }
485 167 markom
                  exit(0);
486
                } else
487 2 cvs
                if (strcmp(item1, "help") == 0)  /* help */
488
                        help();
489
                else
490
                if (strcmp(item1, "t") == 0) {   /* trace */
491
                        cont_run = 1;
492
                } else
493
                if (strcmp(item1, "dm") == 0) {  /* dump memory */
494
                        char item2[20];
495
                        char item3[20];
496
                        static int from = 0, to = 0;
497
 
498
                        strtoken(linestr, item2, 2);
499
                        strtoken(linestr, item3, 3);
500
 
501
                        if (strlen(item2)) {
502
                                if (item2[0] == '_')
503
                                        from = eval_label(item2);
504
                                else
505
                                        from = strtoul(item2, NULL, 0);
506
                                to = from + 0x40;
507
                        }
508
                        if (strlen(item3))
509
                                to = strtoul(item3, NULL, 0);
510 167 markom
                        dumpmemory(from, to, 0);
511 54 lampret
                        printf("\n");
512 2 cvs
                } else
513 54 lampret
                if (strcmp(item1, "dv") == 0) {/* dump memory as verilog*/
514
                        char item2[20];
515
                        char item3[20];
516
                        char item4[20];
517
                        static int from = 0, to = 0;
518
 
519
                        strtoken(linestr, item2, 2);
520
                        strtoken(linestr, item3, 3);
521
                        strtoken(linestr, item4, 4);
522
 
523
                        if (strlen(item2)) {
524
                                if (item2[0] == '_')
525
                                        from = eval_label(item2);
526
                                else
527
                                        from = strtoul(item2, NULL, 0);
528
                                to = from + 0x40;
529
                        }
530
                        if (strlen(item3))
531
                                to = strtoul(item3, NULL, 0);
532
                        if (!strlen(item4))
533
                                strcpy(item4, "or1k_mem");
534
                        dumpverilog(item4, from, to);
535
                        printf("\n");
536
                } else
537 86 lampret
                if (strcmp(item1, "dh") == 0) {/* dump memory as hex*/
538
                        char item2[20];
539
                        char item3[20];
540
                        static int from = 0, to = 0;
541
 
542
                        strtoken(linestr, item2, 2);
543
                        strtoken(linestr, item3, 3);
544
 
545
                        if (strlen(item2)) {
546
                                if (item2[0] == '_')
547
                                        from = eval_label(item2);
548
                                else
549
                                        from = strtoul(item2, NULL, 0);
550
                                to = from + 0x40;
551
                        }
552
                        if (strlen(item3))
553
                                to = strtoul(item3, NULL, 0);
554
                        dumphex(from, to);
555
                        printf("\n");
556
                } else
557 2 cvs
                if (strcmp(item1, "pm") == 0) {  /* patch memory */
558
                        char item2[20];
559
                        char item3[20];
560
                        static int addr = 0;
561 123 markom
                        int breakpoint = 0;
562
 
563 2 cvs
                        strtoken(linestr, item2, 2);
564
                        strtoken(linestr, item3, 3);
565
                        if (strlen(item2))
566
                                if (item2[0] == '_')
567
                                        addr = eval_label(item2);
568
                                else
569
                                        addr = strtoul(item2, NULL, 0);
570 123 markom
                        set_mem32(addr, strtoul(item3, NULL, 0), &breakpoint);
571 2 cvs
                } else
572
                if (strcmp(item1, "pr") == 0) {  /* patch regs */
573
                        char item2[20];
574
                        char item3[20];
575
 
576
                        strtoken(linestr, item2, 2);
577
                        strtoken(linestr, item3, 3);
578 138 markom
                        set_reg32(strtoul(item2, NULL,0), strtoul(item3, NULL, 0));
579 2 cvs
                } else
580
                if (strcmp(item1, "pc") == 0) {  /* patch PC */
581
                        char item2[20];
582
 
583
                        strtoken(linestr, item2, 2);
584 86 lampret
                        pcnext = strtoul(item2, NULL, 0);
585 2 cvs
                } else
586 7 jrydberg
                if (strcmp(item1, "break") == 0) {       /* set/clear breakpoint */
587 2 cvs
                        char item2[20];
588
 
589
                        strtoken(linestr, item2, 2);
590
                        set_insnbrkpoint(strtoul(item2, NULL, 0));
591
                } else
592
                if (strcmp(item1, "r") == 0) {   /* dump regs */
593
                        dumpreg();
594
                } else
595 21 cmchen
                if (strcmp(item1, "de") == 0) {  /* reset simulator */
596
                        debugmem();
597
                } else
598 18 lampret
                if (strcmp(item1, "reset") == 0) {       /* reset simulator */
599 30 lampret
                        uart_reset();
600 92 lampret
                        tick_reset();
601 103 lampret
                        pm_reset();
602
                        pic_reset();
603 123 markom
                        reset(); /* Old or new mode */
604 18 lampret
                } else
605 69 lampret
                if (strcmp(item1, "debug") == 0) {       /* debug mode */
606
                        config.simdebug ^= 1;
607
                } else
608 2 cvs
                if (strcmp(item1, "hist") == 0) {        /* dump history */
609
                        int i;
610
                        for(i = HISTEXEC_LEN; i; i--)
611 167 markom
                                dumpmemory(histexec[i - 1], histexec[i - 1] + 4, 1);
612 46 lampret
                        printf("\n");
613 2 cvs
                } else
614
                if (strcmp(item1, "run") == 0) { /* run */
615
                        char item2[20];
616
                        char item3[20];
617
 
618
                        strtoken(linestr, item2, 2);
619
                        strtoken(linestr, item3, 3);
620
                        if (strcmp(item3, "hush") == 0)
621
                                hush = 1;
622
                        else
623
                                hush = 0;
624 173 markom
                        cont_run = strtol(item2, NULL, 0);
625 2 cvs
                } else
626 181 chris
                if(!strcmp(item1, "stall")) { /* Added by CZ 210801 */
627
                  extern int cpu_stalled;  /* CZ from debug_interface */
628
                  cpu_stalled = 1;
629
                  config.iprompt = 0;
630
                  cont_run = -1;
631
                  hush = 1;
632
                } else
633
                if (!strcmp(item1, "trace")) { /* Added by CZ 210801 */
634
                  char item2[256];
635 206 chris
                  char item3[256];
636
                  char *s,*q;
637
 
638 181 chris
                  strtoken(linestr, item2, 2);
639 206 chris
                  strtoken(linestr, item3, 3);
640 181 chris
                  if(trace_fd)
641
                    {
642
                      close(trace_fd);
643
                      trace_fd = 0;
644 206 chris
                      memset(trace_reg,'\0',sizeof(trace_reg));
645 181 chris
                    }
646
                  if(strcmp(item2,"off")) /* if we're not being turned off */
647
                    {
648
                      if(item2[0])
649
                        trace_fd = open(item2,O_CREAT | O_NOCTTY |
650
                                        O_TRUNC | O_WRONLY, 0644);
651
                      else
652
                        trace_fd = dup(1);
653
                      if(trace_fd < 0)
654
                        {
655
                          perror(item2[0]?item2:"stdout");
656
                          trace_fd = 0;
657
                        }
658
                    }
659 206 chris
                  if(!trace_fd && strlen(item3))
660
                    printf("Syntax error on trace: \"%s\" unexpected\n",item3);
661
                  else
662
                    for(s = item3;s && *s; s = q)
663
                      {
664
                        if(q = strchr(s,','))
665
                          *q++ = '\0';
666
 
667
                        if(strlen(s) < 4 && (s[0] == 'r' || s[0] == 'R') &&
668
                           isdigit(s[1]) && (isdigit(s[2]) || !s[2]))
669
                          trace_reg[atoi(&s[1])] = 1;
670
                        else
671
                          printf("Syntax error in format: \"%s\" not a valid register\n",s);
672
                      }
673
 
674 181 chris
                } else
675 2 cvs
                if (strcmp(item1, "stats") == 0) { /* stats */
676 6 lampret
                        char item2[20];
677
                        int i = 0;
678
 
679
                        strtoken(linestr, item2, 2);
680
                        if (strcmp(item2, "clear") == 0) {
681
                                initstats();
682
                                printf("Cleared.\n");
683
                        } else {
684
                                i = strtoul(item2, NULL, 0);
685
                                printstats(i);
686
                        }
687
                } else
688
                if (strcmp(item1, "info") == 0) { /* configuration info */
689 78 lampret
                        itlb_status(-1);
690
                        dtlb_status(-1);
691 6 lampret
                        bpb_info();
692
                        btic_info();
693
                        ic_info();
694
                        dc_info();
695 30 lampret
                        uart_status();
696
                        sprs_status();
697 7 jrydberg
                } else {
698 103 lampret
                        printf("%s: Unknown command.\n", linestr);
699
                }
700
 
701 138 markom
                /* MM: 'run -1' means endless execution.  */
702
                while(cont_run != 0) {
703 123 markom
                  extern int cycle_delay;  /* Added by CZ 27/05/01. Set during exception. */
704 127 chris
                  extern int cpu_stalled;  /* CZ from debug_interface */
705 123 markom
 
706 127 chris
                  if(cpu_stalled)
707
                    {
708
                      BlockJTAG();
709
                      HandleServerSocket(false);
710
                      continue;
711
                    }
712
 
713 167 markom
                        if (!testsprbits(SPR_PMR, SPR_PMR_DME | SPR_PMR_SME)) {
714 123 markom
                          if(cycle_delay <= 0)
715
                            {
716 181 chris
                              unsigned int addr;
717 173 markom
                              if (cont_run > 0) cont_run--;
718 123 markom
                              if(fetch()) {
719
                                cont_run = 0; /* memory breakpoint encountered */
720
                                break;
721
                              }
722 181 chris
                              addr = iqueue[0].insn_addr;
723
 
724
                              /* If trace_fd is non zero, we want
725
                                 to make sure that disassemble is called */
726
 
727
                              decode_execute(&iqueue[0],trace_fd);
728
                              if(trace_fd)
729
                                {
730
                                  char sTemp[256];
731
                                  char sTemp2[256];
732 206 chris
                                  char reg_value[16];
733 181 chris
                                  unsigned long value;
734 206 chris
                                  int first_register = 1;
735
                                  int i;
736 181 chris
                                  extern char *disassembled;
737
                                  extern unsigned long reg[];
738
 
739 206 chris
                                  value = (mem[0x0c].data << 24) +
740
                                    (mem[0x0d].data << 16) +
741
                                    (mem[0x0e].data << 8)
742
                                    + mem[0x0f].data;
743 181 chris
 
744 206 chris
#if 0
745 181 chris
                                  sprintf(sTemp,"0x%06x: %s",addr,disassembled);
746 206 chris
                                  memset(sTemp2,' ',80);
747 181 chris
                                  strncpy(sTemp2,sTemp,strlen(sTemp));
748 206 chris
 
749
                                  sTemp[0] = '\0';
750
                                  sTemp2[78] = '\0';
751
                                  for(i=0;i<32;i++)
752
                                    if(trace_reg[i])
753
                                      {
754
                                        sprintf(reg_value,"%c0x%08x",first_register?'<':',',
755
                                                reg[i]);
756
                                        strcat(sTemp,reg_value);
757
                                        first_register = 0;
758
                                      }
759
                                  if(!first_register)
760
                                    sprintf(&sTemp2[40],"%s>\n",sTemp);
761
#endif
762
                                  sprintf(sTemp2,"0x%06x: %s <0x%08x>\n",addr,disassembled,value);
763 181 chris
                                  write(trace_fd,sTemp2,strlen(sTemp2));
764
                                }
765 123 markom
                              update_pc();
766
                              analysis();
767
                              if (!hush)
768
                                dumpreg();
769
                            }
770
                          else
771
                            cycle_delay--;
772
 
773
                          pic_clock();
774
                          dc_clock();
775
                          ic_clock();
776 103 lampret
                        }
777 167 markom
                        if (!testsprbits(SPR_PMR, SPR_PMR_SME))
778 123 markom
                          tick_clock();
779 103 lampret
                        pm_clock();
780 30 lampret
                        uart_clock();
781 167 markom
#ifndef DEBUGMOD_OFF
782 123 markom
                        HandleServerSocket(false); /* block & check_stdin = false */
783 167 markom
#endif
784 2 cvs
                }
785
                hush = 0;
786
                fflush(stdout);
787
                freopen("/dev/fd/0", "w+", stdout);
788
 
789 173 markom
                if (!config.iprompt && !GlobalMode) {   /* non-interactive quit in old mode */
790
                  if (config.profile) {
791
                    extern int cycles;
792
                    fprintf(config.fprof,"-%08X FFFFFFFF\n", cycles);
793
                    fclose(config.fprof);
794
                  }
795
                  exit(0);
796
                }
797 16 jrydberg
#ifdef HAVE_LIBREADLINE
798 103 lampret
                if (linestr)
799
                        free (linestr);
800 16 jrydberg
#endif
801 7 jrydberg
 
802 2 cvs
        }
803
        exit(0);
804
}
805 7 jrydberg
 
806 16 jrydberg
#ifdef HAVE_LIBREADLINE
807 7 jrydberg
char *command_generator ();
808
char **sim_completion ();
809
 
810
/* Tell the GNU readline library how to complete.  We want to try to complete
811
   on command names if this is the first word in the line, or on filenames
812
   if not. */
813
void initialize_readline ()
814
{
815
  /* Allow conditional parsing of the ~/.inputrc file. */
816
  rl_readline_name = "or1ksim";
817
 
818
  /* Tell the completer that we want a crack first. */
819
  rl_attempted_completion_function = (CPPFunction *)sim_completion;
820
}
821
 
822
/* Attempt to complete on the contents of TEXT.  START and END bound the
823
   region of rl_line_buffer that contains the word to complete.  TEXT is
824
   the word to complete.  We can use the entire contents of rl_line_buffer
825
   in case we want to do some simple parsing.  Return the array of matches,
826
   or NULL if there aren't any. */
827
char **
828
sim_completion (text, start, end)
829
     char *text;
830
     int start, end;
831
{
832
  char **matches;
833
 
834
  matches = (char **)NULL;
835
 
836
  /* If this word is at the start of the line, then it is a command
837
     to complete.  Otherwise it is the name of a file in the current
838
     directory. */
839
  if (start == 0)
840
    matches = completion_matches (text, command_generator);
841
 
842
  return (matches);
843
}
844
 
845
/* Generator function for command completion.  STATE lets us know whether
846
   to start from scratch; without any state (i.e. STATE == 0), then we
847
   start at the top of the list. */
848
char *
849
command_generator (text, state)
850
     char *text;
851
     int state;
852
{
853
  static int list_index, len;
854
  char *name;
855
 
856
  /* If this is a new word to complete, initialize now.  This includes
857
     saving the length of TEXT for efficiency, and initializing the index
858
     variable to 0. */
859
  if (!state)
860
    {
861
      list_index = 0;
862
      len = strlen (text);
863
    }
864
 
865
  /* Return the next name which partially matches from the command list. */
866
  while (name = sim_commands[list_index])
867
    {
868
      list_index++;
869
 
870
      if (strncmp (name, text, len) == 0)
871
        return (dupstr(name));
872
    }
873
 
874
  /* If no names matched, then return NULL. */
875
  return ((char *)NULL);
876
}
877
 
878
char *
879
dupstr (s)
880
     char *s;
881
{
882
  char *r;
883
 
884
  r = xmalloc (strlen (s) + 1);
885
  strcpy (r, s);
886
  return (r);
887
}
888
 
889
/* Repeats the last command.  */
890
char *
891
repeat_last_command ()
892
{
893
  int offset = where_history ();
894
  HIST_ENTRY *hist;
895
 
896
  if (hist = history_get (offset))
897
    {
898
      return dupstr (hist->line);
899
    }
900
  return 0;
901
}
902 16 jrydberg
 
903
#endif
904
 
905 138 markom
extern char *disassembled;
906 21 cmchen
void debugmem() {
907 138 markom
  int i;
908
  printf("starting to dump mem...\n");
909
  for(i=0; i<500; i++) {
910
    printf("i=%x :: ", i);
911
    if (mem[i].label)
912
      printf("label: %s |", mem[i].label->name);
913
    {
914
      unsigned int _insn;
915
      _insn = ((unsigned long)mem[i].data << 24);
916
      _insn |= ((unsigned long)mem[i + 1].data << 16);
917
      _insn |= ((unsigned long)mem[i + 2].data << 8);
918
      _insn |= ((unsigned long)mem[i + 3].data);
919
      iqueue[0].insn_index = insn_decode(_insn);
920
      iqueue[0].insn = _insn;
921
      disassemble_insn (_insn);
922
      printf("%s\n", disassembled);
923
    }
924
  }
925 21 cmchen
}
926 123 markom
 
927 127 chris
static int tcp_level = 0;
928
 
929 123 markom
/* Added by CZ 24/05/01 */
930
int GetServerSocket(const char* name,const char* proto,int port)
931
{
932
  struct servent *service;
933
  struct protoent *protocol;
934
  struct sockaddr_in sa;
935
  struct hostent *hp;
936
  int sockfd;
937
  char myname[256];
938
  int flags;
939
  char sTemp[256];
940
 
941
  /* First, get the protocol number of TCP */
942
  if(!(protocol = getprotobyname(proto)))
943
    {
944
      sprintf(sTemp,"Unable to load protocol \"%s\"",proto);
945
      perror(sTemp);
946
      return 0;
947
    }
948 127 chris
  tcp_level = protocol->p_proto; /* Save for later */
949
 
950 123 markom
  /* If we weren't passed a non standard port, get the port
951
     from the services directory. */
952
  if(!port)
953
    {
954
      if(service = getservbyname(name,protocol->p_name))
955
        port = ntohs(service->s_port);
956
    }
957
 
958
  /* Create the socket using the TCP protocol */
959
  if((sockfd = socket(PF_INET,SOCK_STREAM,protocol->p_proto)) < 0)
960
    {
961
      perror("Unable to create socket");
962
      return 0;
963
    }
964
 
965
  flags = 1;
966
  if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,(const char*)&flags,sizeof(int))
967
 < 0)
968
    {
969
      sprintf(sTemp,"Can not set SO_REUSEADDR option on socket %d",sockfd);
970
      perror(sTemp);
971
      close(sockfd);
972
      return 0;
973
    }
974
 
975
  /* The server should also be non blocking. Get the current flags. */
976
  if(fcntl(sockfd,F_GETFL,&flags) < 0)
977
    {
978
      sprintf(sTemp,"Unable to get flags for socket %d",sockfd);
979
      perror(sTemp);
980
      close(sockfd);
981
      return 0;
982
    }
983
 
984
  /* Set the nonblocking flag */
985
  if(fcntl(sockfd,F_SETFL, flags | O_NONBLOCK) < 0)
986
    {
987
      sprintf(sTemp,"Unable to set flags for socket %d to value 0x%08x",
988
              sockfd,flags | O_NONBLOCK);
989
      perror(sTemp);
990
      close(sockfd);
991
      return 0;
992
    }
993
 
994
  /* Find out what our address is */
995
  memset(&sa,0,sizeof(struct sockaddr_in));
996
  gethostname(myname,sizeof(myname));
997
  if(!(hp = gethostbyname(myname)))
998
    {
999
      perror("Unable to read hostname");
1000
      close(sockfd);
1001
      return 0;
1002
    }
1003
 
1004
  /* Bind our socket to the appropriate address */
1005
  sa.sin_family = hp->h_addrtype;
1006
  sa.sin_port = htons(port);
1007
  if(bind(sockfd,(struct sockaddr*)&sa,sizeof(struct sockaddr_in)) < 0)
1008
    {
1009
      sprintf(sTemp,"Unable to bind socket %d to port %d",sockfd,port);
1010
      perror(sTemp);
1011
      close(sockfd);
1012
      return 0;
1013
    }
1014
  serverIP = sa.sin_addr.s_addr;
1015
  flags = sizeof(struct sockaddr_in);
1016
  if(getsockname(sockfd,(struct sockaddr*)&sa,&flags) < 0)
1017
    {
1018
      sprintf(sTemp,"Unable to get socket information for socket %d",sockfd);
1019
      perror(sTemp);
1020
      close(sockfd);
1021
      return 0;
1022
    }
1023
  serverPort = ntohs(sa.sin_port);
1024
 
1025
  /* Set the backlog to 1 connections */
1026
  if(listen(sockfd,1) < 0)
1027
    {
1028
      sprintf(sTemp,"Unable to set backlog on socket %d to %d",sockfd,1);
1029
      perror(sTemp);
1030
      close(sockfd);
1031
      return 0;
1032
    }
1033
 
1034
  return sockfd;
1035
}
1036
 
1037 127 chris
void BlockJTAG()
1038 123 markom
{
1039
  struct pollfd fds[2];
1040
  int n = 0;
1041 127 chris
 
1042
  fds[n].fd = server_fd;
1043
  fds[n].events = POLLIN;
1044
  fds[n++].revents = 0;
1045
  if(gdb_fd)
1046
    {
1047
      fds[n].fd = gdb_fd;
1048
      fds[n].events = POLLIN;
1049
      fds[n++].revents = 0;
1050
    }
1051
  poll(fds,n,-1);
1052
}
1053
 
1054
void HandleServerSocket(Boolean block)
1055
{
1056
  struct pollfd fds[3];
1057
  int n = 0;
1058 123 markom
  int timeout = block ? -1 : 0;
1059
  int server_index = -1;
1060
  int gdb_index = -1;
1061
  Boolean data_on_stdin = false;
1062
  int o_serv_fd = server_fd;
1063
 
1064
  if(!o_serv_fd && !gdb_fd)
1065
    return;
1066
 
1067
  if(o_serv_fd)
1068
    {
1069
      fds[n].fd = o_serv_fd;
1070
      fds[n].events = POLLIN;
1071
      fds[n++].revents = 0;
1072
    }
1073
  if(gdb_fd)
1074
    {
1075
      fds[n].fd = gdb_fd;
1076
      fds[n].events = POLLIN;
1077
      fds[n++].revents = 0;
1078
    }
1079
  if(block)
1080
    {
1081
      fds[n].fd = 0;
1082
      fds[n].events = POLLIN;
1083
      fds[n++].revents = 0;
1084
    }
1085
 
1086
  while(!data_on_stdin)
1087
    {
1088
      switch(poll(fds,n,timeout))
1089
        {
1090
        case -1:
1091
          if(errno == EINTR)
1092
            continue;
1093
          perror("poll");
1094
          server_fd = 0;
1095
          break;
1096
        case 0: /* Nothing interesting going on */
1097
          data_on_stdin = true; /* Can only get here if nonblocking */
1098
          break;
1099
        default:
1100 127 chris
          /* Make sure to handle the gdb port first! */
1101 123 markom
          if((fds[0].revents && (gdb_fd && !o_serv_fd) ||
1102
              fds[1].revents && (server_fd && gdb_fd)))
1103
            {
1104
              int revents = o_serv_fd ? fds[1].revents : fds[0].revents;
1105
 
1106
              if(revents & POLLIN)
1107
                GDBRequest();
1108
              else /* Error Occurred */
1109
                {
1110
                  fprintf(stderr,"Received flags 0x%08x on gdb socket. Shutting down.\n",revents);
1111
                  close(gdb_fd);
1112
                  gdb_fd = 0;
1113
                }
1114
            }
1115 127 chris
          if(fds[0].revents && o_serv_fd)
1116
            {
1117
              if(fds[0].revents & POLLIN)
1118
                JTAGRequest();
1119
              else /* Error Occurred */
1120
                {
1121
                  fprintf(stderr,"Received flags 0x%08x on server. Shutting down.\n",fds[0].revents);
1122
                  close(o_serv_fd);
1123
                  server_fd = 0;
1124
                  serverPort = 0;
1125
                  serverIP = 0;
1126
                }
1127
            }
1128 123 markom
          if(fds[2].revents || (fds[1].revents && !gdb_fd))
1129
            data_on_stdin = true;
1130
          break;
1131
        } /* End of switch statement */
1132
    } /* End of while statement */
1133
}
1134
 
1135
void JTAGRequest()
1136
{
1137
  struct sockaddr_in sa;
1138
  struct sockaddr* addr = (struct sockaddr*)&sa;
1139
  int n = sizeof(struct sockaddr_in);
1140
  int fd = accept(server_fd,addr,&n);
1141
  int on_off = 0; /* Turn off Nagel's algorithm on the socket */
1142
  int flags;
1143
  char sTemp[256];
1144
 
1145
  if(fd < 0)
1146
    {
1147
      /* This is valid, because a connection could have started,
1148
         and then terminated due to a protocol error or user
1149
         initiation before the accept could take place. */
1150
      if(errno != EWOULDBLOCK && errno != EAGAIN)
1151
        {
1152
          perror("accept");
1153
          close(server_fd);
1154
          server_fd = 0;
1155
          serverPort = 0;
1156
          serverIP = 0;
1157
        }
1158
      return;
1159
    }
1160
 
1161
  if(gdb_fd)
1162
    {
1163
      close(fd);
1164
      return;
1165
    }
1166
 
1167
  if(fcntl(fd,F_GETFL,&flags) < 0)
1168
    {
1169
      sprintf(sTemp,"Unable to get flags for gdb socket %d",fd);
1170
      perror(sTemp);
1171
      close(fd);
1172
      return;
1173
    }
1174
 
1175
  if(fcntl(fd,F_SETFL, flags | O_NONBLOCK) < 0)
1176
    {
1177
      sprintf(sTemp,"Unable to set flags for gdb socket %d to value 0x%08x",
1178
              fd,flags | O_NONBLOCK);
1179
      perror(sTemp);
1180
      close(fd);
1181
      return;
1182
    }
1183
 
1184 127 chris
  if(setsockopt(fd,tcp_level,TCP_NODELAY,&on_off,sizeof(int)) < 0)
1185 123 markom
    {
1186
      sprintf(sTemp,"Unable to disable Nagel's algorithm for socket %d.\nsetsockopt",fd);
1187
      perror(sTemp);
1188
      close(fd);
1189
      return;
1190
    }
1191
 
1192
  gdb_fd = fd;
1193
}
1194
 
1195
void GDBRequest()
1196
{
1197 127 chris
  JTAGProxyWriteMessage msg_write;
1198
  JTAGProxyReadMessage msg_read;
1199
  JTAGProxyChainMessage msg_chain;
1200
  JTAGProxyWriteResponse resp_write;
1201
  JTAGProxyReadResponse resp_read;
1202
  JTAGProxyChainResponse resp_chain;
1203 139 chris
  JTAGProxyBlockWriteMessage *msg_bwrite;
1204
  JTAGProxyBlockReadMessage msg_bread;
1205
  JTAGProxyBlockWriteResponse resp_bwrite;
1206
  JTAGProxyBlockReadResponse *resp_bread;
1207 127 chris
  char *buf;
1208
  unsigned long long data;
1209 139 chris
  int err = 0;
1210 127 chris
  uint32_t command,length;
1211 139 chris
  int len,i;
1212 127 chris
 
1213
  /* First, we must read the incomming command */
1214
  if(gdb_read(&command,sizeof(uint32_t)) < 0)
1215
    {
1216
      if(gdb_fd)
1217
        {
1218
          perror("gdb socket - 1");
1219
          close(gdb_fd);
1220
          gdb_fd = 0;
1221
        }
1222
      return;
1223
    }
1224
  if(gdb_read(&length,sizeof(uint32_t)) < 0)
1225
    {
1226
      if(gdb_fd)
1227
        {
1228
          perror("gdb socket - 2");
1229
          close(gdb_fd);
1230
          gdb_fd = 0;
1231
        }
1232
      return;
1233
    }
1234
  length = ntohl(length);
1235
 
1236
  /* Now, verify the protocol and implement the command */
1237
  switch(ntohl(command))
1238
    {
1239
    case JTAG_COMMAND_WRITE:
1240
      if(length != sizeof(msg_write) - 8)
1241
        {
1242
          ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
1243
          return;
1244
        }
1245
      buf = (char*)&msg_write;
1246
      if(gdb_read(&buf[8],length) < 0)
1247
        {
1248
          if(gdb_fd)
1249
            {
1250
              perror("gdb socket - 3");
1251
              close(gdb_fd);
1252
              gdb_fd = 0;
1253
            }
1254
          return;
1255
        }
1256
      msg_write.address = ntohl(msg_write.address);
1257
      msg_write.data_H = ntohl(msg_write.data_H);
1258
      msg_write.data_L = ntohl(msg_write.data_L);
1259
      err = DebugSetRegister(msg_write.address,msg_write.data_L);
1260
      resp_write.status = htonl(err);
1261
      if(gdb_write(&resp_write,sizeof(resp_write)) < 0)
1262
        {
1263
          if(gdb_fd)
1264
            {
1265
              perror("gdb socket - 4");
1266
              close(gdb_fd);
1267
              gdb_fd = 0;
1268
            }
1269
          return;
1270
        }
1271
      break;
1272
    case JTAG_COMMAND_READ:
1273
      if(length != sizeof(msg_read) - 8)
1274
        {
1275
          ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
1276
          return;
1277
        }
1278
      buf = (char*)&msg_read;
1279
      if(gdb_read(&buf[8],length) < 0)
1280
        {
1281
          if(gdb_fd)
1282
            {
1283
              perror("gdb socket - 5");
1284
              close(gdb_fd);
1285
              gdb_fd = 0;
1286
            }
1287
          return;
1288
        }
1289
      msg_read.address = ntohl(msg_read.address);
1290
      err = DebugGetRegister(msg_read.address,&resp_read.data_L);
1291
      resp_read.status = htonl(err);
1292
      resp_read.data_H = 0;
1293
      resp_read.data_L = htonl(resp_read.data_L);
1294
      if(gdb_write(&resp_read,sizeof(resp_read)) < 0)
1295
        {
1296
          if(gdb_fd)
1297
            {
1298
              perror("gdb socket - 6");
1299
              close(gdb_fd);
1300
              gdb_fd = 0;
1301
            }
1302
          return;
1303
        }
1304
      break;
1305 139 chris
    case JTAG_COMMAND_BLOCK_WRITE:
1306
      if(length < sizeof(JTAGProxyBlockWriteMessage)-8)
1307
        {
1308
          ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
1309
          return;
1310
        }
1311
      if(!(buf = (char*)malloc(8+length)))
1312
        {
1313
          ProtocolClean(length,JTAG_PROXY_OUT_OF_MEMORY);
1314
          return;
1315
        }
1316
      msg_bwrite = (JTAGProxyBlockWriteMessage*)buf;
1317
      if(gdb_read(&buf[8],length) < 0)
1318
        {
1319
          if(gdb_fd)
1320
            {
1321
              perror("gdb socket - 5");
1322
              close(gdb_fd);
1323
              gdb_fd = 0;
1324
            }
1325
          free(buf);
1326
          return;
1327
        }
1328
      msg_bwrite->address = ntohl(msg_bwrite->address);
1329
      msg_bwrite->nRegisters = ntohl(msg_bwrite->nRegisters);
1330
      for(i=0;i<msg_bwrite->nRegisters;i++)
1331
        {
1332
          int t_err;
1333
 
1334
          msg_bwrite->data[i] = ntohl(msg_bwrite->data[i]);
1335
          t_err = DebugSetRegister(msg_bwrite->address+i,msg_bwrite->data[i]);
1336
          err = err ? err : t_err;
1337
        }
1338
      resp_bwrite.status = htonl(err);
1339
      free(buf);
1340
      buf = msg_bwrite = NULL;
1341
      if(gdb_write(&resp_bwrite,sizeof(resp_bwrite)) < 0)
1342
        {
1343
          if(gdb_fd)
1344
            {
1345
              perror("gdb socket - 4");
1346
              close(gdb_fd);
1347
              gdb_fd = 0;
1348
            }
1349
          return;
1350
        }
1351
      break;
1352
    case JTAG_COMMAND_BLOCK_READ:
1353
      if(length != sizeof(msg_bread) - 8)
1354
        {
1355
          ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
1356
          return;
1357
        }
1358
      buf = (char*)&msg_bread;
1359
      if(gdb_read(&buf[8],length) < 0)
1360
        {
1361
          if(gdb_fd)
1362
            {
1363
              perror("gdb socket - 5");
1364
              close(gdb_fd);
1365
              gdb_fd = 0;
1366
            }
1367
          return;
1368
        }
1369
      msg_bread.address = ntohl(msg_bread.address);
1370
      msg_bread.nRegisters = ntohl(msg_bread.nRegisters);
1371
      len = sizeof(JTAGProxyBlockReadResponse) + 4*(msg_bread.nRegisters-1);
1372
      if(!(buf = (char*)malloc(len)))
1373
        {
1374
          ProtocolClean(0,JTAG_PROXY_OUT_OF_MEMORY);
1375
          return;
1376
        }
1377
      resp_bread = (JTAGProxyBlockReadResponse*)buf;
1378
      for(i=0;i<msg_bread.nRegisters;i++)
1379
        {
1380
          int t_err;
1381
 
1382
          t_err = DebugGetRegister(msg_bread.address+i,&resp_bread->data[i]);
1383
          resp_bread->data[i] = htonl(resp_bread->data[i]);
1384
          err = err ? err : t_err;
1385
        }
1386
      resp_bread->status = htonl(err);
1387
      resp_bread->nRegisters = htonl(msg_bread.nRegisters);
1388
      if(gdb_write(resp_bread,len) < 0)
1389
        {
1390
          if(gdb_fd)
1391
            {
1392
              perror("gdb socket - 6");
1393
              close(gdb_fd);
1394
              gdb_fd = 0;
1395
            }
1396
          free(buf);
1397
          return;
1398
        }
1399
      free(buf);
1400
      buf = resp_bread = NULL;
1401
      break;
1402 127 chris
    case JTAG_COMMAND_CHAIN:
1403
      if(length != sizeof(msg_chain) - 8)
1404
        {
1405
          ProtocolClean(length,JTAG_PROXY_PROTOCOL_ERROR);
1406
          return;
1407
        }
1408
      buf = (char*)&msg_chain;
1409
      if(gdb_read(&buf[8],sizeof(msg_chain)-8) < 0)
1410
        {
1411
          if(gdb_fd)
1412
            {
1413
              perror("gdb socket - 7");
1414
              close(gdb_fd);
1415
              gdb_fd = 0;
1416
            }
1417
          return;
1418
        }
1419
      msg_chain.chain = htonl(msg_chain.chain);
1420
      err = DebugSetChain(msg_chain.chain);
1421
      resp_chain.status = htonl(err);
1422
      if(gdb_write(&resp_chain,sizeof(resp_chain)) < 0)
1423
        {
1424
          if(gdb_fd)
1425
            {
1426
              perror("gdb socket - 8");
1427
              close(gdb_fd);
1428
              gdb_fd = 0;
1429
            }
1430
          return;
1431
        }
1432
      break;
1433
    default:
1434
      ProtocolClean(length,JTAG_PROXY_COMMAND_NOT_IMPLEMENTED);
1435
      break;
1436
    }
1437 123 markom
}
1438 127 chris
 
1439
void ProtocolClean(int length,int32_t err)
1440
{
1441
  char buf[4096];
1442
 
1443
  err = htonl(err);
1444
  if((gdb_read(buf,length) < 0) ||
1445
      (gdb_write(&err,sizeof(err)) < 0) && gdb_fd)
1446
    {
1447
      perror("gdb socket - 9");
1448
      close(gdb_fd);
1449
      gdb_fd = 0;
1450
    }
1451
}
1452
 
1453
static int gdb_write(void* buf,int len)
1454
{
1455
  int n;
1456
  char* w_buf = (char*)buf;
1457
  struct pollfd block;
1458
 
1459
  while(len)
1460
    {
1461
      if((n = write(gdb_fd,w_buf,len)) < 0)
1462
        {
1463
          switch(errno)
1464
            {
1465
            case EWOULDBLOCK: /* or EAGAIN */
1466
              /* We've been called on a descriptor marked
1467
                 for nonblocking I/O. We better simulate
1468
                 blocking behavior. */
1469
              block.fd = gdb_fd;
1470
              block.events = POLLOUT;
1471
              block.revents = 0;
1472
              poll(&block,1,-1);
1473
              continue;
1474
            case EINTR:
1475
              continue;
1476
            case EPIPE:
1477
              close(gdb_fd);
1478
              gdb_fd = 0;
1479
              return -1;
1480
            default:
1481
              return -1;
1482
            }
1483
        }
1484
      else
1485
        {
1486
          len -= n;
1487
          w_buf += n;
1488
        }
1489
    }
1490
  return 0;
1491
}
1492
 
1493
static int gdb_read(void* buf,int len)
1494
{
1495
  int n;
1496
  char* r_buf = (char*)buf;
1497
  struct pollfd block;
1498
 
1499
  while(len)
1500
    {
1501
      if((n = read(gdb_fd,r_buf,len)) < 0)
1502
        {
1503
          switch(errno)
1504
            {
1505
            case EWOULDBLOCK: /* or EAGAIN */
1506
              /* We've been called on a descriptor marked
1507
                 for nonblocking I/O. We better simulate
1508
                 blocking behavior. */
1509
              block.fd = gdb_fd;
1510
              block.events = POLLIN;
1511
              block.revents = 0;
1512
              poll(&block,1,-1);
1513
              continue;
1514
            case EINTR:
1515
              continue;
1516
            default:
1517
              return -1;
1518
            }
1519
        }
1520
      else if(n == 0)
1521
        {
1522
          close(gdb_fd);
1523
          gdb_fd = 0;
1524
          return -1;
1525
        }
1526
      else
1527
        {
1528
          len -= n;
1529
          r_buf += n;
1530
        }
1531
    }
1532
  return 0;
1533
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.