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