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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_69/] [or1ksim/] [sim-cmd.c] - Blame information for rev 1370

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

powered by: WebSVN 2.1.0

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