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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_67/] [or1ksim/] [sim-cmd.c] - Blame information for rev 1363

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

powered by: WebSVN 2.1.0

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