SPARC: Make software trap 3 flush the register windows like the ABI specifies.

--HG--
extra : convert_revision : 8ff43617b56dcca5783d6cc490f87140fc20a36d
This commit is contained in:
Gabe Black 2007-10-04 12:24:16 -07:00
parent 50e2d20cb8
commit 2848ef6696
4 changed files with 108 additions and 4 deletions

View file

@ -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);
}

View file

@ -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__

View file

@ -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))

View file

@ -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__