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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [or1ksim/] [sim-cmd.c] - Blame information for rev 1717

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 1557 nogj
#define _GNU_SOURCE /* For isblank() */
22 1353 nogj
#include <stdio.h>
23
#include <string.h>
24
#include <ctype.h>
25
#include <unistd.h>
26 1580 nogj
#include <limits.h>
27 1353 nogj
 
28
#include "config.h"
29
 
30
#ifdef HAVE_LIBREADLINE
31
#include <readline/readline.h>
32
#include <readline/history.h>
33
#endif /* HAVE_LIBREADLINE */
34
 
35
#ifdef HAVE_INTTYPES_H
36
#include <inttypes.h>
37
#endif
38
 
39
#include "port.h"
40
#include "arch.h"
41
#include "abstract.h"
42
#include "labels.h"
43
#include "opcode/or32.h"
44
#include "mprofiler.h"
45
#include "profiler.h"
46
#include "sim-config.h"
47
#include "dumpverilog.h"
48 1432 nogj
#include "spr_defs.h"
49 1353 nogj
#include "execute.h"
50
#include "debug_unit.h"
51
#include "debug.h"
52
#include "trace.h"
53
#include "stats.h"
54
#include "cuc.h"
55
#include "gdbcomm.h"
56 1471 nogj
#include "sched.h"
57 1353 nogj
 
58
/* FIXME: These *really* need to be cleaned up */
59
#include "sprs.h"
60
#include "immu.h"
61
#include "dmmu.h"
62
#include "icache_model.h"
63
#include "dcache_model.h"
64
#include "branch_predict.h"
65
 
66 1471 nogj
/* The number of instructions to execute before droping into interactive mode */
67
static long long to_insn_num;
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 1432 nogj
    uint32_t insn;
101 1353 nogj
    PRINTF("i=%x :: ", i);
102
 
103
    if (verify_memoryarea(i) && (entry = get_label(i)))
104
      PRINTF("label: %s |", entry->name);
105
 
106 1487 nogj
    insn = eval_direct32(i, 0, 0);
107 1432 nogj
    disassemble_insn (insn);
108
    PRINTF("%08x %s\n", insn, disassembled);
109
    i += 4;
110 1353 nogj
  }
111
}
112
 
113 1471 nogj
/* Scheduler job that drops us back into interactive mode after the next
114
 * instruction has executed */
115
void reenter_int(void *dat)
116
{
117
  if (!runtime.sim.hush) dumpreg();
118
  handle_sim_command();
119
}
120
 
121 1353 nogj
static int sim_cmd_quit(int argc, char **argv) /* quit */
122
{
123
  PRINTF ("\n");
124
  sim_done();
125
  return 0;
126
}
127
 
128
static int sim_cmd_help(int argc, char **argv) /* help */
129
{
130
  PRINTF("q      - quit simulator\n");
131
  PRINTF("r      - display all registers\n");
132
  PRINTF("t      - execute next instruction\n");
133
  PRINTF("run <instructions> [<hush>]   - execute <instruction> instructions, no reg dump if hush\n");
134
  PRINTF("pr <r> <value>                - patch register <r> with <value>\n");
135
  PRINTF("dm <fromaddr> [<toaddr>]      - display memory from <fromaddr> to <toaddr>\n");
136
  PRINTF("de <fromaddr> [<toaddr>]      - debug insn memory\n");
137
  PRINTF("pm <addr> <value>             - patch memory location <addr> with <value>\n");
138
  PRINTF("pc <value>                    - patch PC register with <value>\n");
139
  PRINTF("cm <fromaddr> <toaddr> <size> - copy memory\n");
140
  PRINTF("break <addr>      - toggle breakpoint at address <addr>\n");
141
  PRINTF("breaks            - print all set breakpoints\n");
142
  PRINTF("reset             - simulator reset\n");
143
  PRINTF("hist              - execution history\n");
144
  PRINTF("stall             - stalls the processor and gives control to the debugger\n");
145
  PRINTF("stats <num|clear> - execution statistics num or clear it.\n");
146
  PRINTF("info              - configuration info (caches etc.)\n");
147
  PRINTF("dv <fromaddr> [<toaddr>] [<modname>] - dumps memory as verilog (use redirect)\n");
148
  PRINTF("dh <fromaddr> [<toaddr>]             - dumps memory as hex code (use redirect)\n");
149
  PRINTF("<cmd> > <filename> - redirect simulator stdout to <filename> (and not emulated PRINTF)\n");
150 1389 nogj
  PRINTF("setdbch            - toggles debug channels on/off\n");
151 1353 nogj
  PRINTF("set <section> <item> = <param>  - set configuration.  See sim.cfg for more information.\n");
152
  PRINTF("debug      - toggles simulator debug mode\n");
153
  mp_help ();
154
  prof_help ();
155
  PRINTF("cuc        - enters Custom Unit Compiler command prompt\n");
156
  PRINTF("help       - available commands (this list)\n");
157
  return 0;
158
}
159
 
