summaryrefslogtreecommitdiff
path: root/src/sim/init.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/sim/init.cc')
-rw-r--r--src/sim/init.cc81
1 files changed, 80 insertions, 1 deletions
diff --git a/src/sim/init.cc b/src/sim/init.cc
index f2395eec4..33cd4040f 100644
--- a/src/sim/init.cc
+++ b/src/sim/init.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2012, 2017 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -56,6 +56,7 @@
#include "base/misc.hh"
#include "base/types.hh"
#include "config/have_protobuf.hh"
+#include "python/pybind11/pybind.hh"
#include "sim/async.hh"
#include "sim/core.hh"
@@ -65,6 +66,7 @@
#endif
using namespace std;
+namespace py = pybind11;
// The python library is totally messed up with respect to constness,
// so make a simple macro to make life a little easier
@@ -184,10 +186,87 @@ EmbeddedSwig::initAll()
_Py_PackageContext = old_context;
}
+EmbeddedPyBind::EmbeddedPyBind(const char *_name,
+ void (*init_func)(py::module &),
+ const char *_base)
+ : initFunc(init_func), registered(false), name(_name), base(_base)
+{
+ getMap()[_name] = this;
+}
+
+EmbeddedPyBind::EmbeddedPyBind(const char *_name,
+ void (*init_func)(py::module &))
+ : initFunc(init_func), registered(false), name(_name), base("")
+{
+ getMap()[_name] = this;
+}
+
+void
+EmbeddedPyBind::init(py::module &m)
+{
+ if (!registered) {
+ initFunc(m);
+ registered = true;
+ } else {
+ cprintf("Warning: %s already registered.\n", name);
+ }
+}
+
+bool
+EmbeddedPyBind::depsReady() const
+{
+ return base.empty() || getMap()[base]->registered;
+}
+
+std::map<std::string, EmbeddedPyBind *> &
+EmbeddedPyBind::getMap()
+{
+ static std::map<std::string, EmbeddedPyBind *> objs;
+ return objs;
+}
+
+void
+EmbeddedPyBind::initAll()
+{
+ std::list<EmbeddedPyBind *> pending;
+
+ py::module m_m5 = py::module("_m5");
+ m_m5.attr("__package__") = py::cast("_m5");
+
+ pybind_init_core(m_m5);
+ pybind_init_debug(m_m5);
+
+ pybind_init_event(m_m5);
+ pybind_init_pyobject(m_m5);
+ pybind_init_stats(m_m5);
+
+ for (auto &kv : getMap()) {
+ auto &obj = kv.second;
+ if (obj->base.empty()) {
+ obj->init(m_m5);
+ } else {
+ pending.push_back(obj);
+ }
+ }
+
+ while (!pending.empty()) {
+ for (auto it = pending.begin(); it != pending.end(); ) {
+ EmbeddedPyBind &obj = **it;
+ if (obj.depsReady()) {
+ obj.init(m_m5);
+ it = pending.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
+}
+
int
initM5Python()
{
EmbeddedSwig::initAll();
+ EmbeddedPyBind::initAll();
return EmbeddedPython::initAll();
}