pseudo_inst.cc revision 3126
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 902235SN/A if (quiesceEvent->scheduled()) 912235SN/A quiesceEvent->reschedule(curTick + Clock::Int::ns * ns); 922188SN/A else 932235SN/A quiesceEvent->schedule(curTick + Clock::Int::ns * ns); 942188SN/A 952680Sktlim@umich.edu tc->suspend(); 962680Sktlim@umich.edu if (tc->getKernelStats()) 972680Sktlim@umich.edu tc->getKernelStats()->quiesce(); 982188SN/A } 992188SN/A 1002188SN/A void 1012680Sktlim@umich.edu quiesceCycles(ThreadContext *tc, uint64_t cycles) 1022188SN/A { 1032188SN/A if (!doQuiesce || cycles == 0) 1042188SN/A return; 1052188SN/A 1062680Sktlim@umich.edu EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); 1072235SN/A 1082235SN/A if (quiesceEvent->scheduled()) 1092235SN/A quiesceEvent->reschedule(curTick + 1102680Sktlim@umich.edu tc->getCpuPtr()->cycles(cycles)); 1112188SN/A else 1122235SN/A quiesceEvent->schedule(curTick + 1132680Sktlim@umich.edu tc->getCpuPtr()->cycles(cycles)); 1142188SN/A 1152680Sktlim@umich.edu tc->suspend(); 1162680Sktlim@umich.edu if (tc->getKernelStats()) 1172680Sktlim@umich.edu tc->getKernelStats()->quiesce(); 1182188SN/A } 1192188SN/A 1202188SN/A uint64_t 1212680Sktlim@umich.edu quiesceTime(ThreadContext *tc) 1222188SN/A { 1232680Sktlim@umich.edu return (tc->readLastActivate() - tc->readLastSuspend()) / Clock::Int::ns; 1242188SN/A } 1252188SN/A 1262188SN/A void 1272680Sktlim@umich.edu ivlb(ThreadContext *tc) 128711SN/A { 1292680Sktlim@umich.edu if (tc->getKernelStats()) 1302680Sktlim@umich.edu tc->getKernelStats()->ivlb(); 131711SN/A } 132711SN/A 133711SN/A void 1342680Sktlim@umich.edu ivle(ThreadContext *tc) 135711SN/A { 136711SN/A } 137711SN/A 138711SN/A void 1392680Sktlim@umich.edu m5exit_old(ThreadContext *tc) 140298SN/A { 1412667Sstever@eecs.umich.edu exitSimLoop(curTick, "m5_exit_old instruction encountered"); 142298SN/A } 143298SN/A 144298SN/A void 1452680Sktlim@umich.edu m5exit(ThreadContext *tc, Tick delay) 146298SN/A { 1471609SN/A Tick when = curTick + delay * Clock::Int::ns; 1482667Sstever@eecs.umich.edu exitSimLoop(when, "m5_exit instruction encountered"); 149298SN/A } 150298SN/A 151298SN/A void 1523126Sktlim@umich.edu loadsymbol(ThreadContext *tc) 1532358SN/A { 1543126Sktlim@umich.edu const string &filename = tc->getCpuPtr()->system->params()->symbolfile; 1552358SN/A if (filename.empty()) { 1562358SN/A return; 1572358SN/A } 1582358SN/A 1592358SN/A std::string buffer; 1602358SN/A ifstream file(filename.c_str()); 1612358SN/A 1622358SN/A if (!file) 1632358SN/A fatal("file error: Can't open symbol table file %s\n", filename); 1642358SN/A 1652358SN/A while (!file.eof()) { 1662358SN/A getline(file, buffer); 1672358SN/A 1682358SN/A if (buffer.empty()) 1692358SN/A continue; 1702358SN/A 1712358SN/A int idx = buffer.find(' '); 1722358SN/A if (idx == string::npos) 1732358SN/A continue; 1742358SN/A 1752358SN/A string address = "0x" + buffer.substr(0, idx); 1762358SN/A eat_white(address); 1772358SN/A if (address.empty()) 1782358SN/A continue; 1792358SN/A 1802358SN/A // Skip over letter and space 1812358SN/A string symbol = buffer.substr(idx + 3); 1822358SN/A eat_white(symbol); 1832358SN/A if (symbol.empty()) 1842358SN/A continue; 1852358SN/A 1862358SN/A Addr addr; 1872358SN/A if (!to_number(address, addr)) 1882358SN/A continue; 1892358SN/A 1903126Sktlim@umich.edu if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol)) 1912358SN/A continue; 1922358SN/A 1932358SN/A 1942358SN/A DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 1952358SN/A } 1962358SN/A file.close(); 1972358SN/A } 1982358SN/A 1992358SN/A void 2002680Sktlim@umich.edu resetstats(ThreadContext *tc, Tick delay, Tick period) 201298SN/A { 202299SN/A if (!doStatisticsInsts) 203299SN/A return; 204299SN/A 205298SN/A 2061609SN/A Tick when = curTick + delay * Clock::Int::ns; 2071609SN/A Tick repeat = period * Clock::Int::ns; 208298SN/A 209729SN/A using namespace Stats; 210298SN/A SetupEvent(Reset, when, repeat); 211298SN/A } 212298SN/A 213298SN/A void 2142680Sktlim@umich.edu dumpstats(ThreadContext *tc, Tick delay, Tick period) 215298SN/A { 216299SN/A if (!doStatisticsInsts) 217299SN/A return; 218299SN/A 219298SN/A 2201609SN/A Tick when = curTick + delay * Clock::Int::ns; 2211609SN/A Tick repeat = period * Clock::Int::ns; 222298SN/A 223729SN/A using namespace Stats; 224298SN/A SetupEvent(Dump, when, repeat); 225298SN/A } 226298SN/A 227298SN/A void 2282680Sktlim@umich.edu addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr) 2291973SN/A { 2301973SN/A char symb[100]; 2312680Sktlim@umich.edu CopyStringOut(tc, symb, symbolAddr, 100); 2321973SN/A std::string symbol(symb); 2331973SN/A 2341973SN/A DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 2351973SN/A 2362680Sktlim@umich.edu tc->getSystemPtr()->kernelSymtab->insert(addr,symbol); 2371973SN/A } 2381973SN/A 2391973SN/A void 2403089Ssaidi@eecs.umich.edu anBegin(ThreadContext *tc, uint64_t cur) 2413089Ssaidi@eecs.umich.edu { 2423089Ssaidi@eecs.umich.edu Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & 2433089Ssaidi@eecs.umich.edu 0xFFFFFFFF, 0,0); 2443089Ssaidi@eecs.umich.edu } 2453089Ssaidi@eecs.umich.edu 2463089Ssaidi@eecs.umich.edu void 2473089Ssaidi@eecs.umich.edu anWait(ThreadContext *tc, uint64_t cur, uint64_t wait) 2483089Ssaidi@eecs.umich.edu { 2493089Ssaidi@eecs.umich.edu Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & 2503089Ssaidi@eecs.umich.edu 0xFFFFFFFF, wait >> 32, wait & 0xFFFFFFFF); 2513089Ssaidi@eecs.umich.edu } 2523089Ssaidi@eecs.umich.edu 2533089Ssaidi@eecs.umich.edu 2543089Ssaidi@eecs.umich.edu void 2552680Sktlim@umich.edu dumpresetstats(ThreadContext *tc, Tick delay, Tick period) 256298SN/A { 257299SN/A if (!doStatisticsInsts) 258299SN/A return; 259299SN/A 260298SN/A 2611609SN/A Tick when = curTick + delay * Clock::Int::ns; 2621609SN/A Tick repeat = period * Clock::Int::ns; 263298SN/A 264729SN/A using namespace Stats; 265298SN/A SetupEvent(Dump|Reset, when, repeat); 266298SN/A } 267298SN/A 268298SN/A void 2692680Sktlim@umich.edu m5checkpoint(ThreadContext *tc, Tick delay, Tick period) 270298SN/A { 271299SN/A if (!doCheckpointInsts) 272299SN/A return; 2732841Sktlim@umich.edu exitSimLoop("checkpoint"); 274298SN/A } 275298SN/A 2762081SN/A uint64_t 2772680Sktlim@umich.edu readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset) 278954SN/A { 2792680Sktlim@umich.edu const string &file = tc->getCpuPtr()->system->params()->readfile; 280954SN/A if (file.empty()) { 2812081SN/A return ULL(0); 282954SN/A } 283954SN/A 284954SN/A uint64_t result = 0; 285954SN/A 286954SN/A int fd = ::open(file.c_str(), O_RDONLY, 0); 287954SN/A if (fd < 0) 288954SN/A panic("could not open file %s\n", file); 289954SN/A 2901642SN/A if (::lseek(fd, offset, SEEK_SET) < 0) 2911642SN/A panic("could not seek: %s", strerror(errno)); 2921642SN/A 293954SN/A char *buf = new char[len]; 294954SN/A char *p = buf; 295954SN/A while (len > 0) { 2961642SN/A int bytes = ::read(fd, p, len); 297954SN/A if (bytes <= 0) 298954SN/A break; 299954SN/A 300954SN/A p += bytes; 301954SN/A result += bytes; 302954SN/A len -= bytes; 303954SN/A } 304954SN/A 305954SN/A close(fd); 3062680Sktlim@umich.edu CopyIn(tc, vaddr, buf, result); 307954SN/A delete [] buf; 3082081SN/A return result; 309954SN/A } 310954SN/A 311299SN/A class Context : public ParamContext 312299SN/A { 313299SN/A public: 314299SN/A Context(const string §ion) : ParamContext(section) {} 315299SN/A void checkParams(); 316299SN/A }; 317299SN/A 3181343SN/A Context context("pseudo_inst"); 319299SN/A 320310SN/A Param<bool> __quiesce(&context, "quiesce", 321310SN/A "enable quiesce instructions", 322310SN/A true); 323300SN/A Param<bool> __statistics(&context, "statistics", 324310SN/A "enable statistics pseudo instructions", 325301SN/A true); 326300SN/A Param<bool> __checkpoint(&context, "checkpoint", 327310SN/A "enable checkpoint pseudo instructions", 328301SN/A true); 329299SN/A 330299SN/A void 331299SN/A Context::checkParams() 332299SN/A { 333310SN/A doQuiesce = __quiesce; 334299SN/A doStatisticsInsts = __statistics; 335299SN/A doCheckpointInsts = __checkpoint; 336299SN/A } 3371052SN/A 3382680Sktlim@umich.edu void debugbreak(ThreadContext *tc) 3391052SN/A { 3401052SN/A debug_break(); 3411052SN/A } 3421052SN/A 3432680Sktlim@umich.edu void switchcpu(ThreadContext *tc) 3441052SN/A { 3452841Sktlim@umich.edu exitSimLoop("switchcpu"); 3461052SN/A } 347298SN/A} 348