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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_62/] [or1ksim/] [sim-cmd.c] - Blame information for rev 1375

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

Line No. Rev Author Line
1 1353 nogj
/* sim-cmd.c -- Simulator command parsing
2
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
3
   Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
4
 
5
This file is part of OpenRISC 1000 Architectural Simulator.
6
 
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 2 of the License, or
10
(at your option) any later version.
11
 
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
 
21
 
22
#include <stdio.h>
23
#include <string.h>
24
#include <ctype.h>
25
#include <unistd.h>
26
 
27
#include "config.h"
28
 
29
#ifdef HAVE_LIBREADLINE
30
#include <readline/readline.h>
31
#include <readline/history.h>
32
#endif /* HAVE_LIBREADLINE */
33
 
34
#ifdef HAVE_INTTYPES_H
35
#include <inttypes.h>
36
#endif
37
 
38
#include "port.h"
39
#include "arch.h"
40
#include "abstract.h"
41
#include "labels.h"
42
#include "opcode/or32.h"
43
#include "mprofiler.h"
44
#include "profiler.h"
45
#include "sim-config.h"
46
#include "dumpverilog.h"
47
#include "execute.h"
48
#include "debug_unit.h"
49
#include "debug.h"
50
#include "trace.h"
51
#include "stats.h"
52
#include "cuc.h"
53
#include "gdbcomm.h"
54
 
55
/* FIXME: These *really* need to be cleaned up */
56
#include "sprs.h"
57
#include "immu.h"
58
#include "dmmu.h"
59
#include "icache_model.h"
60
#include "dcache_model.h"
61
#include "branch_predict.h"
62
 
63 1363 nogj
struct sim_stat {
64
  void (*stat_func)(void *dat);
65
  void *dat;
66
  struct sim_stat *next;
67
};
68
 
69
static struct sim_stat *sim_stats = NULL;
70
 
71
/* Registers a status printing callback */
72
void reg_sim_stat(void (*stat_func)(void *dat), void *dat)
73
{
74
  struct sim_stat *new = malloc(sizeof(struct sim_stat));
75
 
76
  if(!new) {
77
    fprintf(stderr, "reg_sim_stat: Out-of-memory\n");
78
    exit(1);
79
  }
80
 
81
  new->stat_func = stat_func;
82
  new->dat = dat;
83
  new->next = sim_stats;
84
  sim_stats = new;
85
}
86
 
87 1353 nogj
extern char *disassembled;
88
static void debugmem( oraddr_t from, oraddr_t to )
89
{
90
  int i;
91
  PRINTF("starting to dump mem...\n");
92
  for(i=from; i<to; ) {
93
    struct label_entry *entry;
94
    unsigned int _insn;
95
    PRINTF("i=%x :: ", i);
96
 
97
    if (verify_memoryarea(i) && (entry = get_label(i)))
98
      PRINTF("label: %s |", entry->name);
99
 
100
    iqueue[0].insn = _insn = evalsim_mem32(i);
101
    iqueue[0].insn_index = insn_decode(_insn);
102
    disassemble_insn (_insn);
103
    PRINTF("%08x %s\n", _insn, disassembled);
104
    i += insn_len( iqueue[0].insn_index );
105
  }
106
}
107
 
108
static int sim_cmd_quit(int argc, char **argv) /* quit */
109
{
110
  PRINTF ("\n");
111
  sim_done();
112
  return 0;
113
}
114
 
