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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [or1ksim/] [sim-cmd.c] - Blame information for rev 1772

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 1748 jeremybenn
 
3 1353 nogj
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
4
   Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
5 1748 jeremybenn
   Copyright (C) 2008 Embecosm Limited
6 1353 nogj
 
7 1748 jeremybenn
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
8 1353 nogj
 
9 1748 jeremybenn
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
10 1353 nogj
 
11 1748 jeremybenn
   This program is free software; you can redistribute it and/or modify it
12
   under the terms of the GNU General Public License as published by the Free
13
   Software Foundation; either version 3 of the License, or (at your option)
14
   any later version.
15 1353 nogj
 
16 1748 jeremybenn
   This program is distributed in the hope that it will be useful, but WITHOUT
17
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
19
   more details.
20 1353 nogj
 
21 1748 jeremybenn
   You should have received a copy of the GNU General Public License along
22
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
23 1353 nogj
 
24 1748 jeremybenn
/* This program is commented throughout in a fashion suitable for processing
25
   with Doxygen. */
26
 
27
 
28
/* Autoconf and/or portability configuration */
29 1353 nogj
#include "config.h"
30
 
31 1748 jeremybenn
/* System includes */
32
#include <stdlib.h>
33
#include <unistd.h>
34
#include <stdio.h>
35
 
36 1353 nogj
#ifdef HAVE_LIBREADLINE
37
#include <readline/readline.h>
38
#include <readline/history.h>
39
#endif /* HAVE_LIBREADLINE */
40
 
41 1748 jeremybenn
/* Package includes */
42
#include "sim-cmd.h"
43
#include "sim-config.h"
44
#include "execute.h"
45 1353 nogj
#include "labels.h"
46 1748 jeremybenn
#include "gdbcomm.h"
47
#include "sched.h"
48
#include "toplevel-support.h"
49
#include "dumpverilog.h"
50
#include "profiler.h"
51 1353 nogj
#include "mprofiler.h"
52
#include "trace.h"
53 1748 jeremybenn
#include "debug-unit.h"
54 1353 nogj
#include "stats.h"
55 1748 jeremybenn
#include "sprs.h"
56
#include "dcache-model.h"
57
#include "branch-predict.h"
58
#include "debug.h"
59 1353 nogj
#include "cuc.h"
60 1751 jeremybenn
#include "rsp-server.h"
61 1353 nogj
 
62
 
63 1471 nogj
/* The number of instructions to execute before droping into interactive mode */
64
static long long to_insn_num;
65
 
