qemu-arm
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-arm] [RFC v3] qapi: command category to stimulate high-level machi


From: Steffen Görtz
Subject: [Qemu-arm] [RFC v3] qapi: command category to stimulate high-level machine devices
Date: Sun, 3 Jun 2018 16:34:12 -0400

Changes in v2:
  - Remove stray 1

Changes in v1:
  - Fix coding style issues

Add a new category "stimulate" to host commands that
act upon high-level devices associated with machines/boards.

This is patch is part of an effort to add support for BBC:microbit
educational computer to QEMU.

The microbit board, as many other microcontroller boards,
contains typical trivial (digital) input and output options such as buttons and 
LEDs,
but also more sophiscated possibilities such as analog inputs and
complex dedicated sensor ICs that are connected to the microbit machine
by means of inter-ic bus (i2c).
These devices interact with peripheral devices of the microcontroller
in use, for example with the GPIO peripheral of the used NRF51.

One aim of our efforts is to create a user interface that models the
look and feel of the physical microbit board and lets the user interact
with its inputs and provide feedback on its outsputs.

For this it is necessary to transmit user inputs such as the pressing of a
button to the machine.
In return, when the state of an output is changed on the machine, this
change needs to be reflected in the user interface.

At the moment, there are only a few QMP commands that provide user input to the
machine, eg. send-keys, input-button. These commands require very
high-level concepts, which are not really suitable for applications that
microcontrollers are typically used in in.

This RFC is meant to start a discussion on how to provide stimuli to
low-complex inputs and outputs typically found in embedded
microcontroller applications. To the best of my knowledge, there are
currently no examples of how to provide such stimuli to either SoC
device peripheral or machine level concepts like pushbuttons and LEDs.

To my understanding, the following concepts/apis are needed:
- QMP commands to send stimuli to machine level concepts like
pushbuttons
- Machine level devices that receive these stimuli and act as an adapter
to manipulate the associated SoC peripheral devices
- For outputs, machine level devices are needed that observe changes in
SoC peripherals and emit QMP events that clients can receive

This patch adds a new qmp command "buttons-set-state" to update the
push-down state of arbitrarily identified buttons (string identifier).

The handler of this command is mocked to set the machines SoC gpio/irq
lines associated with these buttons on the machine by means of object
property aliases. This is just a mock until a proper concept/api is
agreed upon.

As i recently joined the QEMU community as part of GSoC, i am still a
greenhorn to the codebase and i am really excited to discuss potential
concepts and APIs to realize the described features.

Steffen

Based-on: <address@hidden>
Signed-off-by: Steffen Goertz <address@hidden>
---
 Makefile              |  8 +++++++
 Makefile.objs         |  4 ++++
 Makefile.target       |  1 +
 hw/arm/microbit.c     |  7 ++++++
 qapi/qapi-schema.json |  1 +
 qapi/stimulate.json   | 22 ++++++++++++++++++
 stimulate.c           | 52 +++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 95 insertions(+)
 create mode 100644 qapi/stimulate.json
 create mode 100644 stimulate.c

diff --git a/Makefile b/Makefile
index d71dd5bea4..d9319efa68 100644
--- a/Makefile
+++ b/Makefile
@@ -108,6 +108,7 @@ GENERATED_FILES += qapi/qapi-types-tpm.h 
qapi/qapi-types-tpm.c
 GENERATED_FILES += qapi/qapi-types-trace.h qapi/qapi-types-trace.c
 GENERATED_FILES += qapi/qapi-types-transaction.h qapi/qapi-types-transaction.c
 GENERATED_FILES += qapi/qapi-types-ui.h qapi/qapi-types-ui.c
+GENERATED_FILES += qapi/qapi-types-stimulate.h qapi/qapi-types-stimulate.c
 GENERATED_FILES += qapi/qapi-builtin-visit.h qapi/qapi-builtin-visit.c
 GENERATED_FILES += qapi/qapi-visit.h qapi/qapi-visit.c
 GENERATED_FILES += qapi/qapi-visit-block-core.h qapi/qapi-visit-block-core.c
