pseudo_inst.cc revision 2665:a124942bacb8
1/*
2 * Copyright (c) 2003-2006 The Regents of The University of Michigan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Authors: Nathan Binkert
29 */
30
31#include <errno.h>
32#include <fcntl.h>
33#include <unistd.h>
34
35#include <string>
36
37#include "sim/pseudo_inst.hh"
38#include "arch/vtophys.hh"
39#include "cpu/base.hh"
40#include "cpu/sampler/sampler.hh"
41#include "cpu/exec_context.hh"
42#include "kern/kernel_stats.hh"
43#include "sim/param.hh"
44#include "sim/serialize.hh"
45#include "sim/sim_exit.hh"
46#include "sim/stat_control.hh"
47#include "sim/stats.hh"
48#include "sim/system.hh"
49#include "sim/debug.hh"
50#include "sim/vptr.hh"
51
52using namespace std;
53
54extern Sampler *SampCPU;
55
56using namespace Stats;
57using namespace TheISA;
58
59namespace AlphaPseudo
60{
61    bool doStatisticsInsts;
62    bool doCheckpointInsts;
63    bool doQuiesce;
64
65    void
66    arm(ExecContext *xc)
67    {
68        xc->getCpuPtr()->kernelStats->arm();
69    }
70
71    void
72    quiesce(ExecContext *xc)
73    {
74        if (!doQuiesce)
75            return;
76
77        xc->suspend();
78        xc->getCpuPtr()->kernelStats->quiesce();
79    }
80
81    void
82    quiesceNs(ExecContext *xc, uint64_t ns)
83    {
84        if (!doQuiesce || ns == 0)
85            return;
86
87        Event *quiesceEvent = xc->getQuiesceEvent();
88
89        if (quiesceEvent->scheduled())
90            quiesceEvent->reschedule(curTick + Clock::Int::ns * ns);
91        else
92            quiesceEvent->schedule(curTick + Clock::Int::ns * ns);
93
94        xc->suspend();
95        xc->getCpuPtr()->kernelStats->quiesce();
96    }
97
98    void
99    quiesceCycles(ExecContext *xc, uint64_t cycles)
100    {
101        if (!doQuiesce || cycles == 0)
102            return;
103
104        Event *quiesceEvent = xc->getQuiesceEvent();
105
106        if (quiesceEvent->scheduled())
107            quiesceEvent->reschedule(curTick +
108                                     xc->getCpuPtr()->cycles(cycles));
109        else
110            quiesceEvent->schedule(curTick +
111                                   xc->getCpuPtr()->cycles(cycles));
112
113        xc->suspend();
114        xc->getCpuPtr()->kernelStats->quiesce();
115    }
116
117    uint64_t
118    quiesceTime(ExecContext *xc)
119    {
120        return (xc->readLastActivate() - xc->readLastSuspend()) / Clock::Int::ns;
121    }
122
123    void
124    ivlb(ExecContext *xc)
125    {
126        xc->getCpuPtr()->kernelStats->ivlb();
127    }
128
129    void
130    ivle(ExecContext *xc)
131    {
132    }
133
134    void
135    m5exit_old(ExecContext *xc)
136    {
137        SimExit(curTick, "m5_exit_old instruction encountered");
138    }
139
140    void
141    m5exit(ExecContext *xc, Tick delay)
142    {
143        Tick when = curTick + delay * Clock::Int::ns;
144        SimExit(when, "m5_exit instruction encountered");
145    }
146
147    void
148    resetstats(ExecContext *xc, Tick delay, Tick period)
149    {
150        if (!doStatisticsInsts)
151            return;
152
153
154        Tick when = curTick + delay * Clock::Int::ns;
155        Tick repeat = period * Clock::Int::ns;
156
157        using namespace Stats;
158        SetupEvent(Reset, when, repeat);
159    }
160
161    void
162    dumpstats(ExecContext *xc, Tick delay, Tick period)
163    {
164        if (!doStatisticsInsts)
165            return;
166
167
168        Tick when = curTick + delay * Clock::Int::ns;
169        Tick repeat = period * Clock::Int::ns;
170
171        using namespace Stats;
172        SetupEvent(Dump, when, repeat);
173    }
174
175    void
176    addsymbol(ExecContext *xc, Addr addr, Addr symbolAddr)
177    {
178        char symb[100];
179        CopyStringOut(xc, symb, symbolAddr, 100);
180        std::string symbol(symb);
181
182        DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
183
184        xc->getSystemPtr()->kernelSymtab->insert(addr,symbol);
185    }
186
187    void
188    dumpresetstats(ExecContext *xc, Tick delay, Tick period)
189    {
190        if (!doStatisticsInsts)
191            return;
192
193
194        Tick when = curTick + delay * Clock::Int::ns;
195        Tick repeat = period * Clock::Int::ns;
196
197        using namespace Stats;
198        SetupEvent(Dump|Reset, when, repeat);
199    }
200
201    void
202    m5checkpoint(ExecContext *xc, Tick delay, Tick period)
203    {
204        if (!doCheckpointInsts)
205            return;
206
207
208        Tick when = curTick + delay * Clock::Int::ns;
209        Tick repeat = period * Clock::Int::ns;
210
211        Checkpoint::setup(when, repeat);
212    }
213
214    uint64_t
215    readfile(ExecContext *xc, Addr vaddr, uint64_t len, uint64_t offset)
216    {
217        const string &file = xc->getCpuPtr()->system->params()->readfile;
218        if (file.empty()) {
219            return ULL(0);
220        }
221
222        uint64_t result = 0;
223
224        int fd = ::open(file.c_str(), O_RDONLY, 0);
225        if (fd < 0)
226            panic("could not open file %s\n", file);
227
228        if (::lseek(fd, offset, SEEK_SET) < 0)
229            panic("could not seek: %s", strerror(errno));
230
231        char *buf = new char[len];
232        char *p = buf;
233        while (len > 0) {
234            int bytes = ::read(fd, p, len);
235            if (bytes <= 0)
236                break;
237
238            p += bytes;
239            result += bytes;
240            len -= bytes;
241        }
242
243        close(fd);
244        CopyIn(xc, vaddr, buf, result);
245        delete [] buf;
246        return result;
247    }
248
249    class Context : public ParamContext
250    {
251      public:
252        Context(const string &section) : ParamContext(section) {}
253        void checkParams();
254    };
255
256    Context context("pseudo_inst");
257
258    Param<bool> __quiesce(&context, "quiesce",
259                          "enable quiesce instructions",
260                          true);
261    Param<bool> __statistics(&context, "statistics",
262                             "enable statistics pseudo instructions",
263                             true);
264    Param<bool> __checkpoint(&context, "checkpoint",
265                             "enable checkpoint pseudo instructions",
266                             true);
267
268    void
269    Context::checkParams()
270    {
271        doQuiesce = __quiesce;
272        doStatisticsInsts = __statistics;
273        doCheckpointInsts = __checkpoint;
274    }
275
276    void debugbreak(ExecContext *xc)
277    {
278        debug_break();
279    }
280
281    void switchcpu(ExecContext *xc)
282    {
283        if (SampCPU)
284            SampCPU->switchCPUs();
285    }
286}
287