pseudo_inst.cc revision 3373
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 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 ivlb(ThreadContext *tc) 138711SN/A { 1392680Sktlim@umich.edu if (tc->getKernelStats()) 1402680Sktlim@umich.edu tc->getKernelStats()->ivlb(); 141711SN/A } 142711SN/A 143711SN/A void 1442680Sktlim@umich.edu ivle(ThreadContext *tc) 145711SN/A { 146711SN/A } 147711SN/A 148711SN/A void 1492680Sktlim@umich.edu m5exit_old(ThreadContext *tc) 150298SN/A { 1513144Shsul@eecs.umich.edu exitSimLoop("m5_exit_old instruction encountered"); 152298SN/A } 153298SN/A 154298SN/A void 1552680Sktlim@umich.edu m5exit(ThreadContext *tc, Tick delay) 156298SN/A { 1571609SN/A Tick when = curTick + delay * Clock::Int::ns; 1583144Shsul@eecs.umich.edu schedExitSimLoop("m5_exit instruction encountered", when); 159298SN/A } 160298SN/A 161298SN/A void 1623126Sktlim@umich.edu loadsymbol(ThreadContext *tc) 1632358SN/A { 1643126Sktlim@umich.edu const string &filename = tc->getCpuPtr()->system->params()->symbolfile; 1652358SN/A if (filename.empty()) { 1662358SN/A return; 1672358SN/A } 1682358SN/A 1692358SN/A std::string buffer; 1702358SN/A ifstream file(filename.c_str()); 1712358SN/A 1722358SN/A if (!file) 1732358SN/A fatal("file error: Can't open symbol table file %s\n", filename); 1742358SN/A 1752358SN/A while (!file.eof()) { 1762358SN/A getline(file, buffer); 1772358SN/A 1782358SN/A if (buffer.empty()) 1792358SN/A continue; 1802358SN/A 1812358SN/A int idx = buffer.find(' '); 1822358SN/A if (idx == string::npos) 1832358SN/A continue; 1842358SN/A 1852358SN/A string address = "0x" + buffer.substr(0, idx); 1862358SN/A eat_white(address); 1872358SN/A if (address.empty()) 1882358SN/A continue; 1892358SN/A 1902358SN/A // Skip over letter and space 1912358SN/A string symbol = buffer.substr(idx + 3); 1922358SN/A eat_white(symbol); 1932358SN/A if (symbol.empty()) 1942358SN/A continue; 1952358SN/A 1962358SN/A Addr addr; 1972358SN/A if (!to_number(address, addr)) 1982358SN/A continue; 1992358SN/A 2003126Sktlim@umich.edu if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol)) 2012358SN/A continue; 2022358SN/A 2032358SN/A 2042358SN/A DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 2052358SN/A } 2062358SN/A file.close(); 2072358SN/A } 2082358SN/A 2092358SN/A void 2102680Sktlim@umich.edu resetstats(ThreadContext *tc, Tick delay, Tick period) 211298SN/A { 212299SN/A if (!doStatisticsInsts) 213299SN/A return; 214299SN/A 215298SN/A 2161609SN/A Tick when = curTick + delay * Clock::Int::ns; 2171609SN/A Tick repeat = period * Clock::Int::ns; 218298SN/A 219729SN/A using namespace Stats; 220298SN/A SetupEvent(Reset, when, repeat); 221298SN/A } 222298SN/A 223298SN/A void 2242680Sktlim@umich.edu dumpstats(ThreadContext *tc, Tick delay, Tick period) 225298SN/A { 226299SN/A if (!doStatisticsInsts) 227299SN/A return; 228299SN/A 229298SN/A 2301609SN/A Tick when = curTick + delay * Clock::Int::ns; 2311609SN/A Tick repeat = period * Clock::Int::ns; 232298SN/A 233729SN/A using namespace Stats; 234298SN/A SetupEvent(Dump, when, repeat); 235298SN/A } 236298SN/A 237298SN/A void 2382680Sktlim@umich.edu addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr) 2391973SN/A { 2401973SN/A char symb[100]; 2412680Sktlim@umich.edu CopyStringOut(tc, symb, symbolAddr, 100); 2421973SN/A std::string symbol(symb); 2431973SN/A 2441973SN/A DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 2451973SN/A 2462680Sktlim@umich.edu tc->getSystemPtr()->kernelSymtab->insert(addr,symbol); 2471973SN/A } 2481973SN/A 2491973SN/A void 2503089Ssaidi@eecs.umich.edu anBegin(ThreadContext *tc, uint64_t cur) 2513089Ssaidi@eecs.umich.edu { 2523089Ssaidi@eecs.umich.edu Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & 2533089Ssaidi@eecs.umich.edu 0xFFFFFFFF, 0,0); 2543089Ssaidi@eecs.umich.edu } 2553089Ssaidi@eecs.umich.edu 2563089Ssaidi@eecs.umich.edu void 2573089Ssaidi@eecs.umich.edu anWait(ThreadContext *tc, uint64_t cur, uint64_t wait) 2583089Ssaidi@eecs.umich.edu { 2593089Ssaidi@eecs.umich.edu Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & 2603089Ssaidi@eecs.umich.edu 0xFFFFFFFF, wait >> 32, wait & 0xFFFFFFFF); 2613089Ssaidi@eecs.umich.edu } 2623089Ssaidi@eecs.umich.edu 2633089Ssaidi@eecs.umich.edu 2643089Ssaidi@eecs.umich.edu void 2652680Sktlim@umich.edu dumpresetstats(ThreadContext *tc, Tick delay, Tick period) 266298SN/A { 267299SN/A if (!doStatisticsInsts) 268299SN/A return; 269299SN/A 270298SN/A 2711609SN/A Tick when = curTick + delay * Clock::Int::ns; 2721609SN/A Tick repeat = period * Clock::Int::ns; 273298SN/A 274729SN/A using namespace Stats; 275298SN/A SetupEvent(Dump|Reset, when, repeat); 276298SN/A } 277298SN/A 278298SN/A void 2792680Sktlim@umich.edu m5checkpoint(ThreadContext *tc, Tick delay, Tick period) 280298SN/A { 281299SN/A if (!doCheckpointInsts) 282299SN/A return; 2833144Shsul@eecs.umich.edu 2843144Shsul@eecs.umich.edu Tick when = curTick + delay * Clock::Int::ns; 2853144Shsul@eecs.umich.edu Tick repeat = period * Clock::Int::ns; 2863144Shsul@eecs.umich.edu 2873144Shsul@eecs.umich.edu schedExitSimLoop("checkpoint", when, repeat); 288298SN/A } 289298SN/A 2902081SN/A uint64_t 2912680Sktlim@umich.edu readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset) 292954SN/A { 2932680Sktlim@umich.edu const string &file = tc->getCpuPtr()->system->params()->readfile; 294954SN/A if (file.empty()) { 2952081SN/A return ULL(0); 296954SN/A } 297954SN/A 298954SN/A uint64_t result = 0; 299954SN/A 300954SN/A int fd = ::open(file.c_str(), O_RDONLY, 0); 301954SN/A if (fd < 0) 302954SN/A panic("could not open file %s\n", file); 303954SN/A 3041642SN/A if (::lseek(fd, offset, SEEK_SET) < 0) 3051642SN/A panic("could not seek: %s", strerror(errno)); 3061642SN/A 307954SN/A char *buf = new char[len]; 308954SN/A char *p = buf; 309954SN/A while (len > 0) { 3101642SN/A int bytes = ::read(fd, p, len); 311954SN/A if (bytes <= 0) 312954SN/A break; 313954SN/A 314954SN/A p += bytes; 315954SN/A result += bytes; 316954SN/A len -= bytes; 317954SN/A } 318954SN/A 319954SN/A close(fd); 3202680Sktlim@umich.edu CopyIn(tc, vaddr, buf, result); 321954SN/A delete [] buf; 3222081SN/A return result; 323954SN/A } 324954SN/A 325299SN/A class Context : public ParamContext 326299SN/A { 327299SN/A public: 328299SN/A Context(const string §ion) : ParamContext(section) {} 329299SN/A void checkParams(); 330299SN/A }; 331299SN/A 3321343SN/A Context context("pseudo_inst"); 333299SN/A 334310SN/A Param<bool> __quiesce(&context, "quiesce", 335310SN/A "enable quiesce instructions", 336310SN/A true); 337300SN/A Param<bool> __statistics(&context, "statistics", 338310SN/A "enable statistics pseudo instructions", 339301SN/A true); 340300SN/A Param<bool> __checkpoint(&context, "checkpoint", 341310SN/A "enable checkpoint pseudo instructions", 342301SN/A true); 343299SN/A 344299SN/A void 345299SN/A Context::checkParams() 346299SN/A { 347310SN/A doQuiesce = __quiesce; 348299SN/A doStatisticsInsts = __statistics; 349299SN/A doCheckpointInsts = __checkpoint; 350299SN/A } 3511052SN/A 3522680Sktlim@umich.edu void debugbreak(ThreadContext *tc) 3531052SN/A { 3541052SN/A debug_break(); 3551052SN/A } 3561052SN/A 3572680Sktlim@umich.edu void switchcpu(ThreadContext *tc) 3581052SN/A { 3592841Sktlim@umich.edu exitSimLoop("switchcpu"); 3601052SN/A } 361298SN/A} 362