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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [sim-config.c] - Blame information for rev 220

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

Line No. Rev Author Line
1 19 jeremybenn
/* sim-config.c -- Simulator configuration
2
 
3
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
4
   Copyright (C) 2008 Embecosm Limited
5
 
6
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
7
 
8
   This file is part of OpenRISC 1000 Architectural Simulator.
9
 
10
   This program is free software; you can redistribute it and/or modify it
11
   under the terms of the GNU General Public License as published by the Free
12
   Software Foundation; either version 3 of the License, or (at your option)
13
   any later version.
14
 
15
   This program is distributed in the hope that it will be useful, but WITHOUT
16
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18
   more details.
19
 
20
   You should have received a copy of the GNU General Public License along
21
   with this program.  If not, see <http://www.gnu.org/licenses/>. */
22
 
23
/* This program is commented throughout in a fashion suitable for processing
24
   with Doxygen. */
25
 
26
/* Simulator configuration. Eventually this one will be a lot bigger. Updated
27
   to use argtable2 for argument parsing. */
28
 
29
 
30
/* Autoconf and/or portability configuration */
31
#include "config.h"
32
#include "port.h"
33
 
34
/* System includes */
35
#include <stdlib.h>
36
 
37
/* Package includes */
38
#include "sim-config.h"
39
#include "vapi.h"
40
#include "cuc.h"
41
#include "cpu-config.h"
42
#include "memory.h"
43
#include "dmmu.h"
44
#include "immu.h"
45
#include "dcache-model.h"
46
#include "icache-model.h"
47
#include "pic.h"
48
#include "pm.h"
49
#include "branch-predict.h"
50
#include "debug-unit.h"
51
#include "mc.h"
52
#include "16450.h"
53
#include "dma.h"
54
#include "eth.h"
55
#include "gpio.h"
56
#include "vga.h"
57
#include "fb.h"
58
#include "ps2kbd.h"
59
#include "atahost.h"
60
#include "generic.h"
61
#include "execute.h"
62
#include "spr-defs.h"
63
#include "debug.h"
64 82 jeremybenn
#include "jtag.h"
65 19 jeremybenn
#include "misc.h"
66
#include "argtable2.h"
67
 
68
 
69
struct config config;
70
struct runtime runtime;
71
 
72
struct config_section *cur_section;
73
 
74
struct config_section *sections = NULL;
75
 
76
/* Forward declarations */
77
static void read_script_file (const char *filename);
78
 
79
 
80
 
81
/*---------------------------------------------------------------------------*/
82
/*!Set default configuration parameters for fixed components
83
 
84
   These values are held in the global config variable. Parameter orders
85
   match the order in the corresponding section registration function and
86
   documentation.
87
 
88
   Also set some starting values for runtime elements.                       */
