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

Subversion Repositories or1k

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

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

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

powered by: WebSVN 2.1.0

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