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

Subversion Repositories or1k

[/] [or1k/] [tags/] [stable_0_2_0_rc2/] [or1ksim/] [toplevel.c] - Blame information for rev 78

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 78 lampret
const char rcsrev[] = "$Revision: 1.12 $";
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 2 cvs
        printf("<cmd> > <filename>       - redirect simulator stdout to <filename> (and not emulated printf)\n");
175 69 lampret
        printf("debug                    - toggles simulator debug mode\n");
176 2 cvs
        printf("help                     - available commands (this list)\n");
177
}
178
 
179 21 cmchen
void debugmem();
180
 
181 7 jrydberg
main(argc, argv)
182
     int argc;
183
     char *argv[];
184 2 cvs
{
185 7 jrydberg
        char *linestr;
186 16 jrydberg
        char item1[500], b2[500];
187 2 cvs
        char *redirstr;
188
        int hush;
189 69 lampret
        unsigned long endaddr;
190 2 cvs
 
191 7 jrydberg
        if (argc != 2)
192
    {
193
      printf("Usage: %s <filename>\n", argv[0]);
194
      exit(-1);
195
    }
196
 
197 16 jrydberg
#ifdef HAVE_LIBREADLINE
198 7 jrydberg
  initialize_readline ();       /* Bind our completer. */
199 16 jrydberg
#endif  
200
 
201 46 lampret
        srand(getpid());
202 2 cvs
        version();
203 6 lampret
        init_defconfig();
204 2 cvs
        signal(SIGINT, ctrl_c);
205
        initstats();
206 69 lampret
        memset(mem, 0, sizeof(mem));
207
        endaddr = loadcode(argv[1], MEMORY_START, 0);
208
        if (endaddr == -1) {
209
                printf("Problems loading boot code.\n");
210
                exit(1);
211
        }
212 30 lampret
        uart_reset();
213 2 cvs
        reset();
214 69 lampret
        set_reg32("r3", endaddr);
215 7 jrydberg
 
216
        while(1)
217
    {
218 16 jrydberg
#ifdef HAVE_LIBREADLINE
219 7 jrydberg
      linestr = readline("(sim) ");
220 16 jrydberg
#else
221
      printf ("(sim) ");
222
      linestr = fgets(b2, sizeof b2, stdin);
223
#endif
224 7 jrydberg
 
225
      if (!linestr)
226
        {
227
          break;
228
        }
229
      linestr = stripwhite (linestr);
230
 
231 16 jrydberg
#ifdef HAVE_LIBREADLINE
232 7 jrydberg
      if (strlen(linestr) == 0)
233
        {
234
          char *l = repeat_last_command ();
235
 
236
          if (l)
237
            {
238
              free (linestr);
239
              linestr = l;
240
            }
241
        }
242
 
243
      if (*linestr)
244
        {
245
          add_history (linestr);
246
        }
247 16 jrydberg
#endif /* HAVE_LIBREADLINE */
248 2 cvs
 
249 7 jrydberg
      if (redirstr = strstr(linestr, ">"))
250
        {
251
          *redirstr = '\0';
252
          strtoken(&redirstr[1], item1, 1);
253
          freopen(item1, "w+", stdout);
254
        }
255 2 cvs
 
256
                strtoken(linestr, item1, 1);
257
                if (strcmp(item1, "q") == 0)     /* quit */
258
                        exit(0);
259
                else
260
                if (strcmp(item1, "help") == 0)  /* help */
261
                        help();
262
                else
263
                if (strcmp(item1, "t") == 0) {   /* trace */
264
                        cont_run = 1;
265
                } else
266
                if (strcmp(item1, "dm") == 0) {  /* dump memory */
267
                        char item2[20];
268
                        char item3[20];
269
                        static int from = 0, to = 0;
270
 
271
                        strtoken(linestr, item2, 2);
272
                        strtoken(linestr, item3, 3);
273
 
274
                        if (strlen(item2)) {
275
                                if (item2[0] == '_')
276
                                        from = eval_label(item2);
277
                                else
278
                                        from = strtoul(item2, NULL, 0);
279
                                to = from + 0x40;
280
                        }
281
                        if (strlen(item3))
282
                                to = strtoul(item3, NULL, 0);
283
                        dumpmemory(from, to);
284 54 lampret
                        printf("\n");
285 2 cvs
                } else
286 54 lampret
                if (strcmp(item1, "dv") == 0) {/* dump memory as verilog*/
287
                        char item2[20];
288
                        char item3[20];
289
                        char item4[20];
290
                        static int from = 0, to = 0;
291
 
292
                        strtoken(linestr, item2, 2);
293
                        strtoken(linestr, item3, 3);
294
                        strtoken(linestr, item4, 4);
295
 
296
                        if (strlen(item2)) {
297
                                if (item2[0] == '_')
298
                                        from = eval_label(item2);
299
                                else
300
                                        from = strtoul(item2, NULL, 0);
301
                                to = from + 0x40;
302
                        }
303
                        if (strlen(item3))
304
                                to = strtoul(item3, NULL, 0);
305
                        if (!strlen(item4))
306
                                strcpy(item4, "or1k_mem");
307
                        dumpverilog(item4, from, to);
308
                        printf("\n");
309
                } else
310 2 cvs
                if (strcmp(item1, "pm") == 0) {  /* patch memory */
311
                        char item2[20];
312
                        char item3[20];
313
                        static int addr = 0;
314
 
315
                        strtoken(linestr, item2, 2);
316
                        strtoken(linestr, item3, 3);
317
                        if (strlen(item2))
318
                                if (item2[0] == '_')
319
                                        addr = eval_label(item2);
320
                                else
321
                                        addr = strtoul(item2, NULL, 0);
322
                        set_mem32(addr, strtoul(item3, NULL, 0));
323
                } else
324
                if (strcmp(item1, "pr") == 0) {  /* patch regs */
325
                        char item2[20];
326
                        char item3[20];
327
 
328
                        strtoken(linestr, item2, 2);
329
                        strtoken(linestr, item3, 3);
330
                        set_reg32(item2, strtoul(item3, NULL, 0));
331
                } else
332
                if (strcmp(item1, "pc") == 0) {  /* patch PC */
333
                        char item2[20];
334
 
335
                        strtoken(linestr, item2, 2);
336
                        pctemp = strtoul(item2, NULL, 0);
337
                } else
338 7 jrydberg
                if (strcmp(item1, "break") == 0) {       /* set/clear breakpoint */
339 2 cvs
                        char item2[20];
340
 
341
                        strtoken(linestr, item2, 2);
342
                        set_insnbrkpoint(strtoul(item2, NULL, 0));
343
                } else
344
                if (strcmp(item1, "r") == 0) {   /* dump regs */
345
                        dumpreg();
346
                } else
347 21 cmchen
                if (strcmp(item1, "de") == 0) {  /* reset simulator */
348
                        debugmem();
349
                } else
350 18 lampret
                if (strcmp(item1, "reset") == 0) {       /* reset simulator */
351 30 lampret
                        uart_reset();
352 18 lampret
                        reset();
353
                } else
354 69 lampret
                if (strcmp(item1, "debug") == 0) {       /* debug mode */
355
                        config.simdebug ^= 1;
356
                } else
357 2 cvs
                if (strcmp(item1, "hist") == 0) {        /* dump history */
358
                        int i;
359
                        for(i = HISTEXEC_LEN; i; i--)
360
                                dumpmemory(histexec[i - 1], histexec[i - 1] + 4);
361 46 lampret
                        printf("\n");
362 2 cvs
                } else
363
                if (strcmp(item1, "run") == 0) { /* run */
364
                        char item2[20];
365
                        char item3[20];
366
 
367
                        strtoken(linestr, item2, 2);
368
                        strtoken(linestr, item3, 3);
369
                        if (strcmp(item3, "hush") == 0)
370
                                hush = 1;
371
                        else
372
                                hush = 0;
373
                        cont_run = strtoul(item2, NULL, 0);
374
                } else
375
                if (strcmp(item1, "stats") == 0) { /* stats */
376 6 lampret
                        char item2[20];
377
                        int i = 0;
378
 
379
                        strtoken(linestr, item2, 2);
380
                        if (strcmp(item2, "clear") == 0) {
381
                                initstats();
382
                                printf("Cleared.\n");
383
                        } else {
384
                                i = strtoul(item2, NULL, 0);
385
                                printstats(i);
386
                        }
387
                } else
388
                if (strcmp(item1, "info") == 0) { /* configuration info */
389 78 lampret
                        itlb_status(-1);
390
                        dtlb_status(-1);
391 6 lampret
                        bpb_info();
392
                        btic_info();
393
                        ic_info();
394
                        dc_info();
395 30 lampret
                        uart_status();
396
                        sprs_status();
397 7 jrydberg
                } else {
398
      printf("%s: Unknown command.\n", linestr);
399
    }
400 2 cvs
 
401
                while(cont_run) {
402
                        cont_run--;
403
                        fetch();
404
                        decode(&iqueue[0]);
405
                        execute();
406 30 lampret
                        uart_clock();
407 2 cvs
                        if (!hush)
408
                                dumpreg();
409
                }
410
 
411
                hush = 0;
412
                fflush(stdout);
413
                freopen("/dev/fd/0", "w+", stdout);
414
 
415 16 jrydberg
#ifdef HAVE_LIBREADLINE
416 7 jrydberg
    if (linestr)
417
      free (linestr);
418 16 jrydberg
#endif
419 7 jrydberg
 
420 2 cvs
        }
421
        exit(0);
422
}
423 7 jrydberg
 
