pseudo_inst.cc revision 3565
1298SN/A/* 22188SN/A * Copyright (c) 2003-2006 The Regents of The University of Michigan 3298SN/A * All rights reserved. 4298SN/A * 5298SN/A * Redistribution and use in source and binary forms, with or without 6298SN/A * modification, are permitted provided that the following conditions are 7298SN/A * met: redistributions of source code must retain the above copyright 8298SN/A * notice, this list of conditions and the following disclaimer; 9298SN/A * redistributions in binary form must reproduce the above copyright 10298SN/A * notice, this list of conditions and the following disclaimer in the 11298SN/A * documentation and/or other materials provided with the distribution; 12298SN/A * neither the name of the copyright holders nor the names of its 13298SN/A * contributors may be used to endorse or promote products derived from 14298SN/A * this software without specific prior written permission. 15298SN/A * 16298SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17298SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18298SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19298SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20298SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21298SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22298SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23298SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24298SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25298SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26298SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert 29298SN/A */ 30298SN/A 311642SN/A#include <errno.h> 32954SN/A#include <fcntl.h> 33956SN/A#include <unistd.h> 34956SN/A 35299SN/A#include <string> 36299SN/A 372170SN/A#include "arch/vtophys.hh" 383089Ssaidi@eecs.umich.edu#include "base/annotate.hh" 391717SN/A#include "cpu/base.hh" 402680Sktlim@umich.edu#include "cpu/thread_context.hh" 412313SN/A#include "cpu/quiesce_event.hh" 423565Sgblack@eecs.umich.edu#include "arch/kernel_stats.hh" 43299SN/A#include "sim/param.hh" 443565Sgblack@eecs.umich.edu#include "sim/pseudo_inst.hh" 45298SN/A#include "sim/serialize.hh" 46298SN/A#include "sim/sim_exit.hh" 47695SN/A#include "sim/stat_control.hh" 48695SN/A#include "sim/stats.hh" 49954SN/A#include "sim/system.hh" 501052SN/A#include "sim/debug.hh" 512080SN/A#include "sim/vptr.hh" 52298SN/A 53299SN/Ausing namespace std; 541052SN/A 55729SN/Ausing namespace Stats; 562107SN/Ausing namespace TheISA; 57298SN/A 58298SN/Anamespace AlphaPseudo 59298SN/A{ 60299SN/A bool doStatisticsInsts; 61299SN/A bool doCheckpointInsts; 62310SN/A bool doQuiesce; 63310SN/A 64310SN/A void 652680Sktlim@umich.edu arm(ThreadContext *tc) 66711SN/A { 672680Sktlim@umich.edu if (tc->getKernelStats()) 682680Sktlim@umich.edu tc->getKernelStats()->arm(); 69711SN/A } 70711SN/A 71711SN/A void 722680Sktlim@umich.edu quiesce(ThreadContext *tc) 73310SN/A { 74310SN/A if (!doQuiesce) 75310SN/A return; 76310SN/A 773373Sstever@eecs.umich.edu DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name()); 783373Sstever@eecs.umich.edu 792680Sktlim@umich.edu tc->suspend(); 802680Sktlim@umich.edu if (tc->getKernelStats()) 812680Sktlim@umich.edu tc->getKernelStats()->quiesce(); 82310SN/A } 83299SN/A 84298SN/A void 852680Sktlim@umich.edu quiesceNs(ThreadContext *tc, uint64_t ns) 862188SN/A { 872188SN/A if (!doQuiesce || ns == 0) 882188SN/A return; 892188SN/A 902680Sktlim@umich.edu EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); 912235SN/A 923368Sstever@eecs.umich.edu Tick resume = curTick + Clock::Int::ns * ns; 933368Sstever@eecs.umich.edu 942235SN/A if (quiesceEvent->scheduled()) 953368Sstever@eecs.umich.edu quiesceEvent->reschedule(resume); 962188SN/A else 973368Sstever@eecs.umich.edu quiesceEvent->schedule(resume); 983368Sstever@eecs.umich.edu 993368Sstever@eecs.umich.edu DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n", 1003368Sstever@eecs.umich.edu tc->getCpuPtr()->name(), ns, resume); 1012188SN/A 1022680Sktlim@umich.edu tc->suspend(); 1032680Sktlim@umich.edu if (tc->getKernelStats()) 1042680Sktlim@umich.edu tc->getKernelStats()->quiesce(); 1052188SN/A } 1062188SN/A 1072188SN/A void 1082680Sktlim@umich.edu quiesceCycles(ThreadContext *tc, uint64_t cycles) 1092188SN/A { 1102188SN/A if (!doQuiesce || cycles == 0) 1112188SN/A return; 1122188SN/A 1132680Sktlim@umich.edu EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); 1142235SN/A 1153368Sstever@eecs.umich.edu Tick resume = curTick + tc->getCpuPtr()->cycles(cycles); 1163368Sstever@eecs.umich.edu 1172235SN/A if (quiesceEvent->scheduled()) 1183368Sstever@eecs.umich.edu quiesceEvent->reschedule(resume); 1192188SN/A else 1203368Sstever@eecs.umich.edu quiesceEvent->schedule(resume); 1213368Sstever@eecs.umich.edu 1223368Sstever@eecs.umich.edu DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n", 1233368Sstever@eecs.umich.edu tc->getCpuPtr()->name(), cycles, resume); 1242188SN/A 1252680Sktlim@umich.edu tc->suspend(); 1262680Sktlim@umich.edu if (tc->getKernelStats()) 1272680Sktlim@umich.edu tc->getKernelStats()->quiesce(); 1282188SN/A } 1292188SN/A 1302188SN/A uint64_t 1312680Sktlim@umich.edu quiesceTime(ThreadContext *tc) 1322188SN/A { 1332680Sktlim@umich.edu return (tc->readLastActivate() - tc->readLastSuspend()) / Clock::Int::ns; 1342188SN/A } 1352188SN/A 1362188SN/A void 1372680Sktlim@umich.edu m5exit_old(ThreadContext *tc) 138298SN/A { 1393144Shsul@eecs.umich.edu exitSimLoop("m5_exit_old instruction encountered"); 140298SN/A } 141298SN/A 142298SN/A void 1432680Sktlim@umich.edu m5exit(ThreadContext *tc, Tick delay) 144298SN/A { 1451609SN/A Tick when = curTick + delay * Clock::Int::ns; 1463144Shsul@eecs.umich.edu schedExitSimLoop("m5_exit instruction encountered", when); 147298SN/A } 148298SN/A 149298SN/A void 1503126Sktlim@umich.edu loadsymbol(ThreadContext *tc) 1512358SN/A { 1523126Sktlim@umich.edu const string &filename = tc->getCpuPtr()->system->params()->symbolfile; 1532358SN/A if (filename.empty()) { 1542358SN/A return; 1552358SN/A } 1562358SN/A 1572358SN/A std::string buffer; 1582358SN/A ifstream file(filename.c_str()); 1592358SN/A 1602358SN/A if (!file) 1612358SN/A fatal("file error: Can't open symbol table file %s\n", filename); 1622358SN/A 1632358SN/A while (!file.eof()) { 1642358SN/A getline(file, buffer); 1652358SN/A 1662358SN/A if (buffer.empty()) 1672358SN/A continue; 1682358SN/A 1692358SN/A int idx = buffer.find(' '); 1702358SN/A if (idx == string::npos) 1712358SN/A continue; 1722358SN/A 1732358SN/A string address = "0x" + buffer.substr(0, idx); 1742358SN/A eat_white(address); 1752358SN/A if (address.empty()) 1762358SN/A continue; 1772358SN/A 1782358SN/A // Skip over letter and space 1792358SN/A string symbol = buffer.substr(idx + 3); 1802358SN/A eat_white(symbol); 1812358SN/A if (symbol.empty()) 1822358SN/A continue; 1832358SN/A 1842358SN/A Addr addr; 1852358SN/A if (!to_number(address, addr)) 1862358SN/A continue; 1872358SN/A 1883126Sktlim@umich.edu if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol)) 1892358SN/A continue; 1902358SN/A 1912358SN/A 1922358SN/A DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 1932358SN/A } 1942358SN/A file.close(); 1952358SN/A } 1962358SN/A 1972358SN/A void 1982680Sktlim@umich.edu resetstats(ThreadContext *tc, Tick delay, Tick period) 199298SN/A { 200299SN/A if (!doStatisticsInsts) 201299SN/A return; 202299SN/A 203298SN/A 2041609SN/A Tick when = curTick + delay * Clock::Int::ns; 2051609SN/A Tick repeat = period * Clock::Int::ns; 206298SN/A 207729SN/A using namespace Stats; 208298SN/A SetupEvent(Reset, when, repeat); 209298SN/A } 210298SN/A 211298SN/A void 2122680Sktlim@umich.edu dumpstats(ThreadContext *tc, Tick delay, Tick period) 213298SN/A { 214299SN/A if (!doStatisticsInsts) 215299SN/A return; 216299SN/A 217298SN/A 2181609SN/A Tick when = curTick + delay * Clock::Int::ns; 2191609SN/A Tick repeat = period * Clock::Int::ns; 220298SN/A 221729SN/A using namespace Stats; 222298SN/A SetupEvent(Dump, when, repeat); 223298SN/A } 224298SN/A 225298SN/A void 2262680Sktlim@umich.edu addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr) 2271973SN/A { 2281973SN/A char symb[100]; 2292680Sktlim@umich.edu CopyStringOut(tc, symb, symbolAddr, 100); 2301973SN/A std::string symbol(symb); 2311973SN/A 2321973SN/A DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 2331973SN/A 2342680Sktlim@umich.edu tc->getSystemPtr()->kernelSymtab->insert(addr,symbol); 2351973SN/A } 2361973SN/A 2371973SN/A void 2383089Ssaidi@eecs.umich.edu anBegin(ThreadContext *tc, uint64_t cur) 2393089Ssaidi@eecs.umich.edu { 2403089Ssaidi@eecs.umich.edu Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & 2413089Ssaidi@eecs.umich.edu 0xFFFFFFFF, 0,0); 2423089Ssaidi@eecs.umich.edu } 2433089Ssaidi@eecs.umich.edu 2443089Ssaidi@eecs.umich.edu void 2453089Ssaidi@eecs.umich.edu anWait(ThreadContext *tc, uint64_t cur, uint64_t wait) 2463089Ssaidi@eecs.umich.edu { 2473089Ssaidi@eecs.umich.edu Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & 2483089Ssaidi@eecs.umich.edu 0xFFFFFFFF, wait >> 32, wait & 0xFFFFFFFF); 2493089Ssaidi@eecs.umich.edu } 2503089Ssaidi@eecs.umich.edu 2513089Ssaidi@eecs.umich.edu 2523089Ssaidi@eecs.umich.edu void 2532680Sktlim@umich.edu dumpresetstats(ThreadContext *tc, Tick delay, Tick period) 254298SN/A { 255299SN/A if (!doStatisticsInsts) 256299SN/A return; 257299SN/A 258298SN/A 2591609SN/A Tick when = curTick + delay * Clock::Int::ns; 2601609SN/A Tick repeat = period * Clock::Int::ns; 261298SN/A 262729SN/A using namespace Stats; 263298SN/A SetupEvent(Dump|Reset, when, repeat); 264298SN/A } 265298SN/A 266298SN/A void 2672680Sktlim@umich.edu m5checkpoint(ThreadContext *tc, Tick delay, Tick period) 268298SN/A { 269299SN/A if (!doCheckpointInsts) 270299SN/A return; 2713144Shsul@eecs.umich.edu 2723144Shsul@eecs.umich.edu Tick when = curTick + delay * Clock::Int::ns; 2733144Shsul@eecs.umich.edu Tick repeat = period * Clock::Int::ns; 2743144Shsul@eecs.umich.edu 2753144Shsul@eecs.umich.edu schedExitSimLoop("checkpoint", when, repeat); 276298SN/A } 277298SN/A 2782081SN/A uint64_t 2792680Sktlim@umich.edu readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset) 280954SN/A { 2812680Sktlim@umich.edu const string &file = tc->getCpuPtr()->system->params()->readfile; 282954SN/A if (file.empty()) { 2832081SN/A return ULL(0); 284954SN/A } 285954SN/A 286954SN/A uint64_t result = 0; 287954SN/A 288954SN/A int fd = ::open(file.c_str(), O_RDONLY, 0); 289954SN/A if (fd < 0) 290954SN/A panic("could not open file %s\n", file); 291954SN/A 2921642SN/A if (::lseek(fd, offset, SEEK_SET) < 0) 2931642SN/A panic("could not seek: %s", strerror(errno)); 2941642SN/A 295954SN/A char *buf = new char[len]; 296954SN/A char *p = buf; 297954SN/A while (len > 0) { 2981642SN/A int bytes = ::read(fd, p, len); 299954SN/A if (bytes <= 0) 300954SN/A break; 301954SN/A 302954SN/A p += bytes; 303954SN/A result += bytes; 304954SN/A len -= bytes; 305954SN/A } 306954SN/A 307954SN/A close(fd); 3082680Sktlim@umich.edu CopyIn(tc, vaddr, buf, result); 309954SN/A delete [] buf; 3102081SN/A return result; 311954SN/A } 312954SN/A 313299SN/A class Context : public ParamContext 314299SN/A { 315299SN/A public: 316299SN/A Context(const string §ion) : ParamContext(section) {} 317299SN/A void checkParams(); 318299SN/A }; 319299SN/A 3201343SN/A Context context("pseudo_inst"); 321299SN/A 322310SN/A Param<bool> __quiesce(&context, "quiesce", 323310SN/A "enable quiesce instructions", 324310SN/A true); 325300SN/A Param<bool> __statistics(&context, "statistics", 326310SN/A "enable statistics pseudo instructions", 327301SN/A true); 328300SN/A Param<bool> __checkpoint(&context, "checkpoint", 329310SN/A "enable checkpoint pseudo instructions", 330301SN/A true); 331299SN/A 332299SN/A void 333299SN/A Context::checkParams() 334299SN/A { 335310SN/A doQuiesce = __quiesce; 336299SN/A doStatisticsInsts = __statistics; 337299SN/A doCheckpointInsts = __checkpoint; 338299SN/A } 3391052SN/A 3402680Sktlim@umich.edu void debugbreak(ThreadContext *tc) 3411052SN/A { 3421052SN/A debug_break(); 3431052SN/A } 3441052SN/A 3452680Sktlim@umich.edu void switchcpu(ThreadContext *tc) 3461052SN/A { 3472841Sktlim@umich.edu exitSimLoop("switchcpu"); 3481052SN/A } 349298SN/A} 350