89
/*---------------------------------------------------------------------------*/
90
void
91
init_defconfig ()
92
{
93
  int  set_bits;                /* Temporaries for computing bit fields */
94
  int  way_bits;
95
 
96
  memset (&config, 0, sizeof (config));
97
 
98
  /* External linkage disabled here. */
99
  config.ext.class_ptr = NULL;
100
  config.ext.read_up   = NULL;
101
  config.ext.write_up  = NULL;
102
 
103
  /* Sim */
104 202 julius
  config.sim.is_library          = 0;    /* Not library operation */
105
  config.sim.verbose             = 0;
106
  config.sim.debug               = 0;
107
  config.sim.profile             = 0;
108
  config.sim.prof_fn             = strdup ("sim.profile");
109
  config.sim.mprofile            = 0;
110
  config.sim.mprof_fn            = strdup ("sim.mprofile");
111
  config.sim.history             = 0;
112
  config.sim.exe_log             = 0;
113
  config.sim.exe_log_type        = EXE_LOG_HARDWARE;
114
  config.sim.exe_log_start       = 0;
115
  config.sim.exe_log_end         = 0;
116
  config.sim.exe_log_marker      = 0;
117
  config.sim.exe_log_fn          = strdup ("executed.log");
118
  config.sim.exe_bin_insn_log    = 0;
119
  config.sim.exe_bin_insn_log_fn = strdup ("exe-insn.bin");
120
  config.sim.clkcycle_ps         = 4000;        /* 4000 for 4ns (250MHz) */
121 19 jeremybenn
 
122 82 jeremybenn
  /* Debug */
123
  config.debug.jtagcycle_ps = 40000;    /* 40000 for 40ns (25MHz) */
124
 
125 19 jeremybenn
  /* VAPI */
126
  config.vapi.enabled        = 0;
127
  config.vapi.server_port    = 50000;
128
  config.vapi.log_enabled    = 0;
129
  config.vapi.hide_device_id = 0;
130
  config.vapi.vapi_fn        = strdup ("vapi.log");
131
 
132
  /* CUC */
133
  config.cuc.calling_convention = 1;
134
  config.cuc.enable_bursts      = 1;
135
  config.cuc.no_multicycle      = 1;
136
  config.cuc.memory_order       = MO_STRONG;
137
  config.cuc.timings_fn         = strdup ("virtex.tim");
138
 
139
  /* CPU */
140
  cpu_state.sprs[SPR_VR]      = 0;
141
  cpu_state.sprs[SPR_UPR]     = SPR_UPR_UP | SPR_UPR_TTP;
142
  cpu_state.sprs[SPR_SR]      = SPR_SR_FO  | SPR_SR_SM;
143
  cpu_state.sprs[SPR_CPUCFGR] = SPR_CPUCFGR_OB32S;
144
  config.cpu.superscalar      = 0;
145
  config.cpu.hazards          = 0;
146
  config.cpu.dependstats      = 0;
147
  config.cpu.sbuf_len         = 0;
148 100 julius
  config.cpu.hardfloat        = 0;
149 19 jeremybenn
 
150
  /* Data cache (IC is set dynamically). Also set relevant SPR bits */
151
  config.dc.enabled         = 0;
152
  config.dc.nsets           = 1;
153
  config.dc.nways           = 1;
154
  config.dc.blocksize       = 1;
155
  config.dc.ustates         = 2;
156
  config.dc.load_hitdelay   = 2;
157
  config.dc.load_missdelay  = 2;
158
  config.dc.store_hitdelay  = 0;
159
  config.dc.store_missdelay = 0;
160
 
161
  if (config.dc.enabled)
162
    {
163
      cpu_state.sprs[SPR_UPR] |= SPR_UPR_DCP;
164
    }
165
  else
166
    {
167
      cpu_state.sprs[SPR_UPR] &= ~SPR_UPR_DCP;
168
    }
169
 
170
  set_bits = log2_int (config.dc.nsets);
171
  cpu_state.sprs[SPR_DCCFGR] &= ~SPR_DCCFGR_NCS;
172
  cpu_state.sprs[SPR_DCCFGR] |= set_bits << SPR_DCCFGR_NCS_OFF;
173
 
174
  way_bits = log2_int (config.dc.nways);
175
  cpu_state.sprs[SPR_DCCFGR] &= ~SPR_DCCFGR_NCW;
176
  cpu_state.sprs[SPR_DCCFGR] |= way_bits << SPR_DCCFGR_NCW_OFF;
177
 
178
  if (MIN_DC_BLOCK_SIZE == config.dc.blocksize)
179
    {
180
      cpu_state.sprs[SPR_DCCFGR] &= ~SPR_DCCFGR_CBS;
181
    }
182
  else
183
    {
184
      cpu_state.sprs[SPR_DCCFGR] |= SPR_DCCFGR_CBS;
185
    }
186
 
187
  /* Power management */
188
  config.pm.enabled = 0;
189
 
190
  if (config.pm.enabled)
191
    {
192
      cpu_state.sprs[SPR_UPR] |= SPR_UPR_PMP;
193
    }
194
  else
195
    {
196
      cpu_state.sprs[SPR_UPR] &= ~SPR_UPR_PMP;
197
    }
198
 
199
  /* Programmable Interrupt Controller */
200
  config.pic.enabled      = 0;
201
  config.pic.edge_trigger = 1;
202
 
203
  if (config.pic.enabled)
204
    {
205
      cpu_state.sprs[SPR_UPR] |= SPR_UPR_PICP;
206
    }
207
  else
208
    {
209
      cpu_state.sprs[SPR_UPR] &= ~SPR_UPR_PICP;
210
    }
211
 
212
  /* Branch Prediction */
213
  config.bpb.enabled     = 0;
214
  config.bpb.btic        = 0;
215
  config.bpb.sbp_bnf_fwd = 0;
216
  config.bpb.sbp_bf_fwd  = 0;
217
  config.bpb.missdelay   = 0;
218
  config.bpb.hitdelay    = 0;
219
 
220
  /* Debug */
221
  config.debug.enabled     = 0;
222
  config.debug.gdb_enabled = 0;
223
  config.debug.rsp_enabled = 0;
224
  config.debug.server_port = 51000;
225
  config.debug.rsp_port    = 51000;
226
  config.debug.vapi_id     = 0;
227
 
228
  cpu_state.sprs[SPR_DCFGR] = SPR_DCFGR_WPCI |
229
                              MATCHPOINTS_TO_NDP (MAX_MATCHPOINTS);
230
 
231
  if (config.debug.enabled)
232
    {
233
      cpu_state.sprs[SPR_UPR] |= SPR_UPR_DUP;
234
    }
235
  else
236
    {
237
      cpu_state.sprs[SPR_UPR] &= ~SPR_UPR_DUP;
238
    }
239
 
240
  /* Configure runtime */
241
  memset (&runtime, 0, sizeof (runtime));
242
 
243
  /* Sim */
244
  runtime.sim.fexe_log              = NULL;
245
  runtime.sim.iprompt               = 0;
246
  runtime.sim.fprof                 = NULL;
247
  runtime.sim.fmprof                = NULL;
248
  runtime.sim.fout                  = stdout;
249
 
250 82 jeremybenn
  /* Debug */
251
  runtime.debug.instr           = JI_UNDEFINED;
252
  runtime.debug.mod_id          = JM_UNDEFINED;
253
  runtime.debug.write_defined_p = 0;             /* No WRITE_COMMAND yet */
254
 
255 19 jeremybenn
  /* NPC state. Set to 1 when NPC is changed while the processor is stalled. */
256
  cpu_state.npc_not_valid = 0;
257
 
258
  /* VAPI */
259
  runtime.vapi.vapi_file = NULL;
260
  runtime.vapi.enabled   = 0;
261
 
262
}       /* init_defconfig() */
263
 
