summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/sparc/process.cc103
-rw-r--r--src/arch/sparc/process.hh3
-rw-r--r--src/arch/sparc/solaris/process.cc2
-rw-r--r--src/arch/sparc/solaris/process.hh4
4 files changed, 108 insertions, 4 deletions
diff --git a/src/arch/sparc/process.cc b/src/arch/sparc/process.cc
index 29b1a244b..91564e754 100644
--- a/src/arch/sparc/process.cc
+++ b/src/arch/sparc/process.cc
@@ -73,8 +73,39 @@ void SparcLiveProcess::handleTrap(int trapNum, ThreadContext *tc)
{
switch(trapNum)
{
+ case 0x01: //Software breakpoint
+ warn("Software breakpoint encountered at pc %#x.\n", tc->readPC());
+ break;
+ case 0x02: //Division by zero
+ warn("Software signaled a division by zero at pc %#x.\n",
+ tc->readPC());
+ break;
case 0x03: //Flush window trap
- warn("Ignoring request to flush register windows.\n");
+ flushWindows(tc);
+ break;
+ case 0x04: //Clean windows
+ warn("Ignoring process request for clean register "
+ "windows at pc %#x.\n", tc->readPC());
+ break;
+ case 0x05: //Range check
+ warn("Software signaled a range check at pc %#x.\n",
+ tc->readPC());
+ break;
+ case 0x06: //Fix alignment
+ warn("Ignoring process request for os assisted unaligned accesses "
+ "at pc %#x.\n", tc->readPC());
+ break;
+ case 0x07: //Integer overflow
+ warn("Software signaled an integer overflow at pc %#x.\n",
+ tc->readPC());
+ break;
+ case 0x32: //Get integer condition codes
+ warn("Ignoring process request to get the integer condition codes "
+ "at pc %#x.\n", tc->readPC());
+ break;
+ case 0x33: //Set integer condition codes
+ warn("Ignoring process request to set the integer condition codes "
+ "at pc %#x.\n", tc->readPC());
break;
default:
panic("Unimplemented trap to operating system: trap number %#x.\n", trapNum);
@@ -636,3 +667,73 @@ Sparc32LiveProcess::argsInit(int intSize, int pageSize)
// num_processes++;
}
+
+void Sparc32LiveProcess::flushWindows(ThreadContext *tc)
+{
+ IntReg Cansave = tc->readIntReg(NumIntArchRegs + 3);
+ IntReg Canrestore = tc->readIntReg(NumIntArchRegs + 4);
+ IntReg Otherwin = tc->readIntReg(NumIntArchRegs + 6);
+ MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
+ MiscReg origCWP = CWP;
+ CWP = (CWP + Cansave + 2) % NWindows;
+ while(NWindows - 2 - Cansave != 0)
+ {
+ if (Otherwin) {
+ panic("Otherwin non-zero.\n");
+ } else {
+ tc->setMiscReg(MISCREG_CWP, CWP);
+ //Do the stores
+ IntReg sp = tc->readIntReg(StackPointerReg);
+ for (int index = 16; index < 32; index++) {
+ IntReg regVal = tc->readIntReg(index);
+ regVal = htog(regVal);
+ if (!tc->getMemPort()->tryWriteBlob(
+ sp + (index - 16) * 4, (uint8_t *)&regVal, 4)) {
+ warn("Failed to save register to the stack when "
+ "flushing windows.\n");
+ }
+ }
+ Canrestore--;
+ Cansave++;
+ CWP = (CWP + 1) % NWindows;
+ }
+ }
+ tc->setIntReg(NumIntArchRegs + 3, Cansave);
+ tc->setIntReg(NumIntArchRegs + 4, Canrestore);
+ tc->setMiscReg(MISCREG_CWP, origCWP);
+}
+
+void Sparc64LiveProcess::flushWindows(ThreadContext *tc)
+{
+ IntReg Cansave = tc->readIntReg(NumIntArchRegs + 3);
+ IntReg Canrestore = tc->readIntReg(NumIntArchRegs + 4);
+ IntReg Otherwin = tc->readIntReg(NumIntArchRegs + 6);
+ MiscReg CWP = tc->readMiscReg(MISCREG_CWP);
+ MiscReg origCWP = CWP;
+ CWP = (CWP + Cansave + 2) % NWindows;
+ while(NWindows - 2 - Cansave != 0)
+ {
+ if (Otherwin) {
+ panic("Otherwin non-zero.\n");
+ } else {
+ tc->setMiscReg(MISCREG_CWP, CWP);
+ //Do the stores
+ IntReg sp = tc->readIntReg(StackPointerReg);
+ for (int index = 16; index < 32; index++) {
+ IntReg regVal = tc->readIntReg(index);
+ regVal = htog(regVal);
+ if (!tc->getMemPort()->tryWriteBlob(
+ sp + 2047 + (index - 16) * 8, (uint8_t *)&regVal, 8)) {
+ warn("Failed to save register to the stack when "
+ "flushing windows.\n");
+ }
+ }
+ Canrestore--;
+ Cansave++;
+ CWP = (CWP + 1) % NWindows;
+ }
+ }
+ tc->setIntReg(NumIntArchRegs + 3, Cansave);
+ tc->setIntReg(NumIntArchRegs + 4, Canrestore);
+ tc->setMiscReg(MISCREG_CWP, origCWP);
+}
diff --git a/src/arch/sparc/process.hh b/src/arch/sparc/process.hh
index 2512441c6..f4e823a9a 100644
--- a/src/arch/sparc/process.hh
+++ b/src/arch/sparc/process.hh
@@ -66,6 +66,7 @@ class SparcLiveProcess : public LiveProcess
Addr readSpillStart()
{ return spillStart; }
+ virtual void flushWindows(ThreadContext *tc) = 0;
};
struct M5_32_auxv_t
@@ -116,6 +117,7 @@ class Sparc32LiveProcess : public SparcLiveProcess
void argsInit(int intSize, int pageSize);
+ void flushWindows(ThreadContext *tc);
};
struct M5_64_auxv_t
@@ -169,6 +171,7 @@ class Sparc64LiveProcess : public SparcLiveProcess
void argsInit(int intSize, int pageSize);
+ void flushWindows(ThreadContext *tc);
};
#endif // __SPARC_PROCESS_HH__
diff --git a/src/arch/sparc/solaris/process.cc b/src/arch/sparc/solaris/process.cc
index f9876bf00..b7a49ab8d 100644
--- a/src/arch/sparc/solaris/process.cc
+++ b/src/arch/sparc/solaris/process.cc
@@ -336,7 +336,7 @@ SparcSolarisProcess::SparcSolarisProcess(const std::string &name,
uint64_t _egid,
uint64_t _pid,
uint64_t _ppid)
- : SparcLiveProcess(name, objFile, system,
+ : Sparc64LiveProcess(name, objFile, system,
stdin_fd, stdout_fd, stderr_fd, argv, envp, cwd,
_uid, _euid, _gid, _egid, _pid, _ppid),
Num_Syscall_Descs(sizeof(syscallDescs) / sizeof(SyscallDesc))
diff --git a/src/arch/sparc/solaris/process.hh b/src/arch/sparc/solaris/process.hh
index f65a60656..174eaecd7 100644
--- a/src/arch/sparc/solaris/process.hh
+++ b/src/arch/sparc/solaris/process.hh
@@ -38,7 +38,7 @@
namespace SparcISA {
/// A process with emulated SPARC/Solaris syscalls.
-class SparcSolarisProcess : public SparcLiveProcess
+class SparcSolarisProcess : public Sparc64LiveProcess
{
public:
/// Constructor.
@@ -66,4 +66,4 @@ class SparcSolarisProcess : public SparcLiveProcess
} // namespace SparcISA
-#endif // __ALPHA_SOLARIS_PROCESS_HH__
+#endif // __SPARC_SOLARIS_PROCESS_HH__