pseudo_inst.cc revision 3617
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
372170SN/A#include "arch/vtophys.hh"
383089Ssaidi@eecs.umich.edu#include "base/annotate.hh"
391717SN/A#include "cpu/base.hh"
402680Sktlim@umich.edu#include "cpu/thread_context.hh"
412313SN/A#include "cpu/quiesce_event.hh"
423565Sgblack@eecs.umich.edu#include "arch/kernel_stats.hh"
433565Sgblack@eecs.umich.edu#include "sim/pseudo_inst.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
54729SN/Ausing namespace Stats;
552107SN/Ausing namespace TheISA;
56298SN/A
57298SN/Anamespace AlphaPseudo
58298SN/A{
59310SN/A    void
602680Sktlim@umich.edu    arm(ThreadContext *tc)
61711SN/A    {
622680Sktlim@umich.edu        if (tc->getKernelStats())
632680Sktlim@umich.edu            tc->getKernelStats()->arm();
64711SN/A    }
65711SN/A
66711SN/A    void
672680Sktlim@umich.edu    quiesce(ThreadContext *tc)
68310SN/A    {
693617Sbinkertn@umich.edu        if (!tc->getCpuPtr()->params->do_quiesce)
70310SN/A            return;
71310SN/A
723373Sstever@eecs.umich.edu        DPRINTF(Quiesce, "%s: quiesce()\n", tc->getCpuPtr()->name());
733373Sstever@eecs.umich.edu
742680Sktlim@umich.edu        tc->suspend();
752680Sktlim@umich.edu        if (tc->getKernelStats())
762680Sktlim@umich.edu            tc->getKernelStats()->quiesce();
77310SN/A    }
78299SN/A
79298SN/A    void
802680Sktlim@umich.edu    quiesceNs(ThreadContext *tc, uint64_t ns)
812188SN/A    {
823617Sbinkertn@umich.edu        if (!tc->getCpuPtr()->params->do_quiesce || ns == 0)
832188SN/A            return;
842188SN/A
852680Sktlim@umich.edu        EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
862235SN/A
873368Sstever@eecs.umich.edu        Tick resume = curTick + Clock::Int::ns * ns;
883368Sstever@eecs.umich.edu
892235SN/A        if (quiesceEvent->scheduled())
903368Sstever@eecs.umich.edu            quiesceEvent->reschedule(resume);
912188SN/A        else
923368Sstever@eecs.umich.edu            quiesceEvent->schedule(resume);
933368Sstever@eecs.umich.edu
943368Sstever@eecs.umich.edu        DPRINTF(Quiesce, "%s: quiesceNs(%d) until %d\n",
953368Sstever@eecs.umich.edu                tc->getCpuPtr()->name(), ns, resume);
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    {
1053617Sbinkertn@umich.edu        if (!tc->getCpuPtr()->params->do_quiesce || cycles == 0)
1062188SN/A            return;
1072188SN/A
1082680Sktlim@umich.edu        EndQuiesceEvent *quiesceEvent = tc->getQuiesceEvent();
1092235SN/A
1103368Sstever@eecs.umich.edu        Tick resume = curTick + tc->getCpuPtr()->cycles(cycles);
1113368Sstever@eecs.umich.edu
1122235SN/A        if (quiesceEvent->scheduled())
1133368Sstever@eecs.umich.edu            quiesceEvent->reschedule(resume);
1142188SN/A        else
1153368Sstever@eecs.umich.edu            quiesceEvent->schedule(resume);
1163368Sstever@eecs.umich.edu
1173368Sstever@eecs.umich.edu        DPRINTF(Quiesce, "%s: quiesceCycles(%d) until %d\n",
1183368Sstever@eecs.umich.edu                tc->getCpuPtr()->name(), cycles, resume);
1192188SN/A
1202680Sktlim@umich.edu        tc->suspend();
1212680Sktlim@umich.edu        if (tc->getKernelStats())
1222680Sktlim@umich.edu            tc->getKernelStats()->quiesce();
1232188SN/A    }
1242188SN/A
1252188SN/A    uint64_t
1262680Sktlim@umich.edu    quiesceTime(ThreadContext *tc)
1272188SN/A    {
1282680Sktlim@umich.edu        return (tc->readLastActivate() - tc->readLastSuspend()) / Clock::Int::ns;
1292188SN/A    }
1302188SN/A
1312188SN/A    void
1322680Sktlim@umich.edu    m5exit_old(ThreadContext *tc)
133298SN/A    {
1343144Shsul@eecs.umich.edu        exitSimLoop("m5_exit_old instruction encountered");
135298SN/A    }
136298SN/A
137298SN/A    void
1382680Sktlim@umich.edu    m5exit(ThreadContext *tc, Tick delay)
139298SN/A    {
1401609SN/A        Tick when = curTick + delay * Clock::Int::ns;
1413144Shsul@eecs.umich.edu        schedExitSimLoop("m5_exit instruction encountered", when);
142298SN/A    }
143298SN/A
144298SN/A    void
1453126Sktlim@umich.edu    loadsymbol(ThreadContext *tc)
1462358SN/A    {
1473126Sktlim@umich.edu        const string &filename = tc->getCpuPtr()->system->params()->symbolfile;
1482358SN/A        if (filename.empty()) {
1492358SN/A            return;
1502358SN/A        }
1512358SN/A
1522358SN/A        std::string buffer;
1532358SN/A        ifstream file(filename.c_str());
1542358SN/A
1552358SN/A        if (!file)
1562358SN/A            fatal("file error: Can't open symbol table file %s\n", filename);
1572358SN/A
1582358SN/A        while (!file.eof()) {
1592358SN/A            getline(file, buffer);
1602358SN/A
1612358SN/A            if (buffer.empty())
1622358SN/A                continue;
1632358SN/A
1642358SN/A            int idx = buffer.find(' ');
1652358SN/A            if (idx == string::npos)
1662358SN/A                continue;
1672358SN/A
1682358SN/A            string address = "0x" + buffer.substr(0, idx);
1692358SN/A            eat_white(address);
1702358SN/A            if (address.empty())
1712358SN/A                continue;
1722358SN/A
1732358SN/A            // Skip over letter and space
1742358SN/A            string symbol = buffer.substr(idx + 3);
1752358SN/A            eat_white(symbol);
1762358SN/A            if (symbol.empty())
1772358SN/A                continue;
1782358SN/A
1792358SN/A            Addr addr;
1802358SN/A            if (!to_number(address, addr))
1812358SN/A                continue;
1822358SN/A
1833126Sktlim@umich.edu            if (!tc->getSystemPtr()->kernelSymtab->insert(addr, symbol))
1842358SN/A                continue;
1852358SN/A
1862358SN/A
1872358SN/A            DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
1882358SN/A        }
1892358SN/A        file.close();
1902358SN/A    }
1912358SN/A
1922358SN/A    void
1932680Sktlim@umich.edu    resetstats(ThreadContext *tc, Tick delay, Tick period)
194298SN/A    {
1953617Sbinkertn@umich.edu        if (!tc->getCpuPtr()->params->do_statistics_insts)
196299SN/A            return;
197299SN/A
198298SN/A
1991609SN/A        Tick when = curTick + delay * Clock::Int::ns;
2001609SN/A        Tick repeat = period * Clock::Int::ns;
201298SN/A
202729SN/A        using namespace Stats;
203298SN/A        SetupEvent(Reset, 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
216729SN/A        using namespace Stats;
217298SN/A        SetupEvent(Dump, when, repeat);
218298SN/A    }
219298SN/A
220298SN/A    void
2212680Sktlim@umich.edu    addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr)
2221973SN/A    {
2231973SN/A        char symb[100];
2242680Sktlim@umich.edu        CopyStringOut(tc, symb, symbolAddr, 100);
2251973SN/A        std::string symbol(symb);
2261973SN/A
2271973SN/A        DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
2281973SN/A
2292680Sktlim@umich.edu        tc->getSystemPtr()->kernelSymtab->insert(addr,symbol);
2301973SN/A    }
2311973SN/A
2321973SN/A    void
2333089Ssaidi@eecs.umich.edu    anBegin(ThreadContext *tc, uint64_t cur)
2343089Ssaidi@eecs.umich.edu    {
2353089Ssaidi@eecs.umich.edu        Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur &
2363089Ssaidi@eecs.umich.edu                0xFFFFFFFF, 0,0);
2373089Ssaidi@eecs.umich.edu    }
2383089Ssaidi@eecs.umich.edu
2393089Ssaidi@eecs.umich.edu    void
2403089Ssaidi@eecs.umich.edu    anWait(ThreadContext *tc, uint64_t cur, uint64_t wait)
2413089Ssaidi@eecs.umich.edu    {
2423089Ssaidi@eecs.umich.edu        Annotate::annotations.add(tc->getSystemPtr(), 0, cur >> 32, cur &
2433089Ssaidi@eecs.umich.edu                0xFFFFFFFF, wait >> 32, wait & 0xFFFFFFFF);
2443089Ssaidi@eecs.umich.edu    }
2453089Ssaidi@eecs.umich.edu
2463089Ssaidi@eecs.umich.edu
2473089Ssaidi@eecs.umich.edu    void
2482680Sktlim@umich.edu    dumpresetstats(ThreadContext *tc, Tick delay, Tick period)
249298SN/A    {
2503617Sbinkertn@umich.edu        if (!tc->getCpuPtr()->params->do_statistics_insts)
251299SN/A            return;
252299SN/A
253298SN/A
2541609SN/A        Tick when = curTick + delay * Clock::Int::ns;
2551609SN/A        Tick repeat = period * Clock::Int::ns;
256298SN/A
257729SN/A        using namespace Stats;
258298SN/A        SetupEvent(Dump|Reset, when, repeat);
259298SN/A    }
260298SN/A
261298SN/A    void
2622680Sktlim@umich.edu    m5checkpoint(ThreadContext *tc, Tick delay, Tick period)
263298SN/A    {
2643617Sbinkertn@umich.edu        if (!tc->getCpuPtr()->params->do_checkpoint_insts)
265299SN/A            return;
2663144Shsul@eecs.umich.edu
2673144Shsul@eecs.umich.edu        Tick when = curTick + delay * Clock::Int::ns;
2683144Shsul@eecs.umich.edu        Tick repeat = period * Clock::Int::ns;
2693144Shsul@eecs.umich.edu
2703144Shsul@eecs.umich.edu        schedExitSimLoop("checkpoint", when, repeat);
271298SN/A    }
272298SN/A
2732081SN/A    uint64_t
2742680Sktlim@umich.edu    readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset)
275954SN/A    {
2763617Sbinkertn@umich.edu        const string &file = tc->getSystemPtr()->params()->readfile;
277954SN/A        if (file.empty()) {
2782081SN/A            return ULL(0);
279954SN/A        }
280954SN/A
281954SN/A        uint64_t result = 0;
282954SN/A
283954SN/A        int fd = ::open(file.c_str(), O_RDONLY, 0);
284954SN/A        if (fd < 0)
285954SN/A            panic("could not open file %s\n", file);
286954SN/A
2871642SN/A        if (::lseek(fd, offset, SEEK_SET) < 0)
2881642SN/A            panic("could not seek: %s", strerror(errno));
2891642SN/A
290954SN/A        char *buf = new char[len];
291954SN/A        char *p = buf;
292954SN/A        while (len > 0) {
2931642SN/A            int bytes = ::read(fd, p, len);
294954SN/A            if (bytes <= 0)
295954SN/A                break;
296954SN/A
297954SN/A            p += bytes;
298954SN/A            result += bytes;
299954SN/A            len -= bytes;
300954SN/A        }
301954SN/A
302954SN/A        close(fd);
3032680Sktlim@umich.edu        CopyIn(tc, vaddr, buf, result);
304954SN/A        delete [] buf;
3052081SN/A        return result;
306954SN/A    }
307954SN/A
3082680Sktlim@umich.edu    void debugbreak(ThreadContext *tc)
3091052SN/A    {
3101052SN/A        debug_break();
3111052SN/A    }
3121052SN/A
3132680Sktlim@umich.edu    void switchcpu(ThreadContext *tc)
3141052SN/A    {
3152841Sktlim@umich.edu        exitSimLoop("switchcpu");
3161052SN/A    }
317298SN/A}
318