pseudo_inst.cc revision 2235
12SN/A/*
21762SN/A * Copyright (c) 2003-2006 The Regents of The University of Michigan
32SN/A * All rights reserved.
42SN/A *
52SN/A * Redistribution and use in source and binary forms, with or without
62SN/A * modification, are permitted provided that the following conditions are
72SN/A * met: redistributions of source code must retain the above copyright
82SN/A * notice, this list of conditions and the following disclaimer;
92SN/A * redistributions in binary form must reproduce the above copyright
102SN/A * notice, this list of conditions and the following disclaimer in the
112SN/A * documentation and/or other materials provided with the distribution;
122SN/A * neither the name of the copyright holders nor the names of its
132SN/A * contributors may be used to endorse or promote products derived from
142SN/A * this software without specific prior written permission.
152SN/A *
162SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
172SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
182SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
202SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
212SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
222SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
232SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
242SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
252SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
262SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
272665Ssaidi@eecs.umich.edu */
282665Ssaidi@eecs.umich.edu
292665Ssaidi@eecs.umich.edu#include <errno.h>
302665Ssaidi@eecs.umich.edu#include <fcntl.h>
312SN/A#include <unistd.h>
322SN/A#include <cstdio>
332SN/A
342SN/A#include <string>
352SN/A
362655Sstever@eecs.umich.edu#include "sim/pseudo_inst.hh"
372655Sstever@eecs.umich.edu#include "arch/vtophys.hh"
382SN/A#include "cpu/base.hh"
392SN/A#include "cpu/sampler/sampler.hh"
401399SN/A#include "cpu/exec_context.hh"
411396SN/A#include "kern/kernel_stats.hh"
422SN/A#include "sim/param.hh"
432SN/A#include "sim/serialize.hh"
442667Sstever@eecs.umich.edu#include "sim/sim_exit.hh"
452SN/A#include "sim/stat_control.hh"
461310SN/A#include "sim/stats.hh"
472SN/A#include "sim/system.hh"
482SN/A#include "sim/debug.hh"
492SN/A#include "sim/vptr.hh"
502667Sstever@eecs.umich.edu
5156SN/Ausing namespace std;
52146SN/A
531388SN/Aextern Sampler *SampCPU;
5456SN/A
5556SN/Ausing namespace Stats;
561311SN/Ausing namespace TheISA;
57400SN/A
581717SN/Anamespace AlphaPseudo
591717SN/A{
60146SN/A    bool doStatisticsInsts;
61146SN/A    bool doCheckpointInsts;
62146SN/A    bool doQuiesce;
63146SN/A
6456SN/A    void
6556SN/A    arm(ExecContext *xc)
6656SN/A    {
67695SN/A        xc->getCpuPtr()->kernelStats->arm();
68695SN/A    }
691696SN/A
702SN/A    void
712SN/A    quiesce(ExecContext *xc)
722SN/A    {
732SN/A        if (!doQuiesce)
742SN/A            return;
752SN/A
76329SN/A        xc->suspend();
772SN/A        xc->getCpuPtr()->kernelStats->quiesce();
782SN/A    }
792SN/A
802SN/A    void
812SN/A    quiesceNs(ExecContext *xc, uint64_t ns)
822SN/A    {
832SN/A        if (!doQuiesce || ns == 0)
842SN/A            return;
852SN/A
862SN/A        Event *quiesceEvent = xc->getQuiesceEvent();
872SN/A
882SN/A        if (quiesceEvent->scheduled())
89329SN/A            quiesceEvent->reschedule(curTick + Clock::Int::ns * ns);
90329SN/A        else
91329SN/A            quiesceEvent->schedule(curTick + Clock::Int::ns * ns);
92329SN/A
93329SN/A        xc->suspend();
94329SN/A        xc->getCpuPtr()->kernelStats->quiesce();
95329SN/A    }
962SN/A
972SN/A    void
982SN/A    quiesceCycles(ExecContext *xc, uint64_t cycles)
992SN/A    {
1002SN/A        if (!doQuiesce || cycles == 0)
1012SN/A            return;
1022SN/A
1032SN/A        Event *quiesceEvent = xc->getQuiesceEvent();
104764SN/A
105764SN/A        if (quiesceEvent->scheduled())
106764SN/A            quiesceEvent->reschedule(curTick +
107764SN/A                                     xc->getCpuPtr()->cycles(cycles));
108764SN/A        else
109764SN/A            quiesceEvent->schedule(curTick +
110764SN/A                                   xc->getCpuPtr()->cycles(cycles));
111764SN/A
112764SN/A        xc->suspend();
113764SN/A        xc->getCpuPtr()->kernelStats->quiesce();
114764SN/A    }
115764SN/A
1162SN/A    uint64_t
1172667Sstever@eecs.umich.edu    quiesceTime(ExecContext *xc)
1182667Sstever@eecs.umich.edu    {
1192667Sstever@eecs.umich.edu        return (xc->readLastActivate() - xc->readLastSuspend()) / Clock::Int::ns;
1202667Sstever@eecs.umich.edu    }
1212667Sstever@eecs.umich.edu
1222667Sstever@eecs.umich.edu    void
1231388SN/A    ivlb(ExecContext *xc)
1242667Sstever@eecs.umich.edu    {
1252SN/A        xc->getCpuPtr()->kernelStats->ivlb();
1262667Sstever@eecs.umich.edu    }
1272SN/A
1282667Sstever@eecs.umich.edu    void
1292667Sstever@eecs.umich.edu    ivle(ExecContext *xc)
1302667Sstever@eecs.umich.edu    {
1312667Sstever@eecs.umich.edu    }
1322667Sstever@eecs.umich.edu
1332SN/A    void
1342667Sstever@eecs.umich.edu    m5exit_old(ExecContext *xc)
1352667Sstever@eecs.umich.edu    {
1362667Sstever@eecs.umich.edu        SimExit(curTick, "m5_exit_old instruction encountered");
1372SN/A    }
1382667Sstever@eecs.umich.edu
1392667Sstever@eecs.umich.edu    void
1402667Sstever@eecs.umich.edu    m5exit(ExecContext *xc, Tick delay)
1412SN/A    {
1422SN/A        Tick when = curTick + delay * Clock::Int::ns;
1432667Sstever@eecs.umich.edu        SimExit(when, "m5_exit instruction encountered");
1442SN/A    }
1452SN/A
1462SN/A    void
1472SN/A    resetstats(ExecContext *xc, Tick delay, Tick period)
1482667Sstever@eecs.umich.edu    {
1492SN/A        if (!doStatisticsInsts)
1502SN/A            return;
1512SN/A
152329SN/A
153329SN/A        Tick when = curTick + delay * Clock::Int::ns;
154329SN/A        Tick repeat = period * Clock::Int::ns;
155764SN/A
1562SN/A        using namespace Stats;
1572655Sstever@eecs.umich.edu        SetupEvent(Reset, when, repeat);
1582667Sstever@eecs.umich.edu    }
1592667Sstever@eecs.umich.edu
1602667Sstever@eecs.umich.edu    void
1612667Sstever@eecs.umich.edu    dumpstats(ExecContext *xc, Tick delay, Tick period)
1622667Sstever@eecs.umich.edu    {
1632667Sstever@eecs.umich.edu        if (!doStatisticsInsts)
1642667Sstever@eecs.umich.edu            return;
1652667Sstever@eecs.umich.edu
1662667Sstever@eecs.umich.edu
1672667Sstever@eecs.umich.edu        Tick when = curTick + delay * Clock::Int::ns;
1682667Sstever@eecs.umich.edu        Tick repeat = period * Clock::Int::ns;
1692667Sstever@eecs.umich.edu
1702667Sstever@eecs.umich.edu        using namespace Stats;
1712667Sstever@eecs.umich.edu        SetupEvent(Dump, when, repeat);
1722667Sstever@eecs.umich.edu    }
1732667Sstever@eecs.umich.edu
1742667Sstever@eecs.umich.edu    void
1752667Sstever@eecs.umich.edu    addsymbol(ExecContext *xc, Addr addr, Addr symbolAddr)
1762667Sstever@eecs.umich.edu    {
1772667Sstever@eecs.umich.edu        char symb[100];
1782667Sstever@eecs.umich.edu        CopyString(xc, symb, symbolAddr, 100);
1792667Sstever@eecs.umich.edu        std::string symbol(symb);
1802667Sstever@eecs.umich.edu
1812667Sstever@eecs.umich.edu        DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
1822667Sstever@eecs.umich.edu
1832667Sstever@eecs.umich.edu        xc->getSystemPtr()->kernelSymtab->insert(addr,symbol);
1842667Sstever@eecs.umich.edu    }
1852667Sstever@eecs.umich.edu
1862667Sstever@eecs.umich.edu    void
1872667Sstever@eecs.umich.edu    dumpresetstats(ExecContext *xc, Tick delay, Tick period)
1882667Sstever@eecs.umich.edu    {
1892667Sstever@eecs.umich.edu        if (!doStatisticsInsts)
1902667Sstever@eecs.umich.edu            return;
1912667Sstever@eecs.umich.edu
1922667Sstever@eecs.umich.edu
1932667Sstever@eecs.umich.edu        Tick when = curTick + delay * Clock::Int::ns;
1942667Sstever@eecs.umich.edu        Tick repeat = period * Clock::Int::ns;
1952667Sstever@eecs.umich.edu
1962667Sstever@eecs.umich.edu        using namespace Stats;
1972667Sstever@eecs.umich.edu        SetupEvent(Dump|Reset, when, repeat);
1982667Sstever@eecs.umich.edu    }
1992667Sstever@eecs.umich.edu
2002667Sstever@eecs.umich.edu    void
2012667Sstever@eecs.umich.edu    m5checkpoint(ExecContext *xc, Tick delay, Tick period)
2022667Sstever@eecs.umich.edu    {
2032667Sstever@eecs.umich.edu        if (!doCheckpointInsts)
2042667Sstever@eecs.umich.edu            return;
2052667Sstever@eecs.umich.edu
2062667Sstever@eecs.umich.edu
2072667Sstever@eecs.umich.edu        Tick when = curTick + delay * Clock::Int::ns;
2082667Sstever@eecs.umich.edu        Tick repeat = period * Clock::Int::ns;
2092667Sstever@eecs.umich.edu
2102667Sstever@eecs.umich.edu        Checkpoint::setup(when, repeat);
2112655Sstever@eecs.umich.edu    }
2122655Sstever@eecs.umich.edu
2131311SN/A    uint64_t
2142667Sstever@eecs.umich.edu    readfile(ExecContext *xc, Addr vaddr, uint64_t len, uint64_t offset)
2152667Sstever@eecs.umich.edu    {
2161703SN/A        const string &file = xc->getCpuPtr()->system->params()->readfile;
2172667Sstever@eecs.umich.edu        if (file.empty()) {
2182667Sstever@eecs.umich.edu            return ULL(0);
2192667Sstever@eecs.umich.edu        }
2202667Sstever@eecs.umich.edu
2212667Sstever@eecs.umich.edu        uint64_t result = 0;
2222667Sstever@eecs.umich.edu
2232667Sstever@eecs.umich.edu        int fd = ::open(file.c_str(), O_RDONLY, 0);
2242667Sstever@eecs.umich.edu        if (fd < 0)
2251703SN/A            panic("could not open file %s\n", file);
2262667Sstever@eecs.umich.edu
2272667Sstever@eecs.umich.edu        if (::lseek(fd, offset, SEEK_SET) < 0)
2282667Sstever@eecs.umich.edu            panic("could not seek: %s", strerror(errno));
2292667Sstever@eecs.umich.edu
2302667Sstever@eecs.umich.edu        char *buf = new char[len];
2312SN/A        char *p = buf;
2322667Sstever@eecs.umich.edu        while (len > 0) {
2332667Sstever@eecs.umich.edu            int bytes = ::read(fd, p, len);
2342667Sstever@eecs.umich.edu            if (bytes <= 0)
2352667Sstever@eecs.umich.edu                break;
2362667Sstever@eecs.umich.edu
2372667Sstever@eecs.umich.edu            p += bytes;
2382667Sstever@eecs.umich.edu            result += bytes;
2392667Sstever@eecs.umich.edu            len -= bytes;
2402667Sstever@eecs.umich.edu        }
2412667Sstever@eecs.umich.edu
2422667Sstever@eecs.umich.edu        close(fd);
2432667Sstever@eecs.umich.edu        CopyIn(xc, vaddr, buf, result);
2442667Sstever@eecs.umich.edu        delete [] buf;
2452667Sstever@eecs.umich.edu        return result;
2462667Sstever@eecs.umich.edu    }
2472667Sstever@eecs.umich.edu
2482667Sstever@eecs.umich.edu    class Context : public ParamContext
2492667Sstever@eecs.umich.edu    {
2502655Sstever@eecs.umich.edu      public:
2512667Sstever@eecs.umich.edu        Context(const string &section) : ParamContext(section) {}
2521388SN/A        void checkParams();
2532667Sstever@eecs.umich.edu    };
2542667Sstever@eecs.umich.edu
2552667Sstever@eecs.umich.edu    Context context("pseudo_inst");
2562667Sstever@eecs.umich.edu
2572667Sstever@eecs.umich.edu    Param<bool> __quiesce(&context, "quiesce",
2582667Sstever@eecs.umich.edu                          "enable quiesce instructions",
2592655Sstever@eecs.umich.edu                          true);
2601388SN/A    Param<bool> __statistics(&context, "statistics",
2612SN/A                             "enable statistics pseudo instructions",
2621388SN/A                             true);
2632655Sstever@eecs.umich.edu    Param<bool> __checkpoint(&context, "checkpoint",
2642SN/A                             "enable checkpoint pseudo instructions",
2651388SN/A                             true);
2661388SN/A
2672SN/A    void
2681310SN/A    Context::checkParams()
2691388SN/A    {
2701310SN/A        doQuiesce = __quiesce;
2711310SN/A        doStatisticsInsts = __statistics;
2721310SN/A        doCheckpointInsts = __checkpoint;
2731388SN/A    }
2741388SN/A
2751388SN/A    void debugbreak(ExecContext *xc)
2761388SN/A    {
2772667Sstever@eecs.umich.edu        debug_break();
2781104SN/A    }
2792SN/A
2802499SN/A    void switchcpu(ExecContext *xc)
2812499SN/A    {
2822499SN/A        if (SampCPU)
2832499SN/A            SampCPU->switchCPUs();
2841127SN/A    }
2851127SN/A}
2861127SN/A