All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC v3 0/6] SDM Interface
@ 2016-06-17 15:54 Christian Pinto
  2016-06-17 15:54 ` [Qemu-devel] [RFC v3 1/6] hw/misc: sdm interface Christian Pinto
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: Christian Pinto @ 2016-06-17 15:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: b.reynal, tech, Claudio.Fontana, Jani.Kokkonen, Christian Pinto

This patch series introduces a new device to QEMU, the SDM (Signal Distribution 
Module),
intended to route inter-processor signals intra and inter QEMU instances.

To be as modular as possible, the device is split between the interface
(virtio/platform) and the communication channel (local/socket).

A platform interface has been implemented to allow non-linux operating
system (FreeRTOS for example) to use the SDM.

Also, various signals can be defined with hardware operations.

Those signals can be used, for example, to route interrupts or to
trigger the boot of another QEMU instance.

When a signal is received on a SDM, it will check if the signal
ID is associate to a hardware action that will be executed if found.
The hardware action allows the signal to perform some actions (e.g
triggering boot) before being forwarded to the operating system.

You can test thoses patches using modules and test application
available on https://git.virtualopensystems.com/dev/qemu-het-tools :

- Platform module on branch sdm_test_mod_v1
- Virtio module on branch sdm-dev-v3
- Test application on branch sdm_test_app

QEMU code is avalaible here on git@git.virtualopensystems.com:dev/qemu-het.git
branch sdm-dev-v3.


Run QEMU instance:
./qemu-system-arm -nographic \
        -kernel zImage \
        -M virt -m 512M \
        -initrd busybox.cpio \
        -object sdm-communication-local,id=localcomm \
        -object sdm-signal,id=interrupt \
        -device sdm-platform,comm=localcomm,master,num-slaves=1,len-signals=1,signals[0]="interrupt" \
        -device sdm-platform,comm=localcomm,len-signals=1,len-signals=1,signals[0]="interrupt"

After loading the corresponding module (insmod sdm_test_mod.ko), you can send 
signal
accross instances using the sdm-test application:
./sdm-test -s 0 0 0x0 0x0 0x0

This patch series is a follow-up of "[Qemu-devel] [RFC v2 0/6]
SDM Interface":
https://lists.gnu.org/archive/html/qemu-devel/2016-03/msg04492.html

This work has been sponsored by Huawei Technologies Duesseldorf GmbH.

---
Changes since v2: 
- added virtio device configuration space
- added configuration accessory methods
- fixed bug in local communication channel
- aligned virto device ID with specification RFC
---

Baptiste Reynal (6):
  hw/misc: sdm interface
  hw/misc: sdm platform device
  hw/arm: sysbus-fdt
  hw/misc: sdm virtio device
  hw/misc: sdm communication local
  hw/misc: sdm communication socket

 default-configs/arm-softmmu.mak            |   1 +
 hw/arm/sysbus-fdt.c                        |  62 ++++++
 hw/misc/Makefile.objs                      |   7 +
 hw/misc/sdm-communication-local.c          | 116 +++++++++++
 hw/misc/sdm-communication-socket.c         | 160 +++++++++++++++
 hw/misc/sdm-communication.c                |  68 +++++++
 hw/misc/sdm-device.c                       |  78 ++++++++
 hw/misc/sdm-platform.c                     | 231 ++++++++++++++++++++++
 hw/misc/sdm-signal.c                       |  52 +++++
 hw/virtio/Makefile.objs                    |   1 +
 hw/virtio/virtio-sdm.c                     | 303 +++++++++++++++++++++++++++++
 include/hw/misc/sdm-communication-local.h  |  35 ++++
 include/hw/misc/sdm-communication-socket.h |  42 ++++
 include/hw/misc/sdm-communication.h        |  60 ++++++
 include/hw/misc/sdm-device.h               |  61 ++++++
 include/hw/misc/sdm-platform.h             |  65 +++++++
 include/hw/misc/sdm-signal.h               |  61 ++++++
 include/hw/virtio/virtio-sdm.h             |  58 ++++++
 linux-headers/linux/virtio_sdm.h           |  58 ++++++
 19 files changed, 1519 insertions(+)
 create mode 100644 hw/misc/sdm-communication-local.c
 create mode 100644 hw/misc/sdm-communication-socket.c
 create mode 100644 hw/misc/sdm-communication.c
 create mode 100644 hw/misc/sdm-device.c
 create mode 100644 hw/misc/sdm-platform.c
 create mode 100644 hw/misc/sdm-signal.c
 create mode 100644 hw/virtio/virtio-sdm.c
 create mode 100644 include/hw/misc/sdm-communication-local.h
 create mode 100644 include/hw/misc/sdm-communication-socket.h
 create mode 100644 include/hw/misc/sdm-communication.h
 create mode 100644 include/hw/misc/sdm-device.h
 create mode 100644 include/hw/misc/sdm-platform.h
 create mode 100644 include/hw/misc/sdm-signal.h
 create mode 100644 include/hw/virtio/virtio-sdm.h
 create mode 100644 linux-headers/linux/virtio_sdm.h

-- 
1.9.1

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Qemu-devel] [RFC v3 1/6] hw/misc: sdm interface
  2016-06-17 15:54 [Qemu-devel] [RFC v3 0/6] SDM Interface Christian Pinto
@ 2016-06-17 15:54 ` Christian Pinto
  2016-06-17 15:54 ` [Qemu-devel] [RFC v3 2/6] hw/misc: sdm platform device Christian Pinto
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Christian Pinto @ 2016-06-17 15:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: b.reynal, tech, Claudio.Fontana, Jani.Kokkonen, Christian Pinto

From: Baptiste Reynal <b.reynal@virtualopensystems.com>

This patch forms the common skeleton code for the SDM interface.

The SDMDevice represents the interface with the machine, the
SDMCommunication the communication channel and the SDMSignal
represents an action to perform when a signal is received
(for example to boot the machine).

Signed-off-by: Baptiste Reynal <b.reynal@virtualopensystems.com>
Signed-off-by: Christian Pinto <c.pinto@virtualopensystems.com>

---
v2 -> v3:
- Added sdm_device_set_num_slaves function to sdm-device class
- Added sdm_communication_update_num_slaves to sdm-communication class
---
---
 default-configs/arm-softmmu.mak     |  1 +
 hw/misc/Makefile.objs               |  4 ++
 hw/misc/sdm-communication.c         | 68 ++++++++++++++++++++++++++++++++
 hw/misc/sdm-device.c                | 78 +++++++++++++++++++++++++++++++++++++
 hw/misc/sdm-signal.c                | 51 ++++++++++++++++++++++++
 include/hw/misc/sdm-communication.h | 60 ++++++++++++++++++++++++++++
 include/hw/misc/sdm-device.h        | 61 +++++++++++++++++++++++++++++
 include/hw/misc/sdm-signal.h        | 60 ++++++++++++++++++++++++++++
 8 files changed, 383 insertions(+)
 create mode 100644 hw/misc/sdm-communication.c
 create mode 100644 hw/misc/sdm-device.c
 create mode 100644 hw/misc/sdm-signal.c
 create mode 100644 include/hw/misc/sdm-communication.h
 create mode 100644 include/hw/misc/sdm-device.h
 create mode 100644 include/hw/misc/sdm-signal.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index d9b90a5..4002e2b 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -109,3 +109,4 @@ CONFIG_IOH3420=y
 CONFIG_I82801B11=y
 CONFIG_ACPI=y
 CONFIG_SMBIOS=y
+CONFIG_SDM=y
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 4aa76ff..ce2aa89 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -21,6 +21,10 @@ common-obj-$(CONFIG_MACIO) += macio/
 
 obj-$(CONFIG_IVSHMEM) += ivshmem.o
 
+obj-$(CONFIG_SDM) += sdm-device.o 
+obj-$(CONFIG_SDM) += sdm-communication.o
+obj-$(CONFIG_SDM) += sdm-signal.o
+
 obj-$(CONFIG_REALVIEW) += arm_sysctl.o
 obj-$(CONFIG_NSERIES) += cbus.o
 obj-$(CONFIG_ECCMEMCTL) += eccmemctl.o
diff --git a/hw/misc/sdm-communication.c b/hw/misc/sdm-communication.c
new file mode 100644
index 0000000..a85fe35
--- /dev/null
+++ b/hw/misc/sdm-communication.c
@@ -0,0 +1,68 @@
+/*
+ * SDM Communication
+ *
+ * Copyright (C) 2016 - Virtual Open Systems
+ *
+ * Author: Baptiste Reynal <b.reynal@virtualopensystems.com>
+ *	   Christian Pinto <c.pinto@virtualopensystems.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+
+#include "hw/misc/sdm-communication.h"
+#include "qom/object_interfaces.h"
+
+int sdm_communication_signal(SDMCommunication *sdmc, SDMDevice *sdm,
+        SDMSignalData *signal)
+{
+    SDMCommunicationClass *sdmck = SDM_COMMUNICATION_GET_CLASS(sdmc);
+
+    if (sdmck->signal) {
+        return sdmck->signal(sdmc, sdm, signal);
+    } else {
+        return -1;
+    }
+}
+
+int sdm_communication_connect(SDMCommunication *sdmc, SDMDevice *sdm)
+{
+    SDMCommunicationClass *sdmck = SDM_COMMUNICATION_GET_CLASS(sdmc);
+
+    if (sdmck->connect) {
+        return sdmck->connect(sdmc, sdm);
+    } else {
+        return -1;
+    }
+}
+
+int sdm_communication_update_num_slaves(SDMCommunication *sdmc, SDMDevice *sdm,
+            uint16_t num_slaves)
+{
+    SDMCommunicationClass *sdmck = SDM_COMMUNICATION_GET_CLASS(sdmc);
+
+    if (sdmck->update_num_slaves) {
+        return sdmck->update_num_slaves(sdmc, sdm, num_slaves);
+    } else {
+        return -1;
+    }
+}
+
+static const TypeInfo sdm_communication_info = {
+    .name = TYPE_SDM_COMMUNICATION,
+    .parent = TYPE_OBJECT,
+    .abstract = true,
+    .class_size = sizeof(SDMCommunicationClass),
+    .instance_size = sizeof(SDMCommunication),
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_USER_CREATABLE },
+        { }
+    }
+};
+
+static void register_types(void)
+{
+    type_register_static(&sdm_communication_info);
+}
+
+type_init(register_types);
diff --git a/hw/misc/sdm-device.c b/hw/misc/sdm-device.c
new file mode 100644
index 0000000..01e0cbc
--- /dev/null
+++ b/hw/misc/sdm-device.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 - Virtual Open Systems
+ *
+ * Author: Baptiste Reynal <b.reynal@virtualopensystems.com>
+ * 	   Christian Pinto <c.pinto@virtualopensystems.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+#include "hw/misc/sdm-device.h"
+
+int sdm_device_notify(SDMDevice *sdm, SDMSignalData *signal)
+{
+    SDMDeviceClass *sdmc = SDM_DEVICE_GET_CLASS(sdm);
+
+    if (sdmc->notify) {
+        return sdmc->notify(sdm, signal);
+    } else {
+        return -1;
+    }
+}
+
+int sdm_device_accept(SDMDevice *sdm)
+{
+    SDMDeviceClass *sdmc = SDM_DEVICE_GET_CLASS(sdm);
+
+    if (sdmc->accept) {
+        return sdmc->accept(sdm);
+    } else {
+        return -1;
+    }
+}
+
+int sdm_device_get_num_slaves(SDMDevice *sdm)
+{
+    SDMDeviceClass *sdmc = SDM_DEVICE_GET_CLASS(sdm);
+
+    if (sdmc->get_num_slaves) {
+        return sdmc->get_num_slaves(sdm);
+    } else {
+        return 0;
+    }
+}
+
+int sdm_device_set_num_slaves(SDMDevice *sdm, uint16_t num_slaves)
+{
+    SDMDeviceClass *sdmc = SDM_DEVICE_GET_CLASS(sdm);
+
+    if (sdmc->set_num_slaves) {
+        return sdmc->set_num_slaves(sdm, num_slaves);
+    } else {
+        return 0;
+    }
+}
+
+bool sdm_device_is_master(SDMDevice *sdm)
+{
+    SDMDeviceClass *sdmc = SDM_DEVICE_GET_CLASS(sdm);
+
+    if (sdmc->is_master) {
+        return sdmc->is_master(sdm);
+    } else {
+        return false;
+    }
+}
+
+static void register_types(void)
+{
+    static const TypeInfo sdm_device_info = {
+        .name		= TYPE_SDM_DEVICE,
+        .parent		= TYPE_INTERFACE,
+        .class_size	= sizeof(SDMDeviceClass),
+    };
+
+    type_register_static(&sdm_device_info);
+}
+
+type_init(register_types)
diff --git a/hw/misc/sdm-signal.c b/hw/misc/sdm-signal.c
new file mode 100644
index 0000000..c4af0ac
--- /dev/null
+++ b/hw/misc/sdm-signal.c
@@ -0,0 +1,51 @@
+/*
+ * SDM Signal
+ *
+ * Copyright (C) 2016 - Virtual Open Systems
+ *
+ * Author: Baptiste Reynal <b.reynal@virtualopensystems.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+#include "hw/misc/sdm-signal.h"
+#include "qom/object_interfaces.h"
+
+int sdm_signal_hw_ops(SDMSignal *signal, SDMSignalData *data) {
+    SDMSignalClass *signalc = SDM_SIGNAL_GET_CLASS(signal);
+
+    if (signalc->hw_ops) {
+        return signalc->hw_ops(signal, data);
+    } else {
+        return 0;
+    }
+}
+
+bool sdm_signal_hw_only(SDMSignal *signal)
+{
+    SDMSignalClass *signalc = SDM_SIGNAL_GET_CLASS(signal);
+
+    if (signalc->hw_only) {
+        return signalc->hw_only(signal);
+    } else {
+        return false;
+    }
+}
+
+static const TypeInfo sdm_signal_info = {
+    .name = TYPE_SDM_SIGNAL,
+    .parent = TYPE_OBJECT,
+    .class_size = sizeof(SDMSignalClass),
+    .instance_size = sizeof(SDMSignal),
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_USER_CREATABLE },
+        { }
+    }
+};
+
+static void register_types(void)
+{
+    type_register_static(&sdm_signal_info);
+}
+
+type_init(register_types);
diff --git a/include/hw/misc/sdm-communication.h b/include/hw/misc/sdm-communication.h
new file mode 100644
index 0000000..e9b04a4
--- /dev/null
+++ b/include/hw/misc/sdm-communication.h
@@ -0,0 +1,60 @@
+/*
+ * SDM Communication
+ *
+ * Copyright (C) 2016 - Virtual Open Systems
+ *
+ * Author: Baptiste Reynal <b.reynal@virtualopensystems.com>
+ *	   Christian Pinto <c.pinto@virtualopensystems.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+#ifndef HW_SDM_COMM_H
+#define HW_SDM_COMM_H
+
+#include "hw/misc/sdm-device.h"
+
+#define TYPE_SDM_COMMUNICATION "sdm-communication"
+#define SDM_COMMUNICATION(obj) \
+    OBJECT_CHECK(SDMCommunication, (obj), TYPE_SDM_COMMUNICATION)
+#define SDM_COMMUNICATION_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(SDMCommunicationClass, (obj), TYPE_SDM_COMMUNICATION)
+#define SDM_COMMUNICATION_CLASS(klass) \
+    OBJECT_CLASS_CHECK(SDMCommunicationClass, (klass), \
+            TYPE_SDM_COMMUNICATION);
+
+typedef struct SDMCommunication SDMCommunication;
+typedef struct SDMCommunicationClass SDMCommunicationClass;
+
+/**
+ * @SDMCommunicationClass
+ *
+ * @parent_class: opaque parent class container
+ */
+struct SDMCommunicationClass {
+    ObjectClass parent_class;
+
+    int (*signal)(SDMCommunication *sdmc, SDMDevice *sdm,
+            SDMSignalData *signal);
+    int (*connect)(SDMCommunication *sdmc, SDMDevice *sdm);
+    int (*update_num_slaves)(SDMCommunication *sdmc, SDMDevice *sdm,
+                uint16_t num_slaves);
+};
+
+/**
+ * @SDMCommunication
+ *
+ * @parent: opaque parent object container
+ */
+struct SDMCommunication {
+    /* private */
+    Object parent;
+};
+
+int sdm_communication_signal(SDMCommunication *sdmc, SDMDevice *sdm,
+        SDMSignalData *signal);
+int sdm_communication_connect(SDMCommunication *sdmc, SDMDevice *sdm);
+int sdm_communication_update_num_slaves(SDMCommunication *sdmc,
+        SDMDevice *sdm, uint16_t num_slaves);
+
+#endif
diff --git a/include/hw/misc/sdm-device.h b/include/hw/misc/sdm-device.h
new file mode 100644
index 0000000..a0aca28
--- /dev/null
+++ b/include/hw/misc/sdm-device.h
@@ -0,0 +1,61 @@
+/*
+ * SDM Device
+ *
+ * Copyright (C) 2016 - Virtual Open Systems
+ *
+ * Author: Baptiste Reynal <b.reynal@virtualopensystems.com>
+ *	   Christian Pinto <c.pinto@virtualopensystems.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+#ifndef HW_SDM_H
+#define HW_SDM_H
+
+#include "qemu-common.h"
+#include "qom/object.h"
+#include "hw/misc/sdm-signal.h"
+
+#define TYPE_SDM_DEVICE "sdm-device"
+#define SDM_DEVICE_CLASS(klass) \
+    OBJECT_CLASS_CHECK(SDMDeviceClass, (klass), TYPE_SDM_DEVICE);
+#define SDM_DEVICE_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(SDMDeviceClass, (obj), TYPE_SDM_DEVICE)
+#define SDM_DEVICE(obj) \
+    INTERFACE_CHECK(SDMDevice, (obj), TYPE_SDM_DEVICE)
+
+typedef struct SDMDevice SDMDevice;
+typedef struct SDMDeviceClass SDMDeviceClass;
+
+/**
+ * SDMDeviceClass
+ *
+ * @parent_class: opaque parent class container
+ */
+struct SDMDeviceClass {
+    InterfaceClass parent_class;
+
+    int (**signal_hw_ops)(SDMDevice *sdm, SDMSignalData *signal);
+
+    /* Notify the device about a new signal. If the signal cannot
+     * be handled by device (busy), returns -1. The communication
+     * channel should then try to deliver the signal again later.
+     */
+    int (*notify)(SDMDevice *sdm, SDMSignalData *signal);
+    int (*accept)(SDMDevice *sdm);
+    int (*get_num_slaves)(SDMDevice *sdm);
+    int (*set_num_slaves)(SDMDevice *sdm, uint16_t num_slaves);
+    bool (*is_master)(SDMDevice *sdm);
+};
+
+struct SDMDevice {
+    /* private */
+    Object parent;
+};
+
+int sdm_device_notify(SDMDevice *sdm, SDMSignalData *signal);
+int sdm_device_accept(SDMDevice *sdm);
+int sdm_device_get_num_slaves(SDMDevice *sdm);
+int sdm_device_set_num_slaves(SDMDevice *sdm, uint16_t num_slaves);
+bool sdm_device_is_master(SDMDevice *sdm);
+#endif
diff --git a/include/hw/misc/sdm-signal.h b/include/hw/misc/sdm-signal.h
new file mode 100644
index 0000000..f9b82eb
--- /dev/null
+++ b/include/hw/misc/sdm-signal.h
@@ -0,0 +1,60 @@
+/*
+ * SDM Signal
+ *
+ * Copyright (C) 2016 - Virtual Open Systems
+ *
+ * Author: Baptiste Reynal <b.reynal@virtualopensystems.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+#ifndef HW_SDM_SIGNAL_H
+#define HW_SDM_SIGNAL_H
+
+#include "qemu-common.h"
+#include "qom/object.h"
+
+#define TYPE_SDM_SIGNAL "sdm-signal"
+#define SDM_SIGNAL(obj) \
+    OBJECT_CHECK(SDMSignal, (obj), TYPE_SDM_SIGNAL)
+#define SDM_SIGNAL_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(SDMSignalClass, (obj), TYPE_SDM_SIGNAL)
+#define SDM_SIGNAL_CLASS(klass) \
+    OBJECT_CLASS_CHECK(SDMSignalClass, (klass), \
+            TYPE_SDM_SIGNAL)
+
+typedef struct SDMSignalData SDMSignalData;
+typedef struct SDMSignal SDMSignal;
+typedef struct SDMSignalClass SDMSignalClass;
+
+struct SDMSignalData {
+    uint32_t type;
+    uint32_t slave;
+    uint32_t payload[2];
+};
+
+/**
+ * @SDMSignalClass
+ *
+ * @parent_class: opaque parent class container
+ */
+struct SDMSignalClass {
+    ObjectClass parent_class;
+
+    int (*hw_ops)(SDMSignal *signal, SDMSignalData *data);
+    bool (*hw_only)(SDMSignal *signal);
+};
+
+/**
+ * @SDMSignal
+ *
+ * @parent: opaque parent object container
+ */
+struct SDMSignal {
+    /* private */
+    Object parent;
+};
+
+int sdm_signal_hw_ops(SDMSignal *signal, SDMSignalData *data);
+bool sdm_signal_hw_only(SDMSignal *signal);
+#endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [RFC v3 2/6] hw/misc: sdm platform device
  2016-06-17 15:54 [Qemu-devel] [RFC v3 0/6] SDM Interface Christian Pinto
  2016-06-17 15:54 ` [Qemu-devel] [RFC v3 1/6] hw/misc: sdm interface Christian Pinto