160
static int sim_cmd_trace(int argc, char **argv) /* trace */
161
{
162 1471 nogj
  runtime.sim.hush = 0;
163 1545 nogj
  sched_next_insn(reenter_int, NULL);
164 1353 nogj
  return 1;
165
}
166
 
167
static int sim_cmd_dm(int argc, char **argv) /* dump memory */
168
{
169
  static oraddr_t from = 0, to = 0;
170
 
171
  if(argc >= 2) {
172
    if(argv[1][0] == '_')
173
      from = eval_label(argv[1]);
174
    else
175
      from = strtoul(argv[1], NULL, 0);
176
    to = from + 0x40;
177
  }
178
  if(argc >= 3)
179
    to = strtoul(argv[2], NULL, 0);
180
  dumpmemory(from, to, 0, 1);
181
  PRINTF("\n");
182
  return 0;
183
}
184
 
185 1446 nogj
static int sim_cmd_dv(int argc, char **argv) /* dump memory as verilog */
186 1353 nogj
{
187
  static oraddr_t from = 0, to = 0;
188
 
189
  if(argc >= 2) {
190
    if(argv[1][0] == '_')
191
      from = eval_label(argv[1]);
192
    else
193
      from = strtoul(argv[1], NULL, 0);
194
    to = from + 0x40;
195
  }
196
  if(argc >= 3)
197
    to = strtoul(argv[2], NULL, 0);
198
 
199
  if(argc < 4)
200
    dumpverilog("or1k_mem", from, to);
201
  else
202
    dumpverilog(argv[3], from, to);
203
 
204
  PRINTF("\n");
205
  return 0;
206
}
207
 
208 1446 nogj
static int sim_cmd_dh(int argc, char **argv) /* dump memory as hex */
209 1353 nogj
{
210
  static oraddr_t from = 0, to = 0;
211
 
212
  if(argc >= 2) {
213
    if(argv[1][0] == '_')
214
      from = eval_label(argv[1]);
215
    else
216
      from = strtoul(argv[1], NULL, 0);
217
    to = from + 0x40;
218
  }
219
  if(argc >= 3)
220
    to = strtoul(argv[2], NULL, 0);
221
 
222
  dumphex(from, to);
223
  PRINTF("\n");
224
  return 0;
225
}
226
 
227
static int sim_cmd_pm(int argc, char **argv) /* patch memory */
228
{
229
  static oraddr_t addr = 0;
230
  int breakpoint = 0;
231
 
232
  if(argc != 3) {
233
    PRINTF("pm <address> <value>\n");
234
    return 0;
235
  }
236
 
237
  if(argc >= 2) {
238
    if (argv[1][0] == '_')
239
      addr = eval_label(argv[1]);
240
    else
241
      addr = strtoul(argv[1], NULL, 0);
242
  }
243
  set_mem32(addr, strtoul(argv[2], NULL, 0), &breakpoint);
244
  return 0;
245
}
246
 
