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 1371

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

powered by: WebSVN 2.1.0

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