pseudo_inst.cc revision 2358
1/* 2 * Copyright (c) 2003-2006 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 <errno.h> 30#include <fcntl.h> 31#include <unistd.h> 32#include <cstdio> 33 34#include <string> 35 36#include "sim/pseudo_inst.hh" 37#include "arch/vtophys.hh" 38#include "cpu/base.hh" 39#include "cpu/sampler/sampler.hh" 40#include "cpu/exec_context.hh" 41#include "cpu/quiesce_event.hh" 42#include "kern/kernel_stats.hh" 43#include "sim/param.hh" 44#include "sim/serialize.hh" 45#include "sim/sim_exit.hh" 46#include "sim/stat_control.hh" 47#include "sim/stats.hh" 48#include "sim/system.hh" 49#include "sim/debug.hh" 50#include "sim/vptr.hh" 51 52using namespace std; 53 54extern Sampler *SampCPU; 55 56using namespace Stats; 57using namespace TheISA; 58 59namespace AlphaPseudo 60{ 61 bool doStatisticsInsts; 62 bool doCheckpointInsts; 63 bool doQuiesce; 64 65 void 66 arm(ExecContext *xc) 67 { 68 if (xc->getKernelStats()) 69 xc->getKernelStats()->arm(); 70 } 71 72 void 73 quiesce(ExecContext *xc) 74 { 75 if (!doQuiesce) 76 return; 77 78 xc->suspend(); 79 if (xc->getKernelStats()) 80 xc->getKernelStats()->quiesce(); 81 } 82 83 void 84 quiesceNs(ExecContext *xc, uint64_t ns) 85 { 86 if (!doQuiesce || ns == 0) 87 return; 88 89 EndQuiesceEvent *quiesceEvent = xc->getQuiesceEvent(); 90 91 if (quiesceEvent->scheduled()) 92 quiesceEvent->reschedule(curTick + Clock::Int::ns * ns); 93 else 94 quiesceEvent->schedule(curTick + Clock::Int::ns * ns); 95 96 xc->suspend(); 97 if (xc->getKernelStats()) 98 xc->getKernelStats()->quiesce(); 99 } 100 101 void 102 quiesceCycles(ExecContext *xc, uint64_t cycles) 103 { 104 if (!doQuiesce || cycles == 0) 105 return; 106 107 EndQuiesceEvent *quiesceEvent = xc->getQuiesceEvent(); 108 109 if (quiesceEvent->scheduled()) 110 quiesceEvent->reschedule(curTick + 111 xc->getCpuPtr()->cycles(cycles)); 112 else 113 quiesceEvent->schedule(curTick + 114 xc->getCpuPtr()->cycles(cycles)); 115 116 xc->suspend(); 117 if (xc->getKernelStats()) 118 xc->getKernelStats()->quiesce(); 119 } 120 121 uint64_t 122 quiesceTime(ExecContext *xc) 123 { 124 return (xc->readLastActivate() - xc->readLastSuspend()) / Clock::Int::ns; 125 } 126 127 void 128 ivlb(ExecContext *xc) 129 { 130 if (xc->getKernelStats()) 131 xc->getKernelStats()->ivlb(); 132 } 133 134 void 135 ivle(ExecContext *xc) 136 { 137 } 138 139 void 140 m5exit_old(ExecContext *xc) 141 { 142 SimExit(curTick, "m5_exit_old instruction encountered"); 143 } 144 145 void 146 m5exit(ExecContext *xc, Tick delay) 147 { 148 Tick when = curTick + delay * Clock::Int::ns; 149 SimExit(when, "m5_exit instruction encountered"); 150 } 151 152 void 153 loadsymbol(ExecContext *xc) 154 { 155 const string &filename = xc->getCpuPtr()->system->params()->symbolfile; 156 if (filename.empty()) { 157 return; 158 } 159 160 std::string buffer; 161 ifstream file(filename.c_str()); 162 163 if (!file) 164 fatal("file error: Can't open symbol table file %s\n", filename); 165 166 while (!file.eof()) { 167 getline(file, buffer); 168 169 if (buffer.empty()) 170 continue; 171 172 int idx = buffer.find(' '); 173 if (idx == string::npos) 174 continue; 175 176 string address = "0x" + buffer.substr(0, idx); 177 eat_white(address); 178 if (address.empty()) 179 continue; 180 181 // Skip over letter and space 182 string symbol = buffer.substr(idx + 3); 183 eat_white(symbol); 184 if (symbol.empty()) 185 continue; 186 187 Addr addr; 188 if (!to_number(address, addr)) 189 continue; 190 191 if (!xc->getSystemPtr()->kernelSymtab->insert(addr, symbol)) 192 continue; 193 194 195 DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 196 } 197 file.close(); 198 } 199 200 void 201 resetstats(ExecContext *xc, Tick delay, Tick period) 202 { 203 if (!doStatisticsInsts) 204 return; 205 206 207 Tick when = curTick + delay * Clock::Int::ns; 208 Tick repeat = period * Clock::Int::ns; 209 210 using namespace Stats; 211 SetupEvent(Reset, when, repeat); 212 } 213 214 void 215 dumpstats(ExecContext *xc, Tick delay, Tick period) 216 { 217 if (!doStatisticsInsts) 218 return; 219 220 221 Tick when = curTick + delay * Clock::Int::ns; 222 Tick repeat = period * Clock::Int::ns; 223 224 using namespace Stats; 225 SetupEvent(Dump, when, repeat); 226 } 227 228 void 229 addsymbol(ExecContext *xc, Addr addr, Addr symbolAddr) 230 { 231 char symb[100]; 232 CopyString(xc, symb, symbolAddr, 100); 233 std::string symbol(symb); 234 235 DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 236 237 xc->getSystemPtr()->kernelSymtab->insert(addr,symbol); 238 } 239 240 void 241 dumpresetstats(ExecContext *xc, Tick delay, Tick period) 242 { 243 if (!doStatisticsInsts) 244 return; 245 246 247 Tick when = curTick + delay * Clock::Int::ns; 248 Tick repeat = period * Clock::Int::ns; 249 250 using namespace Stats; 251 SetupEvent(Dump|Reset, when, repeat); 252 } 253 254 void 255 m5checkpoint(ExecContext *xc, Tick delay, Tick period) 256 { 257 if (!doCheckpointInsts) 258 return; 259 260 261 Tick when = curTick + delay * Clock::Int::ns; 262 Tick repeat = period * Clock::Int::ns; 263 264 Checkpoint::setup(when, repeat); 265 } 266 267 uint64_t 268 readfile(ExecContext *xc, Addr vaddr, uint64_t len, uint64_t offset) 269 { 270 const string &file = xc->getCpuPtr()->system->params()->readfile; 271 if (file.empty()) { 272 return ULL(0); 273 } 274 275 uint64_t result = 0; 276 277 int fd = ::open(file.c_str(), O_RDONLY, 0); 278 if (fd < 0) 279 panic("could not open file %s\n", file); 280 281 if (::lseek(fd, offset, SEEK_SET) < 0) 282 panic("could not seek: %s", strerror(errno)); 283 284 char *buf = new char[len]; 285 char *p = buf; 286 while (len > 0) { 287 int bytes = ::read(fd, p, len); 288 if (bytes <= 0) 289 break; 290 291 p += bytes; 292 result += bytes; 293 len -= bytes; 294 } 295 296 close(fd); 297 CopyIn(xc, vaddr, buf, result); 298 delete [] buf; 299 return result; 300 } 301 302 class Context : public ParamContext 303 { 304 public: 305 Context(const string §ion) : ParamContext(section) {} 306 void checkParams(); 307 }; 308 309 Context context("pseudo_inst"); 310 311 Param<bool> __quiesce(&context, "quiesce", 312 "enable quiesce instructions", 313 true); 314 Param<bool> __statistics(&context, "statistics", 315 "enable statistics pseudo instructions", 316 true); 317 Param<bool> __checkpoint(&context, "checkpoint", 318 "enable checkpoint pseudo instructions", 319 true); 320 321 void 322 Context::checkParams() 323 { 324 doQuiesce = __quiesce; 325 doStatisticsInsts = __statistics; 326 doCheckpointInsts = __checkpoint; 327 } 328 329 void debugbreak(ExecContext *xc) 330 { 331 debug_break(); 332 } 333 334 void switchcpu(ExecContext *xc) 335 { 336 if (SampCPU) 337 SampCPU->switchCPUs(); 338 } 339} 340