/* * Copyright (c) 2010-2012, 2016-2017 ARM Limited * Copyright (c) 2013 Advanced Micro Devices, Inc. * All rights reserved * * The license below extends only to copyright in the software and shall * not be construed as granting a license to any other intellectual * property including but not limited to intellectual property relating * to a hardware implementation of the functionality of the software * licensed hereunder. You may use the software subject to the license * terms below provided that you ensure that this notice is replicated * unmodified and in its entirety in all distributions of the software, * modified or unmodified, in source code or in binary form. * * Copyright (c) 2004-2006 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer; * redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution; * neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Kevin Lim * Korey Sewell */ #ifndef __CPU_O3_THREAD_CONTEXT_IMPL_HH__ #define __CPU_O3_THREAD_CONTEXT_IMPL_HH__ #include "arch/kernel_stats.hh" #include "arch/registers.hh" #include "config/the_isa.hh" #include "cpu/o3/thread_context.hh" #include "cpu/quiesce_event.hh" #include "debug/O3CPU.hh" template FSTranslatingPortProxy& O3ThreadContext::getVirtProxy() { return thread->getVirtProxy(); } template void O3ThreadContext::dumpFuncProfile() { thread->dumpFuncProfile(); } template void O3ThreadContext::takeOverFrom(ThreadContext *old_context) { ::takeOverFrom(*this, *old_context); TheISA::Decoder *newDecoder = getDecoderPtr(); TheISA::Decoder *oldDecoder = old_context->getDecoderPtr(); newDecoder->takeOverFrom(oldDecoder); thread->kernelStats = old_context->getKernelStats(); thread->funcExeInst = old_context->readFuncExeInst(); thread->noSquashFromTC = false; thread->trapPending = false; } template void O3ThreadContext::activate() { DPRINTF(O3CPU, "Calling activate on Thread Context %d\n", threadId()); if (thread->status() == ThreadContext::Active) return; thread->lastActivate = curTick(); thread->setStatus(ThreadContext::Active); // status() == Suspended cpu->activateContext(thread->threadId()); } template void O3ThreadContext::suspend() { DPRINTF(O3CPU, "Calling suspend on Thread Context %d\n", threadId()); if (thread->status() == ThreadContext::Suspended) return; if (cpu->isDraining()) { DPRINTF(O3CPU, "Ignoring suspend on TC due to pending drain\n"); return; } thread->lastActivate = curTick(); thread->lastSuspend = curTick(); thread->setStatus(ThreadContext::Suspended); cpu->suspendContext(thread->threadId()); } template void O3ThreadContext::halt() { DPRINTF(O3CPU, "Calling halt on Thread Context %d\n", threadId()); if (thread->status() == ThreadContext::Halted) return; thread->setStatus(ThreadContext::Halted); cpu->haltContext(thread->threadId()); } template void O3ThreadContext::regStats(const std::string &name) { if (FullSystem) { thread->kernelStats = new TheISA::Kernel::Statistics(); thread->kernelStats->regStats(name + ".kern"); } } template Tick O3ThreadContext::readLastActivate() { return thread->lastActivate; } template Tick O3ThreadContext::readLastSuspend() { return thread->lastSuspend; } template void O3ThreadContext::profileClear() { thread->profileClear(); } template void O3ThreadContext::profileSample() { thread->profileSample(); } template void O3ThreadContext::copyArchRegs(ThreadContext *tc) { // Prevent squashing thread->noSquashFromTC = true; TheISA::copyRegs(tc, this); thread->noSquashFromTC = false; if (!FullSystem) this->thread->funcExeInst = tc->readFuncExeInst(); } template void O3ThreadContext::clearArchRegs() { cpu->isa[thread->threadId()]->clear(); } template uint64_t O3ThreadContext::readIntRegFlat(int reg_idx) { return cpu->readArchIntReg(reg_idx, thread->threadId()); } template TheISA::FloatReg O3ThreadContext::readFloatRegFlat(int reg_idx) { return cpu->readArchFloatReg(reg_idx, thread->threadId()); } template TheISA::FloatRegBits O3ThreadContext::readFloatRegBitsFlat(int reg_idx) { return cpu->readArchFloatRegInt(reg_idx, thread->threadId()); } template const TheISA::VecRegContainer& O3ThreadContext::readVecRegFlat(int reg_id) const { return cpu->readArchVecReg(reg_id, thread->threadId()); } template TheISA::VecRegContainer& O3ThreadContext::getWritableVecRegFlat(int reg_id) { return cpu->getWritableArchVecReg(reg_id, thread->threadId()); } template const TheISA::VecElem& O3ThreadContext::readVecElemFlat(const RegIndex& idx, const ElemIndex& elemIndex) const { return cpu->readArchVecElem(idx, elemIndex, thread->threadId()); } template TheISA::CCReg O3ThreadContext::readCCRegFlat(int reg_idx) { return cpu->readArchCCReg(reg_idx, thread->threadId()); } template void O3ThreadContext::setIntRegFlat(int reg_idx, uint64_t val) { cpu->setArchIntReg(reg_idx, val, thread->threadId()); conditionalSquash(); } template void O3ThreadContext::setFloatRegFlat(int reg_idx, FloatReg val) { cpu->setArchFloatReg(reg_idx, val, thread->threadId()); conditionalSquash(); } template void O3ThreadContext::setFloatRegBitsFlat(int reg_idx, FloatRegBits val) { cpu->setArchFloatRegInt(reg_idx, val, thread->threadId()); conditionalSquash(); } template void O3ThreadContext::setVecRegFlat(int reg_idx, const VecRegContainer& val) { cpu->setArchVecReg(reg_idx, val, thread->threadId()); conditionalSquash(); } template void O3ThreadContext::setVecElemFlat(const RegIndex& idx, const ElemIndex& elemIndex, const VecElem& val) { cpu->setArchVecElem(idx, elemIndex, val, thread->threadId()); conditionalSquash(); } template void O3ThreadContext::setCCRegFlat(int reg_idx, TheISA::CCReg val) { cpu->setArchCCReg(reg_idx, val, thread->threadId()); conditionalSquash(); } template void O3ThreadContext::pcState(const TheISA::PCState &val) { cpu->pcState(val, thread->threadId()); conditionalSquash(); } template void O3ThreadContext::pcStateNoRecord(const TheISA::PCState &val) { cpu->pcState(val, thread->threadId()); conditionalSquash(); } template RegId O3ThreadContext::flattenRegId(const RegId& regId) const { return cpu->isa[thread->threadId()]->flattenRegId(regId); } template void O3ThreadContext::setMiscRegNoEffect(int misc_reg, const MiscReg &val) { cpu->setMiscRegNoEffect(misc_reg, val, thread->threadId()); conditionalSquash(); } #endif//__CPU_O3_THREAD_CONTEXT_IMPL_HH__ template void O3ThreadContext::setMiscReg(int misc_reg, const MiscReg &val) { cpu->setMiscReg(misc_reg, val, thread->threadId()); conditionalSquash(); }