@ 2016-06-17 15:54 ` Christian Pinto
  2016-06-17 15:55 ` [Qemu-devel] [RFC v3 3/6] hw/arm: sysbus-fdt Christian Pinto
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Christian Pinto @ 2016-06-17 15:54 UTC (permalink / raw)
  To: qemu-devel
  Cc: b.reynal, tech, Claudio.Fontana, Jani.Kokkonen, Christian Pinto

From: Baptiste Reynal <b.reynal@virtualopensystems.com>

This is the platform implementation for an SDM device.

Parameters are:
    comm=[sdm_communication_id] specifies the communication channel
    master=[true/false] - configure the SDM device as master or slave
    num_slaves=[slave_number] - if master is true, specifies the number
of slaves
    len-signals=[signals_number] - specifies the number of signals
    signals[x]=[signal_id] - add a signal to the device, with the ID x

Signed-off-by: Baptiste Reynal <b.reynal@virtualopensystems.com>
Signed-off-by: Christian Pinto <c.pinto@virtualopensystems.com>
---
 hw/misc/Makefile.objs          |   1 +
 hw/misc/sdm-platform.c         | 231 +++++++++++++++++++++++++++++++++++++++++
 hw/misc/sdm-signal.c           |   1 +
 include/hw/misc/sdm-platform.h |  65 ++++++++++++
 include/hw/misc/sdm-signal.h   |   1 +
 5 files changed, 299 insertions(+)
 create mode 100644 hw/misc/sdm-platform.c
 create mode 100644 include/hw/misc/sdm-platform.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index ce2aa89..85cfda9 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -24,6 +24,7 @@ obj-$(CONFIG_IVSHMEM) += ivshmem.o
 obj-$(CONFIG_SDM) += sdm-device.o 
 obj-$(CONFIG_SDM) += sdm-communication.o
 obj-$(CONFIG_SDM) += sdm-signal.o