247
static int sim_cmd_cm(int argc, char **argv) /* copy memory 2004-01-20 hpanther*/
248
{
249
  static oraddr_t from = 0, to = 0;
250
  static unsigned int size = 0;
251
  int i;
252
 
253
  if(argc >= 2) {
254
    if (argv[1][0] == '_')
255
      from = eval_label(argv[1]);
256
    else
257
      from = strtoul(argv[1], NULL, 0);
258
  }
259
 
260
  if(argc >= 3) {
261
    if (argv[2][0] == '_')
262
      to = eval_label(argv[2]);
263
    else
264
      to = strtoul(argv[2], NULL, 0);
265
  }
266
 
267
  if(argc >= 4) {
268
    if (argv[3][0] == '_')
269
      size = eval_label(argv[3]);
270
    else
271
      size = strtoul(argv[3], NULL, 0);
272
  }
273
 
274
  for(i = 0; i < size; i += 4)
275 1487 nogj
    set_direct32(to + i, eval_direct32(from + i, 0, 0), 0, 0);
276 1353 nogj
  return 0;
277
}
278
 
279
static int sim_cmd_pr(int argc, char **argv) /* patch regs */
280
{
281
  if(argc != 3) {
282
    PRINTF("pr <register> <value>\n");
283
    return 0;
284
  }
285
  setsim_reg(strtoul(argv[1], NULL,0), strtoul(argv[2], NULL, 0));
286 1471 nogj
#if DYNAMIC_EXECUTION
287
  PRINTF("WARNING: Patching registers may not work with the dynamic execution model\n");
288
#endif
289 1353 nogj
  return 0;
290
}
291
 
292
static int sim_cmd_pc(int argc, char **argv) /* patch PC */
293
{
294 1471 nogj
#if DYNAMIC_EXECUTION
295
  PRINTF("Patching the pc in the dynamic execution model doesn't work\n");
296
#else
297 1353 nogj
  if(argc != 2) {
298
    PRINTF("pc <value>\n");
299
    return 0;
300
  }
301
 
302 1432 nogj
  cpu_state.pc = strtoul(argv[1], NULL, 0);
303
  pcnext = cpu_state.pc + 4;
304 1471 nogj
#endif
305 1353 nogj
  return 0;
306
}
307
 
308
static int sim_cmd_breaks(int argc, char **argv) /* print breakpoints */
309
{
310
  print_breakpoints();
311
  return 0;
312
}
313
 
314
static int sim_cmd_break(int argc, char **argv) /* set/clear breakpoint */
315
{
316 1479 nogj
#if DYNAMIC_EXECUTION
317
  PRINTF("Setting simulator breakpoints is not support with the recompiler\n");
318
  return 0;
319
#else
320 1353 nogj
  char *p;
321
  oraddr_t addr;
322
  struct label_entry *l;
323
 
324
  if(argc != 2) {
325
    PRINTF("break <label or address>\n");
326
    return 0;
327
  }
328
 
329
  addr = strtoul(argv[1], &p, 0);
330
  if(*p) {
331
    l = find_label(argv[1]);
332
    if(l)
333 1643 nogj
      set_insnbrkpoint(l->addr);
334 1353 nogj
    else
335 1643 nogj
      PRINTF("Label `%s' does not exist\n", argv[1]);
336
  } else
337
    set_insnbrkpoint(addr);
338 1353 nogj
  return 0;
339 1479 nogj
#endif
340 1353 nogj
}
341
 
342
static int sim_cmd_r(int argc, char **argv) /* dump regs */
343
{
344
  dumpreg();
345
  return 0;
346
}
347
 
