pseudo_inst.cc revision 2841
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"
391717SN/A#include "cpu/base.hh"
401717SN/A#include "cpu/sampler/sampler.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
772680Sktlim@umich.edu        tc->suspend();
782680Sktlim@umich.edu        if (tc->getKernelStats())
792680Sktlim@umich.edu            tc->getKernelStats()->quiesce();
80310SN/A    }
81299SN/A
82298SN/A    void
832680Sktlim@umich.edu    quiesceNs(ThreadContext *tc, uint64_t ns)
842188SN/A    {
852188SN/A        if (!doQuiesce || ns == 0)
862188SN/A            return;
872188SN/A
882680Sktlim@umich.edu        EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
892235SN/A
902235SN/A        if (quiesceEvent->scheduled())
912235SN/A            quiesceEvent->reschedule(curTick + Clock::Int::ns * ns);
922188SN/A        else
932235SN/A            quiesceEvent->schedule(curTick + Clock::Int::ns * ns);
942188SN/A
952680Sktlim@umich.edu        tc->suspend();
962680Sktlim@umich.edu        if (tc->getKernelStats())
972680Sktlim@umich.edu            tc->getKernelStats()->quiesce();
982188SN/A    }
992188SN/A
1002188SN/A    void
1012680Sktlim@umich.edu    quiesceCycles(ThreadContext *tc, uint64_t cycles)
1022188SN/A    {
1032188SN/A        if (!doQuiesce || cycles == 0)
1042188SN/A            return;
1052188SN/A
1062680Sktlim@umich.edu        EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
1072235SN/A
1082235SN/A        if (quiesceEvent->scheduled())
1092235SN/A            quiesceEvent->reschedule(curTick +
1102680Sktlim@umich.edu                                     tc->getCpuPtr()->cycles(cycles));
1112188SN/A        else
1122235SN/A            quiesceEvent->schedule(curTick +
1132680Sktlim@umich.edu                                   tc->getCpuPtr()->cycles(cycles));
1142188SN/A
1152680Sktlim@umich.edu        tc->suspend();
1162680Sktlim@umich.edu        if (tc->getKernelStats())
1172680Sktlim@umich.edu            tc->getKernelStats()->quiesce();
1182188SN/A    }
1192188SN/A
1202188SN/A    uint64_t
1212680Sktlim@umich.edu    quiesceTime(ThreadContext *tc)
1222188SN/A    {
1232680Sktlim@umich.edu        return (tc->readLastActivate() - tc->readLastSuspend()) / Clock::Int::ns;
1242188SN/A    }
1252188SN/A
1262188SN/A    void
1272680Sktlim@umich.edu    ivlb(ThreadContext *tc)
128711SN/A    {
1292680Sktlim@umich.edu        if (tc->getKernelStats())
1302680Sktlim@umich.edu            tc->getKernelStats()->ivlb();
131711SN/A    }
132711SN/A
133711SN/A    void
1342680Sktlim@umich.edu    ivle(ThreadContext *tc)
135711SN/A    {
136711SN/A    }
137711SN/A
138711SN/A    void
1392680Sktlim@umich.edu    m5exit_old(ThreadContext *tc)
140298SN/A    {
1412667Sstever@eecs.umich.edu        exitSimLoop(curTick, "m5_exit_old instruction encountered");
142298SN/A    }
143298SN/A
144298SN/A    void
1452680Sktlim@umich.edu    m5exit(ThreadContext *tc, Tick delay)
146298SN/A    {
1471609SN/A        Tick when = curTick + delay * Clock::Int::ns;
1482667Sstever@eecs.umich.edu        exitSimLoop(when, "m5_exit instruction encountered");
149298SN/A    }
150298SN/A
151298SN/A    void
1522680Sktlim@umich.edu    resetstats(ThreadContext *tc, Tick delay, Tick period)
153298SN/A    {
154299SN/A        if (!doStatisticsInsts)
155299SN/A            return;
156299SN/A
157298SN/A
1581609SN/A        Tick when = curTick + delay * Clock::Int::ns;
1591609SN/A        Tick repeat = period * Clock::Int::ns;
160298SN/A
161729SN/A        using namespace Stats;
162298SN/A        SetupEvent(Reset, when, repeat);
163298SN/A    }
164298SN/A
165298SN/A    void
1662680Sktlim@umich.edu    dumpstats(ThreadContext *tc, Tick delay, Tick period)
167298SN/A    {
168299SN/A        if (!doStatisticsInsts)
169299SN/A            return;
170299SN/A
171298SN/A
1721609SN/A        Tick when = curTick + delay * Clock::Int::ns;
1731609SN/A        Tick repeat = period * Clock::Int::ns;
174298SN/A
175729SN/A        using namespace Stats;
176298SN/A        SetupEvent(Dump, when, repeat);
177298SN/A    }
178298SN/A
179298SN/A    void
1802680Sktlim@umich.edu    addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr)
1811973SN/A    {
1821973SN/A        char symb[100];
1832680Sktlim@umich.edu        CopyStringOut(tc, symb, symbolAddr, 100);
1841973SN/A        std::string symbol(symb);
1851973SN/A
1861973SN/A        DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
1871973SN/A
1882680Sktlim@umich.edu        tc->getSystemPtr()->kernelSymtab->insert(addr,symbol);
1891973SN/A    }
1901973SN/A
1911973SN/A    void
1922680Sktlim@umich.edu    dumpresetstats(ThreadContext *tc, Tick delay, Tick period)
193298SN/A    {
194299SN/A        if (!doStatisticsInsts)
195299SN/A            return;
196299SN/A
197298SN/A
1981609SN/A        Tick when = curTick + delay * Clock::Int::ns;
1991609SN/A        Tick repeat = period * Clock::Int::ns;
200298SN/A
201729SN/A        using namespace Stats;
202298SN/A        SetupEvent(Dump|Reset, when, repeat);
203298SN/A    }
204298SN/A
205298SN/A    void
2062680Sktlim@umich.edu    m5checkpoint(ThreadContext *tc, Tick delay, Tick period)
207298SN/A    {
208299SN/A        if (!doCheckpointInsts)
209299SN/A            return;
2102841Sktlim@umich.edu        exitSimLoop("checkpoint");
211298SN/A    }
212298SN/A
2132081SN/A    uint64_t
2142680Sktlim@umich.edu    readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset)
215954SN/A    {
2162680Sktlim@umich.edu        const string &file = tc->getCpuPtr()->system->params()->readfile;
217954SN/A        if (file.empty()) {
2182081SN/A            return ULL(0);
219954SN/A        }
220954SN/A
221954SN/A        uint64_t result = 0;
222954SN/A
223954SN/A        int fd = ::open(file.c_str(), O_RDONLY, 0);
224954SN/A        if (fd < 0)
225954SN/A            panic("could not open file %s\n", file);
226954SN/A
2271642SN/A        if (::lseek(fd, offset, SEEK_SET) < 0)
2281642SN/A            panic("could not seek: %s", strerror(errno));
2291642SN/A
230954SN/A        char *buf = new char[len];
231954SN/A        char *p = buf;
232954SN/A        while (len > 0) {
2331642SN/A            int bytes = ::read(fd, p, len);
234954SN/A            if (bytes <= 0)
235954SN/A                break;
236954SN/A
237954SN/A            p += bytes;
238954SN/A            result += bytes;
239954SN/A            len -= bytes;
240954SN/A        }
241954SN/A
242954SN/A        close(fd);
2432680Sktlim@umich.edu        CopyIn(tc, vaddr, buf, result);
244954SN/A        delete [] buf;
2452081SN/A        return result;
246954SN/A    }
247954SN/A
248299SN/A    class Context : public ParamContext
249299SN/A    {
250299SN/A      public:
251299SN/A        Context(const string &section) : ParamContext(section) {}
252299SN/A        void checkParams();
253299SN/A    };
254299SN/A
2551343SN/A    Context context("pseudo_inst");
256299SN/A
257310SN/A    Param<bool> __quiesce(&context, "quiesce",
258310SN/A                          "enable quiesce instructions",
259310SN/A                          true);
260300SN/A    Param<bool> __statistics(&context, "statistics",
261310SN/A                             "enable statistics pseudo instructions",
262301SN/A                             true);
263300SN/A    Param<bool> __checkpoint(&context, "checkpoint",
264310SN/A                             "enable checkpoint pseudo instructions",
265301SN/A                             true);
266299SN/A
267299SN/A    void
268299SN/A    Context::checkParams()
269299SN/A    {
270310SN/A        doQuiesce = __quiesce;
271299SN/A        doStatisticsInsts = __statistics;
272299SN/A        doCheckpointInsts = __checkpoint;
273299SN/A    }
2741052SN/A
2752680Sktlim@umich.edu    void debugbreak(ThreadContext *tc)
2761052SN/A    {
2771052SN/A        debug_break();
2781052SN/A    }
2791052SN/A
2802680Sktlim@umich.edu    void switchcpu(ThreadContext *tc)
2811052SN/A    {
2822841Sktlim@umich.edu        exitSimLoop("switchcpu");
2831052SN/A    }
284298SN/A}
285