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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_67/] [or1ksim/] [sim-cmd.c] - Blame information for rev 1374

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

powered by: WebSVN 2.1.0

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