pseudo_inst.cc revision 3373
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
35299SN/A#include <string>
36299SN/A
372081SN/A#include "sim/pseudo_inst.hh"
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"
431070SN/A#include "kern/kernel_stats.hh"
44299SN/A#include "sim/param.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{
60299SN/A    bool doStatisticsInsts;
61299SN/A    bool doCheckpointInsts;
62310SN/A    bool doQuiesce;
63310SN/A
64310SN/A    void
652680Sktlim@umich.edu    arm(ThreadContext *tc)
66711SN/A    {
672680Sktlim@umich.edu        if (tc->getKernelStats())
682680Sktlim@umich.edu            tc->getKernelStats()->arm();
69711SN/A    }
70711SN/A
71711SN/A    void
722680Sktlim@umich.edu    quiesce(ThreadContext *tc)
73310SN/A    {
74310SN/A        if (!doQuiesce)
75310SN/A            return;
76310SN/A
773373Sstever@eecs.umich.edu        DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name());
783373Sstever@eecs.umich.edu
792680Sktlim@umich.edu        tc->suspend();
802680Sktlim@umich.edu        if (tc->getKernelStats())
812680Sktlim@umich.edu            tc->getKernelStats()->quiesce();
82310SN/A    }
83299SN/A
84298SN/A    void
852680Sktlim@umich.edu    quiesceNs(ThreadContext *tc, uint64_t ns)
862188SN/A    {
872188SN/A        if (!doQuiesce || ns == 0)
882188SN/A            return;
892188SN/A
902680Sktlim@umich.edu        EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
912235SN/A
923368Sstever@eecs.umich.edu        Tick resume = curTick + Clock::Int::ns * ns;
933368Sstever@eecs.umich.edu
942235SN/A        if (quiesceEvent->scheduled())
953368Sstever@eecs.umich.edu            quiesceEvent->reschedule(resume);
962188SN/A        else
973368Sstever@eecs.umich.edu            quiesceEvent->schedule(resume);
983368Sstever@eecs.umich.edu
993368Sstever@eecs.umich.edu        DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n",
1003368Sstever@eecs.umich.edu                tc->getCpuPtr()->name(), ns, resume);
1012188SN/A
1022680Sktlim@umich.edu        tc->suspend();
1032680Sktlim@umich.edu        if (tc->getKernelStats())
1042680Sktlim@umich.edu            tc->getKernelStats()->quiesce();
1052188SN/A    }
1062188SN/A
1072188SN/A    void
1082680Sktlim@umich.edu    quiesceCycles(ThreadContext *tc, uint64_t cycles)
1092188SN/A    {
1102188SN/A        if (!doQuiesce || cycles == 0)
1112188SN/A            return;
1122188SN/A
1132680Sktlim@umich.edu        EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
1142235SN/A
1153368Sstever@eecs.umich.edu        Tick resume = curTick + tc->getCpuPtr()->cycles(cycles);
1163368Sstever@eecs.umich.edu
1172235SN/A        if (quiesceEvent->scheduled())
1183368Sstever@eecs.umich.edu            quiesceEvent->reschedule(resume);
1192188SN/A        else
1203368Sstever@eecs.umich.edu            quiesceEvent->schedule(resume);
1213368Sstever@eecs.umich.edu
1223368Sstever@eecs.umich.edu        DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n",
1233368Sstever@eecs.umich.edu                tc->getCpuPtr()->name(), cycles, resume);
1242188SN/A
1252680Sktlim@umich.edu        tc->suspend();
1262680Sktlim@umich.edu        if (tc->getKernelStats())
1272680Sktlim@umich.edu            tc->getKernelStats()->quiesce();
1282188SN/A    }
1292188SN/A
1302188SN/A    uint64_t
1312680Sktlim@umich.edu    quiesceTime(ThreadContext *tc)
1322188SN/A    {
1332680Sktlim@umich.edu        return (tc->readLastActivate() - tc->readLastSuspend()) / Clock::Int::ns;
1342188SN/A    }
1352188SN/A
1362188SN/A    void
1372680Sktlim@umich.edu    ivlb(ThreadContext *tc)
138711SN/A    {
1392680Sktlim@umich.edu        if (tc->getKernelStats())
1402680Sktlim@umich.edu            tc->getKernelStats()->ivlb();
141711SN/A    }
142711SN/A
143711SN/A    void
1442680Sktlim@umich.edu    ivle(ThreadContext *tc)
145711SN/A    {
146711SN/A    }
147711SN/A
148711SN/A    void
1492680Sktlim@umich.edu    m5exit_old(ThreadContext *tc)
150298SN/A    {
1513144Shsul@eecs.umich.edu        exitSimLoop("m5_exit_old instruction encountered");
152298SN/A    }
153298SN/A
154298SN/A    void
1552680Sktlim@umich.edu    m5exit(ThreadContext *tc, Tick delay)
156298SN/A    {
1571609SN/A        Tick when = curTick + delay * Clock::Int::ns;
1583144Shsul@eecs.umich.edu        schedExitSimLoop("m5_exit instruction encountered", when);
159298SN/A    }
160298SN/A
161298SN/A    void
1623126Sktlim@umich.edu    loadsymbol(ThreadContext *tc)
1632358SN/A    {
1643126Sktlim@umich.edu        const string &filename = tc->getCpuPtr()->system->params()->symbolfile;
1652358SN/A        if (filename.empty()) {
1662358SN/A            return;
1672358SN/A        }
1682358SN/A
1692358SN/A        std::string buffer;
1702358SN/A        ifstream file(filename.c_str());
1712358SN/A
1722358SN/A        if (!file)
1732358SN/A            fatal("file error: Can't open symbol table file %s\n", filename);
1742358SN/A
1752358SN/A        while (!file.eof()) {
1762358SN/A            getline(file, buffer);
1772358SN/A
1782358SN/A            if (buffer.empty())
1792358SN/A                continue;
1802358SN/A
1812358SN/A            int idx = buffer.find(' ');
1822358SN/A            if (idx == string::npos)
1832358SN/A                continue;
1842358SN/A
1852358SN/A            string address = "0x" + buffer.substr(0, idx);
1862358SN/A            eat_white(address);
1872358SN/A            if (address.empty())
1882358SN/A                continue;
1892358SN/A
1902358SN/A            // Skip over letter and space
1912358SN/A            string symbol = buffer.substr(idx + 3);
1922358SN/A            eat_white(symbol);
1932358SN/A            if (symbol.empty())
1942358SN/A                continue;
1952358SN/A
1962358SN/A            Addr addr;
1972358SN/A            if (!to_number(address, addr))
1982358SN/A                continue;
1992358SN/A
2003126Sktlim@umich.edu            if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol))
2012358SN/A                continue;
2022358SN/A
2032358SN/A
2042358SN/A            DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
2052358SN/A        }
2062358SN/A        file.close();
2072358SN/A    }
2082358SN/A
2092358SN/A    void
2102680Sktlim@umich.edu    resetstats(ThreadContext *tc, Tick delay, Tick period)
211298SN/A    {
212299SN/A        if (!doStatisticsInsts)
213299SN/A            return;
214299SN/A
215298SN/A
2161609SN/A        Tick when = curTick + delay * Clock::Int::ns;
2171609SN/A        Tick repeat = period * Clock::Int::ns;
218298SN/A
219729SN/A        using namespace Stats;
220298SN/A        SetupEvent(Reset, when, repeat);
221298SN/A    }
222298SN/A
223298SN/A    void
2242680Sktlim@umich.edu    dumpstats(ThreadContext *tc, Tick delay, Tick period)
225298SN/A    {
226299SN/A        if (!doStatisticsInsts)
227299SN/A            return;
228299SN/A
229298SN/A
2301609SN/A        Tick when = curTick + delay * Clock::Int::ns;
2311609SN/A        Tick repeat = period * Clock::Int::ns;
232298SN/A
233729SN/A        using namespace Stats;
234298SN/A        SetupEvent(Dump, when, repeat);
235298SN/A    }
236298SN/A
237298SN/A    void
2382680Sktlim@umich.edu    addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr)
2391973SN/A    {
2401973SN/A        char symb[100];
2412680Sktlim@umich.edu        CopyStringOut(tc, symb, symbolAddr, 100);
2421973SN/A        std::string symbol(symb);
2431973SN/A
2441973SN/A        DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
2451973SN/A
2462680Sktlim@umich.edu        tc->getSystemPtr()->kernelSymtab->insert(addr,symbol);
2471973SN/A    }
2481973SN/A
2491973SN/A    void
2503089Ssaidi@eecs.umich.edu    anBegin(ThreadContext *tc, uint64_t cur)
2513089Ssaidi@eecs.umich.edu    {
2523089Ssaidi@eecs.umich.edu        Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur &
2533089Ssaidi@eecs.umich.edu                0xFFFFFFFF, 0,0);
2543089Ssaidi@eecs.umich.edu    }
2553089Ssaidi@eecs.umich.edu
2563089Ssaidi@eecs.umich.edu    void
2573089Ssaidi@eecs.umich.edu    anWait(ThreadContext *tc, uint64_t cur, uint64_t wait)
2583089Ssaidi@eecs.umich.edu    {
2593089Ssaidi@eecs.umich.edu        Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur &
2603089Ssaidi@eecs.umich.edu                0xFFFFFFFF, wait >> 32, wait & 0xFFFFFFFF);
2613089Ssaidi@eecs.umich.edu    }
2623089Ssaidi@eecs.umich.edu
2633089Ssaidi@eecs.umich.edu
2643089Ssaidi@eecs.umich.edu    void
2652680Sktlim@umich.edu    dumpresetstats(ThreadContext *tc, Tick delay, Tick period)
266298SN/A    {
267299SN/A        if (!doStatisticsInsts)
268299SN/A            return;
269299SN/A
270298SN/A
2711609SN/A        Tick when = curTick + delay * Clock::Int::ns;
2721609SN/A        Tick repeat = period * Clock::Int::ns;
273298SN/A
274729SN/A        using namespace Stats;
275298SN/A        SetupEvent(Dump|Reset, when, repeat);
276298SN/A    }
277298SN/A
278298SN/A    void
2792680Sktlim@umich.edu    m5checkpoint(ThreadContext *tc, Tick delay, Tick period)
280298SN/A    {
281299SN/A        if (!doCheckpointInsts)
282299SN/A            return;
2833144Shsul@eecs.umich.edu
2843144Shsul@eecs.umich.edu        Tick when = curTick + delay * Clock::Int::ns;
2853144Shsul@eecs.umich.edu        Tick repeat = period * Clock::Int::ns;
2863144Shsul@eecs.umich.edu
2873144Shsul@eecs.umich.edu        schedExitSimLoop("checkpoint", when, repeat);
288298SN/A    }
289298SN/A
2902081SN/A    uint64_t
2912680Sktlim@umich.edu    readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset)
292954SN/A    {
2932680Sktlim@umich.edu        const string &file = tc->getCpuPtr()->system->params()->readfile;
294954SN/A        if (file.empty()) {
2952081SN/A            return ULL(0);
296954SN/A        }
297954SN/A
298954SN/A        uint64_t result = 0;
299954SN/A
300954SN/A        int fd = ::open(file.c_str(), O_RDONLY, 0);
301954SN/A        if (fd < 0)
302954SN/A            panic("could not open file %s\n", file);
303954SN/A
3041642SN/A        if (::lseek(fd, offset, SEEK_SET) < 0)
3051642SN/A            panic("could not seek: %s", strerror(errno));
3061642SN/A
307954SN/A        char *buf = new char[len];
308954SN/A        char *p = buf;
309954SN/A        while (len > 0) {
3101642SN/A            int bytes = ::read(fd, p, len);
311954SN/A            if (bytes <= 0)
312954SN/A                break;
313954SN/A
314954SN/A            p += bytes;
315954SN/A            result += bytes;
316954SN/A            len -= bytes;
317954SN/A        }
318954SN/A
319954SN/A        close(fd);
3202680Sktlim@umich.edu        CopyIn(tc, vaddr, buf, result);
321954SN/A        delete [] buf;
3222081SN/A        return result;
323954SN/A    }
324954SN/A
325299SN/A    class Context : public ParamContext
326299SN/A    {
327299SN/A      public:
328299SN/A        Context(const string &section) : ParamContext(section) {}
329299SN/A        void checkParams();
330299SN/A    };
331299SN/A
3321343SN/A    Context context("pseudo_inst");
333299SN/A
334310SN/A    Param<bool> __quiesce(&context, "quiesce",
335310SN/A                          "enable quiesce instructions",
336310SN/A                          true);
337300SN/A    Param<bool> __statistics(&context, "statistics",
338310SN/A                             "enable statistics pseudo instructions",
339301SN/A                             true);
340300SN/A    Param<bool> __checkpoint(&context, "checkpoint",
341310SN/A                             "enable checkpoint pseudo instructions",
342301SN/A                             true);
343299SN/A
344299SN/A    void
345299SN/A    Context::checkParams()
346299SN/A    {
347310SN/A        doQuiesce = __quiesce;
348299SN/A        doStatisticsInsts = __statistics;
349299SN/A        doCheckpointInsts = __checkpoint;
350299SN/A    }
3511052SN/A
3522680Sktlim@umich.edu    void debugbreak(ThreadContext *tc)
3531052SN/A    {
3541052SN/A        debug_break();
3551052SN/A    }
3561052SN/A
3572680Sktlim@umich.edu    void switchcpu(ThreadContext *tc)
3581052SN/A    {
3592841Sktlim@umich.edu        exitSimLoop("switchcpu");
3601052SN/A    }
361298SN/A}
362