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

Subversion Repositories or1k

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

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
 
33 16 jrydberg
#ifdef HAVE_LIBREADLINE
34 7 jrydberg
#include <readline/readline.h>
35
#include <readline/history.h>
36 16 jrydberg
#endif /* HAVE_LIBREADLINE */
37 7 jrydberg
 
38 2 cvs
#include "arch.h"
39
#include "parse.h"
40
#include "abstract.h"
41
#include "trace.h"
42
#include "execute.h"
43 69 lampret
#include "sim-config.h"
44 2 cvs
 
45 28 lampret
#include "coff.h"
46
 
47 2 cvs
/* CVS revision number. */
48 86 lampret
const char rcsrev[] = "$Revision: 1.13 $";
49 2 cvs
 
50
/* Continuos run versus single step tracing switch. */
51
int cont_run;
52
 
53
/* History of execution */
54
int histexec[HISTEXEC_LEN];
55
 
56 7 jrydberg
char *sim_commands [] = {
57
  "q",
58
  "t",
59
  "help",
60 21 cmchen
  "de",
61 7 jrydberg
  "dm",
62
  "run",
63
  "pr",
64
  "pm",
65
  "pc",
66 18 lampret
  "reset",
67
  "break",
68 7 jrydberg
  "hist",
69
  "stats",
70
  "info",
71
  "r",
72 54 lampret
  "dv",
73 7 jrydberg
 
74
};
75
 
76 2 cvs
void debug(const char *format, ...)
77
{
78 7 jrydberg
  char *p;
79
  va_list ap;
80 2 cvs
 
81 69 lampret
  if (config.simdebug) {
82
    if ((p = malloc(1000)) == NULL)
83
      return;
84
    va_start(ap, format);
85
    (void) vsnprintf(p, 1000, format, ap);
86
    va_end(ap);
87
    printf("%s\n", p);
88
    fflush(stdout);
89
    free(p);
90
  } else {
91
#if DEBUG
92 7 jrydberg
  if ((p = malloc(1000)) == NULL)
93
    return;
94
  va_start(ap, format);
95
  (void) vsnprintf(p, 1000, format, ap);
96
  va_end(ap);
97
  printf("%s\n", p);
98
  fflush(stdout);
99
  free(p);
100 2 cvs
#endif
101 69 lampret
  }
102 7 jrydberg
  return;
103 2 cvs
}
104
 
105 30 lampret
/* Strip whitespace from the start and end of STRING.  Return a pointer
106
   into STRING. */
107
#ifndef whitespace
108
#define whitespace(a)   ((a) == '\t' ? 1 : ((a) == ' '? 1 : 0))
109
#endif
110
 
111
char *
112
stripwhite (string)
113
     char *string;
114
{
115
  register char *s, *t;
116
 
117
  for (s = string; whitespace (*s); s++)
118
    ;
119
 
120
  if (*s == 0)
121
    return (s);
122
 
123
  t = s + strlen (s) - 1;
124
  while (t > s && whitespace (*t))
125
    t--;
126
  *++t = '\0';
127
 
128
  return s;
129
}
130
 
131 7 jrydberg
void
132
ctrl_c(signum)
133
     int signum;
134 2 cvs
{
135
        cont_run = 1;
136 7 jrydberg
  signal(SIGINT, ctrl_c);
137 2 cvs
}
138
 
139 7 jrydberg
void
140
version()
141 2 cvs
{
142 7 jrydberg
        printf ("\n");
143 18 lampret
        printf ("OpenRISC 1000 (OR16+OR32) Architectural Simulator, %s\n", rcsrev);
144
        printf ("Copyright (C) 1999 Damjan Lampret, lampret@opencores.org\n");
145
        printf ("Copyright (C) 2000 Damjan Lampret, lampret@opencores.org\n");
146 21 cmchen
        printf ("                   Jimmy Chen-Min Chen, jimmy@ee.nctu.edu.tw\n");
147 18 lampret
        printf ("                   Johan Rydberg, johan.rydberg@insight.se\n");
148 7 jrydberg
        printf ("Visit http://www.opencores.org for more information about ");
149
        printf ("OpenRISC 1000 and\nother open source cores.\n\n");
150
        printf ("This software comes with ABSOLUTELY NO WARRANTY; for ");
151
        printf ("details see COPYING.\nThis is free software, and you ");
152
        printf ("are welcome to redistribute it under certain\nconditions; ");
153
        printf ("for details see COPYING.\n");
154 2 cvs
}
155
 
