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

Subversion Repositories or1k

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

powered by: WebSVN 2.1.0

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