This scenario utilities file currently implements one function.
This function is the event callback registration function which walks
through all guest devices to find those of a given type then registers
their event callback.

Signed-off-by: Victor CLEMENT <victor.clem...@openwide.fr>
---
 Makefile.objs            |  6 +++++
 include/scenario/utils.h | 23 +++++++++++++++++
 scenario/utils.c         | 65 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 94 insertions(+)
 create mode 100644 include/scenario/utils.h
 create mode 100644 scenario/utils.c

diff --git a/Makefile.objs b/Makefile.objs
index f094eff..3ebb694 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -105,6 +105,12 @@ util-obj-y +=  trace/
 target-obj-y += trace/
 
 ######################################################################
+
+######################################################################
+# scenario
+util-obj-$(CONFIG_SCENARIO) +=  scenario/utils.o
+
+######################################################################
 # guest agent
 
 # FIXME: a few definitions from qapi-types.o/qapi-visit.o are needed
diff --git a/include/scenario/utils.h b/include/scenario/utils.h
new file mode 100644
index 0000000..56066e9
--- /dev/null
+++ b/include/scenario/utils.h
@@ -0,0 +1,23 @@
+#ifndef SCENARIO_UTILS_H
+#define SCENARIO_UTILS_H
+
+/*
+ * Every emulator callback register should implement this prototype in order to
+ * allow the recursive callback registration function to call it
+ */
+typedef void scenario_emulator_cb_register_t \
+            (void *opaque, unsigned int id, void *emulator_cb);
+
+/*
+ * Registers emulator callbacks of every devices of specified type
+ *
+ * type: a string representing the target device emulator type (ex. "pl061")
+ * cb_register: the device emulator scenario API callback register function
+ * emulator_cb: the user implemented callback to register (its prototype should
+ * be predefined in the device emulator API)
+ */
+unsigned int scenario_register_emulator_cb(const char *type,
+        scenario_emulator_cb_register_t *cb_register,
+        void *emulator_cb);
+
+#endif
diff --git a/scenario/utils.c b/scenario/utils.c
new file mode 100644
index 0000000..e64699a
--- /dev/null
+++ b/scenario/utils.c
@@ -0,0 +1,65 @@
+#include "scenario/utils.h"
+#include "hw/qdev-core.h"
+#include "stdio.h"
+
+// #define DEBUG_SCENARIO_UTILS
+
+#ifdef DEBUG_SCENARIO_UTILS
+#define DPRINTF(fmt, ...) \
+    do { printf("scenario: " fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) do {} while (0)
+#endif
+
+/*
+ * Recursively walk through all devices from system bus to find devices
+ * corresponding to name parameter then registers their scenario callbacks
+ *
+ * bus: current bus
+ * name: target device type name
+ * n: current scenario device identifier
+ * cb_register: emulator callaback register function
+ * emulator_cb: emulator callback to set
+ */
+static DeviceState *register_simu_callback_recursive(BusState *bus,
+        const char *name,
+        unsigned int *n,
+        scenario_emulator_cb_register_t *cb_register,
+        void *emulator_cb)
+{
+    BusChild *kid;
+    DeviceState *ret;
+    BusState *child;
+
+    QTAILQ_FOREACH(kid, &bus->children, sibling) {
+        DeviceState *dev = kid->child;
+
+        if (strcmp(object_get_typename(OBJECT(dev)), name) == 0) {
+            (*n)++;
+            DPRINTF("Device %s #%d found\n", name, *n);
+            cb_register(dev, *n, emulator_cb);
+        }
+
+        QLIST_FOREACH(child, &dev->child_bus, sibling) {
+            ret = register_simu_callback_recursive(
+                    child, name, n, cb_register, emulator_cb);
+            if (ret) {
+                return ret;
+            }
+        }
+    }
+    return NULL;
+}
+
+unsigned int scenario_register_emulator_cb(const char *type,
+        scenario_emulator_cb_register_t *cb_register,
+        void *emulator_cb)
+{
+    unsigned int n = 0;
+    register_simu_callback_recursive(sysbus_get_default(), type, &n,
+            cb_register, emulator_cb);
+    if (!n) {
+        printf("scenario: WARNING: no \"%s\" devices found\n", type);
+    }
+    return n;
+}
-- 
2.5.1


Reply via email to