156 7 jrydberg
void
157
help()
158 2 cvs
{
159
        printf("q                        - quit simulator\n");
160
        printf("r                        - display all registers\n");
161
        printf("t                        - execute next instruction\n");
162
        printf("run <cycles> [<hush>]    - execute <cycles> instructions, no reg dump if hush\n");
163
        printf("pr <r> <value>           - patch register <r> with <value>\n");
164
        printf("dm <fromaddr> [<toaddr>] - display memory from <fromaddr> to <toaddr>\n");
165 21 cmchen
        printf("de                       - debug insn memory\n");
166 2 cvs
        printf("pm <addr> <value>        - patch memory location <addr> with <value>\n");
167
        printf("pc <value>               - patch PC register with <value>\n");
168 18 lampret
        printf("break <addr>             - toggle breakpoint at address <addr>\n");
169
        printf("reset                    - simulator reset\n");
170 2 cvs
        printf("hist                     - execution history\n");
171 6 lampret
        printf("stats <num|clear>        - execution statistics num or clear it.\n");
172
        printf("info                     - configuration info (caches etc.)\n");
173 54 lampret
        printf("dv <fromaddr> [<toaddr>] [<modname>] - dumps memory as verilog (use redirect)\n");
174 86 lampret
        printf("dh <fromaddr> [<toaddr>] - dumps memory as hex code (use redirect)\n");
175 2 cvs
        printf("<cmd> > <filename>       - redirect simulator stdout to <filename> (and not emulated printf)\n");
176 69 lampret
        printf("debug                    - toggles simulator debug mode\n");
177 2 cvs
        printf("help                     - available commands (this list)\n");
178
}
179
 
180 21 cmchen
void debugmem();
181
 
182 7 jrydberg
main(argc, argv)
183
     int argc;
184
     char *argv[];
