pseudo_inst.cc revision 5504
11060SN/A/* 29814Sandreas.hansson@arm.com * Copyright (c) 2003-2006 The Regents of The University of Michigan 39920Syasuko.eckert@amd.com * All rights reserved. 47944SGiacomo.Gabrielli@arm.com * 57944SGiacomo.Gabrielli@arm.com * Redistribution and use in source and binary forms, with or without 67944SGiacomo.Gabrielli@arm.com * modification, are permitted provided that the following conditions are 77944SGiacomo.Gabrielli@arm.com * met: redistributions of source code must retain the above copyright 87944SGiacomo.Gabrielli@arm.com * notice, this list of conditions and the following disclaimer; 97944SGiacomo.Gabrielli@arm.com * redistributions in binary form must reproduce the above copyright 107944SGiacomo.Gabrielli@arm.com * notice, this list of conditions and the following disclaimer in the 117944SGiacomo.Gabrielli@arm.com * documentation and/or other materials provided with the distribution; 127944SGiacomo.Gabrielli@arm.com * neither the name of the copyright holders nor the names of its 137944SGiacomo.Gabrielli@arm.com * contributors may be used to endorse or promote products derived from 147944SGiacomo.Gabrielli@arm.com * this software without specific prior written permission. 152702Sktlim@umich.edu * 166973Stjones1@inf.ed.ac.uk * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171060SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181060SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191060SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201060SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211060SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221060SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231060SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241060SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251060SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261060SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271060SN/A * 281060SN/A * Authors: Nathan Binkert 291060SN/A */ 301060SN/A 311060SN/A#include <errno.h> 321060SN/A#include <fcntl.h> 331060SN/A#include <unistd.h> 341060SN/A 351060SN/A#include <fstream> 361060SN/A#include <string> 371060SN/A 381060SN/A#include "arch/vtophys.hh" 391060SN/A#include "base/annotate.hh" 401060SN/A#include "cpu/base.hh" 412665Ssaidi@eecs.umich.edu#include "cpu/thread_context.hh" 422665Ssaidi@eecs.umich.edu#include "cpu/quiesce_event.hh" 436973Stjones1@inf.ed.ac.uk#include "arch/kernel_stats.hh" 441060SN/A#include "sim/pseudo_inst.hh" 451060SN/A#include "sim/serialize.hh" 461464SN/A#include "sim/sim_exit.hh" 471464SN/A#include "sim/stat_control.hh" 481060SN/A#include "sim/stats.hh" 492731Sktlim@umich.edu#include "sim/system.hh" 502292SN/A#include "sim/debug.hh" 511464SN/A#include "sim/vptr.hh" 528733Sgeoffrey.blake@arm.com 531060SN/Ausing namespace std; 5410687SAndreas.Sandberg@ARM.com 557720Sgblack@eecs.umich.eduusing namespace Stats; 561060SN/Ausing namespace TheISA; 576658Snate@binkert.org 588887Sgeoffrey.blake@arm.comnamespace PseudoInst { 593770Sgblack@eecs.umich.edu 6010319SAndreas.Sandberg@ARM.comvoid 611464SN/Aarm(ThreadContext *tc) 621464SN/A{ 632669Sktlim@umich.edu if (tc->getKernelStats()) 641060SN/A tc->getKernelStats()->arm(); 656973Stjones1@inf.ed.ac.uk} 662669Sktlim@umich.edu 677678Sgblack@eecs.umich.eduvoid 682292SN/Aquiesce(ThreadContext *tc) 691060SN/A{ 701060SN/A if (!tc->getCpuPtr()->params->do_quiesce) 711060SN/A return; 721060SN/A 731060SN/A DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name()); 741060SN/A 751060SN/A tc->suspend(); 7610319SAndreas.Sandberg@ARM.com if (tc->getKernelStats()) 771060SN/A tc->getKernelStats()->quiesce(); 781060SN/A} 791060SN/A 802733Sktlim@umich.eduvoid 812733Sktlim@umich.eduquiesceNs(ThreadContext *tc, uint64_t ns) 821060SN/A{ 832292SN/A if (!tc->getCpuPtr()->params->do_quiesce || ns == 0) 842107SN/A return; 851060SN/A 862292SN/A EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); 872292SN/A 888486Sgblack@eecs.umich.edu Tick resume = curTick + Clock::Int::ns * ns; 892292SN/A 902292SN/A quiesceEvent->reschedule(resume, true); 912292SN/A 922292SN/A DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n", 931060SN/A tc->getCpuPtr()->name(), ns, resume); 945543Ssaidi@eecs.umich.edu 958902Sandreas.hansson@arm.com tc->suspend(); 961060SN/A if (tc->getKernelStats()) 971060SN/A tc->getKernelStats()->quiesce(); 989046SAli.Saidi@ARM.com} 999046SAli.Saidi@ARM.com 1009046SAli.Saidi@ARM.comvoid 1019046SAli.Saidi@ARM.comquiesceCycles(ThreadContext *tc, uint64_t cycles) 1029046SAli.Saidi@ARM.com{ 1039046SAli.Saidi@ARM.com if (!tc->getCpuPtr()->params->do_quiesce || cycles == 0) 1049046SAli.Saidi@ARM.com return; 1059046SAli.Saidi@ARM.com 1069046SAli.Saidi@ARM.com EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); 1079046SAli.Saidi@ARM.com 1089046SAli.Saidi@ARM.com Tick resume = curTick + tc->getCpuPtr()->ticks(cycles); 1099046SAli.Saidi@ARM.com 1109046SAli.Saidi@ARM.com quiesceEvent->reschedule(resume, true); 1119046SAli.Saidi@ARM.com 1129046SAli.Saidi@ARM.com DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n", 1139046SAli.Saidi@ARM.com tc->getCpuPtr()->name(), cycles, resume); 1149046SAli.Saidi@ARM.com 1159046SAli.Saidi@ARM.com tc->suspend(); 1169046SAli.Saidi@ARM.com if (tc->getKernelStats()) 1179046SAli.Saidi@ARM.com tc->getKernelStats()->quiesce(); 1189046SAli.Saidi@ARM.com} 1199046SAli.Saidi@ARM.com 1209046SAli.Saidi@ARM.comuint64_t 1219046SAli.Saidi@ARM.comquiesceTime(ThreadContext *tc) 1229046SAli.Saidi@ARM.com{ 1239046SAli.Saidi@ARM.com return (tc->readLastActivate() - tc->readLastSuspend()) / Clock::Int::ns; 1249046SAli.Saidi@ARM.com} 1259046SAli.Saidi@ARM.com 1269046SAli.Saidi@ARM.comvoid 1279046SAli.Saidi@ARM.comm5exit_old(ThreadContext *tc) 1289046SAli.Saidi@ARM.com{ 1299046SAli.Saidi@ARM.com exitSimLoop("m5_exit_old instruction encountered"); 1309046SAli.Saidi@ARM.com} 1319046SAli.Saidi@ARM.com 1329046SAli.Saidi@ARM.comvoid 1339046SAli.Saidi@ARM.comm5exit(ThreadContext *tc, Tick delay) 1349046SAli.Saidi@ARM.com{ 1359046SAli.Saidi@ARM.com Tick when = curTick + delay * Clock::Int::ns; 1369046SAli.Saidi@ARM.com schedExitSimLoop("m5_exit instruction encountered", when); 1379046SAli.Saidi@ARM.com} 1389046SAli.Saidi@ARM.com 1399046SAli.Saidi@ARM.comvoid 1409046SAli.Saidi@ARM.comloadsymbol(ThreadContext *tc) 1419046SAli.Saidi@ARM.com{ 1429046SAli.Saidi@ARM.com const string &filename = tc->getCpuPtr()->system->params()->symbolfile; 1439046SAli.Saidi@ARM.com if (filename.empty()) { 1449046SAli.Saidi@ARM.com return; 1459046SAli.Saidi@ARM.com } 1469046SAli.Saidi@ARM.com 1479046SAli.Saidi@ARM.com std::string buffer; 1489046SAli.Saidi@ARM.com ifstream file(filename.c_str()); 1499046SAli.Saidi@ARM.com 1509046SAli.Saidi@ARM.com if (!file) 1519046SAli.Saidi@ARM.com fatal("file error: Can't open symbol table file %s\n", filename); 1529046SAli.Saidi@ARM.com 1539046SAli.Saidi@ARM.com while (!file.eof()) { 1549046SAli.Saidi@ARM.com getline(file, buffer); 1559046SAli.Saidi@ARM.com 1569046SAli.Saidi@ARM.com if (buffer.empty()) 1572292SN/A continue; 15810417Sandreas.hansson@arm.com 1599046SAli.Saidi@ARM.com int idx = buffer.find(' '); 1609046SAli.Saidi@ARM.com if (idx == string::npos) 1619046SAli.Saidi@ARM.com continue; 1629046SAli.Saidi@ARM.com 16310030SAli.Saidi@ARM.com string address = "0x" + buffer.substr(0, idx); 16410030SAli.Saidi@ARM.com eat_white(address); 1659046SAli.Saidi@ARM.com if (address.empty()) 1669046SAli.Saidi@ARM.com continue; 1679046SAli.Saidi@ARM.com 1689046SAli.Saidi@ARM.com // Skip over letter and space 1699046SAli.Saidi@ARM.com string symbol = buffer.substr(idx + 3); 1709046SAli.Saidi@ARM.com eat_white(symbol); 1719046SAli.Saidi@ARM.com if (symbol.empty()) 1729046SAli.Saidi@ARM.com continue; 1739046SAli.Saidi@ARM.com 1749046SAli.Saidi@ARM.com Addr addr; 1759046SAli.Saidi@ARM.com if (!to_number(address, addr)) 1769046SAli.Saidi@ARM.com continue; 1779046SAli.Saidi@ARM.com 1789046SAli.Saidi@ARM.com if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol)) 1799046SAli.Saidi@ARM.com continue; 1809046SAli.Saidi@ARM.com 1819046SAli.Saidi@ARM.com 1829046SAli.Saidi@ARM.com DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 1839046SAli.Saidi@ARM.com } 1849046SAli.Saidi@ARM.com file.close(); 1859046SAli.Saidi@ARM.com} 1869046SAli.Saidi@ARM.com 1879046SAli.Saidi@ARM.comvoid 1889046SAli.Saidi@ARM.comresetstats(ThreadContext *tc, Tick delay, Tick period) 1899046SAli.Saidi@ARM.com{ 1909046SAli.Saidi@ARM.com if (!tc->getCpuPtr()->params->do_statistics_insts) 1919046SAli.Saidi@ARM.com return; 1929046SAli.Saidi@ARM.com 1939046SAli.Saidi@ARM.com 1949046SAli.Saidi@ARM.com Tick when = curTick + delay * Clock::Int::ns; 1959046SAli.Saidi@ARM.com Tick repeat = period * Clock::Int::ns; 1969046SAli.Saidi@ARM.com 1979046SAli.Saidi@ARM.com Stats::StatEvent(false, true, when, repeat); 1989046SAli.Saidi@ARM.com} 1999046SAli.Saidi@ARM.com 2009046SAli.Saidi@ARM.comvoid 2019046SAli.Saidi@ARM.comdumpstats(ThreadContext *tc, Tick delay, Tick period) 2029046SAli.Saidi@ARM.com{ 2039046SAli.Saidi@ARM.com if (!tc->getCpuPtr()->params->do_statistics_insts) 2049046SAli.Saidi@ARM.com return; 2059046SAli.Saidi@ARM.com 20610417Sandreas.hansson@arm.com 2071060SN/A Tick when = curTick + delay * Clock::Int::ns; 2089046SAli.Saidi@ARM.com Tick repeat = period * Clock::Int::ns; 2099046SAli.Saidi@ARM.com 2109046SAli.Saidi@ARM.com Stats::StatEvent(true, false, when, repeat); 2119046SAli.Saidi@ARM.com} 2129046SAli.Saidi@ARM.com 2139046SAli.Saidi@ARM.comvoid 2149046SAli.Saidi@ARM.comaddsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr) 2159046SAli.Saidi@ARM.com{ 2169046SAli.Saidi@ARM.com char symb[100]; 2179046SAli.Saidi@ARM.com CopyStringOut(tc, symb, symbolAddr, 100); 2189046SAli.Saidi@ARM.com std::string symbol(symb); 2199046SAli.Saidi@ARM.com 2209046SAli.Saidi@ARM.com DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 2219046SAli.Saidi@ARM.com 2229046SAli.Saidi@ARM.com tc->getSystemPtr()->kernelSymtab->insert(addr,symbol); 2239046SAli.Saidi@ARM.com} 2249046SAli.Saidi@ARM.com 2259046SAli.Saidi@ARM.comvoid 2269046SAli.Saidi@ARM.comanBegin(ThreadContext *tc, uint64_t cur) 2279046SAli.Saidi@ARM.com{ 2289046SAli.Saidi@ARM.com Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & 2299046SAli.Saidi@ARM.com 0xFFFFFFFF, 0,0); 2309046SAli.Saidi@ARM.com} 2319046SAli.Saidi@ARM.com 2329046SAli.Saidi@ARM.comvoid 2339046SAli.Saidi@ARM.comanWait(ThreadContext *tc, uint64_t cur, uint64_t wait) 2349046SAli.Saidi@ARM.com{ 2359046SAli.Saidi@ARM.com Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & 2369046SAli.Saidi@ARM.com 0xFFFFFFFF, wait >> 32, wait & 0xFFFFFFFF); 2379046SAli.Saidi@ARM.com} 2389046SAli.Saidi@ARM.com 2399046SAli.Saidi@ARM.com 2409046SAli.Saidi@ARM.comvoid 2419046SAli.Saidi@ARM.comdumpresetstats(ThreadContext *tc, Tick delay, Tick period) 2429046SAli.Saidi@ARM.com{ 2439046SAli.Saidi@ARM.com if (!tc->getCpuPtr()->params->do_statistics_insts) 2449046SAli.Saidi@ARM.com return; 2459046SAli.Saidi@ARM.com 2469046SAli.Saidi@ARM.com 2479046SAli.Saidi@ARM.com Tick when = curTick + delay * Clock::Int::ns; 2489046SAli.Saidi@ARM.com Tick repeat = period * Clock::Int::ns; 2499046SAli.Saidi@ARM.com 2509046SAli.Saidi@ARM.com Stats::StatEvent(true, true, when, repeat); 2519046SAli.Saidi@ARM.com} 2529046SAli.Saidi@ARM.com 2539046SAli.Saidi@ARM.comvoid 2549046SAli.Saidi@ARM.comm5checkpoint(ThreadContext *tc, Tick delay, Tick period) 2559046SAli.Saidi@ARM.com{ 2569046SAli.Saidi@ARM.com if (!tc->getCpuPtr()->params->do_checkpoint_insts) 2579046SAli.Saidi@ARM.com return; 2589046SAli.Saidi@ARM.com 2599046SAli.Saidi@ARM.com Tick when = curTick + delay * Clock::Int::ns; 2609046SAli.Saidi@ARM.com Tick repeat = period * Clock::Int::ns; 2619046SAli.Saidi@ARM.com 2629046SAli.Saidi@ARM.com schedExitSimLoop("checkpoint", when, repeat); 2639046SAli.Saidi@ARM.com} 2649046SAli.Saidi@ARM.com 2659046SAli.Saidi@ARM.comuint64_t 2669046SAli.Saidi@ARM.comreadfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset) 2679046SAli.Saidi@ARM.com{ 2689046SAli.Saidi@ARM.com const string &file = tc->getSystemPtr()->params()->readfile; 2699046SAli.Saidi@ARM.com if (file.empty()) { 2709046SAli.Saidi@ARM.com return ULL(0); 2719046SAli.Saidi@ARM.com } 2729046SAli.Saidi@ARM.com 2739046SAli.Saidi@ARM.com uint64_t result = 0; 2749046SAli.Saidi@ARM.com 2759046SAli.Saidi@ARM.com int fd = ::open(file.c_str(), O_RDONLY, 0); 2769046SAli.Saidi@ARM.com if (fd < 0) 2779046SAli.Saidi@ARM.com panic("could not open file %s\n", file); 2789046SAli.Saidi@ARM.com 2799046SAli.Saidi@ARM.com if (::lseek(fd, offset, SEEK_SET) < 0) 2809046SAli.Saidi@ARM.com panic("could not seek: %s", strerror(errno)); 2819046SAli.Saidi@ARM.com 2829046SAli.Saidi@ARM.com char *buf = new char[len]; 2839046SAli.Saidi@ARM.com char *p = buf; 2849046SAli.Saidi@ARM.com while (len > 0) { 2859046SAli.Saidi@ARM.com int bytes = ::read(fd, p, len); 2869046SAli.Saidi@ARM.com if (bytes <= 0) 2879046SAli.Saidi@ARM.com break; 2889046SAli.Saidi@ARM.com 2899046SAli.Saidi@ARM.com p += bytes; 2909046SAli.Saidi@ARM.com result += bytes; 2911060SN/A len -= bytes; 2921060SN/A } 2931060SN/A 2941060SN/A close(fd); 2951060SN/A CopyIn(tc, vaddr, buf, result); 2961060SN/A delete [] buf; 2975358Sgblack@eecs.umich.edu return result; 2985358Sgblack@eecs.umich.edu} 2995358Sgblack@eecs.umich.edu 3005358Sgblack@eecs.umich.eduvoid 3015358Sgblack@eecs.umich.edudebugbreak(ThreadContext *tc) 3025358Sgblack@eecs.umich.edu{ 3035358Sgblack@eecs.umich.edu debug_break(); 3045358Sgblack@eecs.umich.edu} 3055358Sgblack@eecs.umich.edu 3065358Sgblack@eecs.umich.eduvoid 3075358Sgblack@eecs.umich.eduswitchcpu(ThreadContext *tc) 3085358Sgblack@eecs.umich.edu{ 3095358Sgblack@eecs.umich.edu exitSimLoop("switchcpu"); 3108444Sgblack@eecs.umich.edu} 3117520Sgblack@eecs.umich.edu 3128444Sgblack@eecs.umich.edu/* namespace PseudoInst */ } 3138444Sgblack@eecs.umich.edu