264
 
265
/*---------------------------------------------------------------------------*/
266
/*! Parse the arguments for the standalone simulator
267
 
268
    Updated by Jeremy Bennett to use argtable2.
269
 
270
    @param[in] argc  Number of command args
271
    @param[in] argv  Vector of the command args
272
 
273
    @return  0 on success, 1 on failure                                      */
274
/*---------------------------------------------------------------------------*/
275
int
276
parse_args (int argc, char *argv[])
277
{
278
  struct arg_lit *vercop;
279
  struct arg_lit *help;
280
  struct arg_file *cfg_file;
281
  struct arg_lit *nosrv;
282
  struct arg_int *srv;
283
  struct arg_str *dbg;
284
  struct arg_lit *command;
285 220 jeremybenn
  struct arg_lit *quiet;
286
  struct arg_lit *report_mem_errs;
287 19 jeremybenn
  struct arg_lit *strict_npc;
288
  struct arg_lit *profile;
289
  struct arg_lit *mprofile;
290
  struct arg_file *load_file;
291
  struct arg_end *end;
292
 
293 220 jeremybenn
  void *argtab[14];
294 19 jeremybenn
  int nerrors;
295
 
296
  /* Specify each argument, with fall back values */
297
  vercop = arg_lit0 ("v", "version", "version and copyright notice");
298
  help = arg_lit0 ("h", "help", "print this help message");
299
  cfg_file = arg_file0 ("f", "file", "<file>",
300
                        "config file (default \"sim.cfg\")");
301
  cfg_file->filename[0] = "sim.cfg";
302
  nosrv = arg_lit0 (NULL, "nosrv", "do not launch JTAG proxy server");
303
  srv = arg_int0 (NULL, "srv", "<n>", "port number (default random)");
304
  srv->ival[0] = rand () % (65536 - 49152) + 49152;
305
  srv->hdr.flag |= ARG_HASOPTVALUE;
306
  dbg = arg_str0 ("d", "debug-config", "<str>", "Debug config string");
307
  command = arg_lit0 ("i", "interactive", "launch interactive prompt");
308 220 jeremybenn
  quiet = arg_lit0 ("q", "quiet", "minimal message output");
309
  report_mem_errs = arg_lit0 (NULL, "report-memory-errors",
310
                              "Report out of memory accesses");
311 19 jeremybenn
  strict_npc = arg_lit0 (NULL, "strict-npc", "setting NPC flushes pipeline");
312
  profile = arg_lit0 (NULL, "enable-profile", "enable profiling");
313
  mprofile = arg_lit0 (NULL, "enable-mprofile", "enable memory profiling");
314
  load_file = arg_file0 (NULL, NULL, "<file>", "OR32 executable");
315
  end = arg_end (20);
316
 
317
  /* Set up the argument table */
318
  argtab[ 0] = vercop;
319
  argtab[ 1] = help;
320
  argtab[ 2] = cfg_file;
321
  argtab[ 3] = nosrv;
322
  argtab[ 4] = srv;
323
  argtab[ 5] = dbg;
324
  argtab[ 6] = command;
325 220 jeremybenn
  argtab[ 7] = quiet;
326
  argtab[ 8] = report_mem_errs;
327
  argtab[ 9] = strict_npc;
328
  argtab[10] = profile;
329
  argtab[11] = mprofile;
330
  argtab[12] = load_file;
331
  argtab[13] = end;
332 19 jeremybenn
 
333
  /* Parse */
334
  nerrors = arg_parse (argc, argv, argtab);
335
 
336
  /* Special case here is if help or version is specified, we ignore any other
337
     errors and just print the help or version information and then give up. */
338
  if (vercop->count > 0)
339
    {
340
      PRINTF ("OpenRISC 1000 Architectural Simulator, version %s\n",
341
              PACKAGE_VERSION);
342
 
343
      arg_freetable (argtab, sizeof (argtab) / sizeof (argtab[0]));
344
      return 1;
345
    }
346
 
347
  if (help->count > 0)
348
    {
349
      printf ("Usage:\n  %s ", argv[0]);
350
      arg_print_syntax (stdout, argtab, "\n\n");
351
      arg_print_glossary (stdout, argtab, "  %-25s %s\n");
352
 
353
      arg_freetable (argtab, sizeof (argtab) / sizeof (argtab[0]));
354
      return 1;
355
    }
356
 
357
  /* Deal with any errors */
358
  if (0 != nerrors)
359
    {
360
      arg_print_errors (stderr, end, "or1ksim");
361
      printf ("\nUsage:\n  %s ", argv[0]);
362
      arg_print_syntaxv (stderr, argtab, "\n");
363
 
364
      arg_freetable (argtab, sizeof (argtab) / sizeof (argtab[0]));
365
      return 1;
366
    }
367
 
368
  /* Process config file next, so any other command args will override */
369
  if (0 == cfg_file->count)
370
    {
371
      fprintf (stderr,
372
               "Warning: No config file given, default configuration used\n");
373
    }
374
 
375
  read_script_file (cfg_file->filename[0]);
376
 
377
 
378
  /* Remote debug server */
379
  if (nosrv->count > 0)
380
    {
381
      if (srv->count > 0)
382
        {
383
          fprintf (stderr,
384
                   "%s: cannot specify --nosrv with --srv. Ignoring --nosrv\n",
385
                   argv[0]);
386
        }
387
      else
388
        {
389
          config.debug.enabled = 0;
390
          config.debug.gdb_enabled = 0;
391
        }
392
    }
393
 
394
  if (srv->count > 0)
395
    {
396
      config.debug.enabled = 1;
397
      config.debug.gdb_enabled = 1;
398
      config.debug.server_port = srv->ival[0];
399
    }
400
 
401
  /* Runtime debug messages */
402
  if (dbg->count > 0)
403
    {
404
      parse_dbchs (dbg->sval[0]);
405
    }
406
 
407
  /* Interactive operation */
408
  runtime.sim.iprompt = command->count;
409
 
410 220 jeremybenn
  /* Request for quiet running */
411
  config.sim.quiet = quiet->count;
412
 
413
  /* Request for quiet running */
414
  config.sim.report_mem_errs = report_mem_errs->count;
415
 
416 19 jeremybenn
  /* Request for strict NPC behavior (flush the pipeline on change) */
417
  config.sim.strict_npc = strict_npc->count;
418
 
419
  /* Profiling requests */
420
  config.sim.profile = profile->count;
421
  config.sim.mprofile = mprofile->count;
422
 
423
  /* Executable file */
424
  if (load_file->count > 0)
425
    {
426
      runtime.sim.filename = strdup (load_file->filename[0]);
427
    }
428
  else
429
    {
430
      runtime.sim.filename = NULL;
431
    }
432
 
433
  arg_freetable (argtab, sizeof (argtab) / sizeof (argtab[0]));
434
  return 0;                      /* Success */
435
 
436
}       /* parse_args() */
437
 
