pseudo_inst.cc revision 4078
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 354078Sbinkertn@umich.edu#include <fstream> 36299SN/A#include <string> 37299SN/A 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" 433565Sgblack@eecs.umich.edu#include "arch/kernel_stats.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{ 60310SN/A void 612680Sktlim@umich.edu arm(ThreadContext *tc) 62711SN/A { 632680Sktlim@umich.edu if (tc->getKernelStats()) 642680Sktlim@umich.edu tc->getKernelStats()->arm(); 65711SN/A } 66711SN/A 67711SN/A void 682680Sktlim@umich.edu quiesce(ThreadContext *tc) 69310SN/A { 703617Sbinkertn@umich.edu if (!tc->getCpuPtr()->params->do_quiesce) 71310SN/A return; 72310SN/A 733373Sstever@eecs.umich.edu DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name()); 743373Sstever@eecs.umich.edu 752680Sktlim@umich.edu tc->suspend(); 762680Sktlim@umich.edu if (tc->getKernelStats()) 772680Sktlim@umich.edu tc->getKernelStats()->quiesce(); 78310SN/A } 79299SN/A 80298SN/A void 812680Sktlim@umich.edu quiesceNs(ThreadContext *tc, uint64_t ns) 822188SN/A { 833617Sbinkertn@umich.edu if (!tc->getCpuPtr()->params->do_quiesce || ns == 0) 842188SN/A return; 852188SN/A 862680Sktlim@umich.edu EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); 872235SN/A 883368Sstever@eecs.umich.edu Tick resume = curTick + Clock::Int::ns * ns; 893368Sstever@eecs.umich.edu 902235SN/A if (quiesceEvent->scheduled()) 913368Sstever@eecs.umich.edu quiesceEvent->reschedule(resume); 922188SN/A else 933368Sstever@eecs.umich.edu quiesceEvent->schedule(resume); 943368Sstever@eecs.umich.edu 953368Sstever@eecs.umich.edu DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n", 963368Sstever@eecs.umich.edu tc->getCpuPtr()->name(), ns, resume); 972188SN/A 982680Sktlim@umich.edu tc->suspend(); 992680Sktlim@umich.edu if (tc->getKernelStats()) 1002680Sktlim@umich.edu tc->getKernelStats()->quiesce(); 1012188SN/A } 1022188SN/A 1032188SN/A void 1042680Sktlim@umich.edu quiesceCycles(ThreadContext *tc, uint64_t cycles) 1052188SN/A { 1063617Sbinkertn@umich.edu if (!tc->getCpuPtr()->params->do_quiesce || cycles == 0) 1072188SN/A return; 1082188SN/A 1092680Sktlim@umich.edu EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); 1102235SN/A 1113368Sstever@eecs.umich.edu Tick resume = curTick + tc->getCpuPtr()->cycles(cycles); 1123368Sstever@eecs.umich.edu 1132235SN/A if (quiesceEvent->scheduled()) 1143368Sstever@eecs.umich.edu quiesceEvent->reschedule(resume); 1152188SN/A else 1163368Sstever@eecs.umich.edu quiesceEvent->schedule(resume); 1173368Sstever@eecs.umich.edu 1183368Sstever@eecs.umich.edu DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n", 1193368Sstever@eecs.umich.edu tc->getCpuPtr()->name(), cycles, resume); 1202188SN/A 1212680Sktlim@umich.edu tc->suspend(); 1222680Sktlim@umich.edu if (tc->getKernelStats()) 1232680Sktlim@umich.edu tc->getKernelStats()->quiesce(); 1242188SN/A } 1252188SN/A 1262188SN/A uint64_t 1272680Sktlim@umich.edu quiesceTime(ThreadContext *tc) 1282188SN/A { 1292680Sktlim@umich.edu return (tc->readLastActivate() - tc->readLastSuspend()) / Clock::Int::ns; 1302188SN/A } 1312188SN/A 1322188SN/A void 1332680Sktlim@umich.edu m5exit_old(ThreadContext *tc) 134298SN/A { 1353144Shsul@eecs.umich.edu exitSimLoop("m5_exit_old instruction encountered"); 136298SN/A } 137298SN/A 138298SN/A void 1392680Sktlim@umich.edu m5exit(ThreadContext *tc, Tick delay) 140298SN/A { 1411609SN/A Tick when = curTick + delay * Clock::Int::ns; 1423144Shsul@eecs.umich.edu schedExitSimLoop("m5_exit instruction encountered", when); 143298SN/A } 144298SN/A 145298SN/A void 1463126Sktlim@umich.edu loadsymbol(ThreadContext *tc) 1472358SN/A { 1483126Sktlim@umich.edu const string &filename = tc->getCpuPtr()->system->params()->symbolfile; 1492358SN/A if (filename.empty()) { 1502358SN/A return; 1512358SN/A } 1522358SN/A 1532358SN/A std::string buffer; 1542358SN/A ifstream file(filename.c_str()); 1552358SN/A 1562358SN/A if (!file) 1572358SN/A fatal("file error: Can't open symbol table file %s\n", filename); 1582358SN/A 1592358SN/A while (!file.eof()) { 1602358SN/A getline(file, buffer); 1612358SN/A 1622358SN/A if (buffer.empty()) 1632358SN/A continue; 1642358SN/A 1652358SN/A int idx = buffer.find(' '); 1662358SN/A if (idx == string::npos) 1672358SN/A continue; 1682358SN/A 1692358SN/A string address = "0x" + buffer.substr(0, idx); 1702358SN/A eat_white(address); 1712358SN/A if (address.empty()) 1722358SN/A continue; 1732358SN/A 1742358SN/A // Skip over letter and space 1752358SN/A string symbol = buffer.substr(idx + 3); 1762358SN/A eat_white(symbol); 1772358SN/A if (symbol.empty()) 1782358SN/A continue; 1792358SN/A 1802358SN/A Addr addr; 1812358SN/A if (!to_number(address, addr)) 1822358SN/A continue; 1832358SN/A 1843126Sktlim@umich.edu if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol)) 1852358SN/A continue; 1862358SN/A 1872358SN/A 1882358SN/A DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 1892358SN/A } 1902358SN/A file.close(); 1912358SN/A } 1922358SN/A 1932358SN/A void 1942680Sktlim@umich.edu resetstats(ThreadContext *tc, Tick delay, Tick period) 195298SN/A { 1963617Sbinkertn@umich.edu if (!tc->getCpuPtr()->params->do_statistics_insts) 197299SN/A return; 198299SN/A 199298SN/A 2001609SN/A Tick when = curTick + delay * Clock::Int::ns; 2011609SN/A Tick repeat = period * Clock::Int::ns; 202298SN/A 2034078Sbinkertn@umich.edu Stats::StatEvent(false, true, when, repeat); 204298SN/A } 205298SN/A 206298SN/A void 2072680Sktlim@umich.edu dumpstats(ThreadContext *tc, Tick delay, Tick period) 208298SN/A { 2093617Sbinkertn@umich.edu if (!tc->getCpuPtr()->params->do_statistics_insts) 210299SN/A return; 211299SN/A 212298SN/A 2131609SN/A Tick when = curTick + delay * Clock::Int::ns; 2141609SN/A Tick repeat = period * Clock::Int::ns; 215298SN/A 2164078Sbinkertn@umich.edu Stats::StatEvent(true, false, when, repeat); 217298SN/A } 218298SN/A 219298SN/A void 2202680Sktlim@umich.edu addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr) 2211973SN/A { 2221973SN/A char symb[100]; 2232680Sktlim@umich.edu CopyStringOut(tc, symb, symbolAddr, 100); 2241973SN/A std::string symbol(symb); 2251973SN/A 2261973SN/A DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 2271973SN/A 2282680Sktlim@umich.edu tc->getSystemPtr()->kernelSymtab->insert(addr,symbol); 2291973SN/A } 2301973SN/A 2311973SN/A void 2323089Ssaidi@eecs.umich.edu anBegin(ThreadContext *tc, uint64_t cur) 2333089Ssaidi@eecs.umich.edu { 2343089Ssaidi@eecs.umich.edu Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & 2353089Ssaidi@eecs.umich.edu 0xFFFFFFFF, 0,0); 2363089Ssaidi@eecs.umich.edu } 2373089Ssaidi@eecs.umich.edu 2383089Ssaidi@eecs.umich.edu void 2393089Ssaidi@eecs.umich.edu anWait(ThreadContext *tc, uint64_t cur, uint64_t wait) 2403089Ssaidi@eecs.umich.edu { 2413089Ssaidi@eecs.umich.edu Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & 2423089Ssaidi@eecs.umich.edu 0xFFFFFFFF, wait >> 32, wait & 0xFFFFFFFF); 2433089Ssaidi@eecs.umich.edu } 2443089Ssaidi@eecs.umich.edu 2453089Ssaidi@eecs.umich.edu 2463089Ssaidi@eecs.umich.edu void 2472680Sktlim@umich.edu dumpresetstats(ThreadContext *tc, Tick delay, Tick period) 248298SN/A { 2493617Sbinkertn@umich.edu if (!tc->getCpuPtr()->params->do_statistics_insts) 250299SN/A return; 251299SN/A 252298SN/A 2531609SN/A Tick when = curTick + delay * Clock::Int::ns; 2541609SN/A Tick repeat = period * Clock::Int::ns; 255298SN/A 2564078Sbinkertn@umich.edu Stats::StatEvent(true, true, when, repeat); 257298SN/A } 258298SN/A 259298SN/A void 2602680Sktlim@umich.edu m5checkpoint(ThreadContext *tc, Tick delay, Tick period) 261298SN/A { 2623617Sbinkertn@umich.edu if (!tc->getCpuPtr()->params->do_checkpoint_insts) 263299SN/A return; 2643144Shsul@eecs.umich.edu 2653144Shsul@eecs.umich.edu Tick when = curTick + delay * Clock::Int::ns; 2663144Shsul@eecs.umich.edu Tick repeat = period * Clock::Int::ns; 2673144Shsul@eecs.umich.edu 2683144Shsul@eecs.umich.edu schedExitSimLoop("checkpoint", when, repeat); 269298SN/A } 270298SN/A 2712081SN/A uint64_t 2722680Sktlim@umich.edu readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset) 273954SN/A { 2743617Sbinkertn@umich.edu const string &file = tc->getSystemPtr()->params()->readfile; 275954SN/A if (file.empty()) { 2762081SN/A return ULL(0); 277954SN/A } 278954SN/A 279954SN/A uint64_t result = 0; 280954SN/A 281954SN/A int fd = ::open(file.c_str(), O_RDONLY, 0); 282954SN/A if (fd < 0) 283954SN/A panic("could not open file %s\n", file); 284954SN/A 2851642SN/A if (::lseek(fd, offset, SEEK_SET) < 0) 2861642SN/A panic("could not seek: %s", strerror(errno)); 2871642SN/A 288954SN/A char *buf = new char[len]; 289954SN/A char *p = buf; 290954SN/A while (len > 0) { 2911642SN/A int bytes = ::read(fd, p, len); 292954SN/A if (bytes <= 0) 293954SN/A break; 294954SN/A 295954SN/A p += bytes; 296954SN/A result += bytes; 297954SN/A len -= bytes; 298954SN/A } 299954SN/A 300954SN/A close(fd); 3012680Sktlim@umich.edu CopyIn(tc, vaddr, buf, result); 302954SN/A delete [] buf; 3032081SN/A return result; 304954SN/A } 305954SN/A 3062680Sktlim@umich.edu void debugbreak(ThreadContext *tc) 3071052SN/A { 3081052SN/A debug_break(); 3091052SN/A } 3101052SN/A 3112680Sktlim@umich.edu void switchcpu(ThreadContext *tc) 3121052SN/A { 3132841Sktlim@umich.edu exitSimLoop("switchcpu"); 3141052SN/A } 315298SN/A} 316