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

Subversion Repositories openrisc

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

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

powered by: WebSVN 2.1.0

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