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

Subversion Repositories or1k

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

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.dc.enabled) dc_info();
483
 
484
  if (config.bpb.enabled) bpb_info();
485
  if (config.bpb.btic) btic_info();
486
 
487 1363 nogj
  while(cur_stat) {
488
    cur_stat->stat_func(cur_stat->dat);
489
    cur_stat = cur_stat->next;
490
  }
491
 
492 1353 nogj
  return 0;
493
}
494
 
495 1389 nogj
static int sim_cmd_setdbch(int argc, char **argv) /* Toggle debug channel on/off */
496
{
497
  if(argc != 2) {
498
    PRINTF("setdbch <channel>\n");
499
    return 0;
500
  }
501
  parse_dbchs(argv[1]);
502
  return 0;
503
}
504
 
505 1353 nogj
static int sim_cmd_debug(int argc, char **argv) /* debug mode */
506
{
507
  config.sim.debug ^= 1;
508
  return 0;
509
}
510
 
511
static int sim_cmd_profile(int argc, char **argv) /* run profiler utility */
512
{
513
  main_profiler(argc, argv);
514
  return 0;
515
}
516
 
517
static int sim_cmd_mprofile(int argc, char **argv) /* run mprofiler utility */
518
{
519
  main_mprofiler(argc, argv);
520
  return 0;
521
}
522
 
523
static int sim_cmd_cuc(int argc, char **argv) /* run Custom Unit Compiler */
524
{
525
  main_cuc(runtime.sim.filename);
526
  return 0;
527
}
528
 
529
static int sim_cmd_set(int argc, char **argv) /* configuration info */
530
{
531
  set_config_command(argc, argv);
532
  return 0;
533
}
534
 
535
static char *strip_space(char *str)
536
{
537
  while(isblank(*str) && *str) str++;
538
  return str;
539
}
540
 
541
struct sim_command {
542
  const char *name;
543
  int (*cmd_handle)(int argc, char **argv);
544
};
545
 
546
static const struct sim_command sim_commands[] = {
547
 { "q", sim_cmd_quit },
548
 { "help", sim_cmd_help },
549
 { "t", sim_cmd_trace },
550
 { "dm", sim_cmd_dm },
551
 { "dv", sim_cmd_dv },
552
 { "dh", sim_cmd_dh },
553
 { "pm", sim_cmd_pm },
554
 { "cm", sim_cmd_cm },
555
 { "pr", sim_cmd_pr },
556
 { "pc", sim_cmd_pc },
557
 { "breaks", sim_cmd_breaks },
558
 { "break", sim_cmd_break },
559
 { "r", sim_cmd_r },
560
 { "de", sim_cmd_de },
561
 { "reset", sim_cmd_reset },
562
 { "hist", sim_cmd_hist },
563
 { "stall", sim_cmd_stall },
564
 { "stats", sim_cmd_stats },
565
 { "info", sim_cmd_info },
566
 { "run", sim_cmd_run },
567 1389 nogj
 { "setdbch", sim_cmd_setdbch },
568 1353 nogj
 { "debug", sim_cmd_debug },
569
 { "profile", sim_cmd_profile },
570
 { "mprofile", sim_cmd_mprofile },
571
 { "cuc", sim_cmd_cuc },
572
 { "set", sim_cmd_set },
573
 { NULL, NULL } };
574
 
575
#ifdef HAVE_LIBREADLINE
576
static void initialize_readline(void);
577
#endif
578
 
