diff options
author | Gabe Black <gblack@eecs.umich.edu> | 2009-04-06 10:19:36 -0700 |
---|---|---|
committer | Gabe Black <gblack@eecs.umich.edu> | 2009-04-06 10:19:36 -0700 |
commit | d080581db1f9ee4e1e6d07d2b01c13c67908a391 (patch) | |
tree | cc484b289fa5a30c4631f9faa1d8b456bffeebfc /src/arch/sparc | |
parent | 7a7c4c5fca83a8d47c7e71c9c080a882ebe204a9 (diff) | |
parent | 639cb0a42d953ee32bc7e96b0cdfa96cd40e9fc1 (diff) | |
download | gem5-d080581db1f9ee4e1e6d07d2b01c13c67908a391.tar.xz |
Merge ARM into the head. ARM will compile but may not actually work.
Diffstat (limited to 'src/arch/sparc')
42 files changed, 821 insertions, 785 deletions
diff --git a/src/arch/sparc/SConscript b/src/arch/sparc/SConscript index a86c00250..940cf2076 100644 --- a/src/arch/sparc/SConscript +++ b/src/arch/sparc/SConscript @@ -44,11 +44,14 @@ if env['TARGET_ISA'] == 'sparc': Source('utility.cc') SimObject('SparcTLB.py') - TraceFlag('Sparc') + TraceFlag('Sparc', "Generic SPARC ISA stuff") + TraceFlag('RegisterWindows', "Register window manipulation") if env['FULL_SYSTEM']: SimObject('SparcSystem.py') + SimObject('SparcInterrupts.py') + Source('interrupts.cc') Source('stacktrace.cc') Source('system.cc') Source('ua2005.cc') diff --git a/src/arch/sparc/SparcInterrupts.py b/src/arch/sparc/SparcInterrupts.py new file mode 100644 index 000000000..2cc964c2d --- /dev/null +++ b/src/arch/sparc/SparcInterrupts.py @@ -0,0 +1,33 @@ +# Copyright (c) 2008 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 + +from m5.SimObject import SimObject + +class SparcInterrupts(SimObject): + type = 'SparcInterrupts' + cxx_class = 'SparcISA::Interrupts' diff --git a/src/arch/sparc/SparcTLB.py b/src/arch/sparc/SparcTLB.py index 2d0257cd7..6758d612a 100644 --- a/src/arch/sparc/SparcTLB.py +++ b/src/arch/sparc/SparcTLB.py @@ -28,21 +28,20 @@ from m5.SimObject import SimObject from m5.params import * -class SparcTLB(SimObject): + +from BaseTLB import BaseTLB + +class SparcTLB(BaseTLB): type = 'SparcTLB' abstract = True size = Param.Int("TLB size") class SparcDTB(SparcTLB): type = 'SparcDTB' - cxx_namespace = 'SparcISA' - cxx_class = 'DTB' - + cxx_class = 'SparcISA::DTB' size = 64 class SparcITB(SparcTLB): type = 'SparcITB' - cxx_namespace = 'SparcISA' - cxx_class = 'ITB' - + cxx_class = 'SparcISA::ITB' size = 64 diff --git a/src/arch/sparc/faults.cc b/src/arch/sparc/faults.cc index e201cef95..9c189d164 100644 --- a/src/arch/sparc/faults.cc +++ b/src/arch/sparc/faults.cc @@ -546,7 +546,7 @@ void SparcFaultBase::invoke(ThreadContext * tc) doNormalFault(tc, trapType(), true); getHyperVector(tc, PC, NPC, 2); } else if (level == Hyperprivileged || - level == Privileged && trapType() >= 384) { + (level == Privileged && trapType() >= 384)) { doNormalFault(tc, trapType(), true); getHyperVector(tc, PC, NPC, trapType()); } else { diff --git a/src/arch/sparc/floatregfile.cc b/src/arch/sparc/floatregfile.cc index e1b5ea7c8..2d1af2218 100644 --- a/src/arch/sparc/floatregfile.cc +++ b/src/arch/sparc/floatregfile.cc @@ -41,20 +41,6 @@ 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() { memset(regSpace, 0, sizeof(regSpace)); @@ -75,7 +61,8 @@ FloatReg FloatRegFile::readReg(int floatReg, int width) result32 = htog(result32); memcpy(&fresult32, &result32, sizeof(result32)); result = fresult32; - DPRINTF(Sparc, "Read FP32 register %d = [%f]0x%x\n", floatReg, result, result32); + DPRINTF(FloatRegs, "Read FP32 register %d = [%f]0x%x\n", + floatReg, result, result32); break; case DoubleWidth: uint64_t result64; @@ -84,7 +71,8 @@ FloatReg FloatRegFile::readReg(int floatReg, int width) result64 = htog(result64); memcpy(&fresult64, &result64, sizeof(result64)); result = fresult64; - DPRINTF(Sparc, "Read FP64 register %d = [%f]0x%x\n", floatReg, result, result64); + DPRINTF(FloatRegs, "Read FP64 register %d = [%f]0x%x\n", + floatReg, result, result64); break; case QuadWidth: panic("Quad width FP not implemented."); @@ -107,13 +95,15 @@ FloatRegBits FloatRegFile::readRegBits(int floatReg, int width) uint32_t result32; memcpy(&result32, regSpace + 4 * floatReg, sizeof(result32)); result = htog(result32); - DPRINTF(Sparc, "Read FP32 bits register %d = 0x%x\n", floatReg, result); + DPRINTF(FloatRegs, "Read FP32 bits register %d = 0x%x\n", + floatReg, result); break; case DoubleWidth: uint64_t result64; memcpy(&result64, regSpace + 4 * floatReg, sizeof(result64)); result = htog(result64); - DPRINTF(Sparc, "Read FP64 bits register %d = 0x%x\n", floatReg, result); + DPRINTF(FloatRegs, "Read FP64 bits register %d = 0x%x\n", + floatReg, result); break; case QuadWidth: panic("Quad width FP not implemented."); @@ -141,14 +131,16 @@ Fault FloatRegFile::setReg(int floatReg, const FloatReg &val, int width) memcpy(&result32, &fresult32, sizeof(result32)); result32 = gtoh(result32); memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32)); - DPRINTF(Sparc, "Write FP64 register %d = 0x%x\n", floatReg, result32); + DPRINTF(FloatRegs, "Write FP64 register %d = 0x%x\n", + floatReg, result32); break; case DoubleWidth: fresult64 = val; memcpy(&result64, &fresult64, sizeof(result64)); result64 = gtoh(result64); memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64)); - DPRINTF(Sparc, "Write FP64 register %d = 0x%x\n", floatReg, result64); + DPRINTF(FloatRegs, "Write FP64 register %d = 0x%x\n", + floatReg, result64); break; case QuadWidth: panic("Quad width FP not implemented."); @@ -171,12 +163,14 @@ Fault FloatRegFile::setRegBits(int floatReg, const FloatRegBits &val, int width) case SingleWidth: result32 = gtoh((uint32_t)val); memcpy(regSpace + 4 * floatReg, &result32, sizeof(result32)); - DPRINTF(Sparc, "Write FP64 bits register %d = 0x%x\n", floatReg, result32); + DPRINTF(FloatRegs, "Write FP64 bits register %d = 0x%x\n", + floatReg, result32); break; case DoubleWidth: result64 = gtoh((uint64_t)val); memcpy(regSpace + 4 * floatReg, &result64, sizeof(result64)); - DPRINTF(Sparc, "Write FP64 bits register %d = 0x%x\n", floatReg, result64); + DPRINTF(FloatRegs, "Write FP64 bits register %d = 0x%x\n", + floatReg, result64); break; case QuadWidth: panic("Quad width FP not implemented."); diff --git a/src/arch/sparc/floatregfile.hh b/src/arch/sparc/floatregfile.hh index 72803a5e0..265e71b4a 100644 --- a/src/arch/sparc/floatregfile.hh +++ b/src/arch/sparc/floatregfile.hh @@ -42,8 +42,6 @@ class Checkpoint; namespace SparcISA { - std::string getFloatRegName(RegIndex); - const int NumFloatArchRegs = 64; const int NumFloatRegs = 64; diff --git a/src/arch/sparc/interrupts.cc b/src/arch/sparc/interrupts.cc new file mode 100644 index 000000000..96d61e559 --- /dev/null +++ b/src/arch/sparc/interrupts.cc @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2008 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 + */ + +#include "arch/sparc/interrupts.hh" + +SparcISA::Interrupts * +SparcInterruptsParams::create() +{ + return new SparcISA::Interrupts(this); +} diff --git a/src/arch/sparc/interrupts.hh b/src/arch/sparc/interrupts.hh index 4ad3385fb..ec930e2b0 100644 --- a/src/arch/sparc/interrupts.hh +++ b/src/arch/sparc/interrupts.hh @@ -35,25 +35,43 @@ #include "arch/sparc/faults.hh" #include "arch/sparc/isa_traits.hh" #include "cpu/thread_context.hh" +#include "params/SparcInterrupts.hh" +#include "sim/sim_object.hh" namespace SparcISA { -class Interrupts +class Interrupts : public SimObject { - private: + BaseCPU * cpu; uint64_t interrupts[NumInterruptTypes]; uint64_t intStatus; public: - Interrupts() + + void + setCPU(BaseCPU * _cpu) + { + cpu = _cpu; + } + + typedef SparcInterruptsParams Params; + + const Params * + params() const + { + return dynamic_cast<const Params *>(_params); + } + + Interrupts(Params * p) : SimObject(p), cpu(NULL) { - clear_all(); + clearAll(); } - int InterruptLevel(uint64_t softint) + int + InterruptLevel(uint64_t softint) { if (softint & 0x10000 || softint & 0x1) return 14; @@ -66,7 +84,8 @@ class Interrupts return 0; } - void post(int int_num, int index) + void + post(int int_num, int index) { DPRINTF(Interrupt, "Interrupt %d:%d posted\n", int_num, index); assert(int_num >= 0 && int_num < NumInterruptTypes); @@ -76,7 +95,8 @@ class Interrupts intStatus |= ULL(1) << int_num; } - void clear(int int_num, int index) + void + clear(int int_num, int index) { DPRINTF(Interrupt, "Interrupt %d:%d cleared\n", int_num, index); assert(int_num >= 0 && int_num < NumInterruptTypes); @@ -87,7 +107,8 @@ class Interrupts intStatus &= ~(ULL(1) << int_num); } - void clear_all() + void + clearAll() { for (int i = 0; i < NumInterruptTypes; ++i) { interrupts[i] = 0; @@ -95,12 +116,14 @@ class Interrupts intStatus = 0; } - bool check_interrupts(ThreadContext * tc) const + bool + checkInterrupts(ThreadContext *tc) const { return intStatus; } - Fault getInterrupt(ThreadContext * tc) + Fault + getInterrupt(ThreadContext *tc) { int hpstate = tc->readMiscRegNoEffect(MISCREG_HPSTATE); int pstate = tc->readMiscRegNoEffect(MISCREG_PSTATE); @@ -143,8 +166,8 @@ class Interrupts return new DevMondo; } if (interrupts[IT_SOFT_INT]) { - return new - InterruptLevelN(InterruptLevel(interrupts[IT_SOFT_INT])); + int level = InterruptLevel(interrupts[IT_SOFT_INT]); + return new InterruptLevelN(level); } if (interrupts[IT_RES_ERROR]) { @@ -155,24 +178,28 @@ class Interrupts return NoFault; } - void updateIntrInfo(ThreadContext * tc) + void + updateIntrInfo(ThreadContext *tc) { } - uint64_t get_vec(int int_num) + uint64_t + get_vec(int int_num) { assert(int_num >= 0 && int_num < NumInterruptTypes); return interrupts[int_num]; } - void serialize(std::ostream &os) + void + serialize(std::ostream &os) { SERIALIZE_ARRAY(interrupts,NumInterruptTypes); SERIALIZE_SCALAR(intStatus); } - void unserialize(Checkpoint *cp, const std::string §ion) + void + unserialize(Checkpoint *cp, const std::string §ion) { UNSERIALIZE_ARRAY(interrupts,NumInterruptTypes); UNSERIALIZE_SCALAR(intStatus); diff --git a/src/arch/sparc/intregfile.cc b/src/arch/sparc/intregfile.cc index 39a613a0d..54c30d1cc 100644 --- a/src/arch/sparc/intregfile.cc +++ b/src/arch/sparc/intregfile.cc @@ -41,138 +41,40 @@ using namespace std; class Checkpoint; -string SparcISA::getIntRegName(RegIndex index) -{ - static std::string intRegName[NumIntArchRegs] = - {"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(IntReg) * RegsPerFrame); - for(int x = 0; x < 2 * NWindows; x++) - memset(regSegments[x], 0, sizeof(IntReg) * RegsPerFrame); memset(regs, 0, sizeof(IntReg) * NumIntRegs); } IntRegFile::IntRegFile() { - offset[Globals] = 0; - regView[Globals] = regGlobals[0]; - setCWP(0); clear(); } IntReg IntRegFile::readReg(int intReg) { - DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, regs[intReg]); + DPRINTF(IntRegs, "Read register %d = 0x%x\n", intReg, regs[intReg]); return regs[intReg]; - /* XXX Currently not used. When used again regView/offset need to be - * serialized! - IntReg val; - if(intReg < NumIntArchRegs) - val = regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask]; - else if((intReg -= NumIntArchRegs) < NumMicroIntRegs) - val = microRegs[intReg]; - else - panic("Tried to read non-existant integer register %d, %d\n", - NumIntArchRegs + NumMicroIntRegs + intReg, intReg); - - DPRINTF(Sparc, "Read register %d = 0x%x\n", intReg, val); - return val; - */ } void IntRegFile::setReg(int intReg, const IntReg &val) { if(intReg) { - DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val); + DPRINTF(IntRegs, "Wrote register %d = 0x%x\n", intReg, val); regs[intReg] = val; } return; - /* XXX Currently not used. When used again regView/offset need to be - * serialized! - if(intReg) - { - DPRINTF(Sparc, "Wrote register %d = 0x%x\n", intReg, val); - if(intReg < NumIntArchRegs) - regView[intReg >> FrameOffsetBits][intReg & FrameOffsetMask] = val; - else if((intReg -= NumIntArchRegs) < NumMicroIntRegs) - microRegs[intReg] = val; - else - panic("Tried to set non-existant integer register\n"); - } */ -} - -//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; - if (index < 0) - panic("Index less than 0. cwp=%d nwin=%d\n", cwp, NWindows); - 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\n", gl); - - regView[Globals] = regGlobals[gl]; - offset[Globals] = RegGlobalOffset + gl * RegsPerFrame; - - if (regView[Globals] == regView[Inputs] || - regView[Globals] == regView[Locals] || - regView[Globals] == regView[Outputs] ) - panic("Two register arrays set to the same thing!\n"); } void IntRegFile::serialize(std::ostream &os) { SERIALIZE_ARRAY(regs, NumIntRegs); SERIALIZE_ARRAY(microRegs, NumMicroIntRegs); - - /* the below doesn't seem needed unless gabe makes regview work*/ - 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) { UNSERIALIZE_ARRAY(regs, NumIntRegs); UNSERIALIZE_ARRAY(microRegs, NumMicroIntRegs); - - /* the below doesn't seem needed unless gabe makes regview work*/ - 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 index 83ef1d17b..f669f6b0d 100644 --- a/src/arch/sparc/intregfile.hh +++ b/src/arch/sparc/intregfile.hh @@ -42,53 +42,17 @@ class Checkpoint; namespace SparcISA { - class RegFile; - - //This function translates integer register file indices into names - std::string getIntRegName(RegIndex); - const int NumIntArchRegs = 32; const int NumIntRegs = (MaxGL + 1) * 8 + NWindows * 16 + NumMicroIntRegs; class IntRegFile { - private: - friend class RegFile; protected: - //The number of bits needed to index into each 8 register frame - static const int FrameOffsetBits = 3; - //The number of bits to choose between the 4 sets of 8 registers - static const int FrameNumBits = 2; - - //The number of registers per "frame" (8) - static const int RegsPerFrame = 1 << FrameOffsetBits; - //A mask to get the frame number - static const uint64_t FrameNumMask = - (FrameNumBits == sizeof(int)) ? - (unsigned int)(-1) : - (1 << FrameNumBits) - 1; - static const uint64_t FrameOffsetMask = - (FrameOffsetBits == sizeof(int)) ? - (unsigned int)(-1) : - (1 << FrameOffsetBits) - 1; - - IntReg regGlobals[MaxGL+1][RegsPerFrame]; - IntReg regSegments[2 * NWindows][RegsPerFrame]; IntReg microRegs[NumMicroIntRegs]; IntReg regs[NumIntRegs]; - enum regFrame {Globals, Outputs, Locals, Inputs, NumFrames}; - - IntReg * regView[NumFrames]; - - static const int RegGlobalOffset = 0; - static const int FrameOffset = (MaxGL + 1) * RegsPerFrame; - int offset[NumFrames]; - public: - int flattenIndex(int reg); - void clear(); IntRegFile(); @@ -100,14 +64,6 @@ namespace SparcISA 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); }; } diff --git a/src/arch/sparc/isa/decoder.isa b/src/arch/sparc/isa/decoder.isa index c35b231ff..e34ca033f 100644 --- a/src/arch/sparc/isa/decoder.isa +++ b/src/arch/sparc/isa/decoder.isa @@ -1231,16 +1231,14 @@ decode OP default Unknown::unknown() 0x23: Load::lddf({{Frd.udw = Mem.udw;}}); 0x24: Store::stf({{Mem.uw = Frds.uw;}}); 0x25: decode RD { - 0x0: Store::stfsr({{fault = checkFpEnableFault(xc); - if (fault) - return fault; - Mem.uw = Fsr<31:0>; - Fsr = insertBits(Fsr,16,14,0);}}); - 0x1: Store::stxfsr({{fault = checkFpEnableFault(xc); - if (fault) - return fault; - Mem.udw = Fsr; - Fsr = insertBits(Fsr,16,14,0);}}); + 0x0: StoreFsr::stfsr({{fault = checkFpEnableFault(xc); + if (fault) + return fault; + Mem.uw = Fsr<31:0>;}}); + 0x1: StoreFsr::stxfsr({{fault = checkFpEnableFault(xc); + if (fault) + return fault; + Mem.udw = Fsr;}}); default: FailUnimpl::stfsrOther(); } 0x26: stqf({{fault = new FpDisabled;}}); diff --git a/src/arch/sparc/isa/formats/mem/basicmem.isa b/src/arch/sparc/isa/formats/mem/basicmem.isa index e3c043cf3..c7bb3e435 100644 --- a/src/arch/sparc/isa/formats/mem/basicmem.isa +++ b/src/arch/sparc/isa/formats/mem/basicmem.isa @@ -108,6 +108,16 @@ def format Store(code, *opt_flags) {{ StoreFuncs, '', name, Name, 0, opt_flags) }}; +def format StoreFsr(code, *opt_flags) {{ + code = filterDoubles(code) + (header_output, + decoder_output, + exec_output, + decode_block) = doMemFormat(code, + StoreFuncs, '', name, Name, 0, opt_flags, + 'Fsr = insertBits(Fsr,16,14,0);') +}}; + def format TwinLoad(code, *opt_flags) {{ (header_output, decoder_output, diff --git a/src/arch/sparc/isa/formats/mem/swap.isa b/src/arch/sparc/isa/formats/mem/swap.isa index 2ebe9aa15..046f89822 100644 --- a/src/arch/sparc/isa/formats/mem/swap.isa +++ b/src/arch/sparc/isa/formats/mem/swap.isa @@ -133,6 +133,7 @@ let {{ def format Swap(code, postacc_code, mem_flags, *opt_flags) {{ mem_flags = makeList(mem_flags) + mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] flags = string.join(mem_flags, '|') (header_output, @@ -144,6 +145,7 @@ def format Swap(code, postacc_code, mem_flags, *opt_flags) {{ def format SwapAlt(code, postacc_code, mem_flags, *opt_flags) {{ mem_flags = makeList(mem_flags) + mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] mem_flags.append("EXT_ASI") flags = string.join(mem_flags, '|') (header_output, @@ -175,6 +177,7 @@ let {{ def format CasAlt(code, postacc_code, mem_flags, *opt_flags) {{ mem_flags = makeList(mem_flags) + mem_flags = [ 'Request::%s' % flag for flag in mem_flags ] mem_flags.append("EXT_ASI") flags = string.join(mem_flags, '|') (header_output, diff --git a/src/arch/sparc/isa/formats/mem/util.isa b/src/arch/sparc/isa/formats/mem/util.isa index 38cde9a50..31efb9cf6 100644 --- a/src/arch/sparc/isa/formats/mem/util.isa +++ b/src/arch/sparc/isa/formats/mem/util.isa @@ -264,11 +264,6 @@ def template StoreInitiateAcc {{ fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem, EA, %(asi_val)s, 0); } - if(fault == NoFault) - { - //Write the resulting state to the execution context - %(op_wb)s; - } return fault; } }}; @@ -277,6 +272,15 @@ def template StoreCompleteAcc {{ Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const { + Fault fault = NoFault; + %(op_decl)s; + + %(op_rd)s; + %(postacc_code)s; + if (fault == NoFault) + { + %(op_wb)s; + } return NoFault; } }}; @@ -314,10 +318,11 @@ let {{ # are split into ones that are available in priv and hpriv, and # those that are only available in hpriv AlternateASIPrivFaultCheck = ''' - if(!bits(Pstate,2,2) && !bits(Hpstate,2,2) && !AsiIsUnPriv((ASI)EXT_ASI) || - !bits(Hpstate,2,2) && AsiIsHPriv((ASI)EXT_ASI)) - fault = new PrivilegedAction; - else if(AsiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2)) + if ((!bits(Pstate,2,2) && !bits(Hpstate,2,2) && + !AsiIsUnPriv((ASI)EXT_ASI)) || + (!bits(Hpstate,2,2) && AsiIsHPriv((ASI)EXT_ASI))) + fault = new PrivilegedAction; + else if (AsiIsAsIfUser((ASI)EXT_ASI) && !bits(Pstate,2,2)) fault = new PrivilegedAction; ''' diff --git a/src/arch/sparc/isa_traits.hh b/src/arch/sparc/isa_traits.hh index 133817eb5..501f2f990 100644 --- a/src/arch/sparc/isa_traits.hh +++ b/src/arch/sparc/isa_traits.hh @@ -66,18 +66,14 @@ namespace SparcISA }; // semantically meaningful register indices - const int ZeroReg = 0; // architecturally meaningful + const int ZeroReg = 0; // architecturally meaningful // the rest of these depend on the ABI - const int StackPointerReg = 14; const int ReturnAddressReg = 31; // post call, precall is 15 - const int ReturnValueReg = 8; // Post return, 24 is pre-return. + const int StackPointerReg = 14; const int FramePointerReg = 30; - const int ArgumentReg[] = {8, 9, 10, 11, 12, 13}; - const int NumArgumentRegs = sizeof(ArgumentReg) / sizeof(const int); - // Some OS syscall use a second register (o1) to return a second value - const int SyscallPseudoReturnReg = ArgumentReg[1]; + const int SyscallPseudoReturnReg = 9; //8K. This value is implmentation specific; and should probably //be somewhere else. diff --git a/src/arch/sparc/linux/linux.cc b/src/arch/sparc/linux/linux.cc index 1211d5f65..102e5af3b 100644 --- a/src/arch/sparc/linux/linux.cc +++ b/src/arch/sparc/linux/linux.cc @@ -34,34 +34,34 @@ // open(2) flags translation table OpenFlagTransTable SparcLinux::openFlagTable[] = { #ifdef _MSC_VER - { SparcLinux::TGT_O_RDONLY, _O_RDONLY }, - { SparcLinux::TGT_O_WRONLY, _O_WRONLY }, - { SparcLinux::TGT_O_RDWR, _O_RDWR }, - { SparcLinux::TGT_O_APPEND, _O_APPEND }, - { SparcLinux::TGT_O_CREAT, _O_CREAT }, - { SparcLinux::TGT_O_TRUNC, _O_TRUNC }, - { SparcLinux::TGT_O_EXCL, _O_EXCL }, + { SparcLinux::TGT_O_RDONLY, _O_RDONLY }, + { SparcLinux::TGT_O_WRONLY, _O_WRONLY }, + { SparcLinux::TGT_O_RDWR, _O_RDWR }, + { SparcLinux::TGT_O_APPEND, _O_APPEND }, + { SparcLinux::TGT_O_CREAT, _O_CREAT }, + { SparcLinux::TGT_O_TRUNC, _O_TRUNC }, + { SparcLinux::TGT_O_EXCL, _O_EXCL }, #ifdef _O_NONBLOCK - { SparcLinux::TGT_O_NONBLOCK, _O_NONBLOCK }, + { SparcLinux::TGT_O_NONBLOCK, _O_NONBLOCK }, #endif #ifdef _O_NOCTTY - { SparcLinux::TGT_O_NOCTTY, _O_NOCTTY }, + { SparcLinux::TGT_O_NOCTTY, _O_NOCTTY }, #endif #ifdef _O_SYNC - { SparcLinux::TGT_O_SYNC, _O_SYNC }, + { SparcLinux::TGT_O_SYNC, _O_SYNC }, #endif #else /* !_MSC_VER */ - { SparcLinux::TGT_O_RDONLY, O_RDONLY }, - { SparcLinux::TGT_O_WRONLY, O_WRONLY }, - { SparcLinux::TGT_O_RDWR, O_RDWR }, - { SparcLinux::TGT_O_APPEND, O_APPEND }, - { SparcLinux::TGT_O_CREAT, O_CREAT }, - { SparcLinux::TGT_O_TRUNC, O_TRUNC }, - { SparcLinux::TGT_O_EXCL, O_EXCL }, - { SparcLinux::TGT_O_NONBLOCK, O_NONBLOCK }, - { SparcLinux::TGT_O_NOCTTY, O_NOCTTY }, + { SparcLinux::TGT_O_RDONLY, O_RDONLY }, + { SparcLinux::TGT_O_WRONLY, O_WRONLY }, + { SparcLinux::TGT_O_RDWR, O_RDWR }, + { SparcLinux::TGT_O_APPEND, O_APPEND }, + { SparcLinux::TGT_O_CREAT, O_CREAT }, + { SparcLinux::TGT_O_TRUNC, O_TRUNC }, + { SparcLinux::TGT_O_EXCL, O_EXCL }, + { SparcLinux::TGT_O_NONBLOCK, O_NONBLOCK }, + { SparcLinux::TGT_O_NOCTTY, O_NOCTTY }, #ifdef O_SYNC - { SparcLinux::TGT_O_SYNC, O_SYNC }, + { SparcLinux::TGT_O_SYNC, O_SYNC }, #endif #endif /* _MSC_VER */ }; diff --git a/src/arch/sparc/linux/linux.hh b/src/arch/sparc/linux/linux.hh index f396eb5cd..b1dc691ce 100644 --- a/src/arch/sparc/linux/linux.hh +++ b/src/arch/sparc/linux/linux.hh @@ -58,21 +58,21 @@ class SparcLinux : public Linux static OpenFlagTransTable openFlagTable[]; - static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY - static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY - static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR - static const int TGT_O_NONBLOCK = 0x00004000; //!< O_NONBLOCK - static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND - static const int TGT_O_CREAT = 0x00000200; //!< O_CREAT - static const int TGT_O_TRUNC = 0x00000400; //!< O_TRUNC - static const int TGT_O_EXCL = 0x00000800; //!< O_EXCL - static const int TGT_O_NOCTTY = 0x00008000; //!< O_NOCTTY - static const int TGT_O_SYNC = 0x00002000; //!< O_SYNC -// static const int TGT_O_DRD = 0x00010000; //!< O_DRD -// static const int TGT_O_DIRECTIO = 0x00020000; //!< O_DIRECTIO -// static const int TGT_O_CACHE = 0x00002000; //!< O_CACHE -// static const int TGT_O_DSYNC = 0x00008000; //!< O_DSYNC -// static const int TGT_O_RSYNC = 0x00040000; //!< O_RSYNC + static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY + static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY + static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR + static const int TGT_O_NONBLOCK = 0x00004000; //!< O_NONBLOCK + static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND + static const int TGT_O_CREAT = 0x00000200; //!< O_CREAT + static const int TGT_O_TRUNC = 0x00000400; //!< O_TRUNC + static const int TGT_O_EXCL = 0x00000800; //!< O_EXCL + static const int TGT_O_NOCTTY = 0x00008000; //!< O_NOCTTY + static const int TGT_O_SYNC = 0x00002000; //!< O_SYNC +// static const int TGT_O_DRD = 0x00010000; //!< O_DRD +// static const int TGT_O_DIRECTIO = 0x00020000; //!< O_DIRECTIO +// static const int TGT_O_CACHE = 0x00002000; //!< O_CACHE +// static const int TGT_O_DSYNC = 0x00008000; //!< O_DSYNC +// static const int TGT_O_RSYNC = 0x00040000; //!< O_RSYNC static const int NUM_OPEN_FLAGS; diff --git a/src/arch/sparc/linux/process.cc b/src/arch/sparc/linux/process.cc index f4ec28c00..2078c1dce 100644 --- a/src/arch/sparc/linux/process.cc +++ b/src/arch/sparc/linux/process.cc @@ -47,7 +47,7 @@ using namespace SparcISA; SyscallDesc* SparcLinuxProcess::getDesc(int callnum) { - if (callnum < 0 || callnum > Num_Syscall_Descs) + if (callnum < 0 || callnum >= Num_Syscall_Descs) return NULL; return &syscallDescs[callnum]; } @@ -55,7 +55,7 @@ SparcLinuxProcess::getDesc(int callnum) SyscallDesc* SparcLinuxProcess::getDesc32(int callnum) { - if (callnum < 0 || callnum > Num_Syscall32_Descs) + if (callnum < 0 || callnum >= Num_Syscall32_Descs) return NULL; return &syscall32Descs[callnum]; } diff --git a/src/arch/sparc/linux/process.hh b/src/arch/sparc/linux/process.hh index 06eee9235..a76b4b3b2 100644 --- a/src/arch/sparc/linux/process.hh +++ b/src/arch/sparc/linux/process.hh @@ -32,7 +32,6 @@ #define __SPARC_LINUX_PROCESS_HH__ #include "arch/sparc/linux/linux.hh" -#include "arch/sparc/syscallreturn.hh" #include "arch/sparc/process.hh" #include "sim/process.hh" diff --git a/src/arch/sparc/linux/syscalls.cc b/src/arch/sparc/linux/syscalls.cc index 03c8bafe2..8496fca13 100644 --- a/src/arch/sparc/linux/syscalls.cc +++ b/src/arch/sparc/linux/syscalls.cc @@ -29,7 +29,6 @@ */ #include "arch/sparc/linux/process.hh" -#include "arch/sparc/syscallreturn.hh" #include "sim/syscall_emul.hh" class LiveProcess; @@ -42,7 +41,7 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg<Linux::utsname> name(tc->getSyscallArg(0)); + TypedBufferArg<Linux::utsname> name(process->getSyscallArg(tc, 0)); strcpy(name->sysname, "Linux"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -60,9 +59,9 @@ SyscallReturn getresuidFunc(SyscallDesc *desc, int num, LiveProcess *p, ThreadContext *tc) { const IntReg id = htog(100); - Addr ruid = tc->getSyscallArg(0); - Addr euid = tc->getSyscallArg(1); - Addr suid = tc->getSyscallArg(2); + Addr ruid = p->getSyscallArg(tc, 0); + Addr euid = p->getSyscallArg(tc, 1); + Addr suid = p->getSyscallArg(tc, 2); //Handle the EFAULT case //Set the ruid if(ruid) @@ -106,7 +105,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = { /* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", unimplementedFunc), /* 16 */ SyscallDesc("lchown", unimplementedFunc), //32 bit - /* 17 */ SyscallDesc("brk", obreakFunc), + /* 17 */ SyscallDesc("brk", brkFunc), /* 18 */ SyscallDesc("perfctr", unimplementedFunc), //32 bit /* 19 */ SyscallDesc("lseek", lseekFunc), //32 bit /* 20 */ SyscallDesc("getpid", getpidFunc), @@ -147,7 +146,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = { /* 55 */ SyscallDesc("reboot", unimplementedFunc), //32 bit /* 56 */ SyscallDesc("mmap2", unimplementedFunc), //32 bit /* 57 */ SyscallDesc("symlink", unimplementedFunc), - /* 58 */ SyscallDesc("readlink", unimplementedFunc), //32 bit + /* 58 */ SyscallDesc("readlink", readlinkFunc), //32 bit /* 59 */ SyscallDesc("execve", unimplementedFunc), //32 bit /* 60 */ SyscallDesc("umask", unimplementedFunc), //32 bit /* 61 */ SyscallDesc("chroot", unimplementedFunc), @@ -208,7 +207,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = { /* 116 */ SyscallDesc("gettimeofday", unimplementedFunc), //32 bit /* 117 */ SyscallDesc("getrusage", unimplementedFunc), //32 bit /* 118 */ SyscallDesc("getsockopt", unimplementedFunc), - /* 119 */ SyscallDesc("getcwd", unimplementedFunc), + /* 119 */ SyscallDesc("getcwd", getcwdFunc), /* 120 */ SyscallDesc("readv", unimplementedFunc), /* 121 */ SyscallDesc("writev", unimplementedFunc), /* 122 */ SyscallDesc("settimeofday", unimplementedFunc), //32 bit @@ -225,7 +224,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = { /* 133 */ SyscallDesc("sendto", unimplementedFunc), /* 134 */ SyscallDesc("shutdown", unimplementedFunc), /* 135 */ SyscallDesc("socketpair", unimplementedFunc), - /* 136 */ SyscallDesc("mkdir", unimplementedFunc), //32 bit + /* 136 */ SyscallDesc("mkdir", mkdirFunc), //32 bit /* 137 */ SyscallDesc("rmdir", unimplementedFunc), /* 138 */ SyscallDesc("utimes", unimplementedFunc), //32 bit /* 139 */ SyscallDesc("stat64", unimplementedFunc), @@ -339,7 +338,7 @@ SyscallDesc SparcLinuxProcess::syscall32Descs[] = { /* 247 */ SyscallDesc("sched_get_priority_min", unimplementedFunc), //32 bit /* 248 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc), //32 bit /* 249 */ SyscallDesc("nanosleep", unimplementedFunc), - /* 250 */ SyscallDesc("mremap", unimplementedFunc), //32 bit + /* 250 */ SyscallDesc("mremap", mremapFunc<Sparc32Linux>), //32 bit /* 251 */ SyscallDesc("_sysctl", unimplementedFunc), //32 bit /* 252 */ SyscallDesc("getsid", unimplementedFunc), //32 bit /* 253 */ SyscallDesc("fdatasync", unimplementedFunc), @@ -409,7 +408,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = { /* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", chmodFunc<Linux>), /* 16 */ SyscallDesc("lchown", unimplementedFunc), - /* 17 */ SyscallDesc("brk", obreakFunc), + /* 17 */ SyscallDesc("brk", brkFunc), /* 18 */ SyscallDesc("perfctr", unimplementedFunc), /* 19 */ SyscallDesc("lseek", lseekFunc), /* 20 */ SyscallDesc("getpid", getpidFunc), @@ -450,7 +449,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = { /* 55 */ SyscallDesc("reboot", unimplementedFunc), /* 56 */ SyscallDesc("mmap2", unimplementedFunc), /* 57 */ SyscallDesc("symlink", unimplementedFunc), - /* 58 */ SyscallDesc("readlink", unimplementedFunc), + /* 58 */ SyscallDesc("readlink", readlinkFunc), /* 59 */ SyscallDesc("execve", unimplementedFunc), /* 60 */ SyscallDesc("umask", unimplementedFunc), /* 61 */ SyscallDesc("chroot", unimplementedFunc), @@ -528,7 +527,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = { /* 133 */ SyscallDesc("sendto", unimplementedFunc), /* 134 */ SyscallDesc("shutdown", unimplementedFunc), /* 135 */ SyscallDesc("socketpair", unimplementedFunc), - /* 136 */ SyscallDesc("mkdir", unimplementedFunc), + /* 136 */ SyscallDesc("mkdir", mkdirFunc), /* 137 */ SyscallDesc("rmdir", unimplementedFunc), /* 138 */ SyscallDesc("utimes", unimplementedFunc), /* 139 */ SyscallDesc("stat64", unimplementedFunc), @@ -642,7 +641,7 @@ SyscallDesc SparcLinuxProcess::syscallDescs[] = { /* 247 */ SyscallDesc("sched_get_priority_min", unimplementedFunc), /* 248 */ SyscallDesc("sched_rr_get_interval", unimplementedFunc), /* 249 */ SyscallDesc("nanosleep", unimplementedFunc), - /* 250 */ SyscallDesc("mremap", unimplementedFunc), + /* 250 */ SyscallDesc("mremap", mremapFunc<SparcLinux>), /* 251 */ SyscallDesc("_sysctl", unimplementedFunc), /* 252 */ SyscallDesc("getsid", unimplementedFunc), /* 253 */ SyscallDesc("fdatasync", unimplementedFunc), diff --git a/src/arch/sparc/syscallreturn.hh b/src/arch/sparc/microcode_rom.hh index cf13fc3e8..e46000dcc 100644 --- a/src/arch/sparc/syscallreturn.hh +++ b/src/arch/sparc/microcode_rom.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2005 The Regents of The University of Michigan + * Copyright (c) 2008 The Regents of The University of Michigan * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,37 +28,14 @@ * Authors: Gabe Black */ -#ifndef __ARCH_SPARC_SYSCALLRETURN_HH__ -#define __ARCH_SPARC_SYSCALLRETURN_HH__ +#ifndef __ARCH_SPARC_MICROCODE_ROM_HH__ +#define __ARCH_SPARC_MICROCODE_ROM_HH__ -#include <inttypes.h> - -#include "sim/syscallreturn.hh" -#include "arch/sparc/regfile.hh" -#include "cpu/thread_context.hh" +#include "sim/microcode_rom.hh" namespace SparcISA { - static inline void setSyscallReturn(SyscallReturn return_value, - ThreadContext * tc) - { - // 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 - tc->setIntReg(NumIntArchRegs + 2, - tc->readIntReg(NumIntArchRegs + 2) & 0xEE); - //tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) & 0xEE); - tc->setIntReg(ReturnValueReg, return_value.value()); - } else { - // got an error, set XCC.C - tc->setIntReg(NumIntArchRegs + 2, - tc->readIntReg(NumIntArchRegs + 2) | 0x11); - //tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) | 0x11); - tc->setIntReg(ReturnValueReg, -return_value.value()); - } - } -}; + using ::MicrocodeRom; +} -#endif +#endif // __ARCH_SPARC_MICROCODE_ROM_HH__ diff --git a/src/arch/sparc/miscregfile.cc b/src/arch/sparc/miscregfile.cc index 7b9c73433..38eba3862 100644 --- a/src/arch/sparc/miscregfile.cc +++ b/src/arch/sparc/miscregfile.cc @@ -42,27 +42,6 @@ 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", "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", "prictx", "secctx", "partId", "lsuCtrlReg", - "scratch0", "scratch1", "scratch2", "scratch3", "scratch4", - "scratch5", "scratch6", "scratch7", "cpuMondoHead", "cpuMondoTail", - "devMondoHead", "devMondoTail", "resErrorHead", "resErrorTail", - "nresErrorHead", "nresErrorTail", "TlbData" }; - - return miscRegName[index]; -} - enum RegMask { PSTATE_MASK = (((1 << 4) - 1) << 1) | (((1 << 4) - 1) << 6) | (1 << 12) @@ -227,7 +206,7 @@ MiscReg MiscRegFile::readRegNoEffect(int miscReg) /** Floating Point Status Register */ case MISCREG_FSR: - DPRINTF(Sparc, "FSR read as: %#x\n", fsr); + DPRINTF(MiscRegs, "FSR read as: %#x\n", fsr); return fsr; case MISCREG_MMU_P_CONTEXT: @@ -322,12 +301,13 @@ MiscReg MiscRegFile::readReg(int miscReg, ThreadContext * tc) return readFSReg(miscReg, tc); #else case MISCREG_HPSTATE: - //HPSTATE is special because because sometimes in privilege checks for instructions - //it will read HPSTATE to make sure the priv. level is ok - //So, we'll just have to tell it it isn't, instead of panicing. + //HPSTATE is special because because sometimes in privilege + //checks for instructions it will read HPSTATE to make sure + //the priv. level is ok So, we'll just have to tell it it + //isn't, instead of panicing. return 0; - panic("Accessing Fullsystem register %s in SE mode\n",getMiscRegName(miscReg)); + panic("Accessing Fullsystem register %d in SE mode\n", miscReg); #endif } @@ -444,7 +424,7 @@ void MiscRegFile::setRegNoEffect(int miscReg, const MiscReg &val) /** Floating Point Status Register */ case MISCREG_FSR: fsr = val; - DPRINTF(Sparc, "FSR written with: %#x\n", fsr); + DPRINTF(MiscRegs, "FSR written with: %#x\n", fsr); break; case MISCREG_MMU_P_CONTEXT: @@ -540,20 +520,17 @@ void MiscRegFile::setReg(int miscReg, tl = val; #if FULL_SYSTEM if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv)) - tc->getCpuPtr()->post_interrupt(IT_TRAP_LEVEL_ZERO,0); + tc->getCpuPtr()->postInterrupt(IT_TRAP_LEVEL_ZERO, 0); else - tc->getCpuPtr()->clear_interrupt(IT_TRAP_LEVEL_ZERO,0); + tc->getCpuPtr()->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0); #endif return; case MISCREG_CWP: new_val = val >= NWindows ? NWindows - 1 : val; if (val >= NWindows) new_val = NWindows - 1; - - tc->changeRegFileContext(CONTEXT_CWP, new_val); break; case MISCREG_GL: - tc->changeRegFileContext(CONTEXT_GLOBALS, val); break; case MISCREG_PIL: case MISCREG_SOFTINT: @@ -584,13 +561,15 @@ void MiscRegFile::setReg(int miscReg, //HPSTATE is special because normal trap processing saves HPSTATE when //it goes into a trap, and restores it when it returns. return; - panic("Accessing Fullsystem register %s to %#x in SE mode\n", getMiscRegName(miscReg), val); + panic("Accessing Fullsystem register %d to %#x in SE mode\n", + miscReg, val); #endif } setRegNoEffect(miscReg, new_val); } -void MiscRegFile::serialize(std::ostream & os) +void +MiscRegFile::serialize(EventManager *em, std::ostream &os) { SERIALIZE_SCALAR(asi); SERIALIZE_SCALAR(tick); @@ -667,7 +646,9 @@ void MiscRegFile::serialize(std::ostream & os) #endif } -void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section) +void +MiscRegFile::unserialize(EventManager *em, Checkpoint *cp, + const string §ion) { UNSERIALIZE_SCALAR(asi); UNSERIALIZE_SCALAR(tick); @@ -726,15 +707,15 @@ void MiscRegFile::unserialize(Checkpoint * cp, const std::string & section) if (tick_cmp) { tickCompare = new TickCompareEvent(this, tc); - tickCompare->schedule(tick_cmp); + em->schedule(tickCompare, tick_cmp); } if (stick_cmp) { sTickCompare = new STickCompareEvent(this, tc); - sTickCompare->schedule(stick_cmp); + em->schedule(sTickCompare, stick_cmp); } if (hstick_cmp) { hSTickCompare = new HSTickCompareEvent(this, tc); - hSTickCompare->schedule(hstick_cmp); + em->schedule(hSTickCompare, hstick_cmp); } } } diff --git a/src/arch/sparc/miscregfile.hh b/src/arch/sparc/miscregfile.hh index 3e17779a9..9eff7fcac 100644 --- a/src/arch/sparc/miscregfile.hh +++ b/src/arch/sparc/miscregfile.hh @@ -43,9 +43,6 @@ class Checkpoint; namespace SparcISA { - //These functions map register indices to names - std::string getMiscRegName(RegIndex); - enum MiscRegIndex { /** Ancillary State Registers */ @@ -171,50 +168,50 @@ namespace SparcISA private: /* ASR Registers */ - //uint64_t y; // Y (used in obsolete multiplication) - //uint8_t ccr; // Condition Code Register - uint8_t asi; // Address Space Identifier - uint64_t tick; // Hardware clock-tick counter - uint8_t fprs; // Floating-Point Register State - uint64_t gsr; // General Status Register + //uint64_t y; // Y (used in obsolete multiplication) + //uint8_t ccr; // Condition Code Register + uint8_t asi; // Address Space Identifier + uint64_t tick; // Hardware clock-tick counter + uint8_t fprs; // Floating-Point Register State + uint64_t gsr; // General Status Register uint64_t softint; - uint64_t tick_cmpr; // Hardware tick compare registers - uint64_t stick; // Hardware clock-tick counter - uint64_t stick_cmpr; // Hardware tick compare registers + uint64_t tick_cmpr; // Hardware tick compare registers + uint64_t stick; // Hardware clock-tick counter + uint64_t stick_cmpr; // Hardware tick compare registers /* Privileged Registers */ - uint64_t tpc[MaxTL]; // Trap Program Counter (value from + uint64_t tpc[MaxTL]; // Trap Program Counter (value from // previous trap level) - uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from + uint64_t tnpc[MaxTL]; // Trap Next Program Counter (value from // previous trap level) - uint64_t tstate[MaxTL]; // Trap State - uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured + uint64_t tstate[MaxTL]; // Trap State + uint16_t tt[MaxTL]; // Trap Type (Type of trap which occured // on the previous level) - uint64_t tba; // Trap Base Address - - uint16_t pstate; // Process State Register - 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 - //uint8_t wstate; // Window State + uint64_t tba; // Trap Base Address + + uint16_t pstate; // Process State Register + 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 + //uint8_t wstate; // Window State uint8_t gl; // Global level register /** Hyperprivileged Registers */ - uint64_t hpstate; // Hyperprivileged State Register + uint64_t hpstate; // Hyperprivileged State Register uint64_t htstate[MaxTL];// Hyperprivileged Trap State Register uint64_t hintp; - uint64_t htba; // Hyperprivileged Trap Base Address register - uint64_t hstick_cmpr; // Hardware tick compare registers + uint64_t htba; // Hyperprivileged Trap Base Address register + uint64_t hstick_cmpr; // Hardware tick compare registers uint64_t strandStatusReg;// Per strand status register /** Floating point misc registers. */ - uint64_t fsr; // Floating-Point State Register + uint64_t fsr; // Floating-Point State Register /** MMU Internal Registers */ uint16_t priContext; @@ -288,9 +285,10 @@ namespace SparcISA return priContext | (uint32_t)partId << 13; } - void serialize(std::ostream & os); + void serialize(EventManager *em, std::ostream & os); - void unserialize(Checkpoint * cp, const std::string & section); + void unserialize(EventManager *em, Checkpoint *cp, + const std::string & section); void copyMiscRegs(ThreadContext * tc); diff --git a/src/arch/sparc/pagetable.hh b/src/arch/sparc/pagetable.hh index bf7f34b60..cbdabe4c3 100644 --- a/src/arch/sparc/pagetable.hh +++ b/src/arch/sparc/pagetable.hh @@ -31,6 +31,8 @@ #ifndef __ARCH_SPARC_PAGETABLE_HH__ #define __ARCH_SPARC_PAGETABLE_HH__ +#include <cassert> + #include "arch/sparc/isa_traits.hh" #include "base/bitfield.hh" #include "base/misc.hh" @@ -38,8 +40,8 @@ class Checkpoint; -namespace SparcISA -{ +namespace SparcISA { + struct VAddr { VAddr(Addr a) { panic("not implemented yet."); } @@ -54,8 +56,15 @@ class TteTag public: TteTag() : entry(0), populated(false) {} TteTag(uint64_t e) : entry(e), populated(true) {} - const TteTag &operator=(uint64_t e) { populated = true; - entry = e; return *this; } + + const TteTag & + operator=(uint64_t e) + { + populated = true; + entry = e; + return *this; + } + bool valid() const {assert(populated); return !bits(entry,62,62); } Addr va() const {assert(populated); return bits(entry,41,0); } }; @@ -76,13 +85,13 @@ class PageTableEntry uint64_t entry4u; bool populated; - public: - PageTableEntry() : entry(0), type(invalid), populated(false) {} + PageTableEntry() + : entry(0), type(invalid), populated(false) + {} PageTableEntry(uint64_t e, EntryType t = sun4u) : entry(e), type(t), populated(true) - { populate(entry, type); } @@ -113,49 +122,74 @@ class PageTableEntry } } - void clear() + void + clear() { populated = false; } static int pageSizes[6]; - uint64_t operator()() const { assert(populated); return entry4u; } - const PageTableEntry &operator=(uint64_t e) { populated = true; - entry4u = e; return *this; } - - const PageTableEntry &operator=(const PageTableEntry &e) - { populated = true; entry4u = e.entry4u; type = e.type; return *this; } - - bool valid() const { return bits(entry4u,63,63) && populated; } - uint8_t _size() const { assert(populated); - return bits(entry4u, 62,61) | - bits(entry4u, 48,48) << 2; } - Addr size() const { assert(_size() < 6); return pageSizes[_size()]; } - Addr sizeMask() const { assert(_size() < 6); return pageSizes[_size()]-1;} - bool ie() const { return bits(entry4u, 59,59); } - Addr pfn() const { assert(populated); return bits(entry4u,39,13); } - Addr paddr() const { assert(populated); return mbits(entry4u, 39,13);} - bool locked() const { assert(populated); return bits(entry4u,6,6); } - bool cv() const { assert(populated); return bits(entry4u,4,4); } - bool cp() const { assert(populated); return bits(entry4u,5,5); } - bool priv() const { assert(populated); return bits(entry4u,2,2); } - bool writable() const { assert(populated); return bits(entry4u,1,1); } - bool nofault() const { assert(populated); return bits(entry4u,60,60); } - bool sideffect() const { assert(populated); return bits(entry4u,3,3); } - Addr paddrMask() const { assert(populated); - return mbits(entry4u, 39,13) & ~sizeMask(); } + const PageTableEntry & + operator=(uint64_t e) + { + populated = true; + entry4u = e; + return *this; + } + + const PageTableEntry & + operator=(const PageTableEntry &e) + { + populated = true; + entry4u = e.entry4u; + type = e.type; + return *this; + } + + bool valid() const { return bits(entry4u,63,63) && populated; } + + uint8_t + _size() const + { + assert(populated); + return bits(entry4u, 62,61) | bits(entry4u, 48,48) << 2; + } + + Addr size() const { assert(_size() < 6); return pageSizes[_size()]; } + Addr sizeMask() const { return size() - 1; } + bool ie() const { return bits(entry4u, 59,59); } + Addr pfn() const { assert(populated); return bits(entry4u,39,13); } + Addr paddr() const { assert(populated); return mbits(entry4u, 39,13);} + bool locked() const { assert(populated); return bits(entry4u,6,6); } + bool cv() const { assert(populated); return bits(entry4u,4,4); } + bool cp() const { assert(populated); return bits(entry4u,5,5); } + bool priv() const { assert(populated); return bits(entry4u,2,2); } + bool writable() const { assert(populated); return bits(entry4u,1,1); } + bool nofault() const { assert(populated); return bits(entry4u,60,60); } + bool sideffect() const { assert(populated); return bits(entry4u,3,3); } + Addr paddrMask() const { assert(populated); return paddr() & ~sizeMask(); } + + Addr + translate(Addr vaddr) const + { + assert(populated); + Addr mask = sizeMask(); + return (paddr() & ~mask) | (vaddr & mask); + } }; -struct TlbRange { +struct TlbRange +{ Addr va; Addr size; int contextId; int partitionId; bool real; - inline bool operator<(const TlbRange &r2) const + inline bool + operator<(const TlbRange &r2) const { if (real && !r2.real) return true; @@ -178,7 +212,9 @@ struct TlbRange { return true; return false; } - inline bool operator==(const TlbRange &r2) const + + inline bool + operator==(const TlbRange &r2) const { return va == r2.va && size == r2.size && @@ -189,7 +225,11 @@ struct TlbRange { }; -struct TlbEntry { +struct TlbEntry +{ + TlbEntry() + {} + TlbEntry(Addr asn, Addr vaddr, Addr paddr) { uint64_t entry = 0; @@ -215,8 +255,7 @@ struct TlbEntry { valid = true; } - TlbEntry() - {} + TlbRange range; PageTableEntry pte; bool used; @@ -227,13 +266,17 @@ struct TlbEntry { return pte.paddr(); } + void + updateVaddr(Addr new_vaddr) + { + range.va = new_vaddr; + } + void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); - }; - -}; // namespace SparcISA +} // namespace SparcISA #endif // __ARCH_SPARC_PAGE_TABLE_HH__ diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc index 6e490e05e..b2b539816 100644 --- a/src/arch/sparc/process.cc +++ b/src/arch/sparc/process.cc @@ -46,6 +46,9 @@ using namespace std; using namespace SparcISA; +static const int FirstArgumentReg = 8; +static const int ReturnValueReg = 8; + SparcLiveProcess::SparcLiveProcess(LiveProcessParams * params, ObjectFile *objFile, Addr _StackBias) @@ -112,44 +115,45 @@ SparcLiveProcess::startup() { Process::startup(); + ThreadContext *tc = system->getThreadContext(contextIds[0]); //From the SPARC ABI //Setup default FP state - threadContexts[0]->setMiscRegNoEffect(MISCREG_FSR, 0); + tc->setMiscRegNoEffect(MISCREG_FSR, 0); - threadContexts[0]->setMiscRegNoEffect(MISCREG_TICK, 0); + tc->setMiscRegNoEffect(MISCREG_TICK, 0); /* * Register window management registers */ //No windows contain info from other programs - //threadContexts[0]->setMiscRegNoEffect(MISCREG_OTHERWIN, 0); - threadContexts[0]->setIntReg(NumIntArchRegs + 6, 0); + //tc->setMiscRegNoEffect(MISCREG_OTHERWIN, 0); + tc->setIntReg(NumIntArchRegs + 6, 0); //There are no windows to pop - //threadContexts[0]->setMiscRegNoEffect(MISCREG_CANRESTORE, 0); - threadContexts[0]->setIntReg(NumIntArchRegs + 4, 0); + //tc->setMiscRegNoEffect(MISCREG_CANRESTORE, 0); + tc->setIntReg(NumIntArchRegs + 4, 0); //All windows are available to save into - //threadContexts[0]->setMiscRegNoEffect(MISCREG_CANSAVE, NWindows - 2); - threadContexts[0]->setIntReg(NumIntArchRegs + 3, NWindows - 2); + //tc->setMiscRegNoEffect(MISCREG_CANSAVE, NWindows - 2); + tc->setIntReg(NumIntArchRegs + 3, NWindows - 2); //All windows are "clean" - //threadContexts[0]->setMiscRegNoEffect(MISCREG_CLEANWIN, NWindows); - threadContexts[0]->setIntReg(NumIntArchRegs + 5, NWindows); + //tc->setMiscRegNoEffect(MISCREG_CLEANWIN, NWindows); + tc->setIntReg(NumIntArchRegs + 5, NWindows); //Start with register window 0 - threadContexts[0]->setMiscRegNoEffect(MISCREG_CWP, 0); + tc->setMiscRegNoEffect(MISCREG_CWP, 0); //Always use spill and fill traps 0 - //threadContexts[0]->setMiscRegNoEffect(MISCREG_WSTATE, 0); - threadContexts[0]->setIntReg(NumIntArchRegs + 7, 0); + //tc->setMiscRegNoEffect(MISCREG_WSTATE, 0); + tc->setIntReg(NumIntArchRegs + 7, 0); //Set the trap level to 0 - threadContexts[0]->setMiscRegNoEffect(MISCREG_TL, 0); + tc->setMiscRegNoEffect(MISCREG_TL, 0); //Set the ASI register to something fixed - threadContexts[0]->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY); + tc->setMiscRegNoEffect(MISCREG_ASI, ASI_PRIMARY); /* * T1 specific registers */ //Turn on the icache, dcache, dtb translation, and itb translation. - threadContexts[0]->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL, 15); + tc->setMiscRegNoEffect(MISCREG_MMU_LSU_CTRL, 15); } void @@ -160,8 +164,9 @@ Sparc32LiveProcess::startup() SparcLiveProcess::startup(); + ThreadContext *tc = system->getThreadContext(contextIds[0]); //The process runs in user mode with 32 bit addresses - threadContexts[0]->setMiscReg(MISCREG_PSTATE, 0x0a); + tc->setMiscReg(MISCREG_PSTATE, 0x0a); argsInit(32 / 8, VMPageSize); } @@ -174,8 +179,9 @@ Sparc64LiveProcess::startup() SparcLiveProcess::startup(); + ThreadContext *tc = system->getThreadContext(contextIds[0]); //The process runs in user mode - threadContexts[0]->setMiscReg(MISCREG_PSTATE, 0x02); + tc->setMiscReg(MISCREG_PSTATE, 0x02); argsInit(sizeof(IntReg), VMPageSize); } @@ -186,7 +192,7 @@ SparcLiveProcess::argsInit(int pageSize) { int intSize = sizeof(IntType); - typedef M5_auxv_t<IntType> auxv_t; + typedef AuxVector<IntType> auxv_t; std::vector<auxv_t> auxv; @@ -335,18 +341,18 @@ SparcLiveProcess::argsInit(int pageSize) IntType window_save_base = argc_base - window_save_size; #endif - DPRINTF(Sparc, "The addresses of items on the initial stack:\n"); - DPRINTF(Sparc, "%#x - sentry NULL\n", sentry_base); - DPRINTF(Sparc, "filename = %s\n", filename); - DPRINTF(Sparc, "%#x - file name\n", file_name_base); - DPRINTF(Sparc, "%#x - env data\n", env_data_base); - DPRINTF(Sparc, "%#x - arg data\n", arg_data_base); - DPRINTF(Sparc, "%#x - auxv array\n", auxv_array_base); - DPRINTF(Sparc, "%#x - envp array\n", envp_array_base); - DPRINTF(Sparc, "%#x - argv array\n", argv_array_base); - DPRINTF(Sparc, "%#x - argc \n", argc_base); - DPRINTF(Sparc, "%#x - window save\n", window_save_base); - DPRINTF(Sparc, "%#x - stack min\n", stack_min); + DPRINTF(Stack, "The addresses of items on the initial stack:\n"); + DPRINTF(Stack, "%#x - sentry NULL\n", sentry_base); + DPRINTF(Stack, "filename = %s\n", filename); + DPRINTF(Stack, "%#x - file name\n", file_name_base); + DPRINTF(Stack, "%#x - env data\n", env_data_base); + DPRINTF(Stack, "%#x - arg data\n", arg_data_base); + DPRINTF(Stack, "%#x - auxv array\n", auxv_array_base); + DPRINTF(Stack, "%#x - envp array\n", envp_array_base); + DPRINTF(Stack, "%#x - argv array\n", argv_array_base); + DPRINTF(Stack, "%#x - argc \n", argc_base); + DPRINTF(Stack, "%#x - window save\n", window_save_base); + DPRINTF(Stack, "%#x - stack min\n", stack_min); assert(window_save_base == stack_min); @@ -354,7 +360,7 @@ SparcLiveProcess::argsInit(int pageSize) // figure out argc IntType argc = argv.size(); - IntType guestArgc = TheISA::htog(argc); + IntType guestArgc = SparcISA::htog(argc); //Write out the sentry void * uint64_t sentry_NULL = 0; @@ -391,20 +397,21 @@ SparcLiveProcess::argsInit(int pageSize) fillStart = stack_base; spillStart = fillStart + sizeof(MachInst) * numFillInsts; + ThreadContext *tc = system->getThreadContext(contextIds[0]); //Set up the thread context to start running the process //assert(NumArgumentRegs >= 2); - //threadContexts[0]->setIntReg(ArgumentReg[0], argc); - //threadContexts[0]->setIntReg(ArgumentReg[1], argv_array_base); - threadContexts[0]->setIntReg(StackPointerReg, stack_min - StackBias); + //tc->setIntReg(ArgumentReg[0], argc); + //tc->setIntReg(ArgumentReg[1], argv_array_base); + tc->setIntReg(StackPointerReg, stack_min - StackBias); // %g1 is a pointer to a function that should be run at exit. Since we // don't have anything like that, it should be set to 0. - threadContexts[0]->setIntReg(1, 0); + tc->setIntReg(1, 0); Addr prog_entry = objFile->entryPoint(); - threadContexts[0]->setPC(prog_entry); - threadContexts[0]->setNextPC(prog_entry + sizeof(MachInst)); - threadContexts[0]->setNextNPC(prog_entry + (2 * sizeof(MachInst))); + tc->setPC(prog_entry); + tc->setNextPC(prog_entry + sizeof(MachInst)); + tc->setNextNPC(prog_entry + (2 * sizeof(MachInst))); //Align the "stack_min" to a page boundary. stack_min = roundDown(stack_min, pageSize); @@ -505,3 +512,63 @@ void Sparc64LiveProcess::flushWindows(ThreadContext *tc) tc->setIntReg(NumIntArchRegs + 4, Canrestore); tc->setMiscReg(MISCREG_CWP, origCWP); } + +IntReg +Sparc32LiveProcess::getSyscallArg(ThreadContext *tc, int i) +{ + assert(i < 6); + return bits(tc->readIntReg(FirstArgumentReg + i), 31, 0); +} + +void +Sparc32LiveProcess::setSyscallArg(ThreadContext *tc, int i, IntReg val) +{ + assert(i < 6); + tc->setIntReg(FirstArgumentReg + i, bits(val, 31, 0)); +} + +IntReg +Sparc64LiveProcess::getSyscallArg(ThreadContext *tc, int i) +{ + assert(i < 6); + return tc->readIntReg(FirstArgumentReg + i); +} + +void +Sparc64LiveProcess::setSyscallArg(ThreadContext *tc, int i, IntReg val) +{ + assert(i < 6); + tc->setIntReg(FirstArgumentReg + i, val); +} + +void +SparcLiveProcess::setSyscallReturn(ThreadContext *tc, + SyscallReturn return_value) +{ + // 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 + tc->setIntReg(NumIntArchRegs + 2, + tc->readIntReg(NumIntArchRegs + 2) & 0xEE); + //tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) & 0xEE); + IntReg val = return_value.value(); + if (bits(tc->readMiscRegNoEffect( + SparcISA::MISCREG_PSTATE), 3, 3)) { + val = bits(val, 31, 0); + } + tc->setIntReg(ReturnValueReg, val); + } else { + // got an error, set XCC.C + tc->setIntReg(NumIntArchRegs + 2, + tc->readIntReg(NumIntArchRegs + 2) | 0x11); + //tc->setMiscRegNoEffect(MISCREG_CCR, tc->readMiscRegNoEffect(MISCREG_CCR) | 0x11); + IntReg val = -return_value.value(); + if (bits(tc->readMiscRegNoEffect( + SparcISA::MISCREG_PSTATE), 3, 3)) { + val = bits(val, 31, 0); + } + tc->setIntReg(ReturnValueReg, val); + } +} diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh index a37760139..fdb9734ba 100644 --- a/src/arch/sparc/process.hh +++ b/src/arch/sparc/process.hh @@ -69,26 +69,7 @@ class SparcLiveProcess : public LiveProcess { return spillStart; } virtual void flushWindows(ThreadContext *tc) = 0; -}; - -template<class IntType> -struct M5_auxv_t -{ - IntType a_type; - union { - IntType a_val; - IntType a_ptr; - IntType a_fcn; - }; - - M5_auxv_t() - {} - - M5_auxv_t(IntType type, IntType val) - { - a_type = SparcISA::htog(type); - a_val = SparcISA::htog(val); - } + void setSyscallReturn(ThreadContext *tc, SyscallReturn return_value); }; class Sparc32LiveProcess : public SparcLiveProcess @@ -113,6 +94,9 @@ class Sparc32LiveProcess : public SparcLiveProcess void argsInit(int intSize, int pageSize); void flushWindows(ThreadContext *tc); + + SparcISA::IntReg getSyscallArg(ThreadContext *tc, int i); + void setSyscallArg(ThreadContext *tc, int i, SparcISA::IntReg val); }; class Sparc64LiveProcess : public SparcLiveProcess @@ -138,6 +122,9 @@ class Sparc64LiveProcess : public SparcLiveProcess void argsInit(int intSize, int pageSize); void flushWindows(ThreadContext *tc); + + SparcISA::IntReg getSyscallArg(ThreadContext *tc, int i); + void setSyscallArg(ThreadContext *tc, int i, SparcISA::IntReg val); }; #endif // __SPARC_PROCESS_HH__ diff --git a/src/arch/sparc/regfile.cc b/src/arch/sparc/regfile.cc index d6be52424..1c172a4d5 100644 --- a/src/arch/sparc/regfile.cc +++ b/src/arch/sparc/regfile.cc @@ -155,7 +155,7 @@ int SparcISA::flattenIntIndex(ThreadContext * tc, int reg) { int gl = tc->readMiscRegNoEffect(MISCREG_GL); int cwp = tc->readMiscRegNoEffect(MISCREG_CWP); - //DPRINTF(Sparc, "Global Level = %d, Current Window Pointer = %d\n", gl, cwp); + //DPRINTF(RegisterWindows, "Global Level = %d, Current Window Pointer = %d\n", gl, cwp); int newReg; //The total number of global registers int numGlobals = (MaxGL + 1) * 8; @@ -214,46 +214,33 @@ int SparcISA::flattenIntIndex(ThreadContext * tc, int reg) } else panic("Tried to flatten invalid register index %d!\n", reg); - DPRINTF(Sparc, "Flattened register %d to %d.\n", reg, newReg); + DPRINTF(RegisterWindows, "Flattened register %d to %d.\n", reg, newReg); return newReg; //return intRegFile.flattenIndex(reg); } -void RegFile::serialize(std::ostream &os) +void +RegFile::serialize(EventManager *em, ostream &os) { intRegFile.serialize(os); floatRegFile.serialize(os); - miscRegFile.serialize(os); + miscRegFile.serialize(em, os); SERIALIZE_SCALAR(pc); SERIALIZE_SCALAR(npc); SERIALIZE_SCALAR(nnpc); } -void RegFile::unserialize(Checkpoint *cp, const std::string §ion) +void +RegFile::unserialize(EventManager *em, Checkpoint *cp, const string §ion) { intRegFile.unserialize(cp, section); floatRegFile.unserialize(cp, section); - miscRegFile.unserialize(cp, section); + miscRegFile.unserialize(em, cp, section); UNSERIALIZE_SCALAR(pc); UNSERIALIZE_SCALAR(npc); UNSERIALIZE_SCALAR(nnpc); } -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"); - } -} - void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest) { @@ -366,12 +353,12 @@ void SparcISA::copyMiscRegs(ThreadContext *src, ThreadContext *dest) void SparcISA::copyRegs(ThreadContext *src, ThreadContext *dest) { // First loop through the integer registers. - for (int i = 0; i < TheISA::NumIntRegs; ++i) { + for (int i = 0; i < SparcISA::NumIntRegs; ++i) { dest->setIntReg(i, src->readIntReg(i)); } // Then loop through the floating point registers. - for (int i = 0; i < TheISA::NumFloatRegs; ++i) { + for (int i = 0; i < SparcISA::NumFloatRegs; ++i) { dest->setFloatRegBits(i, src->readFloatRegBits(i)); } diff --git a/src/arch/sparc/regfile.hh b/src/arch/sparc/regfile.hh index c03f69fc5..505d7c8d7 100644 --- a/src/arch/sparc/regfile.hh +++ b/src/arch/sparc/regfile.hh @@ -48,8 +48,8 @@ namespace SparcISA class RegFile { protected: - Addr pc; // Program Counter - Addr npc; // Next Program Counter + Addr pc; // Program Counter + Addr npc; // Next Program Counter Addr nnpc; public: @@ -63,16 +63,14 @@ namespace SparcISA void setNextNPC(Addr val); protected: - IntRegFile intRegFile; // integer register file - FloatRegFile floatRegFile; // floating point register file - MiscRegFile miscRegFile; // control register file + IntRegFile intRegFile; // integer register file + FloatRegFile floatRegFile; // floating point register file + MiscRegFile miscRegFile; // control register file public: void clear(); - int FlattenIntIndex(int reg); - MiscReg readMiscRegNoEffect(int miscReg); MiscReg readMiscReg(int miscReg, ThreadContext *tc); @@ -112,12 +110,11 @@ namespace SparcISA void setIntReg(int intReg, const IntReg &val); - void serialize(std::ostream &os); - void unserialize(Checkpoint *cp, const std::string §ion); + void serialize(EventManager *em, std::ostream &os); + void unserialize(EventManager *em, Checkpoint *cp, + const std::string §ion); public: - - void changeContext(RegContextParam param, RegContextVal val); }; int flattenIntIndex(ThreadContext * tc, int reg); diff --git a/src/arch/sparc/remote_gdb.cc b/src/arch/sparc/remote_gdb.cc index 67cc5b0d1..615c5b551 100644 --- a/src/arch/sparc/remote_gdb.cc +++ b/src/arch/sparc/remote_gdb.cc @@ -30,7 +30,7 @@ /* * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. + * The Regents of the University of California. All rights reserved. * * This software was developed by the Computer Systems Engineering group * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and @@ -38,8 +38,8 @@ * * All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Lawrence Berkeley Laboratories. + * This product includes software developed by the University of + * California, Lawrence Berkeley Laboratories. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -51,8 +51,8 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. + * This product includes software developed by the University of + * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. @@ -69,7 +69,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94 + * @(#)kgdb_stub.c 8.4 (Berkeley) 1/12/94 */ /*- @@ -89,8 +89,8 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. * 4. Neither the name of The NetBSD Foundation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. @@ -137,7 +137,7 @@ #include "sim/system.hh" using namespace std; -using namespace TheISA; +using namespace SparcISA; RemoteGDB::RemoteGDB(System *_system, ThreadContext *c) : BaseRemoteGDB(_system, c, NumGDBRegs), nextBkpt(0) @@ -146,7 +146,7 @@ RemoteGDB::RemoteGDB(System *_system, ThreadContext *c) /////////////////////////////////////////////////////////// // RemoteGDB::acc // -// Determine if the mapping at va..(va+len) is valid. +// Determine if the mapping at va..(va+len) is valid. // bool RemoteGDB::acc(Addr va, size_t len) @@ -171,8 +171,8 @@ RemoteGDB::acc(Addr va, size_t len) /////////////////////////////////////////////////////////// // RemoteGDB::getregs // -// Translate the kernel debugger register format into -// the GDB register format. +// Translate the kernel debugger register format into +// the GDB register format. void RemoteGDB::getregs() { @@ -217,8 +217,8 @@ RemoteGDB::getregs() /////////////////////////////////////////////////////////// // RemoteGDB::setregs // -// Translate the GDB register format into the kernel -// debugger register format. +// Translate the GDB register format into the kernel +// debugger register format. // void RemoteGDB::setregs() diff --git a/src/arch/sparc/solaris/process.cc b/src/arch/sparc/solaris/process.cc index 40d172690..22924736b 100644 --- a/src/arch/sparc/solaris/process.cc +++ b/src/arch/sparc/solaris/process.cc @@ -48,7 +48,7 @@ static SyscallReturn unameFunc(SyscallDesc *desc, int callnum, LiveProcess *process, ThreadContext *tc) { - TypedBufferArg<Solaris::utsname> name(tc->getSyscallArg(0)); + TypedBufferArg<Solaris::utsname> name(process->getSyscallArg(tc, 0)); strcpy(name->sysname, "SunOS"); strcpy(name->nodename, "m5.eecs.umich.edu"); @@ -80,7 +80,7 @@ SyscallDesc SparcSolarisProcess::syscallDescs[] = { /* 14 */ SyscallDesc("mknod", unimplementedFunc), /* 15 */ SyscallDesc("chmod", chmodFunc<Solaris>), /* 16 */ SyscallDesc("chown", chownFunc), - /* 17 */ SyscallDesc("brk", obreakFunc), + /* 17 */ SyscallDesc("brk", brkFunc), /* 18 */ SyscallDesc("stat", unimplementedFunc), /* 19 */ SyscallDesc("lseek", lseekFunc), /* 20 */ SyscallDesc("getpid", getpidFunc), @@ -123,7 +123,7 @@ SyscallDesc SparcSolarisProcess::syscallDescs[] = { /* 57 */ SyscallDesc("utssys", unimplementedFunc), /* 58 */ SyscallDesc("fdsync", unimplementedFunc), /* 59 */ SyscallDesc("execve", unimplementedFunc), - /* 60 */ SyscallDesc("umask", unimplementedFunc), + /* 60 */ SyscallDesc("umask", umaskFunc), /* 61 */ SyscallDesc("chroot", unimplementedFunc), /* 62 */ SyscallDesc("fcntl", unimplementedFunc), /* 63 */ SyscallDesc("ulimit", unimplementedFunc), @@ -153,7 +153,7 @@ SyscallDesc SparcSolarisProcess::syscallDescs[] = { /* 87 */ SyscallDesc("poll", unimplementedFunc), /* 88 */ SyscallDesc("lstat", unimplementedFunc), /* 89 */ SyscallDesc("symlink", unimplementedFunc), - /* 90 */ SyscallDesc("readlink", unimplementedFunc), + /* 90 */ SyscallDesc("readlink", readlinkFunc), /* 91 */ SyscallDesc("setgroups", unimplementedFunc), /* 92 */ SyscallDesc("getgroups", unimplementedFunc), /* 93 */ SyscallDesc("fchmod", unimplementedFunc), @@ -336,7 +336,7 @@ SparcSolarisProcess::SparcSolarisProcess(LiveProcessParams * params, SyscallDesc* SparcSolarisProcess::getDesc(int callnum) { - if (callnum < 0 || callnum > Num_Syscall_Descs) + if (callnum < 0 || callnum >= Num_Syscall_Descs) return NULL; return &syscallDescs[callnum]; } diff --git a/src/arch/sparc/solaris/solaris.cc b/src/arch/sparc/solaris/solaris.cc index c53caa72a..3cc910005 100644 --- a/src/arch/sparc/solaris/solaris.cc +++ b/src/arch/sparc/solaris/solaris.cc @@ -35,40 +35,40 @@ // open(2) flags translation table OpenFlagTransTable SparcSolaris::openFlagTable[] = { #ifdef _MSC_VER - { SparcSolaris::TGT_O_RDONLY, _O_RDONLY }, - { SparcSolaris::TGT_O_WRONLY, _O_WRONLY }, - { SparcSolaris::TGT_O_RDWR, _O_RDWR }, - { SparcSolaris::TGT_O_APPEND, _O_APPEND }, - { SparcSolaris::TGT_O_CREAT, _O_CREAT }, - { SparcSolaris::TGT_O_TRUNC, _O_TRUNC }, - { SparcSolaris::TGT_O_EXCL, _O_EXCL }, + { SparcSolaris::TGT_O_RDONLY, _O_RDONLY }, + { SparcSolaris::TGT_O_WRONLY, _O_WRONLY }, + { SparcSolaris::TGT_O_RDWR, _O_RDWR }, + { SparcSolaris::TGT_O_APPEND, _O_APPEND }, + { SparcSolaris::TGT_O_CREAT, _O_CREAT }, + { SparcSolaris::TGT_O_TRUNC, _O_TRUNC }, + { SparcSolaris::TGT_O_EXCL, _O_EXCL }, #ifdef _O_NONBLOCK - { SparcSolaris::TGT_O_NONBLOCK, _O_NONBLOCK }, - { SparcSolaris::TGT_O_NDELAY , _O_NONBLOCK }, + { SparcSolaris::TGT_O_NONBLOCK, _O_NONBLOCK }, + { SparcSolaris::TGT_O_NDELAY , _O_NONBLOCK }, #endif #ifdef _O_NOCTTY - { SparcSolaris::TGT_O_NOCTTY, _O_NOCTTY }, + { SparcSolaris::TGT_O_NOCTTY, _O_NOCTTY }, #endif #ifdef _O_SYNC - { SparcSolaris::TGT_O_SYNC, _O_SYNC }, - { SparcSolaris::TGT_O_DSYNC, _O_SYNC }, - { SparcSolaris::TGT_O_RSYNC, _O_SYNC }, + { SparcSolaris::TGT_O_SYNC, _O_SYNC }, + { SparcSolaris::TGT_O_DSYNC, _O_SYNC }, + { SparcSolaris::TGT_O_RSYNC, _O_SYNC }, #endif #else /* !_MSC_VER */ - { SparcSolaris::TGT_O_RDONLY, O_RDONLY }, - { SparcSolaris::TGT_O_WRONLY, O_WRONLY }, - { SparcSolaris::TGT_O_RDWR, O_RDWR }, - { SparcSolaris::TGT_O_APPEND, O_APPEND }, - { SparcSolaris::TGT_O_CREAT, O_CREAT }, - { SparcSolaris::TGT_O_TRUNC, O_TRUNC }, - { SparcSolaris::TGT_O_EXCL, O_EXCL }, - { SparcSolaris::TGT_O_NONBLOCK, O_NONBLOCK }, - { SparcSolaris::TGT_O_NDELAY , O_NONBLOCK }, - { SparcSolaris::TGT_O_NOCTTY, O_NOCTTY }, + { SparcSolaris::TGT_O_RDONLY, O_RDONLY }, + { SparcSolaris::TGT_O_WRONLY, O_WRONLY }, + { SparcSolaris::TGT_O_RDWR, O_RDWR }, + { SparcSolaris::TGT_O_APPEND, O_APPEND }, + { SparcSolaris::TGT_O_CREAT, O_CREAT }, + { SparcSolaris::TGT_O_TRUNC, O_TRUNC }, + { SparcSolaris::TGT_O_EXCL, O_EXCL }, + { SparcSolaris::TGT_O_NONBLOCK, O_NONBLOCK }, + { SparcSolaris::TGT_O_NDELAY , O_NONBLOCK }, + { SparcSolaris::TGT_O_NOCTTY, O_NOCTTY }, #ifdef O_SYNC - { SparcSolaris::TGT_O_SYNC, O_SYNC }, - { SparcSolaris::TGT_O_DSYNC, O_SYNC }, - { SparcSolaris::TGT_O_RSYNC, O_SYNC }, + { SparcSolaris::TGT_O_SYNC, O_SYNC }, + { SparcSolaris::TGT_O_DSYNC, O_SYNC }, + { SparcSolaris::TGT_O_RSYNC, O_SYNC }, #endif #endif /* _MSC_VER */ }; diff --git a/src/arch/sparc/solaris/solaris.hh b/src/arch/sparc/solaris/solaris.hh index 0564faba4..df2565027 100644 --- a/src/arch/sparc/solaris/solaris.hh +++ b/src/arch/sparc/solaris/solaris.hh @@ -39,22 +39,22 @@ class SparcSolaris : public Solaris static OpenFlagTransTable openFlagTable[]; - static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY - static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY - static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR - static const int TGT_O_NDELAY = 0x00000004; //!< O_NONBLOCK - static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND + static const int TGT_O_RDONLY = 0x00000000; //!< O_RDONLY + static const int TGT_O_WRONLY = 0x00000001; //!< O_WRONLY + static const int TGT_O_RDWR = 0x00000002; //!< O_RDWR + static const int TGT_O_NDELAY = 0x00000004; //!< O_NONBLOCK + static const int TGT_O_APPEND = 0x00000008; //!< O_APPEND static const int TGT_O_SYNC = 0x00000010; //!< O_SYNC static const int TGT_O_DSYNC = 0x00000040; //!< O_SYNC static const int TGT_O_RSYNC = 0x00008000; //!< O_SYNC static const int TGT_O_NONBLOCK = 0x00000080; //!< O_NONBLOCK static const int TGT_O_PRIV = 0x00001000; //?? static const int TGT_O_LARGEFILE = 0x00002000; //?? - static const int TGT_O_CREAT = 0x00000100; //!< O_CREAT - static const int TGT_O_TRUNC = 0x00000200; //!< O_TRUNC - static const int TGT_O_EXCL = 0x00000400; //!< O_EXCL - static const int TGT_O_NOCTTY = 0x00000800; //!< O_NOCTTY - static const int TGT_O_XATTR = 0x00004000; //?? + static const int TGT_O_CREAT = 0x00000100; //!< O_CREAT + static const int TGT_O_TRUNC = 0x00000200; //!< O_TRUNC + static const int TGT_O_EXCL = 0x00000400; //!< O_EXCL + static const int TGT_O_NOCTTY = 0x00000800; //!< O_NOCTTY + static const int TGT_O_XATTR = 0x00004000; //?? static const int NUM_OPEN_FLAGS; diff --git a/src/arch/sparc/sparc_traits.hh b/src/arch/sparc/sparc_traits.hh index 715c08c03..e154ba274 100644 --- a/src/arch/sparc/sparc_traits.hh +++ b/src/arch/sparc/sparc_traits.hh @@ -47,8 +47,8 @@ namespace SparcISA // const int NumRegularIntRegs = MaxGL * 8 + NWindows * 16; // const int NumMicroIntRegs = 1; // const int NumIntRegs = -// NumRegularIntRegs + -// NumMicroIntRegs; +// NumRegularIntRegs + +// NumMicroIntRegs; // const int NumFloatRegs = 64; // const int NumMiscRegs = 40; } diff --git a/src/arch/sparc/stacktrace.cc b/src/arch/sparc/stacktrace.cc index 2d7991267..3ab0edb57 100644 --- a/src/arch/sparc/stacktrace.cc +++ b/src/arch/sparc/stacktrace.cc @@ -70,8 +70,6 @@ namespace SparcISA if (!tc->getSystemPtr()->kernelSymtab->findAddress("task_struct_comm", addr)) panic("thread info not compiled into kernel\n"); name_off = vp->readGtoH<int32_t>(addr); - - tc->delVirtPort(vp); } Addr @@ -87,7 +85,6 @@ namespace SparcISA vp = tc->getVirtPort(); tsk = vp->readGtoH<Addr>(base + task_off); - tc->delVirtPort(vp); return tsk; } @@ -105,7 +102,6 @@ namespace SparcISA vp = tc->getVirtPort(); pd = vp->readGtoH<uint16_t>(task + pid_off); - tc->delVirtPort(vp); return pd; } @@ -163,7 +159,7 @@ namespace SparcISA } SymbolTable *symtab = tc->getSystemPtr()->kernelSymtab; - Addr ksp = tc->readIntReg(TheISA::StackPointerReg); + Addr ksp = tc->readIntReg(SparcISA::StackPointerReg); Addr bottom = ksp & ~0x3fff; Addr addr; diff --git a/src/arch/sparc/stacktrace.hh b/src/arch/sparc/stacktrace.hh index 4bc5d779b..929990fcb 100644 --- a/src/arch/sparc/stacktrace.hh +++ b/src/arch/sparc/stacktrace.hh @@ -61,7 +61,7 @@ namespace SparcISA class StackTrace { protected: - typedef TheISA::MachInst MachInst; + typedef SparcISA::MachInst MachInst; private: ThreadContext *tc; std::vector<Addr> stack; diff --git a/src/arch/sparc/tlb.cc b/src/arch/sparc/tlb.cc index 22df44908..95ad0229e 100644 --- a/src/arch/sparc/tlb.cc +++ b/src/arch/sparc/tlb.cc @@ -51,7 +51,7 @@ TLB::TLB(const Params *p) { // To make this work you'll have to change the hypervisor and OS if (size > 64) - fatal("SPARC T1 TLB registers don't support more than 64 TLB entries."); + fatal("SPARC T1 TLB registers don't support more than 64 TLB entries"); tlb = new TlbEntry[size]; std::memset(tlb, 0, sizeof(TlbEntry) * size); @@ -87,8 +87,6 @@ void TLB::insert(Addr va, int partition_id, int context_id, bool real, const PageTableEntry& PTE, int entry) { - - MapIter i; TlbEntry *new_entry = NULL; // TlbRange tr; @@ -103,8 +101,9 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real, tr.real = real; */ - DPRINTF(TLB, "TLB: Inserting TLB Entry; va=%#x pa=%#x pid=%d cid=%d r=%d entryid=%d\n", - va, PTE.paddr(), partition_id, context_id, (int)real, entry); + DPRINTF(TLB, + "TLB: Inserting Entry; va=%#x pa=%#x pid=%d cid=%d r=%d entryid=%d\n", + va, PTE.paddr(), partition_id, context_id, (int)real, entry); // Demap any entry that conflicts for (x = 0; x < size; x++) { @@ -128,7 +127,6 @@ TLB::insert(Addr va, int partition_id, int context_id, bool real, } } - /* i = lookupTable.find(tr); if (i != lookupTable.end()) { @@ -195,25 +193,22 @@ insertAllLocked: new_entry->valid = true; usedEntries++; - - i = lookupTable.insert(new_entry->range, new_entry); assert(i != lookupTable.end()); - // If all entries have there used bit set, clear it on them all, but the - // one we just inserted + // If all entries have their used bit set, clear it on them all, + // but the one we just inserted if (usedEntries == size) { clearUsedBits(); new_entry->used = true; usedEntries++; } - } TlbEntry* -TLB::lookup(Addr va, int partition_id, bool real, int context_id, bool - update_used) +TLB::lookup(Addr va, int partition_id, bool real, int context_id, + bool update_used) { MapIter i; TlbRange tr; @@ -240,8 +235,8 @@ TLB::lookup(Addr va, int partition_id, bool real, int context_id, bool DPRINTF(TLB, "TLB: Valid entry found pa: %#x size: %#x\n", t->pte.paddr(), t->pte.size()); - // Update the used bits only if this is a real access (not a fake one from - // virttophys() + // Update the used bits only if this is a real access (not a fake + // one from virttophys() if (!t->used && update_used) { t->used = true; usedEntries++; @@ -304,11 +299,10 @@ TLB::demapPage(Addr va, int partition_id, bool real, int context_id) void TLB::demapContext(int partition_id, int context_id) { - int x; DPRINTF(IPR, "TLB: Demapping Context pid=%#d cid=%d\n", partition_id, context_id); cacheValid = false; - for (x = 0; x < size; x++) { + for (int x = 0; x < size; x++) { if (tlb[x].range.contextId == context_id && tlb[x].range.partitionId == partition_id) { if (tlb[x].valid == true) { @@ -327,10 +321,9 @@ TLB::demapContext(int partition_id, int context_id) void TLB::demapAll(int partition_id) { - int x; DPRINTF(TLB, "TLB: Demapping All pid=%#d\n", partition_id); cacheValid = false; - for (x = 0; x < size; x++) { + for (int x = 0; x < size; x++) { if (tlb[x].valid && !tlb[x].pte.locked() && tlb[x].range.partitionId == partition_id) { freeList.push_front(&tlb[x]); @@ -347,11 +340,10 @@ TLB::demapAll(int partition_id) void TLB::invalidateAll() { - int x; cacheValid = false; - lookupTable.clear(); - for (x = 0; x < size; x++) { + + for (int x = 0; x < size; x++) { if (tlb[x].valid == true) freeList.push_back(&tlb[x]); tlb[x].valid = false; @@ -361,7 +353,8 @@ TLB::invalidateAll() } uint64_t -TLB::TteRead(int entry) { +TLB::TteRead(int entry) +{ if (entry >= size) panic("entry: %d\n", entry); @@ -373,7 +366,8 @@ TLB::TteRead(int entry) { } uint64_t -TLB::TagRead(int entry) { +TLB::TagRead(int entry) +{ assert(entry < size); uint64_t tag; if (!tlb[entry].valid) @@ -442,7 +436,7 @@ DTB::writeSfsr(Addr a, bool write, ContextType ct, } Fault -ITB::translate(RequestPtr &req, ThreadContext *tc) +ITB::translateAtomic(RequestPtr req, ThreadContext *tc) { uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA); @@ -459,9 +453,8 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) if (cacheEntry) { if (cacheEntry->range.va < vaddr + sizeof(MachInst) && cacheEntry->range.va + cacheEntry->range.size >= vaddr) { - req->setPaddr(cacheEntry->pte.paddr() & ~(cacheEntry->pte.size()-1) | - vaddr & cacheEntry->pte.size()-1 ); - return NoFault; + req->setPaddr(cacheEntry->pte.translate(vaddr)); + return NoFault; } } else { req->setPaddr(vaddr & PAddrImplMask); @@ -550,18 +543,26 @@ ITB::translate(RequestPtr &req, ThreadContext *tc) cacheState = tlbdata; cacheEntry = e; - req->setPaddr(e->pte.paddr() & ~(e->pte.size()-1) | - vaddr & e->pte.size()-1 ); + req->setPaddr(e->pte.translate(vaddr)); DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); return NoFault; } - +void +ITB::translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation) +{ + assert(translation); + translation->finish(translateAtomic(req, tc), req, tc, false); +} Fault -DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) +DTB::translateAtomic(RequestPtr req, ThreadContext *tc, bool write) { - /* @todo this could really use some profiling and fixing to make it faster! */ + /* + * @todo this could really use some profiling and fixing to make + * it faster! + */ uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA); Addr vaddr = req->getVaddr(); Addr size = req->getSize(); @@ -569,7 +570,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) asi = (ASI)req->getAsi(); bool implicit = false; bool hpriv = bits(tlbdata,0,0); - bool unaligned = (vaddr & size-1); + bool unaligned = vaddr & (size - 1); DPRINTF(TLB, "TLB: DTB Request to translate va=%#x size=%d asi=%#x\n", vaddr, size, asi); @@ -599,11 +600,11 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) if (cacheAsi[0] == asi && ce_va < vaddr + size && ce_va + ce->range.size > vaddr && (!write || ce->pte.writable())) { - req->setPaddr(ce->pte.paddrMask() | vaddr & ce->pte.sizeMask()); - if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1) - req->setFlags(req->getFlags() | UNCACHEABLE); - DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); - return NoFault; + req->setPaddr(ce->pte.translate(vaddr)); + if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1) + req->setFlags(Request::UNCACHEABLE); + DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); + return NoFault; } // if matched } // if cache entry valid if (cacheEntry[1]) { @@ -612,11 +613,11 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) if (cacheAsi[1] == asi && ce_va < vaddr + size && ce_va + ce->range.size > vaddr && (!write || ce->pte.writable())) { - req->setPaddr(ce->pte.paddrMask() | vaddr & ce->pte.sizeMask()); - if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1) - req->setFlags(req->getFlags() | UNCACHEABLE); - DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); - return NoFault; + req->setPaddr(ce->pte.translate(vaddr)); + if (ce->pte.sideffect() || (ce->pte.paddr() >> 39) & 1) + req->setFlags(Request::UNCACHEABLE); + DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); + return NoFault; } // if matched } // if cache entry valid } @@ -639,7 +640,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) TlbEntry *e; DPRINTF(TLB, "TLB: priv:%d hpriv:%d red:%d lsudm:%d part_id: %#X\n", - priv, hpriv, red, lsu_dm, part_id); + priv, hpriv, red, lsu_dm, part_id); if (implicit) { if (tl > 0) { @@ -725,11 +726,10 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) return new DataAccessException; } - if ((!lsu_dm && !hpriv && !red) || AsiIsReal(asi)) { real = true; context = 0; - }; + } if (hpriv && (implicit || (!AsiIsAsIfUser(asi) && !AsiIsReal(asi)))) { req->setPaddr(vaddr & PAddrImplMask); @@ -776,9 +776,8 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) return new DataAccessException; } - if (e->pte.sideffect() || (e->pte.paddr() >> 39) & 1) - req->setFlags(req->getFlags() | UNCACHEABLE); + req->setFlags(Request::UNCACHEABLE); // cache translation date for next translation cacheState = tlbdata; @@ -796,8 +795,7 @@ DTB::translate(RequestPtr &req, ThreadContext *tc, bool write) cacheAsi[0] = (ASI)0; } cacheValid = true; - req->setPaddr(e->pte.paddr() & ~(e->pte.size()-1) | - vaddr & e->pte.size()-1); + req->setPaddr(e->pte.translate(vaddr)); DPRINTF(TLB, "TLB: %#X -> %#X\n", vaddr, req->getPaddr()); return NoFault; @@ -811,8 +809,8 @@ handleIntRegAccess: return new PrivilegedAction; } - if (asi == ASI_SWVR_UDB_INTR_W && !write || - asi == ASI_SWVR_UDB_INTR_R && write) { + if ((asi == ASI_SWVR_UDB_INTR_W && !write) || + (asi == ASI_SWVR_UDB_INTR_R && write)) { writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi); return new DataAccessException; } @@ -832,7 +830,7 @@ handleQueueRegAccess: writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi); return new PrivilegedAction; } - if (!hpriv && vaddr & 0xF || vaddr > 0x3f8 || vaddr < 0x3c0) { + if ((!hpriv && vaddr & 0xF) || vaddr > 0x3f8 || vaddr < 0x3c0) { writeSfsr(vaddr, write, Primary, true, IllegalAsi, asi); return new DataAccessException; } @@ -857,6 +855,14 @@ handleMmuRegAccess: return NoFault; }; +void +DTB::translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation, bool write) +{ + assert(translation); + translation->finish(translateAtomic(req, tc, write), req, tc, write); +} + #if FULL_SYSTEM Tick @@ -869,7 +875,7 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) DPRINTF(IPR, "Memory Mapped IPR Read: asi=%#X a=%#x\n", (uint32_t)pkt->req->getAsi(), pkt->getAddr()); - ITB * itb = tc->getITBPtr(); + ITB *itb = tc->getITBPtr(); switch (asi) { case ASI_LSU_CONTROL_REG: @@ -1018,12 +1024,22 @@ DTB::doMmuRegRead(ThreadContext *tc, Packet *pkt) itb->cx_config)); break; case ASI_SWVR_INTR_RECEIVE: - pkt->set(tc->getCpuPtr()->get_interrupts(IT_INT_VEC)); + { + SparcISA::Interrupts * interrupts = + dynamic_cast<SparcISA::Interrupts *>( + tc->getCpuPtr()->getInterruptController()); + pkt->set(interrupts->get_vec(IT_INT_VEC)); + } break; case ASI_SWVR_UDB_INTR_R: - temp = findMsbSet(tc->getCpuPtr()->get_interrupts(IT_INT_VEC)); - tc->getCpuPtr()->clear_interrupt(IT_INT_VEC, temp); - pkt->set(temp); + { + SparcISA::Interrupts * interrupts = + dynamic_cast<SparcISA::Interrupts *>( + tc->getCpuPtr()->getInterruptController()); + temp = findMsbSet(interrupts->get_vec(IT_INT_VEC)); + tc->getCpuPtr()->clearInterrupt(IT_INT_VEC, temp); + pkt->set(temp); + } break; default: doMmuReadError: @@ -1055,7 +1071,7 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) DPRINTF(IPR, "Memory Mapped IPR Write: asi=%#X a=%#x d=%#X\n", (uint32_t)asi, va, data); - ITB * itb = tc->getITBPtr(); + ITB *itb = tc->getITBPtr(); switch (asi) { case ASI_LSU_CONTROL_REG: @@ -1129,7 +1145,7 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) break; case ASI_SPARC_ERROR_EN_REG: case ASI_SPARC_ERROR_STATUS_REG: - warn("Ignoring write to SPARC ERROR regsiter\n"); + inform("Ignoring write to SPARC ERROR regsiter\n"); break; case ASI_HYP_SCRATCHPAD: case ASI_SCRATCHPAD: @@ -1173,7 +1189,8 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) real_insert = bits(va, 9,9); pte.populate(data, bits(va,10,10) ? PageTableEntry::sun4v : PageTableEntry::sun4u); - insert(va_insert, part_insert, ct_insert, real_insert, pte, entry_insert); + insert(va_insert, part_insert, ct_insert, real_insert, pte, + entry_insert); break; case ASI_IMMU_DEMAP: ignore = false; @@ -1261,18 +1278,23 @@ DTB::doMmuRegWrite(ThreadContext *tc, Packet *pkt) } break; case ASI_SWVR_INTR_RECEIVE: - int msb; - // clear all the interrupts that aren't set in the write - while(tc->getCpuPtr()->get_interrupts(IT_INT_VEC) & data) { - msb = findMsbSet(tc->getCpuPtr()->get_interrupts(IT_INT_VEC) & data); - tc->getCpuPtr()->clear_interrupt(IT_INT_VEC, msb); + { + int msb; + // clear all the interrupts that aren't set in the write + SparcISA::Interrupts * interrupts = + dynamic_cast<SparcISA::Interrupts *>( + tc->getCpuPtr()->getInterruptController()); + while (interrupts->get_vec(IT_INT_VEC) & data) { + msb = findMsbSet(interrupts->get_vec(IT_INT_VEC) & data); + tc->getCpuPtr()->clearInterrupt(IT_INT_VEC, msb); + } } break; case ASI_SWVR_UDB_INTR_W: tc->getSystemPtr()->threadContexts[bits(data,12,8)]->getCpuPtr()-> - post_interrupt(bits(data,5,0),0); + postInterrupt(bits(data, 5, 0), 0); break; - default: + default: doMmuWriteError: panic("need to impl DTB::doMmuRegWrite() got asi=%#x, va=%#x d=%#x\n", (uint32_t)pkt->req->getAsi(), pkt->getAddr(), data); @@ -1310,10 +1332,6 @@ DTB::GetTsbPtr(ThreadContext *tc, Addr addr, int ctx, Addr *ptrs) itb->cx_config); } - - - - uint64_t DTB::MakeTsbPtr(TsbPageSize ps, uint64_t tag_access, uint64_t c0_tsb, uint64_t c0_config, uint64_t cX_tsb, uint64_t cX_config) @@ -1341,7 +1359,6 @@ DTB::MakeTsbPtr(TsbPageSize ps, uint64_t tag_access, uint64_t c0_tsb, return ptr; } - void TLB::serialize(std::ostream &os) { diff --git a/src/arch/sparc/tlb.hh b/src/arch/sparc/tlb.hh index 2f7d08320..4fe532d4a 100644 --- a/src/arch/sparc/tlb.hh +++ b/src/arch/sparc/tlb.hh @@ -109,9 +109,9 @@ class TLB : public BaseTLB * @param paritition_id partition this entry is for * @param real is this a real->phys or virt->phys translation * @param context_id if this is virt->phys what context - * @param update_used should ew update the used bits in the entries on not - * useful if we are trying to do a va->pa without mucking with any state for - * a debug read for example. + * @param update_used should ew update the used bits in the + * entries on not useful if we are trying to do a va->pa without + * mucking with any state for a debug read for example. * @return A pointer to a tlb entry */ TlbEntry *lookup(Addr va, int partition_id, bool real, int context_id = 0, @@ -177,7 +177,9 @@ class ITB : public TLB cacheEntry = NULL; } - Fault translate(RequestPtr &req, ThreadContext *tc); + Fault translateAtomic(RequestPtr req, ThreadContext *tc); + void translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation); private: void writeSfsr(bool write, ContextType ct, bool se, FaultTypes ft, int asi); @@ -199,7 +201,10 @@ class DTB : public TLB cacheEntry[1] = NULL; } - Fault translate(RequestPtr &req, ThreadContext *tc, bool write); + Fault translateAtomic(RequestPtr req, + ThreadContext *tc, bool write=false); + void translateTiming(RequestPtr req, ThreadContext *tc, + Translation *translation, bool write=false); #if FULL_SYSTEM Tick doMmuRegRead(ThreadContext *tc, Packet *pkt); Tick doMmuRegWrite(ThreadContext *tc, Packet *pkt); diff --git a/src/arch/sparc/tlb_map.hh b/src/arch/sparc/tlb_map.hh index 8285db939..fa49584ba 100644 --- a/src/arch/sparc/tlb_map.hh +++ b/src/arch/sparc/tlb_map.hh @@ -52,7 +52,7 @@ class TlbMap i = tree.upper_bound(r); - if (i == tree.begin()) + if (i == tree.begin()) { if (r.real == i->first.real && r.partitionId == i->first.partitionId && i->first.va < r.va + r.size && @@ -62,6 +62,7 @@ class TlbMap else // Nothing could match, so return end() return tree.end(); + } i--; diff --git a/src/arch/sparc/types.hh b/src/arch/sparc/types.hh index d19e2a99f..dd369cc26 100644 --- a/src/arch/sparc/types.hh +++ b/src/arch/sparc/types.hh @@ -51,14 +51,6 @@ namespace SparcISA MiscReg ctrlreg; } AnyReg; - enum RegContextParam - { - CONTEXT_CWP, - CONTEXT_GLOBALS - }; - - typedef int RegContextVal; - typedef uint16_t RegIndex; struct CoreSpecific { diff --git a/src/arch/sparc/ua2005.cc b/src/arch/sparc/ua2005.cc index fe733813c..880d2c3eb 100644 --- a/src/arch/sparc/ua2005.cc +++ b/src/arch/sparc/ua2005.cc @@ -35,34 +35,59 @@ #include "sim/system.hh" using namespace SparcISA; +using namespace std; void MiscRegFile::checkSoftInt(ThreadContext *tc) { + BaseCPU *cpu = tc->getCpuPtr(); + // If PIL < 14, copy over the tm and sm bits if (pil < 14 && softint & 0x10000) - tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,16); + cpu->postInterrupt(IT_SOFT_INT, 16); else - tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,16); + cpu->clearInterrupt(IT_SOFT_INT, 16); if (pil < 14 && softint & 0x1) - tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,0); + cpu->postInterrupt(IT_SOFT_INT, 0); else - tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,0); + cpu->clearInterrupt(IT_SOFT_INT, 0); // Copy over any of the other bits that are set for (int bit = 15; bit > 0; --bit) { if (1 << bit & softint && bit > pil) - tc->getCpuPtr()->post_interrupt(IT_SOFT_INT,bit); + cpu->postInterrupt(IT_SOFT_INT, bit); else - tc->getCpuPtr()->clear_interrupt(IT_SOFT_INT,bit); + cpu->clearInterrupt(IT_SOFT_INT, bit); } } +//These functions map register indices to names +static inline string +getMiscRegName(RegIndex index) +{ + static string miscRegName[NumMiscRegs] = + {/*"y", "ccr",*/ "asi", "tick", "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", "prictx", "secctx", "partId", "lsuCtrlReg", + "scratch0", "scratch1", "scratch2", "scratch3", "scratch4", + "scratch5", "scratch6", "scratch7", "cpuMondoHead", "cpuMondoTail", + "devMondoHead", "devMondoTail", "resErrorHead", "resErrorTail", + "nresErrorHead", "nresErrorTail", "TlbData" }; + return miscRegName[index]; +} void MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) { + BaseCPU *cpu = tc->getCpuPtr(); + int64_t time; switch (miscReg) { /* Full system only ASRs */ @@ -80,12 +105,12 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) tickCompare = new TickCompareEvent(this, tc); setRegNoEffect(miscReg, val); if ((tick_cmpr & ~mask(63)) && tickCompare->scheduled()) - tickCompare->deschedule(); + cpu->deschedule(tickCompare); time = (tick_cmpr & mask(63)) - (tick & mask(63)); if (!(tick_cmpr & ~mask(63)) && time > 0) { if (tickCompare->scheduled()) - tickCompare->deschedule(); - tickCompare->schedule(time * tc->getCpuPtr()->ticks(1)); + cpu->deschedule(tickCompare); + cpu->schedule(tickCompare, curTick + time * cpu->ticks(1)); } panic("writing to TICK compare register %#X\n", val); break; @@ -95,13 +120,13 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) sTickCompare = new STickCompareEvent(this, tc); setRegNoEffect(miscReg, val); if ((stick_cmpr & ~mask(63)) && sTickCompare->scheduled()) - sTickCompare->deschedule(); + cpu->deschedule(sTickCompare); time = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - - tc->getCpuPtr()->instCount(); + cpu->instCount(); if (!(stick_cmpr & ~mask(63)) && time > 0) { if (sTickCompare->scheduled()) - sTickCompare->deschedule(); - sTickCompare->schedule(time * tc->getCpuPtr()->ticks(1) + curTick); + cpu->deschedule(sTickCompare); + cpu->schedule(sTickCompare, curTick + time * cpu->ticks(1)); } DPRINTF(Timer, "writing to sTICK compare register value %#X\n", val); break; @@ -120,9 +145,9 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) case MISCREG_HINTP: setRegNoEffect(miscReg, val); if (hintp) - tc->getCpuPtr()->post_interrupt(IT_HINTP,0); + cpu->postInterrupt(IT_HINTP, 0); else - tc->getCpuPtr()->clear_interrupt(IT_HINTP,0); + cpu->clearInterrupt(IT_HINTP, 0); break; case MISCREG_HTBA: @@ -134,25 +159,25 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) case MISCREG_QUEUE_CPU_MONDO_TAIL: setRegNoEffect(miscReg, val); if (cpu_mondo_head != cpu_mondo_tail) - tc->getCpuPtr()->post_interrupt(IT_CPU_MONDO,0); + cpu->postInterrupt(IT_CPU_MONDO, 0); else - tc->getCpuPtr()->clear_interrupt(IT_CPU_MONDO,0); + cpu->clearInterrupt(IT_CPU_MONDO, 0); break; case MISCREG_QUEUE_DEV_MONDO_HEAD: case MISCREG_QUEUE_DEV_MONDO_TAIL: setRegNoEffect(miscReg, val); if (dev_mondo_head != dev_mondo_tail) - tc->getCpuPtr()->post_interrupt(IT_DEV_MONDO,0); + cpu->postInterrupt(IT_DEV_MONDO, 0); else - tc->getCpuPtr()->clear_interrupt(IT_DEV_MONDO,0); + cpu->clearInterrupt(IT_DEV_MONDO, 0); break; case MISCREG_QUEUE_RES_ERROR_HEAD: case MISCREG_QUEUE_RES_ERROR_TAIL: setRegNoEffect(miscReg, val); if (res_error_head != res_error_tail) - tc->getCpuPtr()->post_interrupt(IT_RES_ERROR,0); + cpu->postInterrupt(IT_RES_ERROR, 0); else - tc->getCpuPtr()->clear_interrupt(IT_RES_ERROR,0); + cpu->clearInterrupt(IT_RES_ERROR, 0); break; case MISCREG_QUEUE_NRES_ERROR_HEAD: case MISCREG_QUEUE_NRES_ERROR_TAIL: @@ -165,13 +190,13 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) hSTickCompare = new HSTickCompareEvent(this, tc); setRegNoEffect(miscReg, val); if ((hstick_cmpr & ~mask(63)) && hSTickCompare->scheduled()) - hSTickCompare->deschedule(); + cpu->deschedule(hSTickCompare); time = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - - tc->getCpuPtr()->instCount(); + cpu->instCount(); if (!(hstick_cmpr & ~mask(63)) && time > 0) { if (hSTickCompare->scheduled()) - hSTickCompare->deschedule(); - hSTickCompare->schedule(curTick + time * tc->getCpuPtr()->ticks(1)); + cpu->deschedule(hSTickCompare); + cpu->schedule(hSTickCompare, curTick + time * cpu->ticks(1)); } DPRINTF(Timer, "writing to hsTICK compare register value %#X\n", val); break; @@ -181,9 +206,9 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) setRegNoEffect(miscReg, val | HPSTATE::id); #if FULL_SYSTEM if (hpstate & HPSTATE::tlz && tl == 0 && !(hpstate & HPSTATE::hpriv)) - tc->getCpuPtr()->post_interrupt(IT_TRAP_LEVEL_ZERO,0); + cpu->postInterrupt(IT_TRAP_LEVEL_ZERO, 0); else - tc->getCpuPtr()->clear_interrupt(IT_TRAP_LEVEL_ZERO,0); + cpu->clearInterrupt(IT_TRAP_LEVEL_ZERO, 0); #endif break; case MISCREG_HTSTATE: @@ -200,11 +225,12 @@ MiscRegFile::setFSReg(int miscReg, const MiscReg &val, ThreadContext *tc) tc->suspend(); if (tc->getKernelStats()) tc->getKernelStats()->quiesce(); - } + } break; default: - panic("Invalid write to FS misc register %s\n", getMiscRegName(miscReg)); + panic("Invalid write to FS misc register %s\n", + getMiscRegName(miscReg)); } } @@ -250,12 +276,13 @@ MiscRegFile::readFSReg(int miscReg, ThreadContext * tc) sys = tc->getSystemPtr(); temp = readRegNoEffect(miscReg) & (STS::active | STS::speculative); - // Check that the CPU array is fully populated (by calling getNumCPus()) - assert(sys->getNumCPUs() > tc->readCpuId()); + // Check that the CPU array is fully populated + // (by calling getNumCPus()) + assert(sys->numContexts() > tc->contextId()); - temp |= tc->readCpuId() << STS::shft_id; + temp |= tc->contextId() << STS::shft_id; - for (x = tc->readCpuId() & ~3; x < sys->threadContexts.size(); x++) { + for (x = tc->contextId() & ~3; x < sys->threadContexts.size(); x++) { switch (sys->threadContexts[x]->status()) { case ThreadContext::Active: temp |= STS::st_run << (STS::shft_fsm0 - @@ -280,16 +307,6 @@ MiscRegFile::readFSReg(int miscReg, ThreadContext * tc) panic("Invalid read to FS misc register\n"); } } -/* - In Niagra STICK==TICK so this isn't needed - case MISCREG_STICK: - SparcSystem *sys; - sys = dynamic_cast<SparcSystem*>(tc->getSystemPtr()); - assert(sys != NULL); - return curTick/Clock::Int::ns - sys->sysTick | (stick & ~(mask(63))); -*/ - - void MiscRegFile::processTickCompare(ThreadContext *tc) @@ -300,12 +317,14 @@ MiscRegFile::processTickCompare(ThreadContext *tc) void MiscRegFile::processSTickCompare(ThreadContext *tc) { + BaseCPU *cpu = tc->getCpuPtr(); + // since our microcode instructions take two cycles we need to check if // we're actually at the correct cycle or we need to wait a little while // more int ticks; ticks = ((int64_t)(stick_cmpr & mask(63)) - (int64_t)stick) - - tc->getCpuPtr()->instCount(); + cpu->instCount(); assert(ticks >= 0 && "stick compare missed interrupt cycle"); if (ticks == 0 || tc->status() == ThreadContext::Suspended) { @@ -315,12 +334,14 @@ MiscRegFile::processSTickCompare(ThreadContext *tc) setReg(MISCREG_SOFTINT, softint | (ULL(1) << 16), tc); } } else - sTickCompare->schedule(ticks * tc->getCpuPtr()->ticks(1) + curTick); + cpu->schedule(sTickCompare, curTick + ticks * cpu->ticks(1)); } void MiscRegFile::processHSTickCompare(ThreadContext *tc) { + BaseCPU *cpu = tc->getCpuPtr(); + // since our microcode instructions take two cycles we need to check if // we're actually at the correct cycle or we need to wait a little while // more @@ -330,7 +351,7 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc) return; ticks = ((int64_t)(hstick_cmpr & mask(63)) - (int64_t)stick) - - tc->getCpuPtr()->instCount(); + cpu->instCount(); assert(ticks >= 0 && "hstick compare missed interrupt cycle"); if (ticks == 0 || tc->status() == ThreadContext::Suspended) { @@ -341,6 +362,6 @@ MiscRegFile::processHSTickCompare(ThreadContext *tc) } // Need to do something to cause interrupt to happen here !!! @todo } else - hSTickCompare->schedule(ticks * tc->getCpuPtr()->ticks(1) + curTick); + cpu->schedule(hSTickCompare, curTick + ticks * cpu->ticks(1)); } diff --git a/src/arch/sparc/utility.cc b/src/arch/sparc/utility.cc index 6d4358603..d4cc286e6 100644 --- a/src/arch/sparc/utility.cc +++ b/src/arch/sparc/utility.cc @@ -46,14 +46,14 @@ namespace SparcISA { //first 6 arguments which the caller may use but doesn't have to. uint64_t getArgument(ThreadContext *tc, int number, bool fp) { #if FULL_SYSTEM + const int NumArgumentRegs = 6; if (number < NumArgumentRegs) { - return tc->readIntReg(ArgumentReg[number]); + return tc->readIntReg(8 + number); } else { Addr sp = tc->readIntReg(StackPointerReg); - VirtualPort *vp = tc->getVirtPort(tc); + VirtualPort *vp = tc->getVirtPort(); uint64_t arg = vp->read<uint64_t>(sp + 92 + (number-NumArgumentRegs) * sizeof(uint64_t)); - tc->delVirtPort(vp); return arg; } #else diff --git a/src/arch/sparc/vtophys.cc b/src/arch/sparc/vtophys.cc index 9a93950d2..f23fb8304 100644 --- a/src/arch/sparc/vtophys.cc +++ b/src/arch/sparc/vtophys.cc @@ -40,85 +40,93 @@ using namespace std; -namespace SparcISA +namespace SparcISA { + +Addr +vtophys(Addr vaddr) { - Addr vtophys(Addr vaddr) - { - // In SPARC it's almost always impossible to turn a VA->PA w/o a context - // The only times we can kinda do it are if we have a SegKPM mapping - // and can find the real address in the tlb or we have a physical - // adddress already (beacuse we are looking at the hypervisor) - // Either case is rare, so we'll just panic. - - panic("vtophys() without context on SPARC largly worthless\n"); - M5_DUMMY_RETURN - } + // In SPARC it's almost always impossible to turn a VA->PA w/o a + // context The only times we can kinda do it are if we have a + // SegKPM mapping and can find the real address in the tlb or we + // have a physical adddress already (beacuse we are looking at the + // hypervisor) Either case is rare, so we'll just panic. + + panic("vtophys() without context on SPARC largly worthless\n"); + M5_DUMMY_RETURN; +} + +Addr +vtophys(ThreadContext *tc, Addr addr) +{ + // Here we have many options and are really implementing something like + // a fill handler to find the address since there isn't a multilevel + // table for us to walk around. + // + // 1. We are currently hyperpriv, return the address unmodified + // 2. The mmu is off return(ra->pa) + // 3. We are currently priv, use ctx0* tsbs to find the page + // 4. We are not priv, use ctxN0* tsbs to find the page + // For all accesses we check the tlbs first since it's possible that + // long standing pages (e.g. locked kernel mappings) won't be in the tsb + uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA); + + bool hpriv = bits(tlbdata,0,0); + //bool priv = bits(tlbdata,2,2); + bool addr_mask = bits(tlbdata,3,3); + bool data_real = !bits(tlbdata,5,5); + bool inst_real = !bits(tlbdata,4,4); + bool ctx_zero = bits(tlbdata,18,16) > 0; + int part_id = bits(tlbdata,15,8); + int pri_context = bits(tlbdata,47,32); + //int sec_context = bits(tlbdata,63,48); - Addr vtophys(ThreadContext *tc, Addr addr) - { - // Here we have many options and are really implementing something like - // a fill handler to find the address since there isn't a multilevel - // table for us to walk around. - // - // 1. We are currently hyperpriv, return the address unmodified - // 2. The mmu is off return(ra->pa) - // 3. We are currently priv, use ctx0* tsbs to find the page - // 4. We are not priv, use ctxN0* tsbs to find the page - // For all accesses we check the tlbs first since it's possible that - // long standing pages (e.g. locked kernel mappings) won't be in the tsb - uint64_t tlbdata = tc->readMiscRegNoEffect(MISCREG_TLB_DATA); - - bool hpriv = bits(tlbdata,0,0); - //bool priv = bits(tlbdata,2,2); - bool addr_mask = bits(tlbdata,3,3); - bool data_real = !bits(tlbdata,5,5); - bool inst_real = !bits(tlbdata,4,4); - bool ctx_zero = bits(tlbdata,18,16) > 0; - int part_id = bits(tlbdata,15,8); - int pri_context = bits(tlbdata,47,32); - //int sec_context = bits(tlbdata,63,48); - - FunctionalPort *mem = tc->getPhysPort(); - ITB* itb = tc->getITBPtr(); - DTB* dtb = tc->getDTBPtr(); - TlbEntry* tbe; - PageTableEntry pte; - Addr tsbs[4]; - Addr va_tag; - TteTag ttetag; - - if (hpriv) - return addr; - - if (addr_mask) - addr = addr & VAddrAMask; - - tbe = dtb->lookup(addr, part_id, data_real, ctx_zero ? 0 : pri_context , false); - if (tbe) goto foundtbe; - - tbe = itb->lookup(addr, part_id, inst_real, ctx_zero ? 0 : pri_context, false); - if (tbe) goto foundtbe; - - // We didn't find it in the tlbs, so lets look at the TSBs - dtb->GetTsbPtr(tc, addr, ctx_zero ? 0 : pri_context, tsbs); - va_tag = bits(addr, 63, 22); - for (int x = 0; x < 4; x++) { - ttetag = betoh(mem->read<uint64_t>(tsbs[x])); - if (ttetag.valid() && ttetag.va() == va_tag) { - pte.populate(betoh(mem->read<uint64_t>(tsbs[x]) + sizeof(uint64_t)), - PageTableEntry::sun4v); // I think it's sun4v at least! - DPRINTF(VtoPhys, "Virtual(%#x)->Physical(%#x) found in TTE\n", addr, - pte.paddrMask() | addr & pte.sizeMask()); - goto foundpte; - } + FunctionalPort *mem = tc->getPhysPort(); + ITB* itb = tc->getITBPtr(); + DTB* dtb = tc->getDTBPtr(); + TlbEntry* tbe; + PageTableEntry pte; + Addr tsbs[4]; + Addr va_tag; + TteTag ttetag; + + if (hpriv) + return addr; + + if (addr_mask) + addr = addr & VAddrAMask; + + tbe = dtb->lookup(addr, part_id, data_real, ctx_zero ? 0 : pri_context , + false); + if (tbe) + goto foundtbe; + + tbe = itb->lookup(addr, part_id, inst_real, ctx_zero ? 0 : pri_context, + false); + if (tbe) + goto foundtbe; + + // We didn't find it in the tlbs, so lets look at the TSBs + dtb->GetTsbPtr(tc, addr, ctx_zero ? 0 : pri_context, tsbs); + va_tag = bits(addr, 63, 22); + for (int x = 0; x < 4; x++) { + ttetag = betoh(mem->read<uint64_t>(tsbs[x])); + if (ttetag.valid() && ttetag.va() == va_tag) { + uint64_t entry = mem->read<uint64_t>(tsbs[x]) + sizeof(uint64_t); + // I think it's sun4v at least! + pte.populate(betoh(entry), PageTableEntry::sun4v); + DPRINTF(VtoPhys, "Virtual(%#x)->Physical(%#x) found in TTE\n", + addr, pte.translate(addr)); + goto foundpte; } - panic("couldn't translate %#x\n", addr); - -foundtbe: - pte = tbe->pte; - DPRINTF(VtoPhys, "Virtual(%#x)->Physical(%#x) found in TLB\n", addr, - pte.paddrMask() | addr & pte.sizeMask()); -foundpte: - return pte.paddrMask() | addr & pte.sizeMask(); } + panic("couldn't translate %#x\n", addr); + + foundtbe: + pte = tbe->pte; + DPRINTF(VtoPhys, "Virtual(%#x)->Physical(%#x) found in TLB\n", addr, + pte.translate(addr)); + foundpte: + return pte.translate(addr); } + +} /* namespace SparcISA */ |