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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [or1ksim/] [sim-cmd.c] - Blame information for rev 1446

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

powered by: WebSVN 2.1.0

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