pseudo_inst.cc revision 5808
18012Ssaidi@eecs.umich.edu/* 28012Ssaidi@eecs.umich.edu * Copyright (c) 2003-2006 The Regents of The University of Michigan 38012Ssaidi@eecs.umich.edu * All rights reserved. 48012Ssaidi@eecs.umich.edu * 58012Ssaidi@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 68012Ssaidi@eecs.umich.edu * modification, are permitted provided that the following conditions are 78012Ssaidi@eecs.umich.edu * met: redistributions of source code must retain the above copyright 88012Ssaidi@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 98012Ssaidi@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 108012Ssaidi@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 118012Ssaidi@eecs.umich.edu * documentation and/or other materials provided with the distribution; 128012Ssaidi@eecs.umich.edu * neither the name of the copyright holders nor the names of its 138012Ssaidi@eecs.umich.edu * contributors may be used to endorse or promote products derived from 148012Ssaidi@eecs.umich.edu * this software without specific prior written permission. 158012Ssaidi@eecs.umich.edu * 168012Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 178012Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 188012Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 198012Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 208012Ssaidi@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 218012Ssaidi@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 228012Ssaidi@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 237977Shsul@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 247977Shsul@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 257977Shsul@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 267977Shsul@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 277977Shsul@eecs.umich.edu * 287977Shsul@eecs.umich.edu * Authors: Nathan Binkert 297977Shsul@eecs.umich.edu */ 307977Shsul@eecs.umich.edu 317977Shsul@eecs.umich.edu#include <errno.h> 327977Shsul@eecs.umich.edu#include <fcntl.h> 337977Shsul@eecs.umich.edu#include <unistd.h> 347977Shsul@eecs.umich.edu 357977Shsul@eecs.umich.edu#include <fstream> 367977Shsul@eecs.umich.edu#include <string> 377977Shsul@eecs.umich.edu 387977Shsul@eecs.umich.edu#include "arch/kernel_stats.hh" 397977Shsul@eecs.umich.edu#include "arch/vtophys.hh" 407977Shsul@eecs.umich.edu#include "base/annotate.hh" 417977Shsul@eecs.umich.edu#include "cpu/base.hh" 427977Shsul@eecs.umich.edu#include "cpu/thread_context.hh" 437977Shsul@eecs.umich.edu#include "cpu/quiesce_event.hh" 447977Shsul@eecs.umich.edu#include "params/BaseCPU.hh" 457977Shsul@eecs.umich.edu#include "sim/pseudo_inst.hh" 467977Shsul@eecs.umich.edu#include "sim/serialize.hh" 477977Shsul@eecs.umich.edu#include "sim/sim_events.hh" 487977Shsul@eecs.umich.edu#include "sim/sim_exit.hh" 497977Shsul@eecs.umich.edu#include "sim/stat_control.hh" 507977Shsul@eecs.umich.edu#include "sim/stats.hh" 517977Shsul@eecs.umich.edu#include "sim/system.hh" 527977Shsul@eecs.umich.edu#include "sim/debug.hh" 537977Shsul@eecs.umich.edu#if FULL_SYSTEM 547977Shsul@eecs.umich.edu#include "sim/vptr.hh" 557977Shsul@eecs.umich.edu#endif 567977Shsul@eecs.umich.edu 577977Shsul@eecs.umich.eduusing namespace std; 587977Shsul@eecs.umich.edu 597977Shsul@eecs.umich.eduusing namespace Stats; 607977Shsul@eecs.umich.eduusing namespace TheISA; 617977Shsul@eecs.umich.edu 627977Shsul@eecs.umich.edunamespace PseudoInst { 637977Shsul@eecs.umich.edu 647977Shsul@eecs.umich.edu#if FULL_SYSTEM 657977Shsul@eecs.umich.edu 667977Shsul@eecs.umich.eduvoid 677977Shsul@eecs.umich.eduarm(ThreadContext *tc) 687977Shsul@eecs.umich.edu{ 697977Shsul@eecs.umich.edu if (tc->getKernelStats()) 707977Shsul@eecs.umich.edu tc->getKernelStats()->arm(); 717977Shsul@eecs.umich.edu} 727977Shsul@eecs.umich.edu 737977Shsul@eecs.umich.eduvoid 747977Shsul@eecs.umich.eduquiesce(ThreadContext *tc) 757977Shsul@eecs.umich.edu{ 767977Shsul@eecs.umich.edu if (!tc->getCpuPtr()->params()->do_quiesce) 777977Shsul@eecs.umich.edu return; 787977Shsul@eecs.umich.edu 797977Shsul@eecs.umich.edu DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name()); 807977Shsul@eecs.umich.edu 817977Shsul@eecs.umich.edu tc->suspend(); 827977Shsul@eecs.umich.edu if (tc->getKernelStats()) 837977Shsul@eecs.umich.edu tc->getKernelStats()->quiesce(); 847977Shsul@eecs.umich.edu} 857977Shsul@eecs.umich.edu 867977Shsul@eecs.umich.eduvoid 877977Shsul@eecs.umich.eduquiesceNs(ThreadContext *tc, uint64_t ns) 887977Shsul@eecs.umich.edu{ 897977Shsul@eecs.umich.edu if (!tc->getCpuPtr()->params()->do_quiesce || ns == 0) 907977Shsul@eecs.umich.edu return; 917977Shsul@eecs.umich.edu 927977Shsul@eecs.umich.edu EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); 937977Shsul@eecs.umich.edu 947977Shsul@eecs.umich.edu Tick resume = curTick + Clock::Int::ns * ns; 957977Shsul@eecs.umich.edu 967977Shsul@eecs.umich.edu mainEventQueue.reschedule(quiesceEvent, resume, true); 977977Shsul@eecs.umich.edu 987977Shsul@eecs.umich.edu DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n", 997977Shsul@eecs.umich.edu tc->getCpuPtr()->name(), ns, resume); 1007977Shsul@eecs.umich.edu 1017977Shsul@eecs.umich.edu tc->suspend(); 1027977Shsul@eecs.umich.edu if (tc->getKernelStats()) 1037977Shsul@eecs.umich.edu tc->getKernelStats()->quiesce(); 1047977Shsul@eecs.umich.edu} 1057977Shsul@eecs.umich.edu 1067977Shsul@eecs.umich.eduvoid 1077977Shsul@eecs.umich.eduquiesceCycles(ThreadContext *tc, uint64_t cycles) 1087977Shsul@eecs.umich.edu{ 1097977Shsul@eecs.umich.edu if (!tc->getCpuPtr()->params()->do_quiesce || cycles == 0) 1107977Shsul@eecs.umich.edu return; 1117977Shsul@eecs.umich.edu 1127977Shsul@eecs.umich.edu EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent(); 1137977Shsul@eecs.umich.edu 1147977Shsul@eecs.umich.edu Tick resume = curTick + tc->getCpuPtr()->ticks(cycles); 1157977Shsul@eecs.umich.edu 1167977Shsul@eecs.umich.edu mainEventQueue.reschedule(quiesceEvent, resume, true); 1177977Shsul@eecs.umich.edu 1187977Shsul@eecs.umich.edu DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n", 1197977Shsul@eecs.umich.edu tc->getCpuPtr()->name(), cycles, resume); 1207977Shsul@eecs.umich.edu 1217977Shsul@eecs.umich.edu tc->suspend(); 1227977Shsul@eecs.umich.edu if (tc->getKernelStats()) 1237977Shsul@eecs.umich.edu tc->getKernelStats()->quiesce(); 1247977Shsul@eecs.umich.edu} 1257977Shsul@eecs.umich.edu 1267977Shsul@eecs.umich.eduuint64_t 1277977Shsul@eecs.umich.eduquiesceTime(ThreadContext *tc) 1287977Shsul@eecs.umich.edu{ 1297977Shsul@eecs.umich.edu return (tc->readLastActivate() - tc->readLastSuspend()) / Clock::Int::ns; 1307977Shsul@eecs.umich.edu} 1317977Shsul@eecs.umich.edu 1327977Shsul@eecs.umich.edu#endif 1337977Shsul@eecs.umich.edu 1347977Shsul@eecs.umich.eduuint64_t 1357977Shsul@eecs.umich.edurpns(ThreadContext *tc) 1367977Shsul@eecs.umich.edu{ 1377977Shsul@eecs.umich.edu return curTick / Clock::Int::ns; 1387977Shsul@eecs.umich.edu} 1397977Shsul@eecs.umich.edu 1407977Shsul@eecs.umich.eduvoid 1417977Shsul@eecs.umich.eduwakeCPU(ThreadContext *tc, uint64_t cpuid) 1427977Shsul@eecs.umich.edu{ 1437977Shsul@eecs.umich.edu System *sys = tc->getSystemPtr(); 1447977Shsul@eecs.umich.edu ThreadContext *other_tc = sys->threadContexts[cpuid]; 1457977Shsul@eecs.umich.edu if (other_tc->status() == ThreadContext::Suspended) 1467977Shsul@eecs.umich.edu other_tc->activate(); 1477977Shsul@eecs.umich.edu} 1487977Shsul@eecs.umich.edu 1497977Shsul@eecs.umich.eduvoid 1507977Shsul@eecs.umich.edum5exit(ThreadContext *tc, Tick delay) 1517977Shsul@eecs.umich.edu{ 1527977Shsul@eecs.umich.edu Tick when = curTick + delay * Clock::Int::ns; 1537977Shsul@eecs.umich.edu Event *event = new SimLoopExitEvent("m5_exit instruction encountered", 0); 1547977Shsul@eecs.umich.edu mainEventQueue.schedule(event, when); 1557977Shsul@eecs.umich.edu} 1567977Shsul@eecs.umich.edu 1577977Shsul@eecs.umich.edu#if FULL_SYSTEM 1587977Shsul@eecs.umich.edu 1597977Shsul@eecs.umich.eduvoid 1607977Shsul@eecs.umich.eduloadsymbol(ThreadContext *tc) 1617977Shsul@eecs.umich.edu{ 1627977Shsul@eecs.umich.edu const string &filename = tc->getCpuPtr()->system->params()->symbolfile; 1637977Shsul@eecs.umich.edu if (filename.empty()) { 1647977Shsul@eecs.umich.edu return; 1657977Shsul@eecs.umich.edu } 1667977Shsul@eecs.umich.edu 1677977Shsul@eecs.umich.edu std::string buffer; 1687977Shsul@eecs.umich.edu ifstream file(filename.c_str()); 1697977Shsul@eecs.umich.edu 1707977Shsul@eecs.umich.edu if (!file) 1717977Shsul@eecs.umich.edu fatal("file error: Can't open symbol table file %s\n", filename); 1727977Shsul@eecs.umich.edu 1737977Shsul@eecs.umich.edu while (!file.eof()) { 1747977Shsul@eecs.umich.edu getline(file, buffer); 1757977Shsul@eecs.umich.edu 1767977Shsul@eecs.umich.edu if (buffer.empty()) 1777977Shsul@eecs.umich.edu continue; 1787977Shsul@eecs.umich.edu 1797977Shsul@eecs.umich.edu int idx = buffer.find(' '); 1807977Shsul@eecs.umich.edu if (idx == string::npos) 1817977Shsul@eecs.umich.edu continue; 1827977Shsul@eecs.umich.edu 1837977Shsul@eecs.umich.edu string address = "0x" + buffer.substr(0, idx); 1847977Shsul@eecs.umich.edu eat_white(address); 1857977Shsul@eecs.umich.edu if (address.empty()) 1867977Shsul@eecs.umich.edu continue; 1877977Shsul@eecs.umich.edu 1887977Shsul@eecs.umich.edu // Skip over letter and space 1897977Shsul@eecs.umich.edu string symbol = buffer.substr(idx + 3); 1907977Shsul@eecs.umich.edu eat_white(symbol); 1917977Shsul@eecs.umich.edu if (symbol.empty()) 1927977Shsul@eecs.umich.edu continue; 1937977Shsul@eecs.umich.edu 1947977Shsul@eecs.umich.edu Addr addr; 1957977Shsul@eecs.umich.edu if (!to_number(address, addr)) 1967977Shsul@eecs.umich.edu continue; 1977977Shsul@eecs.umich.edu 1987977Shsul@eecs.umich.edu if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol)) 1997977Shsul@eecs.umich.edu continue; 2007977Shsul@eecs.umich.edu 2017977Shsul@eecs.umich.edu 2027977Shsul@eecs.umich.edu DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 2037977Shsul@eecs.umich.edu } 2047977Shsul@eecs.umich.edu file.close(); 2057977Shsul@eecs.umich.edu} 2067977Shsul@eecs.umich.edu 2077977Shsul@eecs.umich.eduvoid 2087977Shsul@eecs.umich.eduaddsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr) 2097977Shsul@eecs.umich.edu{ 2107977Shsul@eecs.umich.edu char symb[100]; 2117977Shsul@eecs.umich.edu CopyStringOut(tc, symb, symbolAddr, 100); 2127977Shsul@eecs.umich.edu std::string symbol(symb); 2137977Shsul@eecs.umich.edu 2147977Shsul@eecs.umich.edu DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr); 2157977Shsul@eecs.umich.edu 2167977Shsul@eecs.umich.edu tc->getSystemPtr()->kernelSymtab->insert(addr,symbol); 2177977Shsul@eecs.umich.edu} 2187977Shsul@eecs.umich.edu 2197977Shsul@eecs.umich.edu#endif 2207977Shsul@eecs.umich.edu 2217977Shsul@eecs.umich.edu 2227977Shsul@eecs.umich.eduvoid 2237977Shsul@eecs.umich.eduresetstats(ThreadContext *tc, Tick delay, Tick period) 2247977Shsul@eecs.umich.edu{ 2257977Shsul@eecs.umich.edu if (!tc->getCpuPtr()->params()->do_statistics_insts) 2267977Shsul@eecs.umich.edu return; 2277977Shsul@eecs.umich.edu 2287977Shsul@eecs.umich.edu 2297977Shsul@eecs.umich.edu Tick when = curTick + delay * Clock::Int::ns; 2307977Shsul@eecs.umich.edu Tick repeat = period * Clock::Int::ns; 2317977Shsul@eecs.umich.edu 2327977Shsul@eecs.umich.edu Stats::StatEvent(false, true, when, repeat); 2337977Shsul@eecs.umich.edu} 2347977Shsul@eecs.umich.edu 2357977Shsul@eecs.umich.eduvoid 2367977Shsul@eecs.umich.edudumpstats(ThreadContext *tc, Tick delay, Tick period) 2377977Shsul@eecs.umich.edu{ 2387977Shsul@eecs.umich.edu if (!tc->getCpuPtr()->params()->do_statistics_insts) 2397977Shsul@eecs.umich.edu return; 2407977Shsul@eecs.umich.edu 2417977Shsul@eecs.umich.edu 2427977Shsul@eecs.umich.edu Tick when = curTick + delay * Clock::Int::ns; 2437977Shsul@eecs.umich.edu Tick repeat = period * Clock::Int::ns; 2447977Shsul@eecs.umich.edu 2457977Shsul@eecs.umich.edu Stats::StatEvent(true, false, when, repeat); 2467977Shsul@eecs.umich.edu} 2477977Shsul@eecs.umich.edu 2487977Shsul@eecs.umich.eduvoid 2497977Shsul@eecs.umich.edudumpresetstats(ThreadContext *tc, Tick delay, Tick period) 2507977Shsul@eecs.umich.edu{ 2517977Shsul@eecs.umich.edu if (!tc->getCpuPtr()->params()->do_statistics_insts) 2527977Shsul@eecs.umich.edu return; 2537977Shsul@eecs.umich.edu 2547977Shsul@eecs.umich.edu 2557977Shsul@eecs.umich.edu Tick when = curTick + delay * Clock::Int::ns; 2567977Shsul@eecs.umich.edu Tick repeat = period * Clock::Int::ns; 2577977Shsul@eecs.umich.edu 2587977Shsul@eecs.umich.edu Stats::StatEvent(true, true, when, repeat); 2597977Shsul@eecs.umich.edu} 2607977Shsul@eecs.umich.edu 2617977Shsul@eecs.umich.eduvoid 2627977Shsul@eecs.umich.edum5checkpoint(ThreadContext *tc, Tick delay, Tick period) 2637977Shsul@eecs.umich.edu{ 2647977Shsul@eecs.umich.edu if (!tc->getCpuPtr()->params()->do_checkpoint_insts) 2657977Shsul@eecs.umich.edu return; 2667977Shsul@eecs.umich.edu 2677977Shsul@eecs.umich.edu Tick when = curTick + delay * Clock::Int::ns; 2687977Shsul@eecs.umich.edu Tick repeat = period * Clock::Int::ns; 2697977Shsul@eecs.umich.edu 2707977Shsul@eecs.umich.edu Event *event = new SimLoopExitEvent("checkpoint", 0, repeat); 2717977Shsul@eecs.umich.edu mainEventQueue.schedule(event, when); 2727977Shsul@eecs.umich.edu} 2737977Shsul@eecs.umich.edu 2747977Shsul@eecs.umich.edu#if FULL_SYSTEM 2757977Shsul@eecs.umich.edu 2767977Shsul@eecs.umich.eduuint64_t 2777977Shsul@eecs.umich.edureadfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset) 2787977Shsul@eecs.umich.edu{ 2797977Shsul@eecs.umich.edu const string &file = tc->getSystemPtr()->params()->readfile; 2807977Shsul@eecs.umich.edu if (file.empty()) { 2817977Shsul@eecs.umich.edu return ULL(0); 2827977Shsul@eecs.umich.edu } 2837977Shsul@eecs.umich.edu 2847977Shsul@eecs.umich.edu uint64_t result = 0; 2857977Shsul@eecs.umich.edu 2867977Shsul@eecs.umich.edu int fd = ::open(file.c_str(), O_RDONLY, 0); 2877977Shsul@eecs.umich.edu if (fd < 0) 2887977Shsul@eecs.umich.edu panic("could not open file %s\n", file); 2897977Shsul@eecs.umich.edu 2907977Shsul@eecs.umich.edu if (::lseek(fd, offset, SEEK_SET) < 0) 2917977Shsul@eecs.umich.edu panic("could not seek: %s", strerror(errno)); 2927977Shsul@eecs.umich.edu 2937977Shsul@eecs.umich.edu char *buf = new char[len]; 2947977Shsul@eecs.umich.edu char *p = buf; 2957977Shsul@eecs.umich.edu while (len > 0) { 2967977Shsul@eecs.umich.edu int bytes = ::read(fd, p, len); 2977977Shsul@eecs.umich.edu if (bytes <= 0) 2987977Shsul@eecs.umich.edu break; 2997977Shsul@eecs.umich.edu 3007977Shsul@eecs.umich.edu p += bytes; 3017977Shsul@eecs.umich.edu result += bytes; 3027977Shsul@eecs.umich.edu len -= bytes; 3037977Shsul@eecs.umich.edu } 3047977Shsul@eecs.umich.edu 3057977Shsul@eecs.umich.edu close(fd); 3067977Shsul@eecs.umich.edu CopyIn(tc, vaddr, buf, result); 3077977Shsul@eecs.umich.edu delete [] buf; 3087977Shsul@eecs.umich.edu return result; 3097977Shsul@eecs.umich.edu} 3107977Shsul@eecs.umich.edu 3117977Shsul@eecs.umich.edu#endif 3127977Shsul@eecs.umich.edu 3137977Shsul@eecs.umich.eduvoid 3147977Shsul@eecs.umich.edudebugbreak(ThreadContext *tc) 3157977Shsul@eecs.umich.edu{ 3167977Shsul@eecs.umich.edu debug_break(); 3177977Shsul@eecs.umich.edu} 3187977Shsul@eecs.umich.edu 3197977Shsul@eecs.umich.eduvoid 3207977Shsul@eecs.umich.eduswitchcpu(ThreadContext *tc) 3217977Shsul@eecs.umich.edu{ 3227977Shsul@eecs.umich.edu exitSimLoop("switchcpu"); 3237977Shsul@eecs.umich.edu} 3247977Shsul@eecs.umich.edu 3257977Shsul@eecs.umich.edu/* namespace PseudoInst */ } 3267977Shsul@eecs.umich.edu