348
static int sim_cmd_de(int argc, char **argv) /* disassemble */
349
{
350
  static oraddr_t from = 0, to = 0;
351
 
352
  if(argc >= 2) {
353
    if (argv[1][0] == '_')
354
      from = eval_label(argv[1]);
355
    else
356
      from = strtoul(argv[1], NULL, 0);
357
    to = from + 0x40;
358
  }
359
 
360
  if(argc >= 3)
361
    to = strtoul(argv[2], NULL, 0);
362
 
363
  debugmem(from, to);
364
  PRINTF("\n");
365
  return 0;
366
}
367
 
368
static int sim_cmd_reset(int argc, char **argv) /* reset simulator */
369
{
370
  sim_reset();
371
  return 0;
372
}
373
 
374
static int sim_cmd_hist(int argc, char **argv) /* dump history */
375
{
376
  int i;
377
  struct hist_exec *cur;
378
  if(!config.sim.history) {
379
    PRINTF("Simulation history disabled.\n");
380
    return 0;
381
  }
382 1584 phoenix
  for(i = HISTEXEC_LEN, cur = hist_exec_tail->next; i; i--, cur = cur->next)
383 1353 nogj
    dumpmemory(cur->addr, cur->addr + 4, 1, 1);
384
  PRINTF("\n");
385
  return 0;
386
}
387
 
388 1471 nogj
/* Called when it is suspisous that runtime.sim.instructions has reached
389
 * to_insn_num */
390
void check_insn_exec(void *dat)
391
{
392
  if(runtime.cpu.instructions < to_insn_num) {
393
    /* Instruction count has not yet been reached, reschedule */
394 1580 nogj
    long long int  delta = to_insn_num - runtime.cpu.instructions;
395 1588 nogj
    SCHED_ADD(check_insn_exec, NULL, (delta > INT32_MAX) ? INT32_MAX : delta);
396 1471 nogj
    return;
397
  }
398
  handle_sim_command();
399
}
400
 
401
void print_insn_exec(void *dat)
402
{
403
  dumpreg();
404
  if(runtime.cpu.instructions < to_insn_num) {
405
    /* Instruction count has not yet been reached, reschedule */
406 1545 nogj
    sched_next_insn(print_insn_exec, NULL);
407 1471 nogj
    return;
408
  }
409
  handle_sim_command();
410
}
411
 
412 1353 nogj
static int sim_cmd_run(int argc, char **argv) /* run */
413
{
414 1471 nogj
  runtime.sim.hush = 0;
415 1353 nogj
  if(argc >= 3) {
416
    if(!strcmp(argv[2], "hush"))
417
      runtime.sim.hush = 1;
418
  }
419
 
420 1471 nogj
  if(argc >= 2) {
421 1580 nogj
    if((to_insn_num = strtoll(argv[1], NULL, 0)) != -1) {
422 1471 nogj
      if(runtime.sim.hush) {
423
        /* Schedule a job to run in to_insn_num cycles time since an instruction
424
         * may execute in only 1 cycle.  check_insn_exec will check if the right
425
         * number of instructions have been executed.  If not it will
426
         * reschedule.  */
427 1588 nogj
        SCHED_ADD(check_insn_exec, NULL, (to_insn_num > INT32_MAX) ? INT32_MAX : to_insn_num);
428 1471 nogj
      } else {
429
        /* The user wants to see the execution dumps.  Schedule a task to show
430
         * it to him after each cycle */
431 1545 nogj
        sched_next_insn(print_insn_exec, NULL);
432 1471 nogj
      }
433
      to_insn_num += runtime.cpu.instructions;
434
    } else {
435
      if(!runtime.sim.hush)
436 1545 nogj
        sched_next_insn(print_insn_exec, NULL);
437 1471 nogj
    }
438
  } else
439
    /* Run 0 instructions */
440
    return 0;
441
 
442 1353 nogj
  return 1;
443
}
444
 
