From nobody Mon Feb 9 21:00:00 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1493383609641130.5443317736599; Fri, 28 Apr 2017 05:46:49 -0700 (PDT) Received: from localhost ([::1]:36897 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d45IN-0000oj-RP for importer@patchew.org; Fri, 28 Apr 2017 08:46:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44580) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d45HG-0000FM-R3 for qemu-devel@nongnu.org; Fri, 28 Apr 2017 08:45:40 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d45HD-0004yp-LW for qemu-devel@nongnu.org; Fri, 28 Apr 2017 08:45:38 -0400 Received: from mx1.redhat.com ([209.132.183.28]:57250) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1d45HD-0004yK-B4 for qemu-devel@nongnu.org; Fri, 28 Apr 2017 08:45:35 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 38AA97F4A9; Fri, 28 Apr 2017 12:45:34 +0000 (UTC) Received: from localhost (unknown [10.36.118.5]) by smtp.corp.redhat.com (Postfix) with ESMTP id 029BA8BC2B; Fri, 28 Apr 2017 12:45:28 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 38AA97F4A9 Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=marcandre.lureau@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 38AA97F4A9 From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Date: Fri, 28 Apr 2017 16:45:08 +0400 Message-Id: <20170428124510.23654-2-marcandre.lureau@redhat.com> In-Reply-To: <20170428124510.23654-1-marcandre.lureau@redhat.com> References: <20170428124510.23654-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Fri, 28 Apr 2017 12:45:34 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 1/3] fw_cfg: add DMA register 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: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , somlo@cmu.edu, linux-kernel@vger.kernel.org, mst@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" From: Marc-Andr=C3=A9 Lureau Add an optional kernel module (or command line) parameter using the following syntax: [fw_cfg.]ioport=3D@[::[:]] or [fw_cfg.]mmio=3D@[::[:]] and initializes the register address using given or default offset. Signed-off-by: Marc-Andr=C3=A9 Lureau --- drivers/firmware/qemu_fw_cfg.c | 53 ++++++++++++++++++++++++++++++++------= ---- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c index 0e2011636fbb..614037703530 100644 --- a/drivers/firmware/qemu_fw_cfg.c +++ b/drivers/firmware/qemu_fw_cfg.c @@ -10,20 +10,21 @@ * and select subsets of aarch64), a Device Tree node (on arm), or using * a kernel module (or command line) parameter with the following syntax: * - * [fw_cfg.]ioport=3D@[::] + * [fw_cfg.]ioport=3D@[::[:]] * or - * [fw_cfg.]mmio=3D@[::] + * [fw_cfg.]mmio=3D@[::[:]] * * where: * :=3D size of ioport or mmio range * :=3D physical base address of ioport or mmio range * :=3D (optional) offset of control register * :=3D (optional) offset of data register + * :=3D (optional) offset of dma register * * e.g.: - * fw_cfg.ioport=3D2@0x510:0:1 (the default on x86) + * fw_cfg.ioport=3D2@0x510:0:1:4 (the default on x86) * or - * fw_cfg.mmio=3D0xA@0x9020000:8:0 (the default on arm) + * fw_cfg.mmio=3D0xA@0x9020000:8:0:16 (the default on arm) */ =20 #include @@ -63,6 +64,7 @@ static resource_size_t fw_cfg_p_size; static void __iomem *fw_cfg_dev_base; static void __iomem *fw_cfg_reg_ctrl; static void __iomem *fw_cfg_reg_data; +static void __iomem *fw_cfg_reg_dma; =20 /* atomic access to fw_cfg device (potentially slow i/o, so using mutex) */ static DEFINE_MUTEX(fw_cfg_dev_lock); @@ -118,12 +120,14 @@ static void fw_cfg_io_cleanup(void) # if (defined(CONFIG_ARM) || defined(CONFIG_ARM64)) # define FW_CFG_CTRL_OFF 0x08 # define FW_CFG_DATA_OFF 0x00 +# define FW_CFG_DMA_OFF 0x10 # elif (defined(CONFIG_PPC_PMAC) || defined(CONFIG_SPARC32)) /* ppc/mac,su= n4m */ # define FW_CFG_CTRL_OFF 0x00 # define FW_CFG_DATA_OFF 0x02 # elif (defined(CONFIG_X86) || defined(CONFIG_SPARC64)) /* x86, sun4u */ # define FW_CFG_CTRL_OFF 0x00 # define FW_CFG_DATA_OFF 0x01 +# define FW_CFG_DMA_OFF 0x04 # else # error "QEMU FW_CFG not available on this architecture!" # endif @@ -133,7 +137,7 @@ static void fw_cfg_io_cleanup(void) static int fw_cfg_do_platform_probe(struct platform_device *pdev) { char sig[FW_CFG_SIG_SIZE]; - struct resource *range, *ctrl, *data; + struct resource *range, *ctrl, *data, *dma; =20 /* acquire i/o range details */ fw_cfg_is_mmio =3D false; @@ -170,6 +174,7 @@ static int fw_cfg_do_platform_probe(struct platform_dev= ice *pdev) /* were custom register offsets provided (e.g. on the command line)? */ ctrl =3D platform_get_resource_byname(pdev, IORESOURCE_REG, "ctrl"); data =3D platform_get_resource_byname(pdev, IORESOURCE_REG, "data"); + dma =3D platform_get_resource_byname(pdev, IORESOURCE_REG, "dma"); if (ctrl && data) { fw_cfg_reg_ctrl =3D fw_cfg_dev_base + ctrl->start; fw_cfg_reg_data =3D fw_cfg_dev_base + data->start; @@ -179,6 +184,13 @@ static int fw_cfg_do_platform_probe(struct platform_de= vice *pdev) fw_cfg_reg_data =3D fw_cfg_dev_base + FW_CFG_DATA_OFF; } =20 + if (dma) + fw_cfg_reg_dma =3D fw_cfg_dev_base + dma->start; +#ifdef FW_CFG_DMA_OFF + else + fw_cfg_reg_dma =3D fw_cfg_dev_base + FW_CFG_DMA_OFF; +#endif + /* verify fw_cfg device signature */ fw_cfg_read_blob(FW_CFG_SIGNATURE, sig, 0, FW_CFG_SIG_SIZE); if (memcmp(sig, "QEMU", FW_CFG_SIG_SIZE) !=3D 0) { @@ -628,6 +640,7 @@ static struct platform_device *fw_cfg_cmdline_dev; /* use special scanf/printf modifier for phys_addr_t, resource_size_t */ #define PH_ADDR_SCAN_FMT "@%" __PHYS_ADDR_PREFIX "i%n" \ ":%" __PHYS_ADDR_PREFIX "i" \ + ":%" __PHYS_ADDR_PREFIX "i%n" \ ":%" __PHYS_ADDR_PREFIX "i%n" =20 #define PH_ADDR_PR_1_FMT "0x%" __PHYS_ADDR_PREFIX "x@" \ @@ -637,12 +650,15 @@ static struct platform_device *fw_cfg_cmdline_dev; ":%" __PHYS_ADDR_PREFIX "u" \ ":%" __PHYS_ADDR_PREFIX "u" =20 +#define PH_ADDR_PR_4_FMT PH_ADDR_PR_3_FMT \ + ":%" __PHYS_ADDR_PREFIX "u" + static int fw_cfg_cmdline_set(const char *arg, const struct kernel_param *= kp) { - struct resource res[3] =3D {}; + struct resource res[4] =3D {}; char *str; phys_addr_t base; - resource_size_t size, ctrl_off, data_off; + resource_size_t size, ctrl_off, data_off, dma_off; int processed, consumed =3D 0; =20 /* only one fw_cfg device can exist system-wide, so if one @@ -658,19 +674,20 @@ static int fw_cfg_cmdline_set(const char *arg, const = struct kernel_param *kp) /* consume "" portion of command line argument */ size =3D memparse(arg, &str); =20 - /* get "@[::]" chunks */ + /* get "@[::[:]]" chunks */ processed =3D sscanf(str, PH_ADDR_SCAN_FMT, &base, &consumed, - &ctrl_off, &data_off, &consumed); + &ctrl_off, &data_off, &consumed, + &dma_off, &consumed); =20 - /* sscanf() must process precisely 1 or 3 chunks: + /* sscanf() must process precisely 1, 3 or 4 chunks: * is mandatory, optionally followed by - * and ; + * and , and ; * there must be no extra characters after the last chunk, * so str[consumed] must be '\0'. */ if (str[consumed] || - (processed !=3D 1 && processed !=3D 3)) + (processed !=3D 1 && processed !=3D 3 && process !=3D 4)) return -EINVAL; =20 res[0].start =3D base; @@ -687,6 +704,11 @@ static int fw_cfg_cmdline_set(const char *arg, const s= truct kernel_param *kp) res[2].start =3D data_off; res[2].flags =3D IORESOURCE_REG; } + if (processed > 3) { + res[3].name =3D "dma"; + res[3].start =3D dma_off; + res[3].flags =3D IORESOURCE_REG; + } =20 /* "processed" happens to nicely match the number of resources * we need to pass in to this platform device. @@ -721,6 +743,13 @@ static int fw_cfg_cmdline_get(char *buf, const struct = kernel_param *kp) fw_cfg_cmdline_dev->resource[0].start, fw_cfg_cmdline_dev->resource[1].start, fw_cfg_cmdline_dev->resource[2].start); + case 4: + return snprintf(buf, PAGE_SIZE, PH_ADDR_PR_4_FMT, + resource_size(&fw_cfg_cmdline_dev->resource[0]), + fw_cfg_cmdline_dev->resource[0].start, + fw_cfg_cmdline_dev->resource[1].start, + fw_cfg_cmdline_dev->resource[2].start, + fw_cfg_cmdline_dev->resource[3].start); } =20 /* Should never get here */ --=20 2.12.0.191.gc5d8de91d