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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_40/] [or1ksim/] [sim-cmd.c] - Blame information for rev 1372

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

powered by: WebSVN 2.1.0

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