115
static int sim_cmd_help(int argc, char **argv) /* help */
116
{
117
  PRINTF("q      - quit simulator\n");
118
  PRINTF("r      - display all registers\n");
119
  PRINTF("t      - execute next instruction\n");
120
  PRINTF("run <instructions> [<hush>]   - execute <instruction> instructions, no reg dump if hush\n");
121
  PRINTF("pr <r> <value>                - patch register <r> with <value>\n");
122
  PRINTF("dm <fromaddr> [<toaddr>]      - display memory from <fromaddr> to <toaddr>\n");
123
  PRINTF("de <fromaddr> [<toaddr>]      - debug insn memory\n");
124
  PRINTF("pm <addr> <value>             - patch memory location <addr> with <value>\n");
125
  PRINTF("pc <value>                    - patch PC register with <value>\n");
126
  PRINTF("cm <fromaddr> <toaddr> <size> - copy memory\n");
127
  PRINTF("break <addr>      - toggle breakpoint at address <addr>\n");
128
  PRINTF("breaks            - print all set breakpoints\n");
129
  PRINTF("reset             - simulator reset\n");
130
  PRINTF("hist              - execution history\n");
131
  PRINTF("stall             - stalls the processor and gives control to the debugger\n");
132
  PRINTF("stats <num|clear> - execution statistics num or clear it.\n");
133
  PRINTF("info              - configuration info (caches etc.)\n");
134
  PRINTF("dv <fromaddr> [<toaddr>] [<modname>] - dumps memory as verilog (use redirect)\n");
135
  PRINTF("dh <fromaddr> [<toaddr>]             - dumps memory as hex code (use redirect)\n");
136
  PRINTF("<cmd> > <filename> - redirect simulator stdout to <filename> (and not emulated PRINTF)\n");
137
  PRINTF("set <section> <item> = <param>  - set configuration.  See sim.cfg for more information.\n");
138
  PRINTF("debug      - toggles simulator debug mode\n");
139
  mp_help ();
140
  prof_help ();
141
  PRINTF("cuc        - enters Custom Unit Compiler command prompt\n");
142
  PRINTF("help       - available commands (this list)\n");
143
  return 0;
144
}
145
 
146
static int sim_cmd_trace(int argc, char **argv) /* trace */
147
{
148
  runtime.sim.cont_run = 1;
149
  return 1;
150
}
151
 
152
static int sim_cmd_dm(int argc, char **argv) /* dump memory */
153
{
154
  static oraddr_t from = 0, to = 0;
155
 
156
  if(argc >= 2) {
157
    if(argv[1][0] == '_')
158
      from = eval_label(argv[1]);
159
    else
160
      from = strtoul(argv[1], NULL, 0);
161
    to = from + 0x40;
162
  }
163
  if(argc >= 3)
164
    to = strtoul(argv[2], NULL, 0);
165
  dumpmemory(from, to, 0, 1);
166
  PRINTF("\n");
167
  return 0;
168
}
169
 
170
static int sim_cmd_dv(int argc, char **argv) /* dump memory as verilog*/
171
{
172
  static oraddr_t from = 0, to = 0;
173
 
174
  if(argc >= 2) {
175
    if(argv[1][0] == '_')
176
      from = eval_label(argv[1]);
177
    else
178
      from = strtoul(argv[1], NULL, 0);
179
    to = from + 0x40;
180
  }
181
  if(argc >= 3)
182
    to = strtoul(argv[2], NULL, 0);
183
 
184
  if(argc < 4)
185
    dumpverilog("or1k_mem", from, to);
186
  else
187
    dumpverilog(argv[3], from, to);
188
 
189
  PRINTF("\n");
190
  return 0;
191
}
192
 
193
static int sim_cmd_dh(int argc, char **argv) /* dump memory as hex*/
194
{
195
  static oraddr_t from = 0, to = 0;
196
 
197
  if(argc >= 2) {
198
    if(argv[1][0] == '_')
199
      from = eval_label(argv[1]);
200
    else
201
      from = strtoul(argv[1], NULL, 0);
202
    to = from + 0x40;
203
  }
204
  if(argc >= 3)
205
    to = strtoul(argv[2], NULL, 0);
206
 
207
  dumphex(from, to);
208
  PRINTF("\n");
209
  return 0;
210
}
211
 