445
static int sim_cmd_stall(int argc, char **argv) /* Added by CZ 210801 */
446
{
447 1479 nogj
#if DYNAMIC_EXECUTION
448
  PRINTF("Can't stall the cpu with the dynamic recompiler\n");
449
  return 0;
450
#else
451 1353 nogj
  set_stall_state (1);
452
  runtime.sim.iprompt = 0;
453
  runtime.sim.hush = 1;
454
  return 1;
455 1479 nogj
#endif
456 1353 nogj
}
457
 
458
static int sim_cmd_stats(int argc, char **argv) /* stats */
459
{
460
  if(argc != 2) {
461
    PRINTF("stats <stat no. or `clear'>\n");
462
    return 0;
463
  }
464
 
465
  if(strcmp(argv[1], "clear") == 0) {
466
    initstats();
467
    PRINTF("Cleared.\n");
468
  } else {
469
    printstats(strtoul(argv[1], NULL, 0));
470
  }
471
  return 0;
472
}
473
 
474
static int sim_cmd_info(int argc, char **argv) /* configuration info */
475
{
476 1363 nogj
  struct sim_stat *cur_stat = sim_stats;
477
 
478 1353 nogj
  /* Display info about various modules */
479
  sprs_status();
480
  PRINTF ("\n");
481
  memory_table_status ();
482
  if (config.dmmu.enabled) dtlb_status(-1);
483
  if (config.ic.enabled) ic_info();
484
  if (config.dc.enabled) dc_info();
485
 
486
  if (config.bpb.enabled) bpb_info();
487
  if (config.bpb.btic) btic_info();
488
 
489 1363 nogj
  while(cur_stat) {
490
    cur_stat->stat_func(cur_stat->dat);
491
    cur_stat = cur_stat->next;
492
  }
493
 
494 1353 nogj
  return 0;
495
}
496
 
497 1389 nogj
static int sim_cmd_setdbch(int argc, char **argv) /* Toggle debug channel on/off */
498
{
499
  if(argc != 2) {
500
    PRINTF("setdbch <channel>\n");
501
    return 0;
502
  }
503
  parse_dbchs(argv[1]);
504
  return 0;
505
}
506
 
507 1353 nogj
static int sim_cmd_debug(int argc, char **argv) /* debug mode */
508
{
509
  config.sim.debug ^= 1;
510
  return 0;
511
}
512
 
513
static int sim_cmd_profile(int argc, char **argv) /* run profiler utility */
514
{
515
  main_profiler(argc, argv);
516
  return 0;
517
}
518
 
519
static int sim_cmd_mprofile(int argc, char **argv) /* run mprofiler utility */
520
{
521
  main_mprofiler(argc, argv);
522
  return 0;
523
}
524
 
525
static int sim_cmd_cuc(int argc, char **argv) /* run Custom Unit Compiler */
526
{
527
  main_cuc(runtime.sim.filename);
528
  return 0;
529
}
530
 
531
static int sim_cmd_set(int argc, char **argv) /* configuration info */
532
{
533
  set_config_command(argc, argv);
534
  return 0;
535
}
536
 
537
static char *strip_space(char *str)
538
{
539
  while(isblank(*str) && *str) str++;
540
  return str;
541
}
542
 
543
struct sim_command {
544
  const char *name;
545
  int (*cmd_handle)(int argc, char **argv);
546
};
547
 
