diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2006-08-11 19:43:10 -0400 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2006-08-11 19:43:10 -0400 |
commit | 800e6ecc07d01c49808cc4f9597d94cc8cfd9fae (patch) | |
tree | bdc05bad76c4a757533cccb5002dadc15eca0456 /src/arch/sparc | |
parent | f612f09669310359d6a194645b00e32a3921283b (diff) | |
download | gem5-800e6ecc07d01c49808cc4f9597d94cc8cfd9fae.tar.xz |
Pushed most of constants.hh back into isa_traits.hh and regfile.hh and created a seperate file for the syscallreturn class.
--HG--
extra : convert_revision : 9507ea1c09fda959f00aec9ec8ffb887ec8dd0f9
Diffstat (limited to 'src/arch/sparc')
-rw-r--r-- | src/arch/sparc/SConscript | 11 | ||||
-rw-r--r-- | src/arch/sparc/floatregfile.cc | 174 | ||||
-rw-r--r-- | src/arch/sparc/floatregfile.hh | 83 | ||||
-rw-r--r-- | src/arch/sparc/intregfile.cc | 133 | ||||
-rw-r--r-- | src/arch/sparc/intregfile.hh | 103 | ||||
-rw-r--r-- | src/arch/sparc/isa_traits.hh | 106 | ||||
-rw-r--r-- | src/arch/sparc/miscregfile.cc | 540 | ||||
-rw-r--r-- | src/arch/sparc/miscregfile.hh | 410 | ||||
-rw-r--r-- | src/arch/sparc/regfile.cc | 279 | ||||
-rw-r--r-- | src/arch/sparc/regfile.hh | 824 | ||||
-rw-r--r-- | src/arch/sparc/syscallreturn.hh | 90 | ||||
-rw-r--r-- | src/arch/sparc/types.hh | 63 |
12 files changed, 1944 insertions, 872 deletions
diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript index e7a8278db..66f2b57e0 100644 --- a/src/arch/sparc/SConscript +++ b/src/arch/sparc/SConscript @@ -45,22 +45,25 @@ Import('env') # Base sources used by all configurations. base_sources = Split(''' faults.cc - isa_traits.cc + floatregfile.cc + intregfile.cc + miscregfile.cc + regfile.cc ''') # Full-system sources full_system_sources = Split(''' - vtophys.cc ua2005.cc + vtophys.cc ''') # Syscall emulation (non-full-system) sources syscall_emulation_sources = Split(''' linux/linux.cc linux/process.cc - solaris/solaris.cc - solaris/process.cc process.cc + solaris/process.cc + solaris/solaris.cc ''') sources = base_sources diff --git a/src/arch/sparc/floatregfile.cc b/src/arch/sparc/floatregfile.cc new file mode 100644 index 000000000..3cacbb278 --- /dev/null +++ b/src/arch/sparc/floatregfile.cc @@ -0,0 +1,174 @@ +/* + * 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. + * + * Authors: Gabe Black + * Ali Saidi + */ + +#include "arch/sparc/floatregfile.hh" +#include "base/trace.hh" +#include "sim/byteswap.hh" +#include "sim/serialize.hh" + +using namespace SparcISA; +using namespace std; + +class Checkpoint; + +string SparcISA::getFloatRegName(RegIndex index) +{ + static std::string floatRegName[NumFloatRegs] = + {"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", + "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39", + "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47", + "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55", + "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63"}; + return floatRegName[index]; +} + +void FloatRegFile::clear() +{ + bzero(regSpace, sizeof(regSpace)); +} + +FloatReg FloatRegFile::readReg(int floatReg, int width) +{ + //In each of these cases, we have to copy the value into a temporary + //variable. This is because we may otherwise try to access an + //unaligned portion of memory. + switch(width) + { + case SingleWidth: + float32_t result32; + memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32)); + return htog(result32); + case DoubleWidth: + float64_t result64; + memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64)); + return htog(result64); + case QuadWidth: + float128_t result128; + memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128)); + return htog(result128); + default: + panic("Attempted to read a %d bit floating point register!", width); + } +} + +FloatRegBits FloatRegFile::readRegBits(int floatReg, int width) +{ + //In each of these cases, we have to copy the value into a temporary + //variable. This is because we may otherwise try to access an + //unaligned portion of memory. + switch(width) + { + case SingleWidth: + uint32_t result32; + memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32)); + return htog(result32); + case DoubleWidth: + uint64_t result64; + memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64)); + return htog(result64); + case QuadWidth: + uint64_t result128; + memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128)); + return htog(result128); + default: + panic("Attempted to read a %d bit floating point register!", width); + } +} + +Fault FloatRegFile::setReg(int floatReg, const FloatReg &val, int width) +{ + //In each of these cases, we have to copy the value into a temporary + //variable. This is because we may otherwise try to access an + //unaligned portion of memory. + + uint32_t result32; + uint64_t result64; + DPRINTF(Sparc, "Setting floating point register %d\n", floatReg); + switch(width) + { + case SingleWidth: + result32 = gtoh((uint32_t)val); + memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32)); + break; + case DoubleWidth: + result64 = gtoh((uint64_t)val); + memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64)); + break; + case QuadWidth: + panic("Quad width FP not implemented."); + break; + default: + panic("Attempted to read a %d bit floating point register!", width); + } + return NoFault; +} + +Fault FloatRegFile::setRegBits(int floatReg, const FloatRegBits &val, int width) +{ + //In each of these cases, we have to copy the value into a temporary + //variable. This is because we may otherwise try to access an + //unaligned portion of memory. + uint32_t result32; + uint64_t result64; + switch(width) + { + case SingleWidth: + result32 = gtoh((uint32_t)val); + memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32)); + break; + case DoubleWidth: + result64 = gtoh((uint64_t)val); + memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64)); + break; + case QuadWidth: + panic("Quad width FP not implemented."); + break; + default: + panic("Attempted to read a %d bit floating point register!", width); + } + return NoFault; +} + +void FloatRegFile::serialize(std::ostream &os) +{ + SERIALIZE_ARRAY((unsigned char *)regSpace, + SingleWidth / 8 * NumFloatRegs); +} + +void FloatRegFile::unserialize(Checkpoint *cp, const std::string §ion) +{ + UNSERIALIZE_ARRAY((unsigned char *)regSpace, + SingleWidth / 8 * NumFloatRegs); +} + diff --git a/src/arch/sparc/floatregfile.hh b/src/arch/sparc/floatregfile.hh new file mode 100644 index 000000000..9d760c9ff --- /dev/null +++ b/src/arch/sparc/floatregfile.hh @@ -0,0 +1,83 @@ +/* + * 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. + * + * Authors: Gabe Black + * Ali Saidi + */ + +#ifndef __ARCH_SPARC_FLOATREGFILE_HH__ +#define __ARCH_SPARC_FLOATREGFILE_HH__ + +#include "arch/sparc/faults.hh" +#include "arch/sparc/isa_traits.hh" +#include "arch/sparc/types.hh" + +#include <string> + +namespace SparcISA +{ + std::string getFloatRegName(RegIndex); + + typedef float float32_t; + typedef double float64_t; + //FIXME long double refers to a 10 byte float, rather than a + //16 byte float as required. This data type may have to be emulated. + typedef double float128_t; + + class FloatRegFile + { + public: + static const int SingleWidth = 32; + static const int DoubleWidth = 64; + static const int QuadWidth = 128; + + protected: + + //Since the floating point registers overlap each other, + //A generic storage space is used. The float to be returned is + //pulled from the appropriate section of this region. + char regSpace[(SingleWidth / 8) * NumFloatRegs]; + + public: + + void clear(); + + FloatReg readReg(int floatReg, int width); + + FloatRegBits readRegBits(int floatReg, int width); + + Fault setReg(int floatReg, const FloatReg &val, int width); + + Fault setRegBits(int floatReg, const FloatRegBits &val, int width); + + void serialize(std::ostream &os); + + void unserialize(Checkpoint *cp, const std::string §ion); + }; +} + +#endif diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc new file mode 100644 index 000000000..0cc0a886a --- /dev/null +++ b/src/arch/sparc/intregfile.cc @@ -0,0 +1,133 @@ +/* + * 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. + * + * Authors: Gabe Black + * Ali Saidi + */ + +#include "arch/sparc/intregfile.hh" +#include "base/trace.hh" +#include "sim/serialize.hh" + +using namespace SparcISA; +using namespace std; + +class Checkpoint; + +string SparcISA::getIntRegName(RegIndex index) +{ + static std::string intRegName[NumIntRegs] = + {"g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", + "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7", + "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", + "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7"}; + return intRegName[index]; +} + +int IntRegFile::flattenIndex(int reg) +{ + int flatIndex = offset[reg >> FrameOffsetBits] + | (reg & FrameOffsetMask); + DPRINTF(Sparc, "Flattened index %d into %d.\n", reg, flatIndex); + return flatIndex; +} + +void IntRegFile::clear() +{ + int x; + for (x = 0; x < MaxGL; x++) + memset(regGlobals[x], 0, sizeof(regGlobals[x])); + for(int x = 0; x < 2 * NWindows; x++) + bzero(regSegments[x], sizeof(regSegments[x])); +} + +IntRegFile::IntRegFile() +{ + offset[Globals] = 0; + regView[Globals] = regGlobals[0]; + setCWP(0); + clear(); +} + +IntReg IntRegFile::readReg(int intReg) +{ + IntReg val = + regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask]; + DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, val); + return val; +} + +Fault IntRegFile::setReg(int intReg, const IntReg &val) +{ + if(intReg) + DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val); + regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val; + return NoFault; +} + +//This doesn't effect the actual CWP register. +//It's purpose is to adjust the view of the register file +//to what it would be if CWP = cwp. +void IntRegFile::setCWP(int cwp) +{ + int index = ((NWindows - cwp) % NWindows) * 2; + offset[Outputs] = FrameOffset + (index * RegsPerFrame); + offset[Locals] = FrameOffset + ((index+1) * RegsPerFrame); + offset[Inputs] = FrameOffset + + (((index+2) % (NWindows * 2)) * RegsPerFrame); + regView[Outputs] = regSegments[index]; + regView[Locals] = regSegments[index+1]; + regView[Inputs] = regSegments[(index+2) % (NWindows * 2)]; + + DPRINTF(Sparc, "Changed the CWP value to %d\n", cwp); +} + +void IntRegFile::setGlobals(int gl) +{ + DPRINTF(Sparc, "Now using %d globals", gl); + + regView[Globals] = regGlobals[gl]; + offset[Globals] = RegGlobalOffset + gl * RegsPerFrame; +} + +void IntRegFile::serialize(std::ostream &os) +{ + unsigned int x; + for(x = 0; x < MaxGL; x++) + SERIALIZE_ARRAY(regGlobals[x], RegsPerFrame); + for(x = 0; x < 2 * NWindows; x++) + SERIALIZE_ARRAY(regSegments[x], RegsPerFrame); +} + +void IntRegFile::unserialize(Checkpoint *cp, const std::string §ion) +{ + unsigned int x; + for(x = 0; x < MaxGL; x++) + UNSERIALIZE_ARRAY(regGlobals[x], RegsPerFrame); + for(unsigned int x = 0; x < 2 * NWindows; x++) + UNSERIALIZE_ARRAY(regSegments[x], RegsPerFrame); +} diff --git a/src/arch/sparc/intregfile.hh b/src/arch/sparc/intregfile.hh new file mode 100644 index 000000000..d305c753b --- /dev/null +++ b/src/arch/sparc/intregfile.hh @@ -0,0 +1,103 @@ +/* + * 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. + * + * Authors: Gabe Black + * Ali Saidi + */ + +#ifndef __ARCH_SPARC_INTREGFILE_HH__ +#define __ARCH_SPARC_INTREGFILE_HH__ + +#include "arch/sparc/faults.hh" +#include "arch/sparc/isa_traits.hh" +#include "arch/sparc/types.hh" + +#include <string> + +namespace SparcISA +{ + class RegFile; + + //This function translates integer register file indices into names + std::string getIntRegName(RegIndex); + + class IntRegFile + { + private: + friend class RegFile; + protected: + static const int FrameOffsetBits = 3; + static const int FrameNumBits = 2; + + static const int RegsPerFrame = 1 << FrameOffsetBits; + static const int FrameNumMask = + (FrameNumBits == sizeof(int)) ? + (unsigned int)(-1) : + (1 << FrameNumBits) - 1; + static const int FrameOffsetMask = + (FrameOffsetBits == sizeof(int)) ? + (unsigned int)(-1) : + (1 << FrameOffsetBits) - 1; + + IntReg regGlobals[MaxGL][RegsPerFrame]; + IntReg regSegments[2 * NWindows][RegsPerFrame]; + + enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames}; + + IntReg * regView[NumFrames]; + + static const int RegGlobalOffset = 0; + static const int FrameOffset = MaxGL * RegsPerFrame; + int offset[NumFrames]; + + public: + + int flattenIndex(int reg); + + void clear(); + + IntRegFile(); + + IntReg readReg(int intReg); + + Fault setReg(int intReg, const IntReg &val); + + void serialize(std::ostream &os); + + void unserialize(Checkpoint *cp, const std::string §ion); + + protected: + //This doesn't effect the actual CWP register. + //It's purpose is to adjust the view of the register file + //to what it would be if CWP = cwp. + void setCWP(int cwp); + + void setGlobals(int gl); + }; +} + +#endif diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh index 346f7b730..7f830eb28 100644 --- a/src/arch/sparc/isa_traits.hh +++ b/src/arch/sparc/isa_traits.hh @@ -25,13 +25,13 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * Authors: Korey Sewell - * Gabe Black + * Authors: Gabe Black */ #ifndef __ARCH_SPARC_ISA_TRAITS_HH__ #define __ARCH_SPARC_ISA_TRAITS_HH__ +#include "arch/sparc/types.hh" #include "base/misc.hh" #include "config/full_system.hh" #include "sim/host.hh" @@ -46,70 +46,45 @@ class StaticInstPtr; namespace BigEndianGuest {} -#if !FULL_SYSTEM -class SyscallReturn -{ - public: - template <class T> - SyscallReturn(T v, bool s) - { - retval = (uint64_t)v; - success = s; - } - - template <class T> - SyscallReturn(T v) - { - success = (v >= 0); - retval = (uint64_t)v; - } - - ~SyscallReturn() {} - - SyscallReturn& operator=(const SyscallReturn& s) - { - retval = s.retval; - success = s.success; - return *this; - } - - bool successful() { return success; } - uint64_t value() { return retval; } - - private: - uint64_t retval; - bool success; -}; - -#endif - #if FULL_SYSTEM #include "arch/sparc/isa_fullsys_traits.hh" #endif namespace SparcISA { + class RegFile; + + //This makes sure the big endian versions of certain functions are used. + using namespace BigEndianGuest; + + //TODO this needs to be a SPARC Noop + // Alpha UNOP (ldq_u r31,0(r0)) + const MachInst NoopMachInst = 0x2ffe0000; + + const int NumIntRegs = 32; + const int NumFloatRegs = 64; + const int NumMiscRegs = 40; // These enumerate all the registers for dependence tracking. enum DependenceTags { // 0..31 are the integer regs 0..31 - // 32..63 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag) - FP_Base_DepTag = 32, - Ctrl_Base_DepTag = 96, + // 32..95 are the FP regs 0..31, i.e. use (reg + FP_Base_DepTag) + FP_Base_DepTag = NumIntRegs, + Ctrl_Base_DepTag = NumIntRegs + NumFloatRegs, //XXX These are here solely to get compilation and won't work Fpcr_DepTag = 0, Uniq_DepTag = 0 }; - //This makes sure the big endian versions of certain functions are used. - using namespace BigEndianGuest; - typedef uint32_t MachInst; - typedef uint64_t ExtMachInst; + // MAXTL - maximum trap level + const int MaxPTL = 2; + const int MaxTL = 6; + const int MaxGL = 3; + const int MaxPGL = 2; - const int NumIntRegs = 32; - const int NumFloatRegs = 64; - const int NumMiscRegs = 32; + // NWINDOWS - number of register windows, can be 3 to 32 + const int NWindows = 32; // semantically meaningful register indices const int ZeroReg = 0; // architecturally meaningful @@ -131,14 +106,6 @@ namespace SparcISA const int MaxInstSrcRegs = 8; const int MaxInstDestRegs = 9; - typedef uint64_t IntReg; - - // control register file contents - typedef uint64_t MiscReg; - - typedef double FloatReg; - typedef uint64_t FloatRegBits; - //8K. This value is implmentation specific; and should probably //be somewhere else. const int LogVMPageSize = 13; @@ -165,29 +132,4 @@ namespace SparcISA extern const MachInst NoopMachInst; } -#include "arch/sparc/regfile.hh" - -namespace SparcISA -{ - -#if !FULL_SYSTEM - static inline void setSyscallReturn(SyscallReturn return_value, - RegFile *regs) - { - // check for error condition. SPARC syscall convention is to - // indicate success/failure in reg the carry bit of the ccr - // and put the return value itself in the standard return value reg (). - if (return_value.successful()) { - // no error, clear XCC.C - regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) & 0xEF); - regs->setIntReg(ReturnValueReg, return_value.value()); - } else { - // got an error, set XCC.C - regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) | 0x10); - regs->setIntReg(ReturnValueReg, return_value.value()); - } - } -#endif -}; - #endif // __ARCH_SPARC_ISA_TRAITS_HH__ diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc new file mode 100644 index 000000000..8041e45c0 --- /dev/null +++ b/src/arch/sparc/miscregfile.cc @@ -0,0 +1,540 @@ +/* + * 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. + * + * Authors: Gabe Black + * Ali Saidi + */ + +#include "arch/sparc/miscregfile.hh" +#include "base/trace.hh" +#include "cpu/base.hh" +#include "cpu/thread_context.hh" + +using namespace SparcISA; +using namespace std; + +class Checkpoint; + +//These functions map register indices to names +string SparcISA::getMiscRegName(RegIndex index) +{ + static::string miscRegName[NumMiscRegs] = + {"y", "ccr", "asi", "tick", "pc", "fprs", "pcr", "pic", + "gsr", "softint_set", "softint_clr", "softint", "tick_cmpr", + "stick", "stick_cmpr", + "tpc", "tnpc", "tstate", "tt", "privtick", "tba", "pstate", "tl", + "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin", + "wstate", "gl", + "hpstate", "htstate", "hintp", "htba", "hver", "strand_sts_reg", + "hstick_cmpr", + "fsr"}; + return miscRegName[index]; +} + +#if FULL_SYSTEM + +//XXX These need an implementation someplace +/** Fullsystem only register version of ReadRegWithEffect() */ +MiscReg MiscRegFile::readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc); +/** Fullsystem only register version of SetRegWithEffect() */ +Fault MiscRegFile::setFSRegWithEffect(int miscReg, const MiscReg &val, + ThreadContext * tc); +#endif + +void MiscRegFile::reset() +{ + pstateFields.pef = 0; //No FPU + //pstateFields.pef = 1; //FPU +#if FULL_SYSTEM + //For SPARC, when a system is first started, there is a power + //on reset Trap which sets the processor into the following state. + //Bits that aren't set aren't defined on startup. + tl = MaxTL; + gl = MaxGL; + + tickFields.counter = 0; //The TICK register is unreadable bya + tickFields.npt = 1; //The TICK register is unreadable by by !priv + + softint = 0; // Clear all the soft interrupt bits + tick_cmprFields.int_dis = 1; // disable timer compare interrupts + tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing + stickFields.npt = 1; //The TICK register is unreadable by by !priv + stick_cmprFields.int_dis = 1; // disable timer compare interrupts + stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing + + + tt[tl] = power_on_reset; + pstate = 0; // fields 0 but pef + pstateFields.pef = 1; + + hpstate = 0; + hpstateFields.red = 1; + hpstateFields.hpriv = 1; + hpstateFields.tlz = 0; // this is a guess + hintp = 0; // no interrupts pending + hstick_cmprFields.int_dis = 1; // disable timer compare interrupts + hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing +#else +/* //This sets up the initial state of the processor for usermode processes + pstateFields.priv = 0; //Process runs in user mode + pstateFields.ie = 1; //Interrupts are enabled + fsrFields.rd = 0; //Round to nearest + fsrFields.tem = 0; //Floating point traps not enabled + fsrFields.ns = 0; //Non standard mode off + fsrFields.qne = 0; //Floating point queue is empty + fsrFields.aexc = 0; //No accrued exceptions + fsrFields.cexc = 0; //No current exceptions + + //Register window management registers + otherwin = 0; //No windows contain info from other programs + canrestore = 0; //There are no windows to pop + cansave = MaxTL - 2; //All windows are available to save into + cleanwin = MaxTL;*/ +#endif +} + +MiscReg MiscRegFile::readReg(int miscReg) +{ + switch (miscReg) { + case MISCREG_Y: + return y; + case MISCREG_CCR: + return ccr; + case MISCREG_ASI: + return asi; + case MISCREG_FPRS: + return fprs; + case MISCREG_TICK: + return tick; + case MISCREG_PCR: + case MISCREG_PIC: + panic("ASR number %d not implemented\n", miscReg - AsrStart); + case MISCREG_GSR: + return gsr; + case MISCREG_SOFTINT: + return softint; + case MISCREG_TICK_CMPR: + return tick_cmpr; + case MISCREG_STICK: + return stick; + case MISCREG_STICK_CMPR: + return stick_cmpr; + + /** Privilged Registers */ + case MISCREG_TPC: + return tpc[tl-1]; + case MISCREG_TNPC: + return tnpc[tl-1]; + case MISCREG_TSTATE: + return tstate[tl-1]; + case MISCREG_TT: + return tt[tl-1]; + case MISCREG_PRIVTICK: + panic("Priviliged access to tick registers not implemented\n"); + case MISCREG_TBA: + return tba; + case MISCREG_PSTATE: + return pstate; + case MISCREG_TL: + return tl; + case MISCREG_PIL: + return pil; + case MISCREG_CWP: + return cwp; + case MISCREG_CANSAVE: + return cansave; + case MISCREG_CANRESTORE: + return canrestore; + case MISCREG_CLEANWIN: + return cleanwin; + case MISCREG_OTHERWIN: + return otherwin; + case MISCREG_WSTATE: + return wstate; + case MISCREG_GL: + return gl; + + /** Hyper privileged registers */ + case MISCREG_HPSTATE: + return hpstate; + case MISCREG_HTSTATE: + return htstate[tl-1]; + case MISCREG_HINTP: + panic("HINTP not implemented\n"); + case MISCREG_HTBA: + return htba; + case MISCREG_HVER: + return NWindows | MaxTL << 8 | MaxGL << 16; + case MISCREG_STRAND_STS_REG: + return strandStatusReg; + case MISCREG_HSTICK_CMPR: + return hstick_cmpr; + + /** Floating Point Status Register */ + case MISCREG_FSR: + return fsr; + default: + panic("Miscellaneous register %d not implemented\n", miscReg); + } +} + +MiscReg MiscRegFile::readRegWithEffect(int miscReg, + Fault &fault, ThreadContext * tc) +{ + fault = NoFault; + switch (miscReg) { + case MISCREG_Y: + case MISCREG_CCR: + case MISCREG_ASI: + return readReg(miscReg); + + case MISCREG_TICK: + case MISCREG_PRIVTICK: + // Check for reading privilege + if (tickFields.npt && !isNonPriv()) { + fault = new PrivilegedAction; + return 0; + } + return tc->getCpuPtr()->curCycle() - tickFields.counter | + tickFields.npt << 63; + case MISCREG_PC: + return tc->readPC(); + case MISCREG_FPRS: + fault = new UnimpFault("FPU not implemented\n"); + return 0; + case MISCREG_PCR: + fault = new UnimpFault("Performance Instrumentation not impl\n"); + return 0; + case MISCREG_PIC: + fault = new UnimpFault("Performance Instrumentation not impl\n"); + return 0; + case MISCREG_GSR: + return readReg(miscReg); + + /** Privilged Registers */ + case MISCREG_TPC: + case MISCREG_TNPC: + case MISCREG_TSTATE: + case MISCREG_TT: + if (tl == 0) { + fault = new IllegalInstruction; + return 0; + } // NOTE THE FALL THROUGH! + case MISCREG_PSTATE: + case MISCREG_TL: + return readReg(miscReg); + + case MISCREG_TBA: + return readReg(miscReg) & ULL(~0x7FFF); + + case MISCREG_PIL: + + case MISCREG_CWP: + case MISCREG_CANSAVE: + case MISCREG_CANRESTORE: + case MISCREG_CLEANWIN: + case MISCREG_OTHERWIN: + case MISCREG_WSTATE: + case MISCREG_GL: + return readReg(miscReg); + + /** Floating Point Status Register */ + case MISCREG_FSR: + panic("Floating Point not implemented\n"); + default: +#if FULL_SYSTEM + return readFSRegWithEffect(miscReg, fault, tc); +#else + fault = new IllegalInstruction; + return 0; +#endif + } +} + +Fault MiscRegFile::setReg(int miscReg, const MiscReg &val) +{ + switch (miscReg) { + case MISCREG_Y: + y = val; + return NoFault; + case MISCREG_CCR: + ccr = val; + return NoFault; + case MISCREG_ASI: + asi = val; + return NoFault; + case MISCREG_FPRS: + fprs = val; + return NoFault; + case MISCREG_TICK: + tick = val; + return NoFault; + case MISCREG_PCR: + case MISCREG_PIC: + panic("ASR number %d not implemented\n", miscReg - AsrStart); + case MISCREG_GSR: + gsr = val; + case MISCREG_SOFTINT: + softint = val; + return NoFault; + case MISCREG_TICK_CMPR: + tick_cmpr = val; + return NoFault; + case MISCREG_STICK: + stick = val; + return NoFault; + case MISCREG_STICK_CMPR: + stick_cmpr = val; + return NoFault; + + /** Privilged Registers */ + case MISCREG_TPC: + tpc[tl-1] = val; + return NoFault; + case MISCREG_TNPC: + tnpc[tl-1] = val; + return NoFault; + case MISCREG_TSTATE: + tstate[tl-1] = val; + return NoFault; + case MISCREG_TT: + tt[tl-1] = val; + return NoFault; + case MISCREG_PRIVTICK: + panic("Priviliged access to tick regesiters not implemented\n"); + case MISCREG_TBA: + tba = val; + return NoFault; + case MISCREG_PSTATE: + pstate = val; + return NoFault; + case MISCREG_TL: + tl = val; + return NoFault; + case MISCREG_PIL: + pil = val; + return NoFault; + case MISCREG_CWP: + cwp = val; + return NoFault; + case MISCREG_CANSAVE: + cansave = val; + return NoFault; + case MISCREG_CANRESTORE: + canrestore = val; + return NoFault; + case MISCREG_CLEANWIN: + cleanwin = val; + return NoFault; + case MISCREG_OTHERWIN: + otherwin = val; + return NoFault; + case MISCREG_WSTATE: + wstate = val; + return NoFault; + case MISCREG_GL: + gl = val; + return NoFault; + + /** Hyper privileged registers */ + case MISCREG_HPSTATE: + hpstate = val; + return NoFault; + case MISCREG_HTSTATE: + htstate[tl-1] = val; + return NoFault; + case MISCREG_HINTP: + panic("HINTP not implemented\n"); + case MISCREG_HTBA: + htba = val; + return NoFault; + case MISCREG_STRAND_STS_REG: + strandStatusReg = val; + return NoFault; + case MISCREG_HSTICK_CMPR: + hstick_cmpr = val; + return NoFault; + + /** Floating Point Status Register */ + case MISCREG_FSR: + fsr = val; + return NoFault; + default: + panic("Miscellaneous register %d not implemented\n", miscReg); + } +} + +Fault MiscRegFile::setRegWithEffect(int miscReg, + const MiscReg &val, ThreadContext * tc) +{ + const uint64_t Bit64 = (1ULL << 63); + switch (miscReg) { + case MISCREG_Y: + case MISCREG_CCR: + case MISCREG_ASI: + setReg(miscReg, val); + return NoFault; + case MISCREG_PRIVTICK: + case MISCREG_TICK: + if (isNonPriv()) + return new PrivilegedOpcode; + if (isPriv()) + return new PrivilegedAction; + tickFields.counter = tc->getCpuPtr()->curCycle() - val & ~Bit64; + tickFields.npt = val & Bit64 ? 1 : 0; + return NoFault; + case MISCREG_PC: + return new IllegalInstruction; + case MISCREG_FPRS: + return new UnimpFault("FPU not implemented\n"); + case MISCREG_PCR: + return new UnimpFault("Performance Instrumentation not impl\n"); + case MISCREG_PIC: + return new UnimpFault("Performance Instrumentation not impl\n"); + case MISCREG_GSR: + return setReg(miscReg, val); + + /** Privilged Registers */ + case MISCREG_TPC: + case MISCREG_TNPC: + case MISCREG_TSTATE: + case MISCREG_TT: + if (tl == 0) + return new IllegalInstruction; + setReg(miscReg, val); + return NoFault; + + case MISCREG_TBA: + // clear lower 7 bits on writes. + setReg(miscReg, val & ULL(~0x7FFF)); + return NoFault; + + case MISCREG_PSTATE: + setReg(miscReg, val); + return NoFault; + + case MISCREG_TL: + if (isHyperPriv() && val > MaxTL) + setReg(miscReg, MaxTL); + else if (isPriv() && !isHyperPriv() && val > MaxPTL) + setReg(miscReg, MaxPTL); + else + setReg(miscReg, val); + return NoFault; + + case MISCREG_CWP: + tc->changeRegFileContext(CONTEXT_CWP, val); + case MISCREG_CANSAVE: + case MISCREG_CANRESTORE: + case MISCREG_CLEANWIN: + case MISCREG_OTHERWIN: + case MISCREG_WSTATE: + setReg(miscReg, val); + return NoFault; + + case MISCREG_GL: + int newval; + if (isHyperPriv() && val > MaxGL) + newval = MaxGL; + else if (isPriv() && !isHyperPriv() && val > MaxPGL) + newval = MaxPGL; + else + newval = val; + tc->changeRegFileContext(CONTEXT_GLOBALS, newval); + setReg(miscReg, newval); + return NoFault; + + /** Floating Point Status Register */ + case MISCREG_FSR: + panic("Floating Point not implemented\n"); + default: +#if FULL_SYSTEM + setFSRegWithEffect(miscReg, val, tc); +#else + return new IllegalInstruction; +#endif + } +} + +void MiscRegFile::serialize(std::ostream & os) +{ + SERIALIZE_SCALAR(pstate); + SERIALIZE_SCALAR(tba); + SERIALIZE_SCALAR(y); + SERIALIZE_SCALAR(pil); + SERIALIZE_SCALAR(gl); + SERIALIZE_SCALAR(cwp); + SERIALIZE_ARRAY(tt, MaxTL); + SERIALIZE_SCALAR(ccr); + SERIALIZE_SCALAR(asi); + SERIALIZE_SCALAR(tl); + SERIALIZE_ARRAY(tpc, MaxTL); + SERIALIZE_ARRAY(tnpc, MaxTL); + SERIALIZE_ARRAY(tstate, MaxTL); + SERIALIZE_SCALAR(tick); + SERIALIZE_SCALAR(cansave); + SERIALIZE_SCALAR(canrestore); + SERIALIZE_SCALAR(otherwin); + SERIALIZE_SCALAR(cleanwin); + SERIALIZE_SCALAR(wstate); + SERIALIZE_SCALAR(fsr); + SERIALIZE_SCALAR(fprs); + SERIALIZE_SCALAR(hpstate); + SERIALIZE_ARRAY(htstate, MaxTL); + SERIALIZE_SCALAR(htba); + SERIALIZE_SCALAR(hstick_cmpr); +} + +void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section) +{ + UNSERIALIZE_SCALAR(pstate); + UNSERIALIZE_SCALAR(tba); + UNSERIALIZE_SCALAR(y); + UNSERIALIZE_SCALAR(pil); + UNSERIALIZE_SCALAR(gl); + UNSERIALIZE_SCALAR(cwp); + UNSERIALIZE_ARRAY(tt, MaxTL); + UNSERIALIZE_SCALAR(ccr); + UNSERIALIZE_SCALAR(asi); + UNSERIALIZE_SCALAR(tl); + UNSERIALIZE_ARRAY(tpc, MaxTL); + UNSERIALIZE_ARRAY(tnpc, MaxTL); + UNSERIALIZE_ARRAY(tstate, MaxTL); + UNSERIALIZE_SCALAR(tick); + UNSERIALIZE_SCALAR(cansave); + UNSERIALIZE_SCALAR(canrestore); + UNSERIALIZE_SCALAR(otherwin); + UNSERIALIZE_SCALAR(cleanwin); + UNSERIALIZE_SCALAR(wstate); + UNSERIALIZE_SCALAR(fsr); + UNSERIALIZE_SCALAR(fprs); + UNSERIALIZE_SCALAR(hpstate); + UNSERIALIZE_ARRAY(htstate, MaxTL); + UNSERIALIZE_SCALAR(htba); + UNSERIALIZE_SCALAR(hstick_cmpr); +} + diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh new file mode 100644 index 000000000..be143311f --- /dev/null +++ b/src/arch/sparc/miscregfile.hh @@ -0,0 +1,410 @@ +/* + * 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. + * + * Authors: Gabe Black + * Ali Saidi + */ + +#ifndef __ARCH_SPARC_MISCREGFILE_HH__ +#define __ARCH_SPARC_MISCREGFILE_HH__ + +#include "arch/sparc/faults.hh" +#include "arch/sparc/isa_traits.hh" +#include "arch/sparc/types.hh" + +#include <string> + +namespace SparcISA +{ + + //These functions map register indices to names + std::string getMiscRegName(RegIndex); + + const int AsrStart = 0; + const int PrStart = 32; + const int HprStart = 64; + const int MiscStart = 96; + + enum MiscRegIndex + { + /** Ancillary State Registers */ + MISCREG_Y = AsrStart + 0, + MISCREG_CCR = AsrStart + 2, + MISCREG_ASI = AsrStart + 3, + MISCREG_TICK = AsrStart + 4, + MISCREG_PC = AsrStart + 5, + MISCREG_FPRS = AsrStart + 6, + MISCREG_PCR = AsrStart + 16, + MISCREG_PIC = AsrStart + 17, + MISCREG_GSR = AsrStart + 19, + MISCREG_SOFTINT_SET = AsrStart + 20, + MISCREG_SOFTINT_CLR = AsrStart + 21, + MISCREG_SOFTINT = AsrStart + 22, + MISCREG_TICK_CMPR = AsrStart + 23, + MISCREG_STICK = AsrStart + 24, + MISCREG_STICK_CMPR = AsrStart + 25, + + /** Privilged Registers */ + MISCREG_TPC = PrStart + 0, + MISCREG_TNPC = PrStart + 1, + MISCREG_TSTATE = PrStart + 2, + MISCREG_TT = PrStart + 3, + MISCREG_PRIVTICK = PrStart + 4, + MISCREG_TBA = PrStart + 5, + MISCREG_PSTATE = PrStart + 6, + MISCREG_TL = PrStart + 7, + MISCREG_PIL = PrStart + 8, + MISCREG_CWP = PrStart + 9, + MISCREG_CANSAVE = PrStart + 10, + MISCREG_CANRESTORE = PrStart + 11, + MISCREG_CLEANWIN = PrStart + 12, + MISCREG_OTHERWIN = PrStart + 13, + MISCREG_WSTATE = PrStart + 14, + MISCREG_GL = PrStart + 16, + + /** Hyper privileged registers */ + MISCREG_HPSTATE = HprStart + 0, + MISCREG_HTSTATE = HprStart + 1, + MISCREG_HINTP = HprStart + 3, + MISCREG_HTBA = HprStart + 5, + MISCREG_HVER = HprStart + 6, + MISCREG_STRAND_STS_REG = HprStart + 16, + MISCREG_HSTICK_CMPR = HprStart + 31, + + /** Floating Point Status Register */ + MISCREG_FSR = MiscStart + 0 + + }; + + // The control registers, broken out into fields + class MiscRegFile + { + private: + + /* ASR Registers */ + union { + uint64_t y; // Y (used in obsolete multiplication) + struct { + uint64_t value:32; // The actual value stored in y + uint64_t :32; // reserved bits + } yFields; + }; + union { + uint8_t ccr; // Condition Code Register + struct { + union { + uint8_t icc:4; // 32-bit condition codes + struct { + uint8_t c:1; // Carry + uint8_t v:1; // Overflow + uint8_t z:1; // Zero + uint8_t n:1; // Negative + } iccFields; + }; + union { + uint8_t xcc:4; // 64-bit condition codes + struct { + uint8_t c:1; // Carry + uint8_t v:1; // Overflow + uint8_t z:1; // Zero + uint8_t n:1; // Negative + } xccFields; + }; + } ccrFields; + }; + uint8_t asi; // Address Space Identifier + union { + uint64_t tick; // Hardware clock-tick counter + struct { + int64_t counter:63; // Clock-tick count + uint64_t npt:1; // Non-priveleged trap + } tickFields; + }; + union { + uint8_t fprs; // Floating-Point Register State + struct { + uint8_t dl:1; // Dirty lower + uint8_t du:1; // Dirty upper + uint8_t fef:1; // FPRS enable floating-Point + } fprsFields; + }; + union { + uint64_t gsr; //General Status Register + struct { + uint64_t mask:32; + uint64_t :4; + uint64_t im:1; + uint64_t irnd:2; + uint64_t :17; + uint64_t scale:5; + uint64_t align:3; + } gsrFields; + }; + union { + uint64_t softint; + struct { + uint64_t tm:1; + uint64_t int_level:14; + uint64_t sm:1; + } softintFields; + }; + union { + uint64_t tick_cmpr; // Hardware tick compare registers + struct { + uint64_t tick_cmpr:63; // Clock-tick count + uint64_t int_dis:1; // Non-priveleged trap + } tick_cmprFields; + }; + union { + uint64_t stick; // Hardware clock-tick counter + struct { + int64_t :63; // Not used, storage in SparcSystem + uint64_t npt:1; // Non-priveleged trap + } stickFields; + }; + union { + uint64_t stick_cmpr; // Hardware tick compare registers + struct { + uint64_t tick_cmpr:63; // Clock-tick count + uint64_t int_dis:1; // Non-priveleged trap + } stick_cmprFields; + }; + + + /* Privileged Registers */ + uint64_t tpc[MaxTL]; // Trap Program Counter (value from + // previous trap level) + uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from + // previous trap level) + union { + uint64_t tstate[MaxTL]; // Trap State + struct { + //Values are from previous trap level + uint64_t cwp:5; // Current Window Pointer + uint64_t :3; // Reserved bits + uint64_t pstate:13; // Process State + uint64_t :3; // Reserved bits + uint64_t asi:8; // Address Space Identifier + uint64_t ccr:8; // Condition Code Register + uint64_t gl:8; // Global level + } tstateFields[MaxTL]; + }; + uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured + // on the previous level) + uint64_t tba; // Trap Base Address + + union { + uint16_t pstate; // Process State Register + struct { + uint16_t :1; // reserved + uint16_t ie:1; // Interrupt enable + uint16_t priv:1; // Privelege mode + uint16_t am:1; // Address mask + uint16_t pef:1; // PSTATE enable floating-point + uint16_t :1; // reserved2 + uint16_t mm:2; // Memory Model + uint16_t tle:1; // Trap little-endian + uint16_t cle:1; // Current little-endian + } pstateFields; + }; + uint8_t tl; // Trap Level + uint8_t pil; // Process Interrupt Register + uint8_t cwp; // Current Window Pointer + uint8_t cansave; // Savable windows + uint8_t canrestore; // Restorable windows + uint8_t cleanwin; // Clean windows + uint8_t otherwin; // Other windows + union { + uint8_t wstate; // Window State + struct { + uint8_t normal:3; // Bits TT<4:2> are set to on a normal + // register window trap + uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin" + // register window trap + } wstateFields; + }; + uint8_t gl; // Global level register + + + /** Hyperprivileged Registers */ + union { + uint64_t hpstate; // Hyperprivileged State Register + struct { + uint8_t tlz: 1; + uint8_t :1; + uint8_t hpriv:1; + uint8_t :2; + uint8_t red:1; + uint8_t :4; + uint8_t ibe:1; + uint8_t id:1; + } hpstateFields; + }; + + uint64_t htstate[MaxTL]; // Hyperprivileged Trap State Register + uint64_t hintp; + uint64_t htba; // Hyperprivileged Trap Base Address register + union { + uint64_t hstick_cmpr; // Hardware tick compare registers + struct { + uint64_t tick_cmpr:63; // Clock-tick count + uint64_t int_dis:1; // Non-priveleged trap + } hstick_cmprFields; + }; + + uint64_t strandStatusReg; // Per strand status register + + + /** Floating point misc registers. */ + union { + uint64_t fsr; // Floating-Point State Register + struct { + union { + uint64_t cexc:5; // Current excpetion + struct { + uint64_t nxc:1; // Inexact + uint64_t dzc:1; // Divide by zero + uint64_t ufc:1; // Underflow + uint64_t ofc:1; // Overflow + uint64_t nvc:1; // Invalid operand + } cexcFields; + }; + union { + uint64_t aexc:5; // Accrued exception + struct { + uint64_t nxc:1; // Inexact + uint64_t dzc:1; // Divide by zero + uint64_t ufc:1; // Underflow + uint64_t ofc:1; // Overflow + uint64_t nvc:1; // Invalid operand + } aexcFields; + }; + uint64_t fcc0:2; // Floating-Point condtion codes + uint64_t :1; // Reserved bits + uint64_t qne:1; // Deferred trap queue not empty + // with no queue, it should read 0 + uint64_t ftt:3; // Floating-Point trap type + uint64_t ver:3; // Version (of the FPU) + uint64_t :2; // Reserved bits + uint64_t ns:1; // Nonstandard floating point + union { + uint64_t tem:5; // Trap Enable Mask + struct { + uint64_t nxm:1; // Inexact + uint64_t dzm:1; // Divide by zero + uint64_t ufm:1; // Underflow + uint64_t ofm:1; // Overflow + uint64_t nvm:1; // Invalid operand + } temFields; + }; + uint64_t :2; // Reserved bits + uint64_t rd:2; // Rounding direction + uint64_t fcc1:2; // Floating-Point condition codes + uint64_t fcc2:2; // Floating-Point condition codes + uint64_t fcc3:2; // Floating-Point condition codes + uint64_t :26; // Reserved bits + } fsrFields; + }; + + // These need to check the int_dis field and if 0 then + // set appropriate bit in softint and checkinterrutps on the cpu +#if FULL_SYSTEM + /** Process a tick compare event and generate an interrupt on the cpu if + * appropriate. */ + void processTickCompare(ThreadContext *tc); + void processSTickCompare(ThreadContext *tc); + void processHSTickCompare(ThreadContext *tc); + + typedef CpuEventWrapper<MiscRegFile, + &MiscRegFile::processTickCompare> TickCompareEvent; + TickCompareEvent *tickCompare; + + typedef CpuEventWrapper<MiscRegFile, + &MiscRegFile::processSTickCompare> STickCompareEvent; + STickCompareEvent *sTickCompare; + + typedef CpuEventWrapper<MiscRegFile, + &MiscRegFile::processHSTickCompare> HSTickCompareEvent; + HSTickCompareEvent *hSTickCompare; + + /** Fullsystem only register version of ReadRegWithEffect() */ + MiscReg readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc); + /** Fullsystem only register version of SetRegWithEffect() */ + Fault setFSRegWithEffect(int miscReg, const MiscReg &val, + ThreadContext * tc); +#endif + public: + + void reset(); + + MiscRegFile() + { + reset(); + } + + /** read a value out of an either an SE or FS IPR. No checking is done + * about SE vs. FS as this is mostly used to copy the regfile. Thus more + * register are copied that are necessary for FS. However this prevents + * a bunch of ifdefs and is rarely called so is not performance + * criticial. */ + MiscReg readReg(int miscReg); + + /** Read a value from an IPR. Only the SE iprs are here and the rest + * are are readFSRegWithEffect (which is called by readRegWithEffect()). + * Checking is done for permission based on state bits in the miscreg + * file. */ + MiscReg readRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc); + + /** write a value into an either an SE or FS IPR. No checking is done + * about SE vs. FS as this is mostly used to copy the regfile. Thus more + * register are copied that are necessary for FS. However this prevents + * a bunch of ifdefs and is rarely called so is not performance + * criticial.*/ + Fault setReg(int miscReg, const MiscReg &val); + + /** Write a value into an IPR. Only the SE iprs are here and the rest + * are are setFSRegWithEffect (which is called by setRegWithEffect()). + * Checking is done for permission based on state bits in the miscreg + * file. */ + Fault setRegWithEffect(int miscReg, + const MiscReg &val, ThreadContext * tc); + + void serialize(std::ostream & os); + + void unserialize(Checkpoint * cp, const std::string & section); + + void copyMiscRegs(ThreadContext * tc); + + protected: + + bool isHyperPriv() { return hpstateFields.hpriv; } + bool isPriv() { return hpstateFields.hpriv || pstateFields.priv; } + bool isNonPriv() { return !isPriv(); } + }; +} + +#endif diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc new file mode 100644 index 000000000..747426781 --- /dev/null +++ b/src/arch/sparc/regfile.cc @@ -0,0 +1,279 @@ +/* + * 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. + * + * Authors: Gabe Black + * Ali Saidi + */ + +#include "arch/sparc/regfile.hh" +#include "cpu/thread_context.hh" + +class Checkpoint; + +using namespace SparcISA; +using namespace std; + +//RegFile class methods +Addr RegFile::readPC() +{ + return pc; +} + +void RegFile::setPC(Addr val) +{ + pc = val; +} + +Addr RegFile::readNextPC() +{ + return npc; +} + +void RegFile::setNextPC(Addr val) +{ + npc = val; +} + +Addr RegFile::readNextNPC() +{ + return nnpc; +} + +void RegFile::setNextNPC(Addr val) +{ + nnpc = val; +} + +void RegFile::clear() +{ + intRegFile.clear(); + floatRegFile.clear(); +} + +MiscReg RegFile::readMiscReg(int miscReg) +{ + return miscRegFile.readReg(miscReg); +} + +MiscReg RegFile::readMiscRegWithEffect(int miscReg, + Fault &fault, ThreadContext *tc) +{ + return miscRegFile.readRegWithEffect(miscReg, fault, tc); +} + +Fault RegFile::setMiscReg(int miscReg, const MiscReg &val) +{ + return miscRegFile.setReg(miscReg, val); +} + +Fault RegFile::setMiscRegWithEffect(int miscReg, const MiscReg &val, + ThreadContext * tc) +{ + return miscRegFile.setRegWithEffect(miscReg, val, tc); +} + +FloatReg RegFile::readFloatReg(int floatReg, int width) +{ + return floatRegFile.readReg(floatReg, width); +} + +FloatReg RegFile::readFloatReg(int floatReg) +{ + //Use the "natural" width of a single float + return floatRegFile.readReg(floatReg, FloatRegFile::SingleWidth); +} + +FloatRegBits RegFile::readFloatRegBits(int floatReg, int width) +{ + return floatRegFile.readRegBits(floatReg, width); +} + +FloatRegBits RegFile::readFloatRegBits(int floatReg) +{ + //Use the "natural" width of a single float + return floatRegFile.readRegBits(floatReg, + FloatRegFile::SingleWidth); +} + +Fault RegFile::setFloatReg(int floatReg, const FloatReg &val, int width) +{ + return floatRegFile.setReg(floatReg, val, width); +} + +Fault RegFile::setFloatReg(int floatReg, const FloatReg &val) +{ + //Use the "natural" width of a single float + return setFloatReg(floatReg, val, FloatRegFile::SingleWidth); +} + +Fault RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val, int width) +{ + return floatRegFile.setRegBits(floatReg, val, width); +} + +Fault RegFile::setFloatRegBits(int floatReg, const FloatRegBits &val) +{ + //Use the "natural" width of a single float + return floatRegFile.setRegBits(floatReg, val, + FloatRegFile::SingleWidth); +} + +IntReg RegFile::readIntReg(int intReg) +{ + return intRegFile.readReg(intReg); +} + +Fault RegFile::setIntReg(int intReg, const IntReg &val) +{ + return intRegFile.setReg(intReg, val); +} + +void RegFile::serialize(std::ostream &os) +{ + intRegFile.serialize(os); + floatRegFile.serialize(os); + miscRegFile.serialize(os); + SERIALIZE_SCALAR(pc); + SERIALIZE_SCALAR(npc); +} + +void RegFile::unserialize(Checkpoint *cp, const std::string §ion) +{ + intRegFile.unserialize(cp, section); + floatRegFile.unserialize(cp, section); + miscRegFile.unserialize(cp, section); + UNSERIALIZE_SCALAR(pc); + UNSERIALIZE_SCALAR(npc); +} + +void RegFile::changeContext(RegContextParam param, RegContextVal val) +{ + switch(param) + { + case CONTEXT_CWP: + intRegFile.setCWP(val); + break; + case CONTEXT_GLOBALS: + intRegFile.setGlobals(val); + break; + default: + panic("Tried to set illegal context parameter in the SPARC regfile.\n"); + } +} + +int SparcISA::InterruptLevel(uint64_t softint) +{ + if (softint & 0x10000 || softint & 0x1) + return 14; + + int level = 14; + while (level >= 0 && !(1 << (level + 1) & softint)) + level--; + if (1 << (level + 1) & softint) + return level; + return 0; +} + +void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest) +{ + + uint8_t tl = src->readMiscReg(MISCREG_TL); + + // Read all the trap level dependent registers and save them off + for(int i = 1; i <= MaxTL; i++) + { + src->setMiscReg(MISCREG_TL, i); + dest->setMiscReg(MISCREG_TL, i); + + dest->setMiscReg(MISCREG_TT, src->readMiscReg(MISCREG_TT)); + dest->setMiscReg(MISCREG_TPC, src->readMiscReg(MISCREG_TPC)); + dest->setMiscReg(MISCREG_TNPC, src->readMiscReg(MISCREG_TNPC)); + dest->setMiscReg(MISCREG_TSTATE, src->readMiscReg(MISCREG_TSTATE)); + } + + // Save off the traplevel + dest->setMiscReg(MISCREG_TL, tl); + src->setMiscReg(MISCREG_TL, tl); + + + // ASRs + dest->setMiscReg(MISCREG_Y, src->readMiscReg(MISCREG_Y)); + dest->setMiscReg(MISCREG_CCR, src->readMiscReg(MISCREG_CCR)); + dest->setMiscReg(MISCREG_ASI, src->readMiscReg(MISCREG_ASI)); + dest->setMiscReg(MISCREG_TICK, src->readMiscReg(MISCREG_TICK)); + dest->setMiscReg(MISCREG_FPRS, src->readMiscReg(MISCREG_FPRS)); + dest->setMiscReg(MISCREG_SOFTINT, src->readMiscReg(MISCREG_SOFTINT)); + dest->setMiscReg(MISCREG_TICK_CMPR, src->readMiscReg(MISCREG_TICK_CMPR)); + dest->setMiscReg(MISCREG_STICK, src->readMiscReg(MISCREG_STICK)); + dest->setMiscReg(MISCREG_STICK_CMPR, src->readMiscReg(MISCREG_STICK_CMPR)); + + // Priv Registers + dest->setMiscReg(MISCREG_TICK, src->readMiscReg(MISCREG_TICK)); + dest->setMiscReg(MISCREG_TBA, src->readMiscReg(MISCREG_TBA)); + dest->setMiscReg(MISCREG_PSTATE, src->readMiscReg(MISCREG_PSTATE)); + dest->setMiscReg(MISCREG_PIL, src->readMiscReg(MISCREG_PIL)); + dest->setMiscReg(MISCREG_CWP, src->readMiscReg(MISCREG_CWP)); + dest->setMiscReg(MISCREG_CANSAVE, src->readMiscReg(MISCREG_CANSAVE)); + dest->setMiscReg(MISCREG_CANRESTORE, src->readMiscReg(MISCREG_CANRESTORE)); + dest->setMiscReg(MISCREG_OTHERWIN, src->readMiscReg(MISCREG_OTHERWIN)); + dest->setMiscReg(MISCREG_CLEANWIN, src->readMiscReg(MISCREG_CLEANWIN)); + dest->setMiscReg(MISCREG_WSTATE, src->readMiscReg(MISCREG_WSTATE)); + dest->setMiscReg(MISCREG_GL, src->readMiscReg(MISCREG_GL)); + + // Hyperprivilged registers + dest->setMiscReg(MISCREG_HPSTATE, src->readMiscReg(MISCREG_HPSTATE)); + dest->setMiscReg(MISCREG_HINTP, src->readMiscReg(MISCREG_HINTP)); + dest->setMiscReg(MISCREG_HTBA, src->readMiscReg(MISCREG_HTBA)); + dest->setMiscReg(MISCREG_STRAND_STS_REG, + src->readMiscReg(MISCREG_STRAND_STS_REG)); + dest->setMiscReg(MISCREG_HSTICK_CMPR, + src->readMiscReg(MISCREG_HSTICK_CMPR)); + + // FSR + dest->setMiscReg(MISCREG_FSR, src->readMiscReg(MISCREG_FSR)); +} + +void SparcISA::copyRegs(ThreadContext *src, ThreadContext *dest) +{ + // First loop through the integer registers. + for (int i = 0; i < TheISA::NumIntRegs; ++i) { + dest->setIntReg(i, src->readIntReg(i)); + } + + // Then loop through the floating point registers. + for (int i = 0; i < TheISA::NumFloatRegs; ++i) { + dest->setFloatRegBits(i, src->readFloatRegBits(i)); + } + + // Copy misc. registers + copyMiscRegs(src, dest); + + // Lastly copy PC/NPC + dest->setPC(src->readPC()); + dest->setNextPC(src->readNextPC()); + dest->setNextNPC(src->readNextNPC()); +} diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh index db48b2d78..500fbbba4 100644 --- a/src/arch/sparc/regfile.hh +++ b/src/arch/sparc/regfile.hh @@ -32,832 +32,84 @@ #ifndef __ARCH_SPARC_REGFILE_HH__ #define __ARCH_SPARC_REGFILE_HH__ -#include "arch/sparc/exceptions.hh" #include "arch/sparc/faults.hh" -#include "base/trace.hh" -#include "sim/byteswap.hh" -#include "cpu/cpuevent.hh" +#include "arch/sparc/floatregfile.hh" +#include "arch/sparc/intregfile.hh" +#include "arch/sparc/isa_traits.hh" +#include "arch/sparc/miscregfile.hh" +#include "arch/sparc/types.hh" #include "sim/host.hh" +#include <string> + class Checkpoint; namespace SparcISA { - - typedef uint8_t RegIndex; - - // MAXTL - maximum trap level - const int MaxPTL = 2; - const int MaxTL = 6; - const int MaxGL = 3; - const int MaxPGL = 2; - - // NWINDOWS - number of register windows, can be 3 to 32 - const int NWindows = 32; - - const int AsrStart = 0; - const int PrStart = 32; - const int HprStart = 64; - const int MiscStart = 96; - - const uint64_t Bit64 = (1ULL << 63); - class IntRegFile + class RegFile { protected: - static const int FrameOffsetBits = 3; - static const int FrameNumBits = 2; - - static const int RegsPerFrame = 1 << FrameOffsetBits; - static const int FrameNumMask = - (FrameNumBits == sizeof(int)) ? - (unsigned int)(-1) : - (1 << FrameNumBits) - 1; - static const int FrameOffsetMask = - (FrameOffsetBits == sizeof(int)) ? - (unsigned int)(-1) : - (1 << FrameOffsetBits) - 1; - - IntReg regGlobals[MaxGL][RegsPerFrame]; - IntReg regSegments[2 * NWindows][RegsPerFrame]; - - enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames}; - - IntReg * regView[NumFrames]; - - static const int RegGlobalOffset = 0; - static const int FrameOffset = MaxGL * RegsPerFrame; - int offset[NumFrames]; + Addr pc; // Program Counter + Addr npc; // Next Program Counter + Addr nnpc; public: + Addr readPC(); + void setPC(Addr val); - int flattenIndex(int reg) - { - int flatIndex = offset[reg >> FrameOffsetBits] - | (reg & FrameOffsetMask); - DPRINTF(Sparc, "Flattened index %d into %d.\n", reg, flatIndex); - return flatIndex; - } - - void clear() - { - int x; - for (x = 0; x < MaxGL; x++) - memset(regGlobals[x], 0, sizeof(regGlobals[x])); - for(int x = 0; x < 2 * NWindows; x++) - bzero(regSegments[x], sizeof(regSegments[x])); - } - - IntRegFile() - { - offset[Globals] = 0; - regView[Globals] = regGlobals[0]; - setCWP(0); - clear(); - } - - IntReg readReg(int intReg) - { - IntReg val = - regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask]; - DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, val); - return val; - } - - Fault setReg(int intReg, const IntReg &val) - { - if(intReg) - DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val); - regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val; - return NoFault; - } - - //This doesn't effect the actual CWP register. - //It's purpose is to adjust the view of the register file - //to what it would be if CWP = cwp. - void setCWP(int cwp) - { - int index = ((NWindows - cwp) % NWindows) * 2; - offset[Outputs] = FrameOffset + (index * RegsPerFrame); - offset[Locals] = FrameOffset + ((index+1) * RegsPerFrame); - offset[Inputs] = FrameOffset + - (((index+2) % (NWindows * 2)) * RegsPerFrame); - regView[Outputs] = regSegments[index]; - regView[Locals] = regSegments[index+1]; - regView[Inputs] = regSegments[(index+2) % (NWindows * 2)]; - - DPRINTF(Sparc, "Changed the CWP value to %d\n", cwp); - } - - void setGlobals(int gl) - { - - DPRINTF(Sparc, "Now using %d globals", gl); - - regView[Globals] = regGlobals[gl]; - offset[Globals] = RegGlobalOffset + gl * RegsPerFrame; - } + Addr readNextPC(); + void setNextPC(Addr val); - void serialize(std::ostream &os); - - void unserialize(Checkpoint *cp, const std::string §ion); - }; - - typedef float float32_t; - typedef double float64_t; - //FIXME long double refers to a 10 byte float, rather than a - //16 byte float as required. This data type may have to be emulated. - typedef double float128_t; - - class FloatRegFile - { - public: - static const int SingleWidth = 32; - static const int DoubleWidth = 64; - static const int QuadWidth = 128; + Addr readNextNPC(); + void setNextNPC(Addr val); protected: - - //Since the floating point registers overlap each other, - //A generic storage space is used. The float to be returned is - //pulled from the appropriate section of this region. - char regSpace[(SingleWidth / 8) * NumFloatRegs]; + IntRegFile intRegFile; // integer register file + FloatRegFile floatRegFile; // floating point register file + MiscRegFile miscRegFile; // control register file public: - void clear() - { - bzero(regSpace, sizeof(regSpace)); - } - - FloatReg readReg(int floatReg, int width) - { - //In each of these cases, we have to copy the value into a temporary - //variable. This is because we may otherwise try to access an - //unaligned portion of memory. - switch(width) - { - case SingleWidth: - float32_t result32; - memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32)); - return htog(result32); - case DoubleWidth: - float64_t result64; - memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64)); - return htog(result64); - case QuadWidth: - float128_t result128; - memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128)); - return htog(result128); - default: - panic("Attempted to read a %d bit floating point register!", width); - } - } - - FloatRegBits readRegBits(int floatReg, int width) - { - //In each of these cases, we have to copy the value into a temporary - //variable. This is because we may otherwise try to access an - //unaligned portion of memory. - switch(width) - { - case SingleWidth: - uint32_t result32; - memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32)); - return htog(result32); - case DoubleWidth: - uint64_t result64; - memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64)); - return htog(result64); - case QuadWidth: - uint64_t result128; - memcpy(&result128, regSpace + 4 * floatReg, sizeof(result128)); - return htog(result128); - default: - panic("Attempted to read a %d bit floating point register!", width); - } - } - - Fault setReg(int floatReg, const FloatReg &val, int width) - { - //In each of these cases, we have to copy the value into a temporary - //variable. This is because we may otherwise try to access an - //unaligned portion of memory. - - uint32_t result32; - uint64_t result64; - DPRINTF(Sparc, "Setting floating point register %d\n", floatReg); - switch(width) - { - case SingleWidth: - result32 = gtoh((uint32_t)val); - memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32)); - break; - case DoubleWidth: - result64 = gtoh((uint64_t)val); - memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64)); - break; - case QuadWidth: - panic("Quad width FP not implemented."); - break; - default: - panic("Attempted to read a %d bit floating point register!", width); - } - return NoFault; - } - - Fault setRegBits(int floatReg, const FloatRegBits &val, int width) - { - //In each of these cases, we have to copy the value into a temporary - //variable. This is because we may otherwise try to access an - //unaligned portion of memory. - uint32_t result32; - uint64_t result64; - switch(width) - { - case SingleWidth: - result32 = gtoh((uint32_t)val); - memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32)); - break; - case DoubleWidth: - result64 = gtoh((uint64_t)val); - memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64)); - break; - case QuadWidth: - panic("Quad width FP not implemented."); - break; - default: - panic("Attempted to read a %d bit floating point register!", width); - } - return NoFault; - } + void clear(); - void serialize(std::ostream &os); + int FlattenIntIndex(int reg); - void unserialize(Checkpoint *cp, const std::string §ion); - }; + MiscReg readMiscReg(int miscReg); - enum MiscRegIndex - { - /** Ancillary State Registers */ - MISCREG_Y = AsrStart + 0, - MISCREG_CCR = AsrStart + 2, - MISCREG_ASI = AsrStart + 3, - MISCREG_TICK = AsrStart + 4, - MISCREG_PC = AsrStart + 5, - MISCREG_FPRS = AsrStart + 6, - MISCREG_PCR = AsrStart + 16, - MISCREG_PIC = AsrStart + 17, - MISCREG_GSR = AsrStart + 19, - MISCREG_SOFTINT_SET = AsrStart + 20, - MISCREG_SOFTINT_CLR = AsrStart + 21, - MISCREG_SOFTINT = AsrStart + 22, - MISCREG_TICK_CMPR = AsrStart + 23, - MISCREG_STICK = AsrStart + 24, - MISCREG_STICK_CMPR = AsrStart + 25, - - /** Privilged Registers */ - MISCREG_TPC = PrStart + 0, - MISCREG_TNPC = PrStart + 1, - MISCREG_TSTATE = PrStart + 2, - MISCREG_TT = PrStart + 3, - MISCREG_PRIVTICK = PrStart + 4, - MISCREG_TBA = PrStart + 5, - MISCREG_PSTATE = PrStart + 6, - MISCREG_TL = PrStart + 7, - MISCREG_PIL = PrStart + 8, - MISCREG_CWP = PrStart + 9, - MISCREG_CANSAVE = PrStart + 10, - MISCREG_CANRESTORE = PrStart + 11, - MISCREG_CLEANWIN = PrStart + 12, - MISCREG_OTHERWIN = PrStart + 13, - MISCREG_WSTATE = PrStart + 14, - MISCREG_GL = PrStart + 16, - - /** Hyper privileged registers */ - MISCREG_HPSTATE = HprStart + 0, - MISCREG_HTSTATE = HprStart + 1, - MISCREG_HINTP = HprStart + 3, - MISCREG_HTBA = HprStart + 5, - MISCREG_HVER = HprStart + 6, - MISCREG_STRAND_STS_REG = HprStart + 16, - MISCREG_HSTICK_CMPR = HprStart + 31, - - /** Floating Point Status Register */ - MISCREG_FSR = MiscStart + 0 + MiscReg readMiscRegWithEffect(int miscReg, + Fault &fault, ThreadContext *tc); - }; + Fault setMiscReg(int miscReg, const MiscReg &val); - // The control registers, broken out into fields - class MiscRegFile - { - private: - - /* ASR Registers */ - union { - uint64_t y; // Y (used in obsolete multiplication) - struct { - uint64_t value:32; // The actual value stored in y - uint64_t :32; // reserved bits - } yFields; - }; - union { - uint8_t ccr; // Condition Code Register - struct { - union { - uint8_t icc:4; // 32-bit condition codes - struct { - uint8_t c:1; // Carry - uint8_t v:1; // Overflow - uint8_t z:1; // Zero - uint8_t n:1; // Negative - } iccFields; - }; - union { - uint8_t xcc:4; // 64-bit condition codes - struct { - uint8_t c:1; // Carry - uint8_t v:1; // Overflow - uint8_t z:1; // Zero - uint8_t n:1; // Negative - } xccFields; - }; - } ccrFields; - }; - uint8_t asi; // Address Space Identifier - union { - uint64_t tick; // Hardware clock-tick counter - struct { - int64_t counter:63; // Clock-tick count - uint64_t npt:1; // Non-priveleged trap - } tickFields; - }; - union { - uint8_t fprs; // Floating-Point Register State - struct { - uint8_t dl:1; // Dirty lower - uint8_t du:1; // Dirty upper - uint8_t fef:1; // FPRS enable floating-Point - } fprsFields; - }; - union { - uint64_t softint; - struct { - uint64_t tm:1; - uint64_t int_level:14; - uint64_t sm:1; - } softintFields; - }; - union { - uint64_t tick_cmpr; // Hardware tick compare registers - struct { - uint64_t tick_cmpr:63; // Clock-tick count - uint64_t int_dis:1; // Non-priveleged trap - } tick_cmprFields; - }; - union { - uint64_t stick; // Hardware clock-tick counter - struct { - int64_t :63; // Not used, storage in SparcSystem - uint64_t npt:1; // Non-priveleged trap - } stickFields; - }; - union { - uint64_t stick_cmpr; // Hardware tick compare registers - struct { - uint64_t tick_cmpr:63; // Clock-tick count - uint64_t int_dis:1; // Non-priveleged trap - } stick_cmprFields; - }; - - - /* Privileged Registers */ - uint64_t tpc[MaxTL]; // Trap Program Counter (value from - // previous trap level) - uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from - // previous trap level) - union { - uint64_t tstate[MaxTL]; // Trap State - struct { - //Values are from previous trap level - uint64_t cwp:5; // Current Window Pointer - uint64_t :3; // Reserved bits - uint64_t pstate:13; // Process State - uint64_t :3; // Reserved bits - uint64_t asi:8; // Address Space Identifier - uint64_t ccr:8; // Condition Code Register - uint64_t gl:8; // Global level - } tstateFields[MaxTL]; - }; - uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured - // on the previous level) - uint64_t tba; // Trap Base Address - - union { - uint16_t pstate; // Process State Register - struct { - uint16_t :1; // reserved - uint16_t ie:1; // Interrupt enable - uint16_t priv:1; // Privelege mode - uint16_t am:1; // Address mask - uint16_t pef:1; // PSTATE enable floating-point - uint16_t :1; // reserved2 - uint16_t mm:2; // Memory Model - uint16_t tle:1; // Trap little-endian - uint16_t cle:1; // Current little-endian - } pstateFields; - }; - uint8_t tl; // Trap Level - uint8_t pil; // Process Interrupt Register - uint8_t cwp; // Current Window Pointer - uint8_t cansave; // Savable windows - uint8_t canrestore; // Restorable windows - uint8_t cleanwin; // Clean windows - uint8_t otherwin; // Other windows - union { - uint8_t wstate; // Window State - struct { - uint8_t normal:3; // Bits TT<4:2> are set to on a normal - // register window trap - uint8_t other:3; // Bits TT<4:2> are set to on an "otherwin" - // register window trap - } wstateFields; - }; - uint8_t gl; // Global level register - - - /** Hyperprivileged Registers */ - union { - uint64_t hpstate; // Hyperprivileged State Register - struct { - uint8_t tlz: 1; - uint8_t :1; - uint8_t hpriv:1; - uint8_t :2; - uint8_t red:1; - uint8_t :4; - uint8_t ibe:1; - uint8_t id:1; - } hpstateFields; - }; - - uint64_t htstate[MaxTL]; // Hyperprivileged Trap State Register - uint64_t hintp; - uint64_t htba; // Hyperprivileged Trap Base Address register - union { - uint64_t hstick_cmpr; // Hardware tick compare registers - struct { - uint64_t tick_cmpr:63; // Clock-tick count - uint64_t int_dis:1; // Non-priveleged trap - } hstick_cmprFields; - }; - - uint64_t strandStatusReg; // Per strand status register - - - /** Floating point misc registers. */ - union { - uint64_t fsr; // Floating-Point State Register - struct { - union { - uint64_t cexc:5; // Current excpetion - struct { - uint64_t nxc:1; // Inexact - uint64_t dzc:1; // Divide by zero - uint64_t ufc:1; // Underflow - uint64_t ofc:1; // Overflow - uint64_t nvc:1; // Invalid operand - } cexcFields; - }; - union { - uint64_t aexc:5; // Accrued exception - struct { - uint64_t nxc:1; // Inexact - uint64_t dzc:1; // Divide by zero - uint64_t ufc:1; // Underflow - uint64_t ofc:1; // Overflow - uint64_t nvc:1; // Invalid operand - } aexcFields; - }; - uint64_t fcc0:2; // Floating-Point condtion codes - uint64_t :1; // Reserved bits - uint64_t qne:1; // Deferred trap queue not empty - // with no queue, it should read 0 - uint64_t ftt:3; // Floating-Point trap type - uint64_t ver:3; // Version (of the FPU) - uint64_t :2; // Reserved bits - uint64_t ns:1; // Nonstandard floating point - union { - uint64_t tem:5; // Trap Enable Mask - struct { - uint64_t nxm:1; // Inexact - uint64_t dzm:1; // Divide by zero - uint64_t ufm:1; // Underflow - uint64_t ofm:1; // Overflow - uint64_t nvm:1; // Invalid operand - } temFields; - }; - uint64_t :2; // Reserved bits - uint64_t rd:2; // Rounding direction - uint64_t fcc1:2; // Floating-Point condition codes - uint64_t fcc2:2; // Floating-Point condition codes - uint64_t fcc3:2; // Floating-Point condition codes - uint64_t :26; // Reserved bits - } fsrFields; - }; - - // These need to check the int_dis field and if 0 then - // set appropriate bit in softint and checkinterrutps on the cpu -#if FULL_SYSTEM - /** Process a tick compare event and generate an interrupt on the cpu if - * appropriate. */ - void processTickCompare(ThreadContext *tc); - void processSTickCompare(ThreadContext *tc); - void processHSTickCompare(ThreadContext *tc); - - typedef CpuEventWrapper<MiscRegFile, - &MiscRegFile::processTickCompare> TickCompareEvent; - TickCompareEvent *tickCompare; - - typedef CpuEventWrapper<MiscRegFile, - &MiscRegFile::processSTickCompare> STickCompareEvent; - STickCompareEvent *sTickCompare; - - typedef CpuEventWrapper<MiscRegFile, - &MiscRegFile::processHSTickCompare> HSTickCompareEvent; - HSTickCompareEvent *hSTickCompare; - - /** Fullsystem only register version of ReadRegWithEffect() */ - MiscReg readFSRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc); - /** Fullsystem only register version of SetRegWithEffect() */ - Fault setFSRegWithEffect(int miscReg, const MiscReg &val, + Fault setMiscRegWithEffect(int miscReg, const MiscReg &val, ThreadContext * tc); -#endif - public: - void reset() - { - pstateFields.pef = 0; //No FPU - //pstateFields.pef = 1; //FPU -#if FULL_SYSTEM - //For SPARC, when a system is first started, there is a power - //on reset Trap which sets the processor into the following state. - //Bits that aren't set aren't defined on startup. - tl = MaxTL; - gl = MaxGL; - - tickFields.counter = 0; //The TICK register is unreadable bya - tickFields.npt = 1; //The TICK register is unreadable by by !priv - - softint = 0; // Clear all the soft interrupt bits - tick_cmprFields.int_dis = 1; // disable timer compare interrupts - tick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing - stickFields.npt = 1; //The TICK register is unreadable by by !priv - stick_cmprFields.int_dis = 1; // disable timer compare interrupts - stick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing - - - tt[tl] = power_on_reset; - pstate = 0; // fields 0 but pef - pstateFields.pef = 1; - - hpstate = 0; - hpstateFields.red = 1; - hpstateFields.hpriv = 1; - hpstateFields.tlz = 0; // this is a guess - hintp = 0; // no interrupts pending - hstick_cmprFields.int_dis = 1; // disable timer compare interrupts - hstick_cmprFields.tick_cmpr = 0; // Reset to 0 for pretty printing -#else -/* //This sets up the initial state of the processor for usermode processes - pstateFields.priv = 0; //Process runs in user mode - pstateFields.ie = 1; //Interrupts are enabled - fsrFields.rd = 0; //Round to nearest - fsrFields.tem = 0; //Floating point traps not enabled - fsrFields.ns = 0; //Non standard mode off - fsrFields.qne = 0; //Floating point queue is empty - fsrFields.aexc = 0; //No accrued exceptions - fsrFields.cexc = 0; //No current exceptions - - //Register window management registers - otherwin = 0; //No windows contain info from other programs - canrestore = 0; //There are no windows to pop - cansave = MaxTL - 2; //All windows are available to save into - cleanwin = MaxTL;*/ -#endif - } - - MiscRegFile() - { - reset(); - } - - /** read a value out of an either an SE or FS IPR. No checking is done - * about SE vs. FS as this is mostly used to copy the regfile. Thus more - * register are copied that are necessary for FS. However this prevents - * a bunch of ifdefs and is rarely called so is not performance - * criticial. */ - MiscReg readReg(int miscReg); - - /** Read a value from an IPR. Only the SE iprs are here and the rest - * are are readFSRegWithEffect (which is called by readRegWithEffect()). - * Checking is done for permission based on state bits in the miscreg - * file. */ - MiscReg readRegWithEffect(int miscReg, Fault &fault, ThreadContext *tc); - - /** write a value into an either an SE or FS IPR. No checking is done - * about SE vs. FS as this is mostly used to copy the regfile. Thus more - * register are copied that are necessary for FS. However this prevents - * a bunch of ifdefs and is rarely called so is not performance - * criticial.*/ - Fault setReg(int miscReg, const MiscReg &val); - - /** Write a value into an IPR. Only the SE iprs are here and the rest - * are are setFSRegWithEffect (which is called by setRegWithEffect()). - * Checking is done for permission based on state bits in the miscreg - * file. */ - Fault setRegWithEffect(int miscReg, - const MiscReg &val, ThreadContext * tc); - - void serialize(std::ostream & os); - - void unserialize(Checkpoint * cp, const std::string & section); - - void copyMiscRegs(ThreadContext * tc); + FloatReg readFloatReg(int floatReg, int width); - protected: + FloatReg readFloatReg(int floatReg); - bool isHyperPriv() { return hpstateFields.hpriv; } - bool isPriv() { return hpstateFields.hpriv || pstateFields.priv; } - bool isNonPriv() { return !isPriv(); } - }; + FloatRegBits readFloatRegBits(int floatReg, int width); - typedef union - { - IntReg intreg; - FloatReg fpreg; - MiscReg ctrlreg; - } AnyReg; + FloatRegBits readFloatRegBits(int floatReg); - class RegFile - { - protected: - Addr pc; // Program Counter - Addr npc; // Next Program Counter - Addr nnpc; - - public: - Addr readPC() - { - return pc; - } - - void setPC(Addr val) - { - pc = val; - } - - Addr readNextPC() - { - return npc; - } - - void setNextPC(Addr val) - { - npc = val; - } - - Addr readNextNPC() - { - return nnpc; - } - - void setNextNPC(Addr val) - { - nnpc = val; - } - - protected: - IntRegFile intRegFile; // integer register file - FloatRegFile floatRegFile; // floating point register file - MiscRegFile miscRegFile; // control register file + Fault setFloatReg(int floatReg, const FloatReg &val, int width); - public: + Fault setFloatReg(int floatReg, const FloatReg &val); - void clear() - { - intRegFile.clear(); - floatRegFile.clear(); - } + Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width); - int FlattenIntIndex(int reg) - { - return intRegFile.flattenIndex(reg); - } + Fault setFloatRegBits(int floatReg, const FloatRegBits &val); - MiscReg readMiscReg(int miscReg) - { - return miscRegFile.readReg(miscReg); - } + IntReg readIntReg(int intReg); - MiscReg readMiscRegWithEffect(int miscReg, - Fault &fault, ThreadContext *tc) - { - return miscRegFile.readRegWithEffect(miscReg, fault, tc); - } - - Fault setMiscReg(int miscReg, const MiscReg &val) - { - return miscRegFile.setReg(miscReg, val); - } - - Fault setMiscRegWithEffect(int miscReg, const MiscReg &val, - ThreadContext * tc) - { - return miscRegFile.setRegWithEffect(miscReg, val, tc); - } - - FloatReg readFloatReg(int floatReg, int width) - { - return floatRegFile.readReg(floatReg, width); - } - - FloatReg readFloatReg(int floatReg) - { - //Use the "natural" width of a single float - return floatRegFile.readReg(floatReg, FloatRegFile::SingleWidth); - } - - FloatRegBits readFloatRegBits(int floatReg, int width) - { - return floatRegFile.readRegBits(floatReg, width); - } - - FloatRegBits readFloatRegBits(int floatReg) - { - //Use the "natural" width of a single float - return floatRegFile.readRegBits(floatReg, - FloatRegFile::SingleWidth); - } - - Fault setFloatReg(int floatReg, const FloatReg &val, int width) - { - return floatRegFile.setReg(floatReg, val, width); - } - - Fault setFloatReg(int floatReg, const FloatReg &val) - { - //Use the "natural" width of a single float - return setFloatReg(floatReg, val, FloatRegFile::SingleWidth); - } - - Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width) - { - return floatRegFile.setRegBits(floatReg, val, width); - } - - Fault setFloatRegBits(int floatReg, const FloatRegBits &val) - { - //Use the "natural" width of a single float - return floatRegFile.setRegBits(floatReg, val, - FloatRegFile::SingleWidth); - } - - IntReg readIntReg(int intReg) - { - return intRegFile.readReg(intReg); - } - - Fault setIntReg(int intReg, const IntReg &val) - { - return intRegFile.setReg(intReg, val); - } + Fault setIntReg(int intReg, const IntReg &val); void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); public: - enum ContextParam - { - CONTEXT_CWP, - CONTEXT_GLOBALS - }; - typedef int ContextVal; - - void changeContext(ContextParam param, ContextVal val) - { - switch(param) - { - case CONTEXT_CWP: - intRegFile.setCWP(val); - break; - case CONTEXT_GLOBALS: - intRegFile.setGlobals(val); - break; - default: - panic("Tried to set illegal context parameter in the SPARC regfile.\n"); - } - } + void changeContext(RegContextParam param, RegContextVal val); }; void copyRegs(ThreadContext *src, ThreadContext *dest); diff --git a/src/arch/sparc/syscallreturn.hh b/src/arch/sparc/syscallreturn.hh new file mode 100644 index 000000000..fd63a8868 --- /dev/null +++ b/src/arch/sparc/syscallreturn.hh @@ -0,0 +1,90 @@ +/* + * 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. + * + * Authors: Gabe Black + */ + +#ifndef __ARCH_SPARC_SYSCALLRETURN_HH__ +#define __ARCH_SPARC_SYSCALLRETURN_HH__ + +#include <inttypes.h> + +class SyscallReturn +{ + public: + template <class T> + SyscallReturn(T v, bool s) + { + retval = (uint64_t)v; + success = s; + } + + template <class T> + SyscallReturn(T v) + { + success = (v >= 0); + retval = (uint64_t)v; + } + + ~SyscallReturn() {} + + SyscallReturn& operator=(const SyscallReturn& s) + { + retval = s.retval; + success = s.success; + return *this; + } + + bool successful() { return success; } + uint64_t value() { return retval; } + + private: + uint64_t retval; + bool success; +}; + +namespace SparcISA +{ + static inline void setSyscallReturn(SyscallReturn return_value, + RegFile *regs) + { + // check for error condition. SPARC syscall convention is to + // indicate success/failure in reg the carry bit of the ccr + // and put the return value itself in the standard return value reg (). + if (return_value.successful()) { + // no error, clear XCC.C + regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) & 0xEF); + regs->setIntReg(ReturnValueReg, return_value.value()); + } else { + // got an error, set XCC.C + regs->setMiscReg(MISCREG_CCR, regs->readMiscReg(MISCREG_CCR) | 0x10); + regs->setIntReg(ReturnValueReg, return_value.value()); + } + } +}; + +#endif diff --git a/src/arch/sparc/types.hh b/src/arch/sparc/types.hh new file mode 100644 index 000000000..88fb24153 --- /dev/null +++ b/src/arch/sparc/types.hh @@ -0,0 +1,63 @@ +/* + * 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. + * + * Authors: Gabe Black + */ + +#ifndef __ARCH_SPARC_TYPES_HH__ +#define __ARCH_SPARC_TYPES_HH__ + +#include <inttypes.h> + +namespace SparcISA +{ + typedef uint32_t MachInst; + typedef uint64_t ExtMachInst; + + typedef uint64_t IntReg; + typedef uint64_t MiscReg; + typedef double FloatReg; + typedef uint64_t FloatRegBits; + typedef union + { + IntReg intReg; + FloatReg fpreg; + MiscReg ctrlreg; + } AnyReg; + + enum RegContextParam + { + CONTEXT_CWP, + CONTEXT_GLOBALS + }; + + typedef int RegContextVal; + + typedef uint8_t RegIndex; +} + +#endif |