OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

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

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

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

powered by: WebSVN 2.1.0

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