From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53236) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bDw7N-0006el-9I for qemu-devel@nongnu.org; Fri, 17 Jun 2016 11:55:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bDw7K-00019d-Ar for qemu-devel@nongnu.org; Fri, 17 Jun 2016 11:55:35 -0400 Received: from mail-wm0-x243.google.com ([2a00:1450:400c:c09::243]:36645) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bDw7K-00019O-0f for qemu-devel@nongnu.org; Fri, 17 Jun 2016 11:55:34 -0400 Received: by mail-wm0-x243.google.com with SMTP id m124so722575wme.3 for ; Fri, 17 Jun 2016 08:55:33 -0700 (PDT) From: Christian Pinto Date: Fri, 17 Jun 2016 17:55:02 +0200 Message-Id: <1466178903-2184-6-git-send-email-c.pinto@virtualopensystems.com> In-Reply-To: <1466178903-2184-1-git-send-email-c.pinto@virtualopensystems.com> References: <1466178903-2184-1-git-send-email-c.pinto@virtualopensystems.com> Subject: [Qemu-devel] [RFC v3 5/6] hw/misc: sdm communication local List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: b.reynal@virtualopensystems.com, tech@virtualopensystems.com, Claudio.Fontana@huawei.com, Jani.Kokkonen@huawei.com, Christian Pinto From: Baptiste Reynal 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= Signed-off-by: Baptiste Reynal Signed-off-by: Christian Pinto --- 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 + * Christian Pinto + * + * 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 + * + * 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