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

Subversion Repositories or1k

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

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

powered by: WebSVN 2.1.0

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