pseudo_inst.cc revision 8232
11689SN/A/* 22325SN/A * Copyright (c) 2010 ARM Limited 31689SN/A * All rights reserved 41689SN/A * 51689SN/A * The license below extends only to copyright in the software and shall 61689SN/A * not be construed as granting a license to any other intellectual 71689SN/A * property including but not limited to intellectual property relating 81689SN/A * to a hardware implementation of the functionality of the software 91689SN/A * licensed hereunder. You may use the software subject to the license 101689SN/A * terms below provided that you ensure that this notice is replicated 111689SN/A * unmodified and in its entirety in all distributions of the software, 121689SN/A * modified or unmodified, in source code or in binary form. 131689SN/A * 141689SN/A * Copyright (c) 2003-2006 The Regents of The University of Michigan 151689SN/A * All rights reserved. 161689SN/A * 171689SN/A * Redistribution and use in source and binary forms, with or without 181689SN/A * modification, are permitted provided that the following conditions are 191689SN/A * met: redistributions of source code must retain the above copyright 201689SN/A * notice, this list of conditions and the following disclaimer; 211689SN/A * redistributions in binary form must reproduce the above copyright 221689SN/A * notice, this list of conditions and the following disclaimer in the 231689SN/A * documentation and/or other materials provided with the distribution; 241689SN/A * neither the name of the copyright holders nor the names of its 251689SN/A * contributors may be used to endorse or promote products derived from 261689SN/A * this software without specific prior written permission. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 292756Sksewell@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 301689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 311689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 321858SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 332733Sktlim@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 341858SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 351858SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 362356SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 371060SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 381060SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 391060SN/A * 401060SN/A * Authors: Nathan Binkert 411060SN/A */ 422325SN/A 432683Sktlim@umich.edu#include <fcntl.h> 442680Sktlim@umich.edu#include <unistd.h> 452817Sksewell@umich.edu 461717SN/A#include <cerrno> 471060SN/A#include <fstream> 482325SN/A#include <string> 492292SN/A 502292SN/A#include "arch/vtophys.hh" 512794Sktlim@umich.edu#include "base/debug.hh" 522794Sktlim@umich.edu#include "config/full_system.hh" 532794Sktlim@umich.edu#include "config/the_isa.hh" 542794Sktlim@umich.edu#include "cpu/base.hh" 551060SN/A#include "cpu/quiesce_event.hh" 562669Sktlim@umich.edu#include "cpu/thread_context.hh" 571060SN/A#include "debug/Loader.hh" 582733Sktlim@umich.edu#include "debug/Quiesce.hh" 592292SN/A#include "debug/WorkItems.hh" 601060SN/A#include "params/BaseCPU.hh" 611060SN/A#include "sim/pseudo_inst.hh" 621060SN/A#include "sim/serialize.hh" 632292SN/A#include "sim/sim_events.hh" 642733Sktlim@umich.edu#include "sim/sim_exit.hh" 652292SN/A#include "sim/stat_control.hh" 662292SN/A#include "sim/stats.hh" 672292SN/A#include "sim/system.hh" 682292SN/A 691060SN/A#if FULL_SYSTEM 701755SN/A#include "arch/kernel_stats.hh" 711060SN/A#include "sim/vptr.hh" 721060SN/A#endif 731060SN/A 741060SN/Ausing namespace std; 751060SN/A 761060SN/Ausing namespace Stats; 771755SN/Ausing namespace TheISA; 781060SN/A 791060SN/Anamespace PseudoInst { 801060SN/A 811060SN/A#if FULL_SYSTEM 821060SN/A 831060SN/Avoid 841755SN/Aarm(ThreadContext *tc) 851060SN/A{ 861755SN/A if (tc->getKernelStats()) 871060SN/A tc->getKernelStats()->arm(); 881060SN/A} 891060SN/A 902829Sksewell@umich.eduvoid 913221Sktlim@umich.eduquiesce(ThreadContext *tc) 922829Sksewell@umich.edu{ 932829Sksewell@umich.edu if (!tc->getCpuPtr()->params()->do_quiesce) 942829Sksewell@umich.edu return; 952829Sksewell@umich.edu 962829Sksewell@umich.edu DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name()); 972829Sksewell@umich.edu 982829Sksewell@umich.edu tc->suspend(); 992829Sksewell@umich.edu if (tc->getKernelStats()) 1002829Sksewell@umich.edu tc->getKernelStats()->quiesce(); 1012829Sksewell@umich.edu} 1022829Sksewell@umich.edu 1032829Sksewell@umich.eduvoid 1042829Sksewell@umich.eduquiesceSkip(ThreadContext *tc) 1052829Sksewell@umich.edu{ 1062829Sksewell@umich.edu BaseCPU *cpu = tc->getCpuPtr(); 1072829Sksewell@umich.edu 1082829Sksewell@umich.edu if (!cpu->params()->do_quiesce) 1092829Sksewell@umich.edu return; 1102829Sksewell@umich.edu 1112829Sksewell@umich.edu EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); 1122829Sksewell@umich.edu 1132829Sksewell@umich.edu Tick resume = curTick() + 1; 1142829Sksewell@umich.edu 1152829Sksewell@umich.edu cpu->reschedule(quiesceEvent, resume, true); 1162829Sksewell@umich.edu 1172829Sksewell@umich.edu DPRINTF(Quiesce, "%s: quiesceSkip() until %d\n", 1182829Sksewell@umich.edu cpu->name(), resume); 1192875Sksewell@umich.edu 1202875Sksewell@umich.edu tc->suspend(); 1212875Sksewell@umich.edu if (tc->getKernelStats()) 1222875Sksewell@umich.edu tc->getKernelStats()->quiesce(); 1232875Sksewell@umich.edu} 1242875Sksewell@umich.edu 1252875Sksewell@umich.eduvoid 1262875Sksewell@umich.eduquiesceNs(ThreadContext *tc, uint64_t ns) 1272875Sksewell@umich.edu{ 1282875Sksewell@umich.edu BaseCPU *cpu = tc->getCpuPtr(); 1292875Sksewell@umich.edu 1302875Sksewell@umich.edu if (!cpu->params()->do_quiesce || ns == 0) 1312875Sksewell@umich.edu return; 1322875Sksewell@umich.edu 1332875Sksewell@umich.edu EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); 1342875Sksewell@umich.edu 1352875Sksewell@umich.edu Tick resume = curTick() + SimClock::Int::ns * ns; 1362875Sksewell@umich.edu 1372875Sksewell@umich.edu cpu->reschedule(quiesceEvent, resume, true); 1383221Sktlim@umich.edu 1393221Sktlim@umich.edu DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n", 1402875Sksewell@umich.edu cpu->name(), ns, resume); 1412875Sksewell@umich.edu 1422875Sksewell@umich.edu tc->suspend(); 1432875Sksewell@umich.edu if (tc->getKernelStats()) 1442875Sksewell@umich.edu tc->getKernelStats()->quiesce(); 1452875Sksewell@umich.edu} 1462875Sksewell@umich.edu 1472875Sksewell@umich.eduvoid 1482875Sksewell@umich.eduquiesceCycles(ThreadContext *tc, uint64_t cycles) 1492875Sksewell@umich.edu{ 1502292SN/A BaseCPU *cpu = tc->getCpuPtr(); 1512733Sktlim@umich.edu 1521060SN/A if (!cpu->params()->do_quiesce || cycles == 0) 1532292SN/A return; 1541060SN/A 1551060SN/A EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); 1561060SN/A 1571060SN/A Tick resume = curTick() + cpu->ticks(cycles); 1581060SN/A 1591060SN/A cpu->reschedule(quiesceEvent, resume, true); 1602292SN/A 1611060SN/A DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n", 1622831Sksewell@umich.edu cpu->name(), cycles, resume); 1632292SN/A 1642292SN/A tc->suspend(); 1651060SN/A if (tc->getKernelStats()) 1662292SN/A tc->getKernelStats()->quiesce(); 1672292SN/A} 1682292SN/A 1691060SN/Auint64_t 1702831Sksewell@umich.eduquiesceTime(ThreadContext *tc) 1712292SN/A{ 1722292SN/A return (tc->readLastActivate() - tc->readLastSuspend()) / 1732292SN/A SimClock::Int::ns; 1742292SN/A} 1751060SN/A 1762873Sktlim@umich.edu#endif 1772873Sktlim@umich.edu 1782873Sktlim@umich.eduuint64_t 1792873Sktlim@umich.edurpns(ThreadContext *tc) 1802873Sktlim@umich.edu{ 1812873Sktlim@umich.edu return curTick() / SimClock::Int::ns; 1822873Sktlim@umich.edu} 1832873Sktlim@umich.edu 1841060SN/Avoid 1851060SN/AwakeCPU(ThreadContext *tc, uint64_t cpuid) 1861858SN/A{ 1872292SN/A System *sys = tc->getSystemPtr(); 1881060SN/A ThreadContext *other_tc = sys->threadContexts[cpuid]; 1891060SN/A if (other_tc->status() == ThreadContext::Suspended) 1902292SN/A other_tc->activate(); 1912843Sktlim@umich.edu} 1922316SN/A 1932316SN/Avoid 1941060SN/Am5exit(ThreadContext *tc, Tick delay) 1953221Sktlim@umich.edu{ 1963221Sktlim@umich.edu Tick when = curTick() + delay * SimClock::Int::ns; 1973221Sktlim@umich.edu exitSimLoop("m5_exit instruction encountered", 0, when); 1983221Sktlim@umich.edu} 1993221Sktlim@umich.edu 2001681SN/A#if FULL_SYSTEM 2012733Sktlim@umich.edu 2022733Sktlim@umich.eduvoid 2032794Sktlim@umich.eduloadsymbol(ThreadContext *tc) 2042733Sktlim@umich.edu{ 2052316SN/A const string &filename = tc->getCpuPtr()->system->params()->symbolfile; 2062316SN/A if (filename.empty()) { 2072316SN/A return; 2082316SN/A } 2092316SN/A 2102316SN/A std::string buffer; 2112794Sktlim@umich.edu ifstream file(filename.c_str()); 2122794Sktlim@umich.edu 2132794Sktlim@umich.edu if (!file) 2142316SN/A fatal("file error: Can't open symbol table file %s\n", filename); 2152316SN/A 2161858SN/A while (!file.eof()) { 2172292SN/A getline(file, buffer); 2182292SN/A 2191681SN/A if (buffer.empty()) 2201681SN/A continue; 2212325SN/A 2222325SN/A string::size_type idx = buffer.find(' '); 2232325SN/A if (idx == string::npos) 2241060SN/A continue; 2252292SN/A 2262292SN/A string address = "0x" + buffer.substr(0, idx); 2272292SN/A eat_white(address); 2282292SN/A if (address.empty()) 2292292SN/A continue; 2302292SN/A 2311060SN/A // Skip over letter and space 2321060SN/A string symbol = buffer.substr(idx + 3); 2331060SN/A eat_white(symbol); 2341060SN/A if (symbol.empty()) 2351060SN/A continue; 2361060SN/A 2371060SN/A Addr addr; 2381060SN/A if (!to_number(address, addr)) 2391060SN/A continue; 2401060SN/A 2411060SN/A if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol)) 2422292SN/A continue; 2431060SN/A 2441060SN/A 2451060SN/A DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 2461060SN/A } 2471060SN/A file.close(); 2481060SN/A} 2491060SN/A 2501060SN/Avoid 2512292SN/Aaddsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr) 2522292SN/A{ 2532292SN/A char symb[100]; 2542292SN/A CopyStringOut(tc, symb, symbolAddr, 100); 2552292SN/A std::string symbol(symb); 2562307SN/A 2572831Sksewell@umich.edu DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 2582831Sksewell@umich.edu 2592831Sksewell@umich.edu tc->getSystemPtr()->kernelSymtab->insert(addr,symbol); 2602831Sksewell@umich.edu debugSymbolTable->insert(addr,symbol); 2612831Sksewell@umich.edu} 2622831Sksewell@umich.edu 2632292SN/A#endif 2642307SN/A 2652292SN/A 2662292SN/Avoid 2672316SN/Aresetstats(ThreadContext *tc, Tick delay, Tick period) 2682292SN/A{ 2692292SN/A if (!tc->getCpuPtr()->params()->do_statistics_insts) 2702292SN/A return; 2712292SN/A 2722292SN/A 2732292SN/A Tick when = curTick() + delay * SimClock::Int::ns; 2741060SN/A Tick repeat = period * SimClock::Int::ns; 2752292SN/A 2762292SN/A Stats::schedStatEvent(false, true, when, repeat); 2771060SN/A} 2782292SN/A 2792307SN/Avoid 2802292SN/Adumpstats(ThreadContext *tc, Tick delay, Tick period) 2812292SN/A{ 2822292SN/A if (!tc->getCpuPtr()->params()->do_statistics_insts) 2832325SN/A return; 2842292SN/A 2852292SN/A 2862292SN/A Tick when = curTick() + delay * SimClock::Int::ns; 2872325SN/A Tick repeat = period * SimClock::Int::ns; 2882292SN/A 2892292SN/A Stats::schedStatEvent(true, false, when, repeat); 2902292SN/A} 2912292SN/A 2922292SN/Avoid 2932292SN/Adumpresetstats(ThreadContext *tc, Tick delay, Tick period) 2942292SN/A{ 2952292SN/A if (!tc->getCpuPtr()->params()->do_statistics_insts) 2962292SN/A return; 2972292SN/A 2982292SN/A 2992325SN/A Tick when = curTick() + delay * SimClock::Int::ns; 3002292SN/A Tick repeat = period * SimClock::Int::ns; 3012292SN/A 3022292SN/A Stats::schedStatEvent(true, true, when, repeat); 3032325SN/A} 3042292SN/A 3052292SN/Avoid 3062292SN/Am5checkpoint(ThreadContext *tc, Tick delay, Tick period) 3072292SN/A{ 3082292SN/A if (!tc->getCpuPtr()->params()->do_checkpoint_insts) 3092292SN/A return; 3102292SN/A 3112292SN/A Tick when = curTick() + delay * SimClock::Int::ns; 3123221Sktlim@umich.edu Tick repeat = period * SimClock::Int::ns; 3133221Sktlim@umich.edu 3143221Sktlim@umich.edu exitSimLoop("checkpoint", 0, when, repeat); 3152292SN/A} 3162292SN/A 3172292SN/A#if FULL_SYSTEM 3182292SN/A 3192292SN/Auint64_t 3202292SN/Areadfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset) 3212292SN/A{ 3222292SN/A const string &file = tc->getSystemPtr()->params()->readfile; 3232292SN/A if (file.empty()) { 3241060SN/A return ULL(0); 3252292SN/A } 3261060SN/A 3271060SN/A uint64_t result = 0; 3282292SN/A 3292292SN/A int fd = ::open(file.c_str(), O_RDONLY, 0); 3302292SN/A if (fd < 0) 3312829Sksewell@umich.edu panic("could not open file %s\n", file); 3322829Sksewell@umich.edu 3333093Sksewell@umich.edu if (::lseek(fd, offset, SEEK_SET) < 0) 3343093Sksewell@umich.edu panic("could not seek: %s", strerror(errno)); 3353093Sksewell@umich.edu 3363093Sksewell@umich.edu char *buf = new char[len]; 3373093Sksewell@umich.edu char *p = buf; 3382292SN/A while (len > 0) { 3391060SN/A int bytes = ::read(fd, p, len); 3401060SN/A if (bytes <= 0) 3411060SN/A break; 3421755SN/A 3431060SN/A p += bytes; 3441060SN/A result += bytes; 3451060SN/A len -= bytes; 3461060SN/A } 3471060SN/A 3481755SN/A close(fd); 3491062SN/A CopyIn(tc, vaddr, buf, result); 3502733Sktlim@umich.edu delete [] buf; 3512292SN/A return result; 3522733Sktlim@umich.edu} 3532292SN/A 3542292SN/A#endif 3552292SN/A 3562292SN/Avoid 3572292SN/Adebugbreak(ThreadContext *tc) 3582292SN/A{ 3592292SN/A Debug::breakpoint(); 3602292SN/A} 3612292SN/A 3622292SN/Avoid 3632292SN/Aswitchcpu(ThreadContext *tc) 3642292SN/A{ 3652292SN/A exitSimLoop("switchcpu"); 3662292SN/A} 3672292SN/A 3682292SN/A// 3692292SN/A// This function is executed when annotated work items begin. Depending on 3702292SN/A// what the user specified at the command line, the simulation may exit and/or 3712292SN/A// take a checkpoint when a certain work item begins. 3722292SN/A// 3732292SN/Avoid 3742292SN/Aworkbegin(ThreadContext *tc, uint64_t workid, uint64_t threadid) 3752292SN/A{ 3762292SN/A tc->getCpuPtr()->workItemBegin(); 3772292SN/A System *sys = tc->getSystemPtr(); 3782292SN/A 3792292SN/A DPRINTF(WorkItems, "Work Begin workid: %d, threadid %d\n", workid, 3802292SN/A threadid); 3812292SN/A 3822292SN/A // 3832292SN/A // If specified, determine if this is the specific work item the user 3842292SN/A // identified 3852292SN/A // 3862292SN/A if (sys->params()->work_item_id == -1 || 3872292SN/A sys->params()->work_item_id == workid) { 3882292SN/A 3892292SN/A uint64_t systemWorkBeginCount = sys->incWorkItemsBegin(); 3902292SN/A int cpuId = tc->getCpuPtr()->cpuId(); 3912292SN/A 3922292SN/A if (sys->params()->work_cpus_ckpt_count != 0 && 3932292SN/A sys->markWorkItem(cpuId) >= sys->params()->work_cpus_ckpt_count) { 3942292SN/A // 3952292SN/A // If active cpus equals checkpoint count, create checkpoint 3962292SN/A // 3972292SN/A Event *event = new SimLoopExitEvent("checkpoint", 0); 3982292SN/A mainEventQueue.schedule(event, curTick()); 3992292SN/A } 4002292SN/A 4012292SN/A if (systemWorkBeginCount == sys->params()->work_begin_ckpt_count) { 4021062SN/A // 4031062SN/A // Note: the string specified as the cause of the exit event must 4041062SN/A // exactly equal "checkpoint" inorder to create a checkpoint 4052871Sktlim@umich.edu // 4062871Sktlim@umich.edu Event *event = new SimLoopExitEvent("checkpoint", 0); 4072871Sktlim@umich.edu mainEventQueue.schedule(event, curTick()); 4082871Sktlim@umich.edu } 4092871Sktlim@umich.edu 4102871Sktlim@umich.edu if (systemWorkBeginCount == sys->params()->work_begin_exit_count) { 4112871Sktlim@umich.edu // 4122871Sktlim@umich.edu // If a certain number of work items started, exit simulation 4132871Sktlim@umich.edu // 4142871Sktlim@umich.edu Event *event = new SimLoopExitEvent("work started count reach", 0); 4152871Sktlim@umich.edu mainEventQueue.schedule(event, curTick()); 4162871Sktlim@umich.edu } 4171062SN/A 4181755SN/A if (tc->getCpuPtr()->cpuId() == sys->params()->work_begin_cpu_id_exit) { 4191060SN/A // 4202733Sktlim@umich.edu // If work started on the specific cpu id specified, exit simulation 4211060SN/A // 4222292SN/A Event *event = new SimLoopExitEvent("work started on specific cpu", 4232292SN/A 0); 4242325SN/A 4252292SN/A mainEventQueue.schedule(event, curTick() + 1); 4262292SN/A } 4271060SN/A } 4281060SN/A} 4291060SN/A 4301060SN/A// 4311060SN/A// This function is executed when annotated work items end. Depending on 4321060SN/A// what the user specified at the command line, the simulation may exit and/or 4331060SN/A// take a checkpoint when a certain work item ends. 4341060SN/A// 4351060SN/Avoid 4361060SN/Aworkend(ThreadContext *tc, uint64_t workid, uint64_t threadid) 4372292SN/A{ 4382292SN/A tc->getCpuPtr()->workItemEnd(); 4392292SN/A System *sys = tc->getSystemPtr(); 4402292SN/A 4412292SN/A DPRINTF(WorkItems, "Work End workid: %d, threadid %d\n", workid, threadid); 4421060SN/A 4431060SN/A // 4441060SN/A // If specified, determine if this is the specific work item the user 4451060SN/A // identified 4461060SN/A // 4471060SN/A if (sys->params()->work_item_id == -1 || 4481060SN/A sys->params()->work_item_id == workid) { 4492325SN/A 4502292SN/A uint64_t systemWorkEndCount = sys->incWorkItemsEnd(); 4512292SN/A int cpuId = tc->getCpuPtr()->cpuId(); 4522292SN/A 4532292SN/A if (sys->params()->work_cpus_ckpt_count != 0 && 4542292SN/A sys->markWorkItem(cpuId) >= sys->params()->work_cpus_ckpt_count) { 4552325SN/A // 4562867Sktlim@umich.edu // If active cpus equals checkpoint count, create checkpoint 4572905Sktlim@umich.edu // 4583226Sktlim@umich.edu Event *event = new SimLoopExitEvent("checkpoint", 0); 4592325SN/A mainEventQueue.schedule(event, curTick()); 4602325SN/A } 4613221Sktlim@umich.edu 4623226Sktlim@umich.edu if (sys->params()->work_end_ckpt_count != 0 && 4632325SN/A systemWorkEndCount == sys->params()->work_end_ckpt_count) { 4642325SN/A // 4652325SN/A // If total work items completed equals checkpoint count, create 4662325SN/A // checkpoint 4673226Sktlim@umich.edu // 4682325SN/A Event *event = new SimLoopExitEvent("checkpoint", 0); 4692292SN/A mainEventQueue.schedule(event, curTick()); 4702292SN/A } 4712292SN/A 4722292SN/A if (sys->params()->work_end_exit_count != 0 && 4732292SN/A systemWorkEndCount == sys->params()->work_end_exit_count) { 4742292SN/A // 4751060SN/A // If total work items completed equals exit count, exit simulation 4761060SN/A // 4771060SN/A Event *event = new SimLoopExitEvent("work items exit count reached", 4781060SN/A 0); 4791755SN/A 4801060SN/A mainEventQueue.schedule(event, curTick()); 4812307SN/A } 4822680Sktlim@umich.edu } 4832292SN/A} 4841060SN/A 4852292SN/A} // namespace PseudoInst 4862292SN/A