185 2 cvs
{
186 7 jrydberg
        char *linestr;
187 16 jrydberg
        char item1[500], b2[500];
188 2 cvs
        char *redirstr;
189
        int hush;
190 69 lampret
        unsigned long endaddr;
191 2 cvs
 
192 7 jrydberg
        if (argc != 2)
193
    {
194
      printf("Usage: %s <filename>\n", argv[0]);
195
      exit(-1);
196
    }
197
 
198 16 jrydberg
#ifdef HAVE_LIBREADLINE
199 7 jrydberg
  initialize_readline ();       /* Bind our completer. */
200 16 jrydberg
#endif  
201
 
202 46 lampret
        srand(getpid());
203 2 cvs
        version();
204 6 lampret
        init_defconfig();
205 2 cvs
        signal(SIGINT, ctrl_c);
206
        initstats();
207 69 lampret
        memset(mem, 0, sizeof(mem));
208
        endaddr = loadcode(argv[1], MEMORY_START, 0);
209
        if (endaddr == -1) {
210
                printf("Problems loading boot code.\n");
211
                exit(1);
212
        }
213 30 lampret
        uart_reset();
214 2 cvs
        reset();
215 69 lampret
        set_reg32("r3", endaddr);
216 7 jrydberg
 
217
        while(1)
218
    {
219 16 jrydberg
#ifdef HAVE_LIBREADLINE
220 7 jrydberg
      linestr = readline("(sim) ");
221 16 jrydberg
#else
222
      printf ("(sim) ");
223
      linestr = fgets(b2, sizeof b2, stdin);
224
#endif
225 7 jrydberg
 
226
      if (!linestr)
227
        {
228
          break;
229
        }
230
      linestr = stripwhite (linestr);
231
 
232 16 jrydberg
#ifdef HAVE_LIBREADLINE
233 7 jrydberg
      if (strlen(linestr) == 0)
234
        {
235
          char *l = repeat_last_command ();
236
 
237
          if (l)
238
            {
239
              free (linestr);
240
              linestr = l;
241
            }
242
        }
243
 
244
      if (*linestr)
245
        {
246
          add_history (linestr);
247
        }
248 16 jrydberg
#endif /* HAVE_LIBREADLINE */
249 2 cvs
 
250 7 jrydberg
      if (redirstr = strstr(linestr, ">"))
251
        {
252
          *redirstr = '\0';
253
          strtoken(&redirstr[1], item1, 1);
254
          freopen(item1, "w+", stdout);
255
        }
256 2 cvs
 
257
                strtoken(linestr, item1, 1);
258
                if (strcmp(item1, "q") == 0)     /* quit */
259
                        exit(0);
260
                else
261
                if (strcmp(item1, "help") == 0)  /* help */
262
                        help();
263
                else
264
                if (strcmp(item1, "t") == 0) {   /* trace */
265
                        cont_run = 1;
266
                } else
267
                if (strcmp(item1, "dm") == 0) {  /* dump memory */
268
                        char item2[20];
269
                        char item3[20];
270
                        static int from = 0, to = 0;
271
 
272
                        strtoken(linestr, item2, 2);
273
                        strtoken(linestr, item3, 3);
274
 
275
                        if (strlen(item2)) {
276
                                if (item2[0] == '_')
277
                                        from = eval_label(item2);
278
                                else
279
                                        from = strtoul(item2, NULL, 0);
280
                                to = from + 0x40;
281
                        }
282
                        if (strlen(item3))
283
                                to = strtoul(item3, NULL, 0);
284
                        dumpmemory(from, to);
285 54 lampret
                        printf("\n");
286 2 cvs
                } else
287 54 lampret
                if (strcmp(item1, "dv") == 0) {/* dump memory as verilog*/
288
                        char item2[20];
289
                        char item3[20];
290
                        char item4[20];
291
                        static int from = 0, to = 0;
292
 
293
                        strtoken(linestr, item2, 2);
294
                        strtoken(linestr, item3, 3);
295
                        strtoken(linestr, item4, 4);
296
 
297
                        if (strlen(item2)) {
298
                                if (item2[0] == '_')
299
                                        from = eval_label(item2);
300
                                else
301
                                        from = strtoul(item2, NULL, 0);
302
                                to = from + 0x40;
303
                        }
304
                        if (strlen(item3))
305
                                to = strtoul(item3, NULL, 0);
306
                        if (!strlen(item4))
307
                                strcpy(item4, "or1k_mem");
308
                        dumpverilog(item4, from, to);
309
                        printf("\n");
310
                } else
311 86 lampret
                if (strcmp(item1, "dh") == 0) {/* dump memory as hex*/
312
                        char item2[20];
313
                        char item3[20];
314
                        static int from = 0, to = 0;
315
 
316
                        strtoken(linestr, item2, 2);
317
                        strtoken(linestr, item3, 3);
318
 
319
                        if (strlen(item2)) {
320
                                if (item2[0] == '_')
321
                                        from = eval_label(item2);
322
                                else
323
                                        from = strtoul(item2, NULL, 0);
324
                                to = from + 0x40;
325
                        }
326
                        if (strlen(item3))
327
                                to = strtoul(item3, NULL, 0);
328
                        dumphex(from, to);
329
                        printf("\n");
330
                } else
331 2 cvs
                if (strcmp(item1, "pm") == 0) {  /* patch memory */
332
                        char item2[20];
333
                        char item3[20];
334
                        static int addr = 0;
335
 
336
                        strtoken(linestr, item2, 2);
337
                        strtoken(linestr, item3, 3);
338
                        if (strlen(item2))
339
                                if (item2[0] == '_')
340
                                        addr = eval_label(item2);
341
                                else
342
                                        addr = strtoul(item2, NULL, 0);
343
                        set_mem32(addr, strtoul(item3, NULL, 0));
344
                } else
345
                if (strcmp(item1, "pr") == 0) {  /* patch regs */
346
                        char item2[20];
347
                        char item3[20];
348
 
349
                        strtoken(linestr, item2, 2);
350
                        strtoken(linestr, item3, 3);
351
                        set_reg32(item2, strtoul(item3, NULL, 0));
352
                } else
353
                if (strcmp(item1, "pc") == 0) {  /* patch PC */
354
                        char item2[20];
355
 
356
                        strtoken(linestr, item2, 2);
357 86 lampret
                        pcnext = strtoul(item2, NULL, 0);
358 2 cvs
                } else
359 7 jrydberg
                if (strcmp(item1, "break") == 0) {       /* set/clear breakpoint */
360 2 cvs
                        char item2[20];
361
 
362
                        strtoken(linestr, item2, 2);
363
                        set_insnbrkpoint(strtoul(item2, NULL, 0));
364
                } else
365
                if (strcmp(item1, "r") == 0) {   /* dump regs */
366
                        dumpreg();
367
                } else
368 21 cmchen
                if (strcmp(item1, "de") == 0) {  /* reset simulator */
369
                        debugmem();
370
                } else
371 18 lampret
                if (strcmp(item1, "reset") == 0) {       /* reset simulator */
372 30 lampret
                        uart_reset();
373 18 lampret
                        reset();
374
                } else
375 69 lampret
                if (strcmp(item1, "debug") == 0) {       /* debug mode */
376
                        config.simdebug ^= 1;
377
                } else
378 2 cvs
                if (strcmp(item1, "hist") == 0) {        /* dump history */
379
                        int i;
380
                        for(i = HISTEXEC_LEN; i; i--)
381
                                dumpmemory(histexec[i - 1], histexec[i - 1] + 4);
382 46 lampret
                        printf("\n");
383 2 cvs
                } else
384
                if (strcmp(item1, "run") == 0) { /* run */
385
                        char item2[20];
386
                        char item3[20];
387
 
388
                        strtoken(linestr, item2, 2);
389
                        strtoken(linestr, item3, 3);
390
                        if (strcmp(item3, "hush") == 0)
391
                                hush = 1;
392
                        else
393
                                hush = 0;
394
                        cont_run = strtoul(item2, NULL, 0);
395
                } else
396
                if (strcmp(item1, "stats") == 0) { /* stats */
397 6 lampret
                        char item2[20];
398
                        int i = 0;
399
 
400
                        strtoken(linestr, item2, 2);
401
                        if (strcmp(item2, "clear") == 0) {
402
                                initstats();
403
                                printf("Cleared.\n");
404
                        } else {
405
                                i = strtoul(item2, NULL, 0);
406
                                printstats(i);
407
                        }
408
                } else
409
                if (strcmp(item1, "info") == 0) { /* configuration info */
410 78 lampret
                        itlb_status(-1);
411
                        dtlb_status(-1);
412 6 lampret
                        bpb_info();
413
                        btic_info();
414
                        ic_info();
415
                        dc_info();
416 30 lampret
                        uart_status();
417
                        sprs_status();
418 7 jrydberg
                } else {
419
      printf("%s: Unknown command.\n", linestr);
420
    }
421 2 cvs
 
422
                while(cont_run) {
423
                        cont_run--;
424
                        fetch();
425
                        decode(&iqueue[0]);
426
                        execute();
427 30 lampret
                        uart_clock();
428 2 cvs
                        if (!hush)
429
                                dumpreg();
430
                }
431
 
432
                hush = 0;
433
                fflush(stdout);
434
                freopen("/dev/fd/0", "w+", stdout);
435
 
436 16 jrydberg
#ifdef HAVE_LIBREADLINE
437 7 jrydberg
    if (linestr)
438
      free (linestr);
439 16 jrydberg
#endif
440 7 jrydberg
 
441 2 cvs
        }
442
        exit(0);
443
}
444 7 jrydberg
 