424 16 jrydberg
#ifdef HAVE_LIBREADLINE
425 7 jrydberg
char *command_generator ();
426
char **sim_completion ();
427
 
428
/* Tell the GNU readline library how to complete.  We want to try to complete
429
   on command names if this is the first word in the line, or on filenames
430
   if not. */
431
void initialize_readline ()
432
{
433
  /* Allow conditional parsing of the ~/.inputrc file. */
434
  rl_readline_name = "or1ksim";
435
 
436
  /* Tell the completer that we want a crack first. */
437
  rl_attempted_completion_function = (CPPFunction *)sim_completion;
438
}
439
 
440
/* Attempt to complete on the contents of TEXT.  START and END bound the
441
   region of rl_line_buffer that contains the word to complete.  TEXT is
442
   the word to complete.  We can use the entire contents of rl_line_buffer
443
   in case we want to do some simple parsing.  Return the array of matches,
444
   or NULL if there aren't any. */
445
char **
446
sim_completion (text, start, end)
447
     char *text;
448
     int start, end;
449
{
450
  char **matches;
451
 
452
  matches = (char **)NULL;
453
 
454
  /* If this word is at the start of the line, then it is a command
455
     to complete.  Otherwise it is the name of a file in the current
456
     directory. */
457
  if (start == 0)
458
    matches = completion_matches (text, command_generator);
459
 
460
  return (matches);
461
}
462
 
