Merge zizzer:/bk/m5 into zeep.eecs.umich.edu:/z/saidi/work/m5
[gem5.git] / sim / param.hh
1 /*
2 * Copyright (c) 2002-2003 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #ifndef __PARAM_HH__
30 #define __PARAM_HH__
31
32 #include <list>
33 #include <string>
34 #include <vector>
35
36 #include "sim/configfile.hh"
37 #include "sim/startup.hh"
38
39 // forward decls
40 class BaseParam;
41 class SimObject;
42
43 //
44 // The context of a parameter definition... usually a subclass of
45 // SimObjectBuilder (which derives from ParamContext), but abstracted
46 // here to support more global simulator control parameters as well.
47 //
48 class ParamContext : protected StartupCallback
49 {
50 private:
51
52 // static list of all ParamContext objects, built as a side effect
53 // of the ParamContext constructor
54 static std::list<ParamContext *> *ctxList;
55
56 protected:
57
58 // .ini file (database) for parameter lookup... initialized on call
59 // to parseParams()
60 IniFile *iniFilePtr;
61
62 // .ini file section for parameter lookup
63 const std::string iniSection;
64
65 typedef std::vector<BaseParam *> ParamList;
66
67 // list of parameters defined in this context
68 ParamList *paramList;
69
70 ParamList *getParamList() {
71 if (!paramList)
72 paramList = new ParamList;
73 return paramList;
74 }
75
76 public:
77
78 /// Initialization phases for ParamContext objects.
79 enum InitPhase {
80 NoAutoInit = -1, ///< Don't initialize at all... params
81 /// will be parsed later (used by
82 /// SimObjectBuilder, which parses
83 /// params in SimObject::create().
84 OutputInitPhase = 0, ///< Output stream initialization
85 TraceInitPhase = 1, ///< Trace context initialization:
86 /// depends on output streams, but
87 /// needs to come before others so we
88 /// can use tracing in other
89 /// ParamContext init code
90 StatsInitPhase = 2, ///< Stats output initialization
91 DefaultInitPhase = 3 ///< Everything else
92 };
93
94 /// Records the initialization phase for this ParamContext.
95 InitPhase initPhase;
96
97 /// Constructor.
98 /// @param _iniSection Name of .ini section corresponding to this context.
99 /// @param _initPhase Initialization phase (see InitPhase).
100 ParamContext(const std::string &_iniSection,
101 InitPhase _initPhase = DefaultInitPhase);
102
103 virtual ~ParamContext() {}
104
105 // add a parameter to the context... called from the parameter
106 // object's constructor (see BaseParam::BaseParam())
107 void addParam(BaseParam *);
108
109 // call parse() on all params in this context to convert string
110 // representations to parameter values
111 virtual void parseParams(IniFile &iniFile);
112
113 // Check parameter values for validity & consistency. Default
114 // implementation is no-op; derive subclass & override to add
115 // actual functionality here
116 virtual void checkParams();
117
118 // Clean up at end of execution: close file descriptors, etc.
119 // Default implementation is no-op; derive subclass & override to
120 // add actual functionality here
121 virtual void cleanup();
122
123 // dump parameter descriptions
124 void describeParams(std::ostream &);
125
126 // Display the parameters & values used
127 void showParams(std::ostream &);
128
129 // print context information for parameter error
130 virtual void printErrorProlog(std::ostream &);
131
132 // resolve a SimObject name in this context to an object pointer.
133 virtual SimObject *resolveSimObject(const std::string &name);
134
135 // generate the name for this instance of this context (used as a
136 // prefix to create unique names in resolveSimObject()
137 virtual const std::string &getInstanceName() { return iniSection; }
138
139 // return the configuration hierarchy node for this context. Bare
140 // ParamContext objects have no corresponding node, so the default
141 // implementation returns NULL.
142 virtual ConfigNode *getConfigNode() { return NULL; }
143
144 // Parse all parameters registered with all ParamContext objects.
145 static void parseAllContexts(IniFile &iniFile);
146
147 // Check all parameters registered with all ParamContext objects.
148 // (calls checkParams() on each)
149 static void checkAllContexts();
150
151 // Print all parameter values on indicated ostream.
152 static void showAllContexts(std::ostream &os);
153
154 // Clean up all registered ParamContext objects. (calls cleanup()
155 // on each)
156 static void cleanupAllContexts();
157
158 // print descriptions of all parameters registered with all
159 // ParamContext objects
160 static void describeAllContexts(std::ostream &os);
161 };
162
163
164 //
165 // Base class for all parameter objects
166 //
167 class BaseParam
168 {
169 public:
170
171 ParamContext *context;
172 std::string name;
173 std::string description; // text description for help message
174 bool wasSet; // true if parameter was set by user
175 bool hasDefault; // true if parameter has default value
176
177 BaseParam(ParamContext *_context, const std::string &_name,
178 const std::string &_description, bool _hasDefault)
179 : context(_context), name(_name), description(_description),
180 wasSet(false), hasDefault(_hasDefault)
181 {
182 context->addParam(this);
183 }
184
185 virtual ~BaseParam() {}
186
187 // a parameter is valid only if its value was set by the user or
188 // it has a default value
189 bool isValid() const
190 {
191 return (wasSet || hasDefault);
192 }
193
194 // set value by parsing string
195 virtual void parse(const std::string &s) = 0;
196
197 // display value to stream
198 virtual void showValue(std::ostream &) const = 0;
199
200 // display type to stream
201 virtual void showType(std::ostream &) const = 0;
202
203 // signal parse or usage error
204 virtual void die(const std::string &err) const;
205 };
206
207 //
208 // Template classes to specialize parameters to specific types.
209 //
210 // Param<T> is for single-valued (scalar) parameters of type T.
211 // VectorParam<T> is for multi-valued (vector) parameters of type T.
212 // These are specified in the .ini file as a space-delimited list of
213 // arguments.
214 //
215 template <class T>
216 class Param : public BaseParam
217 {
218 protected:
219
220 T value;
221
222 public:
223
224 // Param with default value: set value to default
225 Param(ParamContext *context,
226 const std::string &name, const std::string &description, T dfltValue)
227 : BaseParam(context, name, description, true),
228 value(dfltValue)
229 {
230 }
231
232 // Param with no default value: leave value uninitialized
233 Param(ParamContext *context,
234 const std::string &name, const std::string &description)
235 : BaseParam(context, name, description, false)
236 {
237 }
238
239 virtual ~Param() {}
240
241 operator T&()
242 {
243 // if we attempt to reference an invalid parameter (i.e., one
244 // with no default value that was not set by the user), die.
245 if (!isValid())
246 die("not found");
247 return value;
248 }
249
250 // display value to stream
251 virtual void showValue(std::ostream &os) const;
252
253 // display type to stream
254 virtual void showType(std::ostream &) const;
255
256 // set value by parsing string
257 virtual void parse(const std::string &s);
258 };
259
260
261 //
262 // Template class for vector-valued parameters (lists)
263 //
264 template <class T>
265 class VectorParam : public BaseParam
266 {
267 protected:
268
269 std::vector<T> value;
270
271 public:
272
273 typedef typename std::vector<T>::size_type size_type;
274
275 // Param with default value: set value to default
276 VectorParam(ParamContext *context, const std::string &name,
277 const std::string &description,
278 const std::vector<T> &dfltValue)
279 : BaseParam(context, name, description, true),
280 value(dfltValue)
281 {
282 }
283
284 // Param with no default value: leave value uninitialized
285 VectorParam(ParamContext *context,
286 const std::string &name, const std::string &description)
287 : BaseParam(context, name, description, false)
288 {
289 }
290
291 virtual ~VectorParam() {}
292
293 // basic vector access methods
294 size_type size() const
295 {
296 if (!isValid())
297 die("not found");
298 return value.size();
299 }
300
301 const T &operator[](size_type n) const
302 {
303 if (!isValid())
304 die("not found");
305 return value[n];
306 }
307
308 // return reference to value vector
309 operator std::vector<T>&()
310 {
311 if (!isValid())
312 die("not found");
313 return value;
314 }
315
316 // display value to stream
317 virtual void showValue(std::ostream &os) const;
318
319 // display type to stream
320 virtual void showType(std::ostream &) const;
321
322 // set value by parsing string
323 virtual void parse(const std::string &s);
324 };
325
326 //
327 // Specialization of Param<int> and VectorParam<int> to handle
328 // enumerated types is done in two ways, using SimpleEnumParam and
329 // MappedEnumParam (and their vector counterparts,
330 // SimpleEnumVectorParam and MappedEnumVectorParam). SimpleEnumParam
331 // takes an array of strings and maps them to integers based on array
332 // index. MappedEnumParam takes an array of string-to-int mappings,
333 // allowing for mapping strings to non-contiguous integer values, or
334 // mapping multiple strings to the same integer value.
335 //
336 // Both SimpleEnumParam and MappedEnumParam are implemented using a
337 // single template class, EnumParam<Map>, which takes the type of the map
338 // as a parameter (const char * or EnumParamMap). Similarly,
339 // SimpleEnumVectorParam and MappedEnumVectorParam are both
340 // implemented using EnumVectorParam<Map>.
341 //
342 template <class Map>
343 class EnumParam : public Param<int>
344 {
345 const int num_values;
346 const Map *map;
347
348 public:
349
350 // Param with default value: set value to default
351 EnumParam(ParamContext *context,
352 const std::string &name, const std::string &description,
353 const Map *_map, int _num_values,
354 int dfltValue)
355 : Param<int>(context, name, description, dfltValue),
356 num_values(_num_values), map(_map)
357 {
358 }
359
360 // Param with no default value: leave value uninitialized
361 EnumParam(ParamContext *context,
362 const std::string &name, const std::string &description,
363 const Map *_map, int _num_values)
364 : Param<int>(context, name, description),
365 num_values(_num_values), map(_map)
366 {
367 }
368
369 virtual ~EnumParam() {}
370
371 // display value to stream
372 virtual void showValue(std::ostream &os) const;
373
374 // display type to stream
375 virtual void showType(std::ostream &) const;
376
377 // set value by parsing string
378 virtual void parse(const std::string &s);
379 };
380
381 //
382 // Vector counterpart to SimpleEnumParam
383 //
384 template <class Map>
385 class EnumVectorParam : public VectorParam<int>
386 {
387 const int num_values;
388 const Map *map;
389
390 public:
391
392 // Param with default value: set value to default
393 EnumVectorParam(ParamContext *context,
394 const std::string &name, const std::string &description,
395 const Map *_map, int _num_values,
396 std::vector<int> &dfltValue)
397 : VectorParam<int>(context, name, description, dfltValue),
398 num_values(_num_values), map(_map)
399 {
400 }
401
402 // Param with no default value: leave value uninitialized
403 EnumVectorParam(ParamContext *context,
404 const std::string &name, const std::string &description,
405 const Map *_map, int _num_values)
406 : VectorParam<int>(context, name, description),
407 num_values(_num_values), map(_map)
408 {
409 }
410
411 virtual ~EnumVectorParam() {}
412
413 // display value to stream
414 virtual void showValue(std::ostream &os) const;
415
416 // display type to stream
417 virtual void showType(std::ostream &) const;
418
419 // set value by parsing string
420 virtual void parse(const std::string &s);
421 };
422
423 // Specialize EnumParam for a particular enumeration type ENUM
424 // (automates casting to get value of enum type)
425
426 template <class ENUM>
427 class SimpleEnumParam : public EnumParam<const char *>
428 {
429 public:
430
431 SimpleEnumParam(ParamContext *context,
432 const std::string &name, const std::string &description,
433 const char **_map, int _num_values,
434 ENUM dfltValue)
435 : EnumParam<const char *>(context, name, description,
436 _map, _num_values, (int)dfltValue)
437 {
438 }
439
440 SimpleEnumParam(ParamContext *context,
441 const std::string &name, const std::string &description,
442 const char **_map, int _num_values)
443 : EnumParam<const char *>(context, name, description,
444 _map, _num_values)
445 {
446 }
447
448 operator ENUM() const
449 {
450 if (!isValid())
451 die("not found");
452 return (ENUM)value;
453 }
454 };
455
456
457 // Specialize EnumParam for a particular enumeration type ENUM
458 // (automates casting to get value of enum type)
459
460 template <class ENUM>
461 class SimpleEnumVectorParam : public EnumVectorParam<const char *>
462 {
463 public:
464
465 // skip default value constructor: too much pain to convert
466 // vector<ENUM> initializer to vector<int>
467
468
469 SimpleEnumVectorParam(ParamContext *context,
470 const std::string &name,
471 const std::string &description,
472 const char **_map, int _num_values)
473 : EnumVectorParam<const char *>(context, name, description,
474 _map, _num_values)
475 {
476 }
477
478 ENUM operator[](size_type n)
479 {
480 if (!isValid())
481 die("not found");
482 return (ENUM)value[n];
483 }
484 };
485
486
487 //
488 // Handle enums via string-to-int map (see comment above).
489 //
490
491 // An array of string-to-int mappings must be supplied using the
492 // following type.
493 typedef struct {
494 const char *name;
495 int value;
496 } EnumParamMap;
497
498 // Specialize EnumParam for a particular enumeration type ENUM
499 // (automates casting to get value of enum type)
500
501 template <class ENUM>
502 class MappedEnumParam : public EnumParam<EnumParamMap>
503 {
504 public:
505
506 MappedEnumParam(ParamContext *context,
507 const std::string &name, const std::string &description,
508 const EnumParamMap *_map, int _num_values,
509 ENUM dfltValue)
510 : EnumParam<EnumParamMap>(context, name, description,
511 _map, _num_values, (int)dfltValue)
512 {
513 }
514
515 MappedEnumParam(ParamContext *context,
516 const std::string &name, const std::string &description,
517 const EnumParamMap *_map, int _num_values)
518 : EnumParam<EnumParamMap>(context, name, description,
519 _map, _num_values)
520 {
521 }
522
523 operator ENUM()
524 {
525 if (!isValid())
526 die("not found");
527 return (ENUM)value[n];
528 }
529 };
530
531
532 // Specialize EnumParam for a particular enumeration type ENUM
533 // (automates casting to get value of enum type)
534
535 template <class ENUM>
536 class MappedEnumVectorParam : public EnumVectorParam<EnumParamMap>
537 {
538 public:
539
540 // skip default value constructor: too much pain to convert
541 // vector<ENUM> initializer to vector<int>
542
543
544 MappedEnumVectorParam(ParamContext *context,
545 const std::string &name,
546 const std::string &description,
547 const EnumParamMap *_map, int _num_values)
548 : EnumVectorParam<EnumParamMap>(context, name, description,
549 _map, _num_values)
550 {
551 }
552
553 ENUM operator[](size_type n)
554 {
555 if (!isValid())
556 die("not found");
557 return (ENUM)value[n];
558 }
559 };
560
561
562 //
563 // Parameters that point to other simulation objects (e.g. caches,
564 // busses, etc.) are handled by specializing SimObjectBaseParam to the
565 // specific subtype. The main purpose of SimObjectBaseParam is to
566 // provide a place to stick several helper functions common to all
567 // SimObject-derived parameters.
568 //
569 class SimObjectBaseParam : public BaseParam
570 {
571 public:
572
573 SimObjectBaseParam(ParamContext *context, const std::string &name,
574 const std::string &description, bool hasDefault)
575 : BaseParam(context, name, description, hasDefault)
576 {
577 }
578
579 virtual ~SimObjectBaseParam() {}
580
581 // helper function for SimObjectParam<T>::showValue()
582 void showValue(std::ostream &os, SimObject *obj) const;
583
584 // helper function for SimObjectParam<T>::parse()
585 void parse(const std::string &s, SimObject *&value);
586
587 // helper function for SimObjectParam<T>::parse()
588 void parse(const std::string &s, std::vector<SimObject *>&value_vec);
589 };
590
591
592 //
593 // Parameter to a specific type of SimObject. Note that T must be a
594 // pointer to a class derived from SimObject (e.g., <CPU *>).
595 //
596
597 template <class T> class SimObjectParam;
598
599 template <class T>
600 class SimObjectParam<T *> : public SimObjectBaseParam
601 {
602 protected:
603
604 T *value;
605
606 public:
607
608 // initialization w/o default
609 SimObjectParam(ParamContext *context,
610 const std::string &name, const std::string &description)
611 : SimObjectBaseParam(context, name, description, false)
612 {
613 }
614
615 // initialization wit=h default
616 SimObjectParam(ParamContext *context,
617 const std::string &name, const std::string &description,
618 T *dfltValue)
619 : SimObjectBaseParam(context, name, description, true),
620 value(dfltValue)
621 {
622 }
623
624 virtual ~SimObjectParam() {}
625
626 // convert to pointer
627 operator T*()
628 {
629 if (!isValid())
630 die("not found");
631 return value;
632 }
633
634 T *operator->() const
635 {
636 if (!isValid())
637 die("not found");
638 return value;
639 }
640
641 // display value to stream
642 virtual void showValue(std::ostream &os) const
643 {
644 SimObjectBaseParam::showValue(os, value);
645 }
646
647 // display type to stream: see REGISTER_SIM_OBJECT macro in
648 // sim_object.hh for declaration
649 virtual void showType(std::ostream &os) const;
650
651 // set value by parsing string
652 virtual void parse(const std::string &s)
653 {
654 SimObject *so_ptr;
655 // first parse to generic SimObject *
656 SimObjectBaseParam::parse(s, so_ptr);
657 // now dynamic_cast to specific derived type
658 value = dynamic_cast<T *>(so_ptr);
659 // check for failure of dynamic_cast
660 if (value == NULL && so_ptr != NULL)
661 die("not of appropriate type");
662 }
663 };
664
665
666 //
667 // Vector counterpart to SimObjectParam<T>
668 //
669
670 template <class T> class SimObjectVectorParam;
671
672 template <class T>
673 class SimObjectVectorParam<T *> : public SimObjectBaseParam
674 {
675 protected:
676
677 std::vector<T *> value;
678
679 public:
680
681 typedef typename std::vector<T *>::size_type size_type;
682
683 SimObjectVectorParam(ParamContext *context,
684 const std::string &name,
685 const std::string &description)
686 : SimObjectBaseParam(context, name, description, false)
687 {
688 }
689
690 SimObjectVectorParam(ParamContext *context,
691 const std::string &name,
692 const std::string &description,
693 std::vector<T *> dfltValue)
694 : SimObjectBaseParam(context, name, description, true),
695 value(dfltValue)
696 {
697 }
698
699 virtual ~SimObjectVectorParam() {}
700
701 // basic vector access methods
702 size_type size() const
703 {
704 if (!isValid())
705 die("not found");
706 return value.size();
707 }
708
709 T *&operator[](size_type n)
710 {
711 if (!isValid())
712 die("not found");
713 return value[n];
714 }
715
716 // return reference to value vector
717 operator std::vector<T *>&()
718 {
719 if (!isValid())
720 die("not found");
721 return value;
722 }
723
724 // display value to stream
725 virtual void showValue(std::ostream &os) const
726 {
727 for (int i = 0; i < value.size(); i++) {
728 if (i != 0)
729 os << " ";
730 SimObjectBaseParam::showValue(os, value[i]);
731 }
732 }
733
734 // display type to stream: see
735 virtual void showType(std::ostream &os) const;
736
737 // set value by parsing string
738 virtual void parse(const std::string &s)
739 {
740 std::vector<SimObject *> so_ptr_vec;
741 // first parse to generic SimObject * vector (from SimObjectBaseParam)
742 SimObjectBaseParam::parse(s, so_ptr_vec);
743
744 value.resize(so_ptr_vec.size());
745
746 for (int i = 0; i < so_ptr_vec.size(); ++i) {
747 // now dynamic_cast to specific derived type
748 value[i] = dynamic_cast<T *>(so_ptr_vec[i]);
749 // check for failure of dynamic_cast
750 if (value[i] == NULL && so_ptr_vec[i] != NULL)
751 die("not of appropriate type");
752 }
753 }
754 };
755
756 //
757 // Macro to define showType() methods for SimObjectParam &
758 // SimObjectVectorParam. Can't do this automatically as it requires a
759 // string name for the type, which you can't get from a template
760 // argument. For concrete derived SimObject types, this macro is
761 // automatically invoked by REGISTER_SIM_OBJECT() (see sim_object.hh).
762 //
763 #define DEFINE_SIM_OBJECT_CLASS_NAME(CLASS_NAME, OBJ_CLASS) \
764 void \
765 SimObjectParam<OBJ_CLASS *>::showType(std::ostream &os) const \
766 { \
767 os << CLASS_NAME; \
768 } \
769 \
770 void \
771 SimObjectVectorParam<OBJ_CLASS *>::showType(std::ostream &os) const \
772 { \
773 os << "vector of " << CLASS_NAME; \
774 }
775
776
777 //
778 // Declarations for low-level parsing & displaying functions. These
779 // are used internally, but should not be used directly by clients of
780 // the parameter mechanism, but are declared here so they can be
781 // shared with the serialization code (see sim/serialize.cc).
782 template <class T> bool parseParam(const std::string &str, T &data);
783 template <class T> void showParam(std::ostream &os, const T &data);
784
785 #endif // _PARAM_HH