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