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 181

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

powered by: WebSVN 2.1.0

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