pseudo_inst.cc revision 4437:b6e304245729
110802Srene.dejong@arm.com/* 210802Srene.dejong@arm.com * Copyright (c) 2003-2006 The Regents of The University of Michigan 310802Srene.dejong@arm.com * All rights reserved. 410802Srene.dejong@arm.com * 510802Srene.dejong@arm.com * Redistribution and use in source and binary forms, with or without 610802Srene.dejong@arm.com * modification, are permitted provided that the following conditions are 710802Srene.dejong@arm.com * met: redistributions of source code must retain the above copyright 810802Srene.dejong@arm.com * notice, this list of conditions and the following disclaimer; 910802Srene.dejong@arm.com * redistributions in binary form must reproduce the above copyright 1010802Srene.dejong@arm.com * notice, this list of conditions and the following disclaimer in the 1110802Srene.dejong@arm.com * documentation and/or other materials provided with the distribution; 1210802Srene.dejong@arm.com * neither the name of the copyright holders nor the names of its 1310802Srene.dejong@arm.com * contributors may be used to endorse or promote products derived from 1410802Srene.dejong@arm.com * this software without specific prior written permission. 1510802Srene.dejong@arm.com * 1610802Srene.dejong@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1710802Srene.dejong@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1810802Srene.dejong@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1910802Srene.dejong@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2010802Srene.dejong@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2110802Srene.dejong@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2210802Srene.dejong@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2310802Srene.dejong@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2410802Srene.dejong@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2510802Srene.dejong@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2610802Srene.dejong@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2710802Srene.dejong@arm.com * 2810802Srene.dejong@arm.com * Authors: Nathan Binkert 2910802Srene.dejong@arm.com */ 3010802Srene.dejong@arm.com 3110802Srene.dejong@arm.com#include <errno.h> 3210802Srene.dejong@arm.com#include <fcntl.h> 3310802Srene.dejong@arm.com#include <unistd.h> 3410802Srene.dejong@arm.com 3510802Srene.dejong@arm.com#include <fstream> 3610802Srene.dejong@arm.com#include <string> 3710802Srene.dejong@arm.com 3810802Srene.dejong@arm.com#include "arch/vtophys.hh" 3910802Srene.dejong@arm.com#include "base/annotate.hh" 4010802Srene.dejong@arm.com#include "cpu/base.hh" 4110802Srene.dejong@arm.com#include "cpu/thread_context.hh" 4210802Srene.dejong@arm.com#include "cpu/quiesce_event.hh" 4310802Srene.dejong@arm.com#include "arch/kernel_stats.hh" 4410802Srene.dejong@arm.com#include "sim/pseudo_inst.hh" 4510802Srene.dejong@arm.com#include "sim/serialize.hh" 4610802Srene.dejong@arm.com#include "sim/sim_exit.hh" 4710802Srene.dejong@arm.com#include "sim/stat_control.hh" 4810802Srene.dejong@arm.com#include "sim/stats.hh" 4910802Srene.dejong@arm.com#include "sim/system.hh" 5010802Srene.dejong@arm.com#include "sim/debug.hh" 5110802Srene.dejong@arm.com#include "sim/vptr.hh" 5210802Srene.dejong@arm.com 5310802Srene.dejong@arm.comusing namespace std; 5410802Srene.dejong@arm.com 5510802Srene.dejong@arm.comusing namespace Stats; 5610802Srene.dejong@arm.comusing namespace TheISA; 5710802Srene.dejong@arm.com 5810802Srene.dejong@arm.comnamespace PseudoInst 5910802Srene.dejong@arm.com{ 6010802Srene.dejong@arm.com void 6110802Srene.dejong@arm.com arm(ThreadContext *tc) 6210802Srene.dejong@arm.com { 6310802Srene.dejong@arm.com if (tc->getKernelStats()) 6410802Srene.dejong@arm.com tc->getKernelStats()->arm(); 6510802Srene.dejong@arm.com } 6610802Srene.dejong@arm.com 6710802Srene.dejong@arm.com void 6810802Srene.dejong@arm.com quiesce(ThreadContext *tc) 6910802Srene.dejong@arm.com { 7010802Srene.dejong@arm.com if (!tc->getCpuPtr()->params->do_quiesce) 7110802Srene.dejong@arm.com return; 7210802Srene.dejong@arm.com 7310802Srene.dejong@arm.com DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name()); 7410802Srene.dejong@arm.com 7510802Srene.dejong@arm.com tc->suspend(); 7610802Srene.dejong@arm.com if (tc->getKernelStats()) 7710802Srene.dejong@arm.com tc->getKernelStats()->quiesce(); 7810802Srene.dejong@arm.com } 7910802Srene.dejong@arm.com 8010802Srene.dejong@arm.com void 8110802Srene.dejong@arm.com quiesceNs(ThreadContext *tc, uint64_t ns) 8210802Srene.dejong@arm.com { 8310802Srene.dejong@arm.com if (!tc->getCpuPtr()->params->do_quiesce || ns == 0) 8410802Srene.dejong@arm.com return; 8510802Srene.dejong@arm.com 8610802Srene.dejong@arm.com EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); 8710802Srene.dejong@arm.com 8810802Srene.dejong@arm.com Tick resume = curTick + Clock::Int::ns * ns; 8910802Srene.dejong@arm.com 9010802Srene.dejong@arm.com quiesceEvent->reschedule(resume, true); 9110802Srene.dejong@arm.com 9210802Srene.dejong@arm.com DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n", 9310802Srene.dejong@arm.com tc->getCpuPtr()->name(), ns, resume); 9410802Srene.dejong@arm.com 9510802Srene.dejong@arm.com tc->suspend(); 9610802Srene.dejong@arm.com if (tc->getKernelStats()) 9710802Srene.dejong@arm.com tc->getKernelStats()->quiesce(); 9810802Srene.dejong@arm.com } 9910802Srene.dejong@arm.com 10010802Srene.dejong@arm.com void 10110802Srene.dejong@arm.com quiesceCycles(ThreadContext *tc, uint64_t cycles) 10210802Srene.dejong@arm.com { 10310802Srene.dejong@arm.com if (!tc->getCpuPtr()->params->do_quiesce || cycles == 0) 10410802Srene.dejong@arm.com return; 10510802Srene.dejong@arm.com 10610802Srene.dejong@arm.com EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); 10710802Srene.dejong@arm.com 10810802Srene.dejong@arm.com Tick resume = curTick + tc->getCpuPtr()->cycles(cycles); 10910802Srene.dejong@arm.com 11010802Srene.dejong@arm.com quiesceEvent->reschedule(resume, true); 11110802Srene.dejong@arm.com 11210802Srene.dejong@arm.com DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n", 11310802Srene.dejong@arm.com tc->getCpuPtr()->name(), cycles, resume); 11410802Srene.dejong@arm.com 11510802Srene.dejong@arm.com tc->suspend(); 11610802Srene.dejong@arm.com if (tc->getKernelStats()) 11710802Srene.dejong@arm.com tc->getKernelStats()->quiesce(); 11810802Srene.dejong@arm.com } 11910802Srene.dejong@arm.com 12010802Srene.dejong@arm.com uint64_t 12110802Srene.dejong@arm.com quiesceTime(ThreadContext *tc) 12210802Srene.dejong@arm.com { 12310802Srene.dejong@arm.com return (tc->readLastActivate() - tc->readLastSuspend()) / Clock::Int::ns; 12410802Srene.dejong@arm.com } 12510802Srene.dejong@arm.com 12610802Srene.dejong@arm.com void 12710802Srene.dejong@arm.com m5exit_old(ThreadContext *tc) 12810802Srene.dejong@arm.com { 12910802Srene.dejong@arm.com exitSimLoop("m5_exit_old instruction encountered"); 13010802Srene.dejong@arm.com } 13110802Srene.dejong@arm.com 13210802Srene.dejong@arm.com void 13310802Srene.dejong@arm.com m5exit(ThreadContext *tc, Tick delay) 13410802Srene.dejong@arm.com { 13510802Srene.dejong@arm.com Tick when = curTick + delay * Clock::Int::ns; 13610802Srene.dejong@arm.com schedExitSimLoop("m5_exit instruction encountered", when); 13710802Srene.dejong@arm.com } 13810802Srene.dejong@arm.com 13910802Srene.dejong@arm.com void 14010802Srene.dejong@arm.com loadsymbol(ThreadContext *tc) 14110802Srene.dejong@arm.com { 14210802Srene.dejong@arm.com const string &filename = tc->getCpuPtr()->system->params()->symbolfile; 14310802Srene.dejong@arm.com if (filename.empty()) { 14410802Srene.dejong@arm.com return; 14510802Srene.dejong@arm.com } 14610802Srene.dejong@arm.com 14710802Srene.dejong@arm.com std::string buffer; 14810802Srene.dejong@arm.com ifstream file(filename.c_str()); 14910802Srene.dejong@arm.com 15010802Srene.dejong@arm.com if (!file) 15110802Srene.dejong@arm.com fatal("file error: Can't open symbol table file %s\n", filename); 15210802Srene.dejong@arm.com 15310802Srene.dejong@arm.com while (!file.eof()) { 15410802Srene.dejong@arm.com getline(file, buffer); 15511264Sandreas.sandberg@arm.com 15610802Srene.dejong@arm.com if (buffer.empty()) 15710802Srene.dejong@arm.com continue; 15810802Srene.dejong@arm.com 15910802Srene.dejong@arm.com int idx = buffer.find(' '); 16010802Srene.dejong@arm.com if (idx == string::npos) 16110802Srene.dejong@arm.com continue; 16210802Srene.dejong@arm.com 16310802Srene.dejong@arm.com string address = "0x" + buffer.substr(0, idx); 16410802Srene.dejong@arm.com eat_white(address); 16510802Srene.dejong@arm.com if (address.empty()) 16610802Srene.dejong@arm.com continue; 16710802Srene.dejong@arm.com 16810802Srene.dejong@arm.com // Skip over letter and space 16910802Srene.dejong@arm.com string symbol = buffer.substr(idx + 3); 17010802Srene.dejong@arm.com eat_white(symbol); 17110802Srene.dejong@arm.com if (symbol.empty()) 17210802Srene.dejong@arm.com continue; 17310802Srene.dejong@arm.com 17410802Srene.dejong@arm.com Addr addr; 17510802Srene.dejong@arm.com if (!to_number(address, addr)) 17611168Sandreas.hansson@arm.com continue; 17710802Srene.dejong@arm.com 17811168Sandreas.hansson@arm.com if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol)) 17911168Sandreas.hansson@arm.com continue; 18010802Srene.dejong@arm.com 18110802Srene.dejong@arm.com 18210802Srene.dejong@arm.com DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 18310802Srene.dejong@arm.com } 18410802Srene.dejong@arm.com file.close(); 18510802Srene.dejong@arm.com } 18610802Srene.dejong@arm.com 18710802Srene.dejong@arm.com void 18810802Srene.dejong@arm.com resetstats(ThreadContext *tc, Tick delay, Tick period) 18910802Srene.dejong@arm.com { 19010802Srene.dejong@arm.com if (!tc->getCpuPtr()->params->do_statistics_insts) 19110802Srene.dejong@arm.com return; 19210802Srene.dejong@arm.com 19310802Srene.dejong@arm.com 19410802Srene.dejong@arm.com Tick when = curTick + delay * Clock::Int::ns; 19510802Srene.dejong@arm.com Tick repeat = period * Clock::Int::ns; 19610802Srene.dejong@arm.com 19710802Srene.dejong@arm.com Stats::StatEvent(false, true, when, repeat); 19810802Srene.dejong@arm.com } 19910802Srene.dejong@arm.com 20010802Srene.dejong@arm.com void 20110802Srene.dejong@arm.com dumpstats(ThreadContext *tc, Tick delay, Tick period) 20210802Srene.dejong@arm.com { 20310802Srene.dejong@arm.com if (!tc->getCpuPtr()->params->do_statistics_insts) 20410802Srene.dejong@arm.com return; 20510802Srene.dejong@arm.com 20610802Srene.dejong@arm.com 20710802Srene.dejong@arm.com Tick when = curTick + delay * Clock::Int::ns; 20810802Srene.dejong@arm.com Tick repeat = period * Clock::Int::ns; 20910802Srene.dejong@arm.com 21010802Srene.dejong@arm.com Stats::StatEvent(true, false, when, repeat); 21110802Srene.dejong@arm.com } 21210802Srene.dejong@arm.com 21310802Srene.dejong@arm.com void 21410802Srene.dejong@arm.com addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr) 21510802Srene.dejong@arm.com { 21610802Srene.dejong@arm.com char symb[100]; 21710802Srene.dejong@arm.com CopyStringOut(tc, symb, symbolAddr, 100); 21810802Srene.dejong@arm.com std::string symbol(symb); 21910802Srene.dejong@arm.com 22010802Srene.dejong@arm.com DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 22110802Srene.dejong@arm.com 22210802Srene.dejong@arm.com tc->getSystemPtr()->kernelSymtab->insert(addr,symbol); 22310802Srene.dejong@arm.com } 22410802Srene.dejong@arm.com 22510802Srene.dejong@arm.com void 22610802Srene.dejong@arm.com anBegin(ThreadContext *tc, uint64_t cur) 22710802Srene.dejong@arm.com { 22810802Srene.dejong@arm.com Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & 22910802Srene.dejong@arm.com 0xFFFFFFFF, 0,0); 23010802Srene.dejong@arm.com } 23110802Srene.dejong@arm.com 23210802Srene.dejong@arm.com void 23310802Srene.dejong@arm.com anWait(ThreadContext *tc, uint64_t cur, uint64_t wait) 23410802Srene.dejong@arm.com { 23510802Srene.dejong@arm.com Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur & 23610802Srene.dejong@arm.com 0xFFFFFFFF, wait >> 32, wait & 0xFFFFFFFF); 23710802Srene.dejong@arm.com } 23810802Srene.dejong@arm.com 23910802Srene.dejong@arm.com 24010802Srene.dejong@arm.com void 24110802Srene.dejong@arm.com dumpresetstats(ThreadContext *tc, Tick delay, Tick period) 24210802Srene.dejong@arm.com { 24310802Srene.dejong@arm.com if (!tc->getCpuPtr()->params->do_statistics_insts) 24410802Srene.dejong@arm.com return; 24510802Srene.dejong@arm.com 24610802Srene.dejong@arm.com 24710802Srene.dejong@arm.com Tick when = curTick + delay * Clock::Int::ns; 24810802Srene.dejong@arm.com Tick repeat = period * Clock::Int::ns; 24910802Srene.dejong@arm.com 25010802Srene.dejong@arm.com Stats::StatEvent(true, true, when, repeat); 25110802Srene.dejong@arm.com } 25210802Srene.dejong@arm.com 25310802Srene.dejong@arm.com void 25410802Srene.dejong@arm.com m5checkpoint(ThreadContext *tc, Tick delay, Tick period) 25510802Srene.dejong@arm.com { 25610802Srene.dejong@arm.com if (!tc->getCpuPtr()->params->do_checkpoint_insts) 25710802Srene.dejong@arm.com return; 25810802Srene.dejong@arm.com 25910802Srene.dejong@arm.com Tick when = curTick + delay * Clock::Int::ns; 26010802Srene.dejong@arm.com Tick repeat = period * Clock::Int::ns; 26110802Srene.dejong@arm.com 26210802Srene.dejong@arm.com schedExitSimLoop("checkpoint", when, repeat); 26310802Srene.dejong@arm.com } 26410802Srene.dejong@arm.com 26510802Srene.dejong@arm.com uint64_t 26610802Srene.dejong@arm.com readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset) 26710802Srene.dejong@arm.com { 26810802Srene.dejong@arm.com const string &file = tc->getSystemPtr()->params()->readfile; 26910802Srene.dejong@arm.com if (file.empty()) { 27010802Srene.dejong@arm.com return ULL(0); 27110802Srene.dejong@arm.com } 27210802Srene.dejong@arm.com 27310802Srene.dejong@arm.com uint64_t result = 0; 27410802Srene.dejong@arm.com 27510802Srene.dejong@arm.com int fd = ::open(file.c_str(), O_RDONLY, 0); 27610802Srene.dejong@arm.com if (fd < 0) 27710802Srene.dejong@arm.com panic("could not open file %s\n", file); 27810802Srene.dejong@arm.com 27910802Srene.dejong@arm.com if (::lseek(fd, offset, SEEK_SET) < 0) 28010802Srene.dejong@arm.com panic("could not seek: %s", strerror(errno)); 28110802Srene.dejong@arm.com 28210802Srene.dejong@arm.com char *buf = new char[len]; 28310802Srene.dejong@arm.com char *p = buf; 28410802Srene.dejong@arm.com while (len > 0) { 28510802Srene.dejong@arm.com int bytes = ::read(fd, p, len); 28610802Srene.dejong@arm.com if (bytes <= 0) 28710802Srene.dejong@arm.com break; 28810802Srene.dejong@arm.com 28910802Srene.dejong@arm.com p += bytes; 29010802Srene.dejong@arm.com result += bytes; 29110802Srene.dejong@arm.com len -= bytes; 29210802Srene.dejong@arm.com } 29310802Srene.dejong@arm.com 29410802Srene.dejong@arm.com close(fd); 29510802Srene.dejong@arm.com CopyIn(tc, vaddr, buf, result); 29610802Srene.dejong@arm.com delete [] buf; 29710802Srene.dejong@arm.com return result; 29810802Srene.dejong@arm.com } 29910802Srene.dejong@arm.com 30010802Srene.dejong@arm.com void debugbreak(ThreadContext *tc) 30110802Srene.dejong@arm.com { 30210802Srene.dejong@arm.com debug_break(); 30310802Srene.dejong@arm.com } 30410802Srene.dejong@arm.com 30510802Srene.dejong@arm.com void switchcpu(ThreadContext *tc) 30610802Srene.dejong@arm.com { 30710802Srene.dejong@arm.com exitSimLoop("switchcpu"); 30810802Srene.dejong@arm.com } 30910802Srene.dejong@arm.com} 31010802Srene.dejong@arm.com