pseudo_inst.cc revision 2667
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"
41298SN/A#include "cpu/exec_context.hh"
421070SN/A#include "kern/kernel_stats.hh"
43299SN/A#include "sim/param.hh"
44298SN/A#include "sim/serialize.hh"
45298SN/A#include "sim/sim_exit.hh"
46695SN/A#include "sim/stat_control.hh"
47695SN/A#include "sim/stats.hh"
48954SN/A#include "sim/system.hh"
491052SN/A#include "sim/debug.hh"
502080SN/A#include "sim/vptr.hh"
51298SN/A
52299SN/Ausing namespace std;
531052SN/A
541752SN/Aextern Sampler *SampCPU;
551052SN/A
56729SN/Ausing namespace Stats;
572107SN/Ausing namespace TheISA;
58298SN/A
59298SN/Anamespace AlphaPseudo
60298SN/A{
61299SN/A    bool doStatisticsInsts;
62299SN/A    bool doCheckpointInsts;
63310SN/A    bool doQuiesce;
64310SN/A
65310SN/A    void
66711SN/A    arm(ExecContext *xc)
67711SN/A    {
682190SN/A        xc->getCpuPtr()->kernelStats->arm();
69711SN/A    }
70711SN/A
71711SN/A    void
72310SN/A    quiesce(ExecContext *xc)
73310SN/A    {
74310SN/A        if (!doQuiesce)
75310SN/A            return;
76310SN/A
77393SN/A        xc->suspend();
782190SN/A        xc->getCpuPtr()->kernelStats->quiesce();
79310SN/A    }
80299SN/A
81298SN/A    void
822188SN/A    quiesceNs(ExecContext *xc, uint64_t ns)
832188SN/A    {
842188SN/A        if (!doQuiesce || ns == 0)
852188SN/A            return;
862188SN/A
872235SN/A        Event *quiesceEvent = xc->getQuiesceEvent();
882235SN/A
892235SN/A        if (quiesceEvent->scheduled())
902235SN/A            quiesceEvent->reschedule(curTick + Clock::Int::ns * ns);
912188SN/A        else
922235SN/A            quiesceEvent->schedule(curTick + Clock::Int::ns * ns);
932188SN/A
942188SN/A        xc->suspend();
952235SN/A        xc->getCpuPtr()->kernelStats->quiesce();
962188SN/A    }
972188SN/A
982188SN/A    void
992188SN/A    quiesceCycles(ExecContext *xc, uint64_t cycles)
1002188SN/A    {
1012188SN/A        if (!doQuiesce || cycles == 0)
1022188SN/A            return;
1032188SN/A
1042235SN/A        Event *quiesceEvent = xc->getQuiesceEvent();
1052235SN/A
1062235SN/A        if (quiesceEvent->scheduled())
1072235SN/A            quiesceEvent->reschedule(curTick +
1082235SN/A                                     xc->getCpuPtr()->cycles(cycles));
1092188SN/A        else
1102235SN/A            quiesceEvent->schedule(curTick +
1112235SN/A                                   xc->getCpuPtr()->cycles(cycles));
1122188SN/A
1132188SN/A        xc->suspend();
1142235SN/A        xc->getCpuPtr()->kernelStats->quiesce();
1152188SN/A    }
1162188SN/A
1172188SN/A    uint64_t
1182188SN/A    quiesceTime(ExecContext *xc)
1192188SN/A    {
1202235SN/A        return (xc->readLastActivate() - xc->readLastSuspend()) / Clock::Int::ns;
1212188SN/A    }
1222188SN/A
1232188SN/A    void
124711SN/A    ivlb(ExecContext *xc)
125711SN/A    {
1262190SN/A        xc->getCpuPtr()->kernelStats->ivlb();
127711SN/A    }
128711SN/A
129711SN/A    void
130711SN/A    ivle(ExecContext *xc)
131711SN/A    {
132711SN/A    }
133711SN/A
134711SN/A    void
135298SN/A    m5exit_old(ExecContext *xc)
136298SN/A    {
1372667Sstever@eecs.umich.edu        exitSimLoop(curTick, "m5_exit_old instruction encountered");
138298SN/A    }
139298SN/A
140298SN/A    void
1412081SN/A    m5exit(ExecContext *xc, Tick delay)
142298SN/A    {
1431609SN/A        Tick when = curTick + delay * Clock::Int::ns;
1442667Sstever@eecs.umich.edu        exitSimLoop(when, "m5_exit instruction encountered");
145298SN/A    }
146298SN/A
147298SN/A    void
1482081SN/A    resetstats(ExecContext *xc, Tick delay, Tick period)
149298SN/A    {
150299SN/A        if (!doStatisticsInsts)
151299SN/A            return;
152299SN/A
153298SN/A
1541609SN/A        Tick when = curTick + delay * Clock::Int::ns;
1551609SN/A        Tick repeat = period * Clock::Int::ns;
156298SN/A
157729SN/A        using namespace Stats;
158298SN/A        SetupEvent(Reset, when, repeat);
159298SN/A    }
160298SN/A
161298SN/A    void
1622081SN/A    dumpstats(ExecContext *xc, Tick delay, Tick period)
163298SN/A    {
164299SN/A        if (!doStatisticsInsts)
165299SN/A            return;
166299SN/A
167298SN/A
1681609SN/A        Tick when = curTick + delay * Clock::Int::ns;
1691609SN/A        Tick repeat = period * Clock::Int::ns;
170298SN/A
171729SN/A        using namespace Stats;
172298SN/A        SetupEvent(Dump, when, repeat);
173298SN/A    }
174298SN/A
175298SN/A    void
1762081SN/A    addsymbol(ExecContext *xc, Addr addr, Addr symbolAddr)
1771973SN/A    {
1781973SN/A        char symb[100];
1792521SN/A        CopyStringOut(xc, symb, symbolAddr, 100);
1801973SN/A        std::string symbol(symb);
1811973SN/A
1821973SN/A        DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
1831973SN/A
1842190SN/A        xc->getSystemPtr()->kernelSymtab->insert(addr,symbol);
1851973SN/A    }
1861973SN/A
1871973SN/A    void
1882081SN/A    dumpresetstats(ExecContext *xc, Tick delay, Tick period)
189298SN/A    {
190299SN/A        if (!doStatisticsInsts)
191299SN/A            return;
192299SN/A
193298SN/A
1941609SN/A        Tick when = curTick + delay * Clock::Int::ns;
1951609SN/A        Tick repeat = period * Clock::Int::ns;
196298SN/A
197729SN/A        using namespace Stats;
198298SN/A        SetupEvent(Dump|Reset, when, repeat);
199298SN/A    }
200298SN/A
201298SN/A    void
2022081SN/A    m5checkpoint(ExecContext *xc, Tick delay, Tick period)
203298SN/A    {
204299SN/A        if (!doCheckpointInsts)
205299SN/A            return;
206299SN/A
207298SN/A
2081609SN/A        Tick when = curTick + delay * Clock::Int::ns;
2091609SN/A        Tick repeat = period * Clock::Int::ns;
210298SN/A
211449SN/A        Checkpoint::setup(when, repeat);
212298SN/A    }
213298SN/A
2142081SN/A    uint64_t
2152081SN/A    readfile(ExecContext *xc, Addr vaddr, uint64_t len, uint64_t offset)
216954SN/A    {
2172234SN/A        const string &file = xc->getCpuPtr()->system->params()->readfile;
218954SN/A        if (file.empty()) {
2192081SN/A            return ULL(0);
220954SN/A        }
221954SN/A
222954SN/A        uint64_t result = 0;
223954SN/A
224954SN/A        int fd = ::open(file.c_str(), O_RDONLY, 0);
225954SN/A        if (fd < 0)
226954SN/A            panic("could not open file %s\n", file);
227954SN/A
2281642SN/A        if (::lseek(fd, offset, SEEK_SET) < 0)
2291642SN/A            panic("could not seek: %s", strerror(errno));
2301642SN/A
231954SN/A        char *buf = new char[len];
232954SN/A        char *p = buf;
233954SN/A        while (len > 0) {
2341642SN/A            int bytes = ::read(fd, p, len);
235954SN/A            if (bytes <= 0)
236954SN/A                break;
237954SN/A
238954SN/A            p += bytes;
239954SN/A            result += bytes;
240954SN/A            len -= bytes;
241954SN/A        }
242954SN/A
243954SN/A        close(fd);
244954SN/A        CopyIn(xc, vaddr, buf, result);
245954SN/A        delete [] buf;
2462081SN/A        return result;
247954SN/A    }
248954SN/A
249299SN/A    class Context : public ParamContext
250299SN/A    {
251299SN/A      public:
252299SN/A        Context(const string &section) : ParamContext(section) {}
253299SN/A        void checkParams();
254299SN/A    };
255299SN/A
2561343SN/A    Context context("pseudo_inst");
257299SN/A
258310SN/A    Param<bool> __quiesce(&context, "quiesce",
259310SN/A                          "enable quiesce instructions",
260310SN/A                          true);
261300SN/A    Param<bool> __statistics(&context, "statistics",
262310SN/A                             "enable statistics pseudo instructions",
263301SN/A                             true);
264300SN/A    Param<bool> __checkpoint(&context, "checkpoint",
265310SN/A                             "enable checkpoint pseudo instructions",
266301SN/A                             true);
267299SN/A
268299SN/A    void
269299SN/A    Context::checkParams()
270299SN/A    {
271310SN/A        doQuiesce = __quiesce;
272299SN/A        doStatisticsInsts = __statistics;
273299SN/A        doCheckpointInsts = __checkpoint;
274299SN/A    }
2751052SN/A
2761052SN/A    void debugbreak(ExecContext *xc)
2771052SN/A    {
2781052SN/A        debug_break();
2791052SN/A    }
2801052SN/A
2811052SN/A    void switchcpu(ExecContext *xc)
2821052SN/A    {
2831052SN/A        if (SampCPU)
2841052SN/A            SampCPU->switchCPUs();
2851052SN/A    }
286298SN/A}
287