arch,cpu: Move TheISA::copyRegs to TheISA::ISA::copyRegsFrom.
This eliminates the last externally used function in arch/utility.hh. Change-Id: I7f402b0303e2758762e19d69f3bed37262cc9289 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/39336 Maintainer: Gabe Black <gabe.black@gmail.com> Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com> Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
This commit is contained in:
@@ -487,6 +487,49 @@ ISA::takeOverFrom(ThreadContext *new_tc, ThreadContext *old_tc)
|
||||
setupThreadContext();
|
||||
}
|
||||
|
||||
static void
|
||||
copyVecRegs(ThreadContext *src, ThreadContext *dest)
|
||||
{
|
||||
auto src_mode = src->getIsaPtr()->vecRegRenameMode(src);
|
||||
|
||||
// The way vector registers are copied (VecReg vs VecElem) is relevant
|
||||
// in the O3 model only.
|
||||
if (src_mode == Enums::Full) {
|
||||
for (auto idx = 0; idx < NumVecRegs; idx++)
|
||||
dest->setVecRegFlat(idx, src->readVecRegFlat(idx));
|
||||
} else {
|
||||
for (auto idx = 0; idx < NumVecRegs; idx++)
|
||||
for (auto elem_idx = 0; elem_idx < NumVecElemPerVecReg; elem_idx++)
|
||||
dest->setVecElemFlat(
|
||||
idx, elem_idx, src->readVecElemFlat(idx, elem_idx));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ISA::copyRegsFrom(ThreadContext *src)
|
||||
{
|
||||
for (int i = 0; i < NUM_INTREGS; i++)
|
||||
tc->setIntRegFlat(i, src->readIntRegFlat(i));
|
||||
|
||||
for (int i = 0; i < NUM_CCREGS; i++)
|
||||
tc->setCCReg(i, src->readCCReg(i));
|
||||
|
||||
for (int i = 0; i < NUM_MISCREGS; i++)
|
||||
tc->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
|
||||
|
||||
copyVecRegs(src, tc);
|
||||
|
||||
// setMiscReg "with effect" will set the misc register mapping correctly.
|
||||
// e.g. updateRegMap(val)
|
||||
tc->setMiscReg(MISCREG_CPSR, src->readMiscRegNoEffect(MISCREG_CPSR));
|
||||
|
||||
// Copy over the PC State
|
||||
tc->pcState(src->pcState());
|
||||
|
||||
// Invalidate the tlb misc register cache
|
||||
static_cast<MMU *>(tc->getMMUPtr())->invalidateMiscReg();
|
||||
}
|
||||
|
||||
RegVal
|
||||
ISA::readMiscRegNoEffect(int misc_reg) const
|
||||
{
|
||||
|
||||
@@ -905,6 +905,8 @@ namespace ArmISA
|
||||
CPSR cpsr = miscRegs[MISCREG_CPSR];
|
||||
return ArmISA::inUserMode(cpsr);
|
||||
}
|
||||
|
||||
void copyRegsFrom(ThreadContext *src) override;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ class ArmLinux : public Linux
|
||||
ThreadContext *ptc, ThreadContext *ctc,
|
||||
uint64_t stack, uint64_t tls)
|
||||
{
|
||||
ArmISA::copyRegs(ptc, ctc);
|
||||
ctc->getIsaPtr()->copyRegsFrom(ptc);
|
||||
|
||||
if (flags & TGT_CLONE_SETTLS) {
|
||||
/* TPIDR_EL0 is architecturally mapped to TPIDRURW, so
|
||||
|
||||
@@ -55,49 +55,6 @@
|
||||
namespace ArmISA
|
||||
{
|
||||
|
||||
static void
|
||||
copyVecRegs(ThreadContext *src, ThreadContext *dest)
|
||||
{
|
||||
auto src_mode = src->getIsaPtr()->vecRegRenameMode(src);
|
||||
|
||||
// The way vector registers are copied (VecReg vs VecElem) is relevant
|
||||
// in the O3 model only.
|
||||
if (src_mode == Enums::Full) {
|
||||
for (auto idx = 0; idx < NumVecRegs; idx++)
|
||||
dest->setVecRegFlat(idx, src->readVecRegFlat(idx));
|
||||
} else {
|
||||
for (auto idx = 0; idx < NumVecRegs; idx++)
|
||||
for (auto elem_idx = 0; elem_idx < NumVecElemPerVecReg; elem_idx++)
|
||||
dest->setVecElemFlat(
|
||||
idx, elem_idx, src->readVecElemFlat(idx, elem_idx));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
copyRegs(ThreadContext *src, ThreadContext *dest)
|
||||
{
|
||||
for (int i = 0; i < NUM_INTREGS; i++)
|
||||
dest->setIntRegFlat(i, src->readIntRegFlat(i));
|
||||
|
||||
for (int i = 0; i < NUM_CCREGS; i++)
|
||||
dest->setCCReg(i, src->readCCReg(i));
|
||||
|
||||
for (int i = 0; i < NUM_MISCREGS; i++)
|
||||
dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
|
||||
|
||||
copyVecRegs(src, dest);
|
||||
|
||||
// setMiscReg "with effect" will set the misc register mapping correctly.
|
||||
// e.g. updateRegMap(val)
|
||||
dest->setMiscReg(MISCREG_CPSR, src->readMiscRegNoEffect(MISCREG_CPSR));
|
||||
|
||||
// Copy over the PC State
|
||||
dest->pcState(src->pcState());
|
||||
|
||||
// Invalidate the tlb misc register cache
|
||||
static_cast<MMU *>(dest->getMMUPtr())->invalidateMiscReg();
|
||||
}
|
||||
|
||||
void
|
||||
sendEvent(ThreadContext *tc)
|
||||
{
|
||||
|
||||
@@ -85,8 +85,6 @@ testPredicate(uint32_t nz, uint32_t c, uint32_t v, ConditionCode code)
|
||||
}
|
||||
}
|
||||
|
||||
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
||||
|
||||
/** Send an event (SEV) to a specific PE if there isn't
|
||||
* already a pending event */
|
||||
void sendEvent(ThreadContext *tc);
|
||||
|
||||
@@ -66,6 +66,7 @@ class BaseISA : public SimObject
|
||||
|
||||
virtual uint64_t getExecutingAsid() const { return 0; }
|
||||
virtual bool inUserMode() const = 0;
|
||||
virtual void copyRegsFrom(ThreadContext *src) = 0;
|
||||
|
||||
virtual Enums::VecRegRenameMode
|
||||
initVecRegRenameMode() const
|
||||
|
||||
@@ -163,6 +163,25 @@ ISA::clear()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ISA::copyRegsFrom(ThreadContext *src)
|
||||
{
|
||||
// First loop through the integer registers.
|
||||
for (int i = 0; i < NumIntRegs; i++)
|
||||
tc->setIntRegFlat(i, src->readIntRegFlat(i));
|
||||
|
||||
// Then loop through the floating point registers.
|
||||
for (int i = 0; i < NumFloatRegs; i++)
|
||||
tc->setFloatRegFlat(i, src->readFloatRegFlat(i));
|
||||
|
||||
// Copy misc. registers
|
||||
for (int i = 0; i < MISCREG_NUMREGS; i++)
|
||||
tc->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
|
||||
|
||||
// Copy over the PC State
|
||||
tc->pcState(src->pcState());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ISA::configCP()
|
||||
|
||||
@@ -160,6 +160,8 @@ namespace MipsISA
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void copyRegsFrom(ThreadContext *src) override;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -205,23 +205,4 @@ isSnan(void *val_ptr, int size)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
copyRegs(ThreadContext *src, ThreadContext *dest)
|
||||
{
|
||||
// First loop through the integer registers.
|
||||
for (int i = 0; i < NumIntRegs; i++)
|
||||
dest->setIntRegFlat(i, src->readIntRegFlat(i));
|
||||
|
||||
// Then loop through the floating point registers.
|
||||
for (int i = 0; i < NumFloatRegs; i++)
|
||||
dest->setFloatRegFlat(i, src->readFloatRegFlat(i));
|
||||
|
||||
// Copy misc. registers
|
||||
for (int i = 0; i < MISCREG_NUMREGS; i++)
|
||||
dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
|
||||
|
||||
// Copy over the PC State
|
||||
dest->pcState(src->pcState());
|
||||
}
|
||||
|
||||
} // namespace MipsISA
|
||||
|
||||
@@ -48,7 +48,6 @@ if env['TARGET_ISA'] == 'power':
|
||||
Source('remote_gdb.cc')
|
||||
Source('se_workload.cc')
|
||||
Source('tlb.cc')
|
||||
Source('utility.cc')
|
||||
|
||||
SimObject('PowerInterrupts.py')
|
||||
SimObject('PowerISA.py')
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#include "arch/power/miscregs.hh"
|
||||
#include "arch/power/registers.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "params/PowerISA.hh"
|
||||
|
||||
namespace PowerISA
|
||||
@@ -58,4 +59,21 @@ ISA::ISA(const Params &p) : BaseISA(p)
|
||||
clear();
|
||||
}
|
||||
|
||||
void
|
||||
ISA::copyRegsFrom(ThreadContext *src)
|
||||
{
|
||||
// First loop through the integer registers.
|
||||
for (int i = 0; i < NumIntRegs; ++i)
|
||||
tc->setIntReg(i, src->readIntReg(i));
|
||||
|
||||
// Then loop through the floating point registers.
|
||||
for (int i = 0; i < NumFloatRegs; ++i)
|
||||
tc->setFloatReg(i, src->readFloatReg(i));
|
||||
|
||||
//TODO Copy misc. registers
|
||||
|
||||
// Lastly copy PC/NPC
|
||||
tc->pcState(src->pcState());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -133,6 +133,8 @@ class ISA : public BaseISA
|
||||
return false;
|
||||
}
|
||||
|
||||
void copyRegsFrom(ThreadContext *src) override;
|
||||
|
||||
using Params = PowerISAParams;
|
||||
|
||||
ISA(const Params &p);
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
#include "arch/power/isa_traits.hh"
|
||||
#include "arch/power/utility.hh"
|
||||
#include "sim/serialize.hh"
|
||||
|
||||
namespace PowerISA
|
||||
{
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 The Regents of The University of Michigan
|
||||
* Copyright (c) 2007-2008 The Florida State University
|
||||
* Copyright (c) 2009 The University of Edinburgh
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "arch/power/utility.hh"
|
||||
|
||||
#include "base/logging.hh"
|
||||
|
||||
namespace PowerISA
|
||||
{
|
||||
|
||||
void
|
||||
copyRegs(ThreadContext *src, ThreadContext *dest)
|
||||
{
|
||||
// First loop through the integer registers.
|
||||
for (int i = 0; i < NumIntRegs; ++i)
|
||||
dest->setIntReg(i, src->readIntReg(i));
|
||||
|
||||
// Then loop through the floating point registers.
|
||||
for (int i = 0; i < NumFloatRegs; ++i)
|
||||
dest->setFloatReg(i, src->readFloatReg(i));
|
||||
|
||||
//TODO Copy misc. registers.
|
||||
|
||||
// Lastly copy PC/NPC
|
||||
dest->pcState(src->pcState());
|
||||
}
|
||||
|
||||
} // namespace PowerISA
|
||||
@@ -31,15 +31,4 @@
|
||||
#ifndef __ARCH_POWER_UTILITY_HH__
|
||||
#define __ARCH_POWER_UTILITY_HH__
|
||||
|
||||
#include "base/types.hh"
|
||||
#include "cpu/static_inst.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
|
||||
namespace PowerISA {
|
||||
|
||||
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
||||
|
||||
} // namespace PowerISA
|
||||
|
||||
|
||||
#endif // __ARCH_POWER_UTILITY_HH__
|
||||
|
||||
@@ -192,6 +192,21 @@ ISA::ISA(const Params &p) : BaseISA(p)
|
||||
clear();
|
||||
}
|
||||
|
||||
void
|
||||
ISA::copyRegsFrom(ThreadContext *src)
|
||||
{
|
||||
// First loop through the integer registers.
|
||||
for (int i = 0; i < NumIntRegs; ++i)
|
||||
tc->setIntReg(i, src->readIntReg(i));
|
||||
|
||||
// Second loop through the float registers.
|
||||
for (int i = 0; i < NumFloatRegs; ++i)
|
||||
tc->setFloatReg(i, src->readFloatReg(i));
|
||||
|
||||
// Lastly copy PC/NPC
|
||||
tc->pcState(src->pcState());
|
||||
}
|
||||
|
||||
void ISA::clear()
|
||||
{
|
||||
std::fill(miscRegFile.begin(), miscRegFile.end(), 0);
|
||||
|
||||
@@ -96,6 +96,7 @@ class ISA : public BaseISA
|
||||
int flattenMiscIndex(int reg) const { return reg; }
|
||||
|
||||
bool inUserMode() const override { return true; }
|
||||
void copyRegsFrom(ThreadContext *src) override;
|
||||
|
||||
void serialize(CheckpointOut &cp) const override;
|
||||
void unserialize(CheckpointIn &cp) override;
|
||||
|
||||
@@ -200,7 +200,7 @@ class RiscvLinux64 : public RiscvLinux
|
||||
ThreadContext *ptc, ThreadContext *ctc,
|
||||
uint64_t stack, uint64_t tls)
|
||||
{
|
||||
RiscvISA::copyRegs(ptc, ctc);
|
||||
ctc->getIsaPtr()->copyRegsFrom(ptc);
|
||||
if (flags & TGT_CLONE_SETTLS)
|
||||
ctc->setIntReg(RiscvISA::ThreadPointerReg, tls);
|
||||
if (stack)
|
||||
@@ -374,7 +374,7 @@ class RiscvLinux32 : public RiscvLinux
|
||||
ThreadContext *ptc, ThreadContext *ctc,
|
||||
uint64_t stack, uint64_t tls)
|
||||
{
|
||||
RiscvISA::copyRegs(ptc, ctc);
|
||||
ctc->getIsaPtr()->copyRegsFrom(ptc);
|
||||
if (stack)
|
||||
ctc->setIntReg(RiscvISA::StackPointerReg, stack);
|
||||
}
|
||||
|
||||
@@ -98,21 +98,6 @@ issignalingnan<double>(double val)
|
||||
&& (reinterpret_cast<uint64_t&>(val)&0x0004000000000000ULL);
|
||||
}
|
||||
|
||||
inline void
|
||||
copyRegs(ThreadContext *src, ThreadContext *dest)
|
||||
{
|
||||
// First loop through the integer registers.
|
||||
for (int i = 0; i < NumIntRegs; ++i)
|
||||
dest->setIntReg(i, src->readIntReg(i));
|
||||
|
||||
// Second loop through the float registers.
|
||||
for (int i = 0; i < NumFloatRegs; ++i)
|
||||
dest->setFloatReg(i, src->readFloatReg(i));
|
||||
|
||||
// Lastly copy PC/NPC
|
||||
dest->pcState(src->pcState());
|
||||
}
|
||||
|
||||
inline std::string
|
||||
registerName(RegId reg)
|
||||
{
|
||||
|
||||
@@ -45,7 +45,6 @@ if env['TARGET_ISA'] == 'sparc':
|
||||
Source('solaris/solaris.cc')
|
||||
Source('tlb.cc')
|
||||
Source('ua2005.cc')
|
||||
Source('utility.cc')
|
||||
|
||||
SimObject('SparcFsWorkload.py')
|
||||
SimObject('SparcInterrupts.py')
|
||||
|
||||
@@ -74,6 +74,183 @@ ISA::ISA(const Params &p) : BaseISA(p)
|
||||
clear();
|
||||
}
|
||||
|
||||
static void
|
||||
copyMiscRegs(ThreadContext *src, ThreadContext *dest)
|
||||
{
|
||||
uint8_t tl = src->readMiscRegNoEffect(MISCREG_TL);
|
||||
|
||||
// Read all the trap level dependent registers and save them off
|
||||
for (int i = 1; i <= MaxTL; i++) {
|
||||
src->setMiscRegNoEffect(MISCREG_TL, i);
|
||||
dest->setMiscRegNoEffect(MISCREG_TL, i);
|
||||
|
||||
dest->setMiscRegNoEffect(MISCREG_TT,
|
||||
src->readMiscRegNoEffect(MISCREG_TT));
|
||||
dest->setMiscRegNoEffect(MISCREG_TPC,
|
||||
src->readMiscRegNoEffect(MISCREG_TPC));
|
||||
dest->setMiscRegNoEffect(MISCREG_TNPC,
|
||||
src->readMiscRegNoEffect(MISCREG_TNPC));
|
||||
dest->setMiscRegNoEffect(MISCREG_TSTATE,
|
||||
src->readMiscRegNoEffect(MISCREG_TSTATE));
|
||||
}
|
||||
|
||||
// Save off the traplevel
|
||||
dest->setMiscRegNoEffect(MISCREG_TL, tl);
|
||||
src->setMiscRegNoEffect(MISCREG_TL, tl);
|
||||
|
||||
|
||||
// ASRs
|
||||
// dest->setMiscRegNoEffect(MISCREG_Y,
|
||||
// src->readMiscRegNoEffect(MISCREG_Y));
|
||||
// dest->setMiscRegNoEffect(MISCREG_CCR,
|
||||
// src->readMiscRegNoEffect(MISCREG_CCR));
|
||||
dest->setMiscReg(MISCREG_ASI,
|
||||
src->readMiscRegNoEffect(MISCREG_ASI));
|
||||
dest->setMiscRegNoEffect(MISCREG_TICK,
|
||||
src->readMiscRegNoEffect(MISCREG_TICK));
|
||||
dest->setMiscRegNoEffect(MISCREG_FPRS,
|
||||
src->readMiscRegNoEffect(MISCREG_FPRS));
|
||||
dest->setMiscRegNoEffect(MISCREG_SOFTINT,
|
||||
src->readMiscRegNoEffect(MISCREG_SOFTINT));
|
||||
dest->setMiscRegNoEffect(MISCREG_TICK_CMPR,
|
||||
src->readMiscRegNoEffect(MISCREG_TICK_CMPR));
|
||||
dest->setMiscRegNoEffect(MISCREG_STICK,
|
||||
src->readMiscRegNoEffect(MISCREG_STICK));
|
||||
dest->setMiscRegNoEffect(MISCREG_STICK_CMPR,
|
||||
src->readMiscRegNoEffect(MISCREG_STICK_CMPR));
|
||||
|
||||
// Priv Registers
|
||||
dest->setMiscRegNoEffect(MISCREG_TICK,
|
||||
src->readMiscRegNoEffect(MISCREG_TICK));
|
||||
dest->setMiscRegNoEffect(MISCREG_TBA,
|
||||
src->readMiscRegNoEffect(MISCREG_TBA));
|
||||
dest->setMiscRegNoEffect(MISCREG_PSTATE,
|
||||
src->readMiscRegNoEffect(MISCREG_PSTATE));
|
||||
dest->setMiscRegNoEffect(MISCREG_PIL,
|
||||
src->readMiscRegNoEffect(MISCREG_PIL));
|
||||
dest->setMiscReg(MISCREG_CWP,
|
||||
src->readMiscRegNoEffect(MISCREG_CWP));
|
||||
// dest->setMiscRegNoEffect(MISCREG_CANSAVE,
|
||||
// src->readMiscRegNoEffect(MISCREG_CANSAVE));
|
||||
// dest->setMiscRegNoEffect(MISCREG_CANRESTORE,
|
||||
// src->readMiscRegNoEffect(MISCREG_CANRESTORE));
|
||||
// dest->setMiscRegNoEffect(MISCREG_OTHERWIN,
|
||||
// src->readMiscRegNoEffect(MISCREG_OTHERWIN));
|
||||
// dest->setMiscRegNoEffect(MISCREG_CLEANWIN,
|
||||
// src->readMiscRegNoEffect(MISCREG_CLEANWIN));
|
||||
// dest->setMiscRegNoEffect(MISCREG_WSTATE,
|
||||
// src->readMiscRegNoEffect(MISCREG_WSTATE));
|
||||
dest->setMiscReg(MISCREG_GL, src->readMiscRegNoEffect(MISCREG_GL));
|
||||
|
||||
// Hyperprivilged registers
|
||||
dest->setMiscRegNoEffect(MISCREG_HPSTATE,
|
||||
src->readMiscRegNoEffect(MISCREG_HPSTATE));
|
||||
dest->setMiscRegNoEffect(MISCREG_HINTP,
|
||||
src->readMiscRegNoEffect(MISCREG_HINTP));
|
||||
dest->setMiscRegNoEffect(MISCREG_HTBA,
|
||||
src->readMiscRegNoEffect(MISCREG_HTBA));
|
||||
dest->setMiscRegNoEffect(MISCREG_STRAND_STS_REG,
|
||||
src->readMiscRegNoEffect(MISCREG_STRAND_STS_REG));
|
||||
dest->setMiscRegNoEffect(MISCREG_HSTICK_CMPR,
|
||||
src->readMiscRegNoEffect(MISCREG_HSTICK_CMPR));
|
||||
|
||||
// FSR
|
||||
dest->setMiscRegNoEffect(MISCREG_FSR,
|
||||
src->readMiscRegNoEffect(MISCREG_FSR));
|
||||
|
||||
// Strand Status Register
|
||||
dest->setMiscRegNoEffect(MISCREG_STRAND_STS_REG,
|
||||
src->readMiscRegNoEffect(MISCREG_STRAND_STS_REG));
|
||||
|
||||
// MMU Registers
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_P_CONTEXT,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_P_CONTEXT));
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_S_CONTEXT,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_S_CONTEXT));
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_PART_ID,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_PART_ID));
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_LSU_CTRL));
|
||||
|
||||
// Scratchpad Registers
|
||||
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R0,
|
||||
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R0));
|
||||
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R1,
|
||||
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R1));
|
||||
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R2,
|
||||
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R2));
|
||||
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R3,
|
||||
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R3));
|
||||
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R4,
|
||||
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R4));
|
||||
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R5,
|
||||
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R5));
|
||||
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R6,
|
||||
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R6));
|
||||
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R7,
|
||||
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R7));
|
||||
|
||||
// Queue Registers
|
||||
dest->setMiscRegNoEffect(MISCREG_QUEUE_CPU_MONDO_HEAD,
|
||||
src->readMiscRegNoEffect(MISCREG_QUEUE_CPU_MONDO_HEAD));
|
||||
dest->setMiscRegNoEffect(MISCREG_QUEUE_CPU_MONDO_TAIL,
|
||||
src->readMiscRegNoEffect(MISCREG_QUEUE_CPU_MONDO_TAIL));
|
||||
dest->setMiscRegNoEffect(MISCREG_QUEUE_DEV_MONDO_HEAD,
|
||||
src->readMiscRegNoEffect(MISCREG_QUEUE_DEV_MONDO_HEAD));
|
||||
dest->setMiscRegNoEffect(MISCREG_QUEUE_DEV_MONDO_TAIL,
|
||||
src->readMiscRegNoEffect(MISCREG_QUEUE_DEV_MONDO_TAIL));
|
||||
dest->setMiscRegNoEffect(MISCREG_QUEUE_RES_ERROR_HEAD,
|
||||
src->readMiscRegNoEffect(MISCREG_QUEUE_RES_ERROR_HEAD));
|
||||
dest->setMiscRegNoEffect(MISCREG_QUEUE_RES_ERROR_TAIL,
|
||||
src->readMiscRegNoEffect(MISCREG_QUEUE_RES_ERROR_TAIL));
|
||||
dest->setMiscRegNoEffect(MISCREG_QUEUE_NRES_ERROR_HEAD,
|
||||
src->readMiscRegNoEffect(MISCREG_QUEUE_NRES_ERROR_HEAD));
|
||||
dest->setMiscRegNoEffect(MISCREG_QUEUE_NRES_ERROR_TAIL,
|
||||
src->readMiscRegNoEffect(MISCREG_QUEUE_NRES_ERROR_TAIL));
|
||||
}
|
||||
|
||||
void
|
||||
ISA::copyRegsFrom(ThreadContext *src)
|
||||
{
|
||||
// First loop through the integer registers.
|
||||
int old_gl = src->readMiscRegNoEffect(MISCREG_GL);
|
||||
int old_cwp = src->readMiscRegNoEffect(MISCREG_CWP);
|
||||
// Globals
|
||||
for (int x = 0; x < MaxGL; ++x) {
|
||||
src->setMiscReg(MISCREG_GL, x);
|
||||
tc->setMiscReg(MISCREG_GL, x);
|
||||
// Skip %g0 which is always zero.
|
||||
for (int y = 1; y < 8; y++)
|
||||
tc->setIntReg(y, src->readIntReg(y));
|
||||
}
|
||||
// Locals and ins. Outs are all also ins.
|
||||
for (int x = 0; x < NWindows; ++x) {
|
||||
src->setMiscReg(MISCREG_CWP, x);
|
||||
tc->setMiscReg(MISCREG_CWP, x);
|
||||
for (int y = 16; y < 32; y++)
|
||||
tc->setIntReg(y, src->readIntReg(y));
|
||||
}
|
||||
// Microcode reg and pseudo int regs (misc regs in the integer regfile).
|
||||
for (int y = NumIntArchRegs; y < NumIntArchRegs + NumMicroIntRegs; ++y)
|
||||
tc->setIntReg(y, src->readIntReg(y));
|
||||
|
||||
// Restore src's GL, CWP
|
||||
src->setMiscReg(MISCREG_GL, old_gl);
|
||||
src->setMiscReg(MISCREG_CWP, old_cwp);
|
||||
|
||||
|
||||
// Then loop through the floating point registers.
|
||||
for (int i = 0; i < SparcISA::NumFloatArchRegs; ++i) {
|
||||
tc->setFloatReg(i, src->readFloatReg(i));
|
||||
}
|
||||
|
||||
// Copy misc. registers
|
||||
copyMiscRegs(src, tc);
|
||||
|
||||
// Lastly copy PC/NPC
|
||||
tc->pcState(src->pcState());
|
||||
}
|
||||
|
||||
void
|
||||
ISA::reloadRegMap()
|
||||
{
|
||||
|
||||
@@ -231,6 +231,8 @@ class ISA : public BaseISA
|
||||
return !(pstate.priv || hpstate.hpriv);
|
||||
}
|
||||
|
||||
void copyRegsFrom(ThreadContext *src) override;
|
||||
|
||||
ISA(const Params &p);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -29,7 +29,10 @@
|
||||
#ifndef __ARCH_SPARC_LINUX_LINUX_HH__
|
||||
#define __ARCH_SPARC_LINUX_LINUX_HH__
|
||||
|
||||
#include "arch/sparc/asi.hh"
|
||||
#include "arch/sparc/miscregs.hh"
|
||||
#include "arch/sparc/utility.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "kern/linux/linux.hh"
|
||||
|
||||
class SparcLinux : public Linux
|
||||
@@ -216,7 +219,7 @@ class SparcLinux : public Linux
|
||||
ThreadContext *ptc, ThreadContext *ctc,
|
||||
uint64_t stack, uint64_t tls)
|
||||
{
|
||||
SparcISA::copyRegs(ptc, ctc);
|
||||
ctc->getIsaPtr()->copyRegsFrom(ptc);
|
||||
ctc->setIntReg(SparcISA::INTREG_OTHERWIN, 0);
|
||||
ctc->setIntReg(SparcISA::INTREG_CANRESTORE, 0);
|
||||
ctc->setIntReg(SparcISA::INTREG_CANSAVE, SparcISA::NWindows - 2);
|
||||
|
||||
@@ -1,215 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2005 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.
|
||||
*/
|
||||
|
||||
#include "arch/sparc/utility.hh"
|
||||
|
||||
#include "arch/sparc/faults.hh"
|
||||
#include "mem/port_proxy.hh"
|
||||
|
||||
namespace SparcISA
|
||||
{
|
||||
|
||||
void
|
||||
copyMiscRegs(ThreadContext *src, ThreadContext *dest)
|
||||
{
|
||||
|
||||
uint8_t tl = src->readMiscRegNoEffect(MISCREG_TL);
|
||||
|
||||
// Read all the trap level dependent registers and save them off
|
||||
for (int i = 1; i <= MaxTL; i++) {
|
||||
src->setMiscRegNoEffect(MISCREG_TL, i);
|
||||
dest->setMiscRegNoEffect(MISCREG_TL, i);
|
||||
|
||||
dest->setMiscRegNoEffect(MISCREG_TT,
|
||||
src->readMiscRegNoEffect(MISCREG_TT));
|
||||
dest->setMiscRegNoEffect(MISCREG_TPC,
|
||||
src->readMiscRegNoEffect(MISCREG_TPC));
|
||||
dest->setMiscRegNoEffect(MISCREG_TNPC,
|
||||
src->readMiscRegNoEffect(MISCREG_TNPC));
|
||||
dest->setMiscRegNoEffect(MISCREG_TSTATE,
|
||||
src->readMiscRegNoEffect(MISCREG_TSTATE));
|
||||
}
|
||||
|
||||
// Save off the traplevel
|
||||
dest->setMiscRegNoEffect(MISCREG_TL, tl);
|
||||
src->setMiscRegNoEffect(MISCREG_TL, tl);
|
||||
|
||||
|
||||
// ASRs
|
||||
// dest->setMiscRegNoEffect(MISCREG_Y,
|
||||
// src->readMiscRegNoEffect(MISCREG_Y));
|
||||
// dest->setMiscRegNoEffect(MISCREG_CCR,
|
||||
// src->readMiscRegNoEffect(MISCREG_CCR));
|
||||
dest->setMiscReg(MISCREG_ASI,
|
||||
src->readMiscRegNoEffect(MISCREG_ASI));
|
||||
dest->setMiscRegNoEffect(MISCREG_TICK,
|
||||
src->readMiscRegNoEffect(MISCREG_TICK));
|
||||
dest->setMiscRegNoEffect(MISCREG_FPRS,
|
||||
src->readMiscRegNoEffect(MISCREG_FPRS));
|
||||
dest->setMiscRegNoEffect(MISCREG_SOFTINT,
|
||||
src->readMiscRegNoEffect(MISCREG_SOFTINT));
|
||||
dest->setMiscRegNoEffect(MISCREG_TICK_CMPR,
|
||||
src->readMiscRegNoEffect(MISCREG_TICK_CMPR));
|
||||
dest->setMiscRegNoEffect(MISCREG_STICK,
|
||||
src->readMiscRegNoEffect(MISCREG_STICK));
|
||||
dest->setMiscRegNoEffect(MISCREG_STICK_CMPR,
|
||||
src->readMiscRegNoEffect(MISCREG_STICK_CMPR));
|
||||
|
||||
// Priv Registers
|
||||
dest->setMiscRegNoEffect(MISCREG_TICK,
|
||||
src->readMiscRegNoEffect(MISCREG_TICK));
|
||||
dest->setMiscRegNoEffect(MISCREG_TBA,
|
||||
src->readMiscRegNoEffect(MISCREG_TBA));
|
||||
dest->setMiscRegNoEffect(MISCREG_PSTATE,
|
||||
src->readMiscRegNoEffect(MISCREG_PSTATE));
|
||||
dest->setMiscRegNoEffect(MISCREG_PIL,
|
||||
src->readMiscRegNoEffect(MISCREG_PIL));
|
||||
dest->setMiscReg(MISCREG_CWP,
|
||||
src->readMiscRegNoEffect(MISCREG_CWP));
|
||||
// dest->setMiscRegNoEffect(MISCREG_CANSAVE,
|
||||
// src->readMiscRegNoEffect(MISCREG_CANSAVE));
|
||||
// dest->setMiscRegNoEffect(MISCREG_CANRESTORE,
|
||||
// src->readMiscRegNoEffect(MISCREG_CANRESTORE));
|
||||
// dest->setMiscRegNoEffect(MISCREG_OTHERWIN,
|
||||
// src->readMiscRegNoEffect(MISCREG_OTHERWIN));
|
||||
// dest->setMiscRegNoEffect(MISCREG_CLEANWIN,
|
||||
// src->readMiscRegNoEffect(MISCREG_CLEANWIN));
|
||||
// dest->setMiscRegNoEffect(MISCREG_WSTATE,
|
||||
// src->readMiscRegNoEffect(MISCREG_WSTATE));
|
||||
dest->setMiscReg(MISCREG_GL, src->readMiscRegNoEffect(MISCREG_GL));
|
||||
|
||||
// Hyperprivilged registers
|
||||
dest->setMiscRegNoEffect(MISCREG_HPSTATE,
|
||||
src->readMiscRegNoEffect(MISCREG_HPSTATE));
|
||||
dest->setMiscRegNoEffect(MISCREG_HINTP,
|
||||
src->readMiscRegNoEffect(MISCREG_HINTP));
|
||||
dest->setMiscRegNoEffect(MISCREG_HTBA,
|
||||
src->readMiscRegNoEffect(MISCREG_HTBA));
|
||||
dest->setMiscRegNoEffect(MISCREG_STRAND_STS_REG,
|
||||
src->readMiscRegNoEffect(MISCREG_STRAND_STS_REG));
|
||||
dest->setMiscRegNoEffect(MISCREG_HSTICK_CMPR,
|
||||
src->readMiscRegNoEffect(MISCREG_HSTICK_CMPR));
|
||||
|
||||
// FSR
|
||||
dest->setMiscRegNoEffect(MISCREG_FSR,
|
||||
src->readMiscRegNoEffect(MISCREG_FSR));
|
||||
|
||||
// Strand Status Register
|
||||
dest->setMiscRegNoEffect(MISCREG_STRAND_STS_REG,
|
||||
src->readMiscRegNoEffect(MISCREG_STRAND_STS_REG));
|
||||
|
||||
// MMU Registers
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_P_CONTEXT,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_P_CONTEXT));
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_S_CONTEXT,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_S_CONTEXT));
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_PART_ID,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_PART_ID));
|
||||
dest->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL,
|
||||
src->readMiscRegNoEffect(MISCREG_MMU_LSU_CTRL));
|
||||
|
||||
// Scratchpad Registers
|
||||
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R0,
|
||||
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R0));
|
||||
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R1,
|
||||
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R1));
|
||||
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R2,
|
||||
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R2));
|
||||
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R3,
|
||||
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R3));
|
||||
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R4,
|
||||
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R4));
|
||||
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R5,
|
||||
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R5));
|
||||
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R6,
|
||||
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R6));
|
||||
dest->setMiscRegNoEffect(MISCREG_SCRATCHPAD_R7,
|
||||
src->readMiscRegNoEffect(MISCREG_SCRATCHPAD_R7));
|
||||
|
||||
// Queue Registers
|
||||
dest->setMiscRegNoEffect(MISCREG_QUEUE_CPU_MONDO_HEAD,
|
||||
src->readMiscRegNoEffect(MISCREG_QUEUE_CPU_MONDO_HEAD));
|
||||
dest->setMiscRegNoEffect(MISCREG_QUEUE_CPU_MONDO_TAIL,
|
||||
src->readMiscRegNoEffect(MISCREG_QUEUE_CPU_MONDO_TAIL));
|
||||
dest->setMiscRegNoEffect(MISCREG_QUEUE_DEV_MONDO_HEAD,
|
||||
src->readMiscRegNoEffect(MISCREG_QUEUE_DEV_MONDO_HEAD));
|
||||
dest->setMiscRegNoEffect(MISCREG_QUEUE_DEV_MONDO_TAIL,
|
||||
src->readMiscRegNoEffect(MISCREG_QUEUE_DEV_MONDO_TAIL));
|
||||
dest->setMiscRegNoEffect(MISCREG_QUEUE_RES_ERROR_HEAD,
|
||||
src->readMiscRegNoEffect(MISCREG_QUEUE_RES_ERROR_HEAD));
|
||||
dest->setMiscRegNoEffect(MISCREG_QUEUE_RES_ERROR_TAIL,
|
||||
src->readMiscRegNoEffect(MISCREG_QUEUE_RES_ERROR_TAIL));
|
||||
dest->setMiscRegNoEffect(MISCREG_QUEUE_NRES_ERROR_HEAD,
|
||||
src->readMiscRegNoEffect(MISCREG_QUEUE_NRES_ERROR_HEAD));
|
||||
dest->setMiscRegNoEffect(MISCREG_QUEUE_NRES_ERROR_TAIL,
|
||||
src->readMiscRegNoEffect(MISCREG_QUEUE_NRES_ERROR_TAIL));
|
||||
}
|
||||
|
||||
void
|
||||
copyRegs(ThreadContext *src, ThreadContext *dest)
|
||||
{
|
||||
// First loop through the integer registers.
|
||||
int old_gl = src->readMiscRegNoEffect(MISCREG_GL);
|
||||
int old_cwp = src->readMiscRegNoEffect(MISCREG_CWP);
|
||||
// Globals
|
||||
for (int x = 0; x < MaxGL; ++x) {
|
||||
src->setMiscReg(MISCREG_GL, x);
|
||||
dest->setMiscReg(MISCREG_GL, x);
|
||||
// Skip %g0 which is always zero.
|
||||
for (int y = 1; y < 8; y++)
|
||||
dest->setIntReg(y, src->readIntReg(y));
|
||||
}
|
||||
// Locals and ins. Outs are all also ins.
|
||||
for (int x = 0; x < NWindows; ++x) {
|
||||
src->setMiscReg(MISCREG_CWP, x);
|
||||
dest->setMiscReg(MISCREG_CWP, x);
|
||||
for (int y = 16; y < 32; y++)
|
||||
dest->setIntReg(y, src->readIntReg(y));
|
||||
}
|
||||
// Microcode reg and pseudo int regs (misc regs in the integer regfile).
|
||||
for (int y = NumIntArchRegs; y < NumIntArchRegs + NumMicroIntRegs; ++y)
|
||||
dest->setIntReg(y, src->readIntReg(y));
|
||||
|
||||
// Restore src's GL, CWP
|
||||
src->setMiscReg(MISCREG_GL, old_gl);
|
||||
src->setMiscReg(MISCREG_CWP, old_cwp);
|
||||
|
||||
|
||||
// Then loop through the floating point registers.
|
||||
for (int i = 0; i < SparcISA::NumFloatArchRegs; ++i) {
|
||||
dest->setFloatReg(i, src->readFloatReg(i));
|
||||
}
|
||||
|
||||
// Copy misc. registers
|
||||
copyMiscRegs(src, dest);
|
||||
|
||||
// Lastly copy PC/NPC
|
||||
dest->pcState(src->pcState());
|
||||
}
|
||||
|
||||
} // namespace SPARC_ISA
|
||||
@@ -29,20 +29,4 @@
|
||||
#ifndef __ARCH_SPARC_UTILITY_HH__
|
||||
#define __ARCH_SPARC_UTILITY_HH__
|
||||
|
||||
#include "arch/sparc/isa_traits.hh"
|
||||
#include "arch/sparc/miscregs.hh"
|
||||
#include "arch/sparc/tlb.hh"
|
||||
#include "base/bitfield.hh"
|
||||
#include "base/logging.hh"
|
||||
#include "cpu/static_inst.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "sim/full_system.hh"
|
||||
|
||||
namespace SparcISA
|
||||
{
|
||||
|
||||
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
||||
|
||||
} // namespace SparcISA
|
||||
|
||||
#endif
|
||||
|
||||
@@ -152,6 +152,42 @@ ISA::ISA(const X86ISAParams &p) : BaseISA(p), vendorString(p.vendor_string)
|
||||
clear();
|
||||
}
|
||||
|
||||
static void
|
||||
copyMiscRegs(ThreadContext *src, ThreadContext *dest)
|
||||
{
|
||||
// This function assumes no side effects other than TLB invalidation
|
||||
// need to be considered while copying state. That will likely not be
|
||||
// true in the future.
|
||||
for (int i = 0; i < NUM_MISCREGS; ++i) {
|
||||
if (!isValidMiscReg(i))
|
||||
continue;
|
||||
|
||||
dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
|
||||
}
|
||||
|
||||
// The TSC has to be updated with side-effects if the CPUs in a
|
||||
// CPU switch have different frequencies.
|
||||
dest->setMiscReg(MISCREG_TSC, src->readMiscReg(MISCREG_TSC));
|
||||
|
||||
dest->getMMUPtr()->flushAll();
|
||||
}
|
||||
|
||||
void
|
||||
ISA::copyRegsFrom(ThreadContext *src)
|
||||
{
|
||||
//copy int regs
|
||||
for (int i = 0; i < NumIntRegs; ++i)
|
||||
tc->setIntRegFlat(i, src->readIntRegFlat(i));
|
||||
//copy float regs
|
||||
for (int i = 0; i < NumFloatRegs; ++i)
|
||||
tc->setFloatRegFlat(i, src->readFloatRegFlat(i));
|
||||
//copy condition-code regs
|
||||
for (int i = 0; i < NumCCRegs; ++i)
|
||||
tc->setCCRegFlat(i, src->readCCRegFlat(i));
|
||||
copyMiscRegs(src, tc);
|
||||
tc->pcState(src->pcState());
|
||||
}
|
||||
|
||||
RegVal
|
||||
ISA::readMiscRegNoEffect(int miscReg) const
|
||||
{
|
||||
|
||||
@@ -110,6 +110,8 @@ namespace X86ISA
|
||||
return m5reg.cpl == 3;
|
||||
}
|
||||
|
||||
void copyRegsFrom(ThreadContext *src) override;
|
||||
|
||||
void serialize(CheckpointOut &cp) const override;
|
||||
void unserialize(CheckpointIn &cp) override;
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ class X86Linux : public Linux
|
||||
ThreadContext *ptc, ThreadContext *ctc,
|
||||
uint64_t stack, uint64_t tls)
|
||||
{
|
||||
X86ISA::copyRegs(ptc, ctc);
|
||||
ctc->getIsaPtr()->copyRegsFrom(ptc);
|
||||
|
||||
if (flags & TGT_CLONE_SETTLS) {
|
||||
ctc->setMiscRegNoEffect(X86ISA::MISCREG_FS_BASE, tls);
|
||||
|
||||
@@ -49,42 +49,6 @@
|
||||
namespace X86ISA
|
||||
{
|
||||
|
||||
void
|
||||
copyMiscRegs(ThreadContext *src, ThreadContext *dest)
|
||||
{
|
||||
// This function assumes no side effects other than TLB invalidation
|
||||
// need to be considered while copying state. That will likely not be
|
||||
// true in the future.
|
||||
for (int i = 0; i < NUM_MISCREGS; ++i) {
|
||||
if (!isValidMiscReg(i))
|
||||
continue;
|
||||
|
||||
dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
|
||||
}
|
||||
|
||||
// The TSC has to be updated with side-effects if the CPUs in a
|
||||
// CPU switch have different frequencies.
|
||||
dest->setMiscReg(MISCREG_TSC, src->readMiscReg(MISCREG_TSC));
|
||||
|
||||
dest->getMMUPtr()->flushAll();
|
||||
}
|
||||
|
||||
void
|
||||
copyRegs(ThreadContext *src, ThreadContext *dest)
|
||||
{
|
||||
//copy int regs
|
||||
for (int i = 0; i < NumIntRegs; ++i)
|
||||
dest->setIntRegFlat(i, src->readIntRegFlat(i));
|
||||
//copy float regs
|
||||
for (int i = 0; i < NumFloatRegs; ++i)
|
||||
dest->setFloatRegFlat(i, src->readFloatRegFlat(i));
|
||||
//copy condition-code regs
|
||||
for (int i = 0; i < NumCCRegs; ++i)
|
||||
dest->setCCRegFlat(i, src->readCCRegFlat(i));
|
||||
copyMiscRegs(src, dest);
|
||||
dest->pcState(src->pcState());
|
||||
}
|
||||
|
||||
uint64_t
|
||||
getRFlags(ThreadContext *tc)
|
||||
{
|
||||
|
||||
@@ -44,8 +44,6 @@
|
||||
|
||||
namespace X86ISA
|
||||
{
|
||||
void copyRegs(ThreadContext *src, ThreadContext *dest);
|
||||
|
||||
/**
|
||||
* Reconstruct the rflags register from the internal gem5 register
|
||||
* state.
|
||||
|
||||
@@ -154,7 +154,7 @@ O3ThreadContext<Impl>::copyArchRegs(ThreadContext *tc)
|
||||
|
||||
// Prevent squashing
|
||||
thread->noSquashFromTC = true;
|
||||
TheISA::copyRegs(tc, this);
|
||||
getIsaPtr()->copyRegsFrom(tc);
|
||||
thread->noSquashFromTC = false;
|
||||
|
||||
if (!FullSystem)
|
||||
|
||||
@@ -165,7 +165,7 @@ SimpleThread::halt()
|
||||
void
|
||||
SimpleThread::copyArchRegs(ThreadContext *src_tc)
|
||||
{
|
||||
TheISA::copyRegs(src_tc, this);
|
||||
getIsaPtr()->copyRegsFrom(src_tc);
|
||||
}
|
||||
|
||||
// hardware transactional memory
|
||||
|
||||
Reference in New Issue
Block a user