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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_49/] [or1ksim/] [sim-cmd.c] - Blame information for rev 1367

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

powered by: WebSVN 2.1.0

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