212
static int sim_cmd_pm(int argc, char **argv) /* patch memory */
213
{
214
  static oraddr_t addr = 0;
215
  int breakpoint = 0;
216
 
217
  if(argc != 3) {
218
    PRINTF("pm <address> <value>\n");
219
    return 0;
220
  }
221
 
222
  if(argc >= 2) {
223
    if (argv[1][0] == '_')
224
      addr = eval_label(argv[1]);
225
    else
226
      addr = strtoul(argv[1], NULL, 0);
227
  }
228
  set_mem32(addr, strtoul(argv[2], NULL, 0), &breakpoint);
229
  return 0;
230
}
231
 
232
static int sim_cmd_cm(int argc, char **argv) /* copy memory 2004-01-20 hpanther*/
233
{
234
  static oraddr_t from = 0, to = 0;
235
  static unsigned int size = 0;
236
  int i;
237
 
238
  if(argc >= 2) {
239
    if (argv[1][0] == '_')
240
      from = eval_label(argv[1]);
241
    else
242
      from = strtoul(argv[1], NULL, 0);
243
  }
244
 
245
  if(argc >= 3) {
246
    if (argv[2][0] == '_')
247
      to = eval_label(argv[2]);
248
    else
249
      to = strtoul(argv[2], NULL, 0);
250
  }
251
 
252
  if(argc >= 4) {
253
    if (argv[3][0] == '_')
254
      size = eval_label(argv[3]);
255
    else
256
      size = strtoul(argv[3], NULL, 0);
257
  }
258
 
259
  for(i = 0; i < size; i += 4)
260
    setsim_mem32(to + i, evalsim_mem32(from + i));
261
  return 0;
262
}
263
 
264
static int sim_cmd_pr(int argc, char **argv) /* patch regs */
265
{
266
  if(argc != 3) {
267
    PRINTF("pr <register> <value>\n");
268
    return 0;
269
  }
270
  setsim_reg(strtoul(argv[1], NULL,0), strtoul(argv[2], NULL, 0));
271
  return 0;
272
}
273
 
274
static int sim_cmd_pc(int argc, char **argv) /* patch PC */
275
{
276
  if(argc != 2) {
277
    PRINTF("pc <value>\n");
278
    return 0;
279
  }
280
 
281
  pc = strtoul(argv[1], NULL, 0);
282
  pcnext = pc + 4;
283
  return 0;
284
}
285
 
286
static int sim_cmd_breaks(int argc, char **argv) /* print breakpoints */
287
{
288
  print_breakpoints();
289
  return 0;
290
}
291
 
292
static int sim_cmd_break(int argc, char **argv) /* set/clear breakpoint */
293
{
294
  char *p;
295
  oraddr_t addr;
296
  struct label_entry *l;
297
 
298
  if(argc != 2) {
299
    PRINTF("break <label or address>\n");
300
    return 0;
301
  }
302
 
303
  addr = strtoul(argv[1], &p, 0);
304
  if(*p) {
305
    l = find_label(argv[1]);
306
    if(l)
307
      addr = l->addr;
308
    else
309
      PRINTF("Label `%s' does not exist\n", l->name);
310
  }
311
  set_insnbrkpoint(addr);
312
  return 0;
313
}
314
 
315
static int sim_cmd_r(int argc, char **argv) /* dump regs */
316
{
317
  dumpreg();
318
  return 0;
319
}
320
 
321
static int sim_cmd_de(int argc, char **argv) /* disassemble */
322
{
323
  static oraddr_t from = 0, to = 0;
324
 
325
  if(argc >= 2) {
326
    if (argv[1][0] == '_')
327
      from = eval_label(argv[1]);
328
    else
329
      from = strtoul(argv[1], NULL, 0);
330
    to = from + 0x40;
331
  }
332
 
333
  if(argc >= 3)
334
    to = strtoul(argv[2], NULL, 0);
335
 
336
  debugmem(from, to);
337
  PRINTF("\n");
338
  return 0;
339
}
340
 
