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

Subversion Repositories or1k

[/] [or1k/] [tags/] [tn_m001/] [or1ksim/] [toplevel.c] - Blame information for rev 221

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

powered by: WebSVN 2.1.0

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