ARM: Trigger system calls from the SupervisorCall invoke method.
This simplifies the decoder slightly, and makes the system call mechanism very slightly more realistic.
This commit is contained in:
parent
52460938cb
commit
34032f97d6
|
@ -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
|
#endif // FULL_SYSTEM
|
||||||
|
|
||||||
// return via SUBS pc, lr, xxx; rfe, movs, ldm
|
// return via SUBS pc, lr, xxx; rfe, movs, ldm
|
||||||
|
|
|
@ -125,7 +125,19 @@ class UndefinedInstruction : public ArmFault<UndefinedInstruction>
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
class SupervisorCall : public ArmFault<SupervisorCall> {};
|
class SupervisorCall : public ArmFault<SupervisorCall>
|
||||||
|
{
|
||||||
|
#if !FULL_SYSTEM
|
||||||
|
protected:
|
||||||
|
ExtMachInst machInst;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SupervisorCall(ExtMachInst _machInst) : machInst(_machInst)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void invoke(ThreadContext *tc);
|
||||||
|
#endif
|
||||||
|
};
|
||||||
class PrefetchAbort : public ArmFault<PrefetchAbort> {};
|
class PrefetchAbort : public ArmFault<PrefetchAbort> {};
|
||||||
class DataAbort : public ArmFault<DataAbort> {};
|
class DataAbort : public ArmFault<DataAbort> {};
|
||||||
class Interrupt : public ArmFault<Interrupt> {};
|
class Interrupt : public ArmFault<Interrupt> {};
|
||||||
|
|
|
@ -286,18 +286,13 @@ format DataOp {
|
||||||
} // CPNUM (OP4 == 1)
|
} // CPNUM (OP4 == 1)
|
||||||
} //OPCODE_4
|
} //OPCODE_4
|
||||||
|
|
||||||
|
1: PredOp::swi({{
|
||||||
#if FULL_SYSTEM
|
#if FULL_SYSTEM
|
||||||
1: PredOp::swi({{ fault = new SupervisorCall; }}, IsSerializeAfter, IsNonSpeculative, IsSyscall);
|
fault = new SupervisorCall();
|
||||||
#else
|
#else
|
||||||
1: PredOp::swi({{ if (testPredicate(CondCodes, condCode))
|
fault = new SupervisorCall(machInst);
|
||||||
{
|
#endif
|
||||||
if (IMMED_23_0)
|
}}, IsSyscall);
|
||||||
xc->syscall(IMMED_23_0);
|
|
||||||
else
|
|
||||||
xc->syscall(R7);
|
|
||||||
}
|
|
||||||
}});
|
|
||||||
#endif // FULL_SYSTEM
|
|
||||||
} // OPCODE_24
|
} // OPCODE_24
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue