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

Subversion Repositories or1k

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

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 1643 nogj
      set_insnbrkpoint(l->addr);
334 1353 nogj
    else
335 1643 nogj
      PRINTF("Label `%s' does not exist\n", argv[1]);
336
  } else
337
    set_insnbrkpoint(addr);
338 1353 nogj
  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.ic.enabled) ic_info();
483
  if (config.dc.enabled) dc_info();
484
 
485
  if (config.bpb.enabled) bpb_info();
486
  if (config.bpb.btic) btic_info();
487
 
488 1363 nogj
  while(cur_stat) {
489
    cur_stat->stat_func(cur_stat->dat);
490
    cur_stat = cur_stat->next;
491
  }
492
 
493 1353 nogj
  return 0;
494
}
495
 
496 1389 nogj
static int sim_cmd_setdbch(int argc, char **argv) /* Toggle debug channel on/off */
497
{
498
  if(argc != 2) {
499
    PRINTF("setdbch <channel>\n");
500
    return 0;
501
  }
502
  parse_dbchs(argv[1]);
503
  return 0;
504
}
505
 
506 1353 nogj
static int sim_cmd_debug(int argc, char **argv) /* debug mode */
507
{
508
  config.sim.debug ^= 1;
509
  return 0;
510
}
511
 
512
static int sim_cmd_profile(int argc, char **argv) /* run profiler utility */
513
{
514
  main_profiler(argc, argv);
515
  return 0;
516
}
517
 
518
static int sim_cmd_mprofile(int argc, char **argv) /* run mprofiler utility */
519
{
520
  main_mprofiler(argc, argv);
521
  return 0;
522
}
523
 
524
static int sim_cmd_cuc(int argc, char **argv) /* run Custom Unit Compiler */
525
{
526
  main_cuc(runtime.sim.filename);
527
  return 0;
528
}
529
 
530
static int sim_cmd_set(int argc, char **argv) /* configuration info */
531
{
532
  set_config_command(argc, argv);
533
  return 0;
534
}
535
 
536
static char *strip_space(char *str)
537
{
538
  while(isblank(*str) && *str) str++;
539
  return str;
540
}
541
 
542
struct sim_command {
543
  const char *name;
544
  int (*cmd_handle)(int argc, char **argv);
545
};
546
 
547
static const struct sim_command sim_commands[] = {
548
 { "q", sim_cmd_quit },
549
 { "help", sim_cmd_help },
550
 { "t", sim_cmd_trace },
551
 { "dm", sim_cmd_dm },
552
 { "dv", sim_cmd_dv },
553
 { "dh", sim_cmd_dh },
554
 { "pm", sim_cmd_pm },
555
 { "cm", sim_cmd_cm },
556
 { "pr", sim_cmd_pr },
557
 { "pc", sim_cmd_pc },
558
 { "breaks", sim_cmd_breaks },
559
 { "break", sim_cmd_break },
560
 { "r", sim_cmd_r },
561
 { "de", sim_cmd_de },
562
 { "reset", sim_cmd_reset },
563
 { "hist", sim_cmd_hist },
564
 { "stall", sim_cmd_stall },
565
 { "stats", sim_cmd_stats },
566
 { "info", sim_cmd_info },
567
 { "run", sim_cmd_run },
568 1389 nogj
 { "setdbch", sim_cmd_setdbch },
569 1353 nogj
 { "debug", sim_cmd_debug },
570
 { "profile", sim_cmd_profile },
571
 { "mprofile", sim_cmd_mprofile },
572
 { "cuc", sim_cmd_cuc },
573
 { "set", sim_cmd_set },
574
 { NULL, NULL } };
575
 
576
#ifdef HAVE_LIBREADLINE
577
static void initialize_readline(void);
578
#endif
579
 
580
void handle_sim_command(void)
581
{
582
  char *redirstr;
583
  int argc;
584
  char *argv[5];
585
  char *cur_arg;
586
  const struct sim_command *cur_cmd;
587
#ifdef HAVE_LIBREADLINE
588
  static char *prev_str = NULL;
589
#else
590
  char b2[500];
591
  static char prev_str[500] = { 0 };
592
#endif
593
 
594 1593 nogj
  runtime.sim.iprompt_run = 1;
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 1596 nogj
    if(!cur_arg)
618
      sim_done();
619
 
620 1353 nogj
    if (!*cur_arg) {
621
      usleep(1000);
622
      continue;
623
    }
624
#endif
625
 
626
#ifdef HAVE_LIBREADLINE
627
    if(!*cur_arg) {
628
      if(prev_str) {
629
        free(cur_arg);
630
        cur_arg = prev_str;
631
      }
632
    } else {
633
      prev_str = cur_arg;
634
      add_history(cur_arg);
635
    }
636
#else
637
    cur_arg = strip_space(cur_arg);
638
    if(*cur_arg == '\n')
639
      strcpy(cur_arg, prev_str);
640
    else
641
      strcpy(prev_str, cur_arg);
642
#endif
643
 
644
    if((redirstr = strchr(cur_arg, '>'))) {
645
      redirstr = strip_space(++redirstr);
646
 
647
      while(!isspace(*redirstr) && *redirstr) redirstr++;
648
      *redirstr = '\0';
649
 
650
      redirstr = strchr(cur_arg, '>');
651
      *redirstr = '\0';
652
 
653
      redirstr = strip_space(++redirstr);
654
      runtime.sim.fout = fopen(redirstr, "w+");
655
      if (!runtime.sim.fout) runtime.sim.fout = stdout;
656
    }
657
 
658
    if(*cur_arg) {
659
      argc = 0;
660
      while(*cur_arg) {
661
        argv[argc] = cur_arg;
662
        argc++;
663
        while(!isspace(*cur_arg) && *cur_arg) cur_arg++;
664
        if(*cur_arg) {
665
          *cur_arg = '\0';
666
          cur_arg = strip_space(cur_arg + 1);
667
        } else
668
          *cur_arg = '\0';
669
        if(argc == 5) {
670
          fprintf(stderr, "Too many arguments given to command `%s'\n", argv[0]);
671
          break;
672
        }
673
      }
674
 
675
      for(cur_cmd = sim_commands; cur_cmd->name; cur_cmd++) {
676
        if(!strcmp(cur_cmd->name, argv[0])) {
677 1471 nogj
          if(cur_cmd->cmd_handle(argc, argv)) {
678
            runtime.sim.iprompt = 0;
679 1593 nogj
            runtime.sim.iprompt_run = 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-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.