From patchwork Wed Mar 4 16:18:26 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Auger Eric X-Patchwork-Id: 45427 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-we0-f198.google.com (mail-we0-f198.google.com [74.125.82.198]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 7A1AA204BC for ; Wed, 4 Mar 2015 16:18:48 +0000 (UTC) Received: by wesq59 with SMTP id q59sf34873351wes.2 for ; Wed, 04 Mar 2015 08:18:47 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:x-original-sender :x-original-authentication-results:precedence:mailing-list:list-id :list-post:list-help:list-archive:list-unsubscribe; bh=f/3YZgENHa4klSUyP405zev9JjWncZuE7V2ERm/ZuKk=; b=jzV+5ZSRxOB/OK8o61vjOqzQTbCIlXEfNLd2aAMzaW6H2gj1mW2UxuPRgUhERpcs/E yWQMj4pOtLmSzd9t/67jwAVSKgmD/ELD+thJup3xbtPKF7VjEZzEMzKTdX+K53Zgs3eH EcW8vT/isU8aEeimlg3pMrIMmyoa8yrZS3cpaOlVyRUag6O5PYOUf94dnzeGUqATxXpd DkeC0+FLBmD29D5p6dExzXZhAJXmBr6qecFGMEqun65S3BdIIYEb0gnwDrH4dfLFJsFQ QmXhWEQGiraEPzxxKEZ6kIisccTWyh6m3fx4IfjESpwWOBNT2XNo/WG/3zuwLL2a2N5I +fQg== X-Gm-Message-State: ALoCoQk5ONyYfljrmBqyhd8Sdzl9+QaclvVNXEo+cvfZq1xu3gDYkSIVy/HzupSXXwFDBQkiVxHG X-Received: by 10.112.40.81 with SMTP id v17mr812715lbk.5.1425485927721; Wed, 04 Mar 2015 08:18:47 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.115.180 with SMTP id jp20ls185766lab.64.gmail; Wed, 04 Mar 2015 08:18:47 -0800 (PST) X-Received: by 10.152.28.233 with SMTP id e9mr4155003lah.3.1425485927546; Wed, 04 Mar 2015 08:18:47 -0800 (PST) Received: from mail-lb0-f171.google.com (mail-lb0-f171.google.com. [209.85.217.171]) by mx.google.com with ESMTPS id qs6si2819678lbb.49.2015.03.04.08.18.47 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 04 Mar 2015 08:18:47 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.171 as permitted sender) client-ip=209.85.217.171; Received: by lbdu14 with SMTP id u14so24203392lbd.0 for ; Wed, 04 Mar 2015 08:18:47 -0800 (PST) X-Received: by 10.152.178.197 with SMTP id da5mr4337883lac.56.1425485927411; Wed, 04 Mar 2015 08:18:47 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patches@linaro.org Received: by 10.112.35.133 with SMTP id h5csp1318629lbj; Wed, 4 Mar 2015 08:18:46 -0800 (PST) X-Received: by 10.194.216.34 with SMTP id on2mr10088939wjc.24.1425485923515; Wed, 04 Mar 2015 08:18:43 -0800 (PST) Received: from mail-we0-f172.google.com (mail-we0-f172.google.com. [74.125.82.172]) by mx.google.com with ESMTPS id eq4si7766071wjd.112.2015.03.04.08.18.43 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 04 Mar 2015 08:18:43 -0800 (PST) Received-SPF: pass (google.com: domain of eric.auger@linaro.org designates 74.125.82.172 as permitted sender) client-ip=74.125.82.172; Received: by wevk48 with SMTP id k48so811815wev.5 for ; Wed, 04 Mar 2015 08:18:43 -0800 (PST) X-Received: by 10.181.13.146 with SMTP id ey18mr57906645wid.84.1425485923176; Wed, 04 Mar 2015 08:18:43 -0800 (PST) Received: from midway01-04-00.lavalab ([81.128.185.50]) by mx.google.com with ESMTPSA id g5sm6607766wjr.19.2015.03.04.08.18.42 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 04 Mar 2015 08:18:42 -0800 (PST) From: Eric Auger To: eric.auger@st.com, qemu-devel@nongnu.org, peter.maydell@linaro.org Cc: eric.auger@linaro.org, christoffer.dall@linaro.org, kvmarm@lists.cs.columbia.edu, patches@linaro.org, agraf@suse.de, pbonzini@redhat.com, b.reynal@virtualopensystems.com Subject: [PATCH v11 1/4] hw/arm/sysbus-fdt: helpers for platform bus nodes addition Date: Wed, 4 Mar 2015 16:18:26 +0000 Message-Id: <1425485909-5091-2-git-send-email-eric.auger@linaro.org> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1425485909-5091-1-git-send-email-eric.auger@linaro.org> References: <1425485909-5091-1-git-send-email-eric.auger@linaro.org> X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: eric.auger@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.171 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Precedence: list Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org List-ID: X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , This new C module will be used by ARM machine files to generate platform bus node and their dynamic sysbus device tree nodes. Dynamic sysbus device node addition is done in a machine init done notifier. arm_register_platform_bus_fdt_creator does the registration of this latter and is supposed to be called by ARM machine files that support platform bus and their dynamic sysbus. Addition of dynamic sysbus nodes is done only if the user did not provide any dtb. Signed-off-by: Alexander Graf Signed-off-by: Eric Auger Reviewed-by: Shannon Zhao Reviewed-by: Alexander Graf Reviewed-by: Alex Bennée --- v9 -> v10: - add assert and exit in add_fdt_node v8 -> v9: - s/Fdt/FDT in struct type names - reorder fields in PlatformBusFdtNotifierParams and use DO_UPCAST instead of container_of - use assert() when relevant (board model issue) - g_free the ARMPlatformBusFDTParams and PlatformBusFDTNotifierParams pointers in platform_bus_fdt_notify v7 -> v8: add Reviewed-by from Alex and Shannon v6 -> v7: - revert indentation in add_fdt_node_functions v5 -> v6: - add_all_platform_bus_fdt_nodes is not a modify_dtb function anymore - it now takes a handle to an ARMPlatformBusFdtParams. - fdt pointer is checked in case this notifier is executed after the one that executes the load_dtb (this latter deallocates the fdt pointer) - check of fdt_filename moved in here. - upgrade_dtb is removed - copyright aligned between .h and .c v4 -> v5: - change indentation in add_fdt_node_functions. Also becomes a static const. - ARMPlatformBusFdtParams.system_params becomes a pointer to a const ARMPlatformBusSystemParams - removes platform-bus.h second inclusion v3 -> v4: - dyn_sysbus_devtree.c renamed into sysbus-fdt.c - use new PlatformBusDevice object - the dtb upgrade is done through modify_dtb. Before the fdt was recreated from scratch. When the user provided a dtb this latter was overwritten which was not correct. - an array contains the association between device type names and their node creation function - I must aknowledge I did not find any cleaner way to implement a FDT_BUILDER interface, as suggested by Paolo. The class method would need to be initialized somewhere and since it cannot happen in the device itself - according to Alex & Peter comments -, I don't see when I shall associate the device type and its interface implementation. v2 -> v3: - add arm_ prefix - arm_sysbus_device_create_devtree becomes static v1 -> v2: - Code moved in an arch specific file to accomodate architecture dependent specificities. - remove platform_bus_base from PlatformDevtreeData v1: code originally written by Alex Graf in e500.c and reused for ARM [Eric Auger] --- hw/arm/Makefile.objs | 1 + hw/arm/sysbus-fdt.c | 174 ++++++++++++++++++++++++++++++++++++++++++++ include/hw/arm/sysbus-fdt.h | 60 +++++++++++++++ 3 files changed, 235 insertions(+) create mode 100644 hw/arm/sysbus-fdt.c create mode 100644 include/hw/arm/sysbus-fdt.h diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 6088e53..0cc63e1 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -3,6 +3,7 @@ obj-$(CONFIG_DIGIC) += digic_boards.o obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o +obj-y += sysbus-fdt.o obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o obj-$(CONFIG_DIGIC) += digic.o diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c new file mode 100644 index 0000000..3038b94 --- /dev/null +++ b/hw/arm/sysbus-fdt.c @@ -0,0 +1,174 @@ +/* + * ARM Platform Bus device tree generation helpers + * + * Copyright (c) 2014 Linaro Limited + * + * Authors: + * Alex Graf + * Eric Auger + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + */ + +#include "hw/arm/sysbus-fdt.h" +#include "qemu/error-report.h" +#include "sysemu/device_tree.h" +#include "hw/platform-bus.h" +#include "sysemu/sysemu.h" + +/* + * internal struct that contains the information to create dynamic + * sysbus device node + */ +typedef struct PlatformBusFDTData { + void *fdt; /* device tree handle */ + int irq_start; /* index of the first IRQ usable by platform bus devices */ + const char *pbus_node_name; /* name of the platform bus node */ + PlatformBusDevice *pbus; +} PlatformBusFDTData; + +/* + * struct used when calling the machine init done notifier + * that constructs the fdt nodes of platform bus devices + */ +typedef struct PlatformBusFDTNotifierParams { + Notifier notifier; + ARMPlatformBusFDTParams *fdt_params; +} PlatformBusFDTNotifierParams; + +/* struct that associates a device type name and a node creation function */ +typedef struct NodeCreationPair { + const char *typename; + int (*add_fdt_node_fn)(SysBusDevice *sbdev, void *opaque); +} NodeCreationPair; + +/* list of supported dynamic sysbus devices */ +static const NodeCreationPair add_fdt_node_functions[] = { + {"", NULL}, /* last element */ +}; + +/** + * add_fdt_node - add the device tree node of a dynamic sysbus device + * + * @sbdev: handle to the sysbus device + * @opaque: handle to the PlatformBusFDTData + * + * Checks the sysbus type belongs to the list of device types that + * are dynamically instantiable and if so call the node creation + * function. + */ +static int add_fdt_node(SysBusDevice *sbdev, void *opaque) +{ + int i, ret; + + for (i = 0; i < ARRAY_SIZE(add_fdt_node_functions); i++) { + if (!strcmp(object_get_typename(OBJECT(sbdev)), + add_fdt_node_functions[i].typename)) { + ret = add_fdt_node_functions[i].add_fdt_node_fn(sbdev, opaque); + assert(!ret); + return 0; + } + } + error_report("Device %s can not be dynamically instantiated", + qdev_fw_name(DEVICE(sbdev))); + exit(1); +} + +/** + * add_all_platform_bus_fdt_nodes - create all the platform bus nodes + * + * builds the parent platform bus node and all the nodes of dynamic + * sysbus devices attached to it. + */ +static void add_all_platform_bus_fdt_nodes(ARMPlatformBusFDTParams *fdt_params) +{ + const char platcomp[] = "qemu,platform\0simple-bus"; + PlatformBusDevice *pbus; + DeviceState *dev; + gchar *node; + uint64_t addr, size; + int irq_start, dtb_size; + struct arm_boot_info *info = fdt_params->binfo; + const ARMPlatformBusSystemParams *params = fdt_params->system_params; + const char *intc = fdt_params->intc; + void *fdt = info->get_dtb(info, &dtb_size); + + /* + * If the user provided a dtb, we assume the dynamic sysbus nodes + * already are integrated there. This corresponds to a use case where + * the dynamic sysbus nodes are complex and their generation is not yet + * supported. In that case the user can take charge of the guest dt + * while qemu takes charge of the qom stuff. + */ + if (info->dtb_filename) { + return; + } + + assert(fdt); + + node = g_strdup_printf("/platform@%"PRIx64, params->platform_bus_base); + addr = params->platform_bus_base; + size = params->platform_bus_size; + irq_start = params->platform_bus_first_irq; + + /* Create a /platform node that we can put all devices into */ + qemu_fdt_add_subnode(fdt, node); + qemu_fdt_setprop(fdt, node, "compatible", platcomp, sizeof(platcomp)); + + /* Our platform bus region is less than 32bits, so 1 cell is enough for + * address and size + */ + qemu_fdt_setprop_cells(fdt, node, "#size-cells", 1); + qemu_fdt_setprop_cells(fdt, node, "#address-cells", 1); + qemu_fdt_setprop_cells(fdt, node, "ranges", 0, addr >> 32, addr, size); + + qemu_fdt_setprop_phandle(fdt, node, "interrupt-parent", intc); + + dev = qdev_find_recursive(sysbus_get_default(), TYPE_PLATFORM_BUS_DEVICE); + pbus = PLATFORM_BUS_DEVICE(dev); + + /* We can only create dt nodes for dynamic devices when they're ready */ + assert(pbus->done_gathering); + + PlatformBusFDTData data = { + .fdt = fdt, + .irq_start = irq_start, + .pbus_node_name = node, + .pbus = pbus, + }; + + /* Loop through all dynamic sysbus devices and create their node */ + foreach_dynamic_sysbus_device(add_fdt_node, &data); + + g_free(node); +} + +static void platform_bus_fdt_notify(Notifier *notifier, void *data) +{ + PlatformBusFDTNotifierParams *p = DO_UPCAST(PlatformBusFDTNotifierParams, + notifier, notifier); + + add_all_platform_bus_fdt_nodes(p->fdt_params); + g_free(p->fdt_params); + g_free(p); +} + +void arm_register_platform_bus_fdt_creator(ARMPlatformBusFDTParams *fdt_params) +{ + PlatformBusFDTNotifierParams *p = g_new(PlatformBusFDTNotifierParams, 1); + + p->fdt_params = fdt_params; + p->notifier.notify = platform_bus_fdt_notify; + qemu_add_machine_init_done_notifier(&p->notifier); +} diff --git a/include/hw/arm/sysbus-fdt.h b/include/hw/arm/sysbus-fdt.h new file mode 100644 index 0000000..e15bb81 --- /dev/null +++ b/include/hw/arm/sysbus-fdt.h @@ -0,0 +1,60 @@ +/* + * Dynamic sysbus device tree node generation API + * + * Copyright Linaro Limited, 2014 + * + * Authors: + * Alex Graf + * Eric Auger + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + * + */ + +#ifndef HW_ARM_SYSBUS_FDT_H +#define HW_ARM_SYSBUS_FDT_H + +#include "hw/arm/arm.h" +#include "qemu-common.h" +#include "hw/sysbus.h" + +/* + * struct that contains dimensioning parameters of the platform bus + */ +typedef struct { + hwaddr platform_bus_base; /* start address of the bus */ + hwaddr platform_bus_size; /* size of the bus */ + int platform_bus_first_irq; /* first hwirq assigned to the bus */ + int platform_bus_num_irqs; /* number of hwirq assigned to the bus */ +} ARMPlatformBusSystemParams; + +/* + * struct that contains all relevant info to build the fdt nodes of + * platform bus and attached dynamic sysbus devices + * in the future might be augmented with additional info + * such as PHY, CLK handles ... + */ +typedef struct { + const ARMPlatformBusSystemParams *system_params; + struct arm_boot_info *binfo; + const char *intc; /* parent interrupt controller name */ +} ARMPlatformBusFDTParams; + +/** + * arm_register_platform_bus_fdt_creator - register a machine init done + * notifier that creates the device tree nodes of the platform bus and + * associated dynamic sysbus devices + */ +void arm_register_platform_bus_fdt_creator(ARMPlatformBusFDTParams *fdt_params); + +#endif