pseudo_inst.cc revision 4078
1298SN/A/*
22188SN/A * Copyright (c) 2003-2006 The Regents of The University of Michigan
3298SN/A * All rights reserved.
4298SN/A *
5298SN/A * Redistribution and use in source and binary forms, with or without
6298SN/A * modification, are permitted provided that the following conditions are
7298SN/A * met: redistributions of source code must retain the above copyright
8298SN/A * notice, this list of conditions and the following disclaimer;
9298SN/A * redistributions in binary form must reproduce the above copyright
10298SN/A * notice, this list of conditions and the following disclaimer in the
11298SN/A * documentation and/or other materials provided with the distribution;
12298SN/A * neither the name of the copyright holders nor the names of its
13298SN/A * contributors may be used to endorse or promote products derived from
14298SN/A * this software without specific prior written permission.
15298SN/A *
16298SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17298SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18298SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19298SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20298SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21298SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22298SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23298SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24298SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25298SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26298SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu *
282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert
29298SN/A */
30298SN/A
311642SN/A#include <errno.h>
32954SN/A#include <fcntl.h>
33956SN/A#include <unistd.h>
34956SN/A
354078Sbinkertn@umich.edu#include <fstream>
36299SN/A#include <string>
37299SN/A
382170SN/A#include "arch/vtophys.hh"
393089Ssaidi@eecs.umich.edu#include "base/annotate.hh"
401717SN/A#include "cpu/base.hh"
412680Sktlim@umich.edu#include "cpu/thread_context.hh"
422313SN/A#include "cpu/quiesce_event.hh"
433565Sgblack@eecs.umich.edu#include "arch/kernel_stats.hh"
443565Sgblack@eecs.umich.edu#include "sim/pseudo_inst.hh"
45298SN/A#include "sim/serialize.hh"
46298SN/A#include "sim/sim_exit.hh"
47695SN/A#include "sim/stat_control.hh"
48695SN/A#include "sim/stats.hh"
49954SN/A#include "sim/system.hh"
501052SN/A#include "sim/debug.hh"
512080SN/A#include "sim/vptr.hh"
52298SN/A
53299SN/Ausing namespace std;
541052SN/A
55729SN/Ausing namespace Stats;
562107SN/Ausing namespace TheISA;
57298SN/A
58298SN/Anamespace AlphaPseudo
59298SN/A{
60310SN/A    void
612680Sktlim@umich.edu    arm(ThreadContext *tc)
62711SN/A    {
632680Sktlim@umich.edu        if (tc->getKernelStats())
642680Sktlim@umich.edu            tc->getKernelStats()->arm();
65711SN/A    }
66711SN/A
67711SN/A    void
682680Sktlim@umich.edu    quiesce(ThreadContext *tc)
69310SN/A    {
703617Sbinkertn@umich.edu        if (!tc->getCpuPtr()->params->do_quiesce)
71310SN/A            return;
72310SN/A
733373Sstever@eecs.umich.edu        DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name());
743373Sstever@eecs.umich.edu
752680Sktlim@umich.edu        tc->suspend();
762680Sktlim@umich.edu        if (tc->getKernelStats())
772680Sktlim@umich.edu            tc->getKernelStats()->quiesce();
78310SN/A    }
79299SN/A
80298SN/A    void
812680Sktlim@umich.edu    quiesceNs(ThreadContext *tc, uint64_t ns)
822188SN/A    {
833617Sbinkertn@umich.edu        if (!tc->getCpuPtr()->params->do_quiesce || ns == 0)
842188SN/A            return;
852188SN/A
862680Sktlim@umich.edu        EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
872235SN/A
883368Sstever@eecs.umich.edu        Tick resume = curTick + Clock::Int::ns * ns;
893368Sstever@eecs.umich.edu
902235SN/A        if (quiesceEvent->scheduled())
913368Sstever@eecs.umich.edu            quiesceEvent->reschedule(resume);
922188SN/A        else
933368Sstever@eecs.umich.edu            quiesceEvent->schedule(resume);
943368Sstever@eecs.umich.edu
953368Sstever@eecs.umich.edu        DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n",
963368Sstever@eecs.umich.edu                tc->getCpuPtr()->name(), ns, resume);
972188SN/A
982680Sktlim@umich.edu        tc->suspend();
992680Sktlim@umich.edu        if (tc->getKernelStats())
1002680Sktlim@umich.edu            tc->getKernelStats()->quiesce();
1012188SN/A    }
1022188SN/A
1032188SN/A    void
1042680Sktlim@umich.edu    quiesceCycles(ThreadContext *tc, uint64_t cycles)
1052188SN/A    {
1063617Sbinkertn@umich.edu        if (!tc->getCpuPtr()->params->do_quiesce || cycles == 0)
1072188SN/A            return;
1082188SN/A
1092680Sktlim@umich.edu        EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
1102235SN/A
1113368Sstever@eecs.umich.edu        Tick resume = curTick + tc->getCpuPtr()->cycles(cycles);
1123368Sstever@eecs.umich.edu
1132235SN/A        if (quiesceEvent->scheduled())
1143368Sstever@eecs.umich.edu            quiesceEvent->reschedule(resume);
1152188SN/A        else
1163368Sstever@eecs.umich.edu            quiesceEvent->schedule(resume);
1173368Sstever@eecs.umich.edu
1183368Sstever@eecs.umich.edu        DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n",
1193368Sstever@eecs.umich.edu                tc->getCpuPtr()->name(), cycles, resume);
1202188SN/A
1212680Sktlim@umich.edu        tc->suspend();
1222680Sktlim@umich.edu        if (tc->getKernelStats())
1232680Sktlim@umich.edu            tc->getKernelStats()->quiesce();
1242188SN/A    }
1252188SN/A
1262188SN/A    uint64_t
1272680Sktlim@umich.edu    quiesceTime(ThreadContext *tc)
1282188SN/A    {
1292680Sktlim@umich.edu        return (tc->readLastActivate() - tc->readLastSuspend()) / Clock::Int::ns;
1302188SN/A    }
1312188SN/A
1322188SN/A    void
1332680Sktlim@umich.edu    m5exit_old(ThreadContext *tc)
134298SN/A    {
1353144Shsul@eecs.umich.edu        exitSimLoop("m5_exit_old instruction encountered");
136298SN/A    }
137298SN/A
138298SN/A    void
1392680Sktlim@umich.edu    m5exit(ThreadContext *tc, Tick delay)
140298SN/A    {
1411609SN/A        Tick when = curTick + delay * Clock::Int::ns;
1423144Shsul@eecs.umich.edu        schedExitSimLoop("m5_exit instruction encountered", when);
143298SN/A    }
144298SN/A
145298SN/A    void
1463126Sktlim@umich.edu    loadsymbol(ThreadContext *tc)
1472358SN/A    {
1483126Sktlim@umich.edu        const string &filename = tc->getCpuPtr()->system->params()->symbolfile;
1492358SN/A        if (filename.empty()) {
1502358SN/A            return;
1512358SN/A        }
1522358SN/A
1532358SN/A        std::string buffer;
1542358SN/A        ifstream file(filename.c_str());
1552358SN/A
1562358SN/A        if (!file)
1572358SN/A            fatal("file error: Can't open symbol table file %s\n", filename);
1582358SN/A
1592358SN/A        while (!file.eof()) {
1602358SN/A            getline(file, buffer);
1612358SN/A
1622358SN/A            if (buffer.empty())
1632358SN/A                continue;
1642358SN/A
1652358SN/A            int idx = buffer.find(' ');
1662358SN/A            if (idx == string::npos)
1672358SN/A                continue;
1682358SN/A
1692358SN/A            string address = "0x" + buffer.substr(0, idx);
1702358SN/A            eat_white(address);
1712358SN/A            if (address.empty())
1722358SN/A                continue;
1732358SN/A
1742358SN/A            // Skip over letter and space
1752358SN/A            string symbol = buffer.substr(idx + 3);
1762358SN/A            eat_white(symbol);
1772358SN/A            if (symbol.empty())
1782358SN/A                continue;
1792358SN/A
1802358SN/A            Addr addr;
1812358SN/A            if (!to_number(address, addr))
1822358SN/A                continue;
1832358SN/A
1843126Sktlim@umich.edu            if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol))
1852358SN/A                continue;
1862358SN/A
1872358SN/A
1882358SN/A            DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
1892358SN/A        }
1902358SN/A        file.close();
1912358SN/A    }
1922358SN/A
1932358SN/A    void
1942680Sktlim@umich.edu    resetstats(ThreadContext *tc, Tick delay, Tick period)
195298SN/A    {
1963617Sbinkertn@umich.edu        if (!tc->getCpuPtr()->params->do_statistics_insts)
197299SN/A            return;
198299SN/A
199298SN/A
2001609SN/A        Tick when = curTick + delay * Clock::Int::ns;
2011609SN/A        Tick repeat = period * Clock::Int::ns;
202298SN/A
2034078Sbinkertn@umich.edu        Stats::StatEvent(false, true, when, repeat);
204298SN/A    }
205298SN/A
206298SN/A    void
2072680Sktlim@umich.edu    dumpstats(ThreadContext *tc, Tick delay, Tick period)
208298SN/A    {
2093617Sbinkertn@umich.edu        if (!tc->getCpuPtr()->params->do_statistics_insts)
210299SN/A            return;
211299SN/A
212298SN/A
2131609SN/A        Tick when = curTick + delay * Clock::Int::ns;
2141609SN/A        Tick repeat = period * Clock::Int::ns;
215298SN/A
2164078Sbinkertn@umich.edu        Stats::StatEvent(true, false, when, repeat);
217298SN/A    }
218298SN/A
219298SN/A    void
2202680Sktlim@umich.edu    addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr)
2211973SN/A    {
2221973SN/A        char symb[100];
2232680Sktlim@umich.edu        CopyStringOut(tc, symb, symbolAddr, 100);
2241973SN/A        std::string symbol(symb);
2251973SN/A
2261973SN/A        DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
2271973SN/A
2282680Sktlim@umich.edu        tc->getSystemPtr()->kernelSymtab->insert(addr,symbol);
2291973SN/A    }
2301973SN/A
2311973SN/A    void
2323089Ssaidi@eecs.umich.edu    anBegin(ThreadContext *tc, uint64_t cur)
2333089Ssaidi@eecs.umich.edu    {
2343089Ssaidi@eecs.umich.edu        Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur &
2353089Ssaidi@eecs.umich.edu                0xFFFFFFFF, 0,0);
2363089Ssaidi@eecs.umich.edu    }
2373089Ssaidi@eecs.umich.edu
2383089Ssaidi@eecs.umich.edu    void
2393089Ssaidi@eecs.umich.edu    anWait(ThreadContext *tc, uint64_t cur, uint64_t wait)
2403089Ssaidi@eecs.umich.edu    {
2413089Ssaidi@eecs.umich.edu        Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur &
2423089Ssaidi@eecs.umich.edu                0xFFFFFFFF, wait >> 32, wait & 0xFFFFFFFF);
2433089Ssaidi@eecs.umich.edu    }
2443089Ssaidi@eecs.umich.edu
2453089Ssaidi@eecs.umich.edu
2463089Ssaidi@eecs.umich.edu    void
2472680Sktlim@umich.edu    dumpresetstats(ThreadContext *tc, Tick delay, Tick period)
248298SN/A    {
2493617Sbinkertn@umich.edu        if (!tc->getCpuPtr()->params->do_statistics_insts)
250299SN/A            return;
251299SN/A
252298SN/A
2531609SN/A        Tick when = curTick + delay * Clock::Int::ns;
2541609SN/A        Tick repeat = period * Clock::Int::ns;
255298SN/A
2564078Sbinkertn@umich.edu        Stats::StatEvent(true, true, when, repeat);
257298SN/A    }
258298SN/A
259298SN/A    void
2602680Sktlim@umich.edu    m5checkpoint(ThreadContext *tc, Tick delay, Tick period)
261298SN/A    {
2623617Sbinkertn@umich.edu        if (!tc->getCpuPtr()->params->do_checkpoint_insts)
263299SN/A            return;
2643144Shsul@eecs.umich.edu
2653144Shsul@eecs.umich.edu        Tick when = curTick + delay * Clock::Int::ns;
2663144Shsul@eecs.umich.edu        Tick repeat = period * Clock::Int::ns;
2673144Shsul@eecs.umich.edu
2683144Shsul@eecs.umich.edu        schedExitSimLoop("checkpoint", when, repeat);
269298SN/A    }
270298SN/A
2712081SN/A    uint64_t
2722680Sktlim@umich.edu    readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset)
273954SN/A    {
2743617Sbinkertn@umich.edu        const string &file = tc->getSystemPtr()->params()->readfile;
275954SN/A        if (file.empty()) {
2762081SN/A            return ULL(0);
277954SN/A        }
278954SN/A
279954SN/A        uint64_t result = 0;
280954SN/A
281954SN/A        int fd = ::open(file.c_str(), O_RDONLY, 0);
282954SN/A        if (fd < 0)
283954SN/A            panic("could not open file %s\n", file);
284954SN/A
2851642SN/A        if (::lseek(fd, offset, SEEK_SET) < 0)
2861642SN/A            panic("could not seek: %s", strerror(errno));
2871642SN/A
288954SN/A        char *buf = new char[len];
289954SN/A        char *p = buf;
290954SN/A        while (len > 0) {
2911642SN/A            int bytes = ::read(fd, p, len);
292954SN/A            if (bytes <= 0)
293954SN/A                break;
294954SN/A
295954SN/A            p += bytes;
296954SN/A            result += bytes;
297954SN/A            len -= bytes;
298954SN/A        }
299954SN/A
300954SN/A        close(fd);
3012680Sktlim@umich.edu        CopyIn(tc, vaddr, buf, result);
302954SN/A        delete [] buf;
3032081SN/A        return result;
304954SN/A    }
305954SN/A
3062680Sktlim@umich.edu    void debugbreak(ThreadContext *tc)
3071052SN/A    {
3081052SN/A        debug_break();
3091052SN/A    }
3101052SN/A
3112680Sktlim@umich.edu    void switchcpu(ThreadContext *tc)
3121052SN/A    {
3132841Sktlim@umich.edu        exitSimLoop("switchcpu");
3141052SN/A    }
315298SN/A}
316