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

Subversion Repositories or1k

[/] [or1k/] [tags/] [rel-0-3-0-rc2/] [or1ksim/] [sim-config.c] - Blame information for rev 1765

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

powered by: WebSVN 2.1.0

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