438
 
439
/*---------------------------------------------------------------------------*/
440
/*!Print the current configuration                                           */
441
/*---------------------------------------------------------------------------*/
442
void
443
print_config ()
444
{
445
  if (config.sim.verbose)
446
    {
447
      char temp[20];
448
      PRINTF ("Verbose on, ");
449
      if (config.sim.debug)
450
        PRINTF ("simdebug on, ");
451
      else
452
        PRINTF ("simdebug off, ");
453
      if (runtime.sim.iprompt)
454
        PRINTF ("interactive prompt on\n");
455
      else
456
        PRINTF ("interactive prompt off\n");
457
 
458
      PRINTF ("Machine initialization...\n");
459
      generate_time_pretty (temp, config.sim.clkcycle_ps);
460
      PRINTF ("Clock cycle: %s\n", temp);
461
      if (cpu_state.sprs[SPR_UPR] & SPR_UPR_DCP)
462
        PRINTF ("Data cache present.\n");
463
      else
464
        PRINTF ("No data cache.\n");
465
      if (cpu_state.sprs[SPR_UPR] & SPR_UPR_ICP)
466
        PRINTF ("Insn cache tag present.\n");
467
      else
468
        PRINTF ("No instruction cache.\n");
469
      if (config.bpb.enabled)
470
        PRINTF ("BPB simulation on.\n");
471
      else
472
        PRINTF ("BPB simulation off.\n");
473
      if (config.bpb.btic)
474
        PRINTF ("BTIC simulation on.\n");
475
      else
476
        PRINTF ("BTIC simulation off.\n");
477
    }
478
}
479
 
480
struct config_param
481
{
482
  char *name;
483
  enum param_t type;
484
  void (*func) (union param_val, void *dat);
485
  struct config_param *next;
486
};
487
 
488
void
489
base_include (union param_val val, void *dat)
490
{
491
  read_script_file (val.str_val);
492
  cur_section = NULL;
493
}
494
 
495
/*---------------------------------------------[ Simulator configuration ]---*/
496
 
497
 
498
void
499
sim_verbose (union param_val val, void *dat)
500
{
501
  config.sim.verbose = val.int_val;
502
}
503
 
504
 
505
/*---------------------------------------------------------------------------*/
506
/*!Set the simulator debug message level
507
 
508
   Value must be in the range 0 (no messages) to 9. Values outside this range
509
   are converted to the nearer end of the range with a warning.
510
 
511
   @param[in] val  The value to use
512
   @param[in] dat  The config data structure (not used here)                 */
