exec_context.hh revision 11877
1/*
2 * Copyright (c) 2011-2014 ARM Limited
3 * Copyright (c) 2013 Advanced Micro Devices, Inc.
4 * All rights reserved
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder.  You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
14 *
15 * Copyright (c) 2002-2005 The Regents of The University of Michigan
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * Authors: Steve Reinhardt
42 *          Dave Greene
43 *          Nathan Binkert
44 *          Andrew Bardsley
45 */
46
47/**
48 * @file
49 *
50 *  ExecContext bears the exec_context interface for Minor.
51 */
52
53#ifndef __CPU_MINOR_EXEC_CONTEXT_HH__
54#define __CPU_MINOR_EXEC_CONTEXT_HH__
55
56#include "cpu/exec_context.hh"
57#include "cpu/minor/execute.hh"
58#include "cpu/minor/pipeline.hh"
59#include "cpu/base.hh"
60#include "cpu/simple_thread.hh"
61#include "mem/request.hh"
62#include "debug/MinorExecute.hh"
63
64namespace Minor
65{
66
67/* Forward declaration of Execute */
68class Execute;
69
70/** ExecContext bears the exec_context interface for Minor.  This nicely
71 *  separates that interface from other classes such as Pipeline, MinorCPU
72 *  and DynMinorInst and makes it easier to see what state is accessed by it.
73 */
74class ExecContext : public ::ExecContext
75{
76  public:
77    MinorCPU &cpu;
78
79    /** ThreadState object, provides all the architectural state. */
80    SimpleThread &thread;
81
82    /** The execute stage so we can peek at its contents. */
83    Execute &execute;
84
85    /** Instruction for the benefit of memory operations and for PC */
86    MinorDynInstPtr inst;
87
88    ExecContext (
89        MinorCPU &cpu_,
90        SimpleThread &thread_, Execute &execute_,
91        MinorDynInstPtr inst_) :
92        cpu(cpu_),
93        thread(thread_),
94        execute(execute_),
95        inst(inst_)
96    {
97        DPRINTF(MinorExecute, "ExecContext setting PC: %s\n", inst->pc);
98        pcState(inst->pc);
99        setPredicate(true);
100        thread.setIntReg(TheISA::ZeroReg, 0);
101#if THE_ISA == ALPHA_ISA
102        thread.setFloatReg(TheISA::ZeroReg, 0.0);
103#endif
104    }
105
106    Fault
107    initiateMemRead(Addr addr, unsigned int size,
108                    Request::Flags flags) override
109    {
110        execute.getLSQ().pushRequest(inst, true /* load */, nullptr,
111            size, addr, flags, NULL);
112        return NoFault;
113    }
114
115    Fault
116    writeMem(uint8_t *data, unsigned int size, Addr addr,
117             Request::Flags flags, uint64_t *res) override
118    {
119        execute.getLSQ().pushRequest(inst, false /* store */, data,
120            size, addr, flags, res);
121        return NoFault;
122    }
123
124    IntReg
125    readIntRegOperand(const StaticInst *si, int idx) override
126    {
127        return thread.readIntReg(si->srcRegIdx(idx));
128    }
129
130    TheISA::FloatReg
131    readFloatRegOperand(const StaticInst *si, int idx) override
132    {
133        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
134        return thread.readFloatReg(reg_idx);
135    }
136
137    TheISA::FloatRegBits
138    readFloatRegOperandBits(const StaticInst *si, int idx) override
139    {
140        int reg_idx = si->srcRegIdx(idx) - TheISA::FP_Reg_Base;
141        return thread.readFloatRegBits(reg_idx);
142    }
143
144    void
145    setIntRegOperand(const StaticInst *si, int idx, IntReg val) override
146    {
147        thread.setIntReg(si->destRegIdx(idx), val);
148    }
149
150    void
151    setFloatRegOperand(const StaticInst *si, int idx,
152        TheISA::FloatReg val) override
153    {
154        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
155        thread.setFloatReg(reg_idx, val);
156    }
157
158    void
159    setFloatRegOperandBits(const StaticInst *si, int idx,
160        TheISA::FloatRegBits val) override
161    {
162        int reg_idx = si->destRegIdx(idx) - TheISA::FP_Reg_Base;
163        thread.setFloatRegBits(reg_idx, val);
164    }
165
166    bool
167    readPredicate() override
168    {
169        return thread.readPredicate();
170    }
171
172    void
173    setPredicate(bool val) override
174    {
175        thread.setPredicate(val);
176    }
177
178    TheISA::PCState
179    pcState() const override
180    {
181        return thread.pcState();
182    }
183
184    void
185    pcState(const TheISA::PCState &val) override
186    {
187        thread.pcState(val);
188    }
189
190    TheISA::MiscReg
191    readMiscRegNoEffect(int misc_reg) const
192    {
193        return thread.readMiscRegNoEffect(misc_reg);
194    }
195
196    TheISA::MiscReg
197    readMiscReg(int misc_reg) override
198    {
199        return thread.readMiscReg(misc_reg);
200    }
201
202    void
203    setMiscReg(int misc_reg, const TheISA::MiscReg &val) override
204    {
205        thread.setMiscReg(misc_reg, val);
206    }
207
208    TheISA::MiscReg
209    readMiscRegOperand(const StaticInst *si, int idx) override
210    {
211        int reg_idx = si->srcRegIdx(idx) - TheISA::Misc_Reg_Base;
212        return thread.readMiscReg(reg_idx);
213    }
214
215    void
216    setMiscRegOperand(const StaticInst *si, int idx,
217        const TheISA::MiscReg &val) override
218    {
219        int reg_idx = si->destRegIdx(idx) - TheISA::Misc_Reg_Base;
220        return thread.setMiscReg(reg_idx, val);
221    }
222
223    Fault
224    hwrei() override
225    {
226#if THE_ISA == ALPHA_ISA
227        return thread.hwrei();
228#else
229        return NoFault;
230#endif
231    }
232
233    bool
234    simPalCheck(int palFunc) override
235    {
236#if THE_ISA == ALPHA_ISA
237        return thread.simPalCheck(palFunc);
238#else
239        return false;
240#endif
241    }
242
243    void
244    syscall(int64_t callnum, Fault *fault) override
245     {
246        if (FullSystem)
247            panic("Syscall emulation isn't available in FS mode.\n");
248
249        thread.syscall(callnum, fault);
250    }
251
252    ThreadContext *tcBase() override { return thread.getTC(); }
253
254    /* @todo, should make stCondFailures persistent somewhere */
255    unsigned int readStCondFailures() const override { return 0; }
256    void setStCondFailures(unsigned int st_cond_failures) override {}
257
258    ContextID contextId() { return thread.contextId(); }
259    /* ISA-specific (or at least currently ISA singleton) functions */
260
261    /* X86: TLB twiddling */
262    void
263    demapPage(Addr vaddr, uint64_t asn) override
264    {
265        thread.getITBPtr()->demapPage(vaddr, asn);
266        thread.getDTBPtr()->demapPage(vaddr, asn);
267    }
268
269    TheISA::CCReg
270    readCCRegOperand(const StaticInst *si, int idx) override
271    {
272        int reg_idx = si->srcRegIdx(idx) - TheISA::CC_Reg_Base;
273        return thread.readCCReg(reg_idx);
274    }
275
276    void
277    setCCRegOperand(const StaticInst *si, int idx, TheISA::CCReg val) override
278    {
279        int reg_idx = si->destRegIdx(idx) - TheISA::CC_Reg_Base;
280        thread.setCCReg(reg_idx, val);
281    }
282
283    void
284    demapInstPage(Addr vaddr, uint64_t asn)
285    {
286        thread.getITBPtr()->demapPage(vaddr, asn);
287    }
288
289    void
290    demapDataPage(Addr vaddr, uint64_t asn)
291    {
292        thread.getDTBPtr()->demapPage(vaddr, asn);
293    }
294
295    /* ALPHA/POWER: Effective address storage */
296    void setEA(Addr ea) override
297    {
298        inst->ea = ea;
299    }
300
301    BaseCPU *getCpuPtr() { return &cpu; }
302
303    /* POWER: Effective address storage */
304    Addr getEA() const override
305    {
306        return inst->ea;
307    }
308
309    /* MIPS: other thread register reading/writing */
310    uint64_t
311    readRegOtherThread(int idx, ThreadID tid = InvalidThreadID)
312    {
313        SimpleThread *other_thread = (tid == InvalidThreadID
314            ? &thread : cpu.threads[tid]);
315
316        if (idx < TheISA::FP_Reg_Base) { /* Integer */
317            return other_thread->readIntReg(idx);
318        } else if (idx < TheISA::Misc_Reg_Base) { /* Float */
319            return other_thread->readFloatRegBits(idx
320                - TheISA::FP_Reg_Base);
321        } else { /* Misc */
322            return other_thread->readMiscReg(idx
323                - TheISA::Misc_Reg_Base);
324        }
325    }
326
327    void
328    setRegOtherThread(int idx, const TheISA::MiscReg &val,
329        ThreadID tid = InvalidThreadID)
330    {
331        SimpleThread *other_thread = (tid == InvalidThreadID
332            ? &thread : cpu.threads[tid]);
333
334        if (idx < TheISA::FP_Reg_Base) { /* Integer */
335            return other_thread->setIntReg(idx, val);
336        } else if (idx < TheISA::Misc_Reg_Base) { /* Float */
337            return other_thread->setFloatRegBits(idx
338                - TheISA::FP_Reg_Base, val);
339        } else { /* Misc */
340            return other_thread->setMiscReg(idx
341                - TheISA::Misc_Reg_Base, val);
342        }
343    }
344
345  public:
346    // monitor/mwait funtions
347    void armMonitor(Addr address) override
348    { getCpuPtr()->armMonitor(inst->id.threadId, address); }
349
350    bool mwait(PacketPtr pkt) override
351    { return getCpuPtr()->mwait(inst->id.threadId, pkt); }
352
353    void mwaitAtomic(ThreadContext *tc) override
354    { return getCpuPtr()->mwaitAtomic(inst->id.threadId, tc, thread.dtb); }
355
356    AddressMonitor *getAddrMonitor() override
357    { return getCpuPtr()->getCpuAddrMonitor(inst->id.threadId); }
358};
359
360}
361
362#endif /* __CPU_MINOR_EXEC_CONTEXT_HH__ */
363