341
static int sim_cmd_reset(int argc, char **argv) /* reset simulator */
342
{
343
  sim_reset();
344
  return 0;
345
}
346
 
347
static int sim_cmd_hist(int argc, char **argv) /* dump history */
348
{
349
  int i;
350
  struct hist_exec *cur;
351
  if(!config.sim.history) {
352
    PRINTF("Simulation history disabled.\n");
353
    return 0;
354
  }
355
  for(i = HISTEXEC_LEN, cur = hist_exec_tail->prev; i; i--, cur = cur->prev)
356
    dumpmemory(cur->addr, cur->addr + 4, 1, 1);
357
  PRINTF("\n");
358
  return 0;
359
}
360
 
361
static int sim_cmd_run(int argc, char **argv) /* run */
362
{
363
  if(argc >= 3) {
364
    if(!strcmp(argv[2], "hush"))
365
      runtime.sim.hush = 1;
366
    else
367
      runtime.sim.hush = 0;
368
  }
369
 
370
  if(argc >= 2)
371
    runtime.sim.cont_run = strtol(argv[1], NULL, 0);
372
  else
373
    runtime.sim.cont_run = 0;
374
  return 1;
375
}
376
 
377
static int sim_cmd_stall(int argc, char **argv) /* Added by CZ 210801 */
378
{
379
  set_stall_state (1);
380
  runtime.sim.iprompt = 0;
381
  runtime.sim.cont_run = -1;
382
  runtime.sim.hush = 1;
383
  return 1;
384
}
385
 
386
static int sim_cmd_stats(int argc, char **argv) /* stats */
387
{
388
  if(argc != 2) {
389
    PRINTF("stats <stat no. or `clear'>\n");
390
    return 0;
391
  }
392
 
393
  if(strcmp(argv[1], "clear") == 0) {
394
    initstats();
395
    PRINTF("Cleared.\n");
396
  } else {
397
    printstats(strtoul(argv[1], NULL, 0));
398
  }
399
  return 0;
400
}
401
 
402
static int sim_cmd_info(int argc, char **argv) /* configuration info */
403
{
404 1363 nogj
  struct sim_stat *cur_stat = sim_stats;
405
 
406 1353 nogj
  /* Display info about various modules */
407
  sprs_status();
408
  PRINTF ("\n");
409
  memory_table_status ();
410
  if (config.immu.enabled) itlb_status(-1);
411
  if (config.dmmu.enabled) dtlb_status(-1);
412
  if (config.ic.enabled) ic_info();
413
  if (config.dc.enabled) dc_info();
414
 
415
  if (config.bpb.enabled) bpb_info();
416
  if (config.bpb.btic) btic_info();
417
 
418 1363 nogj
  while(cur_stat) {
419
    cur_stat->stat_func(cur_stat->dat);
420
    cur_stat = cur_stat->next;
421
  }
422
 
423 1353 nogj
  return 0;
424
}
425
 
426
static int sim_cmd_debug(int argc, char **argv) /* debug mode */
427
{
428
  config.sim.debug ^= 1;
429
  return 0;
430
}
431
 
432
static int sim_cmd_profile(int argc, char **argv) /* run profiler utility */
433
{
434
  main_profiler(argc, argv);
435
  return 0;
436
}
437
 
438
static int sim_cmd_mprofile(int argc, char **argv) /* run mprofiler utility */
439
{
440
  main_mprofiler(argc, argv);
441
  return 0;
442
}
443
 
444
static int sim_cmd_cuc(int argc, char **argv) /* run Custom Unit Compiler */
445
{
446
  main_cuc(runtime.sim.filename);
447
  return 0;
448
}
449
 
450
static int sim_cmd_set(int argc, char **argv) /* configuration info */
451
{
452
  set_config_command(argc, argv);
453
  return 0;
454
}
455
 