513
/*---------------------------------------------------------------------------*/
514
void
515
sim_debug (union param_val  val,
516
           void            *dat)
517
{
518
  if (val.int_val < 0)
519
    {
520
      fprintf (stderr,
521
               "Warning: Config debug value negative: 0 substituted\n");
522
      config.sim.debug = 0;
523
    }
524
  else if (val.int_val > 9)
525
    {
526
      fprintf (stderr,
527
               "Warning: Config debug value too large: 9 substituted\n");
528
      config.sim.debug = 9;
529
    }
530
  else
531
    {
532
      config.sim.debug = val.int_val;
533
    }
534
}       /* sim_debug() */
535
 
536
 
537
void
538
sim_profile (union param_val val, void *dat)
539
{
540
  config.sim.profile = val.int_val;
541
}
542
 
543
void
544
sim_prof_fn (union param_val val, void *dat)
545
{
546
  if (NULL != config.sim.prof_fn)
547
    {
548
      free (config.sim.prof_fn);
549
    }
550
 
551
  config.sim.prof_fn = strdup(val.str_val);
552
}
553
 
554
void
555
sim_mprofile (union param_val val, void *dat)
556
{
557
  config.sim.mprofile = val.int_val;
558
}
559
 
560
void
561
sim_mprof_fn (union param_val val, void *dat)
562
{
563
  if (NULL != config.sim.mprof_fn)
564
    {
565
      free (config.sim.mprof_fn);
566
    }
567
 
568
  config.sim.mprof_fn = strdup (val.str_val);
569
}
570
 
571
void
572
sim_history (union param_val val, void *dat)
573
{
574
  config.sim.history = val.int_val;
575
}
576
 
577
void
578
sim_exe_log (union param_val val, void *dat)
579
{
580
  config.sim.exe_log = val.int_val;
581
}
582
 
583
/*---------------------------------------------------------------------------*/
584
/*!Set the execution log type
585
 
586
   Value must be one of default, hardware, simple or software. Invalid values
587
   are ignored with a warning.
588
 
589
   @param[in] val  The value to use
590
   @param[in] dat  The config data structure (not used here)                 */
591
/*---------------------------------------------------------------------------*/
592
void
593
sim_exe_log_type (union param_val  val,
594
                  void            *dat)
595
{
596
  if (strcasecmp (val.str_val, "default") == 0)
597
    {
598
      config.sim.exe_log_type = EXE_LOG_HARDWARE;
599
    }
600
  else if (strcasecmp (val.str_val, "hardware") == 0)
601
    {
602
      config.sim.exe_log_type = EXE_LOG_HARDWARE;
603
    }
604
  else if (strcasecmp (val.str_val, "simple") == 0)
605
    {
606
      config.sim.exe_log_type = EXE_LOG_SIMPLE;
607
    }
608
  else if (strcasecmp (val.str_val, "software") == 0)
609
    {
610
      config.sim.exe_log_type = EXE_LOG_SOFTWARE;
611
    }
612
  else
613
    {
614
      fprintf (stderr, "Warning: Execution log type %s invalid. Ignored",
615
               val.str_val);
616
    }
617
}       /* sim_exe_log_type() */
618
 
619
 
620
void
621
sim_exe_log_start (union param_val val, void *dat)
622
{
623
  config.sim.exe_log_start = val.longlong_val;
624
}
625
 
626
void
627
sim_exe_log_end (union param_val val, void *dat)
628
{
629
  config.sim.exe_log_end = val.longlong_val;
630
}
631
 
632
void
633
sim_exe_log_marker (union param_val val, void *dat)
634
{
635
  config.sim.exe_log_marker = val.int_val;
636
}
637
 
638
void
639
sim_exe_log_fn (union param_val val, void *dat)
640
{
641
  if (NULL != config.sim.exe_log_fn)
642
    {
643
      free (config.sim.exe_log_fn);
644
    }
645
 
646
  config.sim.exe_log_fn = strdup (val.str_val);
647
}
648
 
649 202 julius
void
650
sim_exe_bin_insn_log (union param_val val, void *dat)
651
{
652
  config.sim.exe_bin_insn_log = val.int_val;
653
}
654
 
655
void
656
sim_exe_bin_insn_log_fn (union param_val val, void *dat)
657
{
658
  if (NULL != config.sim.exe_bin_insn_log_fn)
659
    {
660
      free (config.sim.exe_bin_insn_log_fn);
661
    }
662
 
663
  config.sim.exe_bin_insn_log_fn = strdup (val.str_val);
664
}
665
 
666
 
667
 
668
 
669
 
670 19 jeremybenn
/*---------------------------------------------------------------------------*/
671
/*!Set the clock cycle time.
672
 
673
   Value must be an integer followed by one of ps, ns, us or ms.
674
 
675
   If a valid time is not presented, the value is unchanged.
676
 
677
   @param[in] val  The value to use
678
   @param[in] dat  The config data structure (not used here)                 */
