Merged head into linux tree
[gem5.git] / sim / system.cc
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
35 using namespace std;
36
37 vector<System *> System::systemList;
38
39 int System::numSystemsRunning = 0;
40
41 System::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
94 System::~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
106 int
107 System::registerExecContext(ExecContext *xc)
108 {
109 int myIndex = execContexts.size();
110 execContexts.push_back(xc);
111 return myIndex;
112 }
113
114
115 void
116 System::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
127 void
128 System::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
138 extern "C"
139 void
140 printSystems()
141 {
142 System::printSystems();
143 }
144
145 void
146 System::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
153 bool
154 System::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
167 void
168 System::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
184 Stats::MainBin *
185 System::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
194 SWContext *
195 System::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
207 void
208 System::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
238 void
239 System::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
274 DEFINE_SIM_OBJECT_CLASS_NAME("System", System)
275