53,54c53,57
< public:
< enum DebugFunc
---
> protected:
> std::string _message;
> virtual void debugFunc() = 0;
> void
> advancePC(ThreadContext *tc, const StaticInstPtr &inst)
56,60c59,64
< PanicFunc,
< FatalFunc,
< WarnFunc,
< WarnOnceFunc
< };
---
> if (inst) {
> auto pc = tc->pcState();
> inst->advancePC(pc);
> tc->pcState(pc);
> }
> }
62,65d65
< protected:
< std::string message;
< DebugFunc func;
<
67,68c67,71
< 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...))
71,72c74,78
< FaultName
< name() const
---
> std::string message() { return _message; }
>
> void
> invoke(ThreadContext *tc, const StaticInstPtr &inst =
> StaticInst::nullStaticInstPtr) override
74,85c80,81
< 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);
86a83
> };
87a85,107
> // 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))
> {}
>
90c110
< StaticInst::nullStaticInstPtr)
---
> StaticInst::nullStaticInstPtr) override
92,106c112,114
< 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();
107a116
> advancePC(tc, inst);
111,112c120
< template <int Func>
< class M5VarArgsFault : public M5DebugFault
---
> class M5PanicFault : public M5DebugFault
115,118c123,125
< 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"; }
121,124c128,134
< typedef M5VarArgsFault<M5DebugFault::PanicFunc> M5PanicFault;
< typedef M5VarArgsFault<M5DebugFault::FatalFunc> M5FatalFault;
< typedef M5VarArgsFault<M5DebugFault::WarnFunc> M5WarnFault;
< typedef M5VarArgsFault<M5DebugFault::WarnOnceFunc> M5WarnOnceFault;
---
> class M5FatalFault : public M5DebugFault
> {
> public:
> using M5DebugFault::M5DebugFault;
> void debugFunc() override { fatal(message()); }
> FaultName name() const override { return "fatal fault"; }
> };
125a136,172
> 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"; }
> };
>
> using M5InformFault = M5InformFaultBase<M5DebugFault>;
> using M5InformOnceFault =
> M5InformFaultBase<M5DebugOnceFault<M5InformFault>>;
>