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 1484

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

powered by: WebSVN 2.1.0

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