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

Subversion Repositories or1k

[/] [or1k/] [tags/] [stable_0_2_0/] [or1ksim/] [sim-cmd.c] - Blame information for rev 1487

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 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
/* 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 1487 nogj
    set_direct32(to + i, eval_direct32(from + i, 0, 0), 0, 0);
291 1353 nogj
  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 1479 nogj
#if DYNAMIC_EXECUTION
332
  PRINTF("Setting simulator breakpoints is not support with the recompiler\n");
333
  return 0;
334
#else
335 1353 nogj
  char *p;
336
  oraddr_t addr;
337
  struct label_entry *l;
338
 
339
  if(argc != 2) {
340
    PRINTF("break <label or address>\n");
341
    return 0;
342
  }
343
 
344
  addr = strtoul(argv[1], &p, 0);
345
  if(*p) {
346
    l = find_label(argv[1]);
347
    if(l)
348
      addr = l->addr;
349
    else
350
      PRINTF("Label `%s' does not exist\n", l->name);
351
  }
352
  set_insnbrkpoint(addr);
353
  return 0;
354 1479 nogj
#endif
355 1353 nogj
}
356
 
357
static int sim_cmd_r(int argc, char **argv) /* dump regs */
358
{
359
  dumpreg();
360
  return 0;
361
}
362
 
363
static int sim_cmd_de(int argc, char **argv) /* disassemble */
364
{
365
  static oraddr_t from = 0, to = 0;
366
 
367
  if(argc >= 2) {
368
    if (argv[1][0] == '_')
369
      from = eval_label(argv[1]);
370
    else
371
      from = strtoul(argv[1], NULL, 0);
372
    to = from + 0x40;
373
  }
374
 
375
  if(argc >= 3)
376
    to = strtoul(argv[2], NULL, 0);
377
 
378
  debugmem(from, to);
379
  PRINTF("\n");
380
  return 0;
381
}
382
 
383
static int sim_cmd_reset(int argc, char **argv) /* reset simulator */
384
{
385
  sim_reset();
386
  return 0;
387
}
388
 
389
static int sim_cmd_hist(int argc, char **argv) /* dump history */
390
{
391
  int i;
392
  struct hist_exec *cur;
393
  if(!config.sim.history) {
394
    PRINTF("Simulation history disabled.\n");
395
    return 0;
396
  }
397
  for(i = HISTEXEC_LEN, cur = hist_exec_tail->prev; i; i--, cur = cur->prev)
398
    dumpmemory(cur->addr, cur->addr + 4, 1, 1);
399
  PRINTF("\n");
400
  return 0;
401
}
402
 
403 1471 nogj
/* Called when it is suspisous that runtime.sim.instructions has reached
404
 * to_insn_num */
405
void check_insn_exec(void *dat)
406
{
407
  if(runtime.cpu.instructions < to_insn_num) {
408
    /* Instruction count has not yet been reached, reschedule */
409
    SCHED_ADD(check_insn_exec, NULL, to_insn_num - runtime.cpu.instructions);
410
    return;
411
  }
412
  handle_sim_command();
413
}
414
 
415
void print_insn_exec(void *dat)
416
{
417
  dumpreg();
418
  if(runtime.cpu.instructions < to_insn_num) {
419
    /* Instruction count has not yet been reached, reschedule */
420
    sched_next_insn(print_insn_exec);
421
    return;
422
  }
423
  handle_sim_command();
424
}
425
 
