system.cc revision 878
1/*
2 * Copyright (c) 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#include "cpu/exec_context.hh"
30#include "targetarch/vtophys.hh"
31#include "sim/param.hh"
32#include "sim/system.hh"
33#include "base/trace.hh"
34
35using namespace std;
36
37vector<System *> System::systemList;
38
39int System::numSystemsRunning = 0;
40
41System::System(const std::string _name,
42               const uint64_t _init_param,
43               MemoryController *_memCtrl,
44               PhysicalMemory *_physmem,
45               const bool _bin,
46               const std::vector<string> &binned_fns)
47
48    : SimObject(_name),
49      init_param(_init_param),
50      memCtrl(_memCtrl),
51      physmem(_physmem),
52      bin(_bin),
53      binned_fns(binned_fns)
54{
55    // increment the number of running systems
56    numSystemsRunning++;
57
58    // add self to global system list
59    systemList.push_back(this);
60    if (bin == true) {
61        Kernel = new Stats::MainBin("non TCPIP Kernel stats");
62        Kernel->activate();
63        User = new Stats::MainBin("User stats");
64
65        int end = binned_fns.size();
66        assert(!(end & 1));
67
68        Stats::MainBin *Bin;
69
70        fnEvents.resize(end>>1);
71
72        for (int i = 0; i < end; i +=2) {
73            Bin = new Stats::MainBin(binned_fns[i]);
74            fnBins.insert(make_pair(binned_fns[i], Bin));
75
76            fnEvents[(i>>1)] = new FnEvent(&pcEventQueue, binned_fns[i], this);
77
78            if (binned_fns[i+1] == "null")
79                populateMap(binned_fns[i], "");
80            else
81                populateMap(binned_fns[i], binned_fns[i+1]);
82        }
83
84        fnCalls
85            .name(name() + ":fnCalls")
86            .desc("all fn calls being tracked")
87            ;
88
89    } else
90        Kernel = NULL;
91}
92
93
94System::~System()
95{
96    if (bin == true) {
97        int end = fnEvents.size();
98        for (int i = 0; i < end; ++i) {
99            delete fnEvents[i];
100        }
101        fnEvents.clear();
102    }
103}
104
105
106int
107System::registerExecContext(ExecContext *xc)
108{
109    int myIndex = execContexts.size();
110    execContexts.push_back(xc);
111    return myIndex;
112}
113
114
115void
116System::replaceExecContext(int xcIndex, ExecContext *xc)
117{
118    if (xcIndex >= execContexts.size()) {
119        panic("replaceExecContext: bad xcIndex, %d >= %d\n",
120              xcIndex, execContexts.size());
121    }
122
123    execContexts[xcIndex] = xc;
124}
125
126
127void
128System::printSystems()
129{
130    vector<System *>::iterator i = systemList.begin();
131    vector<System *>::iterator end = systemList.end();
132    for (; i != end; ++i) {
133        System *sys = *i;
134        cerr << "System " << sys->name() << ": " << hex << sys << endl;
135    }
136}
137
138extern "C"
139void
140printSystems()
141{
142    System::printSystems();
143}
144
145void
146System::populateMap(std::string callee, std::string caller)
147{
148    multimap<const string, string>::const_iterator i;
149    i = callerMap.insert(make_pair(callee, caller));
150    assert(i != callerMap.end() && "should not fail populating callerMap");
151}
152
153bool
154System::findCaller(std::string callee, std::string caller) const
155{
156    typedef multimap<const std::string, std::string>::const_iterator iter;
157    pair<iter, iter> range;
158
159    range = callerMap.equal_range(callee);
160    for (iter i = range.first; i != range.second; ++i) {
161        if ((*i).second == caller)
162            return true;
163    }
164    return false;
165}
166
167void
168System::dumpState(ExecContext *xc) const
169{
170    if (xc->swCtx) {
171        stack<fnCall *> copy(xc->swCtx->callStack);
172        if (copy.empty())
173            return;
174        DPRINTF(TCPIP, "xc->swCtx, size: %d:\n", copy.size());
175        fnCall *top;
176        DPRINTF(TCPIP, "||     call : %d\n",xc->swCtx->calls);
177        for (top = copy.top(); !copy.empty(); copy.pop() ) {
178            top = copy.top();
179            DPRINTF(TCPIP, "||  %13s : %s \n", top->name, top->myBin->name());
180        }
181    }
182}
183
184Stats::MainBin *
185System::getBin(const std::string &name)
186{
187    std::map<const std::string, Stats::MainBin *>::const_iterator i;
188    i = fnBins.find(name);
189    if (i == fnBins.end())
190        panic("trying to getBin %s that is not on system map!", name);
191    return (*i).second;
192}
193
194SWContext *
195System::findContext(Addr pcb)
196{
197  std::map<Addr, SWContext *>::const_iterator iter;
198  iter = swCtxMap.find(pcb);
199  if (iter != swCtxMap.end()) {
200      SWContext *ctx = (*iter).second;
201      assert(ctx != NULL && "should never have a null ctx in ctxMap");
202      return ctx;
203  } else
204      return NULL;
205}
206
207void
208System::serialize(std::ostream &os)
209{
210    if (bin == true) {
211        map<const Addr, SWContext *>::const_iterator iter, end;
212        iter = swCtxMap.begin();
213        end = swCtxMap.end();
214
215        int numCtxs = swCtxMap.size();
216        SERIALIZE_SCALAR(numCtxs);
217        SWContext *ctx;
218        for (int i = 0; iter != end; ++i, ++iter) {
219            paramOut(os, csprintf("Addr[%d]",i), (*iter).first);
220            ctx = (*iter).second;
221            paramOut(os, csprintf("calls[%d]",i), ctx->calls);
222
223            stack<fnCall *> *stack = &(ctx->callStack);
224            fnCall *top;
225            int size = stack->size();
226            paramOut(os, csprintf("stacksize[%d]",i), size);
227            for (int j=0; j<size; ++j) {
228                top = stack->top();
229                paramOut(os, csprintf("ctx[%d].stackpos[%d]",i,j),
230                         top->name);
231                delete top;
232                stack->pop();
233            }
234        }
235    }
236}
237
238void
239System::unserialize(Checkpoint *cp, const std::string &section)
240{
241    if (bin == true) {
242        int numCtxs;
243        UNSERIALIZE_SCALAR(numCtxs);
244
245        SWContext *ctx;
246        Addr addr;
247        int size;
248        for(int i = 0; i < numCtxs; ++i) {
249            ctx = new SWContext;
250            paramIn(cp, section, csprintf("Addr[%d]",i), addr);
251            paramIn(cp, section, csprintf("calls[%d]",i), ctx->calls);
252
253            paramIn(cp, section, csprintf("stacksize[%d]",i), size);
254
255            vector<fnCall *> calls;
256            fnCall *call;
257            for (int j = 0; j < size; ++j) {
258                call = new fnCall;
259                paramIn(cp, section, csprintf("ctx[%d].stackpos[%d]",i,j),
260                        call->name);
261                call->myBin = getBin(call->name);
262                calls.push_back(call);
263            }
264
265            for (int j=size-1; j>=0; --j) {
266                ctx->callStack.push(calls[j]);
267            }
268
269            addContext(addr, ctx);
270        }
271    }
272}
273
274DEFINE_SIM_OBJECT_CLASS_NAME("System", System)
275
276