548
static const struct sim_command sim_commands[] = {
549
 { "q", sim_cmd_quit },
550
 { "help", sim_cmd_help },
551
 { "t", sim_cmd_trace },
552
 { "dm", sim_cmd_dm },
553
 { "dv", sim_cmd_dv },
554
 { "dh", sim_cmd_dh },
555
 { "pm", sim_cmd_pm },
556
 { "cm", sim_cmd_cm },
557
 { "pr", sim_cmd_pr },
558
 { "pc", sim_cmd_pc },
559
 { "breaks", sim_cmd_breaks },
560
 { "break", sim_cmd_break },
561
 { "r", sim_cmd_r },
562
 { "de", sim_cmd_de },
563
 { "reset", sim_cmd_reset },
564
 { "hist", sim_cmd_hist },
565
 { "stall", sim_cmd_stall },
566
 { "stats", sim_cmd_stats },
567
 { "info", sim_cmd_info },
568
 { "run", sim_cmd_run },
569 1389 nogj
 { "setdbch", sim_cmd_setdbch },
570 1353 nogj
 { "debug", sim_cmd_debug },
571
 { "profile", sim_cmd_profile },
572
 { "mprofile", sim_cmd_mprofile },
573
 { "cuc", sim_cmd_cuc },
574
 { "set", sim_cmd_set },
575
 { NULL, NULL } };
576
 
577
#ifdef HAVE_LIBREADLINE
578
static void initialize_readline(void);
579
#endif
580
 
581
void handle_sim_command(void)
582
{
583
  char *redirstr;
584
  int argc;
585
  char *argv[5];
586
  char *cur_arg;
587
  const struct sim_command *cur_cmd;
588
#ifdef HAVE_LIBREADLINE
589
  static char *prev_str = NULL;
590
#else
591
  char b2[500];
592
  static char prev_str[500] = { 0 };
593
#endif
594
 
595 1593 nogj
  runtime.sim.iprompt_run = 1;
596
 
597 1471 nogj
  /* Make sure that check_insn_exec is not left hanging in the scheduler (and
598
   * breaking the sim when the user doesn't want it to break). */
599
  SCHED_FIND_REMOVE(check_insn_exec, NULL);
600
  SCHED_FIND_REMOVE(print_insn_exec, NULL);
601
 
602 1353 nogj
#ifdef HAVE_LIBREADLINE
603
  initialize_readline (); /* Bind our completer. */
604
#endif
605
 
606
  for(;;) {
607
#ifdef HAVE_LIBREADLINE
608
    cur_arg = readline("(sim) ");
609
#else
610
    PRINTF("(sim) ");
611
    if(config.debug.gdb_enabled) {
612
      fflush(stdout);
613
      HandleServerSocket(true);  /* block & check_stdin = true */
614
    }
615
 
616
    cur_arg = fgets(b2, sizeof(b2), stdin);
617
 
618 1596 nogj
    if(!cur_arg)
619
      sim_done();
620
 
621 1353 nogj
    if (!*cur_arg) {
622
      usleep(1000);
623
      continue;
624
    }
625
#endif
626
 
627
#ifdef HAVE_LIBREADLINE
628
    if(!*cur_arg) {
629
      if(prev_str) {
630
        free(cur_arg);
631
        cur_arg = prev_str;
632
      }
633
    } else {
634
      prev_str = cur_arg;
635
      add_history(cur_arg);
636
    }
637
#else
638
    cur_arg = strip_space(cur_arg);
639
    if(*cur_arg == '\n')
640
      strcpy(cur_arg, prev_str);
641
    else
642
      strcpy(prev_str, cur_arg);
643
#endif
644
 
645
    if((redirstr = strchr(cur_arg, '>'))) {
646
      redirstr = strip_space(++redirstr);
647
 
648
      while(!isspace(*redirstr) && *redirstr) redirstr++;
649
      *redirstr = '\0';
650
 
651
      redirstr = strchr(cur_arg, '>');
652
      *redirstr = '\0';
653
 
654
      redirstr = strip_space(++redirstr);
655
      runtime.sim.fout = fopen(redirstr, "w+");
656
      if (!runtime.sim.fout) runtime.sim.fout = stdout;
657
    }
658
 
659
    if(*cur_arg) {
660
      argc = 0;
661
      while(*cur_arg) {
662
        argv[argc] = cur_arg;
663
        argc++;
664
        while(!isspace(*cur_arg) && *cur_arg) cur_arg++;
665
        if(*cur_arg) {
666
          *cur_arg = '\0';
667
          cur_arg = strip_space(cur_arg + 1);
668
        } else
669
          *cur_arg = '\0';
670
        if(argc == 5) {
671
          fprintf(stderr, "Too many arguments given to command `%s'\n", argv[0]);
672
          break;
673
        }
674
      }
675
 
676
      for(cur_cmd = sim_commands; cur_cmd->name; cur_cmd++) {
677
        if(!strcmp(cur_cmd->name, argv[0])) {
678 1471 nogj
          if(cur_cmd->cmd_handle(argc, argv)) {
679
            runtime.sim.iprompt = 0;
680 1593 nogj
            runtime.sim.iprompt_run = 0;
681 1353 nogj
            return;
682 1471 nogj
          }
683 1353 nogj
          break;
684
        }
685
      }
686
 
687
      if(!cur_cmd->name)
688
        PRINTF("%s: Unknown command.\n", argv[0]);
689
    }
690
  }
691
}
692
 