679
/*---------------------------------------------------------------------------*/
680
void
681
sim_clkcycle (union param_val  val,
682
              void            *dat)
683
{
684
  int len = strlen (val.str_val);
685
  int pos = len - 1;
686
  long time;
687
  if ((len < 2) || (val.str_val[pos--] != 's'))
688
    {
689
      fprintf (stderr, "Warning: Clock cycle time %s invalid: ignored\n",
690
               val.str_val);
691
      return;
692
    }
693
 
694
  switch (val.str_val[pos--])
695
    {
696
    case 'p':
697
      time = 1;
698
      break;
699
    case 'n':
700
      time = 1000;
701
      break;
702
    case 'u':
703
      time = 1000000;
704
      break;
705
    case 'm':
706
      time = 1000000000;
707
      break;
708
    default:
709
      fprintf (stderr, "Warning: Clock cycle time %s invalid: ignored\n",
710
               val.str_val);
711
      return;
712
    }
713
 
714
  val.str_val[pos + 1] = 0;
715
  time = time * atol (val.str_val);
716
 
717
  if (0 == time)
718
    {
719
      fprintf (stderr, "Warning: Clock cycle time of zero invalid: ignored\n");
720
      return;
721
    }
722
 
723
  config.sim.clkcycle_ps = time;
724
 
725
}       /* sim_clkcycle() */
726
 
727
 
728
/*---------------------------------------------------------------------------*/
729
/*!Register the functions to handle a section sim
730
 
731
   This section does not allocate dynamically a data structure holding its
732
   config information. It's all in the global config.sim data
733
   structure. Therefore it does not need a start and end function to
734
   initialize default values (although it might be clearer to do so). The
735
   default values are set in init_defconfig().
736
 
737
   New preferred parameter names are introduced (_file for filenames), but
738
   the legacy names (_fn) are also present for backwards compatibility       */
739
/*---------------------------------------------------------------------------*/
740
static void
741
reg_sim_sec ()
742
{
743
  struct config_section *sec = reg_config_sec ("sim", NULL, NULL);
744
 
745
  reg_config_param (sec, "verbose",        paramt_int,      sim_verbose);
746
  reg_config_param (sec, "debug",          paramt_int,      sim_debug);
747
  reg_config_param (sec, "profile",        paramt_int,      sim_profile);
748
  reg_config_param (sec, "prof_file",      paramt_str,      sim_prof_fn);
749
  reg_config_param (sec, "prof_fn",        paramt_str,      sim_prof_fn);
750
  reg_config_param (sec, "mprofile",       paramt_int,      sim_mprofile);
751
  reg_config_param (sec, "mprof_file",     paramt_str,      sim_mprof_fn);
752
  reg_config_param (sec, "mprof_fn",       paramt_str,      sim_mprof_fn);
753
  reg_config_param (sec, "history",        paramt_int,      sim_history);
754
  reg_config_param (sec, "exe_log",        paramt_int,      sim_exe_log);
755
  reg_config_param (sec, "exe_log_type",   paramt_word,     sim_exe_log_type);
756
  reg_config_param (sec, "exe_log_start",  paramt_longlong, sim_exe_log_start);
757
  reg_config_param (sec, "exe_log_end",    paramt_longlong, sim_exe_log_end);
758
  reg_config_param (sec, "exe_log_marker", paramt_int,      sim_exe_log_marker);
759
  reg_config_param (sec, "exe_log_file",   paramt_str,      sim_exe_log_fn);
760
  reg_config_param (sec, "exe_log_fn",     paramt_str,      sim_exe_log_fn);
761 202 julius
  reg_config_param (sec, "exe_bin_insn_log",paramt_int,     sim_exe_bin_insn_log);
762
  reg_config_param (sec, "exe_bin_insn_log_fn",paramt_str,  sim_exe_bin_insn_log_fn);
763
  reg_config_param (sec, "exe_bin_insn_log_file",paramt_str,  sim_exe_bin_insn_log_fn);
764 19 jeremybenn
  reg_config_param (sec, "clkcycle",       paramt_word,     sim_clkcycle);
765
 
766
}       /* reg_sim_sec() */
767
 
768
 
769
void
770
reg_config_secs (void)
771
{
772
  reg_config_param (reg_config_sec ("base", NULL, NULL), "include",
773
                    paramt_str, base_include);
774
 
775
  reg_generic_sec ();           /* JPB */
776
  reg_sim_sec ();
777
  reg_cpu_sec ();
778
  reg_pic_sec ();
779
  reg_memory_sec ();
780
  reg_mc_sec ();
781
  reg_uart_sec ();
782
  reg_dma_sec ();
783
  reg_debug_sec ();
784
  reg_vapi_sec ();
785
  reg_ethernet_sec ();
786
  reg_immu_sec ();
787
  reg_dmmu_sec ();
788
  reg_ic_sec ();
789
  reg_dc_sec ();
790
  reg_gpio_sec ();
791
  reg_bpb_sec ();
792
  reg_pm_sec ();
793
  reg_vga_sec ();
794
  reg_fb_sec ();
795
  reg_kbd_sec ();
796
  reg_ata_sec ();
797
  reg_cuc_sec ();
798
}
799
 