426 1353 nogj
static int sim_cmd_run(int argc, char **argv) /* run */
427
{
428 1471 nogj
  runtime.sim.hush = 0;
429 1353 nogj
  if(argc >= 3) {
430
    if(!strcmp(argv[2], "hush"))
431
      runtime.sim.hush = 1;
432
  }
433
 
434 1471 nogj
  if(argc >= 2) {
435
    if((to_insn_num = strtol(argv[1], NULL, 0)) != -1) {
436
      if(runtime.sim.hush) {
437
        /* Schedule a job to run in to_insn_num cycles time since an instruction
438
         * may execute in only 1 cycle.  check_insn_exec will check if the right
439
         * number of instructions have been executed.  If not it will
440
         * reschedule.  */
441
        SCHED_ADD(check_insn_exec, NULL, to_insn_num);
442
      } else {
443
        /* The user wants to see the execution dumps.  Schedule a task to show
444
         * it to him after each cycle */
445
        sched_next_insn(print_insn_exec);
446
      }
447
      to_insn_num += runtime.cpu.instructions;
448
    } else {
449
      if(!runtime.sim.hush)
450
        sched_next_insn(print_insn_exec);
451
    }
452
  } else
453
    /* Run 0 instructions */
454
    return 0;
455
 
456 1353 nogj
  return 1;
457
}
458
 
459
static int sim_cmd_stall(int argc, char **argv) /* Added by CZ 210801 */
460
{
461 1479 nogj
#if DYNAMIC_EXECUTION
462
  PRINTF("Can't stall the cpu with the dynamic recompiler\n");
463
  return 0;
464
#else
465 1353 nogj
  set_stall_state (1);
466
  runtime.sim.iprompt = 0;
467
  runtime.sim.hush = 1;
468
  return 1;
469 1479 nogj
#endif
470 1353 nogj
}
471
 
472
static int sim_cmd_stats(int argc, char **argv) /* stats */
473
{
474
  if(argc != 2) {
475
    PRINTF("stats <stat no. or `clear'>\n");
476
    return 0;
477
  }
478
 
479
  if(strcmp(argv[1], "clear") == 0) {
480
    initstats();
481
    PRINTF("Cleared.\n");
482
  } else {
483
    printstats(strtoul(argv[1], NULL, 0));
484
  }
485
  return 0;
486
}
487
 
488
static int sim_cmd_info(int argc, char **argv) /* configuration info */
489
{
490 1363 nogj
  struct sim_stat *cur_stat = sim_stats;
491
 
492 1353 nogj
  /* Display info about various modules */
493
  sprs_status();
494
  PRINTF ("\n");
495
  memory_table_status ();
496
  if (config.immu.enabled) itlb_status(-1);
497
  if (config.dmmu.enabled) dtlb_status(-1);
498
  if (config.ic.enabled) ic_info();
499
  if (config.dc.enabled) dc_info();
500
 
501
  if (config.bpb.enabled) bpb_info();
502
  if (config.bpb.btic) btic_info();
503
 
504 1363 nogj
  while(cur_stat) {
505
    cur_stat->stat_func(cur_stat->dat);
506
    cur_stat = cur_stat->next;
507
  }
508
 
509 1353 nogj
  return 0;
510
}
511
 
512 1389 nogj
static int sim_cmd_setdbch(int argc, char **argv) /* Toggle debug channel on/off */
513
{
514
  if(argc != 2) {
515
    PRINTF("setdbch <channel>\n");
516
    return 0;
517
  }
518
  parse_dbchs(argv[1]);
519
  return 0;
520
}
521
 
522 1353 nogj
static int sim_cmd_debug(int argc, char **argv) /* debug mode */
523
{
524
  config.sim.debug ^= 1;
525
  return 0;
526
}
527
 
528
static int sim_cmd_profile(int argc, char **argv) /* run profiler utility */
529
{
530
  main_profiler(argc, argv);
531
  return 0;
532
}
533
 
534
static int sim_cmd_mprofile(int argc, char **argv) /* run mprofiler utility */
535
{
536
  main_mprofiler(argc, argv);
537
  return 0;
538
}
539
 
540
static int sim_cmd_cuc(int argc, char **argv) /* run Custom Unit Compiler */
541
{
542
  main_cuc(runtime.sim.filename);
543
  return 0;
544
}
545
 
546
static int sim_cmd_set(int argc, char **argv) /* configuration info */
547
{
548
  set_config_command(argc, argv);
549
  return 0;
550
}
551
 
552
static char *strip_space(char *str)
553
{
554
  while(isblank(*str) && *str) str++;
555
  return str;
556
}
557
 
558
struct sim_command {
559
  const char *name;
560
  int (*cmd_handle)(int argc, char **argv);
561
};
562
 
