@@ -109,3 +109,4 @@ CONFIG_IOH3420=y
CONFIG_I82801B11=y
CONFIG_ACPI=y
CONFIG_SMBIOS=y
+CONFIG_SDM=y
@@ -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
new file mode 100644
@@ -0,0 +1,55 @@
+/*
+ * SDM Communication
+ *
+ * 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-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;
+ }
+}
+
+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);
new file mode 100644
@@ -0,0 +1,66 @@
+/*
+ * 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-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;
+ }
+}
+
+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)
new file mode 100644
@@ -0,0 +1,52 @@
+/*
+ * 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);
new file mode 100644
@@ -0,0 +1,54 @@
+/*
+ * SDM Communication
+ *
+ * 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_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);
+};
+
+/**
+ * @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);
+#endif
new file mode 100644
@@ -0,0 +1,58 @@
+/*
+ * SDM Device
+ *
+ * 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_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);
+ 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);
+bool sdm_device_is_master(SDMDevice *sdm);
+#endif
new file mode 100644
@@ -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
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> --- default-configs/arm-softmmu.mak | 1 + hw/misc/Makefile.objs | 4 +++ hw/misc/sdm-communication.c | 55 +++++++++++++++++++++++++++++++ hw/misc/sdm-device.c | 66 +++++++++++++++++++++++++++++++++++++ hw/misc/sdm-signal.c | 52 +++++++++++++++++++++++++++++ include/hw/misc/sdm-communication.h | 54 ++++++++++++++++++++++++++++++ include/hw/misc/sdm-device.h | 58 ++++++++++++++++++++++++++++++++ include/hw/misc/sdm-signal.h | 60 +++++++++++++++++++++++++++++++++ 8 files changed, 350 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