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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [or1ksim/] [sim-config.c] - Blame information for rev 1775

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

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

powered by: WebSVN 2.1.0

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