pseudo_inst.cc revision 3617
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" 433565Sgblack@eecs.umich.edu#include "sim/pseudo_inst.hh" 44298SN/A#include "sim/serialize.hh" 45298SN/A#include "sim/sim_exit.hh" 46695SN/A#include "sim/stat_control.hh" 47695SN/A#include "sim/stats.hh" 48954SN/A#include "sim/system.hh" 491052SN/A#include "sim/debug.hh" 502080SN/A#include "sim/vptr.hh" 51298SN/A 52299SN/Ausing namespace std; 531052SN/A 54729SN/Ausing namespace Stats; 552107SN/Ausing namespace TheISA; 56298SN/A 57298SN/Anamespace AlphaPseudo 58298SN/A{ 59310SN/A void 602680Sktlim@umich.edu arm(ThreadContext *tc) 61711SN/A { 622680Sktlim@umich.edu if (tc->getKernelStats()) 632680Sktlim@umich.edu tc->getKernelStats()->arm(); 64711SN/A } 65711SN/A 66711SN/A void 672680Sktlim@umich.edu quiesce(ThreadContext *tc) 68310SN/A { 693617Sbinkertn@umich.edu if (!tc->getCpuPtr()->params->do_quiesce) 70310SN/A return; 71310SN/A 723373Sstever@eecs.umich.edu DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name()); 733373Sstever@eecs.umich.edu 742680Sktlim@umich.edu tc->suspend(); 752680Sktlim@umich.edu if (tc->getKernelStats()) 762680Sktlim@umich.edu tc->getKernelStats()->quiesce(); 77310SN/A } 78299SN/A 79298SN/A void 802680Sktlim@umich.edu quiesceNs(ThreadContext *tc, uint64_t ns) 812188SN/A { 823617Sbinkertn@umich.edu if (!tc->getCpuPtr()->params->do_quiesce || ns == 0) 832188SN/A return; 842188SN/A 852680Sktlim@umich.edu EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); 862235SN/A 873368Sstever@eecs.umich.edu Tick resume = curTick + Clock::Int::ns * ns; 883368Sstever@eecs.umich.edu 892235SN/A if (quiesceEvent->scheduled()) 903368Sstever@eecs.umich.edu quiesceEvent->reschedule(resume); 912188SN/A else 923368Sstever@eecs.umich.edu quiesceEvent->schedule(resume); 933368Sstever@eecs.umich.edu 943368Sstever@eecs.umich.edu DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n", 953368Sstever@eecs.umich.edu tc->getCpuPtr()->name(), ns, resume); 962188SN/A 972680Sktlim@umich.edu tc->suspend(); 982680Sktlim@umich.edu if (tc->getKernelStats()) 992680Sktlim@umich.edu tc->getKernelStats()->quiesce(); 1002188SN/A } 1012188SN/A 1022188SN/A void 1032680Sktlim@umich.edu quiesceCycles(ThreadContext *tc, uint64_t cycles) 1042188SN/A { 1053617Sbinkertn@umich.edu if (!tc->getCpuPtr()->params->do_quiesce || cycles == 0) 1062188SN/A return; 1072188SN/A 1082680Sktlim@umich.edu EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); 1092235SN/A 1103368Sstever@eecs.umich.edu Tick resume = curTick + tc->getCpuPtr()->cycles(cycles); 1113368Sstever@eecs.umich.edu 1122235SN/A if (quiesceEvent->scheduled()) 1133368Sstever@eecs.umich.edu quiesceEvent->reschedule(resume); 1142188SN/A else 1153368Sstever@eecs.umich.edu quiesceEvent->schedule(resume); 1163368Sstever@eecs.umich.edu 1173368Sstever@eecs.umich.edu DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n", 1183368Sstever@eecs.umich.edu tc->getCpuPtr()->name(), cycles, resume); 1192188SN/A 1202680Sktlim@umich.edu tc->suspend(); 1212680Sktlim@umich.edu if (tc->getKernelStats()) 1222680Sktlim@umich.edu tc->getKernelStats()->quiesce(); 1232188SN/A } 1242188SN/A 1252188SN/A uint64_t 1262680Sktlim@umich.edu quiesceTime(ThreadContext *tc) 1272188SN/A { 1282680Sktlim@umich.edu return (tc->readLastActivate() - tc->readLastSuspend()) / Clock::Int::ns; 1292188SN/A } 1302188SN/A 1312188SN/A void 1322680Sktlim@umich.edu m5exit_old(ThreadContext *tc) 133298SN/A { 1343144Shsul@eecs.umich.edu exitSimLoop("m5_exit_old instruction encountered"); 135298SN/A } 136298SN/A 137298SN/A void 1382680Sktlim@umich.edu m5exit(ThreadContext *tc, Tick delay) 139298SN/A { 1401609SN/A Tick when = curTick + delay * Clock::Int::ns; 1413144Shsul@eecs.umich.edu schedExitSimLoop("m5_exit instruction encountered", when); 142298SN/A } 143298SN/A 144298SN/A void 1453126Sktlim@umich.edu loadsymbol(ThreadContext *tc) 1462358SN/A { 1473126Sktlim@umich.edu const string &filename = tc->getCpuPtr()->system->params()->symbolfile; 1482358SN/A if (filename.empty()) { 1492358SN/A return; 1502358SN/A } 1512358SN/A 1522358SN/A std::string buffer; 1532358SN/A ifstream file(filename.c_str()); 1542358SN/A 1552358SN/A if (!file) 1562358SN/A fatal("file error: Can't open symbol table file %s\n", filename); 1572358SN/A 1582358SN/A while (!file.eof()) { 1592358SN/A getline(file, buffer); 1602358SN/A 1612358SN/A if (buffer.empty()) 1622358SN/A continue; 1632358SN/A 1642358SN/A int idx = buffer.find(' '); 1652358SN/A if (idx == string::npos) 1662358SN/A continue; 1672358SN/A 1682358SN/A string address = "0x" + buffer.substr(0, idx); 1692358SN/A eat_white(address); 1702358SN/A if (address.empty()) 1712358SN/A continue; 1722358SN/A 1732358SN/A // Skip over letter and space 1742358SN/A string symbol = buffer.substr(idx + 3); 1752358SN/A eat_white(symbol); 1762358SN/A if (symbol.empty()) 1772358SN/A continue; 1782358SN/A 1792358SN/A Addr addr; 1802358SN/A if (!to_number(address, addr)) 1812358SN/A continue; 1822358SN/A 1833126Sktlim@umich.edu if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol)) 1842358SN/A continue; 1852358SN/A 1862358SN/A 1872358SN/A DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 1882358SN/A } 1892358SN/A file.close(); 1902358SN/A } 1912358SN/A 1922358SN/A void 1932680Sktlim@umich.edu resetstats(ThreadContext *tc, Tick delay, Tick period) 194298SN/A { 1953617Sbinkertn@umich.edu if (!tc->getCpuPtr()->params->do_statistics_insts) 196299SN/A return; 197299SN/A 198298SN/A 1991609SN/A Tick when = curTick + delay * Clock::Int::ns; 2001609SN/A Tick repeat = period * Clock::Int::ns; 201298SN/A 202729SN/A using namespace Stats; 203298SN/A SetupEvent(Reset, 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 216729SN/A using namespace Stats; 217298SN/A SetupEvent(Dump, when, repeat); 218298SN/A } 219298SN/A 220298SN/A void 2212680Sktlim@umich.edu addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr) 2221973SN/A { 2231973SN/A char symb[100]; 2242680Sktlim@umich.edu CopyStringOut(tc, symb, symbolAddr, 100); 2251973SN/A std::string symbol(symb); 2261973SN/A 2271973SN/A DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 2281973SN/A 2292680Sktlim@umich.edu tc->getSystemPtr()->kernelSymtab->insert(addr,symbol); 2301973SN/A } 2311973SN/A 2321973SN/A void 2333089Ssaidi@eecs.umich.edu anBegin(ThreadContext *tc, uint64_t cur) 2343089Ssaidi@eecs.umich.edu { 2353089Ssaidi@eecs.umich.edu Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & 2363089Ssaidi@eecs.umich.edu 0xFFFFFFFF, 0,0); 2373089Ssaidi@eecs.umich.edu } 2383089Ssaidi@eecs.umich.edu 2393089Ssaidi@eecs.umich.edu void 2403089Ssaidi@eecs.umich.edu anWait(ThreadContext *tc, uint64_t cur, uint64_t wait) 2413089Ssaidi@eecs.umich.edu { 2423089Ssaidi@eecs.umich.edu Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & 2433089Ssaidi@eecs.umich.edu 0xFFFFFFFF, wait >> 32, wait & 0xFFFFFFFF); 2443089Ssaidi@eecs.umich.edu } 2453089Ssaidi@eecs.umich.edu 2463089Ssaidi@eecs.umich.edu 2473089Ssaidi@eecs.umich.edu void 2482680Sktlim@umich.edu dumpresetstats(ThreadContext *tc, Tick delay, Tick period) 249298SN/A { 2503617Sbinkertn@umich.edu if (!tc->getCpuPtr()->params->do_statistics_insts) 251299SN/A return; 252299SN/A 253298SN/A 2541609SN/A Tick when = curTick + delay * Clock::Int::ns; 2551609SN/A Tick repeat = period * Clock::Int::ns; 256298SN/A 257729SN/A using namespace Stats; 258298SN/A SetupEvent(Dump|Reset, when, repeat); 259298SN/A } 260298SN/A 261298SN/A void 2622680Sktlim@umich.edu m5checkpoint(ThreadContext *tc, Tick delay, Tick period) 263298SN/A { 2643617Sbinkertn@umich.edu if (!tc->getCpuPtr()->params->do_checkpoint_insts) 265299SN/A return; 2663144Shsul@eecs.umich.edu 2673144Shsul@eecs.umich.edu Tick when = curTick + delay * Clock::Int::ns; 2683144Shsul@eecs.umich.edu Tick repeat = period * Clock::Int::ns; 2693144Shsul@eecs.umich.edu 2703144Shsul@eecs.umich.edu schedExitSimLoop("checkpoint", when, repeat); 271298SN/A } 272298SN/A 2732081SN/A uint64_t 2742680Sktlim@umich.edu readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset) 275954SN/A { 2763617Sbinkertn@umich.edu const string &file = tc->getSystemPtr()->params()->readfile; 277954SN/A if (file.empty()) { 2782081SN/A return ULL(0); 279954SN/A } 280954SN/A 281954SN/A uint64_t result = 0; 282954SN/A 283954SN/A int fd = ::open(file.c_str(), O_RDONLY, 0); 284954SN/A if (fd < 0) 285954SN/A panic("could not open file %s\n", file); 286954SN/A 2871642SN/A if (::lseek(fd, offset, SEEK_SET) < 0) 2881642SN/A panic("could not seek: %s", strerror(errno)); 2891642SN/A 290954SN/A char *buf = new char[len]; 291954SN/A char *p = buf; 292954SN/A while (len > 0) { 2931642SN/A int bytes = ::read(fd, p, len); 294954SN/A if (bytes <= 0) 295954SN/A break; 296954SN/A 297954SN/A p += bytes; 298954SN/A result += bytes; 299954SN/A len -= bytes; 300954SN/A } 301954SN/A 302954SN/A close(fd); 3032680Sktlim@umich.edu CopyIn(tc, vaddr, buf, result); 304954SN/A delete [] buf; 3052081SN/A return result; 306954SN/A } 307954SN/A 3082680Sktlim@umich.edu void debugbreak(ThreadContext *tc) 3091052SN/A { 3101052SN/A debug_break(); 3111052SN/A } 3121052SN/A 3132680Sktlim@umich.edu void switchcpu(ThreadContext *tc) 3141052SN/A { 3152841Sktlim@umich.edu exitSimLoop("switchcpu"); 3161052SN/A } 317298SN/A} 318