summaryrefslogtreecommitdiff
path: root/src/kern
diff options
context:
space:
mode:
Diffstat (limited to 'src/kern')
-rw-r--r--src/kern/linux/events.cc25
-rw-r--r--src/kern/linux/events.hh27
2 files changed, 52 insertions, 0 deletions
diff --git a/src/kern/linux/events.cc b/src/kern/linux/events.cc
index 60aa857ac..75c2b6f7f 100644
--- a/src/kern/linux/events.cc
+++ b/src/kern/linux/events.cc
@@ -44,11 +44,13 @@
#include <sstream>
#include "base/trace.hh"
+#include "arch/utility.hh"
#include "cpu/thread_context.hh"
#include "kern/linux/events.hh"
#include "kern/linux/printk.hh"
#include "kern/system_events.hh"
#include "sim/arguments.hh"
+#include "sim/pseudo_inst.hh"
#include "sim/system.hh"
namespace Linux {
@@ -66,4 +68,27 @@ DebugPrintkEvent::process(ThreadContext *tc)
SkipFuncEvent::process(tc);
}
+void
+UDelayEvent::process(ThreadContext *tc)
+{
+ int arg_num = 0;
+
+ // Get the time in native size
+ uint64_t time = TheISA::getArgument(tc, arg_num, (uint16_t)-1, false);
+
+ // convert parameter to ns
+ if (argDivToNs)
+ time /= argDivToNs;
+
+ time *= argMultToNs;
+
+ // Convert ns to ticks
+ time *= SimClock::Int::ns;
+
+ SkipFuncEvent::process(tc);
+
+ PseudoInst::quiesceNs(tc, time);
+}
+
+
} // namespace linux
diff --git a/src/kern/linux/events.hh b/src/kern/linux/events.hh
index e36a72dde..3f5f2526f 100644
--- a/src/kern/linux/events.hh
+++ b/src/kern/linux/events.hh
@@ -44,6 +44,33 @@ class DebugPrintkEvent : public SkipFuncEvent
virtual void process(ThreadContext *xc);
};
+/** A class to skip udelay() and related calls in the kernel.
+ * This class has two additional parameters that take the argument to udelay and
+ * manipulated it to come up with ns and eventually ticks to quiesce for.
+ * See descriptions of argDivToNs and argMultToNs below.
+ */
+class UDelayEvent : public SkipFuncEvent
+{
+ private:
+ /** value to divide arg by to create ns. This is present beacues the linux
+ * kernel code sometime precomputes the first multiply that is done in
+ * udelay() if the parameter is a constant. We need to undo it so here is
+ * how. */
+ uint64_t argDivToNs;
+
+ /** value to multiple arg by to create ns. Nominally, this is 1000 to
+ * convert us to ns, but since linux can do some preprocessing of constant
+ * values something else might be required. */
+ uint64_t argMultToNs;
+
+ public:
+ UDelayEvent(PCEventQueue *q, const std::string &desc, Addr addr,
+ uint64_t mult, uint64_t div)
+ : SkipFuncEvent(q, desc, addr), argDivToNs(div), argMultToNs(mult) {}
+ virtual void process(ThreadContext *xc);
+};
+
+
}
#endif