pseudo_inst.cc revision 2654:9559cfa91b9d
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
29#include <errno.h>
30#include <fcntl.h>
31#include <unistd.h>
32
33#include <string>
34
35#include "sim/pseudo_inst.hh"
36#include "arch/vtophys.hh"
37#include "cpu/base.hh"
38#include "cpu/sampler/sampler.hh"
39#include "cpu/exec_context.hh"
40#include "cpu/quiesce_event.hh"
41#include "kern/kernel_stats.hh"
42#include "sim/param.hh"
43#include "sim/serialize.hh"
44#include "sim/sim_exit.hh"
45#include "sim/stat_control.hh"
46#include "sim/stats.hh"
47#include "sim/system.hh"
48#include "sim/debug.hh"
49#include "sim/vptr.hh"
50
51using namespace std;
52
53extern Sampler *SampCPU;
54
55using namespace Stats;
56using namespace TheISA;
57
58namespace AlphaPseudo
59{
60    bool doStatisticsInsts;
61    bool doCheckpointInsts;
62    bool doQuiesce;
63
64    void
65    arm(ExecContext *xc)
66    {
67        if (xc->getKernelStats())
68            xc->getKernelStats()->arm();
69    }
70
71    void
72    quiesce(ExecContext *xc)
73    {
74        if (!doQuiesce)
75            return;
76
77        xc->suspend();
78        if (xc->getKernelStats())
79            xc->getKernelStats()->quiesce();
80    }
81
82    void
83    quiesceNs(ExecContext *xc, uint64_t ns)
84    {
85        if (!doQuiesce || ns == 0)
86            return;
87
88        EndQuiesceEvent *quiesceEvent = xc->getQuiesceEvent();
89
90        if (quiesceEvent->scheduled())
91            quiesceEvent->reschedule(curTick + Clock::Int::ns * ns);
92        else
93            quiesceEvent->schedule(curTick + Clock::Int::ns * ns);
94
95        xc->suspend();
96        if (xc->getKernelStats())
97            xc->getKernelStats()->quiesce();
98    }
99
100    void
101    quiesceCycles(ExecContext *xc, uint64_t cycles)
102    {
103        if (!doQuiesce || cycles == 0)
104            return;
105
106        EndQuiesceEvent *quiesceEvent = xc->getQuiesceEvent();
107
108        if (quiesceEvent->scheduled())
109            quiesceEvent->reschedule(curTick +
110                                     xc->getCpuPtr()->cycles(cycles));
111        else
112            quiesceEvent->schedule(curTick +
113                                   xc->getCpuPtr()->cycles(cycles));
114
115        xc->suspend();
116        if (xc->getKernelStats())
117            xc->getKernelStats()->quiesce();
118    }
119
120    uint64_t
121    quiesceTime(ExecContext *xc)
122    {
123        return (xc->readLastActivate() - xc->readLastSuspend()) / Clock::Int::ns;
124    }
125
126    void
127    ivlb(ExecContext *xc)
128    {
129        if (xc->getKernelStats())
130            xc->getKernelStats()->ivlb();
131    }
132
133    void
134    ivle(ExecContext *xc)
135    {
136    }
137
138    void
139    m5exit_old(ExecContext *xc)
140    {
141        SimExit(curTick, "m5_exit_old instruction encountered");
142    }
143
144    void
145    m5exit(ExecContext *xc, Tick delay)
146    {
147        Tick when = curTick + delay * Clock::Int::ns;
148        SimExit(when, "m5_exit instruction encountered");
149    }
150
151    void
152    resetstats(ExecContext *xc, Tick delay, Tick period)
153    {
154        if (!doStatisticsInsts)
155            return;
156
157
158        Tick when = curTick + delay * Clock::Int::ns;
159        Tick repeat = period * Clock::Int::ns;
160
161        using namespace Stats;
162        SetupEvent(Reset, when, repeat);
163    }
164
165    void
166    dumpstats(ExecContext *xc, Tick delay, Tick period)
167    {
168        if (!doStatisticsInsts)
169            return;
170
171
172        Tick when = curTick + delay * Clock::Int::ns;
173        Tick repeat = period * Clock::Int::ns;
174
175        using namespace Stats;
176        SetupEvent(Dump, when, repeat);
177    }
178
179    void
180    addsymbol(ExecContext *xc, Addr addr, Addr symbolAddr)
181    {
182        char symb[100];
183        CopyStringOut(xc, symb, symbolAddr, 100);
184        std::string symbol(symb);
185
186        DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
187
188        xc->getSystemPtr()->kernelSymtab->insert(addr,symbol);
189    }
190
191    void
192    dumpresetstats(ExecContext *xc, Tick delay, Tick period)
193    {
194        if (!doStatisticsInsts)
195            return;
196
197
198        Tick when = curTick + delay * Clock::Int::ns;
199        Tick repeat = period * Clock::Int::ns;
200
201        using namespace Stats;
202        SetupEvent(Dump|Reset, when, repeat);
203    }
204
205    void
206    m5checkpoint(ExecContext *xc, Tick delay, Tick period)
207    {
208        if (!doCheckpointInsts)
209            return;
210
211
212        Tick when = curTick + delay * Clock::Int::ns;
213        Tick repeat = period * Clock::Int::ns;
214
215        Checkpoint::setup(when, repeat);
216    }
217
218    uint64_t
219    readfile(ExecContext *xc, Addr vaddr, uint64_t len, uint64_t offset)
220    {
221        const string &file = xc->getCpuPtr()->system->params()->readfile;
222        if (file.empty()) {
223            return ULL(0);
224        }
225
226        uint64_t result = 0;
227
228        int fd = ::open(file.c_str(), O_RDONLY, 0);
229        if (fd < 0)
230            panic("could not open file %s\n", file);
231
232        if (::lseek(fd, offset, SEEK_SET) < 0)
233            panic("could not seek: %s", strerror(errno));
234
235        char *buf = new char[len];
236        char *p = buf;
237        while (len > 0) {
238            int bytes = ::read(fd, p, len);
239            if (bytes <= 0)
240                break;
241
242            p += bytes;
243            result += bytes;
244            len -= bytes;
245        }
246
247        close(fd);
248        CopyIn(xc, vaddr, buf, result);
249        delete [] buf;
250        return result;
251    }
252
253    class Context : public ParamContext
254    {
255      public:
256        Context(const string &section) : ParamContext(section) {}
257        void checkParams();
258    };
259
260    Context context("pseudo_inst");
261
262    Param<bool> __quiesce(&context, "quiesce",
263                          "enable quiesce instructions",
264                          true);
265    Param<bool> __statistics(&context, "statistics",
266                             "enable statistics pseudo instructions",
267                             true);
268    Param<bool> __checkpoint(&context, "checkpoint",
269                             "enable checkpoint pseudo instructions",
270                             true);
271
272    void
273    Context::checkParams()
274    {
275        doQuiesce = __quiesce;
276        doStatisticsInsts = __statistics;
277        doCheckpointInsts = __checkpoint;
278    }
279
280    void debugbreak(ExecContext *xc)
281    {
282        debug_break();
283    }
284
285    void switchcpu(ExecContext *xc)
286    {
287        if (SampCPU)
288            SampCPU->switchCPUs();
289    }
290}
291