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

Subversion Repositories openrisc

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

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

powered by: WebSVN 2.1.0

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