From patchwork Fri Jan 5 23:58:03 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bjorn Andersson X-Patchwork-Id: 123575 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp1428229qgn; Fri, 5 Jan 2018 15:58:27 -0800 (PST) X-Google-Smtp-Source: ACJfBosP8SzoMgJwrIdqLouVuzckwO0uQ61Hl4/tmOFrOWb4mRtMof7PvFH9HuN+jRIiW9gWxc5Q X-Received: by 10.101.98.216 with SMTP id m24mr3793916pgv.100.1515196707192; Fri, 05 Jan 2018 15:58:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515196707; cv=none; d=google.com; s=arc-20160816; b=MboK8Kc54ZWhY6EOklz86Qb+ulZYRjxd7Hd8VyG7Cdawoy/xAfNnDd0vCEx7EljPpd Ib9JI22cclUr54LYjS3oI9vO91Duc+ub6iQBWuRhkYOfsEvu/lv369eV8sCRGOMEHx1N kWeoCI9CMtBcU0VZyjieTw4+Yd/P5qP+2C96W7zkH+c01DJfu+TIGfjPQwJocNIUQl2N mv1MrrRdNO8Jfick9ZI+9rQS8Aqu/GG+GSk9vObI/JZNi4jLnS06xrWFuY/BBdK9pgA4 keYYd6zJSTWq/XnIsL6eLLmCkjiwNfPu7MlctiHUp5dZoxh6/xNtUS+jYM5BE8+mN8tX pKXA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=Kp5gI5rm/IRFCRZd606gEcuBj2jnQLgx6zq5s0kNi18=; b=BoGmoMb/MO/RBzxUnINL27sA0moHTcm2gC7gwjxFmxMNAJ/JEOcuziv9dkt3psi9Va zFKsFm07wNTsFqFydKzrn7h55HDt+x4fkEjL5ddUtuWaboJwO4l4cATkiJpq8is9E3+Z xKCCmbTcu3Tbq2gHqa25KM8TXUnjQva0UJpTPYxtiWonGQFYIlUfTC7VQcBarNqg17mZ dh359QB+UteddEMcNksjl3RIUfeCKQzRGPhzvEE8qEUP8G1qiHc/OpH3HuYLXYT/coLx +9OY08W9JqKuEjUsx2en8o5XTK16zx5vK1K3YicRJ3kuoU8k67upHmMCdQO1YzDMfmJZ 5AEw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=NCsTAwOt; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 98si4705984pls.543.2018.01.05.15.58.26; Fri, 05 Jan 2018 15:58:27 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=NCsTAwOt; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753454AbeAEX6Z (ORCPT + 28 others); Fri, 5 Jan 2018 18:58:25 -0500 Received: from mail-pg0-f67.google.com ([74.125.83.67]:41209 "EHLO mail-pg0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753386AbeAEX6R (ORCPT ); Fri, 5 Jan 2018 18:58:17 -0500 Received: by mail-pg0-f67.google.com with SMTP id m17so218132pgd.8 for ; Fri, 05 Jan 2018 15:58:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Kp5gI5rm/IRFCRZd606gEcuBj2jnQLgx6zq5s0kNi18=; b=NCsTAwOt1AVdL7I7yKRpZ1E2yEoh6L8g+yKGoJdu3udWe0DJCbGxNqFouBXFmC6Wav Ejd5P+HcnnmA4NgbJOWoDovaQiTeod+ApEAL1zGuxKBdkRHhorz1fN6JFX9aULAuBSkJ 0huPY7UA4M/kyAKqbv/eAMS5RrDKyV5mrOvig= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Kp5gI5rm/IRFCRZd606gEcuBj2jnQLgx6zq5s0kNi18=; b=DCe4uZ4fqKdH+HtH5On9hnansZ2UhZQO0MuDH3thJiNFLcl00rV7IdtfzerBDJeYyd GbDyzsXqJF9q459b/01wgNzRsddGaYtHwjMV9o/rcyXPiRfR97OiI6KoTmVNKm0CdnBy taf1hWEVpt5u/ZPosf+BpjzuJeE20Fw49yP3/4jYCyuTkKAcAcK/lKgemCVNF5n84cu6 iIIjES0HR95d8T819wiLIGc4Pqa3a9A21AAsrmbZ9li4WlrRYsXAhLEUx373BoKlSmY/ ErJAbnNiMdZJp/yj91nloYlueKp9D0mAxaz4S3jPwNutU0eXcrBOItJi05vr8iJs+Rok kTaw== X-Gm-Message-State: AKGB3mLEO/3RGqP13EbLkkRGWiI7kWcVlxg74GTfVYrFmakDFT3gWA4y RGPnLh0xmpVanUjO3VE+Chx3YplEtJI= X-Received: by 10.98.81.67 with SMTP id f64mr4423084pfb.122.1515196696835; Fri, 05 Jan 2018 15:58:16 -0800 (PST) Received: from localhost.localdomain (104-188-17-28.lightspeed.sndgca.sbcglobal.net. [104.188.17.28]) by smtp.gmail.com with ESMTPSA id x4sm14473188pfk.51.2018.01.05.15.58.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 05 Jan 2018 15:58:16 -0800 (PST) From: Bjorn Andersson To: Ohad Ben-Cohen , Bjorn Andersson Cc: linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org, Loic Pallardy Subject: [PATCH v2 6/8] remoteproc: Move resource table load logic to find Date: Fri, 5 Jan 2018 15:58:03 -0800 Message-Id: <20180105235805.9948-7-bjorn.andersson@linaro.org> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20180105235805.9948-1-bjorn.andersson@linaro.org> References: <20180105235805.9948-1-bjorn.andersson@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Extend the previous operation of finding the resource table in the ELF with the extra step of populating the rproc struct with a copy and the size. This allows drivers to override the mechanism used for acquiring the resource table, or omit it for firmware that is known not to have a resource table. This leaves the custom, dummy, find_rsc_table implementations found in some drivers dangling. Signed-off-by: Bjorn Andersson --- Changes since v1: - None drivers/remoteproc/remoteproc_core.c | 32 ++++++-------------------- drivers/remoteproc/remoteproc_elf_loader.c | 37 ++++++++++++++++++------------ drivers/remoteproc/remoteproc_internal.h | 16 +++++-------- include/linux/remoteproc.h | 2 ++ 4 files changed, 37 insertions(+), 50 deletions(-) -- 2.15.0 diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 3160cfe897da..84e07d5b7c2c 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -907,8 +907,7 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) { struct device *dev = &rproc->dev; const char *name = rproc->firmware; - struct resource_table *table; - int ret, tablesz; + int ret; ret = rproc_fw_sanity_check(rproc, fw); if (ret) @@ -927,27 +926,11 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) } rproc->bootaddr = rproc_get_boot_addr(rproc, fw); - ret = -EINVAL; - - /* look for the resource table */ - table = rproc_find_rsc_table(rproc, fw, &tablesz); - if (!table) { - dev_err(dev, "Failed to find resource table\n"); - goto clean_up; - } - - /* - * Create a copy of the resource table. When a virtio device starts - * and calls vring_new_virtqueue() the address of the allocated vring - * will be stored in the cached_table. Before the device is started, - * cached_table will be copied into device memory. - */ - rproc->cached_table = kmemdup(table, tablesz, GFP_KERNEL); - if (!rproc->cached_table) - goto clean_up; - rproc->table_ptr = rproc->cached_table; - rproc->table_sz = tablesz; + /* load resource table */ + ret = rproc_load_rsc_table(rproc, fw); + if (ret) + goto disable_iommu; /* reset max_notifyid */ rproc->max_notifyid = -1; @@ -967,11 +950,10 @@ static int rproc_fw_boot(struct rproc *rproc, const struct firmware *fw) clean_up_resources: rproc_resource_cleanup(rproc); -clean_up: kfree(rproc->cached_table); rproc->cached_table = NULL; rproc->table_ptr = NULL; - +disable_iommu: rproc_disable_iommu(rproc); return ret; } @@ -1443,7 +1425,7 @@ struct rproc *rproc_alloc(struct device *dev, const char *name, /* Default to ELF loader if no load function is specified */ if (!rproc->ops->load) { rproc->ops->load = rproc_elf_load_segments; - rproc->ops->find_rsc_table = rproc_elf_find_rsc_table; + rproc->ops->load_rsc_table = rproc_elf_load_rsc_table; rproc->ops->find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table; rproc->ops->sanity_check = rproc_elf_sanity_check; rproc->ops->get_boot_addr = rproc_elf_get_boot_addr; diff --git a/drivers/remoteproc/remoteproc_elf_loader.c b/drivers/remoteproc/remoteproc_elf_loader.c index 822fa1bf893f..b17d72ec8603 100644 --- a/drivers/remoteproc/remoteproc_elf_loader.c +++ b/drivers/remoteproc/remoteproc_elf_loader.c @@ -268,42 +268,49 @@ find_table(struct device *dev, struct elf32_hdr *ehdr, size_t fw_size) } /** - * rproc_elf_find_rsc_table() - find the resource table + * rproc_elf_load_rsc_table() - load the resource table * @rproc: the rproc handle * @fw: the ELF firmware image - * @tablesz: place holder for providing back the table size * * This function finds the resource table inside the remote processor's - * firmware. It is used both upon the registration of @rproc (in order - * to look for and register the supported virito devices), and when the - * @rproc is booted. + * firmware, load it into the @cached_table and update @table_ptr. * - * Returns the pointer to the resource table if it is found, and write its - * size into @tablesz. If a valid table isn't found, NULL is returned - * (and @tablesz isn't set). + * Return: 0 on success, negative errno on failure. */ -struct resource_table *rproc_elf_find_rsc_table(struct rproc *rproc, - const struct firmware *fw, - int *tablesz) +int rproc_elf_load_rsc_table(struct rproc *rproc, const struct firmware *fw) { struct elf32_hdr *ehdr; struct elf32_shdr *shdr; struct device *dev = &rproc->dev; struct resource_table *table = NULL; const u8 *elf_data = fw->data; + size_t tablesz; ehdr = (struct elf32_hdr *)elf_data; shdr = find_table(dev, ehdr, fw->size); if (!shdr) - return NULL; + return -EINVAL; table = (struct resource_table *)(elf_data + shdr->sh_offset); - *tablesz = shdr->sh_size; + tablesz = shdr->sh_size; + + /* + * Create a copy of the resource table. When a virtio device starts + * and calls vring_new_virtqueue() the address of the allocated vring + * will be stored in the cached_table. Before the device is started, + * cached_table will be copied into device memory. + */ + rproc->cached_table = kmemdup(table, tablesz, GFP_KERNEL); + if (!rproc->cached_table) + return -ENOMEM; - return table; + rproc->table_ptr = rproc->cached_table; + rproc->table_sz = tablesz; + + return 0; } -EXPORT_SYMBOL(rproc_elf_find_rsc_table); +EXPORT_SYMBOL(rproc_elf_load_rsc_table); /** * rproc_elf_find_loaded_rsc_table() - find the loaded resource table diff --git a/drivers/remoteproc/remoteproc_internal.h b/drivers/remoteproc/remoteproc_internal.h index a42690c514e2..55a2950c5cb7 100644 --- a/drivers/remoteproc/remoteproc_internal.h +++ b/drivers/remoteproc/remoteproc_internal.h @@ -57,9 +57,7 @@ int rproc_trigger_recovery(struct rproc *rproc); int rproc_elf_sanity_check(struct rproc *rproc, const struct firmware *fw); u32 rproc_elf_get_boot_addr(struct rproc *rproc, const struct firmware *fw); int rproc_elf_load_segments(struct rproc *rproc, const struct firmware *fw); -struct resource_table *rproc_elf_find_rsc_table(struct rproc *rproc, - const struct firmware *fw, - int *tablesz); +int rproc_elf_load_rsc_table(struct rproc *rproc, const struct firmware *fw); struct resource_table *rproc_elf_find_loaded_rsc_table(struct rproc *rproc, const struct firmware *fw); @@ -90,15 +88,13 @@ int rproc_load_segments(struct rproc *rproc, const struct firmware *fw) return -EINVAL; } -static inline -struct resource_table *rproc_find_rsc_table(struct rproc *rproc, - const struct firmware *fw, - int *tablesz) +static inline int rproc_load_rsc_table(struct rproc *rproc, + const struct firmware *fw) { - if (rproc->ops->find_rsc_table) - return rproc->ops->find_rsc_table(rproc, fw, tablesz); + if (rproc->ops->load_rsc_table) + return rproc->ops->load_rsc_table(rproc, fw); - return NULL; + return 0; } static inline diff --git a/include/linux/remoteproc.h b/include/linux/remoteproc.h index ca2021cf7b39..cc853745e3a1 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -332,6 +332,7 @@ struct firmware; * @stop: power off the device * @kick: kick a virtqueue (virtqueue id given as a parameter) * @da_to_va: optional platform hook to perform address translations + * @load_rsc_table: load resource table from firmware image * @find_rsc_table: find the resource table inside the firmware image * @find_loaded_rsc_table: find the loaded resouce table * @load: load firmeware to memory, where the remote processor @@ -344,6 +345,7 @@ struct rproc_ops { int (*stop)(struct rproc *rproc); void (*kick)(struct rproc *rproc, int vqid); void * (*da_to_va)(struct rproc *rproc, u64 da, int len); + int (*load_rsc_table)(struct rproc *rproc, const struct firmware *fw); struct resource_table *(*find_rsc_table)(struct rproc *rproc, const struct firmware *fw, int *tablesz);