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:
Gabe Black
2021-01-18 20:01:01 -08:00
parent 2cb09e4042
commit 5ffd619d38
32 changed files with 331 additions and 423 deletions

View File

@@ -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
{

View File

@@ -905,6 +905,8 @@ namespace ArmISA
CPSR cpsr = miscRegs[MISCREG_CPSR];
return ArmISA::inUserMode(cpsr);
}
void copyRegsFrom(ThreadContext *src) override;
};
}

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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);

View File

@@ -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

View File

@@ -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()

View File

@@ -160,6 +160,8 @@ namespace MipsISA
return false;
}
}
void copyRegsFrom(ThreadContext *src) override;
};
}

View File

@@ -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

View File

@@ -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')

View File

@@ -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());
}
}

View File

@@ -133,6 +133,8 @@ class ISA : public BaseISA
return false;
}
void copyRegsFrom(ThreadContext *src) override;
using Params = PowerISAParams;
ISA(const Params &p);

View File

@@ -34,6 +34,7 @@
#include "arch/power/isa_traits.hh"
#include "arch/power/utility.hh"
#include "sim/serialize.hh"
namespace PowerISA
{

View File

@@ -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

View File

@@ -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__

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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)
{

View File

@@ -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')

View File

@@ -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()
{

View File

@@ -231,6 +231,8 @@ class ISA : public BaseISA
return !(pstate.priv || hpstate.hpriv);
}
void copyRegsFrom(ThreadContext *src) override;
ISA(const Params &p);
};
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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
{

View File

@@ -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;

View File

@@ -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);

View File

@@ -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)
{

View File

@@ -44,8 +44,6 @@
namespace X86ISA
{
void copyRegs(ThreadContext *src, ThreadContext *dest);
/**
* Reconstruct the rflags register from the internal gem5 register
* state.

View File

@@ -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)

View File

@@ -165,7 +165,7 @@ SimpleThread::halt()
void
SimpleThread::copyArchRegs(ThreadContext *src_tc)
{
TheISA::copyRegs(src_tc, this);
getIsaPtr()->copyRegsFrom(src_tc);
}
// hardware transactional memory