@@ -126,6 +127,7 @@ GENERATED_FILES += qapi/qapi-visit-tpm.h 
qapi/qapi-visit-tpm.c
 GENERATED_FILES += qapi/qapi-visit-trace.h qapi/qapi-visit-trace.c
 GENERATED_FILES += qapi/qapi-visit-transaction.h qapi/qapi-visit-transaction.c
 GENERATED_FILES += qapi/qapi-visit-ui.h qapi/qapi-visit-ui.c
+GENERATED_FILES += qapi/qapi-visit-stimulate.h qapi/qapi-visit-stimulate.c
 GENERATED_FILES += qapi/qapi-commands.h qapi/qapi-commands.c
 GENERATED_FILES += qapi/qapi-commands-block-core.h 
qapi/qapi-commands-block-core.c
 GENERATED_FILES += qapi/qapi-commands-block.h qapi/qapi-commands-block.c
@@ -143,6 +145,7 @@ GENERATED_FILES += qapi/qapi-commands-tpm.h 
qapi/qapi-commands-tpm.c
 GENERATED_FILES += qapi/qapi-commands-trace.h qapi/qapi-commands-trace.c
 GENERATED_FILES += qapi/qapi-commands-transaction.h 
qapi/qapi-commands-transaction.c
 GENERATED_FILES += qapi/qapi-commands-ui.h qapi/qapi-commands-ui.c
+GENERATED_FILES += qapi/qapi-commands-stimulate.h 
qapi/qapi-commands-stimulate.c
 GENERATED_FILES += qapi/qapi-events.h qapi/qapi-events.c
 GENERATED_FILES += qapi/qapi-events-block-core.h qapi/qapi-events-block-core.c
 GENERATED_FILES += qapi/qapi-events-block.h qapi/qapi-events-block.c
@@ -160,6 +163,7 @@ GENERATED_FILES += qapi/qapi-events-tpm.h 
qapi/qapi-events-tpm.c
 GENERATED_FILES += qapi/qapi-events-trace.h qapi/qapi-events-trace.c
 GENERATED_FILES += qapi/qapi-events-transaction.h 
qapi/qapi-events-transaction.c
 GENERATED_FILES += qapi/qapi-events-ui.h qapi/qapi-events-ui.c
+GENERATED_FILES += qapi/qapi-events-stimulate.h qapi/qapi-events-stimulate.c
 GENERATED_FILES += qapi/qapi-introspect.c qapi/qapi-introspect.h
 GENERATED_FILES += qapi/qapi-doc.texi
 
@@ -611,6 +615,7 @@ qapi/qapi-types-tpm.c qapi/qapi-types-tpm.h \
 qapi/qapi-types-trace.c qapi/qapi-types-trace.h \
 qapi/qapi-types-transaction.c qapi/qapi-types-transaction.h \
 qapi/qapi-types-ui.c qapi/qapi-types-ui.h \
+qapi/qapi-types-stimulate.c qapi/qapi-types-stimulate.h \
 qapi/qapi-builtin-visit.c qapi/qapi-builtin-visit.h \
 qapi/qapi-visit.c qapi/qapi-visit.h \
 qapi/qapi-visit-block-core.c qapi/qapi-visit-block-core.h \
@@ -629,6 +634,7 @@ qapi/qapi-visit-tpm.c qapi/qapi-visit-tpm.h \
 qapi/qapi-visit-trace.c qapi/qapi-visit-trace.h \
 qapi/qapi-visit-transaction.c qapi/qapi-visit-transaction.h \
 qapi/qapi-visit-ui.c qapi/qapi-visit-ui.h \
