summaryrefslogtreecommitdiff
path: root/src/arch/sparc
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/sparc')
-rw-r--r--src/arch/sparc/SConscript5
-rw-r--r--src/arch/sparc/SparcInterrupts.py33
-rw-r--r--src/arch/sparc/SparcTLB.py13
-rw-r--r--src/arch/sparc/faults.cc2
-rw-r--r--src/arch/sparc/floatregfile.cc38
-rw-r--r--src/arch/sparc/floatregfile.hh2
-rw-r--r--src/arch/sparc/interrupts.cc37
-rw-r--r--src/arch/sparc/interrupts.hh59
-rw-r--r--src/arch/sparc/intregfile.cc102
-rw-r--r--src/arch/sparc/intregfile.hh44
-rw-r--r--src/arch/sparc/isa/decoder.isa18
-rw-r--r--src/arch/sparc/isa/formats/mem/basicmem.isa10
-rw-r--r--src/arch/sparc/isa/formats/mem/swap.isa3
-rw-r--r--src/arch/sparc/isa/formats/mem/util.isa23
-rw-r--r--src/arch/sparc/isa_traits.hh10
-rw-r--r--src/arch/sparc/linux/linux.cc40
-rw-r--r--src/arch/sparc/linux/linux.hh30
-rw-r--r--src/arch/sparc/linux/process.cc4
-rw-r--r--src/arch/sparc/linux/process.hh1
-rw-r--r--src/arch/sparc/linux/syscalls.cc27
-rw-r--r--src/arch/sparc/microcode_rom.hh (renamed from src/arch/sparc/syscallreturn.hh)37
-rw-r--r--src/arch/sparc/miscregfile.cc57
-rw-r--r--src/arch/sparc/miscregfile.hh64
-rw-r--r--src/arch/sparc/pagetable.hh127
-rw-r--r--src/arch/sparc/process.cc145
-rw-r--r--src/arch/sparc/process.hh27
-rw-r--r--src/arch/sparc/regfile.cc33
-rw-r--r--src/arch/sparc/regfile.hh19
-rw-r--r--src/arch/sparc/remote_gdb.cc28
-rw-r--r--src/arch/sparc/solaris/process.cc10
-rw-r--r--src/arch/sparc/solaris/solaris.cc52
-rw-r--r--src/arch/sparc/solaris/solaris.hh20
-rw-r--r--src/arch/sparc/sparc_traits.hh4
-rw-r--r--src/arch/sparc/stacktrace.cc6
-rw-r--r--src/arch/sparc/stacktrace.hh2
-rw-r--r--src/arch/sparc/tlb.cc165
-rw-r--r--src/arch/sparc/tlb.hh15
-rw-r--r--src/arch/sparc/tlb_map.hh3
-rw-r--r--src/arch/sparc/types.hh8
-rw-r--r--src/arch/sparc/ua2005.cc115
-rw-r--r--src/arch/sparc/utility.cc6
-rw-r--r--src/arch/sparc/vtophys.cc162
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 &section)
+ void
+ unserialize(Checkpoint *cp, const std::string &section)
{
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 &section)
{
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 &section);
-
- 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 &section)
{
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 &section);
-
};
-
-}; // 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 &section)
+void
+RegFile::unserialize(EventManager *em, Checkpoint *cp, const string &section)
{
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 &section);
+ void serialize(EventManager *em, std::ostream &os);
+ void unserialize(EventManager *em, Checkpoint *cp,
+ const std::string &section);
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 */