sim_object.cc revision 2797
12SN/A/*
21762SN/A * Copyright (c) 2001-2005 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/A *
162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Steve Reinhardt
292665Ssaidi@eecs.umich.edu *          Nathan Binkert
302SN/A */
312SN/A
322SN/A#include <assert.h>
332SN/A
34330SN/A#include "base/callback.hh"
3556SN/A#include "base/inifile.hh"
361031SN/A#include "base/match.hh"
37330SN/A#include "base/misc.hh"
38330SN/A#include "base/trace.hh"
39938SN/A#include "base/stats/events.hh"
402609SN/A#include "base/serializer.hh"
4156SN/A#include "sim/host.hh"
42330SN/A#include "sim/sim_object.hh"
43695SN/A#include "sim/stats.hh"
44843SN/A#include "sim/param.hh"
452SN/A
462SN/Ausing namespace std;
472SN/A
482SN/A
492SN/A////////////////////////////////////////////////////////////////////////
502SN/A//
512SN/A// SimObject member definitions
522SN/A//
532SN/A////////////////////////////////////////////////////////////////////////
542SN/A
552SN/A//
562SN/A// static list of all SimObjects, used for initialization etc.
572SN/A//
582SN/ASimObject::SimObjectList SimObject::simObjectList;
592SN/A
601031SN/Anamespace Stats {
611031SN/A    extern ObjectMatch event_ignore;
621031SN/A}
631031SN/A
642SN/A//
652SN/A// SimObject constructor: used to maintain static simObjectList
662SN/A//
671553SN/ASimObject::SimObject(Params *p)
681553SN/A    : _params(p)
692SN/A{
701031SN/A#ifdef DEBUG
711031SN/A    doDebugBreak = false;
721031SN/A#endif
731031SN/A
741553SN/A    doRecordEvent = !Stats::event_ignore.match(name());
751553SN/A    simObjectList.push_back(this);
762797Sktlim@umich.edu    state = Atomic;
771553SN/A}
781553SN/A
791553SN/A//
801553SN/A// SimObject constructor: used to maintain static simObjectList
811553SN/A//
821553SN/ASimObject::SimObject(const string &_name)
831553SN/A    : _params(new Params)
841553SN/A{
851553SN/A    _params->name = _name;
861553SN/A#ifdef DEBUG
871553SN/A    doDebugBreak = false;
881553SN/A#endif
891553SN/A
901553SN/A    doRecordEvent = !Stats::event_ignore.match(name());
912SN/A    simObjectList.push_back(this);
922797Sktlim@umich.edu    state = Atomic;
932SN/A}
942SN/A
95465SN/Avoid
962499SN/ASimObject::connect()
972499SN/A{
982499SN/A}
992499SN/A
1002499SN/Avoid
101465SN/ASimObject::init()
102465SN/A{
103465SN/A}
104465SN/A
1052SN/A//
1062SN/A// no default statistics, so nothing to do in base implementation
1072SN/A//
1082SN/Avoid
1092SN/ASimObject::regStats()
1102SN/A{
1112SN/A}
1122SN/A
1132SN/Avoid
1142SN/ASimObject::regFormulas()
1152SN/A{
1162SN/A}
1172SN/A
118330SN/Avoid
119330SN/ASimObject::resetStats()
120330SN/A{
121330SN/A}
122330SN/A
1232SN/A//
12453SN/A// static function:
12553SN/A//   call regStats() on all SimObjects and then regFormulas() on all
12653SN/A//   SimObjects.
1272SN/A//
128334SN/Astruct SimObjectResetCB : public Callback
129334SN/A{
130334SN/A    virtual void process() { SimObject::resetAllStats(); }
131334SN/A};
132334SN/A
133334SN/Anamespace {
134334SN/A    static SimObjectResetCB StatResetCB;
135334SN/A}
136334SN/A
1372SN/Avoid
1382SN/ASimObject::regAllStats()
1392SN/A{
1402SN/A    SimObjectList::iterator i;
1412SN/A    SimObjectList::iterator end = simObjectList.end();
1422SN/A
1432SN/A    /**
1442SN/A     * @todo change cprintfs to DPRINTFs
1452SN/A     */
1462SN/A    for (i = simObjectList.begin(); i != end; ++i) {
1472SN/A#ifdef STAT_DEBUG
1482SN/A        cprintf("registering stats for %s\n", (*i)->name());
1492SN/A#endif
1502SN/A        (*i)->regStats();
1512SN/A    }
1522SN/A
1532SN/A    for (i = simObjectList.begin(); i != end; ++i) {
1542SN/A#ifdef STAT_DEBUG
1552SN/A        cprintf("registering formulas for %s\n", (*i)->name());
1562SN/A#endif
1572SN/A        (*i)->regFormulas();
158334SN/A    }
159334SN/A
160729SN/A    Stats::registerResetCallback(&StatResetCB);
1612SN/A}
1622SN/A
1632SN/A//
1642499SN/A// static function: call connect() on all SimObjects.
1652499SN/A//
1662499SN/Avoid
1672499SN/ASimObject::connectAll()
1682499SN/A{
1692499SN/A    SimObjectList::iterator i = simObjectList.begin();
1702499SN/A    SimObjectList::iterator end = simObjectList.end();
1712499SN/A
1722499SN/A    for (; i != end; ++i) {
1732499SN/A        SimObject *obj = *i;
1742499SN/A        obj->connect();
1752499SN/A    }
1762499SN/A}
1772499SN/A
1782499SN/A//
179465SN/A// static function: call init() on all SimObjects.
180465SN/A//
181465SN/Avoid
182465SN/ASimObject::initAll()
183465SN/A{
184465SN/A    SimObjectList::iterator i = simObjectList.begin();
185465SN/A    SimObjectList::iterator end = simObjectList.end();
186465SN/A
187465SN/A    for (; i != end; ++i) {
188465SN/A        SimObject *obj = *i;
189465SN/A        obj->init();
190465SN/A    }
191465SN/A}
192465SN/A
193465SN/A//
194330SN/A// static function: call resetStats() on all SimObjects.
195330SN/A//
196330SN/Avoid
197330SN/ASimObject::resetAllStats()
198330SN/A{
199332SN/A    SimObjectList::iterator i = simObjectList.begin();
200332SN/A    SimObjectList::iterator end = simObjectList.end();
201332SN/A
202332SN/A    for (; i != end; ++i) {
203332SN/A        SimObject *obj = *i;
204332SN/A        obj->resetStats();
205332SN/A    }
206330SN/A}
207330SN/A
208330SN/A//
209395SN/A// static function: serialize all SimObjects.
210395SN/A//
211395SN/Avoid
212395SN/ASimObject::serializeAll(ostream &os)
213395SN/A{
214573SN/A    SimObjectList::reverse_iterator ri = simObjectList.rbegin();
215573SN/A    SimObjectList::reverse_iterator rend = simObjectList.rend();
216395SN/A
217573SN/A    for (; ri != rend; ++ri) {
218573SN/A        SimObject *obj = *ri;
219395SN/A        obj->nameOut(os);
220395SN/A        obj->serialize(os);
221395SN/A   }
222395SN/A}
223843SN/A
2242797Sktlim@umich.eduvoid
2252797Sktlim@umich.eduSimObject::unserializeAll(Checkpoint *cp)
2262797Sktlim@umich.edu{
2272797Sktlim@umich.edu    SimObjectList::reverse_iterator ri = simObjectList.rbegin();
2282797Sktlim@umich.edu    SimObjectList::reverse_iterator rend = simObjectList.rend();
2292797Sktlim@umich.edu
2302797Sktlim@umich.edu    for (; ri != rend; ++ri) {
2312797Sktlim@umich.edu        SimObject *obj = *ri;
2322797Sktlim@umich.edu        DPRINTFR(Config, "Unserializing '%s'\n",
2332797Sktlim@umich.edu                 obj->name());
2342797Sktlim@umich.edu        if(cp->sectionExists(obj->name()))
2352797Sktlim@umich.edu            obj->unserialize(cp, obj->name());
2362797Sktlim@umich.edu        else
2372797Sktlim@umich.edu            warn("Not unserializing '%s': no section found in checkpoint.\n",
2382797Sktlim@umich.edu                 obj->name());
2392797Sktlim@umich.edu   }
2402797Sktlim@umich.edu}
2412797Sktlim@umich.edu
2421031SN/A#ifdef DEBUG
2431031SN/A//
2441031SN/A// static function: flag which objects should have the debugger break
2451031SN/A//
2461031SN/Avoid
2471031SN/ASimObject::debugObjectBreak(const string &objs)
2481031SN/A{
2491031SN/A    SimObjectList::const_iterator i = simObjectList.begin();
2501031SN/A    SimObjectList::const_iterator end = simObjectList.end();
2511031SN/A
2521031SN/A    ObjectMatch match(objs);
2531031SN/A    for (; i != end; ++i) {
2541031SN/A        SimObject *obj = *i;
2551031SN/A        obj->doDebugBreak = match.match(obj->name());
2561031SN/A   }
2571031SN/A}
2581031SN/A
2591031SN/Aextern "C"
2601031SN/Avoid
2611031SN/AdebugObjectBreak(const char *objs)
2621031SN/A{
2631031SN/A    SimObject::debugObjectBreak(string(objs));
2641031SN/A}
2651031SN/A#endif
2661031SN/A
267938SN/Avoid
268938SN/ASimObject::recordEvent(const std::string &stat)
269938SN/A{
270938SN/A    if (doRecordEvent)
271938SN/A        Stats::recordEvent(stat);
272938SN/A}
273938SN/A
2742797Sktlim@umich.edubool
2752797Sktlim@umich.eduSimObject::quiesce(Event *quiesce_event)
2762797Sktlim@umich.edu{
2772797Sktlim@umich.edu    if (state != QuiescedAtomic && state != Atomic) {
2782797Sktlim@umich.edu        panic("Must implement your own quiesce function if it is to be used "
2792797Sktlim@umich.edu              "in timing mode!");
2802797Sktlim@umich.edu    }
2812797Sktlim@umich.edu    state = QuiescedAtomic;
2822797Sktlim@umich.edu    return false;
2832797Sktlim@umich.edu}
2842797Sktlim@umich.edu
2852609SN/Avoid
2862797Sktlim@umich.eduSimObject::resume()
2872609SN/A{
2882797Sktlim@umich.edu    if (state == QuiescedAtomic) {
2892797Sktlim@umich.edu        state = Atomic;
2902797Sktlim@umich.edu    } else if (state == QuiescedTiming) {
2912797Sktlim@umich.edu        state = Timing;
2922797Sktlim@umich.edu    }
2932797Sktlim@umich.edu}
2942797Sktlim@umich.edu
2952797Sktlim@umich.eduvoid
2962797Sktlim@umich.eduSimObject::setMemoryMode(State new_mode)
2972797Sktlim@umich.edu{
2982797Sktlim@umich.edu    assert(new_mode == Timing || new_mode == Atomic);
2992797Sktlim@umich.edu    if (state == QuiescedAtomic && new_mode == Timing) {
3002797Sktlim@umich.edu        state = QuiescedTiming;
3012797Sktlim@umich.edu    } else if (state == QuiescedTiming && new_mode == Atomic) {
3022797Sktlim@umich.edu        state = QuiescedAtomic;
3032797Sktlim@umich.edu    } else {
3042797Sktlim@umich.edu        state = new_mode;
3052797Sktlim@umich.edu    }
3062797Sktlim@umich.edu}
3072797Sktlim@umich.edu
3082797Sktlim@umich.eduvoid
3092797Sktlim@umich.eduSimObject::switchOut()
3102797Sktlim@umich.edu{
3112797Sktlim@umich.edu    panic("Unimplemented!");
3122797Sktlim@umich.edu}
3132797Sktlim@umich.edu
3142797Sktlim@umich.eduvoid
3152797Sktlim@umich.eduSimObject::takeOverFrom(BaseCPU *cpu)
3162797Sktlim@umich.edu{
3172797Sktlim@umich.edu    panic("Unimplemented!");
3182609SN/A}
3192609SN/A
320843SN/ADEFINE_SIM_OBJECT_CLASS_NAME("SimObject", SimObject)
321