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

Subversion Repositories or1k

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

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

powered by: WebSVN 2.1.0

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