[PATCH v2 4/4] remoteproc: qcom: Introduce WCNSS peripheral image loader
This introduces the peripheral image loader, for loading WCNSS firmware and boot the core on e.g. MSM8974. The firmware is verified and booted with the help of the Peripheral Authentication System (PAS) in TrustZone. Signed-off-by: Bjorn Andersson --- Changes since v1: - Hard coding SMEM id for crash-reason and firmware name All dependencies has been merges since v1. drivers/remoteproc/Kconfig | 11 + drivers/remoteproc/Makefile | 2 + drivers/remoteproc/qcom_mdt_loader.c | 213 ++ drivers/remoteproc/qcom_mdt_loader.h | 8 + drivers/remoteproc/qcom_wcnss.c | 550 +++ 5 files changed, 784 insertions(+) create mode 100644 drivers/remoteproc/qcom_mdt_loader.c create mode 100644 drivers/remoteproc/qcom_mdt_loader.h create mode 100644 drivers/remoteproc/qcom_wcnss.c diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index 28c711f0ac6b..f4eb07907851 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -77,4 +77,15 @@ config DA8XX_REMOTEPROC It's safe to say n here if you're not interested in multimedia offloading. +config QCOM_MDT_LOADER + tristate + +config QCOM_WCNSS_PIL + tristate "Qualcomm WCNSS Peripheral Image Loader" + depends on OF && ARCH_QCOM + select REMOTEPROC + select QCOM_MDT_LOADER + help + Peripherial Image Loader for the WCNSS block. + endmenu diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile index 81b04d1e2e58..beb9a4be7ffd 100644 --- a/drivers/remoteproc/Makefile +++ b/drivers/remoteproc/Makefile @@ -11,3 +11,5 @@ obj-$(CONFIG_OMAP_REMOTEPROC) += omap_remoteproc.o obj-$(CONFIG_STE_MODEM_RPROC) += ste_modem_rproc.o obj-$(CONFIG_WKUP_M3_RPROC)+= wkup_m3_rproc.o obj-$(CONFIG_DA8XX_REMOTEPROC) += da8xx_remoteproc.o +obj-$(CONFIG_QCOM_MDT_LOADER) += qcom_mdt_loader.o +obj-$(CONFIG_QCOM_WCNSS_PIL) += qcom_wcnss.o diff --git a/drivers/remoteproc/qcom_mdt_loader.c b/drivers/remoteproc/qcom_mdt_loader.c new file mode 100644 index ..30d67f3e63c1 --- /dev/null +++ b/drivers/remoteproc/qcom_mdt_loader.c @@ -0,0 +1,213 @@ +/* + * Qualcomm Peripheral Image Loader + * + * Copyright (C) 2015 Sony Mobile Communications Inc + * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "remoteproc_internal.h" + +#define segment_is_hash(flag) (((flag) & (0x7 << 24)) == (0x2 << 24)) + +static int segment_is_loadable(const struct elf32_phdr *p) +{ + return (p->p_type == PT_LOAD) && + !segment_is_hash(p->p_flags) && + p->p_memsz; +} + +/** + * rproc_mdt_sanity_check() - sanity check mdt firmware header + * @rproc: the remote processor handle + * @fw: the mdt header firmware image + * + * Returns 0 for a valid header, -EINVAL otherwise. + */ +int qcom_mdt_sanity_check(struct rproc *rproc, + const struct firmware *fw) +{ + struct elf32_hdr *ehdr; + + if (!fw) { + dev_err(>dev, "failed to load %s\n", rproc->name); + return -EINVAL; + } + + if (fw->size < sizeof(struct elf32_hdr)) { + dev_err(>dev, "image is too small\n"); + return -EINVAL; + } + + ehdr = (struct elf32_hdr *)fw->data; + if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) { + dev_err(>dev, "image is corrupted (bad magic)\n"); + return -EINVAL; + } + + if (ehdr->e_phnum == 0) { + dev_err(>dev, "no loadable segments\n"); + return -EINVAL; + } + + if (sizeof(struct elf32_phdr) * ehdr->e_phnum + + sizeof(struct elf32_hdr) > fw->size) { + dev_err(>dev, "firmware size is too small\n"); + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL_GPL(qcom_mdt_sanity_check); + +/** + * qcom_mdt_find_rsc_table() - provide dummy resource table for remoteproc + * @rproc: remoteproc handle + * @fw:firmware header + * @tablesz: outgoing size of the table + * + * Returns a dummy table. + */ +struct resource_table *qcom_mdt_find_rsc_table(struct rproc *rproc, + const struct firmware *fw, +
[PATCH v2 4/4] remoteproc: qcom: Introduce WCNSS peripheral image loader
This introduces the peripheral image loader, for loading WCNSS firmware and boot the core on e.g. MSM8974. The firmware is verified and booted with the help of the Peripheral Authentication System (PAS) in TrustZone. Signed-off-by: Bjorn Andersson--- Changes since v1: - Hard coding SMEM id for crash-reason and firmware name All dependencies has been merges since v1. drivers/remoteproc/Kconfig | 11 + drivers/remoteproc/Makefile | 2 + drivers/remoteproc/qcom_mdt_loader.c | 213 ++ drivers/remoteproc/qcom_mdt_loader.h | 8 + drivers/remoteproc/qcom_wcnss.c | 550 +++ 5 files changed, 784 insertions(+) create mode 100644 drivers/remoteproc/qcom_mdt_loader.c create mode 100644 drivers/remoteproc/qcom_mdt_loader.h create mode 100644 drivers/remoteproc/qcom_wcnss.c diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index 28c711f0ac6b..f4eb07907851 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -77,4 +77,15 @@ config DA8XX_REMOTEPROC It's safe to say n here if you're not interested in multimedia offloading. +config QCOM_MDT_LOADER + tristate + +config QCOM_WCNSS_PIL + tristate "Qualcomm WCNSS Peripheral Image Loader" + depends on OF && ARCH_QCOM + select REMOTEPROC + select QCOM_MDT_LOADER + help + Peripherial Image Loader for the WCNSS block. + endmenu diff --git a/drivers/remoteproc/Makefile b/drivers/remoteproc/Makefile index 81b04d1e2e58..beb9a4be7ffd 100644 --- a/drivers/remoteproc/Makefile +++ b/drivers/remoteproc/Makefile @@ -11,3 +11,5 @@ obj-$(CONFIG_OMAP_REMOTEPROC) += omap_remoteproc.o obj-$(CONFIG_STE_MODEM_RPROC) += ste_modem_rproc.o obj-$(CONFIG_WKUP_M3_RPROC)+= wkup_m3_rproc.o obj-$(CONFIG_DA8XX_REMOTEPROC) += da8xx_remoteproc.o +obj-$(CONFIG_QCOM_MDT_LOADER) += qcom_mdt_loader.o +obj-$(CONFIG_QCOM_WCNSS_PIL) += qcom_wcnss.o diff --git a/drivers/remoteproc/qcom_mdt_loader.c b/drivers/remoteproc/qcom_mdt_loader.c new file mode 100644 index ..30d67f3e63c1 --- /dev/null +++ b/drivers/remoteproc/qcom_mdt_loader.c @@ -0,0 +1,213 @@ +/* + * Qualcomm Peripheral Image Loader + * + * Copyright (C) 2015 Sony Mobile Communications Inc + * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "remoteproc_internal.h" + +#define segment_is_hash(flag) (((flag) & (0x7 << 24)) == (0x2 << 24)) + +static int segment_is_loadable(const struct elf32_phdr *p) +{ + return (p->p_type == PT_LOAD) && + !segment_is_hash(p->p_flags) && + p->p_memsz; +} + +/** + * rproc_mdt_sanity_check() - sanity check mdt firmware header + * @rproc: the remote processor handle + * @fw: the mdt header firmware image + * + * Returns 0 for a valid header, -EINVAL otherwise. + */ +int qcom_mdt_sanity_check(struct rproc *rproc, + const struct firmware *fw) +{ + struct elf32_hdr *ehdr; + + if (!fw) { + dev_err(>dev, "failed to load %s\n", rproc->name); + return -EINVAL; + } + + if (fw->size < sizeof(struct elf32_hdr)) { + dev_err(>dev, "image is too small\n"); + return -EINVAL; + } + + ehdr = (struct elf32_hdr *)fw->data; + if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) { + dev_err(>dev, "image is corrupted (bad magic)\n"); + return -EINVAL; + } + + if (ehdr->e_phnum == 0) { + dev_err(>dev, "no loadable segments\n"); + return -EINVAL; + } + + if (sizeof(struct elf32_phdr) * ehdr->e_phnum + + sizeof(struct elf32_hdr) > fw->size) { + dev_err(>dev, "firmware size is too small\n"); + return -EINVAL; + } + + return 0; +} +EXPORT_SYMBOL_GPL(qcom_mdt_sanity_check); + +/** + * qcom_mdt_find_rsc_table() - provide dummy resource table for remoteproc + * @rproc: remoteproc handle + * @fw:firmware header + * @tablesz: outgoing size of the table + * + * Returns a dummy table. + */ +struct resource_table *qcom_mdt_find_rsc_table(struct rproc *rproc, + const struct firmware *fw,