693
#ifdef HAVE_LIBREADLINE
694
 
695
int check_gdb_comm(void)
696
{
697
  HandleServerSocket(true);  /* block & check_stdin = true */
698
  return 0;
699
}
700
 
701
char *command_generator();
702
char **sim_completion();
703
 
704
/* Tell the GNU readline library how to complete.  We want to try to complete
705
   on command names if this is the first word in the line, or on filenames
706
   if not. */
707
static void initialize_readline(void)
708
{
709
  /* Allow conditional parsing of the ~/.inputrc file. */
710
  rl_readline_name = "or1ksim";
711
 
712
  /* Tell the completer that we want a crack first. */
713
  rl_attempted_completion_function = sim_completion;
714
 
715
  /* Handle the gdb socket while waiting for input */
716
  rl_event_hook = check_gdb_comm;
717
}
718
 
719
/* Attempt to complete on the contents of TEXT.  START and END bound the
720
   region of rl_line_buffer that contains the word to complete.  TEXT is
721
   the word to complete.  We can use the entire contents of rl_line_buffer
722
   in case we want to do some simple parsing.  Return the array of matches,
723
   or NULL if there aren't any. */
724
/* FIXME: Handle arguments to the `set' command */
725
char **sim_completion(char *text, int start, int end)
726
{
727
  char **matches;
728
 
729
  matches = NULL;
730
 
731
  /* If this word is at the start of the line, then it is a command
732
     to complete.  Otherwise it is the name of a file in the current
733
     directory. */
734
  if(!start)
735
    matches = rl_completion_matches(text, command_generator);
736
 
737
  return matches;
738
}
739
 
740
/* Generator function for command completion.  STATE lets us know whether
741
   to start from scratch; without any state (i.e. STATE == 0), then we
742
   start at the top of the list. */
743
char *command_generator(char *text, int state)
744
{
745
  static int list_index, len;
746
  const char *name;
747
 
748
  /* If this is a new word to complete, initialize now.  This includes
749
     saving the length of TEXT for efficiency, and initializing the index
750
     variable to 0. */
751
  if(!state) {
752
    list_index = 0;
753
    len = strlen(text);
754
  }
755
 
756
  /* Return the next name which partially matches from the command list. */
757
  while((name = sim_commands[list_index].name)) {
758
    list_index++;
759
 
760
    if(strncmp(name, text, len) == 0)
761
      return strdup(name);
762
  }
763
 
764
  /* If no names matched, then return NULL. */
765
  return NULL;
766
}
767
 
768
/* Repeats the last command.  */
769
char *repeat_last_command ()
770
{
771
  int offset = where_history ();
772
  HIST_ENTRY *hist;
773
 
774
  if((hist = history_get(offset)))
775
    return strdup(hist->line);
776
  return 0;
777
}
778
 
779
#endif
780
 

powered by: WebSVN 2.1.0

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