+qapi/qapi-visit-stimulate.c qapi/qapi-visit-stimulate.h \
 qapi/qapi-commands.h qapi/qapi-commands.c \
 qapi/qapi-commands-block-core.c qapi/qapi-commands-block-core.h \
 qapi/qapi-commands-block.c qapi/qapi-commands-block.h \
@@ -646,6 +652,7 @@ qapi/qapi-commands-tpm.c qapi/qapi-commands-tpm.h \
 qapi/qapi-commands-trace.c qapi/qapi-commands-trace.h \
 qapi/qapi-commands-transaction.c qapi/qapi-commands-transaction.h \
 qapi/qapi-commands-ui.c qapi/qapi-commands-ui.h \
+qapi/qapi-commands-stimulate.c qapi/qapi-commands-stimulate.h \
 qapi/qapi-events.c qapi/qapi-events.h \
 qapi/qapi-events-block-core.c qapi/qapi-events-block-core.h \
 qapi/qapi-events-block.c qapi/qapi-events-block.h \
@@ -663,6 +670,7 @@ qapi/qapi-events-tpm.c qapi/qapi-events-tpm.h \
 qapi/qapi-events-trace.c qapi/qapi-events-trace.h \
 qapi/qapi-events-transaction.c qapi/qapi-events-transaction.h \
 qapi/qapi-events-ui.c qapi/qapi-events-ui.h \
+qapi/qapi-events-stimulate.c qapi/qapi-events-stimulate.h \
 qapi/qapi-introspect.h qapi/qapi-introspect.c \
 qapi/qapi-doc.texi: \
 qapi-gen-timestamp ;
diff --git a/Makefile.objs b/Makefile.objs
index c6c9b8fc21..c6806ed83c 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -20,6 +20,7 @@ util-obj-y += qapi/qapi-types-tpm.o
 util-obj-y += qapi/qapi-types-trace.o
 util-obj-y += qapi/qapi-types-transaction.o
 util-obj-y += qapi/qapi-types-ui.o
+util-obj-y += qapi/qapi-types-stimulate.o
 util-obj-y += qapi/qapi-builtin-visit.o
 util-obj-y += qapi/qapi-visit.o
 util-obj-y += qapi/qapi-visit-block-core.o
@@ -38,6 +39,7 @@ util-obj-y += qapi/qapi-visit-tpm.o
 util-obj-y += qapi/qapi-visit-trace.o
 util-obj-y += qapi/qapi-visit-transaction.o
 util-obj-y += qapi/qapi-visit-ui.o
+util-obj-y += qapi/qapi-visit-stimulate.o
 util-obj-y += qapi/qapi-events.o
 util-obj-y += qapi/qapi-events-block-core.o
 util-obj-y += qapi/qapi-events-block.o
@@ -55,6 +57,7 @@ util-obj-y += qapi/qapi-events-tpm.o
 util-obj-y += qapi/qapi-events-trace.o
 util-obj-y += qapi/qapi-events-transaction.o
 util-obj-y += qapi/qapi-events-ui.o
+util-obj-y += qapi/qapi-events-stimulate.o
 util-obj-y += qapi/qapi-introspect.o
 
 chardev-obj-y = chardev/
@@ -150,6 +153,7 @@ common-obj-y += qapi/qapi-commands-tpm.o
 common-obj-y += qapi/qapi-commands-trace.o
 common-obj-y += qapi/qapi-commands-transaction.o
 common-obj-y += qapi/qapi-commands-ui.o
+common-obj-y += qapi/qapi-commands-stimulate.o
 common-obj-y += qapi/qapi-introspect.o
 common-obj-y += qmp.o hmp.o
 endif
diff --git a/Makefile.target b/Makefile.target
index d0ec77a307..6ecd09321a 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -139,6 +139,7 @@ obj-y += memory.o
 obj-y += memory_mapping.o
 obj-y += dump.o
 obj-y += migration/ram.o
+obj-y += stimulate.o
 LIBS := $(libs_softmmu) $(LIBS)
 
 # Hardware support