800
void
801
reg_config_param (struct config_section *sec, const char *param,
802
                  enum param_t type,
803
                  void (*param_cb) (union param_val, void *))
804
{
805
  struct config_param *new = malloc (sizeof (struct config_param));
806
 
807
  if (!new)
808
    {
809
      fprintf (stderr, "Out-of-memory\n");
810
      exit (1);
811
    }
812
 
813
  if (!(new->name = strdup (param)))
814
    {
815
      fprintf (stderr, "Out-of-memory\n");
816
      exit (1);
817
    }
818
 
819
  new->func = param_cb;
820
  new->type = type;
821
 
822
  new->next = sec->params;
823
  sec->params = new;
824
}
825
 
826
struct config_section *
827
reg_config_sec (const char *section,
828
                void *(*sec_start) (void), void (*sec_end) (void *))
829
{
830
  struct config_section *new = malloc (sizeof (struct config_section));
831
 
832
  if (!new)
833
    {
834
      fprintf (stderr, "Out-of-memory\n");
835
      exit (1);
836
    }
837
 
838
  if (!(new->name = strdup (section)))
839
    {
840
      fprintf (stderr, "Out-of-memory\n");
841
      exit (1);
842
    }
843
 
844
  new->next = sections;
845
  new->sec_start = sec_start;
846
  new->sec_end = sec_end;
847
  new->params = NULL;
848
 
849
  sections = new;
850
 
851
  return new;
852
}
853
 
854
static void
855
switch_param (char *param, struct config_param *cur_param)
856
{
857
  char *end_p;
858
  union param_val val;
859
 
860
  /* Skip over an = sign if it exists */
861
  if (*param == '=')
862
    {
863
      param++;
864
      while (*param && isspace (*param))
865
        param++;
866
    }
867
 
868
  switch (cur_param->type)
869
    {
870
    case paramt_int:
871
      val.int_val = strtol (param, NULL, 0);
872
      break;
873
    case paramt_longlong:
874
      val.longlong_val = strtoll (param, NULL, 0);
875
      break;
876
    case paramt_addr:
877
      val.addr_val = strtoul (param, NULL, 0);
878
      break;
879
    case paramt_str:
880
      if (*param != '"')
881
        {
882
          fprintf (stderr,
883
                   "Warning: String value for parameter expected: ignored\n");
884
          return;
885
        }
886
 
887
      param++;
888
      end_p = param;
889
      while (*end_p && (*end_p != '"'))
890
        end_p++;
891
      *end_p = '\0';
892
      val.str_val = param;
893
      break;
894
    case paramt_word:
895
      end_p = param;
896
      while (*end_p && !isspace (*end_p))
897
        end_p++;
898
      *end_p = '\0';
899
      val.str_val = param;
900
      break;
901
    case paramt_none:
902
      break;
903
    }
904
 
905
  cur_param->func (val, cur_section->dat);
906
}
907
 
908
/* Read environment from a script file. Does not fail - assumes default configuration instead.
909
   The syntax of script file is:
910
   param = value
911
   section x
912
     data
913
     param = value
914
   end
915
 
916
   Example:
917
   section mc
918
     memory_table_file = sim.mem
919
     enable = 1
920
     POC = 0x47892344
921
   end
922
 
923
 */
924
 
