thread_context_impl.hh revision 12429:beefb9f5f551
112855Sgabeblack@google.com/*
212855Sgabeblack@google.com * Copyright (c) 2010-2012, 2016-2017 ARM Limited
312855Sgabeblack@google.com * Copyright (c) 2013 Advanced Micro Devices, Inc.
412855Sgabeblack@google.com * All rights reserved
512855Sgabeblack@google.com *
612855Sgabeblack@google.com * The license below extends only to copyright in the software and shall
712855Sgabeblack@google.com * not be construed as granting a license to any other intellectual
812855Sgabeblack@google.com * property including but not limited to intellectual property relating
912855Sgabeblack@google.com * to a hardware implementation of the functionality of the software
1012855Sgabeblack@google.com * licensed hereunder.  You may use the software subject to the license
1112855Sgabeblack@google.com * terms below provided that you ensure that this notice is replicated
1212855Sgabeblack@google.com * unmodified and in its entirety in all distributions of the software,
1312855Sgabeblack@google.com * modified or unmodified, in source code or in binary form.
1412855Sgabeblack@google.com *
1512855Sgabeblack@google.com * Copyright (c) 2004-2006 The Regents of The University of Michigan
1612855Sgabeblack@google.com * All rights reserved.
1712855Sgabeblack@google.com *
1812855Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
1912855Sgabeblack@google.com * modification, are permitted provided that the following conditions are
2012855Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
2112855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
2212855Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
2312855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
2412855Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
2512855Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
2612855Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
2712855Sgabeblack@google.com * this software without specific prior written permission.
2812855Sgabeblack@google.com *
2912855Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3012855Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3112855Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3212855Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3312855Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3412855Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3512855Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3612855Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3712855Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3812855Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3912855Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4012855Sgabeblack@google.com *
4112855Sgabeblack@google.com * Authors: Kevin Lim
4212855Sgabeblack@google.com *          Korey Sewell
4312855Sgabeblack@google.com */
4412855Sgabeblack@google.com
4512855Sgabeblack@google.com#ifndef __CPU_O3_THREAD_CONTEXT_IMPL_HH__
4612855Sgabeblack@google.com#define __CPU_O3_THREAD_CONTEXT_IMPL_HH__
4712855Sgabeblack@google.com
4812855Sgabeblack@google.com#include "arch/kernel_stats.hh"
4912855Sgabeblack@google.com#include "arch/registers.hh"
5012855Sgabeblack@google.com#include "config/the_isa.hh"
5112855Sgabeblack@google.com#include "cpu/o3/thread_context.hh"
5212855Sgabeblack@google.com#include "cpu/quiesce_event.hh"
5312855Sgabeblack@google.com#include "debug/O3CPU.hh"
5412855Sgabeblack@google.com
5512855Sgabeblack@google.comtemplate <class Impl>
5612855Sgabeblack@google.comFSTranslatingPortProxy&
5712855Sgabeblack@google.comO3ThreadContext<Impl>::getVirtProxy()
5812855Sgabeblack@google.com{
5912855Sgabeblack@google.com    return thread->getVirtProxy();
6012855Sgabeblack@google.com}
6112855Sgabeblack@google.com
6212855Sgabeblack@google.comtemplate <class Impl>
6312855Sgabeblack@google.comvoid
6412855Sgabeblack@google.comO3ThreadContext<Impl>::dumpFuncProfile()
6512855Sgabeblack@google.com{
6612855Sgabeblack@google.com    thread->dumpFuncProfile();
6712855Sgabeblack@google.com}
6812855Sgabeblack@google.com
6912855Sgabeblack@google.comtemplate <class Impl>
7012855Sgabeblack@google.comvoid
7112855Sgabeblack@google.comO3ThreadContext<Impl>::takeOverFrom(ThreadContext *old_context)
7212855Sgabeblack@google.com{
7312855Sgabeblack@google.com    ::takeOverFrom(*this, *old_context);
7412855Sgabeblack@google.com    TheISA::Decoder *newDecoder = getDecoderPtr();
7512855Sgabeblack@google.com    TheISA::Decoder *oldDecoder = old_context->getDecoderPtr();
7612855Sgabeblack@google.com    newDecoder->takeOverFrom(oldDecoder);
7712855Sgabeblack@google.com
7812855Sgabeblack@google.com    thread->kernelStats = old_context->getKernelStats();
7912855Sgabeblack@google.com    thread->funcExeInst = old_context->readFuncExeInst();
8012855Sgabeblack@google.com
8112855Sgabeblack@google.com    thread->noSquashFromTC = false;
8212855Sgabeblack@google.com    thread->trapPending = false;
8312855Sgabeblack@google.com}
8412855Sgabeblack@google.com
8512855Sgabeblack@google.comtemplate <class Impl>
8612855Sgabeblack@google.comvoid
8712855Sgabeblack@google.comO3ThreadContext<Impl>::activate()
8812855Sgabeblack@google.com{
8912855Sgabeblack@google.com    DPRINTF(O3CPU, "Calling activate on Thread Context %d\n",
9012855Sgabeblack@google.com            threadId());
9112855Sgabeblack@google.com
9212855Sgabeblack@google.com    if (thread->status() == ThreadContext::Active)
9312855Sgabeblack@google.com        return;
9412855Sgabeblack@google.com
9512855Sgabeblack@google.com    thread->lastActivate = curTick();
9612855Sgabeblack@google.com    thread->setStatus(ThreadContext::Active);
9712855Sgabeblack@google.com
9812855Sgabeblack@google.com    // status() == Suspended
9912855Sgabeblack@google.com    cpu->activateContext(thread->threadId());
10012855Sgabeblack@google.com}
10112855Sgabeblack@google.com
10212855Sgabeblack@google.comtemplate <class Impl>
10312855Sgabeblack@google.comvoid
10412855Sgabeblack@google.comO3ThreadContext<Impl>::suspend()
10512855Sgabeblack@google.com{
10612855Sgabeblack@google.com    DPRINTF(O3CPU, "Calling suspend on Thread Context %d\n",
10712855Sgabeblack@google.com            threadId());
10812855Sgabeblack@google.com
10912855Sgabeblack@google.com    if (thread->status() == ThreadContext::Suspended)
11012855Sgabeblack@google.com        return;
11112855Sgabeblack@google.com
11212855Sgabeblack@google.com    if (cpu->isDraining()) {
11312855Sgabeblack@google.com        DPRINTF(O3CPU, "Ignoring suspend on TC due to pending drain\n");
11412855Sgabeblack@google.com        return;
11512855Sgabeblack@google.com    }
116
117    thread->lastActivate = curTick();
118    thread->lastSuspend = curTick();
119
120    thread->setStatus(ThreadContext::Suspended);
121    cpu->suspendContext(thread->threadId());
122}
123
124template <class Impl>
125void
126O3ThreadContext<Impl>::halt()
127{
128    DPRINTF(O3CPU, "Calling halt on Thread Context %d\n", threadId());
129
130    if (thread->status() == ThreadContext::Halted)
131        return;
132
133    thread->setStatus(ThreadContext::Halted);
134    cpu->haltContext(thread->threadId());
135}
136
137template <class Impl>
138void
139O3ThreadContext<Impl>::regStats(const std::string &name)
140{
141    if (FullSystem) {
142        thread->kernelStats = new TheISA::Kernel::Statistics();
143        thread->kernelStats->regStats(name + ".kern");
144    }
145}
146
147template <class Impl>
148Tick
149O3ThreadContext<Impl>::readLastActivate()
150{
151    return thread->lastActivate;
152}
153
154template <class Impl>
155Tick
156O3ThreadContext<Impl>::readLastSuspend()
157{
158    return thread->lastSuspend;
159}
160
161template <class Impl>
162void
163O3ThreadContext<Impl>::profileClear()
164{
165    thread->profileClear();
166}
167
168template <class Impl>
169void
170O3ThreadContext<Impl>::profileSample()
171{
172    thread->profileSample();
173}
174
175template <class Impl>
176void
177O3ThreadContext<Impl>::copyArchRegs(ThreadContext *tc)
178{
179    // Prevent squashing
180    thread->noSquashFromTC = true;
181    TheISA::copyRegs(tc, this);
182    thread->noSquashFromTC = false;
183
184    if (!FullSystem)
185        this->thread->funcExeInst = tc->readFuncExeInst();
186}
187
188template <class Impl>
189void
190O3ThreadContext<Impl>::clearArchRegs()
191{
192    cpu->isa[thread->threadId()]->clear();
193}
194
195template <class Impl>
196uint64_t
197O3ThreadContext<Impl>::readIntRegFlat(int reg_idx)
198{
199    return cpu->readArchIntReg(reg_idx, thread->threadId());
200}
201
202template <class Impl>
203TheISA::FloatReg
204O3ThreadContext<Impl>::readFloatRegFlat(int reg_idx)
205{
206    return cpu->readArchFloatReg(reg_idx, thread->threadId());
207}
208
209template <class Impl>
210TheISA::FloatRegBits
211O3ThreadContext<Impl>::readFloatRegBitsFlat(int reg_idx)
212{
213    return cpu->readArchFloatRegInt(reg_idx, thread->threadId());
214}
215
216template <class Impl>
217const TheISA::VecRegContainer&
218O3ThreadContext<Impl>::readVecRegFlat(int reg_id) const
219{
220    return cpu->readArchVecReg(reg_id, thread->threadId());
221}
222
223template <class Impl>
224TheISA::VecRegContainer&
225O3ThreadContext<Impl>::getWritableVecRegFlat(int reg_id)
226{
227    return cpu->getWritableArchVecReg(reg_id, thread->threadId());
228}
229
230template <class Impl>
231const TheISA::VecElem&
232O3ThreadContext<Impl>::readVecElemFlat(const RegIndex& idx,
233                                           const ElemIndex& elemIndex) const
234{
235    return cpu->readArchVecElem(idx, elemIndex, thread->threadId());
236}
237
238template <class Impl>
239TheISA::CCReg
240O3ThreadContext<Impl>::readCCRegFlat(int reg_idx)
241{
242    return cpu->readArchCCReg(reg_idx, thread->threadId());
243}
244
245template <class Impl>
246void
247O3ThreadContext<Impl>::setIntRegFlat(int reg_idx, uint64_t val)
248{
249    cpu->setArchIntReg(reg_idx, val, thread->threadId());
250
251    conditionalSquash();
252}
253
254template <class Impl>
255void
256O3ThreadContext<Impl>::setFloatRegFlat(int reg_idx, FloatReg val)
257{
258    cpu->setArchFloatReg(reg_idx, val, thread->threadId());
259
260    conditionalSquash();
261}
262
263template <class Impl>
264void
265O3ThreadContext<Impl>::setFloatRegBitsFlat(int reg_idx, FloatRegBits val)
266{
267    cpu->setArchFloatRegInt(reg_idx, val, thread->threadId());
268
269    conditionalSquash();
270}
271
272template <class Impl>
273void
274O3ThreadContext<Impl>::setVecRegFlat(int reg_idx, const VecRegContainer& val)
275{
276    cpu->setArchVecReg(reg_idx, val, thread->threadId());
277
278    conditionalSquash();
279}
280
281template <class Impl>
282void
283O3ThreadContext<Impl>::setVecElemFlat(const RegIndex& idx,
284        const ElemIndex& elemIndex, const VecElem& val)
285{
286    cpu->setArchVecElem(idx, elemIndex, val, thread->threadId());
287    conditionalSquash();
288}
289
290template <class Impl>
291void
292O3ThreadContext<Impl>::setCCRegFlat(int reg_idx, TheISA::CCReg val)
293{
294    cpu->setArchCCReg(reg_idx, val, thread->threadId());
295
296    conditionalSquash();
297}
298
299template <class Impl>
300void
301O3ThreadContext<Impl>::pcState(const TheISA::PCState &val)
302{
303    cpu->pcState(val, thread->threadId());
304
305    conditionalSquash();
306}
307
308template <class Impl>
309void
310O3ThreadContext<Impl>::pcStateNoRecord(const TheISA::PCState &val)
311{
312    cpu->pcState(val, thread->threadId());
313
314    conditionalSquash();
315}
316
317template <class Impl>
318RegId
319O3ThreadContext<Impl>::flattenRegId(const RegId& regId) const
320{
321    return cpu->isa[thread->threadId()]->flattenRegId(regId);
322}
323
324template <class Impl>
325void
326O3ThreadContext<Impl>::setMiscRegNoEffect(int misc_reg, const MiscReg &val)
327{
328    cpu->setMiscRegNoEffect(misc_reg, val, thread->threadId());
329
330    conditionalSquash();
331}
332
333#endif//__CPU_O3_THREAD_CONTEXT_IMPL_HH__
334template <class Impl>
335void
336O3ThreadContext<Impl>::setMiscReg(int misc_reg, const MiscReg &val)
337{
338    cpu->setMiscReg(misc_reg, val, thread->threadId());
339
340    conditionalSquash();
341}
342
343