66 1748 jeremybenn
struct sim_stat
67
{
68
  void (*stat_func) (void *dat);
69 1363 nogj
  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 1748 jeremybenn
void
77
reg_sim_stat (void (*stat_func) (void *dat), void *dat)
78 1363 nogj
{
79 1748 jeremybenn
  struct sim_stat *new = malloc (sizeof (struct sim_stat));
80 1363 nogj
 
81 1748 jeremybenn
  if (!new)
82
    {
83
      fprintf (stderr, "reg_sim_stat: Out-of-memory\n");
84
      exit (1);
85
    }
86 1363 nogj
 
87
  new->stat_func = stat_func;
88
  new->dat = dat;
89
  new->next = sim_stats;
90
  sim_stats = new;
91
}
92
 
93 1471 nogj
/* Scheduler job that drops us back into interactive mode after the next
94
 * instruction has executed */
95 1748 jeremybenn
void
96
reenter_int (void *dat)
97 1471 nogj
{
98 1748 jeremybenn
  if (!runtime.sim.hush)
99
    dumpreg ();
100
  handle_sim_command ();
101 1471 nogj
}
102
 
103 1748 jeremybenn
static int
104
sim_cmd_quit (int argc, char **argv)    /* quit */
105 1353 nogj
{
106
  PRINTF ("\n");
107 1748 jeremybenn
  sim_done ();
108 1353 nogj
  return 0;
109
}
110
 
111 1748 jeremybenn
static int
112
sim_cmd_help (int argc, char **argv)    /* help */
113 1353 nogj
{
114 1748 jeremybenn
  PRINTF ("q                              - quit simulator\n");
115
  PRINTF ("r                              - display all registers\n");
116
  PRINTF ("t                              - execute next instruction\n");
117
  PRINTF
118
    ("run <instructions> [<hush>]    - execute <instruction> instructions, no reg\n");
119
  PRINTF ("                                 dump if hush\n");
120
  PRINTF
121
    ("pr <r> <value>                 - patch register <r> with <value>\n");
122
  PRINTF
123
    ("dm <fromaddr> [<toaddr>]       - display memory from <fromaddr> to <toaddr>\n");
124
  PRINTF ("de <fromaddr> [<toaddr>]       - debug insn memory\n");
125
  PRINTF
126
    ("pm <addr> <value>              - patch memory location <addr> with <value>\n");
127
  PRINTF
128
    ("pc <value>                     - patch PC register with <value>\n");
129
  PRINTF ("cm <fromaddr> <toaddr> <size>  - copy memory\n");
130
  PRINTF
131
    ("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
136
    ("stall                          - stalls the processor and gives control to\n");
137
  PRINTF ("                                 the debugger\n");
138
  PRINTF ("unstall                        - unstalls the processor\n");
139
  PRINTF
140
    ("stats <num|clear>              - execution statistics num or clear it.\n");
141
  PRINTF
142
    ("info                           - configuration info (caches etc.)\n");
143
  PRINTF
144
    ("dv <fromaddr> [<toaddr>] [<m>] - dumps memory as verilog module <m>\n");
145
  PRINTF ("                                 (use redirect to capture)\n");
146
  PRINTF
147
    ("dh <fromaddr> [<toaddr>]       - dumps memory as hex code (use redirect)\n");
148
  PRINTF ("setdbch                        - toggles debug channels on/off\n");
149
  PRINTF
150
    ("set <section> <item> = <param> - set configuration.  See sim.cfg for more\n");
151
  PRINTF ("                                 information.\n");
152
  PRINTF ("debug                          - toggles simulator debug mode\n");
153
  PRINTF
154
    ("cuc                            - enters Custom Unit Compiler command prompt\n");
155
  PRINTF
156
    ("help                           - available commands (this list)\n");
157
  PRINTF
158
    ("<cmd> > <filename>             - redirect simulator stdout to <filename>\n");
159
  PRINTF ("                                 (and not emulated PRINTF)\n\n");
160
  (void)main_mprofiler (0, NULL, 1);
161
  PRINTF ("\n");
162
  (void)main_profiler (0, NULL, 1);
163 1353 nogj
  return 0;
164
}
165
 
166 1748 jeremybenn
static int
167
sim_cmd_trace (int argc, char **argv)   /* trace */
168 1353 nogj
{
169 1471 nogj
  runtime.sim.hush = 0;
170 1748 jeremybenn
  sched_next_insn (reenter_int, NULL);
171 1353 nogj
  return 1;
172
}
173
 
174 1748 jeremybenn
static int
175
sim_cmd_dm (int argc, char **argv)      /* dump memory */
176 1353 nogj
{
177
  static oraddr_t from = 0, to = 0;
178
 
179 1748 jeremybenn
  if (argc >= 2)
180
    {
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
  dump_memory (from, to);
190
  PRINTF ("\n");
191 1353 nogj
  return 0;
192
}
193
 
194 1748 jeremybenn
static int
195
sim_cmd_dv (int argc, char **argv)      /* dump memory as verilog */
196 1353 nogj
{
197
  static oraddr_t from = 0, to = 0;
198 1748 jeremybenn
 
199
  if (argc >= 2)
200
    {
201
      if (argv[1][0] == '_')
202
        from = eval_label (argv[1]);
203
      else
204
        from = strtoul (argv[1], NULL, 0);
205
      to = from + 0x40;
206
    }
207
  if (argc >= 3)
208
    to = strtoul (argv[2], NULL, 0);
209
 
210
  if (argc < 4)
211
    dumpverilog ("or1k_mem", from, to);
212 1353 nogj
  else
213 1748 jeremybenn
    dumpverilog (argv[3], from, to);
214 1353 nogj
 
215 1748 jeremybenn
  PRINTF ("\n");
216 1353 nogj
  return 0;
217
}
218
 
219 1748 jeremybenn
static int
220
sim_cmd_dh (int argc, char **argv)      /* dump memory as hex */
221 1353 nogj
{
222
  static oraddr_t from = 0, to = 0;
223
 
224 1748 jeremybenn
  if (argc >= 2)
225
    {
226
      if (argv[1][0] == '_')
227
        from = eval_label (argv[1]);
228
      else
229
        from = strtoul (argv[1], NULL, 0);
230
      to = from + 0x40;
231
    }
232
  if (argc >= 3)
233
    to = strtoul (argv[2], NULL, 0);
234 1353 nogj
 
235 1748 jeremybenn
  dumphex (from, to);
236
  PRINTF ("\n");
237 1353 nogj
  return 0;
238
}
239
 
240 1748 jeremybenn
static int
241
sim_cmd_pm (int argc, char **argv)      /* patch memory */
242 1353 nogj
{
243
  static oraddr_t addr = 0;
244
  int breakpoint = 0;
245
 
246 1748 jeremybenn
  if (argc != 3)
247
    {
248
      PRINTF ("pm <address> <value>\n");
249
      return 0;
250
    }
251 1353 nogj
 
252 1748 jeremybenn
  if (argc >= 2)
253
    {
254
      if (argv[1][0] == '_')
255
        addr = eval_label (argv[1]);
256
      else
257
        addr = strtoul (argv[1], NULL, 0);
258
    }
259
  set_mem32 (addr, strtoul (argv[2], NULL, 0), &breakpoint);
260 1353 nogj
  return 0;
261
}
262
 
263 1748 jeremybenn
static int
264
sim_cmd_cm (int argc, char **argv)      /* copy memory 2004-01-20 hpanther */
265 1353 nogj
{
266
  static oraddr_t from = 0, to = 0;
267
  static unsigned int size = 0;
268
  int i;
269
 
270 1748 jeremybenn
  if (argc >= 2)
271
    {
272
      if (argv[1][0] == '_')
273
        from = eval_label (argv[1]);
274
      else
275
        from = strtoul (argv[1], NULL, 0);
276
    }
277 1353 nogj
 
278 1748 jeremybenn
  if (argc >= 3)
279
    {
280
      if (argv[2][0] == '_')
281
        to = eval_label (argv[2]);
282
      else
283
        to = strtoul (argv[2], NULL, 0);
284
    }
285 1353 nogj
 
286 1748 jeremybenn
  if (argc >= 4)
287
    {
288
      if (argv[3][0] == '_')
289
        size = eval_label (argv[3]);
290
      else
291
        size = strtoul (argv[3], NULL, 0);
292
    }
293 1353 nogj
 
294 1748 jeremybenn
  for (i = 0; i < size; i += 4)
295
    set_direct32 (to + i, eval_direct32 (from + i, 0, 0), 0, 0);
296 1353 nogj
  return 0;
297
}
298
 
299 1748 jeremybenn
static int
300
sim_cmd_pr (int argc, char **argv)      /* patch regs */
301 1353 nogj
{
302 1748 jeremybenn
  if (argc != 3)
303
    {
304
      PRINTF ("pr <register> <value>\n");
305
      return 0;
306
    }
307
  setsim_reg (strtoul (argv[1], NULL, 0), strtoul (argv[2], NULL, 0));
308 1471 nogj
#if DYNAMIC_EXECUTION
309 1748 jeremybenn
  PRINTF
310
    ("WARNING: Patching registers may not work with the dynamic execution model\n");
311 1471 nogj
#endif
312 1353 nogj
  return 0;
313
}
314
 
315 1748 jeremybenn
static int
316
sim_cmd_pc (int argc, char **argv)      /* patch PC */
317 1353 nogj
{
318 1471 nogj
#if DYNAMIC_EXECUTION
319 1748 jeremybenn
  PRINTF ("Patching the pc in the dynamic execution model doesn't work\n");
320 1471 nogj
#else
321 1748 jeremybenn
  if (argc != 2)
322
    {
323
      PRINTF ("pc <value>\n");
324
      return 0;
325
    }
326 1353 nogj
 
327 1748 jeremybenn
  cpu_state.pc = strtoul (argv[1], NULL, 0);
328 1432 nogj
  pcnext = cpu_state.pc + 4;
329 1471 nogj
#endif
330 1353 nogj
  return 0;
331
}
332
 
333 1748 jeremybenn
static int
334
sim_cmd_breaks (int argc, char **argv)  /* print breakpoints */
335 1353 nogj
{
336 1748 jeremybenn
  print_breakpoints ();
337 1353 nogj
  return 0;
338
}
339
 
340 1748 jeremybenn
static int
341
sim_cmd_break (int argc, char **argv)   /* set/clear breakpoint */
342 1353 nogj
{
343 1479 nogj
#if DYNAMIC_EXECUTION
344 1748 jeremybenn
  PRINTF
345
    ("Setting simulator breakpoints is not support with the recompiler\n");
346 1479 nogj
  return 0;
347
#else
348 1353 nogj
  char *p;
349
  oraddr_t addr;
350
  struct label_entry *l;
351
 
352 1748 jeremybenn
  if (argc != 2)
353
    {
354
      PRINTF ("break <label or address>\n");
355
      return 0;
356
    }
357 1353 nogj
 
358 1748 jeremybenn
  addr = strtoul (argv[1], &p, 0);
359
  if (*p)
360
    {
361
      l = find_label (argv[1]);
362
      if (l)
363
        set_insnbrkpoint (l->addr);
364
      else
365
        PRINTF ("Label `%s' does not exist\n", argv[1]);
366
    }
367
  else
368
    set_insnbrkpoint (addr);
369 1353 nogj
  return 0;
370 1479 nogj
#endif
371 1353 nogj
}
372
 
373 1748 jeremybenn
static int
374
sim_cmd_r (int argc, char **argv)       /* dump regs */
375 1353 nogj
{
376 1748 jeremybenn
  dumpreg ();
377 1353 nogj
  return 0;
378
}
379
 
380 1748 jeremybenn
static int
381
sim_cmd_de (int argc, char **argv)      /* disassemble */
382 1353 nogj
{
383
  static oraddr_t from = 0, to = 0;
384
 
385 1748 jeremybenn
  if (argc >= 2)
386
    {
387
      if (argv[1][0] == '_')
388
        from = eval_label (argv[1]);
389
      else
390
        from = strtoul (argv[1], NULL, 0);
391
      to = from + 0x40;
392
    }
393 1353 nogj
 
394 1748 jeremybenn
  if (argc >= 3)
395
    to = strtoul (argv[2], NULL, 0);
396 1353 nogj
 
397 1748 jeremybenn
  disassemble_memory (from, to, 1);
398
  PRINTF ("\n");
399 1353 nogj
  return 0;
400
}
401
 
402 1748 jeremybenn
static int
403
sim_cmd_reset (int argc, char **argv)   /* reset simulator */
404 1353 nogj
{
405 1748 jeremybenn
  sim_reset ();
406 1353 nogj
  return 0;
407
}
408
 
409 1748 jeremybenn
static int
410
sim_cmd_hist (int argc, char **argv)    /* dump history */
411 1353 nogj
{
412
  int i;
413
  struct hist_exec *cur;
414 1748 jeremybenn
  if (!config.sim.history)
415
    {
416
      PRINTF ("Simulation history disabled.\n");
417
      return 0;
418
    }
419
  for (i = HISTEXEC_LEN, cur = hist_exec_tail->next; i; i--, cur = cur->next)
420
    disassemble_memory (cur->addr, cur->addr + 4, 1);
421
  PRINTF ("\n");
422 1353 nogj
  return 0;
423
}
424
 
425 1471 nogj
/* Called when it is suspisous that runtime.sim.instructions has reached
426
 * to_insn_num */
427 1748 jeremybenn
void
428
check_insn_exec (void *dat)
429 1471 nogj
{
430 1748 jeremybenn
  if (runtime.cpu.instructions < to_insn_num)
431
    {
432
      /* Instruction count has not yet been reached, reschedule */
433
      long long int delta = to_insn_num - runtime.cpu.instructions;
434
      SCHED_ADD (check_insn_exec, NULL,
435
                 (delta > INT32_MAX) ? INT32_MAX : delta);
436
      return;
437
    }
438
  handle_sim_command ();
439 1471 nogj
}
440
 
441 1748 jeremybenn
void
442
print_insn_exec (void *dat)
443 1471 nogj
{
444 1748 jeremybenn
  dumpreg ();
445
  if (runtime.cpu.instructions < to_insn_num)
446
    {
447
      /* Instruction count has not yet been reached, reschedule */
448
      sched_next_insn (print_insn_exec, NULL);
449
      return;
450
    }
451
  handle_sim_command ();
452 1471 nogj
}
453
 
454 1748 jeremybenn
static int
455
sim_cmd_run (int argc, char **argv)     /* run */
456 1353 nogj
{
457 1471 nogj
  runtime.sim.hush = 0;
458 1748 jeremybenn
  if (argc >= 3)
459
    {
460
      if (!strcmp (argv[2], "hush"))
461
        runtime.sim.hush = 1;
462
    }
463 1353 nogj
 
464 1748 jeremybenn
  if (argc >= 2)
465
    {
466
      if ((to_insn_num = strtoll (argv[1], NULL, 0)) != -1)
467
        {
468
          if (runtime.sim.hush)
469
            {
470
              /* Schedule a job to run in to_insn_num cycles time since an instruction
471
               * may execute in only 1 cycle.  check_insn_exec will check if the right
472
               * number of instructions have been executed.  If not it will
473
               * reschedule.  */
474
              SCHED_ADD (check_insn_exec, NULL,
475
                         (to_insn_num > INT32_MAX) ? INT32_MAX : to_insn_num);
476
            }
477
          else
478
            {
479
              /* The user wants to see the execution dumps.  Schedule a task to show
480
               * it to him after each cycle */
481
              sched_next_insn (print_insn_exec, NULL);
482
            }
483
          to_insn_num += runtime.cpu.instructions;
484
        }
485
      else
486
        {
487
          if (!runtime.sim.hush)
488
            sched_next_insn (print_insn_exec, NULL);
489
        }
490 1471 nogj
    }
491 1748 jeremybenn
  else
492 1471 nogj
    /* Run 0 instructions */
493
    return 0;
494
 
495 1353 nogj
  return 1;
496
}
497
 
498 1748 jeremybenn
static int
499
sim_cmd_stall (int argc, char **argv)   /* Added by CZ 210801 */
500 1353 nogj
{
501 1479 nogj
#if DYNAMIC_EXECUTION
502 1748 jeremybenn
  PRINTF ("Can't stall the cpu with the dynamic recompiler\n");
503 1479 nogj
  return 0;
504
#else
505 1353 nogj
  set_stall_state (1);
506
  runtime.sim.iprompt = 0;
507
  runtime.sim.hush = 1;
508
  return 1;
509 1479 nogj
#endif
510 1353 nogj
}
511
 
512 1748 jeremybenn
static int
513
sim_cmd_unstall (int argc, char **argv) /* Added by CZ 210801 */
514 1353 nogj
{
515 1748 jeremybenn
#if DYNAMIC_EXECUTION
516
  PRINTF ("Can't unstall the cpu with the dynamic recompiler\n");
517
  return 0;
518
#else
519
  set_stall_state (0);
520
  return 0;
521
#endif
522
}
523 1353 nogj
 
524 1748 jeremybenn
static int
525
sim_cmd_stats (int argc, char **argv)   /* stats */
526
{
527
  if (argc != 2)
528
    {
529
      PRINTF ("stats <stat no. or `clear'>\n");
530
      return 0;
531
    }
532
 
533
  if (strcmp (argv[1], "clear") == 0)
534
    {
535
      initstats ();
536
      PRINTF ("Cleared.\n");
537
    }
538
  else
539
    {
540
      printstats (strtoul (argv[1], NULL, 0));
541
    }
542 1353 nogj
  return 0;
543
}
544
 
545 1748 jeremybenn
static int
546
sim_cmd_info (int argc, char **argv)    /* configuration info */
547 1353 nogj
{
548 1363 nogj
  struct sim_stat *cur_stat = sim_stats;
549
 
550 1353 nogj
  /* Display info about various modules */
551 1748 jeremybenn
  sprs_status ();
552 1353 nogj
  PRINTF ("\n");
553
  memory_table_status ();
554 1748 jeremybenn
  if (config.dc.enabled)
555
    dc_info ();
556 1363 nogj
 
557 1748 jeremybenn
  if (config.bpb.enabled)
558
    bpb_info ();
559
  if (config.bpb.btic)
560
    btic_info ();
561
 
562
  while (cur_stat)
563
    {
564
      cur_stat->stat_func (cur_stat->dat);
565
      cur_stat = cur_stat->next;
566
    }
567
 
568 1353 nogj
  return 0;
569
}
570
 
571 1748 jeremybenn
static int
572
sim_cmd_setdbch (int argc, char **argv) /* Toggle debug channel on/off */
573 1389 nogj
{
574 1748 jeremybenn
  if (argc != 2)
575
    {
576
      PRINTF ("setdbch <channel>\n");
577
      return 0;
578
    }
579
  parse_dbchs (argv[1]);
580 1389 nogj
  return 0;
581
}
582
 
583 1748 jeremybenn
static int
584
sim_cmd_debug (int argc, char **argv)   /* debug mode */
585 1353 nogj
{
586
  config.sim.debug ^= 1;
587
  return 0;
588
}
589
 
590 1748 jeremybenn
static int
591
sim_cmd_profile (int argc, char **argv) /* run profiler utility */
592 1353 nogj
{
593 1748 jeremybenn
  return  main_profiler (argc, argv, 0);
594 1353 nogj
}
595
 
596 1748 jeremybenn
static int
597
sim_cmd_mprofile (int argc, char **argv)        /* run mprofiler utility */
598 1353 nogj
{
599 1748 jeremybenn
  return  main_mprofiler (argc, argv, 0);
600 1353 nogj
}
601
 
602 1748 jeremybenn
static int
603
sim_cmd_cuc (int argc, char **argv)     /* run Custom Unit Compiler */
604 1353 nogj
{
605 1748 jeremybenn
  main_cuc (runtime.sim.filename);
606 1353 nogj
  return 0;
607
}
608
 
609 1748 jeremybenn
static int
610
sim_cmd_set (int argc, char **argv)     /* configuration info */
611 1353 nogj
{
612 1748 jeremybenn
  set_config_command (argc, argv);
613 1353 nogj
  return 0;
614
}
615
 
616 1748 jeremybenn
static char *
617
strip_space (char *str)
618 1353 nogj
{
619 1748 jeremybenn
  while (isblank (*str) && *str)
620
    str++;
621 1353 nogj
  return str;
622
}
623
 
624 1748 jeremybenn
struct sim_command
625
{
626 1353 nogj
  const char *name;
627 1748 jeremybenn
  int (*cmd_handle) (int argc, char **argv);
628 1353 nogj
};
629
 
630
static const struct sim_command sim_commands[] = {
631 1748 jeremybenn
  {"q", sim_cmd_quit},
632
  {"help", sim_cmd_help},
633
  {"t", sim_cmd_trace},
634
  {"dm", sim_cmd_dm},
635
  {"dv", sim_cmd_dv},
636
  {"dh", sim_cmd_dh},
637
  {"pm", sim_cmd_pm},
638
  {"cm", sim_cmd_cm},
639
  {"pr", sim_cmd_pr},
640
  {"pc", sim_cmd_pc},
641
  {"breaks", sim_cmd_breaks},
642
  {"break", sim_cmd_break},
643
  {"r", sim_cmd_r},
644
  {"de", sim_cmd_de},
645
  {"reset", sim_cmd_reset},
646
  {"hist", sim_cmd_hist},
647
  {"stall", sim_cmd_stall},
648
  {"unstall", sim_cmd_unstall},
649
  {"stats", sim_cmd_stats},
650
  {"info", sim_cmd_info},
651
  {"run", sim_cmd_run},
652
  {"setdbch", sim_cmd_setdbch},
653
  {"debug", sim_cmd_debug},
654
  {"profile", sim_cmd_profile},
655
  {"mprofile", sim_cmd_mprofile},
656
  {"cuc", sim_cmd_cuc},
657
  {"set", sim_cmd_set},
658
  {NULL, NULL}
659
};
660 1353 nogj
 
661
#ifdef HAVE_LIBREADLINE
662 1748 jeremybenn
static void initialize_readline (void);
663 1353 nogj
#endif
664
 
665 1748 jeremybenn
void
666
handle_sim_command (void)
667 1353 nogj
{
668
  char *redirstr;
669
  int argc;
670
  char *argv[5];
671
  char *cur_arg;
672
  const struct sim_command *cur_cmd;
673
#ifdef HAVE_LIBREADLINE
674
  static char *prev_str = NULL;
675
#else
676
  char b2[500];
677
  static char prev_str[500] = { 0 };
678
#endif
679
 
680 1593 nogj
  runtime.sim.iprompt_run = 1;
681
 
682 1471 nogj
  /* Make sure that check_insn_exec is not left hanging in the scheduler (and
683
   * breaking the sim when the user doesn't want it to break). */
684 1748 jeremybenn
  SCHED_FIND_REMOVE (check_insn_exec, NULL);
685
  SCHED_FIND_REMOVE (print_insn_exec, NULL);
686 1471 nogj
 
687 1353 nogj
#ifdef HAVE_LIBREADLINE
688 1748 jeremybenn
  initialize_readline ();       /* Bind our completer. */
689 1353 nogj
#endif
690
 
691 1748 jeremybenn
  for (;;)
692
    {
693 1353 nogj
#ifdef HAVE_LIBREADLINE
694 1748 jeremybenn
      cur_arg = readline ("(sim) ");
695 1353 nogj
#else
696 1748 jeremybenn
      PRINTF ("(sim) ");
697 1751 jeremybenn
 
698
      /* RSP does not get involved during CLI, so only check legacy interface
699
         here. */
700 1748 jeremybenn
      if (config.debug.gdb_enabled)
701
        {
702
          fflush (stdout);
703
          handle_server_socket (TRUE);  /* block & check_stdin = true */
704
        }
705 1353 nogj
 
706 1748 jeremybenn
      cur_arg = fgets (b2, sizeof (b2), stdin);
707 1353 nogj
 
708 1748 jeremybenn
      if (!cur_arg)
709
        sim_done ();
710 1596 nogj
 
711 1748 jeremybenn
      if (!*cur_arg)
712
        {
713
          usleep (1000);
714
          continue;
715
        }
716 1353 nogj
#endif
717
 
718
#ifdef HAVE_LIBREADLINE
719 1748 jeremybenn
      if (!*cur_arg)
720
        {
721
          if (prev_str)
722
            {
723
              free (cur_arg);
724
              cur_arg = prev_str;
725
            }
726
        }
727
      else
728
        {
729
          prev_str = cur_arg;
730
          add_history (cur_arg);
731
        }
732 1353 nogj
#else
733 1748 jeremybenn
      cur_arg = strip_space (cur_arg);
734
      if (*cur_arg == '\n')
735
        strcpy (cur_arg, prev_str);
736
      else
737
        strcpy (prev_str, cur_arg);
738 1353 nogj
#endif
739
 
740 1748 jeremybenn
      if ((redirstr = strchr (cur_arg, '>')))
741
        {
742
          redirstr = strip_space (++redirstr);
743 1353 nogj
 
744 1748 jeremybenn
          while (!isspace (*redirstr) && *redirstr)
745
            redirstr++;
746
          *redirstr = '\0';
747 1353 nogj
 
748 1748 jeremybenn
          redirstr = strchr (cur_arg, '>');
749
          *redirstr = '\0';
750 1353 nogj
 
751 1748 jeremybenn
          redirstr = strip_space (++redirstr);
752
          runtime.sim.fout = fopen (redirstr, "w+");
753
          if (!runtime.sim.fout)
754
            runtime.sim.fout = stdout;
755
        }
756 1353 nogj
 
757 1748 jeremybenn
      if (*cur_arg)
758
        {
759
          argc = 0;
760
          while (*cur_arg)
761
            {
762
              argv[argc] = cur_arg;
763
              argc++;
764
              while (!isspace (*cur_arg) && *cur_arg)
765
                cur_arg++;
766
              if (*cur_arg)
767
                {
768
                  *cur_arg = '\0';
769
                  cur_arg = strip_space (cur_arg + 1);
770
                }
771
              else
772
                *cur_arg = '\0';
773
              if (argc == 5)
774
                {
775
                  fprintf (stderr,
776
                           "Too many arguments given to command `%s'\n",
777
                           argv[0]);
778
                  break;
779
                }
780
            }
781 1353 nogj
 
782 1748 jeremybenn
          for (cur_cmd = sim_commands; cur_cmd->name; cur_cmd++)
783
            {
784
              if (!strcmp (cur_cmd->name, argv[0]))
785
                {
786
                  if (cur_cmd->cmd_handle (argc, argv))
787
                    {
788
                      runtime.sim.iprompt = 0;
789
                      runtime.sim.iprompt_run = 0;
790
                      return;
791
                    }
792
                  break;
793
                }
794
            }
795
 
796
          if (!cur_cmd->name)
797
            PRINTF ("%s: Unknown command.\n", argv[0]);
798
        }
799
 
800
      if (redirstr)
801
        {
802
          redirstr = NULL;
803
          fclose (runtime.sim.fout);
804
          runtime.sim.fout = stdout;
805
        }
806
 
807 1353 nogj
    }
808
}
809
 
810
#ifdef HAVE_LIBREADLINE
811
 
812 1748 jeremybenn
int
813
check_gdb_comm (void)
814 1353 nogj
{
815 1751 jeremybenn
  /* Only do anything for legacy debug interface. RSP does not get involved
816
     when the CLI is active */
817
  if (config.debug.gdb_enabled)
818
    {
819
      handle_server_socket (TRUE);      /* block & check_stdin = true */
820
    }
821
 
822 1353 nogj
  return 0;
823
}
824
 
825 1748 jeremybenn
char *command_generator ();
826
char **sim_completion ();
827 1353 nogj
 
828
/* Tell the GNU readline library how to complete.  We want to try to complete
829
   on command names if this is the first word in the line, or on filenames
830
   if not. */
831 1748 jeremybenn
static void
832
initialize_readline (void)
833 1353 nogj
{
834
  /* Allow conditional parsing of the ~/.inputrc file. */
835
  rl_readline_name = "or1ksim";
836
 
837
  /* Tell the completer that we want a crack first. */
838
  rl_attempted_completion_function = sim_completion;
839
 
840
  /* Handle the gdb socket while waiting for input */
841
  rl_event_hook = check_gdb_comm;
842
}
843
 
844
/* Attempt to complete on the contents of TEXT.  START and END bound the
845
   region of rl_line_buffer that contains the word to complete.  TEXT is
846
   the word to complete.  We can use the entire contents of rl_line_buffer
847
   in case we want to do some simple parsing.  Return the array of matches,
848
   or NULL if there aren't any. */
849
/* FIXME: Handle arguments to the `set' command */
850 1748 jeremybenn
char **
851
sim_completion (char *text, int start, int end)
852 1353 nogj
{
853
  char **matches;
854
 
855
  matches = NULL;
856
 
857
  /* If this word is at the start of the line, then it is a command
858
     to complete.  Otherwise it is the name of a file in the current
859
     directory. */
860 1748 jeremybenn
  if (!start)
861
    matches = rl_completion_matches (text, command_generator);
862 1353 nogj
 
863
  return matches;
864
}
865
 
866
/* Generator function for command completion.  STATE lets us know whether
867
   to start from scratch; without any state (i.e. STATE == 0), then we
868
   start at the top of the list. */
869 1748 jeremybenn
char *
870
command_generator (char *text, int state)
871 1353 nogj
{
872
  static int list_index, len;
873
  const char *name;
874
 
875
  /* If this is a new word to complete, initialize now.  This includes
876
     saving the length of TEXT for efficiency, and initializing the index
877
     variable to 0. */
878 1748 jeremybenn
  if (!state)
879
    {
880
      list_index = 0;
881
      len = strlen (text);
882
    }
883 1353 nogj
 
884
  /* Return the next name which partially matches from the command list. */
885 1748 jeremybenn
  while ((name = sim_commands[list_index].name))
886
    {
887
      list_index++;
888 1353 nogj
 
889 1748 jeremybenn
      if (strncmp (name, text, len) == 0)
890
        return strdup (name);
891
    }
892 1353 nogj
 
893
  /* If no names matched, then return NULL. */
894
  return NULL;
895
}
896
 
897
/* Repeats the last command.  */
898 1748 jeremybenn
char *
899
repeat_last_command ()
900 1353 nogj
{
901
  int offset = where_history ();
902
  HIST_ENTRY *hist;
903
 
904 1748 jeremybenn
  if ((hist = history_get (offset)))
905
    return strdup (hist->line);
906 1353 nogj
  return 0;
907
}
908
 
909
#endif

powered by: WebSVN 2.1.0

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