diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index 2f674cd9ad..b1d8d3f4a7 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -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(tc->getMMUPtr())->invalidateMiscReg(); +} + RegVal ISA::readMiscRegNoEffect(int misc_reg) const { diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index 9bfcf84430..646fc254de 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -905,6 +905,8 @@ namespace ArmISA CPSR cpsr = miscRegs[MISCREG_CPSR]; return ArmISA::inUserMode(cpsr); } + + void copyRegsFrom(ThreadContext *src) override; }; } diff --git a/src/arch/arm/linux/linux.hh b/src/arch/arm/linux/linux.hh index ce73c397ff..2eb47a0be9 100644 --- a/src/arch/arm/linux/linux.hh +++ b/src/arch/arm/linux/linux.hh @@ -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 diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc index f5c792ff4f..6f63bf2cb2 100644 --- a/src/arch/arm/utility.cc +++ b/src/arch/arm/utility.cc @@ -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(dest->getMMUPtr())->invalidateMiscReg(); -} - void sendEvent(ThreadContext *tc) { diff --git a/src/arch/arm/utility.hh b/src/arch/arm/utility.hh index 3c8acb22ea..e919a92248 100644 --- a/src/arch/arm/utility.hh +++ b/src/arch/arm/utility.hh @@ -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); diff --git a/src/arch/generic/isa.hh b/src/arch/generic/isa.hh index ad5fa489c1..278843ebd6 100644 --- a/src/arch/generic/isa.hh +++ b/src/arch/generic/isa.hh @@ -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 diff --git a/src/arch/mips/isa.cc b/src/arch/mips/isa.cc index 98dab66ad2..46116c2e4c 100644 --- a/src/arch/mips/isa.cc +++ b/src/arch/mips/isa.cc @@ -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() diff --git a/src/arch/mips/isa.hh b/src/arch/mips/isa.hh index e2468ce5b2..4945270fc2 100644 --- a/src/arch/mips/isa.hh +++ b/src/arch/mips/isa.hh @@ -160,6 +160,8 @@ namespace MipsISA return false; } } + + void copyRegsFrom(ThreadContext *src) override; }; } diff --git a/src/arch/mips/utility.cc b/src/arch/mips/utility.cc index a0c671ff2a..8159ed239a 100644 --- a/src/arch/mips/utility.cc +++ b/src/arch/mips/utility.cc @@ -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 diff --git a/src/arch/power/SConscript b/src/arch/power/SConscript index cf79094a74..24bf5dbbbd 100644 --- a/src/arch/power/SConscript +++ b/src/arch/power/SConscript @@ -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') diff --git a/src/arch/power/isa.cc b/src/arch/power/isa.cc index 0aa480c3fe..9e97615f43 100644 --- a/src/arch/power/isa.cc +++ b/src/arch/power/isa.cc @@ -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()); +} + } diff --git a/src/arch/power/isa.hh b/src/arch/power/isa.hh index 7ec9ac741d..8c49a05a55 100644 --- a/src/arch/power/isa.hh +++ b/src/arch/power/isa.hh @@ -133,6 +133,8 @@ class ISA : public BaseISA return false; } + void copyRegsFrom(ThreadContext *src) override; + using Params = PowerISAParams; ISA(const Params &p); diff --git a/src/arch/power/pagetable.hh b/src/arch/power/pagetable.hh index f4ec525d8f..1f0ec4cd4a 100644 --- a/src/arch/power/pagetable.hh +++ b/src/arch/power/pagetable.hh @@ -34,6 +34,7 @@ #include "arch/power/isa_traits.hh" #include "arch/power/utility.hh" +#include "sim/serialize.hh" namespace PowerISA { diff --git a/src/arch/power/utility.cc b/src/arch/power/utility.cc deleted file mode 100644 index ffcbe4ffb4..0000000000 --- a/src/arch/power/utility.cc +++ /dev/null @@ -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 diff --git a/src/arch/power/utility.hh b/src/arch/power/utility.hh index 13183f1c37..dfe3d069db 100644 --- a/src/arch/power/utility.hh +++ b/src/arch/power/utility.hh @@ -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__ diff --git a/src/arch/riscv/isa.cc b/src/arch/riscv/isa.cc index 0283ac8b2b..c6f0ca03a5 100644 --- a/src/arch/riscv/isa.cc +++ b/src/arch/riscv/isa.cc @@ -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); diff --git a/src/arch/riscv/isa.hh b/src/arch/riscv/isa.hh index 7f03a170ba..8e070befc8 100644 --- a/src/arch/riscv/isa.hh +++ b/src/arch/riscv/isa.hh @@ -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; diff --git a/src/arch/riscv/linux/linux.hh b/src/arch/riscv/linux/linux.hh index 5f3ff67ab1..c55a2a65cd 100644 --- a/src/arch/riscv/linux/linux.hh +++ b/src/arch/riscv/linux/linux.hh @@ -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); } diff --git a/src/arch/riscv/utility.hh b/src/arch/riscv/utility.hh index f033b2b4c3..5ff9fed677 100644 --- a/src/arch/riscv/utility.hh +++ b/src/arch/riscv/utility.hh @@ -98,21 +98,6 @@ issignalingnan(double val) && (reinterpret_cast(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) { diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript index 5563702d64..00987811b2 100644 --- a/src/arch/sparc/SConscript +++ b/src/arch/sparc/SConscript @@ -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') diff --git a/src/arch/sparc/isa.cc b/src/arch/sparc/isa.cc index c0b07dab8c..9297462d70 100644 --- a/src/arch/sparc/isa.cc +++ b/src/arch/sparc/isa.cc @@ -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() { diff --git a/src/arch/sparc/isa.hh b/src/arch/sparc/isa.hh index 2d75b0aa11..7156afd786 100644 --- a/src/arch/sparc/isa.hh +++ b/src/arch/sparc/isa.hh @@ -231,6 +231,8 @@ class ISA : public BaseISA return !(pstate.priv || hpstate.hpriv); } + void copyRegsFrom(ThreadContext *src) override; + ISA(const Params &p); }; } diff --git a/src/arch/sparc/linux/linux.hh b/src/arch/sparc/linux/linux.hh index 431ec06274..2c9a4bc7f8 100644 --- a/src/arch/sparc/linux/linux.hh +++ b/src/arch/sparc/linux/linux.hh @@ -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); diff --git a/src/arch/sparc/utility.cc b/src/arch/sparc/utility.cc deleted file mode 100644 index e606d16a6c..0000000000 --- a/src/arch/sparc/utility.cc +++ /dev/null @@ -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 diff --git a/src/arch/sparc/utility.hh b/src/arch/sparc/utility.hh index 87626b7ac2..5c3d12dd50 100644 --- a/src/arch/sparc/utility.hh +++ b/src/arch/sparc/utility.hh @@ -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 diff --git a/src/arch/x86/isa.cc b/src/arch/x86/isa.cc index 640422d244..d5dca43d90 100644 --- a/src/arch/x86/isa.cc +++ b/src/arch/x86/isa.cc @@ -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 { diff --git a/src/arch/x86/isa.hh b/src/arch/x86/isa.hh index cc65563a49..8978c2b2db 100644 --- a/src/arch/x86/isa.hh +++ b/src/arch/x86/isa.hh @@ -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; diff --git a/src/arch/x86/linux/linux.hh b/src/arch/x86/linux/linux.hh index 697892cc6a..6c98db8b1b 100644 --- a/src/arch/x86/linux/linux.hh +++ b/src/arch/x86/linux/linux.hh @@ -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); diff --git a/src/arch/x86/utility.cc b/src/arch/x86/utility.cc index c6646202fd..5293d6b4b9 100644 --- a/src/arch/x86/utility.cc +++ b/src/arch/x86/utility.cc @@ -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) { diff --git a/src/arch/x86/utility.hh b/src/arch/x86/utility.hh index a572637c41..0c0b1c0002 100644 --- a/src/arch/x86/utility.hh +++ b/src/arch/x86/utility.hh @@ -44,8 +44,6 @@ namespace X86ISA { - void copyRegs(ThreadContext *src, ThreadContext *dest); - /** * Reconstruct the rflags register from the internal gem5 register * state. diff --git a/src/cpu/o3/thread_context_impl.hh b/src/cpu/o3/thread_context_impl.hh index 1a3a30d651..dd42a167fd 100644 --- a/src/cpu/o3/thread_context_impl.hh +++ b/src/cpu/o3/thread_context_impl.hh @@ -154,7 +154,7 @@ O3ThreadContext::copyArchRegs(ThreadContext *tc) // Prevent squashing thread->noSquashFromTC = true; - TheISA::copyRegs(tc, this); + getIsaPtr()->copyRegsFrom(tc); thread->noSquashFromTC = false; if (!FullSystem) diff --git a/src/cpu/simple_thread.cc b/src/cpu/simple_thread.cc index 7e65bc7630..c776e481ca 100644 --- a/src/cpu/simple_thread.cc +++ b/src/cpu/simple_thread.cc @@ -165,7 +165,7 @@ SimpleThread::halt() void SimpleThread::copyArchRegs(ThreadContext *src_tc) { - TheISA::copyRegs(src_tc, this); + getIsaPtr()->copyRegsFrom(src_tc); } // hardware transactional memory