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

Subversion Repositories or1k

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

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

powered by: WebSVN 2.1.0

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