445 16 jrydberg
#ifdef HAVE_LIBREADLINE
446 7 jrydberg
char *command_generator ();
447
char **sim_completion ();
448
 
449
/* Tell the GNU readline library how to complete.  We want to try to complete
450
   on command names if this is the first word in the line, or on filenames
451
   if not. */
452
void initialize_readline ()
453
{
454
  /* Allow conditional parsing of the ~/.inputrc file. */
455
  rl_readline_name = "or1ksim";
456
 
457
  /* Tell the completer that we want a crack first. */
458
  rl_attempted_completion_function = (CPPFunction *)sim_completion;
459
}
460
 
461
/* Attempt to complete on the contents of TEXT.  START and END bound the
462
   region of rl_line_buffer that contains the word to complete.  TEXT is
463
   the word to complete.  We can use the entire contents of rl_line_buffer
464
   in case we want to do some simple parsing.  Return the array of matches,
465
   or NULL if there aren't any. */
466
char **
467
sim_completion (text, start, end)
468
     char *text;
469
     int start, end;
470
{
471
  char **matches;
472
 
473
  matches = (char **)NULL;
474
 
475
  /* If this word is at the start of the line, then it is a command
476
     to complete.  Otherwise it is the name of a file in the current
477
     directory. */
478
  if (start == 0)
479
    matches = completion_matches (text, command_generator);
480
 
481
  return (matches);
482
}
483
 
