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 257

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

powered by: WebSVN 2.1.0

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