diff --git a/hw/arm/microbit.c b/hw/arm/microbit.c
index b61d0747fe..a3188d83d8 100644
--- a/hw/arm/microbit.c
+++ b/hw/arm/microbit.c
@@ -16,12 +16,19 @@
 static void microbit_init(MachineState *machine)
 {
     DeviceState *dev;
+    NRF51State *soc;
 
     dev = qdev_create(NULL, TYPE_NRF51_SOC);
     if (machine->kernel_filename) {
         qdev_prop_set_string(dev, "kernel-filename", machine->kernel_filename);
     }
     object_property_set_bool(OBJECT(dev), true, "realized", &error_fatal);
+
+    soc = NRF51_SOC(dev);
+    object_property_add_alias(OBJECT(machine), "button-a", OBJECT(soc->nvic),
+            "unnamed-gpio-in[17]", &error_fatal);
+    object_property_add_alias(OBJECT(machine), "button-b", OBJECT(soc->nvic),
+            "unnamed-gpio-in[26]", &error_fatal);
 }
 
 static void microbit_machine_init(MachineClass *mc)
diff --git a/qapi/qapi-schema.json b/qapi/qapi-schema.json
index 25bce78352..0f506ca6f1 100644
--- a/qapi/qapi-schema.json
+++ b/qapi/qapi-schema.json
@@ -93,3 +93,4 @@
 { 'include': 'trace.json' }
 { 'include': 'introspect.json' }
 { 'include': 'misc.json' }
+{ 'include': 'stimulate.json' }
diff --git a/qapi/stimulate.json b/qapi/stimulate.json
new file mode 100644
index 0000000000..5718aafedd
--- /dev/null
+++ b/qapi/stimulate.json
@@ -0,0 +1,22 @@
+##
+# @ButtonPress:
+#
+# @identifier:  Name of the button.
+# @pushed_down: State of the button.
+#
+##
+{ 'struct': 'ButtonPress',
+  'data': {
+    'identifier': 'str',
+    'pushed_down': 'bool'
+     } }
+
+##
+# @buttons-set-state:
+#
+# @buttons: List of updated button states.
+#
+# Returns: nothing in case of success
+##
+{ 'command': 'buttons-set-state',
+  'data': { 'buttons': ['ButtonPress'] } }
diff --git a/stimulate.c b/stimulate.c
new file mode 100644
index 0000000000..fce33ee064
--- /dev/null
+++ b/stimulate.c
@@ -0,0 +1,52 @@
+/*
+ * stimulate.c
+ *
+ * Copyright (C) 2018 Steffen Görtz <address@hidden>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/log.h"
+#include "qom/object.h"
+#include "hw/qdev-core.h"
+#include "hw/boards.h"
+#include "qapi/error.h"
+#include "qapi/qapi-commands-stimulate.h"
+
+#ifndef DEBUG_STIMULATE
+#define DEBUG_STIMULATE 0
+#endif
+
+#define DPRINTF(fmt, ...)                                            \
+
+void qmp_buttons_set_state(ButtonPressList *buttons, Error **errp)
+{
+    for (; buttons; buttons = buttons->next) {
+        if (buttons->value) {
+            DPRINTF("Set button %s to %s", buttons->value->identifier,
+                    buttons->value->pushed_down ? "true" : "false");
+
+            gchar *name = g_strdup_printf("button-%s",
+                    buttons->value->identifier);
+            Object *child = object_resolve_path_component(
+                    OBJECT(current_machine), name);
+
+            if (!child) {
+                error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+                        "GPIO '%s' doesn't exists", name);
+                g_free(name);
+                return;
+
+            } else {
+                g_free(name);
+                qemu_set_irq(OBJECT_CHECK(struct IRQState, (child), TYPE_IRQ),
+                        buttons->value->pushed_down);
+
+            }
+        }
+    }
+}
-- 
2.17.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]