563
static const struct sim_command sim_commands[] = {
564
 { "q", sim_cmd_quit },
565
 { "help", sim_cmd_help },
566
 { "t", sim_cmd_trace },
567
 { "dm", sim_cmd_dm },
568
 { "dv", sim_cmd_dv },
569
 { "dh", sim_cmd_dh },
570
 { "pm", sim_cmd_pm },
571
 { "cm", sim_cmd_cm },
572
 { "pr", sim_cmd_pr },
573
 { "pc", sim_cmd_pc },
574
 { "breaks", sim_cmd_breaks },
575
 { "break", sim_cmd_break },
576
 { "r", sim_cmd_r },
577
 { "de", sim_cmd_de },
578
 { "reset", sim_cmd_reset },
579
 { "hist", sim_cmd_hist },
580
 { "stall", sim_cmd_stall },
581
 { "stats", sim_cmd_stats },
582
 { "info", sim_cmd_info },
583
 { "run", sim_cmd_run },
584 1389 nogj
 { "setdbch", sim_cmd_setdbch },
585 1353 nogj
 { "debug", sim_cmd_debug },
586
 { "profile", sim_cmd_profile },
587
 { "mprofile", sim_cmd_mprofile },
588
 { "cuc", sim_cmd_cuc },
589
 { "set", sim_cmd_set },
590
 { NULL, NULL } };
591
 
592
#ifdef HAVE_LIBREADLINE
593
static void initialize_readline(void);
594
#endif
595
 
596
void handle_sim_command(void)
597
{
598
  char *redirstr;
599
  int argc;
600
  char *argv[5];
601
  char *cur_arg;
602
  const struct sim_command *cur_cmd;
603
#ifdef HAVE_LIBREADLINE
604
  static char *prev_str = NULL;
605
#else
606
  char b2[500];
607
  static char prev_str[500] = { 0 };
608
#endif
609
 
610 1471 nogj
  /* Make sure that check_insn_exec is not left hanging in the scheduler (and
611
   * breaking the sim when the user doesn't want it to break). */
612
  SCHED_FIND_REMOVE(check_insn_exec, NULL);
613
  SCHED_FIND_REMOVE(print_insn_exec, NULL);
614
 
615 1353 nogj
#ifdef HAVE_LIBREADLINE
616
  initialize_readline (); /* Bind our completer. */
617
#endif
618
 
619
  for(;;) {
620
#ifdef HAVE_LIBREADLINE
621
    cur_arg = readline("(sim) ");
622
#else
623
    PRINTF("(sim) ");
624
    if(config.debug.gdb_enabled) {
625
      fflush(stdout);
626
      HandleServerSocket(true);  /* block & check_stdin = true */
627
    }
628
 
629
    cur_arg = fgets(b2, sizeof(b2), stdin);
630
 
631
    if (!*cur_arg) {
632
      usleep(1000);
633
      continue;
634
    }
635
#endif
636
 
637
#ifdef HAVE_LIBREADLINE
638
    if(!*cur_arg) {
639
      if(prev_str) {
640
        free(cur_arg);
641
        cur_arg = prev_str;
642
      }
643
    } else {
644
      prev_str = cur_arg;
645
      add_history(cur_arg);
646
    }
647
#else
648
    cur_arg = strip_space(cur_arg);
649
    if(*cur_arg == '\n')
650
      strcpy(cur_arg, prev_str);
651
    else
652
      strcpy(prev_str, cur_arg);
653
#endif
654
 
655
    if((redirstr = strchr(cur_arg, '>'))) {
656
      redirstr = strip_space(++redirstr);
657
 
658
      while(!isspace(*redirstr) && *redirstr) redirstr++;
659
      *redirstr = '\0';
660
 
661
      redirstr = strchr(cur_arg, '>');
662
      *redirstr = '\0';
663
 
664
      redirstr = strip_space(++redirstr);
665
      runtime.sim.fout = fopen(redirstr, "w+");
666
      if (!runtime.sim.fout) runtime.sim.fout = stdout;
667
    }
668
 
669
    if(*cur_arg) {
670
      argc = 0;
671
      while(*cur_arg) {
672
        argv[argc] = cur_arg;
673
        argc++;
674
        while(!isspace(*cur_arg) && *cur_arg) cur_arg++;
675
        if(*cur_arg) {
676
          *cur_arg = '\0';
677
          cur_arg = strip_space(cur_arg + 1);
678
        } else
679
          *cur_arg = '\0';
680
        if(argc == 5) {
681
          fprintf(stderr, "Too many arguments given to command `%s'\n", argv[0]);
682
          break;
683
        }
684
      }
685
 
686
      for(cur_cmd = sim_commands; cur_cmd->name; cur_cmd++) {
687
        if(!strcmp(cur_cmd->name, argv[0])) {
688 1471 nogj
          if(cur_cmd->cmd_handle(argc, argv)) {
689
            runtime.sim.iprompt = 0;
690 1353 nogj
            return;
691 1471 nogj
          }
692 1353 nogj
          break;
693
        }
694
      }
695
 
696
      if(!cur_cmd->name)
697
        PRINTF("%s: Unknown command.\n", argv[0]);
698
    }
699
  }
700
}
701
 
