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

Subversion Repositories openrisc

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

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

powered by: WebSVN 2.1.0

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