summaryrefslogtreecommitdiff
path: root/src/arch/generic/debugfaults.hh
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2019-09-06 17:14:59 -0700
committerGabe Black <gabeblack@google.com>2019-09-18 06:26:35 +0000
commitf3fd7469677ab1f25533d82c36460a700831ceec (patch)
tree4430edd76fd0b6d6a4ae38870d0d8771994f118e /src/arch/generic/debugfaults.hh
parentcd00a363f1dbb8eaf634154c6d5db9ad85278ee0 (diff)
downloadgem5-f3fd7469677ab1f25533d82c36460a700831ceec.tar.xz
arch, x86: Rework the debug faults and microops.
This makes the non-fatal microops advance the PC, and adds missing functions. The *_once Faults now also can be run once per *something*. They would previously be run once per Fault invoke function which is common to all M5WarnOnceFaults. The warn_once microop will now warn once per message. Change-Id: I05974b93f3b2700077a411b243679c2ff0e8c2cb Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20739 Reviewed-by: Gabe Black <gabeblack@google.com> Reviewed-by: Brandon Potter <Brandon.Potter@amd.com> Maintainer: Gabe Black <gabeblack@google.com> Tested-by: kokoro <noreply+kokoro@google.com>
Diffstat (limited to 'src/arch/generic/debugfaults.hh')
-rw-r--r--src/arch/generic/debugfaults.hh153
1 files changed, 100 insertions, 53 deletions
diff --git a/src/arch/generic/debugfaults.hh b/src/arch/generic/debugfaults.hh
index 5c5aa01ea..1c8d882aa 100644
--- a/src/arch/generic/debugfaults.hh
+++ b/src/arch/generic/debugfaults.hh
@@ -50,78 +50,125 @@ namespace GenericISA
class M5DebugFault : public FaultBase
{
- public:
- enum DebugFunc
- {
- PanicFunc,
- FatalFunc,
- WarnFunc,
- WarnOnceFunc
- };
-
protected:
- std::string message;
- DebugFunc func;
+ std::string _message;
+ virtual void debugFunc() = 0;
+ void
+ advancePC(ThreadContext *tc, const StaticInstPtr &inst)
+ {
+ if (inst) {
+ auto pc = tc->pcState();
+ inst->advancePC(pc);
+ tc->pcState(pc);
+ }
+ }
public:
- M5DebugFault(DebugFunc _func, std::string _message) :
- message(_message), func(_func)
+ M5DebugFault(std::string _m) : _message(_m) {}
+
+ template <class ...Args>
+ M5DebugFault(const std::string &format, const Args &...args) :
+ _message(csprintf(format, args...))
{}
- FaultName
- name() const
+ std::string message() { return _message; }
+
+ void
+ invoke(ThreadContext *tc, const StaticInstPtr &inst =
+ StaticInst::nullStaticInstPtr) override
{
- switch (func) {
- case PanicFunc:
- return "panic fault";
- case FatalFunc:
- return "fatal fault";
- case WarnFunc:
- return "warn fault";
- case WarnOnceFunc:
- return "warn_once fault";
- default:
- panic("unrecognized debug function number\n");
- }
+ debugFunc();
+ advancePC(tc, inst);
+ }
+};
+
+// The "Flavor" template parameter is to keep warn, hack or inform messages
+// with the same token from blocking each other.
+template <class Flavor>
+class M5DebugOnceFault : public M5DebugFault
+{
+ protected:
+ bool &once;
+
+ template <class F, class OnceToken>
+ static bool &
+ lookUpToken(const OnceToken &token)
+ {
+ static std::map<OnceToken, bool> tokenMap;
+ return tokenMap[token];
}
+ public:
+ template <class OnceToken, class ...Args>
+ M5DebugOnceFault(const OnceToken &token, const std::string &format,
+ const Args &...args) :
+ M5DebugFault(format, args...), once(lookUpToken<Flavor>(token))
+ {}
+
void
invoke(ThreadContext *tc, const StaticInstPtr &inst =
- StaticInst::nullStaticInstPtr)
+ StaticInst::nullStaticInstPtr) override
{
- switch (func) {
- case PanicFunc:
- panic(message);
- break;
- case FatalFunc:
- fatal(message);
- break;
- case WarnFunc:
- warn(message);
- break;
- case WarnOnceFunc:
- warn_once(message);
- break;
- default:
- panic("unrecognized debug function number\n");
+ if (!once) {
+ once = true;
+ debugFunc();
}
+ advancePC(tc, inst);
}
};
-template <int Func>
-class M5VarArgsFault : public M5DebugFault
+class M5PanicFault : public M5DebugFault
{
public:
- template<typename ...Args>
- M5VarArgsFault(const std::string &format, const Args &...args) :
- M5DebugFault((DebugFunc)Func, csprintf(format, args...))
- {}
+ using M5DebugFault::M5DebugFault;
+ void debugFunc() override { panic(message()); }
+ FaultName name() const override { return "panic fault"; }
+};
+
+class M5FatalFault : public M5DebugFault
+{
+ public:
+ using M5DebugFault::M5DebugFault;
+ void debugFunc() override { fatal(message()); }
+ FaultName name() const override { return "fatal fault"; }
+};
+
+template <class Base>
+class M5WarnFaultBase : public Base
+{
+ public:
+ using Base::Base;
+ void debugFunc() override { warn(this->message()); }
+ FaultName name() const override { return "warn fault"; }
+};
+
+using M5WarnFault = M5WarnFaultBase<M5DebugFault>;
+using M5WarnOnceFault = M5WarnFaultBase<M5DebugOnceFault<M5WarnFault>>;
+
+template <class Base>
+class M5HackFaultBase : public Base
+{
+ public:
+ using Base::Base;
+ void debugFunc() override { hack(this->message()); }
+ FaultName name() const override { return "hack fault"; }
+};
+
+using M5HackFault = M5HackFaultBase<M5DebugFault>;
+using M5HackOnceFault = M5HackFaultBase<M5DebugOnceFault<M5HackFault>>;
+
+template <class Base>
+class M5InformFaultBase : public Base
+{
+ public:
+ using Base::Base;
+ void debugFunc() override { inform(this->message()); }
+ FaultName name() const override { return "inform fault"; }
};
-typedef M5VarArgsFault<M5DebugFault::PanicFunc> M5PanicFault;
-typedef M5VarArgsFault<M5DebugFault::FatalFunc> M5FatalFault;
-typedef M5VarArgsFault<M5DebugFault::WarnFunc> M5WarnFault;
-typedef M5VarArgsFault<M5DebugFault::WarnOnceFunc> M5WarnOnceFault;
+using M5InformFault = M5InformFaultBase<M5DebugFault>;
+using M5InformOnceFault =
+ M5InformFaultBase<M5DebugOnceFault<M5InformFault>>;
} // namespace GenericISA