579
void handle_sim_command(void)
580
{
581
  char *redirstr;
582
  int argc;
583
  char *argv[5];
584
  char *cur_arg;
585
  const struct sim_command *cur_cmd;
586
#ifdef HAVE_LIBREADLINE
587
  static char *prev_str = NULL;
588
#else
589
  char b2[500];
590
  static char prev_str[500] = { 0 };
591
#endif
592
 
593 1593 nogj
  runtime.sim.iprompt_run = 1;
594
 
595 1471 nogj
  /* Make sure that check_insn_exec is not left hanging in the scheduler (and
596
   * breaking the sim when the user doesn't want it to break). */
597
  SCHED_FIND_REMOVE(check_insn_exec, NULL);
598
  SCHED_FIND_REMOVE(print_insn_exec, NULL);
599
 
600 1353 nogj
#ifdef HAVE_LIBREADLINE
601
  initialize_readline (); /* Bind our completer. */
602
#endif
603
 
604
  for(;;) {
605
#ifdef HAVE_LIBREADLINE
606
    cur_arg = readline("(sim) ");
607
#else
608
    PRINTF("(sim) ");
609
    if(config.debug.gdb_enabled) {
610
      fflush(stdout);
611
      HandleServerSocket(true);  /* block & check_stdin = true */
612
    }
613
 
614
    cur_arg = fgets(b2, sizeof(b2), stdin);
615
 
616 1596 nogj
    if(!cur_arg)
617
      sim_done();
618
 
619 1353 nogj
    if (!*cur_arg) {
620
      usleep(1000);
621
      continue;
622
    }
623
#endif
624
 
625
#ifdef HAVE_LIBREADLINE
626
    if(!*cur_arg) {
627
      if(prev_str) {
628
        free(cur_arg);
629
        cur_arg = prev_str;
630
      }
631
    } else {
632
      prev_str = cur_arg;
633
      add_history(cur_arg);
634
    }
635
#else
636
    cur_arg = strip_space(cur_arg);
637
    if(*cur_arg == '\n')
638
      strcpy(cur_arg, prev_str);
639
    else
640
      strcpy(prev_str, cur_arg);
641
#endif
642
 
643
    if((redirstr = strchr(cur_arg, '>'))) {
644
      redirstr = strip_space(++redirstr);
645
 
646
      while(!isspace(*redirstr) && *redirstr) redirstr++;
647
      *redirstr = '\0';
648
 
649
      redirstr = strchr(cur_arg, '>');
650
      *redirstr = '\0';
651
 
652
      redirstr = strip_space(++redirstr);
653
      runtime.sim.fout = fopen(redirstr, "w+");
654
      if (!runtime.sim.fout) runtime.sim.fout = stdout;
655
    }
656
 
657
    if(*cur_arg) {
658
      argc = 0;
659
      while(*cur_arg) {
660
        argv[argc] = cur_arg;
661
        argc++;
662
        while(!isspace(*cur_arg) && *cur_arg) cur_arg++;
663
        if(*cur_arg) {
664
          *cur_arg = '\0';
665
          cur_arg = strip_space(cur_arg + 1);
666
        } else
667
          *cur_arg = '\0';
668
        if(argc == 5) {
669
          fprintf(stderr, "Too many arguments given to command `%s'\n", argv[0]);
670
          break;
671
        }
672
      }
673
 
674
      for(cur_cmd = sim_commands; cur_cmd->name; cur_cmd++) {
675
        if(!strcmp(cur_cmd->name, argv[0])) {
676 1471 nogj
          if(cur_cmd->cmd_handle(argc, argv)) {
677
            runtime.sim.iprompt = 0;
678 1593 nogj
            runtime.sim.iprompt_run = 0;
679 1353 nogj
            return;
680 1471 nogj
          }
681 1353 nogj
          break;
682
        }
683
      }
684
 
685
      if(!cur_cmd->name)
686
        PRINTF("%s: Unknown command.\n", argv[0]);
687
    }
688
  }
689
}
690
 
691
#ifdef HAVE_LIBREADLINE
692
 
693
int check_gdb_comm(void)
694
{
695
  HandleServerSocket(true);  /* block & check_stdin = true */
696
  return 0;
697
}
698
 
699
char *command_generator();
700
char **sim_completion();
701
 
702
/* Tell the GNU readline library how to complete.  We want to try to complete
703
   on command names if this is the first word in the line, or on filenames
704
   if not. */
705
static void initialize_readline(void)
706
{
707
  /* Allow conditional parsing of the ~/.inputrc file. */
708
  rl_readline_name = "or1ksim";
709
 
710
  /* Tell the completer that we want a crack first. */
711
  rl_attempted_completion_function = sim_completion;
712
 
713
  /* Handle the gdb socket while waiting for input */
714
  rl_event_hook = check_gdb_comm;
715
}
716
 
717
/* Attempt to complete on the contents of TEXT.  START and END bound the
718
   region of rl_line_buffer that contains the word to complete.  TEXT is
719
   the word to complete.  We can use the entire contents of rl_line_buffer
720
   in case we want to do some simple parsing.  Return the array of matches,
721
   or NULL if there aren't any. */
722
/* FIXME: Handle arguments to the `set' command */
723
char **sim_completion(char *text, int start, int end)
724
{
725
  char **matches;
726
 
727
  matches = NULL;
728
 
729
  /* If this word is at the start of the line, then it is a command
730
     to complete.  Otherwise it is the name of a file in the current
731
     directory. */
732
  if(!start)
733
    matches = rl_completion_matches(text, command_generator);
734
 
735
  return matches;
736
}
737
 
738
/* Generator function for command completion.  STATE lets us know whether
739
   to start from scratch; without any state (i.e. STATE == 0), then we
740
   start at the top of the list. */
741
char *command_generator(char *text, int state)
742
{
743
  static int list_index, len;
744
  const char *name;
745
 
746
  /* If this is a new word to complete, initialize now.  This includes
747
     saving the length of TEXT for efficiency, and initializing the index
748
     variable to 0. */
749
  if(!state) {
750
    list_index = 0;
751
    len = strlen(text);
752
  }
753
 
754
  /* Return the next name which partially matches from the command list. */
755
  while((name = sim_commands[list_index].name)) {
756
    list_index++;
757
 
758
    if(strncmp(name, text, len) == 0)
759
      return strdup(name);
760
  }
761
 
762
  /* If no names matched, then return NULL. */
763
  return NULL;
764
}
765
 
766
/* Repeats the last command.  */
767
char *repeat_last_command ()
768
{
769
  int offset = where_history ();
770
  HIST_ENTRY *hist;
771
 
772
  if((hist = history_get(offset)))
773
    return strdup(hist->line);
774
  return 0;
775
}
776
 
777
#endif
778
 

powered by: WebSVN 2.1.0

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