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

Subversion Repositories or1k

[/] [or1k/] [tags/] [stable_0_2_0_rc3/] [or1ksim/] [sim-cmd.c] - Blame information for rev 1471

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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