456
static char *strip_space(char *str)
457
{
458
  while(isblank(*str) && *str) str++;
459
  return str;
460
}
461
 
462
struct sim_command {
463
  const char *name;
464
  int (*cmd_handle)(int argc, char **argv);
465
};
466
 
467
static const struct sim_command sim_commands[] = {
468
 { "q", sim_cmd_quit },
469
 { "help", sim_cmd_help },
470
 { "t", sim_cmd_trace },
471
 { "dm", sim_cmd_dm },
472
 { "dv", sim_cmd_dv },
473
 { "dh", sim_cmd_dh },
474
 { "pm", sim_cmd_pm },
475
 { "cm", sim_cmd_cm },
476
 { "pr", sim_cmd_pr },
477
 { "pc", sim_cmd_pc },
478
 { "breaks", sim_cmd_breaks },
479
 { "break", sim_cmd_break },
480
 { "r", sim_cmd_r },
481
 { "de", sim_cmd_de },
482
 { "reset", sim_cmd_reset },
483
 { "hist", sim_cmd_hist },
484
 { "stall", sim_cmd_stall },
485
 { "stats", sim_cmd_stats },
486
 { "info", sim_cmd_info },
487
 { "run", sim_cmd_run },
488
 { "debug", sim_cmd_debug },
489
 { "profile", sim_cmd_profile },
490
 { "mprofile", sim_cmd_mprofile },
491
 { "cuc", sim_cmd_cuc },
492
 { "set", sim_cmd_set },
493
 { NULL, NULL } };
494
 
495
#ifdef HAVE_LIBREADLINE
496
static void initialize_readline(void);
497
#endif
498
 
499
void handle_sim_command(void)
500
{
501
  char *redirstr;
502
  int argc;
503
  char *argv[5];
504
  char *cur_arg;
505
  const struct sim_command *cur_cmd;
506
#ifdef HAVE_LIBREADLINE
507
  static char *prev_str = NULL;
508
#else
509
  char b2[500];
510
  static char prev_str[500] = { 0 };
511
#endif
512
 
513
#ifdef HAVE_LIBREADLINE
514
  initialize_readline (); /* Bind our completer. */
515
#endif
516
 
517
  for(;;) {
518
#ifdef HAVE_LIBREADLINE
519
    cur_arg = readline("(sim) ");
520
#else
521
    PRINTF("(sim) ");
522
    if(config.debug.gdb_enabled) {
523
      fflush(stdout);
524
      HandleServerSocket(true);  /* block & check_stdin = true */
525
    }
526
 
527
    cur_arg = fgets(b2, sizeof(b2), stdin);
528
 
529
    if (!*cur_arg) {
530
      usleep(1000);
531
      continue;
532
    }
533
#endif
534
 
535
#ifdef HAVE_LIBREADLINE
536
    if(!*cur_arg) {
537
      if(prev_str) {
538
        free(cur_arg);
539
        cur_arg = prev_str;
540
      }
541
    } else {
542
      prev_str = cur_arg;
543
      add_history(cur_arg);
544
    }
545
#else
546
    cur_arg = strip_space(cur_arg);
547
    if(*cur_arg == '\n')
548
      strcpy(cur_arg, prev_str);
549
    else
550
      strcpy(prev_str, cur_arg);
551
#endif
552
 
553
    if((redirstr = strchr(cur_arg, '>'))) {
554
      redirstr = strip_space(++redirstr);
555
 
556
      while(!isspace(*redirstr) && *redirstr) redirstr++;
557
      *redirstr = '\0';
558
 
559
      redirstr = strchr(cur_arg, '>');
560
      *redirstr = '\0';
561
 
562
      redirstr = strip_space(++redirstr);
563
      runtime.sim.fout = fopen(redirstr, "w+");
564
      if (!runtime.sim.fout) runtime.sim.fout = stdout;
565
    }
566
 
567
    if(*cur_arg) {
568
      argc = 0;
569
      while(*cur_arg) {
570
        argv[argc] = cur_arg;
571
        argc++;
572
        while(!isspace(*cur_arg) && *cur_arg) cur_arg++;
573
        if(*cur_arg) {
574
          *cur_arg = '\0';
575
          cur_arg = strip_space(cur_arg + 1);
576
        } else
577
          *cur_arg = '\0';
578
        if(argc == 5) {
579
          fprintf(stderr, "Too many arguments given to command `%s'\n", argv[0]);
580
          break;
581
        }
582
      }
583
 
584
      for(cur_cmd = sim_commands; cur_cmd->name; cur_cmd++) {
585
        if(!strcmp(cur_cmd->name, argv[0])) {
586
          if(cur_cmd->cmd_handle(argc, argv))
587
            return;
588
          break;
589
        }
590
      }
591
 
592
      if(!cur_cmd->name)
593
        PRINTF("%s: Unknown command.\n", argv[0]);
594
    }
595
  }
596
}
597
 