925
static void
926
read_script_file (const char *filename)
927
{
928
  FILE *f;
929
  char *home = getenv ("HOME");
930
  char ctmp[STR_SIZE];
931
  int local = 1;
932
  cur_section = NULL;
933
 
934
  sprintf (ctmp, "%s/.or1k/%s", home, filename);
935
  if ((f = fopen (filename, "rt")) || (home && (f = fopen (ctmp, "rt"))))
936
    {
937
      if (config.sim.verbose)
938
        PRINTF ("Reading script file from '%s'...\n",
939
                local ? filename : ctmp);
940
 
941
      while (!feof (f))
942
        {
943
          char param[STR_SIZE];
944
          if (fscanf (f, "%s ", param) != 1)
945
            break;
946
          /* Is this a section? */
947
          if (strcmp (param, "section") == 0)
948
            {
949
              struct config_section *cur;
950
              cur_section = NULL;
951
              if (fscanf (f, "%s\n", param) != 1)
952
                {
953
                  fprintf (stderr, "%s: ERROR: Section name required.\n",
954
                           local ? filename : ctmp);
955
                  exit (1);
956
                }
957
              for (cur = sections; cur; cur = cur->next)
958
                if (strcmp (cur->name, param) == 0)
959
                  {
960
                    cur_section = cur;
961
                    break;
962
                  }
963
              if (!cur)
964
                {
965
                  fprintf (stderr,
966
                           "Warning: Unknown config section: %s; ignoring.\n",
967
                           param);
968
                  /* just skip section */
969
                  while (fscanf (f, "%s\n", param) == 1
970
                         && strcmp (param, "end"));
971
                }
972
              else
973
                {
974
                  cur->dat = NULL;
975
                  if (cur->sec_start)
976
                    cur->dat = cur->sec_start ();
977
                }
978
            }
979
          else if (strcmp (param, "end") == 0)
980
            {
981
              if (cur_section->sec_end)
982
                cur_section->sec_end (cur_section->dat);
983
              cur_section = NULL;
984
            }
985
          else if (strncmp (param, "/*", 2) == 0)
986
            {
987
              char c0 = 0, c1 = 0;
988
              while (c0 != '*' || c1 != '/')
989
                {
990
                  c0 = c1;
991
                  c1 = fgetc (f);
992
                  if (feof (f))
993
                    {
994
                      fprintf (stderr, "%s: ERROR: Comment reached EOF.\n",
995
                               local ? filename : ctmp);
996
                      exit (1);
997
                    }
998
                }
999
            }
1000
          else
1001
            {
1002 93 jeremybenn
              struct config_param *cur_param = NULL;
1003 19 jeremybenn
              char *cur_p;
1004 93 jeremybenn
              /* If we have a corrupt file, this could be encountered outside
1005
                 a section. So make sure cur_section is defined. */
1006
              if (cur_section)
1007
                {
1008
                  for (cur_param = cur_section->params; cur_param;
1009
                       cur_param = cur_param->next)
1010
                    {
1011
                      if (strcmp (cur_param->name, param) == 0)
1012
                        {
1013
                          break;
1014
                        }
1015
                    }
1016
                }
1017 19 jeremybenn
              if (!cur_param)
1018
                {
1019
                  fprintf (stderr, "Warning: Invalid parameter: %s; ignored\n",
1020
                           param);
1021
                  while (fgetc (f) != '\n' || feof (f));
1022
                  continue;
1023
                }
1024
 
1025
              if (cur_param->type == paramt_none)
1026
                continue;
1027
 
1028
              /* Parse parameter value */
1029
              cur_p = fgets (param, STR_SIZE, f);
1030
 
1031
              while (*cur_p && isspace (*cur_p))
1032
                cur_p++;
1033
 
1034
              switch_param (cur_p, cur_param);
1035
            }
1036
        }
1037
      fclose (f);
1038
    }
1039
  else if (config.sim.verbose)
1040
    fprintf (stderr,
1041
             "Warning: Cannot read script file from '%s' of '%s'.\n",
1042
             filename, ctmp);
1043
}
1044
 
1045
/* Utility for execution of set sim command.  */
1046
static int
1047
set_config (int argc, char **argv)
1048
{
1049
  struct config_section *cur;
1050
  struct config_param *cur_param;
1051
 
1052
  if (argc < 2)
1053
    return 1;
1054
 
1055
  PRINTF ("sec:%s\n", argv[1]);
1056
  cur_section = NULL;
1057
  for (cur = sections; cur; cur = cur->next)
1058
    if (strcmp (cur->name, argv[1]) == 0)
1059
      {
1060
        cur_section = cur;
1061
        break;
1062
      }
1063
 
1064
  if (!cur_section)
1065
    return 1;
1066
 
1067
  if (argc < 3)
1068
    return 2;
1069
 
1070
  PRINTF ("item:%s\n", argv[2]);
1071
  {
1072
    for (cur_param = cur->params; cur_param; cur_param = cur_param->next)
1073
      if (strcmp (cur_param->name, argv[2]) == 0)
1074
        {
1075
          break;
1076
        }
1077
    if (!cur_param)
1078
      return 2;
1079
 
1080
    /* Parse parameter value */
1081
    if (cur_param->type)
1082
      {
1083
        if (argc < 4)
1084
          return 3;
1085
        PRINTF ("params:%s\n", argv[3]);
1086
      }
1087
 
1088
    switch_param (argv[3], cur_param);
1089
  }
1090
  return 0;
1091
}
1092
 
1093
/* Executes set sim command, displays error.  */
1094
void
1095
set_config_command (int argc, char **argv)
1096
{
1097
  struct config_section *cur;
1098
  struct config_param *cur_param;
1099
 
1100
  switch (set_config (argc, argv))
1101
    {
1102
    case 1:
1103
      PRINTF
1104
        ("Invalid or missing section name.  One of valid sections must be specified:\n");
1105
      for (cur = sections; cur; cur = cur->next)
1106
        PRINTF ("%s ", cur->name);
1107
      PRINTF ("\n");
1108
      break;
1109
    case 2:
1110
      PRINTF
1111
        ("Invalid or missing item name.  One of valid items must be specified:\n");
1112
      for (cur_param = cur_section->params; cur_param;
1113
           cur_param = cur_param->next)
1114
        PRINTF ("%s ", cur_param->name);
1115
      PRINTF ("\n");
1116
      break;
1117
    case 3:
1118
      PRINTF ("Invalid parameters specified.\n");
1119
      break;
1120
    }
1121
}

powered by: WebSVN 2.1.0

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