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 1373

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

powered by: WebSVN 2.1.0

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