702
#ifdef HAVE_LIBREADLINE
703
 
704
int check_gdb_comm(void)
705
{
706
  HandleServerSocket(true);  /* block & check_stdin = true */
707
  return 0;
708
}
709
 
710
char *command_generator();
711
char **sim_completion();
712
 
713
/* Tell the GNU readline library how to complete.  We want to try to complete
714
   on command names if this is the first word in the line, or on filenames
715
   if not. */
716
static void initialize_readline(void)
717
{
718
  /* Allow conditional parsing of the ~/.inputrc file. */
719
  rl_readline_name = "or1ksim";
720
 
721
  /* Tell the completer that we want a crack first. */
722
  rl_attempted_completion_function = sim_completion;
723
 
724
  /* Handle the gdb socket while waiting for input */
725
  rl_event_hook = check_gdb_comm;
726
}
727
 
728
/* Attempt to complete on the contents of TEXT.  START and END bound the
729
   region of rl_line_buffer that contains the word to complete.  TEXT is
730
   the word to complete.  We can use the entire contents of rl_line_buffer
731
   in case we want to do some simple parsing.  Return the array of matches,
732
   or NULL if there aren't any. */
733
/* FIXME: Handle arguments to the `set' command */
734
char **sim_completion(char *text, int start, int end)
735
{
736
  char **matches;
737
 
738
  matches = NULL;
739
 
740
  /* If this word is at the start of the line, then it is a command
741
     to complete.  Otherwise it is the name of a file in the current
742
     directory. */
743
  if(!start)
744
    matches = rl_completion_matches(text, command_generator);
745
 
746
  return matches;
747
}
748
 
749
/* Generator function for command completion.  STATE lets us know whether
750
   to start from scratch; without any state (i.e. STATE == 0), then we
751
   start at the top of the list. */
752
char *command_generator(char *text, int state)
753
{
754
  static int list_index, len;
755
  const char *name;
756
 
757
  /* If this is a new word to complete, initialize now.  This includes
758
     saving the length of TEXT for efficiency, and initializing the index
759
     variable to 0. */
760
  if(!state) {
761
    list_index = 0;
762
    len = strlen(text);
763
  }
764
 
765
  /* Return the next name which partially matches from the command list. */
766
  while((name = sim_commands[list_index].name)) {
767
    list_index++;
768
 
769
    if(strncmp(name, text, len) == 0)
770
      return strdup(name);
771
  }
772
 
773
  /* If no names matched, then return NULL. */
774
  return NULL;
775
}
776
 
777
/* Repeats the last command.  */
778
char *repeat_last_command ()
779
{
780
  int offset = where_history ();
781
  HIST_ENTRY *hist;
782
 
783
  if((hist = history_get(offset)))
784
    return strdup(hist->line);
785
  return 0;
786
}
787
 
788
#endif
789
 

powered by: WebSVN 2.1.0

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