pseudo_inst.cc revision 3368
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 372081SN/A#include "sim/pseudo_inst.hh" 382170SN/A#include "arch/vtophys.hh" 393089Ssaidi@eecs.umich.edu#include "base/annotate.hh" 401717SN/A#include "cpu/base.hh" 412680Sktlim@umich.edu#include "cpu/thread_context.hh" 422313SN/A#include "cpu/quiesce_event.hh" 431070SN/A#include "kern/kernel_stats.hh" 44299SN/A#include "sim/param.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 772680Sktlim@umich.edu tc->suspend(); 782680Sktlim@umich.edu if (tc->getKernelStats()) 792680Sktlim@umich.edu tc->getKernelStats()->quiesce(); 80310SN/A } 81299SN/A 82298SN/A void 832680Sktlim@umich.edu quiesceNs(ThreadContext *tc, uint64_t ns) 842188SN/A { 852188SN/A if (!doQuiesce || ns == 0) 862188SN/A return; 872188SN/A 882680Sktlim@umich.edu EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); 892235SN/A 903368Sstever@eecs.umich.edu Tick resume = curTick + Clock::Int::ns * ns; 913368Sstever@eecs.umich.edu 922235SN/A if (quiesceEvent->scheduled()) 933368Sstever@eecs.umich.edu quiesceEvent->reschedule(resume); 942188SN/A else 953368Sstever@eecs.umich.edu quiesceEvent->schedule(resume); 963368Sstever@eecs.umich.edu 973368Sstever@eecs.umich.edu DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n", 983368Sstever@eecs.umich.edu tc->getCpuPtr()->name(), ns, resume); 992188SN/A 1002680Sktlim@umich.edu tc->suspend(); 1012680Sktlim@umich.edu if (tc->getKernelStats()) 1022680Sktlim@umich.edu tc->getKernelStats()->quiesce(); 1032188SN/A } 1042188SN/A 1052188SN/A void 1062680Sktlim@umich.edu quiesceCycles(ThreadContext *tc, uint64_t cycles) 1072188SN/A { 1082188SN/A if (!doQuiesce || cycles == 0) 1092188SN/A return; 1102188SN/A 1112680Sktlim@umich.edu EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); 1122235SN/A 1133368Sstever@eecs.umich.edu Tick resume = curTick + tc->getCpuPtr()->cycles(cycles); 1143368Sstever@eecs.umich.edu 1152235SN/A if (quiesceEvent->scheduled()) 1163368Sstever@eecs.umich.edu quiesceEvent->reschedule(resume); 1172188SN/A else 1183368Sstever@eecs.umich.edu quiesceEvent->schedule(resume); 1193368Sstever@eecs.umich.edu 1203368Sstever@eecs.umich.edu DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n", 1213368Sstever@eecs.umich.edu tc->getCpuPtr()->name(), cycles, resume); 1222188SN/A 1232680Sktlim@umich.edu tc->suspend(); 1242680Sktlim@umich.edu if (tc->getKernelStats()) 1252680Sktlim@umich.edu tc->getKernelStats()->quiesce(); 1262188SN/A } 1272188SN/A 1282188SN/A uint64_t 1292680Sktlim@umich.edu quiesceTime(ThreadContext *tc) 1302188SN/A { 1312680Sktlim@umich.edu return (tc->readLastActivate() - tc->readLastSuspend()) / Clock::Int::ns; 1322188SN/A } 1332188SN/A 1342188SN/A void 1352680Sktlim@umich.edu ivlb(ThreadContext *tc) 136711SN/A { 1372680Sktlim@umich.edu if (tc->getKernelStats()) 1382680Sktlim@umich.edu tc->getKernelStats()->ivlb(); 139711SN/A } 140711SN/A 141711SN/A void 1422680Sktlim@umich.edu ivle(ThreadContext *tc) 143711SN/A { 144711SN/A } 145711SN/A 146711SN/A void 1472680Sktlim@umich.edu m5exit_old(ThreadContext *tc) 148298SN/A { 1493144Shsul@eecs.umich.edu exitSimLoop("m5_exit_old instruction encountered"); 150298SN/A } 151298SN/A 152298SN/A void 1532680Sktlim@umich.edu m5exit(ThreadContext *tc, Tick delay) 154298SN/A { 1551609SN/A Tick when = curTick + delay * Clock::Int::ns; 1563144Shsul@eecs.umich.edu schedExitSimLoop("m5_exit instruction encountered", when); 157298SN/A } 158298SN/A 159298SN/A void 1603126Sktlim@umich.edu loadsymbol(ThreadContext *tc) 1612358SN/A { 1623126Sktlim@umich.edu const string &filename = tc->getCpuPtr()->system->params()->symbolfile; 1632358SN/A if (filename.empty()) { 1642358SN/A return; 1652358SN/A } 1662358SN/A 1672358SN/A std::string buffer; 1682358SN/A ifstream file(filename.c_str()); 1692358SN/A 1702358SN/A if (!file) 1712358SN/A fatal("file error: Can't open symbol table file %s\n", filename); 1722358SN/A 1732358SN/A while (!file.eof()) { 1742358SN/A getline(file, buffer); 1752358SN/A 1762358SN/A if (buffer.empty()) 1772358SN/A continue; 1782358SN/A 1792358SN/A int idx = buffer.find(' '); 1802358SN/A if (idx == string::npos) 1812358SN/A continue; 1822358SN/A 1832358SN/A string address = "0x" + buffer.substr(0, idx); 1842358SN/A eat_white(address); 1852358SN/A if (address.empty()) 1862358SN/A continue; 1872358SN/A 1882358SN/A // Skip over letter and space 1892358SN/A string symbol = buffer.substr(idx + 3); 1902358SN/A eat_white(symbol); 1912358SN/A if (symbol.empty()) 1922358SN/A continue; 1932358SN/A 1942358SN/A Addr addr; 1952358SN/A if (!to_number(address, addr)) 1962358SN/A continue; 1972358SN/A 1983126Sktlim@umich.edu if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol)) 1992358SN/A continue; 2002358SN/A 2012358SN/A 2022358SN/A DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 2032358SN/A } 2042358SN/A file.close(); 2052358SN/A } 2062358SN/A 2072358SN/A void 2082680Sktlim@umich.edu resetstats(ThreadContext *tc, Tick delay, Tick period) 209298SN/A { 210299SN/A if (!doStatisticsInsts) 211299SN/A return; 212299SN/A 213298SN/A 2141609SN/A Tick when = curTick + delay * Clock::Int::ns; 2151609SN/A Tick repeat = period * Clock::Int::ns; 216298SN/A 217729SN/A using namespace Stats; 218298SN/A SetupEvent(Reset, when, repeat); 219298SN/A } 220298SN/A 221298SN/A void 2222680Sktlim@umich.edu dumpstats(ThreadContext *tc, Tick delay, Tick period) 223298SN/A { 224299SN/A if (!doStatisticsInsts) 225299SN/A return; 226299SN/A 227298SN/A 2281609SN/A Tick when = curTick + delay * Clock::Int::ns; 2291609SN/A Tick repeat = period * Clock::Int::ns; 230298SN/A 231729SN/A using namespace Stats; 232298SN/A SetupEvent(Dump, when, repeat); 233298SN/A } 234298SN/A 235298SN/A void 2362680Sktlim@umich.edu addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr) 2371973SN/A { 2381973SN/A char symb[100]; 2392680Sktlim@umich.edu CopyStringOut(tc, symb, symbolAddr, 100); 2401973SN/A std::string symbol(symb); 2411973SN/A 2421973SN/A DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 2431973SN/A 2442680Sktlim@umich.edu tc->getSystemPtr()->kernelSymtab->insert(addr,symbol); 2451973SN/A } 2461973SN/A 2471973SN/A void 2483089Ssaidi@eecs.umich.edu anBegin(ThreadContext *tc, uint64_t cur) 2493089Ssaidi@eecs.umich.edu { 2503089Ssaidi@eecs.umich.edu Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & 2513089Ssaidi@eecs.umich.edu 0xFFFFFFFF, 0,0); 2523089Ssaidi@eecs.umich.edu } 2533089Ssaidi@eecs.umich.edu 2543089Ssaidi@eecs.umich.edu void 2553089Ssaidi@eecs.umich.edu anWait(ThreadContext *tc, uint64_t cur, uint64_t wait) 2563089Ssaidi@eecs.umich.edu { 2573089Ssaidi@eecs.umich.edu Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & 2583089Ssaidi@eecs.umich.edu 0xFFFFFFFF, wait >> 32, wait & 0xFFFFFFFF); 2593089Ssaidi@eecs.umich.edu } 2603089Ssaidi@eecs.umich.edu 2613089Ssaidi@eecs.umich.edu 2623089Ssaidi@eecs.umich.edu void 2632680Sktlim@umich.edu dumpresetstats(ThreadContext *tc, Tick delay, Tick period) 264298SN/A { 265299SN/A if (!doStatisticsInsts) 266299SN/A return; 267299SN/A 268298SN/A 2691609SN/A Tick when = curTick + delay * Clock::Int::ns; 2701609SN/A Tick repeat = period * Clock::Int::ns; 271298SN/A 272729SN/A using namespace Stats; 273298SN/A SetupEvent(Dump|Reset, when, repeat); 274298SN/A } 275298SN/A 276298SN/A void 2772680Sktlim@umich.edu m5checkpoint(ThreadContext *tc, Tick delay, Tick period) 278298SN/A { 279299SN/A if (!doCheckpointInsts) 280299SN/A return; 2813144Shsul@eecs.umich.edu 2823144Shsul@eecs.umich.edu Tick when = curTick + delay * Clock::Int::ns; 2833144Shsul@eecs.umich.edu Tick repeat = period * Clock::Int::ns; 2843144Shsul@eecs.umich.edu 2853144Shsul@eecs.umich.edu schedExitSimLoop("checkpoint", when, repeat); 286298SN/A } 287298SN/A 2882081SN/A uint64_t 2892680Sktlim@umich.edu readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset) 290954SN/A { 2912680Sktlim@umich.edu const string &file = tc->getCpuPtr()->system->params()->readfile; 292954SN/A if (file.empty()) { 2932081SN/A return ULL(0); 294954SN/A } 295954SN/A 296954SN/A uint64_t result = 0; 297954SN/A 298954SN/A int fd = ::open(file.c_str(), O_RDONLY, 0); 299954SN/A if (fd < 0) 300954SN/A panic("could not open file %s\n", file); 301954SN/A 3021642SN/A if (::lseek(fd, offset, SEEK_SET) < 0) 3031642SN/A panic("could not seek: %s", strerror(errno)); 3041642SN/A 305954SN/A char *buf = new char[len]; 306954SN/A char *p = buf; 307954SN/A while (len > 0) { 3081642SN/A int bytes = ::read(fd, p, len); 309954SN/A if (bytes <= 0) 310954SN/A break; 311954SN/A 312954SN/A p += bytes; 313954SN/A result += bytes; 314954SN/A len -= bytes; 315954SN/A } 316954SN/A 317954SN/A close(fd); 3182680Sktlim@umich.edu CopyIn(tc, vaddr, buf, result); 319954SN/A delete [] buf; 3202081SN/A return result; 321954SN/A } 322954SN/A 323299SN/A class Context : public ParamContext 324299SN/A { 325299SN/A public: 326299SN/A Context(const string §ion) : ParamContext(section) {} 327299SN/A void checkParams(); 328299SN/A }; 329299SN/A 3301343SN/A Context context("pseudo_inst"); 331299SN/A 332310SN/A Param<bool> __quiesce(&context, "quiesce", 333310SN/A "enable quiesce instructions", 334310SN/A true); 335300SN/A Param<bool> __statistics(&context, "statistics", 336310SN/A "enable statistics pseudo instructions", 337301SN/A true); 338300SN/A Param<bool> __checkpoint(&context, "checkpoint", 339310SN/A "enable checkpoint pseudo instructions", 340301SN/A true); 341299SN/A 342299SN/A void 343299SN/A Context::checkParams() 344299SN/A { 345310SN/A doQuiesce = __quiesce; 346299SN/A doStatisticsInsts = __statistics; 347299SN/A doCheckpointInsts = __checkpoint; 348299SN/A } 3491052SN/A 3502680Sktlim@umich.edu void debugbreak(ThreadContext *tc) 3511052SN/A { 3521052SN/A debug_break(); 3531052SN/A } 3541052SN/A 3552680Sktlim@umich.edu void switchcpu(ThreadContext *tc) 3561052SN/A { 3572841Sktlim@umich.edu exitSimLoop("switchcpu"); 3581052SN/A } 359298SN/A} 360