1/* 2 * Copyright (c) 2010 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 46 unchanged lines hidden (view full) --- 55#include "config/the_isa.hh" 56#include "cpu/base.hh" 57#include "cpu/quiesce_event.hh" 58#include "cpu/thread_context.hh" 59#include "debug/Loader.hh" 60#include "debug/Quiesce.hh" 61#include "debug/WorkItems.hh" 62#include "params/BaseCPU.hh" |
63#include "sim/full_system.hh" |
64#include "sim/pseudo_inst.hh" 65#include "sim/serialize.hh" 66#include "sim/sim_events.hh" 67#include "sim/sim_exit.hh" 68#include "sim/stat_control.hh" 69#include "sim/stats.hh" 70#include "sim/system.hh" 71#include "sim/vptr.hh" 72 73using namespace std; 74 75using namespace Stats; 76using namespace TheISA; 77 78namespace PseudoInst { 79 |
80static inline void 81panicFsOnlyPseudoInst(const char *name) 82{ 83 panic("Pseudo inst \"%s\" is only available in Full System mode."); 84} |
85 86void 87arm(ThreadContext *tc) 88{ |
89 if (FullSystem) { 90 if (tc->getKernelStats()) 91 tc->getKernelStats()->arm(); 92 } else { 93 panicFsOnlyPseudoInst("arm"); 94 } |
95} 96 97void 98quiesce(ThreadContext *tc) 99{ |
100 if (FullSystem) { 101 if (!tc->getCpuPtr()->params()->do_quiesce) 102 return; |
103 |
104 DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name()); |
105 |
106 tc->suspend(); 107 if (tc->getKernelStats()) 108 tc->getKernelStats()->quiesce(); 109 } else { 110 panicFsOnlyPseudoInst("quiesce"); 111 } |
112} 113 114void 115quiesceSkip(ThreadContext *tc) 116{ |
117 if (FullSystem) { 118 BaseCPU *cpu = tc->getCpuPtr(); |
119 |
120 if (!cpu->params()->do_quiesce) 121 return; |
122 |
123 EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); |
124 |
125 Tick resume = curTick() + 1; |
126 |
127 cpu->reschedule(quiesceEvent, resume, true); |
128 |
129 DPRINTF(Quiesce, "%s: quiesceSkip() until %d\n", 130 cpu->name(), resume); |
131 |
132 tc->suspend(); 133 if (tc->getKernelStats()) 134 tc->getKernelStats()->quiesce(); 135 } else { 136 panicFsOnlyPseudoInst("quiesceSkip"); 137 } |
138} 139 140void 141quiesceNs(ThreadContext *tc, uint64_t ns) 142{ |
143 if (FullSystem) { 144 BaseCPU *cpu = tc->getCpuPtr(); |
145 |
146 if (!cpu->params()->do_quiesce || ns == 0) 147 return; |
148 |
149 EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); |
150 |
151 Tick resume = curTick() + SimClock::Int::ns * ns; |
152 |
153 cpu->reschedule(quiesceEvent, resume, true); |
154 |
155 DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n", 156 cpu->name(), ns, resume); |
157 |
158 tc->suspend(); 159 if (tc->getKernelStats()) 160 tc->getKernelStats()->quiesce(); 161 } else { 162 panicFsOnlyPseudoInst("quiesceNs"); 163 } |
164} 165 166void 167quiesceCycles(ThreadContext *tc, uint64_t cycles) 168{ |
169 if (FullSystem) { 170 BaseCPU *cpu = tc->getCpuPtr(); |
171 |
172 if (!cpu->params()->do_quiesce || cycles == 0) 173 return; |
174 |
175 EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); |
176 |
177 Tick resume = curTick() + cpu->ticks(cycles); |
178 |
179 cpu->reschedule(quiesceEvent, resume, true); |
180 |
181 DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n", 182 cpu->name(), cycles, resume); |
183 |
184 tc->suspend(); 185 if (tc->getKernelStats()) 186 tc->getKernelStats()->quiesce(); 187 } else { 188 panicFsOnlyPseudoInst("quiesceCycles"); 189 } |
190} 191 192uint64_t 193quiesceTime(ThreadContext *tc) 194{ |
195 if (FullSystem) { 196 return (tc->readLastActivate() - tc->readLastSuspend()) / 197 SimClock::Int::ns; 198 } else { 199 panicFsOnlyPseudoInst("quiesceTime"); 200 return 0; 201 } |
202} 203 |
204uint64_t 205rpns(ThreadContext *tc) 206{ 207 return curTick() / SimClock::Int::ns; 208} 209 210void 211wakeCPU(ThreadContext *tc, uint64_t cpuid) --- 6 unchanged lines hidden (view full) --- 218 219void 220m5exit(ThreadContext *tc, Tick delay) 221{ 222 Tick when = curTick() + delay * SimClock::Int::ns; 223 exitSimLoop("m5_exit instruction encountered", 0, when); 224} 225 |
226void 227loadsymbol(ThreadContext *tc) 228{ |
229 if (FullSystem) { 230 const string &filename = tc->getCpuPtr()->system->params()->symbolfile; 231 if (filename.empty()) { 232 return; 233 } |
234 |
235 std::string buffer; 236 ifstream file(filename.c_str()); |
237 |
238 if (!file) 239 fatal("file error: Can't open symbol table file %s\n", filename); |
240 |
241 while (!file.eof()) { 242 getline(file, buffer); |
243 |
244 if (buffer.empty()) 245 continue; |
246 |
247 string::size_type idx = buffer.find(' '); 248 if (idx == string::npos) 249 continue; |
250 |
251 string address = "0x" + buffer.substr(0, idx); 252 eat_white(address); 253 if (address.empty()) 254 continue; |
255 |
256 // Skip over letter and space 257 string symbol = buffer.substr(idx + 3); 258 eat_white(symbol); 259 if (symbol.empty()) 260 continue; |
261 |
262 Addr addr; 263 if (!to_number(address, addr)) 264 continue; |
265 |
266 if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol)) 267 continue; |
268 269 |
270 DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 271 } 272 file.close(); 273 } else { 274 panicFsOnlyPseudoInst("loadsymbol"); |
275 } |
276} 277 278void 279addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr) 280{ |
281 if (FullSystem) { 282 char symb[100]; 283 CopyStringOut(tc, symb, symbolAddr, 100); 284 std::string symbol(symb); |
285 |
286 DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); |
287 |
288 tc->getSystemPtr()->kernelSymtab->insert(addr,symbol); 289 debugSymbolTable->insert(addr,symbol); 290 } else { 291 panicFsOnlyPseudoInst("addSymbol"); 292 } |
293} 294 295uint64_t 296initParam(ThreadContext *tc) 297{ |
298 if (FullSystem) { 299 return tc->getCpuPtr()->system->init_param; 300 } else { 301 panicFsOnlyPseudoInst("initParam"); 302 return 0; 303 } |
304} 305 |
306 |
307void 308resetstats(ThreadContext *tc, Tick delay, Tick period) 309{ 310 if (!tc->getCpuPtr()->params()->do_statistics_insts) 311 return; 312 313 314 Tick when = curTick() + delay * SimClock::Int::ns; --- 35 unchanged lines hidden (view full) --- 350 return; 351 352 Tick when = curTick() + delay * SimClock::Int::ns; 353 Tick repeat = period * SimClock::Int::ns; 354 355 exitSimLoop("checkpoint", 0, when, repeat); 356} 357 |
358uint64_t 359readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset) 360{ |
361 if (FullSystem) { 362 const string &file = tc->getSystemPtr()->params()->readfile; 363 if (file.empty()) { 364 return ULL(0); 365 } |
366 |
367 uint64_t result = 0; |
368 |
369 int fd = ::open(file.c_str(), O_RDONLY, 0); 370 if (fd < 0) 371 panic("could not open file %s\n", file); |
372 |
373 if (::lseek(fd, offset, SEEK_SET) < 0) 374 panic("could not seek: %s", strerror(errno)); |
375 |
376 char *buf = new char[len]; 377 char *p = buf; 378 while (len > 0) { 379 int bytes = ::read(fd, p, len); 380 if (bytes <= 0) 381 break; |
382 |
383 p += bytes; 384 result += bytes; 385 len -= bytes; 386 } |
387 |
388 close(fd); 389 CopyIn(tc, vaddr, buf, result); 390 delete [] buf; 391 return result; 392 } else { 393 panicFsOnlyPseudoInst("readfile"); 394 return 0; 395 } |
396} 397 |
398void 399debugbreak(ThreadContext *tc) 400{ 401 Debug::breakpoint(); 402} 403 404void 405switchcpu(ThreadContext *tc) --- 111 unchanged lines hidden --- |