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

Subversion Repositories or1k

[/] [or1k/] [branches/] [stable_0_1_x/] [or1ksim/] [sim-cmd.c] - Blame information for rev 1768

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

powered by: WebSVN 2.1.0

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