598
#ifdef HAVE_LIBREADLINE
599
 
600
int check_gdb_comm(void)
601
{
602
  HandleServerSocket(true);  /* block & check_stdin = true */
603
  return 0;
604
}
605
 
606
char *command_generator();
607
char **sim_completion();
608
 
609
/* Tell the GNU readline library how to complete.  We want to try to complete
610
   on command names if this is the first word in the line, or on filenames
611
   if not. */
612
static void initialize_readline(void)
613
{
614
  /* Allow conditional parsing of the ~/.inputrc file. */
615
  rl_readline_name = "or1ksim";
616
 
617
  /* Tell the completer that we want a crack first. */
618
  rl_attempted_completion_function = sim_completion;
619
 
620
  /* Handle the gdb socket while waiting for input */
621
  rl_event_hook = check_gdb_comm;
622
}
623
 
624
/* Attempt to complete on the contents of TEXT.  START and END bound the
625
   region of rl_line_buffer that contains the word to complete.  TEXT is
626
   the word to complete.  We can use the entire contents of rl_line_buffer
627
   in case we want to do some simple parsing.  Return the array of matches,
628
   or NULL if there aren't any. */
629
/* FIXME: Handle arguments to the `set' command */
630
char **sim_completion(char *text, int start, int end)
631
{
632
  char **matches;
633
 
634
  matches = NULL;
635
 
636
  /* If this word is at the start of the line, then it is a command
637
     to complete.  Otherwise it is the name of a file in the current
638
     directory. */
639
  if(!start)
640
    matches = rl_completion_matches(text, command_generator);
641
 
642
  return matches;
643
}
644
 
645
/* Generator function for command completion.  STATE lets us know whether
646
   to start from scratch; without any state (i.e. STATE == 0), then we
647
   start at the top of the list. */
648
char *command_generator(char *text, int state)
649
{
650
  static int list_index, len;
651
  const char *name;
652
 
653
  /* If this is a new word to complete, initialize now.  This includes
654
     saving the length of TEXT for efficiency, and initializing the index
655
     variable to 0. */
656
  if(!state) {
657
    list_index = 0;
658
    len = strlen(text);
659
  }
660
 
661
  /* Return the next name which partially matches from the command list. */
662
  while((name = sim_commands[list_index].name)) {
663
    list_index++;
664
 
665
    if(strncmp(name, text, len) == 0)
666
      return strdup(name);
667
  }
668
 
669
  /* If no names matched, then return NULL. */
670
  return NULL;
671
}
672
 
673
/* Repeats the last command.  */
674
char *repeat_last_command ()
675
{
676
  int offset = where_history ();
677
  HIST_ENTRY *hist;
678
 
679
  if((hist = history_get(offset)))
680
    return strdup(hist->line);
681
  return 0;
682
}
683
 
684
#endif
685
 

powered by: WebSVN 2.1.0

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