463
/* Generator function for command completion.  STATE lets us know whether
464
   to start from scratch; without any state (i.e. STATE == 0), then we
465
   start at the top of the list. */
466
char *
467
command_generator (text, state)
468
     char *text;
469
     int state;
470
{
471
  static int list_index, len;
472
  char *name;
473
 
474
  /* If this is a new word to complete, initialize now.  This includes
475
     saving the length of TEXT for efficiency, and initializing the index
476
     variable to 0. */
477
  if (!state)
478
    {
479
      list_index = 0;
480
      len = strlen (text);
481
    }
482
 
483
  /* Return the next name which partially matches from the command list. */
484
  while (name = sim_commands[list_index])
485
    {
486
      list_index++;
487
 
488
      if (strncmp (name, text, len) == 0)
489
        return (dupstr(name));
490
    }
491
 
492
  /* If no names matched, then return NULL. */
493
  return ((char *)NULL);
494
}
495
 
496
char *
497
dupstr (s)
498
     char *s;
499
{
500
  char *r;
501
 
502
  r = xmalloc (strlen (s) + 1);
503
  strcpy (r, s);
504
  return (r);
505
}
506
 
507
/* Repeats the last command.  */
508
char *
509
repeat_last_command ()
510
{
511
  int offset = where_history ();
512
  HIST_ENTRY *hist;
513
 
514
  if (hist = history_get (offset))
515
    {
516
      return dupstr (hist->line);
517
    }
518
  return 0;
519
}
520 16 jrydberg
 
521
#endif
522
 
523
 
524 21 cmchen
void debugmem() {
525
        int i;
526
        printf("starting to dump mem...\n");
527
        for(i=0; i<500; i++) {
528
                printf("i=%x :: ", i);
529 30 lampret
                if (mem[i].label)
530 28 lampret
                        printf("label: %s |", mem[i].label->name);
531
                printf("%s ", mem[i].insn->insn);
532
                if(strlen(mem[i].insn->op1) != 0) printf("%s ", mem[i].insn->op1);
533
                if(strlen(mem[i].insn->op2) != 0) printf("%s ", mem[i].insn->op2);
534
                if(strlen(mem[i].insn->op3) != 0) printf("%s ", mem[i].insn->op3);
535
                if(strlen(mem[i].insn->op4) != 0) printf("%s ", mem[i].insn->op4);
536 21 cmchen
                printf("\n");
537
        }
538
}

powered by: WebSVN 2.1.0

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