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 §ion) 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