From patchwork Fri Jun 17 15:54:59 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Pinto X-Patchwork-Id: 9184501 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id CA3BB608A2 for ; Fri, 17 Jun 2016 16:07:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AC16327DA4 for ; Fri, 17 Jun 2016 16:07:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9F91E280DE; Fri, 17 Jun 2016 16:07:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A794E27DA4 for ; Fri, 17 Jun 2016 16:07:22 +0000 (UTC) Received: from localhost ([::1]:58678 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bDwIj-0001LR-Hz for patchwork-qemu-devel@patchwork.kernel.org; Fri, 17 Jun 2016 12:07:21 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53210) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bDw7L-0006dp-Cx for qemu-devel@nongnu.org; Fri, 17 Jun 2016 11:55:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bDw7G-000182-4z for qemu-devel@nongnu.org; Fri, 17 Jun 2016 11:55:35 -0400 Received: from mail-wm0-x244.google.com ([2a00:1450:400c:c09::244]:36630) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bDw7F-00017d-QD for qemu-devel@nongnu.org; Fri, 17 Jun 2016 11:55:30 -0400 Received: by mail-wm0-x244.google.com with SMTP id m124so722108wme.3 for ; Fri, 17 Jun 2016 08:55:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=virtualopensystems-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=d/gU0SJubVWJmCUnyWgtgmF4A0x10kMQ0sY35j8Ddjc=; b=oPTEAvoj7a+iZGMvQAUuuuqbL7G6aoNgfezx9Q0yOkeRS6kvHZsDNiweqXqUyN0yUH 5dYqBcGvFXOQlOVCP5j/aub4zxnM3dmyoXqyONw6qaKNvF2tq0lwsON+pmi/sTyDIh+M xq5MyYb7muek0pgAkuokB9Spo9yTSsLfzZeF36CctEocyfuuSBk8sivvt3mP5Q/ybmpZ OMYIHLX93VNCyZHi5bjxk7oQXY0OWEBBxJM5EiXFQAZPESnY8rCCtd9tnv5uTvg5Twj4 cxknZYChWi82CJaeiUax3+qN+WEVM/+4hZ0N1JzcgrdXha6ETXInmyVkgsURcgbJOm+i ka7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=d/gU0SJubVWJmCUnyWgtgmF4A0x10kMQ0sY35j8Ddjc=; b=Yo9jqPlwaD/qFvDEZzLh4zIBi/USQr6D3ol5kTJfnzV+6+v8zQhML+4lL13pJkNDkN r+yA2pQ2mtWpedqXwGlll+ZEmLwm0CXGNUyjwDPBl/1Ssn0wRQEt3GZ8xuHOjaIrxC8S it6eUAHunXtNCwdhPXqxV91PXsACILB9DhIjJDXy2DeHuzoSWoWcXoUeYTthTdApRlMC zh2je6cosGou1ork7OxMkfmdu/4E0Clg/FOISXF2h++v+FPFwWMk2dna79pKwHPl/sVJ YA7EQbXnP0jBLx322fBZB7Gll5gmBhfR+hH0ChtrltMqKBiqbF96NlFX5KhROFssFkJU cdhA== X-Gm-Message-State: ALyK8tLzZAtbhpo78J3idF02VOnSqmArzl9WP866m+qA0+1FMH+4SnPubRmqUDLTPlFXAw== X-Received: by 10.194.200.103 with SMTP id jr7mr3034950wjc.105.1466178929005; Fri, 17 Jun 2016 08:55:29 -0700 (PDT) Received: from bumma.localdomain ([151.67.13.17]) by smtp.googlemail.com with ESMTPSA id q189sm254937wmd.19.2016.06.17.08.55.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 17 Jun 2016 08:55:28 -0700 (PDT) From: Christian Pinto To: qemu-devel@nongnu.org Date: Fri, 17 Jun 2016 17:54:59 +0200 Message-Id: <1466178903-2184-3-git-send-email-c.pinto@virtualopensystems.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1466178903-2184-1-git-send-email-c.pinto@virtualopensystems.com> References: <1466178903-2184-1-git-send-email-c.pinto@virtualopensystems.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2a00:1450:400c:c09::244 Subject: [Qemu-devel] [RFC v3 2/6] hw/misc: sdm platform device X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Claudio.Fontana@huawei.com, Jani.Kokkonen@huawei.com, tech@virtualopensystems.com, b.reynal@virtualopensystems.com, Christian Pinto Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Baptiste Reynal 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 Signed-off-by: Christian Pinto --- 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 + * Baptiste Reynal + * + * 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; inum_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 + * Christian Pinto * * 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 + * Baptiste Reynal + * + * 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 + * Christian Pinto * * This work is licensed under the terms of the GNU GPL, version 2. See * the COPYING file in the top-level directory.