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

Subversion Repositories or1k

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

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

powered by: WebSVN 2.1.0

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