pseudo_inst.cc revision 2680
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
551752SN/Aextern Sampler *SampCPU;
561052SN/A
57729SN/Ausing namespace Stats;
582107SN/Ausing namespace TheISA;
59298SN/A
60298SN/Anamespace AlphaPseudo
61298SN/A{
62299SN/A    bool doStatisticsInsts;
63299SN/A    bool doCheckpointInsts;
64310SN/A    bool doQuiesce;
65310SN/A
66310SN/A    void
672680Sktlim@umich.edu    arm(ThreadContext *tc)
68711SN/A    {
692680Sktlim@umich.edu        if (tc->getKernelStats())
702680Sktlim@umich.edu            tc->getKernelStats()->arm();
71711SN/A    }
72711SN/A
73711SN/A    void
742680Sktlim@umich.edu    quiesce(ThreadContext *tc)
75310SN/A    {
76310SN/A        if (!doQuiesce)
77310SN/A            return;
78310SN/A
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
922235SN/A        if (quiesceEvent->scheduled())
932235SN/A            quiesceEvent->reschedule(curTick + Clock::Int::ns * ns);
942188SN/A        else
952235SN/A            quiesceEvent->schedule(curTick + Clock::Int::ns * ns);
962188SN/A
972680Sktlim@umich.edu        tc->suspend();
982680Sktlim@umich.edu        if (tc->getKernelStats())
992680Sktlim@umich.edu            tc->getKernelStats()->quiesce();
1002188SN/A    }
1012188SN/A
1022188SN/A    void
1032680Sktlim@umich.edu    quiesceCycles(ThreadContext *tc, uint64_t cycles)
1042188SN/A    {
1052188SN/A        if (!doQuiesce || cycles == 0)
1062188SN/A            return;
1072188SN/A
1082680Sktlim@umich.edu        EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
1092235SN/A
1102235SN/A        if (quiesceEvent->scheduled())
1112235SN/A            quiesceEvent->reschedule(curTick +
1122680Sktlim@umich.edu                                     tc->getCpuPtr()->cycles(cycles));
1132188SN/A        else
1142235SN/A            quiesceEvent->schedule(curTick +
1152680Sktlim@umich.edu                                   tc->getCpuPtr()->cycles(cycles));
1162188SN/A
1172680Sktlim@umich.edu        tc->suspend();
1182680Sktlim@umich.edu        if (tc->getKernelStats())
1192680Sktlim@umich.edu            tc->getKernelStats()->quiesce();
1202188SN/A    }
1212188SN/A
1222188SN/A    uint64_t
1232680Sktlim@umich.edu    quiesceTime(ThreadContext *tc)
1242188SN/A    {
1252680Sktlim@umich.edu        return (tc->readLastActivate() - tc->readLastSuspend()) / Clock::Int::ns;
1262188SN/A    }
1272188SN/A
1282188SN/A    void
1292680Sktlim@umich.edu    ivlb(ThreadContext *tc)
130711SN/A    {
1312680Sktlim@umich.edu        if (tc->getKernelStats())
1322680Sktlim@umich.edu            tc->getKernelStats()->ivlb();
133711SN/A    }
134711SN/A
135711SN/A    void
1362680Sktlim@umich.edu    ivle(ThreadContext *tc)
137711SN/A    {
138711SN/A    }
139711SN/A
140711SN/A    void
1412680Sktlim@umich.edu    m5exit_old(ThreadContext *tc)
142298SN/A    {
143298SN/A        SimExit(curTick, "m5_exit_old instruction encountered");
144298SN/A    }
145298SN/A
146298SN/A    void
1472680Sktlim@umich.edu    m5exit(ThreadContext *tc, Tick delay)
148298SN/A    {
1491609SN/A        Tick when = curTick + delay * Clock::Int::ns;
150298SN/A        SimExit(when, "m5_exit instruction encountered");
151298SN/A    }
152298SN/A
153298SN/A    void
1542680Sktlim@umich.edu    resetstats(ThreadContext *tc, Tick delay, Tick period)
155298SN/A    {
156299SN/A        if (!doStatisticsInsts)
157299SN/A            return;
158299SN/A
159298SN/A
1601609SN/A        Tick when = curTick + delay * Clock::Int::ns;
1611609SN/A        Tick repeat = period * Clock::Int::ns;
162298SN/A
163729SN/A        using namespace Stats;
164298SN/A        SetupEvent(Reset, when, repeat);
165298SN/A    }
166298SN/A
167298SN/A    void
1682680Sktlim@umich.edu    dumpstats(ThreadContext *tc, Tick delay, Tick period)
169298SN/A    {
170299SN/A        if (!doStatisticsInsts)
171299SN/A            return;
172299SN/A
173298SN/A
1741609SN/A        Tick when = curTick + delay * Clock::Int::ns;
1751609SN/A        Tick repeat = period * Clock::Int::ns;
176298SN/A
177729SN/A        using namespace Stats;
178298SN/A        SetupEvent(Dump, when, repeat);
179298SN/A    }
180298SN/A
181298SN/A    void
1822680Sktlim@umich.edu    addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr)
1831973SN/A    {
1841973SN/A        char symb[100];
1852680Sktlim@umich.edu        CopyStringOut(tc, symb, symbolAddr, 100);
1861973SN/A        std::string symbol(symb);
1871973SN/A
1881973SN/A        DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
1891973SN/A
1902680Sktlim@umich.edu        tc->getSystemPtr()->kernelSymtab->insert(addr,symbol);
1911973SN/A    }
1921973SN/A
1931973SN/A    void
1942680Sktlim@umich.edu    dumpresetstats(ThreadContext *tc, Tick delay, Tick period)
195298SN/A    {
196299SN/A        if (!doStatisticsInsts)
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
203729SN/A        using namespace Stats;
204298SN/A        SetupEvent(Dump|Reset, when, repeat);
205298SN/A    }
206298SN/A
207298SN/A    void
2082680Sktlim@umich.edu    m5checkpoint(ThreadContext *tc, Tick delay, Tick period)
209298SN/A    {
210299SN/A        if (!doCheckpointInsts)
211299SN/A            return;
212299SN/A
213298SN/A
2141609SN/A        Tick when = curTick + delay * Clock::Int::ns;
2151609SN/A        Tick repeat = period * Clock::Int::ns;
216298SN/A
217449SN/A        Checkpoint::setup(when, repeat);
218298SN/A    }
219298SN/A
2202081SN/A    uint64_t
2212680Sktlim@umich.edu    readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset)
222954SN/A    {
2232680Sktlim@umich.edu        const string &file = tc->getCpuPtr()->system->params()->readfile;
224954SN/A        if (file.empty()) {
2252081SN/A            return ULL(0);
226954SN/A        }
227954SN/A
228954SN/A        uint64_t result = 0;
229954SN/A
230954SN/A        int fd = ::open(file.c_str(), O_RDONLY, 0);
231954SN/A        if (fd < 0)
232954SN/A            panic("could not open file %s\n", file);
233954SN/A
2341642SN/A        if (::lseek(fd, offset, SEEK_SET) < 0)
2351642SN/A            panic("could not seek: %s", strerror(errno));
2361642SN/A
237954SN/A        char *buf = new char[len];
238954SN/A        char *p = buf;
239954SN/A        while (len > 0) {
2401642SN/A            int bytes = ::read(fd, p, len);
241954SN/A            if (bytes <= 0)
242954SN/A                break;
243954SN/A
244954SN/A            p += bytes;
245954SN/A            result += bytes;
246954SN/A            len -= bytes;
247954SN/A        }
248954SN/A
249954SN/A        close(fd);
2502680Sktlim@umich.edu        CopyIn(tc, vaddr, buf, result);
251954SN/A        delete [] buf;
2522081SN/A        return result;
253954SN/A    }
254954SN/A
255299SN/A    class Context : public ParamContext
256299SN/A    {
257299SN/A      public:
258299SN/A        Context(const string &section) : ParamContext(section) {}
259299SN/A        void checkParams();
260299SN/A    };
261299SN/A
2621343SN/A    Context context("pseudo_inst");
263299SN/A
264310SN/A    Param<bool> __quiesce(&context, "quiesce",
265310SN/A                          "enable quiesce instructions",
266310SN/A                          true);
267300SN/A    Param<bool> __statistics(&context, "statistics",
268310SN/A                             "enable statistics pseudo instructions",
269301SN/A                             true);
270300SN/A    Param<bool> __checkpoint(&context, "checkpoint",
271310SN/A                             "enable checkpoint pseudo instructions",
272301SN/A                             true);
273299SN/A
274299SN/A    void
275299SN/A    Context::checkParams()
276299SN/A    {
277310SN/A        doQuiesce = __quiesce;
278299SN/A        doStatisticsInsts = __statistics;
279299SN/A        doCheckpointInsts = __checkpoint;
280299SN/A    }
2811052SN/A
2822680Sktlim@umich.edu    void debugbreak(ThreadContext *tc)
2831052SN/A    {
2841052SN/A        debug_break();
2851052SN/A    }
2861052SN/A
2872680Sktlim@umich.edu    void switchcpu(ThreadContext *tc)
2881052SN/A    {
2891052SN/A        if (SampCPU)
2901052SN/A            SampCPU->switchCPUs();
2911052SN/A    }
292298SN/A}
293