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