From patchwork Wed Dec 13 22:41:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bjorn Andersson X-Patchwork-Id: 121868 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp6063917qgn; Wed, 13 Dec 2017 14:41:58 -0800 (PST) X-Google-Smtp-Source: ACJfBotYVAk7HXJLorccUNnBKj3Md2wedsKqPAo25g7tDVFL1kW0GCmlQzs8ooSagxABJ3kA/TGu X-Received: by 10.84.128.76 with SMTP id 70mr7251736pla.171.1513204918489; Wed, 13 Dec 2017 14:41:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1513204918; cv=none; d=google.com; s=arc-20160816; b=WgHBFrPYIAiJIlvJd+R2kGS2Ro2K+kbvnkLUM+FYy6NopYCV4q9yKCTqMJqoNu3oIr AIIjW8CNuuxp+otmOifHQB8vza8I+AvX6EU9mb36lizKIA8f96BA6Hk4X60r+QFBzwC8 sL2cnp/mbEMaDw6kyZ+vjE7QNz4gZVqqqwmEQ+imotF8CwcEVOXru5ySuFjLsaVwsOM7 /QXUtuuhVfXysQsb4+3fiH02Ajox8g+G56U88s7cdRpvrmtP0OAH6BUGwd0KDkYy480u PYLPPBgT2iyJISeGKuKks6nJwsGuZLmv52lBa5/LvlTVBDzr5bbs08Pqw+ANQ8bEi25G fbyg== 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=DOQgzMfTDUb90/2B4qbuBm8PYVJoXD6OEUcFe7jgas4=; b=D9tT7C4CbcTDkrK+o/33//inDgd8ZALohyff2jWVL+ZXRN3G9vb8uMZzKpvNok7dSQ odRtVzrWPHHl0XiVfSoOlI+K392VWpZebr3gnIhYgOiL0RVZD/QwC0Ad1NYBq7LHuXV0 sJ6CPM1KlX8otByLLZ9d/EFdNrDvUCV54uW1Hm4nzYtPlqlRxJ9L78BMb9GddyJX4beN juAvkcwjnkRrS8sGxL66+pvwrPknZJBEuY6986JVF0cK9zSVbkOsOHPtR7pvEvAk0Vi4 XfQtU9UMmqF2fGEENA37A0fcWQcpdswXjTvPyebVJZqRXJvLAJkg44TfMk8z7waTQ/Ou mLEQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=GN0mp4rm; 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 l5si1873271pgr.469.2017.12.13.14.41.58; Wed, 13 Dec 2017 14:41:58 -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=GN0mp4rm; 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 S1753003AbdLMWla (ORCPT + 23 others); Wed, 13 Dec 2017 17:41:30 -0500 Received: from mail-pf0-f194.google.com ([209.85.192.194]:43982 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752914AbdLMWlY (ORCPT ); Wed, 13 Dec 2017 17:41:24 -0500 Received: by mail-pf0-f194.google.com with SMTP id e3so2184338pfi.10 for ; Wed, 13 Dec 2017 14:41:23 -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=DOQgzMfTDUb90/2B4qbuBm8PYVJoXD6OEUcFe7jgas4=; b=GN0mp4rmQhSLezPdGjML0c7SxYfpWRfFC/IcukuipZqWn20WVxg5ZTtymb0hWUX5Lo McFZSUWFNtDT5DFUAsnFApPIHMpPHa/RrVsYLqxQGe7lBAP9/xe7AHj+6lG4AAfpxhdG pFQsdqxBjGv+5wX8kRyXJEq6koIPWcyLwYVr8= 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=DOQgzMfTDUb90/2B4qbuBm8PYVJoXD6OEUcFe7jgas4=; b=ONUu206sEgMwHt43GHK9jfQSozv9/R6L4Q4M8+zx7y2JuvZkrbu7Fgnj591KVvCSVm /JSjOvd8qqycuF4JTcsj2xnnBhWVackg9/ZUjZfT6s5xkMVCm+CMESbJeGm3TnXwNNRU nKkQFMV9fOLx375W4gGdNQT6MrJ2MZ7LcD2ctVAuzWRvfC/1jbVDi4N10F8bgVI5WWoq 4cYU3CNMGr0LTrZQELsoGeUM8+dt42t84CItGxEmiQ9qs73dYlYjfm0IYOesuuuF5a3Q vDkD0Tj4PBibE+YnAv8Vf7VqBjxME9wfBRisMnHyU4MZbZb98fY+lJteIEY+1kFxjJUF IObA== X-Gm-Message-State: AKGB3mLRzhKBOlmg5COnKWEMcmvm9nrzP3u/j7kQ7QDmWdOZBWwadQJB ETiAnz7qzY5DkeWxa5T8qUitQw== X-Received: by 10.159.251.151 with SMTP id m23mr7218832pls.347.1513204883036; Wed, 13 Dec 2017 14:41:23 -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 x15sm4464205pfh.27.2017.12.13.14.41.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 13 Dec 2017 14:41:22 -0800 (PST) From: Bjorn Andersson To: Ohad Ben-Cohen , Bjorn Andersson Cc: linux-remoteproc@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 6/8] remoteproc: Move resource table load logic to find Date: Wed, 13 Dec 2017 14:41:09 -0800 Message-Id: <20171213224111.17864-7-bjorn.andersson@linaro.org> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171213224111.17864-1-bjorn.andersson@linaro.org> References: <20171213224111.17864-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 --- drivers/remoteproc/remoteproc_core.c | 32 ++++++-------------------- drivers/remoteproc/remoteproc_elf_loader.c | 37 ++++++++++++++++++------------ drivers/remoteproc/remoteproc_internal.h | 16 +++++-------- include/linux/remoteproc.h | 1 + 4 files changed, 36 insertions(+), 50 deletions(-) -- 2.15.0 diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index 63d88d1d206e..cbd12382b219 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 e21de55e19d1..ec1ada7cc6d7 100644 --- a/include/linux/remoteproc.h +++ b/include/linux/remoteproc.h @@ -344,6 +344,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);