484
/* Generator function for command completion.  STATE lets us know whether
485
   to start from scratch; without any state (i.e. STATE == 0), then we
486
   start at the top of the list. */
487
char *
488
command_generator (text, state)
489
     char *text;
490
     int state;
491
{
492
  static int list_index, len;
493
  char *name;
494
 
495
  /* If this is a new word to complete, initialize now.  This includes
496
     saving the length of TEXT for efficiency, and initializing the index
497
     variable to 0. */
498
  if (!state)
499
    {
500
      list_index = 0;
501
      len = strlen (text);
502
    }
503
 
504
  /* Return the next name which partially matches from the command list. */
505
  while (name = sim_commands[list_index])
506
    {
507
      list_index++;
508
 
509
      if (strncmp (name, text, len) == 0)
510
        return (dupstr(name));
511
    }
512
 
513
  /* If no names matched, then return NULL. */
514
  return ((char *)NULL);
515
}
516
 
517
char *
518
dupstr (s)
519
     char *s;
520
{
521
  char *r;
522
 
523
  r = xmalloc (strlen (s) + 1);
524
  strcpy (r, s);
525
  return (r);
526
}
527
 
528
/* Repeats the last command.  */
529
char *
530
repeat_last_command ()
531
{
532
  int offset = where_history ();
533
  HIST_ENTRY *hist;
534
 
535
  if (hist = history_get (offset))
536
    {
537
      return dupstr (hist->line);
538
    }
539
  return 0;
540
}
541 16 jrydberg
 
542
#endif
543
 
544
 
545 21 cmchen
void debugmem() {
546
        int i;
547
        printf("starting to dump mem...\n");
548
        for(i=0; i<500; i++) {
549
                printf("i=%x :: ", i);
550 30 lampret
                if (mem[i].label)
551 28 lampret
                        printf("label: %s |", mem[i].label->name);
552
                printf("%s ", mem[i].insn->insn);
553
                if(strlen(mem[i].insn->op1) != 0) printf("%s ", mem[i].insn->op1);
554
                if(strlen(mem[i].insn->op2) != 0) printf("%s ", mem[i].insn->op2);
555
                if(strlen(mem[i].insn->op3) != 0) printf("%s ", mem[i].insn->op3);
556
                if(strlen(mem[i].insn->op4) != 0) printf("%s ", mem[i].insn->op4);
557 21 cmchen
                printf("\n");
558
        }
559
}

powered by: WebSVN 2.1.0

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