thread_context.hh revision 13641:648f3106ebdf
110152Satgutier@umich.edu/* 210152Satgutier@umich.edu * Copyright (c) 2011-2012, 2016-2018 ARM Limited 310152Satgutier@umich.edu * Copyright (c) 2013 Advanced Micro Devices, Inc. 410152Satgutier@umich.edu * All rights reserved 510234Syasuko.eckert@amd.com * 610152Satgutier@umich.edu * The license below extends only to copyright in the software and shall 710152Satgutier@umich.edu * not be construed as granting a license to any other intellectual 810152Satgutier@umich.edu * property including but not limited to intellectual property relating 910152Satgutier@umich.edu * to a hardware implementation of the functionality of the software 1010152Satgutier@umich.edu * licensed hereunder. You may use the software subject to the license 1110152Satgutier@umich.edu * terms below provided that you ensure that this notice is replicated 1210152Satgutier@umich.edu * unmodified and in its entirety in all distributions of the software, 1310152Satgutier@umich.edu * modified or unmodified, in source code or in binary form. 1410152Satgutier@umich.edu * 1510152Satgutier@umich.edu * Copyright (c) 2006 The Regents of The University of Michigan 1610152Satgutier@umich.edu * All rights reserved. 1710152Satgutier@umich.edu * 1810152Satgutier@umich.edu * Redistribution and use in source and binary forms, with or without 1910152Satgutier@umich.edu * modification, are permitted provided that the following conditions are 2010152Satgutier@umich.edu * met: redistributions of source code must retain the above copyright 2110152Satgutier@umich.edu * notice, this list of conditions and the following disclaimer; 2210152Satgutier@umich.edu * redistributions in binary form must reproduce the above copyright 2310152Satgutier@umich.edu * notice, this list of conditions and the following disclaimer in the 2410152Satgutier@umich.edu * documentation and/or other materials provided with the distribution; 2510152Satgutier@umich.edu * neither the name of the copyright holders nor the names of its 2610152Satgutier@umich.edu * contributors may be used to endorse or promote products derived from 2710152Satgutier@umich.edu * this software without specific prior written permission. 2810152Satgutier@umich.edu * 2910234Syasuko.eckert@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3010152Satgutier@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3110152Satgutier@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3210152Satgutier@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3310152Satgutier@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3410152Satgutier@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3510152Satgutier@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3610152Satgutier@umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3710234Syasuko.eckert@amd.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3810152Satgutier@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3910152Satgutier@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4010152Satgutier@umich.edu * 4110234Syasuko.eckert@amd.com * Authors: Kevin Lim 4210234Syasuko.eckert@amd.com */ 4310152Satgutier@umich.edu 4410152Satgutier@umich.edu#ifndef __CPU_THREAD_CONTEXT_HH__ 4510152Satgutier@umich.edu#define __CPU_THREAD_CONTEXT_HH__ 4610152Satgutier@umich.edu 4710234Syasuko.eckert@amd.com#include <iostream> 4810234Syasuko.eckert@amd.com#include <string> 4910234Syasuko.eckert@amd.com 5010234Syasuko.eckert@amd.com#include "arch/registers.hh" 5110234Syasuko.eckert@amd.com#include "arch/types.hh" 5210234Syasuko.eckert@amd.com#include "base/types.hh" 5310234Syasuko.eckert@amd.com#include "config/the_isa.hh" 5410234Syasuko.eckert@amd.com#include "cpu/reg_class.hh" 5510234Syasuko.eckert@amd.com 5610234Syasuko.eckert@amd.com// @todo: Figure out a more architecture independent way to obtain the ITB and 5710234Syasuko.eckert@amd.com// DTB pointers. 5810234Syasuko.eckert@amd.comnamespace TheISA 5910234Syasuko.eckert@amd.com{ 6010234Syasuko.eckert@amd.com class Decoder; 6110234Syasuko.eckert@amd.com} 6210234Syasuko.eckert@amd.comclass BaseCPU; 6310234Syasuko.eckert@amd.comclass BaseTLB; 6410234Syasuko.eckert@amd.comclass CheckerCPU; 6510234Syasuko.eckert@amd.comclass Checkpoint; 6610234Syasuko.eckert@amd.comclass EndQuiesceEvent; 6710234Syasuko.eckert@amd.comclass SETranslatingPortProxy; 6810234Syasuko.eckert@amd.comclass FSTranslatingPortProxy; 6910234Syasuko.eckert@amd.comclass PortProxy; 7010234Syasuko.eckert@amd.comclass Process; 7110234Syasuko.eckert@amd.comclass System; 7210234Syasuko.eckert@amd.comnamespace TheISA { 7310234Syasuko.eckert@amd.com namespace Kernel { 7410234Syasuko.eckert@amd.com class Statistics; 7510234Syasuko.eckert@amd.com } 7610234Syasuko.eckert@amd.com} 7710234Syasuko.eckert@amd.com 7810234Syasuko.eckert@amd.com/** 7910234Syasuko.eckert@amd.com * ThreadContext is the external interface to all thread state for 8010234Syasuko.eckert@amd.com * anything outside of the CPU. It provides all accessor methods to 8110234Syasuko.eckert@amd.com * state that might be needed by external objects, ranging from 8210234Syasuko.eckert@amd.com * register values to things such as kernel stats. It is an abstract 8310234Syasuko.eckert@amd.com * base class; the CPU can create its own ThreadContext by either 8410234Syasuko.eckert@amd.com * deriving from it, or using the templated ProxyThreadContext. 8510234Syasuko.eckert@amd.com * 8610234Syasuko.eckert@amd.com * The ThreadContext is slightly different than the ExecContext. The 8710234Syasuko.eckert@amd.com * ThreadContext provides access to an individual thread's state; an 8810234Syasuko.eckert@amd.com * ExecContext provides ISA access to the CPU (meaning it is 8910234Syasuko.eckert@amd.com * implicitly multithreaded on SMT systems). Additionally the 9010234Syasuko.eckert@amd.com * ThreadState is an abstract class that exactly defines the 9110234Syasuko.eckert@amd.com * interface; the ExecContext is a more implicit interface that must 9210234Syasuko.eckert@amd.com * be implemented so that the ISA can access whatever state it needs. 9310234Syasuko.eckert@amd.com */ 9410234Syasuko.eckert@amd.comclass ThreadContext 9510234Syasuko.eckert@amd.com{ 9610234Syasuko.eckert@amd.com protected: 9710234Syasuko.eckert@amd.com typedef TheISA::MachInst MachInst; 9810234Syasuko.eckert@amd.com using VecRegContainer = TheISA::VecRegContainer; 9910234Syasuko.eckert@amd.com using VecElem = TheISA::VecElem; 10010234Syasuko.eckert@amd.com using VecPredRegContainer = TheISA::VecPredRegContainer; 10110234Syasuko.eckert@amd.com 10210234Syasuko.eckert@amd.com public: 10310234Syasuko.eckert@amd.com 10410234Syasuko.eckert@amd.com enum Status 10510234Syasuko.eckert@amd.com { 10610234Syasuko.eckert@amd.com /// Running. Instructions should be executed only when 10710234Syasuko.eckert@amd.com /// the context is in this state. 10810234Syasuko.eckert@amd.com Active, 10910234Syasuko.eckert@amd.com 11010234Syasuko.eckert@amd.com /// Temporarily inactive. Entered while waiting for 11110234Syasuko.eckert@amd.com /// synchronization, etc. 11210234Syasuko.eckert@amd.com Suspended, 11310234Syasuko.eckert@amd.com 11410234Syasuko.eckert@amd.com /// Trying to exit and waiting for an event to completely exit. 11510234Syasuko.eckert@amd.com /// Entered when target executes an exit syscall. 11610234Syasuko.eckert@amd.com Halting, 11710234Syasuko.eckert@amd.com 11810234Syasuko.eckert@amd.com /// Permanently shut down. Entered when target executes 11910234Syasuko.eckert@amd.com /// m5exit pseudo-instruction. When all contexts enter 12010234Syasuko.eckert@amd.com /// this state, the simulation will terminate. 12110234Syasuko.eckert@amd.com Halted 12210234Syasuko.eckert@amd.com }; 12310234Syasuko.eckert@amd.com 12410234Syasuko.eckert@amd.com virtual ~ThreadContext() { }; 12510234Syasuko.eckert@amd.com 12610234Syasuko.eckert@amd.com virtual BaseCPU *getCpuPtr() = 0; 12710234Syasuko.eckert@amd.com 12810234Syasuko.eckert@amd.com virtual int cpuId() const = 0; 12910234Syasuko.eckert@amd.com 13010234Syasuko.eckert@amd.com virtual uint32_t socketId() const = 0; 13110234Syasuko.eckert@amd.com 13210234Syasuko.eckert@amd.com virtual int threadId() const = 0; 13310234Syasuko.eckert@amd.com 13410234Syasuko.eckert@amd.com virtual void setThreadId(int id) = 0; 13510234Syasuko.eckert@amd.com 13610234Syasuko.eckert@amd.com virtual int contextId() const = 0; 13710234Syasuko.eckert@amd.com 13810234Syasuko.eckert@amd.com virtual void setContextId(int id) = 0; 13910234Syasuko.eckert@amd.com 14010234Syasuko.eckert@amd.com virtual BaseTLB *getITBPtr() = 0; 14110234Syasuko.eckert@amd.com 14210234Syasuko.eckert@amd.com virtual BaseTLB *getDTBPtr() = 0; 14310234Syasuko.eckert@amd.com 14410234Syasuko.eckert@amd.com virtual CheckerCPU *getCheckerCpuPtr() = 0; 14510234Syasuko.eckert@amd.com 14610234Syasuko.eckert@amd.com virtual TheISA::Decoder *getDecoderPtr() = 0; 14710234Syasuko.eckert@amd.com 14810234Syasuko.eckert@amd.com virtual System *getSystemPtr() = 0; 14910234Syasuko.eckert@amd.com 15010234Syasuko.eckert@amd.com virtual TheISA::Kernel::Statistics *getKernelStats() = 0; 15110234Syasuko.eckert@amd.com 15210234Syasuko.eckert@amd.com virtual PortProxy &getPhysProxy() = 0; 15310234Syasuko.eckert@amd.com 15410234Syasuko.eckert@amd.com virtual FSTranslatingPortProxy &getVirtProxy() = 0; 15510234Syasuko.eckert@amd.com 15610234Syasuko.eckert@amd.com /** 15710234Syasuko.eckert@amd.com * Initialise the physical and virtual port proxies and tie them to 15810234Syasuko.eckert@amd.com * the data port of the CPU. 15910234Syasuko.eckert@amd.com * 16010234Syasuko.eckert@amd.com * tc ThreadContext for the virtual-to-physical translation 16110234Syasuko.eckert@amd.com */ 16210234Syasuko.eckert@amd.com virtual void initMemProxies(ThreadContext *tc) = 0; 16310234Syasuko.eckert@amd.com 16410234Syasuko.eckert@amd.com virtual SETranslatingPortProxy &getMemProxy() = 0; 16510234Syasuko.eckert@amd.com 16610234Syasuko.eckert@amd.com virtual Process *getProcessPtr() = 0; 16710234Syasuko.eckert@amd.com 16810234Syasuko.eckert@amd.com virtual void setProcessPtr(Process *p) = 0; 16910234Syasuko.eckert@amd.com 17010234Syasuko.eckert@amd.com virtual Status status() const = 0; 17110234Syasuko.eckert@amd.com 17210234Syasuko.eckert@amd.com virtual void setStatus(Status new_status) = 0; 17310234Syasuko.eckert@amd.com 17410234Syasuko.eckert@amd.com /// Set the status to Active. 17510234Syasuko.eckert@amd.com virtual void activate() = 0; 17610234Syasuko.eckert@amd.com 17710234Syasuko.eckert@amd.com /// Set the status to Suspended. 17810234Syasuko.eckert@amd.com virtual void suspend() = 0; 17910234Syasuko.eckert@amd.com 18010234Syasuko.eckert@amd.com /// Set the status to Halted. 18110234Syasuko.eckert@amd.com virtual void halt() = 0; 18210234Syasuko.eckert@amd.com 18310234Syasuko.eckert@amd.com /// Quiesce thread context 18410234Syasuko.eckert@amd.com void quiesce(); 18510234Syasuko.eckert@amd.com 18610234Syasuko.eckert@amd.com /// Quiesce, suspend, and schedule activate at resume 18710234Syasuko.eckert@amd.com void quiesceTick(Tick resume); 18810234Syasuko.eckert@amd.com 18910234Syasuko.eckert@amd.com virtual void dumpFuncProfile() = 0; 19010234Syasuko.eckert@amd.com 19110234Syasuko.eckert@amd.com virtual void takeOverFrom(ThreadContext *old_context) = 0; 19210234Syasuko.eckert@amd.com 19310234Syasuko.eckert@amd.com virtual void regStats(const std::string &name) = 0; 19410234Syasuko.eckert@amd.com 19510234Syasuko.eckert@amd.com virtual EndQuiesceEvent *getQuiesceEvent() = 0; 19610234Syasuko.eckert@amd.com 19710234Syasuko.eckert@amd.com // Not necessarily the best location for these... 19810234Syasuko.eckert@amd.com // Having an extra function just to read these is obnoxious 19910234Syasuko.eckert@amd.com virtual Tick readLastActivate() = 0; 20010234Syasuko.eckert@amd.com virtual Tick readLastSuspend() = 0; 20110234Syasuko.eckert@amd.com 20210234Syasuko.eckert@amd.com virtual void profileClear() = 0; 20310234Syasuko.eckert@amd.com virtual void profileSample() = 0; 20410234Syasuko.eckert@amd.com 20510152Satgutier@umich.edu virtual void copyArchRegs(ThreadContext *tc) = 0; 20610152Satgutier@umich.edu 20710234Syasuko.eckert@amd.com virtual void clearArchRegs() = 0; 20810234Syasuko.eckert@amd.com 20910234Syasuko.eckert@amd.com // 21010234Syasuko.eckert@amd.com // New accessors for new decoder. 21110234Syasuko.eckert@amd.com // 21210234Syasuko.eckert@amd.com virtual RegVal readIntReg(int reg_idx) = 0; 21310234Syasuko.eckert@amd.com 21410234Syasuko.eckert@amd.com virtual RegVal readFloatReg(int reg_idx) = 0; 21510234Syasuko.eckert@amd.com 21610234Syasuko.eckert@amd.com virtual const VecRegContainer& readVecReg(const RegId& reg) const = 0; 21710234Syasuko.eckert@amd.com virtual VecRegContainer& getWritableVecReg(const RegId& reg) = 0; 21810234Syasuko.eckert@amd.com 21910234Syasuko.eckert@amd.com /** Vector Register Lane Interfaces. */ 22010234Syasuko.eckert@amd.com /** @{ */ 22110234Syasuko.eckert@amd.com /** Reads source vector 8bit operand. */ 22210234Syasuko.eckert@amd.com virtual ConstVecLane8 22310234Syasuko.eckert@amd.com readVec8BitLaneReg(const RegId& reg) const = 0; 22410234Syasuko.eckert@amd.com 22510234Syasuko.eckert@amd.com /** Reads source vector 16bit operand. */ 22610234Syasuko.eckert@amd.com virtual ConstVecLane16 22710234Syasuko.eckert@amd.com readVec16BitLaneReg(const RegId& reg) const = 0; 22810234Syasuko.eckert@amd.com 22910234Syasuko.eckert@amd.com /** Reads source vector 32bit operand. */ 23010234Syasuko.eckert@amd.com virtual ConstVecLane32 23110234Syasuko.eckert@amd.com readVec32BitLaneReg(const RegId& reg) const = 0; 23210234Syasuko.eckert@amd.com 23310234Syasuko.eckert@amd.com /** Reads source vector 64bit operand. */ 23410234Syasuko.eckert@amd.com virtual ConstVecLane64 23510234Syasuko.eckert@amd.com readVec64BitLaneReg(const RegId& reg) const = 0; 23610234Syasuko.eckert@amd.com 23710234Syasuko.eckert@amd.com /** Write a lane of the destination vector register. */ 23810234Syasuko.eckert@amd.com virtual void setVecLane(const RegId& reg, 23910234Syasuko.eckert@amd.com const LaneData<LaneSize::Byte>& val) = 0; 24010234Syasuko.eckert@amd.com virtual void setVecLane(const RegId& reg, 24110234Syasuko.eckert@amd.com const LaneData<LaneSize::TwoByte>& val) = 0; 24210234Syasuko.eckert@amd.com virtual void setVecLane(const RegId& reg, 24310234Syasuko.eckert@amd.com const LaneData<LaneSize::FourByte>& val) = 0; 24410234Syasuko.eckert@amd.com virtual void setVecLane(const RegId& reg, 24510234Syasuko.eckert@amd.com const LaneData<LaneSize::EightByte>& val) = 0; 24610234Syasuko.eckert@amd.com /** @} */ 24710234Syasuko.eckert@amd.com 24810234Syasuko.eckert@amd.com virtual const VecElem& readVecElem(const RegId& reg) const = 0; 24910234Syasuko.eckert@amd.com 25010234Syasuko.eckert@amd.com virtual const VecPredRegContainer& readVecPredReg(const RegId& reg) 25110234Syasuko.eckert@amd.com const = 0; 25210234Syasuko.eckert@amd.com virtual VecPredRegContainer& getWritableVecPredReg(const RegId& reg) = 0; 25310234Syasuko.eckert@amd.com 25410234Syasuko.eckert@amd.com virtual RegVal readCCReg(int reg_idx) = 0; 25510234Syasuko.eckert@amd.com 25610234Syasuko.eckert@amd.com virtual void setIntReg(int reg_idx, RegVal val) = 0; 25710234Syasuko.eckert@amd.com 25810234Syasuko.eckert@amd.com virtual void setFloatReg(int reg_idx, RegVal val) = 0; 25910234Syasuko.eckert@amd.com 26010234Syasuko.eckert@amd.com virtual void setVecReg(const RegId& reg, const VecRegContainer& val) = 0; 26110234Syasuko.eckert@amd.com 26210234Syasuko.eckert@amd.com virtual void setVecElem(const RegId& reg, const VecElem& val) = 0; 26310234Syasuko.eckert@amd.com 26410234Syasuko.eckert@amd.com virtual void setVecPredReg(const RegId& reg, 26510234Syasuko.eckert@amd.com const VecPredRegContainer& val) = 0; 26610234Syasuko.eckert@amd.com 26710234Syasuko.eckert@amd.com virtual void setCCReg(int reg_idx, RegVal val) = 0; 26810234Syasuko.eckert@amd.com 26910234Syasuko.eckert@amd.com virtual TheISA::PCState pcState() = 0; 27010234Syasuko.eckert@amd.com 27110234Syasuko.eckert@amd.com virtual void pcState(const TheISA::PCState &val) = 0; 27210234Syasuko.eckert@amd.com 27310234Syasuko.eckert@amd.com void 27410234Syasuko.eckert@amd.com setNPC(Addr val) 27510234Syasuko.eckert@amd.com { 27610234Syasuko.eckert@amd.com TheISA::PCState pc_state = pcState(); 27710234Syasuko.eckert@amd.com pc_state.setNPC(val); 27810234Syasuko.eckert@amd.com pcState(pc_state); 27910234Syasuko.eckert@amd.com } 28010234Syasuko.eckert@amd.com 28110234Syasuko.eckert@amd.com virtual void pcStateNoRecord(const TheISA::PCState &val) = 0; 28210234Syasuko.eckert@amd.com 28310234Syasuko.eckert@amd.com virtual Addr instAddr() = 0; 28410234Syasuko.eckert@amd.com 28510234Syasuko.eckert@amd.com virtual Addr nextInstAddr() = 0; 28610234Syasuko.eckert@amd.com 28710234Syasuko.eckert@amd.com virtual MicroPC microPC() = 0; 28810234Syasuko.eckert@amd.com 28910234Syasuko.eckert@amd.com virtual RegVal readMiscRegNoEffect(int misc_reg) const = 0; 29010234Syasuko.eckert@amd.com 29110234Syasuko.eckert@amd.com virtual RegVal readMiscReg(int misc_reg) = 0; 29210234Syasuko.eckert@amd.com 29310234Syasuko.eckert@amd.com virtual void setMiscRegNoEffect(int misc_reg, RegVal val) = 0; 29410234Syasuko.eckert@amd.com 29510234Syasuko.eckert@amd.com virtual void setMiscReg(int misc_reg, RegVal val) = 0; 29610234Syasuko.eckert@amd.com 29710234Syasuko.eckert@amd.com virtual RegId flattenRegId(const RegId& regId) const = 0; 29810234Syasuko.eckert@amd.com 29910234Syasuko.eckert@amd.com virtual RegVal 30010234Syasuko.eckert@amd.com readRegOtherThread(const RegId& misc_reg, ThreadID tid) 30110234Syasuko.eckert@amd.com { 30210234Syasuko.eckert@amd.com return 0; 30310234Syasuko.eckert@amd.com } 30410234Syasuko.eckert@amd.com 30510234Syasuko.eckert@amd.com virtual void 30610234Syasuko.eckert@amd.com setRegOtherThread(const RegId& misc_reg, RegVal val, ThreadID tid) 30710234Syasuko.eckert@amd.com { 30810234Syasuko.eckert@amd.com } 30910234Syasuko.eckert@amd.com 31010234Syasuko.eckert@amd.com // Also not necessarily the best location for these two. Hopefully will go 31110234Syasuko.eckert@amd.com // away once we decide upon where st cond failures goes. 31210234Syasuko.eckert@amd.com virtual unsigned readStCondFailures() = 0; 31310234Syasuko.eckert@amd.com 31410234Syasuko.eckert@amd.com virtual void setStCondFailures(unsigned sc_failures) = 0; 31510234Syasuko.eckert@amd.com 31610234Syasuko.eckert@amd.com // Same with st cond failures. 31710234Syasuko.eckert@amd.com virtual Counter readFuncExeInst() = 0; 31810234Syasuko.eckert@amd.com 31910234Syasuko.eckert@amd.com virtual void syscall(int64_t callnum, Fault *fault) = 0; 32010234Syasuko.eckert@amd.com 32110234Syasuko.eckert@amd.com // This function exits the thread context in the CPU and returns 32210234Syasuko.eckert@amd.com // 1 if the CPU has no more active threads (meaning it's OK to exit); 32310234Syasuko.eckert@amd.com // Used in syscall-emulation mode when a thread calls the exit syscall. 32410234Syasuko.eckert@amd.com virtual int exit() { return 1; }; 32510234Syasuko.eckert@amd.com 32610234Syasuko.eckert@amd.com /** function to compare two thread contexts (for debugging) */ 32710234Syasuko.eckert@amd.com static void compare(ThreadContext *one, ThreadContext *two); 32810234Syasuko.eckert@amd.com 32910234Syasuko.eckert@amd.com /** @{ */ 33010234Syasuko.eckert@amd.com /** 33110234Syasuko.eckert@amd.com * Flat register interfaces 33210234Syasuko.eckert@amd.com * 33310234Syasuko.eckert@amd.com * Some architectures have different registers visible in 33410234Syasuko.eckert@amd.com * different modes. Such architectures "flatten" a register (see 33510234Syasuko.eckert@amd.com * flattenRegId()) to map it into the 33610234Syasuko.eckert@amd.com * gem5 register file. This interface provides a flat interface to 33710234Syasuko.eckert@amd.com * the underlying register file, which allows for example 33810234Syasuko.eckert@amd.com * serialization code to access all registers. 33910234Syasuko.eckert@amd.com */ 34010234Syasuko.eckert@amd.com 34110234Syasuko.eckert@amd.com virtual RegVal readIntRegFlat(int idx) = 0; 34210234Syasuko.eckert@amd.com virtual void setIntRegFlat(int idx, RegVal val) = 0; 34310234Syasuko.eckert@amd.com 34410234Syasuko.eckert@amd.com virtual RegVal readFloatRegFlat(int idx) = 0; 34510234Syasuko.eckert@amd.com virtual void setFloatRegFlat(int idx, RegVal val) = 0; 34610234Syasuko.eckert@amd.com 34710234Syasuko.eckert@amd.com virtual const VecRegContainer& readVecRegFlat(int idx) const = 0; 34810234Syasuko.eckert@amd.com virtual VecRegContainer& getWritableVecRegFlat(int idx) = 0; 34910234Syasuko.eckert@amd.com virtual void setVecRegFlat(int idx, const VecRegContainer& val) = 0; 35010234Syasuko.eckert@amd.com 35110234Syasuko.eckert@amd.com virtual const VecElem& readVecElemFlat(const RegIndex& idx, 35210234Syasuko.eckert@amd.com const ElemIndex& elemIdx) const = 0; 35310234Syasuko.eckert@amd.com virtual void setVecElemFlat(const RegIndex& idx, const ElemIndex& elemIdx, 35410234Syasuko.eckert@amd.com const VecElem& val) = 0; 35510234Syasuko.eckert@amd.com 35610234Syasuko.eckert@amd.com virtual const VecPredRegContainer& readVecPredRegFlat(int idx) const = 0; 35710234Syasuko.eckert@amd.com virtual VecPredRegContainer& getWritableVecPredRegFlat(int idx) = 0; 35810234Syasuko.eckert@amd.com virtual void setVecPredRegFlat(int idx, 35910234Syasuko.eckert@amd.com const VecPredRegContainer& val) = 0; 36010234Syasuko.eckert@amd.com 36110234Syasuko.eckert@amd.com virtual RegVal readCCRegFlat(int idx) = 0; 36210234Syasuko.eckert@amd.com virtual void setCCRegFlat(int idx, RegVal val) = 0; 36310234Syasuko.eckert@amd.com /** @} */ 36410234Syasuko.eckert@amd.com 36510234Syasuko.eckert@amd.com}; 36610234Syasuko.eckert@amd.com 36710234Syasuko.eckert@amd.com/** 36810234Syasuko.eckert@amd.com * ProxyThreadContext class that provides a way to implement a 36910234Syasuko.eckert@amd.com * ThreadContext without having to derive from it. ThreadContext is an 37010234Syasuko.eckert@amd.com * abstract class, so anything that derives from it and uses its 37110234Syasuko.eckert@amd.com * interface will pay the overhead of virtual function calls. This 37210234Syasuko.eckert@amd.com * class is created to enable a user-defined Thread object to be used 37310234Syasuko.eckert@amd.com * wherever ThreadContexts are used, without paying the overhead of 37410234Syasuko.eckert@amd.com * virtual function calls when it is used by itself. See 37510234Syasuko.eckert@amd.com * simple_thread.hh for an example of this. 37610234Syasuko.eckert@amd.com */ 37710234Syasuko.eckert@amd.comtemplate <class TC> 37810234Syasuko.eckert@amd.comclass ProxyThreadContext : public ThreadContext 37910234Syasuko.eckert@amd.com{ 38010234Syasuko.eckert@amd.com public: 38110234Syasuko.eckert@amd.com ProxyThreadContext(TC *actual_tc) 38210234Syasuko.eckert@amd.com { actualTC = actual_tc; } 38310234Syasuko.eckert@amd.com 38410234Syasuko.eckert@amd.com private: 38510234Syasuko.eckert@amd.com TC *actualTC; 38610234Syasuko.eckert@amd.com 38710234Syasuko.eckert@amd.com public: 38810234Syasuko.eckert@amd.com 38910234Syasuko.eckert@amd.com BaseCPU *getCpuPtr() { return actualTC->getCpuPtr(); } 39010234Syasuko.eckert@amd.com 39110234Syasuko.eckert@amd.com int cpuId() const { return actualTC->cpuId(); } 39210234Syasuko.eckert@amd.com 39310234Syasuko.eckert@amd.com uint32_t socketId() const { return actualTC->socketId(); } 39410234Syasuko.eckert@amd.com 39510234Syasuko.eckert@amd.com int threadId() const { return actualTC->threadId(); } 39610234Syasuko.eckert@amd.com 39710234Syasuko.eckert@amd.com void setThreadId(int id) { actualTC->setThreadId(id); } 39810234Syasuko.eckert@amd.com 39910234Syasuko.eckert@amd.com int contextId() const { return actualTC->contextId(); } 40010234Syasuko.eckert@amd.com 40110234Syasuko.eckert@amd.com void setContextId(int id) { actualTC->setContextId(id); } 40210234Syasuko.eckert@amd.com 40310234Syasuko.eckert@amd.com BaseTLB *getITBPtr() { return actualTC->getITBPtr(); } 40410234Syasuko.eckert@amd.com 40510234Syasuko.eckert@amd.com BaseTLB *getDTBPtr() { return actualTC->getDTBPtr(); } 40610234Syasuko.eckert@amd.com 40710234Syasuko.eckert@amd.com CheckerCPU *getCheckerCpuPtr() { return actualTC->getCheckerCpuPtr(); } 40810234Syasuko.eckert@amd.com 40910234Syasuko.eckert@amd.com TheISA::Decoder *getDecoderPtr() { return actualTC->getDecoderPtr(); } 41010234Syasuko.eckert@amd.com 41110234Syasuko.eckert@amd.com System *getSystemPtr() { return actualTC->getSystemPtr(); } 41210234Syasuko.eckert@amd.com 41310234Syasuko.eckert@amd.com TheISA::Kernel::Statistics *getKernelStats() 41410234Syasuko.eckert@amd.com { return actualTC->getKernelStats(); } 41510234Syasuko.eckert@amd.com 41610234Syasuko.eckert@amd.com PortProxy &getPhysProxy() { return actualTC->getPhysProxy(); } 41710234Syasuko.eckert@amd.com 41810234Syasuko.eckert@amd.com FSTranslatingPortProxy &getVirtProxy() { return actualTC->getVirtProxy(); } 41910234Syasuko.eckert@amd.com 42010234Syasuko.eckert@amd.com void initMemProxies(ThreadContext *tc) { actualTC->initMemProxies(tc); } 42110234Syasuko.eckert@amd.com 42210234Syasuko.eckert@amd.com SETranslatingPortProxy &getMemProxy() { return actualTC->getMemProxy(); } 42310234Syasuko.eckert@amd.com 42410234Syasuko.eckert@amd.com Process *getProcessPtr() { return actualTC->getProcessPtr(); } 42510234Syasuko.eckert@amd.com 42610234Syasuko.eckert@amd.com void setProcessPtr(Process *p) { actualTC->setProcessPtr(p); } 42710234Syasuko.eckert@amd.com 42810234Syasuko.eckert@amd.com Status status() const { return actualTC->status(); } 42910234Syasuko.eckert@amd.com 43010234Syasuko.eckert@amd.com void setStatus(Status new_status) { actualTC->setStatus(new_status); } 43110234Syasuko.eckert@amd.com 43210234Syasuko.eckert@amd.com /// Set the status to Active. 43310234Syasuko.eckert@amd.com void activate() { actualTC->activate(); } 43410234Syasuko.eckert@amd.com 43510234Syasuko.eckert@amd.com /// Set the status to Suspended. 43610234Syasuko.eckert@amd.com void suspend() { actualTC->suspend(); } 43710234Syasuko.eckert@amd.com 43810234Syasuko.eckert@amd.com /// Set the status to Halted. 43910234Syasuko.eckert@amd.com void halt() { actualTC->halt(); } 44010234Syasuko.eckert@amd.com 44110234Syasuko.eckert@amd.com /// Quiesce thread context 44210234Syasuko.eckert@amd.com void quiesce() { actualTC->quiesce(); } 44310234Syasuko.eckert@amd.com 44410234Syasuko.eckert@amd.com /// Quiesce, suspend, and schedule activate at resume 44510234Syasuko.eckert@amd.com void quiesceTick(Tick resume) { actualTC->quiesceTick(resume); } 44610234Syasuko.eckert@amd.com 44710234Syasuko.eckert@amd.com void dumpFuncProfile() { actualTC->dumpFuncProfile(); } 44810234Syasuko.eckert@amd.com 44910234Syasuko.eckert@amd.com void takeOverFrom(ThreadContext *oldContext) 45010234Syasuko.eckert@amd.com { actualTC->takeOverFrom(oldContext); } 45110234Syasuko.eckert@amd.com 45210234Syasuko.eckert@amd.com void regStats(const std::string &name) { actualTC->regStats(name); } 45310234Syasuko.eckert@amd.com 45410234Syasuko.eckert@amd.com EndQuiesceEvent *getQuiesceEvent() { return actualTC->getQuiesceEvent(); } 45510234Syasuko.eckert@amd.com 45610234Syasuko.eckert@amd.com Tick readLastActivate() { return actualTC->readLastActivate(); } 45710234Syasuko.eckert@amd.com Tick readLastSuspend() { return actualTC->readLastSuspend(); } 45810234Syasuko.eckert@amd.com 45910234Syasuko.eckert@amd.com void profileClear() { return actualTC->profileClear(); } 46010234Syasuko.eckert@amd.com void profileSample() { return actualTC->profileSample(); } 46110234Syasuko.eckert@amd.com 46210234Syasuko.eckert@amd.com // @todo: Do I need this? 46310234Syasuko.eckert@amd.com void copyArchRegs(ThreadContext *tc) { actualTC->copyArchRegs(tc); } 46410234Syasuko.eckert@amd.com 46510234Syasuko.eckert@amd.com void clearArchRegs() { actualTC->clearArchRegs(); } 46610234Syasuko.eckert@amd.com 46710234Syasuko.eckert@amd.com // 46810234Syasuko.eckert@amd.com // New accessors for new decoder. 46910234Syasuko.eckert@amd.com // 47010234Syasuko.eckert@amd.com RegVal readIntReg(int reg_idx) 47110234Syasuko.eckert@amd.com { return actualTC->readIntReg(reg_idx); } 47210234Syasuko.eckert@amd.com 47310234Syasuko.eckert@amd.com RegVal readFloatReg(int reg_idx) 47410234Syasuko.eckert@amd.com { return actualTC->readFloatReg(reg_idx); } 47510234Syasuko.eckert@amd.com 47610234Syasuko.eckert@amd.com const VecRegContainer& readVecReg(const RegId& reg) const 47710234Syasuko.eckert@amd.com { return actualTC->readVecReg(reg); } 47810234Syasuko.eckert@amd.com 47910234Syasuko.eckert@amd.com VecRegContainer& getWritableVecReg(const RegId& reg) 48010234Syasuko.eckert@amd.com { return actualTC->getWritableVecReg(reg); } 48110234Syasuko.eckert@amd.com 48210234Syasuko.eckert@amd.com /** Vector Register Lane Interfaces. */ 48310234Syasuko.eckert@amd.com /** @{ */ 48410234Syasuko.eckert@amd.com /** Reads source vector 8bit operand. */ 48510234Syasuko.eckert@amd.com ConstVecLane8 48610234Syasuko.eckert@amd.com readVec8BitLaneReg(const RegId& reg) const 48710234Syasuko.eckert@amd.com { return actualTC->readVec8BitLaneReg(reg); } 48810234Syasuko.eckert@amd.com 48910234Syasuko.eckert@amd.com /** Reads source vector 16bit operand. */ 49010234Syasuko.eckert@amd.com ConstVecLane16 49110234Syasuko.eckert@amd.com readVec16BitLaneReg(const RegId& reg) const 49210234Syasuko.eckert@amd.com { return actualTC->readVec16BitLaneReg(reg); } 49310234Syasuko.eckert@amd.com 49410234Syasuko.eckert@amd.com /** Reads source vector 32bit operand. */ 49510234Syasuko.eckert@amd.com ConstVecLane32 49610234Syasuko.eckert@amd.com readVec32BitLaneReg(const RegId& reg) const 49710234Syasuko.eckert@amd.com { return actualTC->readVec32BitLaneReg(reg); } 49810234Syasuko.eckert@amd.com 49910234Syasuko.eckert@amd.com /** Reads source vector 64bit operand. */ 50010234Syasuko.eckert@amd.com ConstVecLane64 50110234Syasuko.eckert@amd.com readVec64BitLaneReg(const RegId& reg) const 50210234Syasuko.eckert@amd.com { return actualTC->readVec64BitLaneReg(reg); } 50310234Syasuko.eckert@amd.com 50410234Syasuko.eckert@amd.com /** Write a lane of the destination vector register. */ 50510234Syasuko.eckert@amd.com virtual void setVecLane(const RegId& reg, 50610234Syasuko.eckert@amd.com const LaneData<LaneSize::Byte>& val) 50710234Syasuko.eckert@amd.com { return actualTC->setVecLane(reg, val); } 50810234Syasuko.eckert@amd.com virtual void setVecLane(const RegId& reg, 50910234Syasuko.eckert@amd.com const LaneData<LaneSize::TwoByte>& val) 51010234Syasuko.eckert@amd.com { return actualTC->setVecLane(reg, val); } 51110234Syasuko.eckert@amd.com virtual void setVecLane(const RegId& reg, 51210234Syasuko.eckert@amd.com const LaneData<LaneSize::FourByte>& val) 51310234Syasuko.eckert@amd.com { return actualTC->setVecLane(reg, val); } 51410234Syasuko.eckert@amd.com virtual void setVecLane(const RegId& reg, 51510234Syasuko.eckert@amd.com const LaneData<LaneSize::EightByte>& val) 51610234Syasuko.eckert@amd.com { return actualTC->setVecLane(reg, val); } 51710234Syasuko.eckert@amd.com /** @} */ 51810234Syasuko.eckert@amd.com 51910234Syasuko.eckert@amd.com const VecElem& readVecElem(const RegId& reg) const 52010234Syasuko.eckert@amd.com { return actualTC->readVecElem(reg); } 52110234Syasuko.eckert@amd.com 52210234Syasuko.eckert@amd.com const VecPredRegContainer& readVecPredReg(const RegId& reg) const 52310234Syasuko.eckert@amd.com { return actualTC->readVecPredReg(reg); } 52410234Syasuko.eckert@amd.com 52510234Syasuko.eckert@amd.com VecPredRegContainer& getWritableVecPredReg(const RegId& reg) 52610234Syasuko.eckert@amd.com { return actualTC->getWritableVecPredReg(reg); } 52710234Syasuko.eckert@amd.com 52810234Syasuko.eckert@amd.com RegVal readCCReg(int reg_idx) 52910234Syasuko.eckert@amd.com { return actualTC->readCCReg(reg_idx); } 53010234Syasuko.eckert@amd.com 53110234Syasuko.eckert@amd.com void setIntReg(int reg_idx, RegVal val) 53210234Syasuko.eckert@amd.com { actualTC->setIntReg(reg_idx, val); } 53310234Syasuko.eckert@amd.com 53410234Syasuko.eckert@amd.com void setFloatReg(int reg_idx, RegVal val) 53510234Syasuko.eckert@amd.com { actualTC->setFloatReg(reg_idx, val); } 53610234Syasuko.eckert@amd.com 53710234Syasuko.eckert@amd.com void setVecReg(const RegId& reg, const VecRegContainer& val) 53810234Syasuko.eckert@amd.com { actualTC->setVecReg(reg, val); } 53910234Syasuko.eckert@amd.com 54010234Syasuko.eckert@amd.com void setVecPredReg(const RegId& reg, const VecPredRegContainer& val) 54110234Syasuko.eckert@amd.com { actualTC->setVecPredReg(reg, val); } 54210234Syasuko.eckert@amd.com 54310234Syasuko.eckert@amd.com void setVecElem(const RegId& reg, const VecElem& val) 54410234Syasuko.eckert@amd.com { actualTC->setVecElem(reg, val); } 54510234Syasuko.eckert@amd.com 54610234Syasuko.eckert@amd.com void setCCReg(int reg_idx, RegVal val) 54710234Syasuko.eckert@amd.com { actualTC->setCCReg(reg_idx, val); } 54810234Syasuko.eckert@amd.com 54910234Syasuko.eckert@amd.com TheISA::PCState pcState() { return actualTC->pcState(); } 55010234Syasuko.eckert@amd.com 55110234Syasuko.eckert@amd.com void pcState(const TheISA::PCState &val) { actualTC->pcState(val); } 55210234Syasuko.eckert@amd.com 55310234Syasuko.eckert@amd.com void pcStateNoRecord(const TheISA::PCState &val) { actualTC->pcState(val); } 55410234Syasuko.eckert@amd.com 55510234Syasuko.eckert@amd.com Addr instAddr() { return actualTC->instAddr(); } 55610234Syasuko.eckert@amd.com Addr nextInstAddr() { return actualTC->nextInstAddr(); } 55710234Syasuko.eckert@amd.com MicroPC microPC() { return actualTC->microPC(); } 55810234Syasuko.eckert@amd.com 55910234Syasuko.eckert@amd.com bool readPredicate() { return actualTC->readPredicate(); } 56010234Syasuko.eckert@amd.com 56110234Syasuko.eckert@amd.com void setPredicate(bool val) 56210234Syasuko.eckert@amd.com { actualTC->setPredicate(val); } 56310234Syasuko.eckert@amd.com 56410234Syasuko.eckert@amd.com RegVal readMiscRegNoEffect(int misc_reg) const 56510234Syasuko.eckert@amd.com { return actualTC->readMiscRegNoEffect(misc_reg); } 56610234Syasuko.eckert@amd.com 56710234Syasuko.eckert@amd.com RegVal readMiscReg(int misc_reg) 56810234Syasuko.eckert@amd.com { return actualTC->readMiscReg(misc_reg); } 56910152Satgutier@umich.edu 57010234Syasuko.eckert@amd.com void setMiscRegNoEffect(int misc_reg, RegVal val) 57110234Syasuko.eckert@amd.com { return actualTC->setMiscRegNoEffect(misc_reg, val); } 57210234Syasuko.eckert@amd.com 57310234Syasuko.eckert@amd.com void setMiscReg(int misc_reg, RegVal val) 57410152Satgutier@umich.edu { return actualTC->setMiscReg(misc_reg, val); } 57510234Syasuko.eckert@amd.com 57610234Syasuko.eckert@amd.com RegId flattenRegId(const RegId& regId) const 57710234Syasuko.eckert@amd.com { return actualTC->flattenRegId(regId); } 57810234Syasuko.eckert@amd.com 57910234Syasuko.eckert@amd.com unsigned readStCondFailures() 58010234Syasuko.eckert@amd.com { return actualTC->readStCondFailures(); } 58110234Syasuko.eckert@amd.com 58210234Syasuko.eckert@amd.com void setStCondFailures(unsigned sc_failures) 58310234Syasuko.eckert@amd.com { actualTC->setStCondFailures(sc_failures); } 58410234Syasuko.eckert@amd.com 58510234Syasuko.eckert@amd.com void syscall(int64_t callnum, Fault *fault) 58610234Syasuko.eckert@amd.com { actualTC->syscall(callnum, fault); } 58710234Syasuko.eckert@amd.com 58810234Syasuko.eckert@amd.com Counter readFuncExeInst() { return actualTC->readFuncExeInst(); } 58910234Syasuko.eckert@amd.com 59010234Syasuko.eckert@amd.com RegVal readIntRegFlat(int idx) 59110234Syasuko.eckert@amd.com { return actualTC->readIntRegFlat(idx); } 59210234Syasuko.eckert@amd.com 59310234Syasuko.eckert@amd.com void setIntRegFlat(int idx, RegVal val) 59410234Syasuko.eckert@amd.com { actualTC->setIntRegFlat(idx, val); } 59510234Syasuko.eckert@amd.com 59610234Syasuko.eckert@amd.com RegVal readFloatRegFlat(int idx) 59710152Satgutier@umich.edu { return actualTC->readFloatRegFlat(idx); } 59810234Syasuko.eckert@amd.com 59910234Syasuko.eckert@amd.com void setFloatRegFlat(int idx, RegVal val) 60010234Syasuko.eckert@amd.com { actualTC->setFloatRegFlat(idx, val); } 60110152Satgutier@umich.edu 60210152Satgutier@umich.edu const VecRegContainer& readVecRegFlat(int id) const 60310152Satgutier@umich.edu { return actualTC->readVecRegFlat(id); } 60410152Satgutier@umich.edu 60510152Satgutier@umich.edu VecRegContainer& getWritableVecRegFlat(int id) 60610152Satgutier@umich.edu { return actualTC->getWritableVecRegFlat(id); } 60710152Satgutier@umich.edu 60810234Syasuko.eckert@amd.com void setVecRegFlat(int idx, const VecRegContainer& val) 60910234Syasuko.eckert@amd.com { actualTC->setVecRegFlat(idx, val); } 61010234Syasuko.eckert@amd.com 61110234Syasuko.eckert@amd.com const VecElem& readVecElemFlat(const RegIndex& id, 61210234Syasuko.eckert@amd.com const ElemIndex& elemIndex) const 61310234Syasuko.eckert@amd.com { return actualTC->readVecElemFlat(id, elemIndex); } 61410234Syasuko.eckert@amd.com 61510234Syasuko.eckert@amd.com void setVecElemFlat(const RegIndex& id, const ElemIndex& elemIndex, 61610234Syasuko.eckert@amd.com const VecElem& val) 61710234Syasuko.eckert@amd.com { actualTC->setVecElemFlat(id, elemIndex, val); } 61810234Syasuko.eckert@amd.com 61910234Syasuko.eckert@amd.com const VecPredRegContainer& readVecPredRegFlat(int id) const 62010234Syasuko.eckert@amd.com { return actualTC->readVecPredRegFlat(id); } 62110234Syasuko.eckert@amd.com 62210234Syasuko.eckert@amd.com VecPredRegContainer& getWritableVecPredRegFlat(int id) 62310234Syasuko.eckert@amd.com { return actualTC->getWritableVecPredRegFlat(id); } 62410234Syasuko.eckert@amd.com 62510234Syasuko.eckert@amd.com void setVecPredRegFlat(int idx, const VecPredRegContainer& val) 62610234Syasuko.eckert@amd.com { actualTC->setVecPredRegFlat(idx, val); } 62710152Satgutier@umich.edu 62810234Syasuko.eckert@amd.com RegVal readCCRegFlat(int idx) 62910234Syasuko.eckert@amd.com { return actualTC->readCCRegFlat(idx); } 63010234Syasuko.eckert@amd.com 63110234Syasuko.eckert@amd.com void setCCRegFlat(int idx, RegVal val) 63210234Syasuko.eckert@amd.com { actualTC->setCCRegFlat(idx, val); } 63310234Syasuko.eckert@amd.com}; 63410234Syasuko.eckert@amd.com 63510234Syasuko.eckert@amd.com/** @{ */ 63610234Syasuko.eckert@amd.com/** 63710234Syasuko.eckert@amd.com * Thread context serialization helpers 63810234Syasuko.eckert@amd.com * 63910234Syasuko.eckert@amd.com * These helper functions provide a way to the data in a 64010234Syasuko.eckert@amd.com * ThreadContext. They are provided as separate helper function since 64110234Syasuko.eckert@amd.com * implementing them as members of the ThreadContext interface would 64210234Syasuko.eckert@amd.com * be confusing when the ThreadContext is exported via a proxy. 64310234Syasuko.eckert@amd.com */ 64410234Syasuko.eckert@amd.com 64510234Syasuko.eckert@amd.comvoid serialize(ThreadContext &tc, CheckpointOut &cp); 64610234Syasuko.eckert@amd.comvoid unserialize(ThreadContext &tc, CheckpointIn &cp); 64710234Syasuko.eckert@amd.com 64810234Syasuko.eckert@amd.com/** @} */ 64910234Syasuko.eckert@amd.com 65010234Syasuko.eckert@amd.com 65110234Syasuko.eckert@amd.com/** 65210234Syasuko.eckert@amd.com * Copy state between thread contexts in preparation for CPU handover. 65310234Syasuko.eckert@amd.com * 65410234Syasuko.eckert@amd.com * @note This method modifies the old thread contexts as well as the 65510234Syasuko.eckert@amd.com * new thread context. The old thread context will have its quiesce 65610234Syasuko.eckert@amd.com * event descheduled if it is scheduled and its status set to halted. 65710234Syasuko.eckert@amd.com * 65810234Syasuko.eckert@amd.com * @param new_tc Destination ThreadContext. 65910234Syasuko.eckert@amd.com * @param old_tc Source ThreadContext. 66010234Syasuko.eckert@amd.com */ 66110234Syasuko.eckert@amd.comvoid takeOverFrom(ThreadContext &new_tc, ThreadContext &old_tc); 66210234Syasuko.eckert@amd.com 66310234Syasuko.eckert@amd.com#endif 66410234Syasuko.eckert@amd.com