summaryrefslogtreecommitdiff
path: root/src/arch/arm/faults.cc
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:05 -0500
committerGabe Black <gblack@eecs.umich.edu>2010-06-02 12:58:05 -0500
commit34032f97d6861243a2338d02d6c7d071051c44c5 (patch)
treedb48b07ce2a3ce05273db23c285e7aa34f4052ec /src/arch/arm/faults.cc
parent52460938cbd156c7753deb18e3b2f7ded55335b0 (diff)
downloadgem5-34032f97d6861243a2338d02d6c7d071051c44c5.tar.xz
ARM: Trigger system calls from the SupervisorCall invoke method.
This simplifies the decoder slightly, and makes the system call mechanism very slightly more realistic.
Diffstat (limited to 'src/arch/arm/faults.cc')
-rw-r--r--src/arch/arm/faults.cc21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc
index 9e32a23a3..9b3657909 100644
--- a/src/arch/arm/faults.cc
+++ b/src/arch/arm/faults.cc
@@ -160,6 +160,27 @@ UndefinedInstruction::invoke(ThreadContext *tc)
}
}
+void
+SupervisorCall::invoke(ThreadContext *tc)
+{
+ // As of now, there isn't a 32 bit thumb version of this instruction.
+ assert(!machInst.bigThumb);
+ uint32_t callNum;
+ if (machInst.thumb) {
+ callNum = bits(machInst, 7, 0);
+ } else {
+ callNum = bits(machInst, 23, 0);
+ }
+ if (callNum == 0) {
+ callNum = tc->readIntReg(INTREG_R7);
+ }
+ tc->syscall(callNum);
+
+ // Advance the PC since that won't happen automatically.
+ tc->setPC(tc->readNextPC());
+ tc->setNextPC(tc->readNextNPC());
+}
+
#endif // FULL_SYSTEM
// return via SUBS pc, lr, xxx; rfe, movs, ldm