+obj-$(CONFIG_SDM) += sdm-platform.o
 
 obj-$(CONFIG_REALVIEW) += arm_sysctl.o
 obj-$(CONFIG_NSERIES) += cbus.o
diff --git a/hw/misc/sdm-platform.c b/hw/misc/sdm-platform.c
new file mode 100644
index 0000000..26c202f
--- /dev/null
+++ b/hw/misc/sdm-platform.c
@@ -0,0 +1,231 @@
+/*
+ * SDM Platform Device
+ *
+ * Copyright (C) 2015 - Virtual Open Systems
+ *
+ * Author: Christian Pinto <c.pinto@virtualopensystems.com>
+ * 	   Baptiste Reynal <b.reynal@virtualopensystems.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See the
+ * COPYING file in the top-level directory.
+ */
+#include "hw/misc/sdm-platform.h"
+#include "qemu/error-report.h"
+
+static void reset_irq(SDMPlatform *s)
+{
+    qemu_irq_lower(s->irq);
+}
+
+static uint64_t sdm_platform_read(void *opaque, hwaddr offset, unsigned size)
+{
+    SDMPlatform *sdmp = opaque;
+    uint64_t ret = 0;
+
+    switch(offset) {
+    case SIGNAL_REG:
+        /**
+         * Reading the REGISTER returns informations about the signal (16 high
+         * bytes) and the source (16 low bytes).
+         * The signal register is cleared, and the interrupt
+         * is lowered. Be sure to read the payload before.
+         */
+        ret = sdmp->signal_reg;
+        sdmp->signal_reg = 0;
+        reset_irq(sdmp);
+        sdmp->busy = false;
+    case PAYLOAD_REG0:
+        /**
+         * Reading the payload registers returns the value of the last
+         * payload received (0 initialized)
+         */
+        ret = sdmp->payload_reg[0];
+        break;
+    case PAYLOAD_REG1:
+        ret = sdmp->payload_reg[1];
+        break;
+    default:
+        error_report("SDM platform: wrong register in sdm_read\n");
+        break;
+    }
+
+    return ret;
+}
+
+static void sdm_platform_write(void *opaque, hwaddr offset, uint64_t value,
+        unsigned size)
+{
+    SDMPlatform *sdmp = opaque;
+    SDMSignalData signal;
+
+    switch (offset) {
+    case SIGNAL_REG:
+        /* To signal another slave, the ID should be written to the 16
+         * low bytes and the signal ID to the 16 high bytes. Value 0 is
+         * reserved to kick the master, from 1 upwards for the slaves.
+         */
+        signal.slave = value & 0xffff;
+        signal.type = (value >> 16) & 0xffff;
+        memcpy(&signal.payload, sdmp->payload_reg,
+                2 * sizeof(uint32_t));
+
+        sdm_communication_signal(sdmp->sdmc, SDM_DEVICE(sdmp), &signal);
+
+        break;
+    case PAYLOAD_REG0:
+        /* Set the payload for the next signal */
+        sdmp->payload_reg[0] = value;
+        break;
+    case PAYLOAD_REG1:
+        sdmp->payload_reg[1] = value;
+        break;
+    default:
+        error_report("SDM Platform: wrong register in sdm_write\n");
+        break;
+    }
+}
+
+
+
+static const MemoryRegionOps sdm_platform_mem_ops = {
+    .read = sdm_platform_read,
+    .write = sdm_platform_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void sdm_platform_realize(DeviceState *dev, Error **errp)
+{
+    SDMPlatform *s = SDM_PLATFORM(dev);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    int i;
+
+    s->last_slave = 0;
+
+    /* Initialize MMIO regions with read/write functions */
+    memory_region_init_io(&s->iomem, OBJECT(s), &sdm_platform_mem_ops, s,
+            TYPE_SDM_PLATFORM, SDM_PLATFORM_SIZE);
+    sysbus_init_mmio(sbd, &s->iomem);
+
+    /* Initialize IRQ */
+    sysbus_init_irq(sbd, &s->irq);
+
+    sdm_communication_connect(s->sdmc, SDM_DEVICE(s));
+
+    s->signals = calloc(s->num_signals, sizeof(SDMSignal));
+    for (i=0; i<s->num_signals; i++) {
+        s->signals[i] = (SDMSignal *) object_resolve_path_type(
+                s->signals_name[i],
+                TYPE_SDM_SIGNAL, false);
+        if (!s->signals[i]) {
+            error_report("SDM Platform: Cannot find signal %s",
+                    s->signals_name[i]);;
+        }
+    }
+
+}
+
+static int sdm_platform_accept(SDMDevice *sdm) {
+    SDMPlatform *sdmp = SDM_PLATFORM(sdm);
+
+    if (sdmp->last_slave >= sdmp->num_slaves)
+        return -1;
+
+    return ++sdmp->last_slave;
+}
+
+static int sdm_platform_notify(SDMDevice *sdm, SDMSignalData *signal) {
+    SDMPlatform *sdmp = SDM_PLATFORM(sdm);
+    SDMSignal *hw_signal;
+
+    if (signal->type > sdmp->num_signals) {
+        return 0;
+    }
+
+    hw_signal = sdmp->signals[signal->type];
+
+    if (!hw_signal) {
+        return 0;
+    }
+
+    sdm_signal_hw_ops(hw_signal, signal);
+
+    if (!sdm_signal_hw_only(hw_signal)) {
+        if (sdmp->busy) {
+            return -1;
+        }
+        sdmp->busy = true;
+
+        sdmp->signal_reg = (signal->type << 16) & (signal->slave & 0xffff);
+
+        qemu_irq_raise(sdmp->irq);
+    }
+
+    return 0;
+}
+
+static int sdm_platform_get_num_slaves(SDMDevice *sdm) {
+    SDMPlatform *sdmp = SDM_PLATFORM(sdm);
+
+    return sdmp->num_slaves;
+}
+
+static bool sdm_platform_is_master(SDMDevice *sdm) {
+    SDMPlatform *sdmp = SDM_PLATFORM(sdm);
+
+    return sdmp->master;
+}
+
+static Property sdm_platform_properties[] = {
+    DEFINE_PROP_UINT32("num-slaves", SDMPlatform, num_slaves, 1),
+    DEFINE_PROP_BOOL("master", SDMPlatform, master, false),
+    DEFINE_PROP_ARRAY("signals", SDMPlatform, num_signals, signals_name,
+            qdev_prop_string, char *),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void sdm_platform_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    SDMDeviceClass *sdmc = SDM_DEVICE_CLASS(klass);
+
+    dc->props = sdm_platform_properties;
+    dc->realize = sdm_platform_realize;
+
+    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+
+    sdmc->accept = sdm_platform_accept;
+    sdmc->notify = sdm_platform_notify;
+    sdmc->get_num_slaves = sdm_platform_get_num_slaves;
+    sdmc->is_master = sdm_platform_is_master;
+}
+
+static void sdm_platform_init(Object *obj)
+{
+    SDMPlatform *sdmp = SDM_PLATFORM(obj);
+
+    object_property_add_link(obj, "comm", TYPE_SDM_COMMUNICATION,
+            (Object **)&sdmp->sdmc,
+            qdev_prop_allow_set_link_before_realize,
+            OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);
+
+    sdmp->busy = false;
+}
+
+static const TypeInfo sdm_platform_info = {
+    .name		= TYPE_SDM_PLATFORM,
+    .parent		= TYPE_SYS_BUS_DEVICE,
+    .instance_init	= sdm_platform_init,
+    .instance_size	= sizeof(struct SDMPlatform),
+    .class_init	= sdm_platform_class_init,
+    .interfaces	= (InterfaceInfo[]) {
+        { TYPE_SDM_DEVICE },
+        { }
+    }
+};
+
+static void sdm_register_types(void)
+{
+    type_register_static(&sdm_platform_info);
+}
+
+type_init(sdm_register_types);
diff --git a/hw/misc/sdm-signal.c b/hw/misc/sdm-signal.c
index c4af0ac..a34fbea 100644
--- a/hw/misc/sdm-signal.c
+++ b/hw/misc/sdm-signal.c
@@ -4,6 +4,7 @@
  * Copyright (C) 2016 - Virtual Open Systems
  *
  * Author: Baptiste Reynal <b.reynal@virtualopensystems.com>
+ *        Christian Pinto <c.pinto@virtualopensystems.com>
  *
  * This work is licensed under the terms of the GNU GPL, version 2. See
  * the COPYING file in the top-level directory.
diff --git a/include/hw/misc/sdm-platform.h b/include/hw/misc/sdm-platform.h
new file mode 100644
index 0000000..5b504fe
--- /dev/null
+++ b/include/hw/misc/sdm-platform.h
@@ -0,0 +1,65 @@
+/*
+ * SDM Device Platform
+ *
+ * Copyright (C) 2016 - Virtual Open Systems
+ *
+ * Author: Christian Pinto <c.pinto@virtualopensystems.com>
+ * 	   Baptiste Reynal <b.reynal@virtualopensystems.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+#ifndef HW_SDM_PLATFORM_H
+#define HW_SDM_PLATFORM_H
+
+#include "qemu-common.h"
+#include "hw/misc/sdm-communication.h"
+#include "hw/sysbus.h"
+
+/*
+ * Size of the IO memory mapped region
+ * associated with IDM device registers
+ */
+#define SDM_PLATFORM_SIZE 0x100
+
+/*
+ * Registers
+ */
+#define SIGNAL_REG 0x00
+#define PAYLOAD_REG0 0x04
+#define PAYLOAD_REG1 0x08
+
+#define TYPE_SDM_PLATFORM "sdm-platform"
+#define SDM_PLATFORM(obj) \
+    OBJECT_CHECK(SDMPlatform, (obj), TYPE_SDM_PLATFORM)
+
+typedef struct SDMPlatform SDMPlatform;
+
+/**
+ * @SDMPlatform
+ *
+ * @parent: opaque parent object container
+ */
+struct SDMPlatform {
+    /* private */
+    SysBusDevice parent;
+
+    MemoryRegion iomem;
+    SDMCommunication *sdmc;
+
+    bool master;
+    bool busy;
+
+    uint32_t num_slaves;
+    uint32_t last_slave;
+
+    uint32_t num_signals;
+    char **signals_name;
+    SDMSignal **signals;
+
+    uint32_t signal_reg;
+    uint32_t payload_reg[4];
+
+    qemu_irq irq;
+};
+#endif
diff --git a/include/hw/misc/sdm-signal.h b/include/hw/misc/sdm-signal.h
index f9b82eb..4b60724 100644
--- a/include/hw/misc/sdm-signal.h
+++ b/include/hw/misc/sdm-signal.h
@@ -4,6 +4,7 @@
  * Copyright (C) 2016 - Virtual Open Systems
  *
  * Author: Baptiste Reynal <b.reynal@virtualopensystems.com>
+ *        Christian Pinto <c.pinto@virtualopensystems.com>
  *
  * This work is licensed under the terms of the GNU GPL, version 2. See
  * the COPYING file in the top-level directory.
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [RFC v3 3/6] hw/arm: sysbus-fdt
  2016-06-17 15:54 [Qemu-devel] [RFC v3 0/6] SDM Interface Christian Pinto
  2016-06-17 15:54 ` [Qemu-devel] [RFC v3 1/6] hw/misc: sdm interface Christian Pinto
  2016-06-17 15:54 ` [Qemu-devel] [RFC v3 2/6] hw/misc: sdm platform device Christian Pinto
@ 2016-06-17 15:55 ` Christian Pinto
  2016-06-17 15:55 ` [Qemu-devel] [RFC v3 4/6] hw/misc: sdm virtio device Christian Pinto
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Christian Pinto @ 2016-06-17 15:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: b.reynal, tech, Claudio.Fontana, Jani.Kokkonen, Christian Pinto

From: Baptiste Reynal <b.reynal@virtualopensystems.com>

Added node creation for dynamically instantiated sysbus SDM device.
Support added for all ARM machines modeling dynamic sysbus devices
instantiation.

Signed-off-by: Christian Pinto <c.pinto@virtualopensystems.com>
Signed-off-by: Baptiste Reynal <b.reynal@virtualopensystems.com>
---
 hw/arm/sysbus-fdt.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
index 9d28797..9ad7912 100644
--- a/hw/arm/sysbus-fdt.c
+++ b/hw/arm/sysbus-fdt.c
@@ -28,6 +28,7 @@
 #include "sysemu/sysemu.h"
 #include "hw/vfio/vfio-platform.h"
 #include "hw/vfio/vfio-calxeda-xgmac.h"
+#include "hw/misc/sdm-platform.h"
 #include "hw/arm/fdt.h"
 
 /*
@@ -123,9 +124,70 @@ fail_reg:
     return ret;
 }
 
+/**
+ * add_sdm_fdt_node
+ *
+ * Generates a node with following properties:
+ * compatible string, regs, interrupts
+ *
+ */
+static int add_sdm_fdt_node(SysBusDevice *sbdev, void *opaque)
+{
+    PlatformBusFDTData *data = opaque;
+    PlatformBusDevice *pbus = data->pbus;
+    const char sdm_compat[] = "sdm-ipi";
+    void *fdt = data->fdt;
+    const char *parent_node = data->pbus_node_name;
+    char *nodename;
+    int ret = -1;
+    uint32_t *irq_attr, *reg_attr;
+    uint64_t mmio_base, irq_number;
+
+    mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
+    nodename = g_strdup_printf("%s/%s@%" PRIx64, parent_node,
+        TYPE_SDM_PLATFORM, mmio_base);
+    qemu_fdt_add_subnode(fdt, nodename);
+
+    qemu_fdt_setprop(fdt, nodename, "compatible", sdm_compat,
+        sizeof(sdm_compat));
+
+    /**
+     * There is only one MMIO region defined for the SDM device
+     */
+    reg_attr = g_new(uint32_t, 2);
+    mmio_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
+    reg_attr[0] = cpu_to_be32(mmio_base);
+    reg_attr[1] = cpu_to_be32(SDM_PLATFORM_SIZE);
+    ret = qemu_fdt_setprop(fdt, nodename, "reg", reg_attr,
+        2 * sizeof(uint32_t));
+    if (ret) {
+        error_report("could not set reg property of node %s", nodename);
+        goto fail;
+    }
+
+    irq_attr = g_new(uint32_t, 3);
+    irq_number = platform_bus_get_irqn(pbus, sbdev , 0)
+                     + data->irq_start;
+    irq_attr[0] = cpu_to_be32(GIC_FDT_IRQ_TYPE_SPI);
+    irq_attr[1] = cpu_to_be32(irq_number);
+    irq_attr[2] = cpu_to_be32(GIC_FDT_IRQ_FLAGS_EDGE_LO_HI);
+    ret = qemu_fdt_setprop(fdt, nodename, "interrupts",
+        irq_attr, 3 * sizeof(uint32_t));
+    if (ret) {
+        error_report("could not set interrupts property of node %s",
+                nodename);
+    }
+    g_free(irq_attr);
+fail:
+    g_free(reg_attr);
+    g_free(nodename);
+    return ret;
+}
+
 /* list of supported dynamic sysbus devices */
 static const NodeCreationPair add_fdt_node_functions[] = {
     {TYPE_VFIO_CALXEDA_XGMAC, add_calxeda_midway_xgmac_fdt_node},
+    {TYPE_SDM_PLATFORM, add_sdm_fdt_node},
     {"", NULL}, /* last element */
 };
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [RFC v3 4/6] hw/misc: sdm virtio device
  2016-06-17 15:54 [Qemu-devel] [RFC v3 0/6] SDM Interface Christian Pinto
                   ` (2 preceding siblings ...)
  2016-06-17 15:55 ` [Qemu-devel] [RFC v3 3/6] hw/arm: sysbus-fdt Christian Pinto
@ 2016-06-17 15:55 ` Christian Pinto
  2016-06-17 15:55 ` [Qemu-devel] [RFC v3 5/6] hw/misc: sdm communication local Christian Pinto
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Christian Pinto @ 2016-06-17 15:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: b.reynal, tech, Claudio.Fontana, Jani.Kokkonen, Christian Pinto

From: Baptiste Reynal <b.reynal@virtualopensystems.com>

This is the virtio implementation for an SDM device.

Parameters are:
comm=[sdm_communication_id] specifies the communication channel
master=[true/false] - configure the SDM device as master or slave
num_slaves=[slave_number] - if master is true, specifies the number
of slaves
len-signals=[signals_number] - specifies the number of signals
signals[x]=[signal_id] - add a signal to the device, with the ID x

Signed-off-by: Christian Pinto <c.pinto@virtualopensystems.com>
Signed-off-by: Baptiste Reynal <b.reynal@virtualopensystems.com>

---
v2 -> v3
- add configuration space to virtio sdm device
- add accessor methods (get, set) to sdm virtio device model
- max num_slave changes propagated to communication channel to realloc slaves
  array
- align virtio device ID to device specification RFC submitted to virtio-dev
---
---
 hw/virtio/Makefile.objs          |   1 +
 hw/virtio/virtio-sdm.c           | 303 +++++++++++++++++++++++++++++++++++++++
 include/hw/virtio/virtio-sdm.h   |  58 ++++++++
 linux-headers/linux/virtio_sdm.h |  58 ++++++++
 4 files changed, 420 insertions(+)
 create mode 100644 hw/virtio/virtio-sdm.c
 create mode 100644 include/hw/virtio/virtio-sdm.h
 create mode 100644 linux-headers/linux/virtio_sdm.h

diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
index 19b224a..7e44bc4 100644
--- a/hw/virtio/Makefile.objs
+++ b/hw/virtio/Makefile.objs
@@ -2,6 +2,7 @@ common-obj-y += virtio-rng.o
 common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
 common-obj-y += virtio-bus.o
 common-obj-y += virtio-mmio.o
+obj-$(CONFIG_SDM) += virtio-sdm.o
 obj-$(CONFIG_VIRTIO) += dataplane/
 
 obj-y += virtio.o virtio-balloon.o 
diff --git a/hw/virtio/virtio-sdm.c b/hw/virtio/virtio-sdm.c
new file mode 100644
index 0000000..a210ced
--- /dev/null
+++ b/hw/virtio/virtio-sdm.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2016 - Virtual Open Systems
+ * Authors: Christian Pinto <c.pinto@virtualopensystems.com>
+ *          Baptiste Reynal <b.reynal@virtualopensystems.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/virtio_sdm.h>
+
+#include "qemu/iov.h"
+#include "qemu/error-report.h"
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/virtio-sdm.h"
+
+typedef void (*cmd_handler)(VirtIOSdm *sdm, union sdm_cmd_params);
+/**
+ * Command handler for signal type commands.
+ * Invoked when the command is received from the guest
+ */
+static void handler_signal(VirtIOSdm *sdm, union sdm_cmd_params params)
+{
+    SDMSignalData signal;
+    DEBUG_PRINT("handler_signal: SIGNAL %d, SLAVE_ID %d\n", params.sig.type,
+            params.sig.slave_id);
+
+    signal.type = params.sig.type;
+    signal.slave = params.sig.slave_id;
+    memcpy(&signal.payload, &params.sig.payload, 2 * sizeof(uint32_t));
+
+    sdm_communication_signal(sdm->sdmc, SDM_DEVICE(sdm),  &signal);
+}
+
+static cmd_handler sdm_cmd_handlers[] = {
+    [SDM_SIGNAL_CMD]    = handler_signal,
+};
+
+/**
+ * Send a command to the guest virtio-driver
+ */
+static void send_cmd_to_guest(VirtIOSdm *sdm,
+        struct sdm_cmd cmd)
+{
+    VirtQueueElement elem;
+    VirtIODevice * vdev = VIRTIO_DEVICE(sdm);
+
+    if (!virtqueue_pop(sdm->hg_vq, &elem)) {
+        return;
+    }
+
+    if (iov_from_buf(elem.in_sg, elem.in_num, 0, &cmd, sizeof(cmd))) {
+        virtqueue_push(sdm->hg_vq, &elem, sizeof(cmd));
+        virtio_notify(vdev, sdm->hg_vq);
+        DEBUG_PRINT("Sending command %d of type %d\n",
+                cmd.cmd, cmd.params.sig.type);
+    } else {
+        error_report("virtio-sdm - Failed to issue command id 0x%x\n",
+                cmd.cmd);
+    }
+}
+
+/**
+ * guest -> host virtqueue handler.
+ * Calls the handler assoociated to the command received over the virtqueue
+ */
+static void handle_guest_host_queue(VirtIODevice *vdev, VirtQueue *vq)
+{
+    VirtQueueElement elem;
+    struct sdm_cmd cmd;
+
+    if (!virtqueue_pop(vq,&elem))
+        return;
+
+    if (!iov_to_buf(elem.out_sg, elem.out_num, 0, &cmd, sizeof(cmd)))
+        return;
+
+    DEBUG_PRINT("Command received 0x%x\n", cmd.cmd);
+
+    if (cmd.cmd >= ARRAY_SIZE(sdm_cmd_handlers) ||
+            !sdm_cmd_handlers[cmd.params.sig.type]) {
+        error_report("virtio-sdm - unrecognized command %x\n", cmd.cmd);
+        return;
+    }
+
+    sdm_cmd_handlers[cmd.params.sig.type](VIRTIO_SDM(vdev), cmd.params);
+}
+
+/**
+ * Guest sends commands over this virtqueue only to add an empty
+ * buffer to be later used by the host.
+ */
+static void handle_host_guest_queue(VirtIODevice *vdev, VirtQueue *vq) {
+    VirtIOSdm *sdm = VIRTIO_SDM(vdev);
+
+    sdm->busy = false;
+}
+
+static uint64_t get_features(VirtIODevice *vdev, uint64_t requested_features,
+        Error **errp)
+{
+    return requested_features;
+}
+
+static void virtio_sdm_get_config(VirtIODevice *vdev, uint8_t *config_data)
+{
+    VirtIOSdm *sdm = VIRTIO_SDM(vdev);
+    struct virtio_sdm_config config;
+
+    config.master = sdm->master ? 1 : 0;
+    config.max_slaves = cpu_to_le16(sdm->num_slaves);
+    config.registered_slaves = cpu_to_le16(sdm->last_slave);
+
+    memcpy(config_data, &config, sizeof(struct virtio_sdm_config));
+}
+
+static void virtio_sdm_set_config(VirtIODevice *vdev,
+                                      const uint8_t *config_data)
+{
+    VirtIOSdm *sdm = VIRTIO_SDM(vdev);
+    struct virtio_sdm_config config;
+    uint16_t max_slaves;
+
+    memcpy(&config, config_data, sizeof(struct virtio_sdm_config));
+    max_slaves = le16_to_cpu(config.max_slaves);
+    if(max_slaves > sdm->num_slaves) {
+        sdm_communication_update_num_slaves(sdm->sdmc, SDM_DEVICE(sdm),
+                    max_slaves);
+    } else {
+        printf("WARNING - virtio-sdm: reducing the maximum number of slaves"
+                "is not allowed. The new value should be bigger than the"
+                "current one.\n");
+    }
+}
+
+static void virtio_sdm_device_realize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    VirtIOSdm *sdm = VIRTIO_SDM(dev);
+    int i;
+
+    virtio_init(vdev, "virtio-sdm", VIRTIO_ID_SDM,
+            sizeof(struct virtio_sdm_config));
+
+    sdm->hg_vq = virtio_add_queue(vdev, 128, handle_host_guest_queue);
+    sdm->gh_vq = virtio_add_queue(vdev, 128, handle_guest_host_queue);
+
+    sdm->signals = calloc(sdm->num_signals, sizeof(SDMSignal));
+    for (i=0; i<sdm->num_signals; i++) {
+        sdm->signals[i] = (SDMSignal *) object_resolve_path_type(
+                sdm->signals_name[i],
+                TYPE_SDM_SIGNAL, false);
+        if (!sdm->signals[i]) {
+            error_report("virtio-sdm: Cannot find signal %s",
+                    sdm->signals_name[i]);;
+        }
+    }
+
+    sdm_communication_connect(sdm->sdmc, SDM_DEVICE(sdm));
+}
+
+static void virtio_sdm_device_unrealize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    virtio_cleanup(vdev);
+}
+
+static int virtio_sdm_accept(SDMDevice *sdm)
+{
+    VirtIOSdm *sdmv = VIRTIO_SDM(sdm);
+
+    if (sdmv->last_slave >= sdmv->num_slaves)
+        return -1;
+
+    return ++sdmv->last_slave;
+}
+
+static int virtio_sdm_notify(SDMDevice *sdm, SDMSignalData *signal)
+{
+    VirtIOSdm *sdmv = VIRTIO_SDM(sdm);
+    SDMSignal *hw_signal ;
+    struct sdm_cmd cmd;
+
+    if (signal->type > sdmv->num_signals) {
+        return 0;
+    }
+
+    hw_signal = sdmv->signals[signal->type];
+
+    if (!hw_signal) {
+        return 0;
+    }
+
+    sdm_signal_hw_ops(hw_signal, signal);
+
+    if (!sdm_signal_hw_only(hw_signal)) {
+        if (sdmv->busy) {
+            return -1;
+        }
+
+        sdmv->busy = true;
+
+        cmd.cmd = SDM_SIGNAL_CMD;
+        cmd.params.sig.type = signal->type;
+        cmd.params.sig.slave_id = signal->slave;
+        memcpy(cmd.params.sig.payload, signal->payload, 2 * sizeof(uint32_t));
+
+        DEBUG_PRINT("Forward %d %d\n", cmd.params.sig.type, cmd.params.sig.slave_id);
+        send_cmd_to_guest(sdmv, cmd);
+    }
+
+    return 0;
+}
+
+static int virtio_sdm_get_num_slaves(SDMDevice *sdm)
+{
+    VirtIOSdm *sdmv = VIRTIO_SDM(sdm);
+
+    return sdmv->num_slaves;
+}
+
+static int virtio_sdm_set_num_slaves(SDMDevice *sdm, uint16_t num_slaves)
+{
+    VirtIOSdm *sdmv = VIRTIO_SDM(sdm);
+
+    sdmv->num_slaves = num_slaves;
+
+    return 0;
+}
+
+static bool virtio_sdm_is_master(SDMDevice *sdm)
+{
+    VirtIOSdm *sdmv = VIRTIO_SDM(sdm);
+
+    return sdmv->master;
+}
+
+static Property sdm_virtio_properties[] = {
+    DEFINE_PROP_UINT32("num-slaves", VirtIOSdm, num_slaves, 1),
+    DEFINE_PROP_BOOL("master", VirtIOSdm, master, false),
+    DEFINE_PROP_ARRAY("signals", VirtIOSdm, num_signals, signals_name,
+            qdev_prop_string, char *),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtio_sdm_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+    SDMDeviceClass *sdmc = SDM_DEVICE_CLASS(klass);
+
+    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+    vdc->realize = virtio_sdm_device_realize;
+    vdc->unrealize = virtio_sdm_device_unrealize;
+    vdc->get_features = get_features;
+    vdc->get_config = virtio_sdm_get_config;
+    vdc->set_config = virtio_sdm_set_config;
+
+    sdmc->accept = virtio_sdm_accept;
+    sdmc->notify = virtio_sdm_notify;
+    sdmc->get_num_slaves = virtio_sdm_get_num_slaves;
+    sdmc->set_num_slaves = virtio_sdm_set_num_slaves;
+    sdmc->is_master = virtio_sdm_is_master;
+
+    dc->props = sdm_virtio_properties;
+}
+
+static void virtio_sdm_init(Object *obj)
+{
+    VirtIOSdm *sdm = VIRTIO_SDM(obj);
+
+    object_property_add_link(obj, "comm", TYPE_SDM_COMMUNICATION,
+            (Object **)&sdm->sdmc,
+            qdev_prop_allow_set_link_before_realize,
+            OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);
+
+    sdm->busy = false;
+}
+
+static const TypeInfo virtio_sdm_info = {
+    .name = TYPE_VIRTIO_SDM,
+    .parent = TYPE_VIRTIO_DEVICE,
+    .instance_size = sizeof(VirtIOSdm),
+    .class_init = virtio_sdm_class_init,
+    .instance_init = virtio_sdm_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_SDM_DEVICE },
+        { }
+    }
+};
+
+static void virtio_register_types(void)
+{
+    type_register_static(&virtio_sdm_info);
+}
+
+type_init(virtio_register_types)
diff --git a/include/hw/virtio/virtio-sdm.h b/include/hw/virtio/virtio-sdm.h
new file mode 100644
index 0000000..c86d112
--- /dev/null
+++ b/include/hw/virtio/virtio-sdm.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 - Virtual Open Systems
+ * Author: Christian Pinto <c.pinto@virtualopensystems.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _QEMU_VIRTIO_SDM_H
+#define _QEMU_VIRTIO_SDM_H
+
+#include "hw/virtio/virtio.h"
+#include "hw/misc/sdm-device.h"
+#include "hw/misc/sdm-communication.h"
+
+/*#define DEBUG_SDM*/
+#ifdef DEBUG_SDM
+#define DEBUG_PRINT(fmt, ...) \
+    do {printf("virtio-sdm - " fmt, ## __VA_ARGS__); } while (0)
+#else
+#define DEBUG_PRINT(fmt, ...)
+#endif
+
+#define TYPE_VIRTIO_SDM "virtio-sdm-device"
+#define VIRTIO_SDM(obj) \
+        OBJECT_CHECK(VirtIOSdm, (obj), TYPE_VIRTIO_SDM)
+#define VIRTIO_SDM_GET_PARENT_CLASS(obj) \
+        OBJECT_GET_PARENT_CLASS(obj, TYPE_VIRTIO_SDM)
+
+/* The Virtio ID for the virtio SDM device */
+#define VIRTIO_ID_SDM	19
+
+typedef struct VirtIOSdm {
+    VirtIODevice parent_obj;
+
+    SDMCommunication *sdmc;
+
+    bool master;
+    bool busy;
+
+    uint32_t num_slaves;
+    uint32_t last_slave;
+
+    uint32_t num_signals;
+    char **signals_name;
+    SDMSignal **signals;
+
+    VirtQueue *hg_vq;
+    VirtQueue *gh_vq;
+} VirtIOSdm;
+
+#endif /*_QEMU_VIRTIO_SDM_H*/
diff --git a/linux-headers/linux/virtio_sdm.h b/linux-headers/linux/virtio_sdm.h
new file mode 100644
index 0000000..c43a932
--- /dev/null
+++ b/linux-headers/linux/virtio_sdm.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2016 - Virtual Open Systems
+ * Author: Christian Pinto <c.pinto@virtualopensystems.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _LINUX_VIRTIO_SDM_H
+#define _LINUX_VIRTIO_SDM_H
+#include <linux/virtio_ids.h>
+#include <linux/virtio_config.h>
+#include <linux/types.h>
+/* the commands the host can issue to a virtio-sdm guest */
+enum sdm_cmd_type {
+    SDM_SIGNAL_CMD,
+};
+
+enum sdm_signal_type {
+    SDM_IRQ,
+    SDM_BOOT,
+};
+
+union sdm_cmd_params {
+    /**
+    * This command is used to communicate signals between
+    * guest and host.
+    * The slave_id to which signal triggering/reception is
+    * associated, the type and signal and 2 32-bits registers
+    * for payload are transmitted.
+    */
+    struct {
+        __u16 type;
+        __u16 slave_id;
+
+        __u32 payload[2];
+    } sig;
+        __u32 padding[4];
+};
+
+struct sdm_cmd {
+    enum sdm_cmd_type       cmd;
+    union sdm_cmd_params    params;
+};
+
+struct virtio_sdm_config {
+    __u8 master;
+    __u16 max_slaves;
+    __u16 registered_slaves;
+};
+
+#endif /* _LINUX_VIRTIO_SDM_H */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [RFC v3 5/6] hw/misc: sdm communication local
  2016-06-17 15:54 [Qemu-devel] [RFC v3 0/6] SDM Interface Christian Pinto
                   ` (3 preceding siblings ...)
  2016-06-17 15:55 ` [Qemu-devel] [RFC v3 4/6] hw/misc: sdm virtio device Christian Pinto
@ 2016-06-17 15:55 ` Christian Pinto
  2016-06-17 15:55 ` [Qemu-devel] [RFC v3 6/6] hw/misc: sdm communication socket Christian Pinto
  2016-06-30  8:26 ` [Qemu-devel] [RFC v3 0/6] SDM Interface Christian Pinto
  6 siblings, 0 replies; 10+ messages in thread
From: Christian Pinto @ 2016-06-17 15:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: b.reynal, tech, Claudio.Fontana, Jani.Kokkonen, Christian Pinto

From: Baptiste Reynal <b.reynal@virtualopensystems.com>

This patch introduces local implementation for SDM devices. It allows a
master to communicate with a slave on the same QEMU instance.

Instantiation:
    -object sdm-communication-local,id=<id>

Signed-off-by: Baptiste Reynal <b.reynal@virtualopensystems.com>
Signed-off-by: Christian Pinto <c.pinto@virtualopensystems.com>

---
v2 -> v3:
- added sdm_local_update_num_slaves to local communication channel
- realloc slaves array in case of max slaves change
- fixed bug: signal notifications not sent to correct sdm device instance
---
---
 hw/misc/Makefile.objs                     |   1 +
 hw/misc/sdm-communication-local.c         | 116 ++++++++++++++++++++++++++++++
 include/hw/misc/sdm-communication-local.h |  35 +++++++++
 3 files changed, 152 insertions(+)
 create mode 100644 hw/misc/sdm-communication-local.c
 create mode 100644 include/hw/misc/sdm-communication-local.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 85cfda9..cad0b4c 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -25,6 +25,7 @@ obj-$(CONFIG_SDM) += sdm-device.o
 obj-$(CONFIG_SDM) += sdm-communication.o
 obj-$(CONFIG_SDM) += sdm-signal.o
 obj-$(CONFIG_SDM) += sdm-platform.o
+obj-$(CONFIG_SDM) += sdm-communication-local.o
 
 obj-$(CONFIG_REALVIEW) += arm_sysctl.o
 obj-$(CONFIG_NSERIES) += cbus.o
diff --git a/hw/misc/sdm-communication-local.c b/hw/misc/sdm-communication-local.c
new file mode 100644
index 0000000..a9ce1ba
--- /dev/null
+++ b/hw/misc/sdm-communication-local.c
@@ -0,0 +1,116 @@
+/*
+ * SDM Communication Local
+ *
+ * Copyright (C) 2016 - Virtual Open Systems
+ *
+ * Author: Baptiste Reynal <b.reynal@virtualopensystems.com>
+ * 	   Christian Pinto <c.pinto@virtualopensystems.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+#include "hw/misc/sdm-communication-local.h"
+
+static int sdm_local_signal(SDMCommunication *sdmc, SDMDevice *sdm,
+        SDMSignalData *signal)
+{
+    SDMCommunicationLocal *sdmcl = SDM_COMMUNICATION_LOCAL(sdmc);
+    int id;
+    int dest;
+
+    dest = signal->slave;
+    if (!sdmcl->slaves[dest]) {
+        printf("Error unexisting slave\n");
+        return -1;
+    }
+
+    /* Find sdm ID
+     */
+    for (id=0; id<=sdmcl->num_slaves; id++) {
+        if (sdmcl->slaves[id] == sdm)
+            break;
+    }
+    /**
+     * Update slave_id field with source sdm ID
+     */
+    signal->slave = id;
+
+    while (sdm_device_notify(sdmcl->slaves[dest], signal) < 0) {
+        sleep(1);
+    }
+
+    return 0;
+}
+
+static int sdm_local_connect(SDMCommunication *sdmc, SDMDevice *sdm)
+{
+    SDMCommunicationLocal *sdmcl = SDM_COMMUNICATION_LOCAL(sdmc);
+    int id;
+
+    if (sdm_device_is_master(sdm)) {
+        sdmcl->num_slaves = sdm_device_get_num_slaves(sdm);
+        sdmcl->slaves = calloc(sdmcl->num_slaves + 1,
+                sizeof(SDMDevice *));
+        sdmcl->slaves[0] = sdm;
+    } else {
+        if (!sdmcl->slaves) {
+            printf("SDM Communication Local error : no master registered\n");
+            return -1;
+        }
+
+        id = sdm_device_accept(sdmcl->slaves[0]);
+
+        if (id < 0) {
+            printf("SDM Communication Local error : no id available\n");
+
+            return -1;
+        }
+
+        sdmcl->slaves[id] = sdm;
+    }
+
+    return 0;
+}
+
+static int sdm_local_update_num_slaves(SDMCommunication *sdmc, SDMDevice *sdm,
+            uint16_t num_slaves)
+{
+    SDMCommunicationLocal *sdmcl = SDM_COMMUNICATION_LOCAL(sdmc);
+    SDMDevice **tmp_slaves;
+
+    tmp_slaves = realloc(sdmcl->slaves, (num_slaves + 1) *
+                sizeof(SDMDevice *));
+
+    if(tmp_slaves == NULL)
+        return -1;
+
+    sdmcl->slaves = tmp_slaves;
+    sdmcl->num_slaves = num_slaves;
+    sdm_device_set_num_slaves(sdm, num_slaves);
+
+    return 0;
+}
+
+
+static void sdm_communication_local_class_init(ObjectClass *oc, void *data)
+{
+    SDMCommunicationClass *sdmck = SDM_COMMUNICATION_CLASS(oc);
+
+    sdmck->signal = sdm_local_signal;
+    sdmck->connect = sdm_local_connect;
+    sdmck->update_num_slaves = sdm_local_update_num_slaves;
+}
+
+static const TypeInfo sdm_communication_local_info = {
+    .name = TYPE_SDM_COMMUNICATION_LOCAL,
+    .parent = TYPE_SDM_COMMUNICATION,
+    .class_init = sdm_communication_local_class_init,
+    .instance_size = sizeof(SDMCommunicationLocal),
+};
+
+static void register_types(void)
+{
+    type_register_static(&sdm_communication_local_info);
+}
+
+type_init(register_types);
diff --git a/include/hw/misc/sdm-communication-local.h b/include/hw/misc/sdm-communication-local.h
new file mode 100644
index 0000000..34d1718
--- /dev/null
+++ b/include/hw/misc/sdm-communication-local.h
@@ -0,0 +1,35 @@
+/*
+ * SDM Communication Local
+ *
+ * Copyright (C) 2016 - Virtual Open Systems
+ *
+ * Author: Baptiste Reynal <b.reynal@virtualopensystems.com>
+ *
+ * This works is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file un the top-level directory.
+ */
+#ifndef HW_SDM_COMM_LOCAL_H
+#define HW_SDM_COMM_LOCAL_H
+
+#include "hw/misc/sdm-communication.h"
+
+#define TYPE_SDM_COMMUNICATION_LOCAL "sdm-communication-local"
+#define SDM_COMMUNICATION_LOCAL(obj) \
+    OBJECT_CHECK(SDMCommunicationLocal, (obj), \
+            TYPE_SDM_COMMUNICATION_LOCAL)
+
+typedef struct SDMCommunicationLocal SDMCommunicationLocal;
+
+/**
+ * @SDMCommunicationLocal
+ *
+ * @parent: opaque parent object container
+ */
+struct SDMCommunicationLocal {
+    /* private */
+    SDMCommunication parent;
+
+    int num_slaves;
+    SDMDevice **slaves;
+};
+#endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [RFC v3 6/6] hw/misc: sdm communication socket
  2016-06-17 15:54 [Qemu-devel] [RFC v3 0/6] SDM Interface Christian Pinto
                   ` (4 preceding siblings ...)
  2016-06-17 15:55 ` [Qemu-devel] [RFC v3 5/6] hw/misc: sdm communication local Christian Pinto
@ 2016-06-17 15:55 ` Christian Pinto
  2016-06-30  8:26 ` [Qemu-devel] [RFC v3 0/6] SDM Interface Christian Pinto
  6 siblings, 0 replies; 10+ messages in thread
From: Christian Pinto @ 2016-06-17 15:55 UTC (permalink / raw)
  To: qemu-devel
  Cc: b.reynal, tech, Claudio.Fontana, Jani.Kokkonen, Christian Pinto

From: Baptiste Reynal <b.reynal@virtualopensystems.com>

This is the socket implementation of an SDM communication channel. A
master device can communicate with a slave over a socket.

Parameters:
    socket=[socket_id] - specifies the multi-client socket

This patch depends on "[RFC v2 1/1] backend: multi-client-socket"

Signed-off-by: Baptiste Reynal <b.reynal@virtualopensystems.com>
Signed-off-by: Christian Pinto <c.pinto@virtualopensystems.com>

---
v2 -> v3:
- added sdm_socket_update_num_slaves to socket based communication channel
- realloc slaves array in case of max slaves num change
---
 hw/misc/Makefile.objs                      |   1 +
 hw/misc/sdm-communication-socket.c         | 160 +++++++++++++++++++++++++++++
 include/hw/misc/sdm-communication-socket.h |  42 ++++++++
 3 files changed, 203 insertions(+)
 create mode 100644 hw/misc/sdm-communication-socket.c
 create mode 100644 include/hw/misc/sdm-communication-socket.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index cad0b4c..8f38d35 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -26,6 +26,7 @@ obj-$(CONFIG_SDM) += sdm-communication.o
 obj-$(CONFIG_SDM) += sdm-signal.o
 obj-$(CONFIG_SDM) += sdm-platform.o
 obj-$(CONFIG_SDM) += sdm-communication-local.o
+obj-$(CONFIG_SDM) += sdm-communication-socket.o
 
 obj-$(CONFIG_REALVIEW) += arm_sysctl.o
 obj-$(CONFIG_NSERIES) += cbus.o
diff --git a/hw/misc/sdm-communication-socket.c b/hw/misc/sdm-communication-socket.c
new file mode 100644
index 0000000..15ebed7
--- /dev/null
+++ b/hw/misc/sdm-communication-socket.c
@@ -0,0 +1,160 @@
+/*
+ * SDM Communication Socket
+ *
+ * Copyright (C) 2016 - Virtual Open Systems
+ *
+ * Author: Baptiste Reynal <b.reynal@virtualopensystems.com>
+ *	   Christian Pinto <c.pinto@virtualopensystems.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+#include "hw/misc/sdm-communication-socket.h"
+#include "hw/qdev-properties.h"
+#include "qemu/error-report.h"
+
+static int sdm_socket_signal(SDMCommunication *sdmc, SDMDevice *sdm,
+        SDMSignalData *signal)
+{
+    SDMCommunicationSocket *sdmcs = SDM_COMMUNICATION_SOCKET(sdmc);
+    int len;
+    char *message;
+    SDMSignalData *payload;
+
+    if (!sdmcs->slaves[signal->slave]) {
+        error_report("SDMCommunicationSocket: invalid slave ID %d",
+                signal->slave);
+        return -1;
+    }
+
+    len = strlen(SDM_SIGNAL_CMD) + sizeof(SDMSignalData) + 1;
+    message = malloc(len);
+
+    strcpy((char *) message, SDM_SIGNAL_CMD);
+    payload = (SDMSignalData *) (message + strlen(SDM_SIGNAL_CMD) + 1);
+    memcpy(payload, signal, sizeof(SDMSignalData));
+
+    multi_socket_write_to(sdmcs->slaves[signal->slave],
+            message,
+            len);
+
+    return 0;
+}
+
+static void sdm_register_ms_handler(MSClient *c, const char *message,
+        void *opaque)
+{
+    SDMCommunication *sdmc = opaque;
+    SDMCommunicationSocket *sdmcs = SDM_COMMUNICATION_SOCKET(sdmc);
+    int slave_id;
+
+    slave_id = sdm_device_accept(sdmcs->master);
+    if (slave_id >= 0) {
+        sdmcs->slaves[slave_id] = c;
+    } else {
+        error_report("SDMCommunicationSocket: Slave rejected, no ID available");
+    }
+}
+
+static void sdm_signal_ms_handler(MSClient *c, const char *message,
+        void *opaque)
+{
+    SDMCommunication *sdmc = opaque;
+    SDMCommunicationSocket *sdmcs = SDM_COMMUNICATION_SOCKET(sdmc);
+    int slave;
+    SDMSignalData *signal;
+
+    signal = (SDMSignalData *) message;
+
+    /* Find slave id */
+    for (slave=0; slave<=sdmcs->num_slaves; slave++) {
+        if (sdmcs->slaves[slave] == c)
+            break;
+    }
+
+    signal->slave = slave;
+
+    while (sdm_device_notify(sdmcs->master, signal) < 0) {
+        sleep(100);
+    }
+}
+
+static int sdm_socket_connect(SDMCommunication *sdmc, SDMDevice *sdm)
+{
+    SDMCommunicationSocket *sdmcs = SDM_COMMUNICATION_SOCKET(sdmc);
+
+    sdmcs->master = sdm;
+
+    sdmcs->num_slaves = sdm_device_get_num_slaves(sdm);
+    sdmcs->slaves = calloc(sdmcs->num_slaves + 1,
+            sizeof(MSClient *));
+
+    sdmcs->slaves[0] = &sdmcs->socket->listener;
+    multi_socket_add_handler(sdmcs->socket, SDM_SIGNAL_CMD,
+            sdm_signal_ms_handler, sdmc);
+
+    if (sdm_device_is_master(sdm)) {
+        multi_socket_add_handler(sdmcs->socket, SDM_REGISTER_CMD,
+                sdm_register_ms_handler, sdmc);
+    } else {
+        multi_socket_write_to(sdmcs->slaves[0],
+                SDM_REGISTER_CMD,
+                strlen(SDM_REGISTER_CMD) + 1);
+    }
+
+    return 0;
+}
+
+static int sdm_socket_update_num_slaves(SDMCommunication *sdmc, SDMDevice *sdm,
+            uint16_t num_slaves)
+{
+    SDMCommunicationSocket *sdmcs = SDM_COMMUNICATION_SOCKET(sdmc);
+    MSClient **tmp_slaves;
+
+    tmp_slaves = realloc(sdmcs->slaves, (num_slaves + 1) *
+                sizeof(MSClient *));
+
+    if(tmp_slaves == NULL)
+        return -1;
+
+    sdmcs->slaves = tmp_slaves;
+    sdmcs->num_slaves = num_slaves;
+    sdm_device_set_num_slaves(sdm, num_slaves);
+
+    return 0;
+}
+
+static void sdm_communication_socket_class_init(ObjectClass *oc, void *data)
+{
+    SDMCommunicationClass *sdmck = SDM_COMMUNICATION_CLASS(oc);
+
+    sdmck->signal = sdm_socket_signal;
+    sdmck->connect = sdm_socket_connect;
+    sdmck->update_num_slaves = sdm_socket_update_num_slaves;
+}
+
+static void sdm_communication_socket_init(Object *obj)
+{
+    SDMCommunicationSocket *s = SDM_COMMUNICATION_SOCKET(obj);
+
+    object_property_add_link(obj, "socket", TYPE_MULTI_SOCKET_BACKEND,
+            (Object **)&s->socket,
+            object_property_allow_set_link,
+            OBJ_PROP_LINK_UNREF_ON_RELEASE,
+            &error_abort);
+}
+
+static const TypeInfo sdm_communication_socket_info = {
+    .name = TYPE_SDM_COMMUNICATION_SOCKET,
+    .parent = TYPE_SDM_COMMUNICATION,
+    .class_init = sdm_communication_socket_class_init,
+    .instance_size = sizeof(SDMCommunicationSocket),
+    .instance_init = sdm_communication_socket_init,
+};
+
+static void register_types(void)
+{
+    type_register_static(&sdm_communication_socket_info);
+}
+
+type_init(register_types);
diff --git a/include/hw/misc/sdm-communication-socket.h b/include/hw/misc/sdm-communication-socket.h
new file mode 100644
index 0000000..aa24454
--- /dev/null
+++ b/include/hw/misc/sdm-communication-socket.h
@@ -0,0 +1,42 @@
+/*
+ * SDM Communication Socket
+ *
+ * Copyright (C) 2016 - Virtual Open Systems
+ *
+ * Author: Baptiste Reynal <b.reynal@virtualopensystems.com>
+ *
+ * This works is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ */
+#ifndef HW_SDM_COMM_SOCK_H
+#define HW_SDM_COMM_SOCK_H
+
+#include "hw/misc/sdm-communication.h"
+#include "qemu/multi-socket.h"
+
+#define SDM_REGISTER_CMD "sdm_register"
+#define SDM_SIGNAL_CMD "sdm_signal"
+
+#define TYPE_SDM_COMMUNICATION_SOCKET "sdm-communication-socket"
+#define SDM_COMMUNICATION_SOCKET(obj) \
+    OBJECT_CHECK(SDMCommunicationSocket, (obj), \
+            TYPE_SDM_COMMUNICATION_SOCKET)
+
+typedef struct SDMCommunicationSocket SDMCommunicationSocket;
+
+/**
+ * @SDMCommunicationSocket
+ *
+ * @parent: opaque parent object container
+ */
+struct SDMCommunicationSocket {
+    /* private */
+    SDMCommunication parent;
+
+    SDMDevice *master;
+    MSBackend *socket;
+
+    int num_slaves;
+    MSClient **slaves;
+};
+#endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [RFC v3 0/6] SDM Interface
  2016-06-17 15:54 [Qemu-devel] [RFC v3 0/6] SDM Interface Christian Pinto
                   ` (5 preceding siblings ...)
  2016-06-17 15:55 ` [Qemu-devel] [RFC v3 6/6] hw/misc: sdm communication socket Christian Pinto
@ 2016-06-30  8:26 ` Christian Pinto
  2016-06-30  8:47   ` [Qemu-devel] [virtio-dev] " Stefan Hajnoczi
  6 siblings, 1 reply; 10+ messages in thread
From: Christian Pinto @ 2016-06-30  8:26 UTC (permalink / raw)
  To: qemu-devel@nongnu.org Developers
  Cc: Baptiste Reynal, VirtualOpenSystems Technical Team,
	Claudio Fontana, Jani Kokkonen, Christian Pinto, virtio-dev

Ping...

are there any comments?

Thanks,

Christian

On Fri, Jun 17, 2016 at 5:54 PM, Christian Pinto <
c.pinto@virtualopensystems.com> wrote:

> This patch series introduces a new device to QEMU, the SDM (Signal
> Distribution
> Module),
> intended to route inter-processor signals intra and inter QEMU instances.
>
> To be as modular as possible, the device is split between the interface
> (virtio/platform) and the communication channel (local/socket).
>
> A platform interface has been implemented to allow non-linux operating
> system (FreeRTOS for example) to use the SDM.
>
> Also, various signals can be defined with hardware operations.
>
> Those signals can be used, for example, to route interrupts or to
> trigger the boot of another QEMU instance.
>
> When a signal is received on a SDM, it will check if the signal
> ID is associate to a hardware action that will be executed if found.
> The hardware action allows the signal to perform some actions (e.g
> triggering boot) before being forwarded to the operating system.
>
> You can test thoses patches using modules and test application
> available on https://git.virtualopensystems.com/dev/qemu-het-tools :
>
> - Platform module on branch sdm_test_mod_v1
> - Virtio module on branch sdm-dev-v3
> - Test application on branch sdm_test_app
>
> QEMU code is avalaible here on git@git.virtualopensystems.com:
> dev/qemu-het.git
> branch sdm-dev-v3.
>
>
> Run QEMU instance:
> ./qemu-system-arm -nographic \
>         -kernel zImage \
>         -M virt -m 512M \
>         -initrd busybox.cpio \
>         -object sdm-communication-local,id=localcomm \
>         -object sdm-signal,id=interrupt \
>         -device
> sdm-platform,comm=localcomm,master,num-slaves=1,len-signals=1,signals[0]="interrupt"
> \
>         -device
> sdm-platform,comm=localcomm,len-signals=1,len-signals=1,signals[0]="interrupt"
>
> After loading the corresponding module (insmod sdm_test_mod.ko), you can
> send
> signal
> accross instances using the sdm-test application:
> ./sdm-test -s 0 0 0x0 0x0 0x0
>
> This patch series is a follow-up of "[Qemu-devel] [RFC v2 0/6]
> SDM Interface":
> https://lists.gnu.org/archive/html/qemu-devel/2016-03/msg04492.html
>
> This work has been sponsored by Huawei Technologies Duesseldorf GmbH.
>
> ---
> Changes since v2:
> - added virtio device configuration space
> - added configuration accessory methods
> - fixed bug in local communication channel
> - aligned virto device ID with specification RFC
> ---
>
> Baptiste Reynal (6):
>   hw/misc: sdm interface
>   hw/misc: sdm platform device
>   hw/arm: sysbus-fdt
>   hw/misc: sdm virtio device
>   hw/misc: sdm communication local
>   hw/misc: sdm communication socket
>
>  default-configs/arm-softmmu.mak            |   1 +
>  hw/arm/sysbus-fdt.c                        |  62 ++++++
>  hw/misc/Makefile.objs                      |   7 +
>  hw/misc/sdm-communication-local.c          | 116 +++++++++++
>  hw/misc/sdm-communication-socket.c         | 160 +++++++++++++++
>  hw/misc/sdm-communication.c                |  68 +++++++
>  hw/misc/sdm-device.c                       |  78 ++++++++
>  hw/misc/sdm-platform.c                     | 231 ++++++++++++++++++++++
>  hw/misc/sdm-signal.c                       |  52 +++++
>  hw/virtio/Makefile.objs                    |   1 +
>  hw/virtio/virtio-sdm.c                     | 303
> +++++++++++++++++++++++++++++
>  include/hw/misc/sdm-communication-local.h  |  35 ++++
>  include/hw/misc/sdm-communication-socket.h |  42 ++++
>  include/hw/misc/sdm-communication.h        |  60 ++++++
>  include/hw/misc/sdm-device.h               |  61 ++++++
>  include/hw/misc/sdm-platform.h             |  65 +++++++
>  include/hw/misc/sdm-signal.h               |  61 ++++++
>  include/hw/virtio/virtio-sdm.h             |  58 ++++++
>  linux-headers/linux/virtio_sdm.h           |  58 ++++++
>  19 files changed, 1519 insertions(+)
>  create mode 100644 hw/misc/sdm-communication-local.c
>  create mode 100644 hw/misc/sdm-communication-socket.c
>  create mode 100644 hw/misc/sdm-communication.c
>  create mode 100644 hw/misc/sdm-device.c
>  create mode 100644 hw/misc/sdm-platform.c
>  create mode 100644 hw/misc/sdm-signal.c
>  create mode 100644 hw/virtio/virtio-sdm.c
>  create mode 100644 include/hw/misc/sdm-communication-local.h
>  create mode 100644 include/hw/misc/sdm-communication-socket.h
>  create mode 100644 include/hw/misc/sdm-communication.h
>  create mode 100644 include/hw/misc/sdm-device.h
>  create mode 100644 include/hw/misc/sdm-platform.h
>  create mode 100644 include/hw/misc/sdm-signal.h
>  create mode 100644 include/hw/virtio/virtio-sdm.h
>  create mode 100644 linux-headers/linux/virtio_sdm.h
>
> --
> 1.9.1
>
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [virtio-dev] Re: [RFC v3 0/6] SDM Interface
  2016-06-30  8:26 ` [Qemu-devel] [RFC v3 0/6] SDM Interface Christian Pinto
@ 2016-06-30  8:47   ` Stefan Hajnoczi
  2016-06-30 11:44     ` Christian Pinto
  0 siblings, 1 reply; 10+ messages in thread
From: Stefan Hajnoczi @ 2016-06-30  8:47 UTC (permalink / raw)
  To: Christian Pinto
  Cc: qemu-devel@nongnu.org Developers, Baptiste Reynal,
	VirtualOpenSystems Technical Team, Claudio Fontana,
	Jani Kokkonen, virtio-dev

[-- Attachment #1: Type: text/plain, Size: 296 bytes --]

On Thu, Jun 30, 2016 at 10:26:56AM +0200, Christian Pinto wrote:
> Ping...
> 
> are there any comments?

Hi Christian,
I will be away until Thursday and focussed on the virtio device
specification first.  Maybe others can give you feedback on the QEMU
patches in the meantime.

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [virtio-dev] Re: [RFC v3 0/6] SDM Interface
  2016-06-30  8:47   ` [Qemu-devel] [virtio-dev] " Stefan Hajnoczi
@ 2016-06-30 11:44     ` Christian Pinto
  0 siblings, 0 replies; 10+ messages in thread
From: Christian Pinto @ 2016-06-30 11:44 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: qemu-devel@nongnu.org Developers, Baptiste Reynal,
	VirtualOpenSystems Technical Team, Claudio Fontana,
	Jani Kokkonen, virtio-dev, Christian Pinto

Thanks a lot Stefan.

Looking forward for your feedback.


Christian

On Thu, Jun 30, 2016 at 10:47 AM, Stefan Hajnoczi <stefanha@redhat.com>
wrote:

> On Thu, Jun 30, 2016 at 10:26:56AM +0200, Christian Pinto wrote:
> > Ping...
> >
> > are there any comments?
>
> Hi Christian,
> I will be away until Thursday and focussed on the virtio device
> specification first.  Maybe others can give you feedback on the QEMU
> patches in the meantime.
>
> Stefan
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2016-06-30 11:44 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-17 15:54 [Qemu-devel] [RFC v3 0/6] SDM Interface Christian Pinto
2016-06-17 15:54 ` [Qemu-devel] [RFC v3 1/6] hw/misc: sdm interface Christian Pinto
2016-06-17 15:54 ` [Qemu-devel] [RFC v3 2/6] hw/misc: sdm platform device Christian Pinto
2016-06-17 15:55 ` [Qemu-devel] [RFC v3 3/6] hw/arm: sysbus-fdt Christian Pinto
2016-06-17 15:55 ` [Qemu-devel] [RFC v3 4/6] hw/misc: sdm virtio device Christian Pinto
2016-06-17 15:55 ` [Qemu-devel] [RFC v3 5/6] hw/misc: sdm communication local Christian Pinto
2016-06-17 15:55 ` [Qemu-devel] [RFC v3 6/6] hw/misc: sdm communication socket Christian Pinto
2016-06-30  8:26 ` [Qemu-devel] [RFC v3 0/6] SDM Interface Christian Pinto
2016-06-30  8:47   ` [Qemu-devel] [virtio-dev] " Stefan Hajnoczi
2016-06-30 11:44     ` Christian Pinto

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.