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

Subversion Repositories or1k

[/] [or1k/] [tags/] [rel-0-3-0-rc2/] [or1ksim/] [sim-cmd.c] - Blame information for rev 1364

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

powered by: WebSVN 2.1.0

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