From: Chee, Tien Fong <tien.fong.chee@intel.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [RFC 05/11] arm: K3: Introduce System Firmware loader framework
Date: Tue, 21 May 2019 05:41:52 +0000 [thread overview]
Message-ID: <1558417312.10391.9.camel@intel.com> (raw)
In-Reply-To: <20190516205454.22150-6-dannenberg@ti.com>
On Thu, 2019-05-16 at 15:54 -0500, Andreas Dannenberg wrote:
> Introduce a framework that allows loading the System Firmware (SYSFW)
> binary as well as the associated configuration data from an image
> tree
> blob named "sysfw.itb" from an FS-based boot media using the FS
> loader
> framework.
>
> Signed-off-by: Andreas Dannenberg <dannenberg@ti.com>
> ---
> arch/arm/mach-k3/Kconfig | 22 ++
> arch/arm/mach-k3/Makefile | 3 +
> arch/arm/mach-k3/include/mach/sysfw-loader.h | 12 +
> arch/arm/mach-k3/sysfw-loader.c | 296
> +++++++++++++++++++
> 4 files changed, 333 insertions(+)
> create mode 100644 arch/arm/mach-k3/include/mach/sysfw-loader.h
> create mode 100644 arch/arm/mach-k3/sysfw-loader.c
>
> diff --git a/arch/arm/mach-k3/Kconfig b/arch/arm/mach-k3/Kconfig
> index e677a2e01b..fd28593cec 100644
> --- a/arch/arm/mach-k3/Kconfig
> +++ b/arch/arm/mach-k3/Kconfig
> @@ -58,6 +58,28 @@ config SYS_K3_BOOT_CORE_ID
> int
> default 16
>
> +config K3_LOAD_SYSFW
> + bool
> + depends on SPL
> +
> +config K3_SYSFW_IMAGE_NAME
> + string "File name of SYSFW firmware and configuration blob"
> + depends on K3_LOAD_SYSFW
> + default "sysfw.itb"
> + help
> + Filename of the combined System Firmware and configuration
> image tree
> + blob to be loaded when booting from a filesystem.
> +
> +config K3_SYSFW_IMAGE_SIZE_MAX
> + int "Amount of memory dynamically allocated for loading
> SYSFW blob"
> + depends on K3_LOAD_SYSFW
> + default 269000
> + help
> + Amount of memory (in bytes) reserved through dynamic
> allocation at
> + runtime for loading the combined System Firmware and
> configuration image
> + tree blob. Keep it as tight as possible, as this directly
> affects the
> + overall SPL memory footprint.
> +
> config SYS_K3_SPL_ATF
> bool "Start Cortex-A from SPL"
> depends on SPL && CPU_V7R
> diff --git a/arch/arm/mach-k3/Makefile b/arch/arm/mach-k3/Makefile
> index 0c3a4f7db1..3af7f2ec96 100644
> --- a/arch/arm/mach-k3/Makefile
> +++ b/arch/arm/mach-k3/Makefile
> @@ -7,4 +7,7 @@ obj-$(CONFIG_SOC_K3_AM6) += am6_init.o
> obj-$(CONFIG_ARM64) += arm64-mmu.o
> obj-$(CONFIG_CPU_V7R) += r5_mpu.o lowlevel_init.o
> obj-$(CONFIG_TI_SECURE_DEVICE) += security.o
> +ifeq ($(CONFIG_SPL_BUILD),y)
> +obj-$(CONFIG_K3_LOAD_SYSFW) += sysfw-loader.o
> +endif
> obj-y += common.o
> diff --git a/arch/arm/mach-k3/include/mach/sysfw-loader.h
> b/arch/arm/mach-k3/include/mach/sysfw-loader.h
> new file mode 100644
> index 0000000000..c335c7ed92
> --- /dev/null
> +++ b/arch/arm/mach-k3/include/mach/sysfw-loader.h
> @@ -0,0 +1,12 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti
> .com/
> + * Andreas Dannenberg <dannenberg@ti.com>
> + */
> +
> +#ifndef _SYSFW_LOADER_H_
> +#define _SYSFW_LOADER_H_
> +
> +void k3_sysfw_loader(void (*config_pm_done_callback)(void));
> +
> +#endif
> diff --git a/arch/arm/mach-k3/sysfw-loader.c b/arch/arm/mach-
> k3/sysfw-loader.c
> new file mode 100644
> index 0000000000..1191640acd
> --- /dev/null
> +++ b/arch/arm/mach-k3/sysfw-loader.c
> @@ -0,0 +1,296 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * K3: System Firmware Loader
> + *
> + * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti
> .com/
> + * Andreas Dannenberg <dannenberg@ti.com>
> + */
> +
> +#include <common.h>
> +#include <spl.h>
> +#include <dm.h>
> +#include <dm/uclass-internal.h>
> +#include <dm/pinctrl.h>
> +#include <remoteproc.h>
> +#include <linux/libfdt.h>
> +#include <linux/soc/ti/ti_sci_protocol.h>
> +#include <image.h>
> +#include <malloc.h>
> +#include <fs_loader.h>
> +#include <mmc.h>
> +
> +#include <asm/io.h>
> +#include <asm/spl.h>
> +#include <asm/sections.h>
> +#include <asm/armv7_mpu.h>
> +#include <asm/arch/hardware.h>
> +
> +/* Name of the FIT image nodes for SYSFW and its config data */
> +#define SYSFW_FIRMWARE "sysfw.bin"
> +#define SYSFW_CFG_BOARD "board-cfg.bin"
> +#define SYSFW_CFG_PM "pm-cfg.bin"
> +#define SYSFW_CFG_RM "rm-cfg.bin"
> +#define SYSFW_CFG_SEC "sec-cfg.bin"
> +
> +static int fit_get_data_by_name(const void *fit, int images, const
> char *name,
> + const void **addr, size_t *size)
> +{
> + int node_offset;
> +
> + node_offset = fdt_subnode_offset(fit, images, name);
> + if (node_offset < 0)
> + return -ENOENT;
> +
> + return fit_image_get_data(fit, node_offset, addr, size);
> +}
> +
> +static void k3_sysfw_load_using_fit(void *fit, struct ti_sci_handle
> **ti_sci)
> +{
> + int images;
> + const void *sysfw_addr;
> + size_t sysfw_size;
> + struct udevice *dev;
> + int ret;
> +
> + /* Find the node holding the images information */
> + images = fdt_path_offset(fit, FIT_IMAGES_PATH);
> + if (images < 0)
> + panic("Cannot find /images node (%d)\n", images);
> +
> + /* Extract System Firmware (SYSFW) image from FIT */
> + ret = fit_get_data_by_name(fit, images, SYSFW_FIRMWARE,
> + &sysfw_addr, &sysfw_size);
> + if (ret < 0)
> + panic("Error accessing %s node in FIT (%d)\n",
> SYSFW_FIRMWARE,
> + ret);
> +
> + /*
> + * Start up system controller firmware
> + *
> + * It is assumed that remoteproc device 0 is the
> corresponding
> + * system-controller that runs SYSFW. Make sure DT reflects
> the same.
> + */
> + ret = rproc_dev_init(0);
> + if (ret)
> + panic("rproc failed to be initialized (%d)\n", ret);
> +
> + ret = rproc_load(0, (ulong)sysfw_addr, (ulong)sysfw_size);
> + if (ret)
> + panic("Firmware failed to start on rproc (%d)\n",
> ret);
> +
> + ret = rproc_start(0);
> + if (ret)
> + panic("Firmware init failed on rproc (%d)\n", ret);
> +
> + /* Bring up the Device Management and Security Controller
> (SYSFW) */
> + ret = uclass_get_device_by_name(UCLASS_FIRMWARE, "dmsc",
> &dev);
> + if (ret)
> + panic("Failed to initialize SYSFW (%d)\n", ret);
> +
> + /* Establish handle for easier access */
> + *ti_sci = (struct ti_sci_handle
> *)(ti_sci_get_handle_from_sysfw(dev));
> +}
> +
> +static void k3_sysfw_configure_using_fit(void *fit,
> + struct ti_sci_handle
> *ti_sci,
> + void
> (*config_pm_done_callback)(void))
> +{
> + struct ti_sci_board_ops *board_ops = &ti_sci->ops.board_ops;
> + int images;
> + const void *cfg_fragment_addr;
> + size_t cfg_fragment_size;
> + int ret;
> +
> + /* Find the node holding the images information */
> + images = fdt_path_offset(fit, FIT_IMAGES_PATH);
> + if (images < 0)
> + panic("Cannot find /images node (%d)\n", images);
> +
> + /* Extract board configuration from FIT */
> + ret = fit_get_data_by_name(fit, images, SYSFW_CFG_BOARD,
> + &cfg_fragment_addr,
> &cfg_fragment_size);
> + if (ret < 0)
> + panic("Error accessing %s node in FIT (%d)\n",
> SYSFW_CFG_BOARD,
> + ret);
> +
> + /* Apply board configuration to SYSFW */
> + ret = board_ops->board_config(ti_sci,
> + (u64)(u32)cfg_fragment_addr,
> + (u32)cfg_fragment_size);
> + if (ret)
> + panic("Failed to set board configuration (%d)\n",
> ret);
> +
> + /* Extract power/clock (PM) specific configuration from FIT
> */
> + ret = fit_get_data_by_name(fit, images, SYSFW_CFG_PM,
> + &cfg_fragment_addr,
> &cfg_fragment_size);
> + if (ret < 0)
> + panic("Error accessing %s node in FIT (%d)\n",
> SYSFW_CFG_PM,
> + ret);
> +
> + /* Apply power/clock (PM) specific configuration to SYSFW */
> + ret = board_ops->board_config_pm(ti_sci,
> + (u64)(u32)cfg_fragment_addr
> ,
> + (u32)cfg_fragment_size);
> + if (ret)
> + panic("Failed to set board PM configuration (%d)\n",
> ret);
> +
> + /* Extract resource management (RM) specific configuration
> from FIT */
> + ret = fit_get_data_by_name(fit, images, SYSFW_CFG_RM,
> + &cfg_fragment_addr,
> &cfg_fragment_size);
> + if (ret < 0)
> + panic("Error accessing %s node in FIT (%d)\n",
> SYSFW_CFG_RM,
> + ret);
> +
> + /* Apply resource management (RM) configuration to SYSFW */
> + ret = board_ops->board_config_rm(ti_sci,
> + (u64)(u32)cfg_fragment_addr
> ,
> + (u32)cfg_fragment_size);
> + if (ret)
> + panic("Failed to set board RM configuration (%d)\n",
> ret);
> +
> + /* Extract security specific configuration from FIT */
> + ret = fit_get_data_by_name(fit, images, SYSFW_CFG_SEC,
> + &cfg_fragment_addr,
> &cfg_fragment_size);
> + if (ret < 0)
> + panic("Error accessing %s node in FIT (%d)\n",
> SYSFW_CFG_SEC,
> + ret);
> +
> + /* Apply security configuration to SYSFW */
> + ret = board_ops->board_config_security(ti_sci,
> + (u64)(u32)cfg_fragmen
> t_addr,
> + (u32)cfg_fragment_siz
> e);
> + if (ret)
> + panic("Failed to set board security configuration
> (%d)\n",
> + ret);
> +
> + /*
> + * Now that all clocks and PM aspects are setup, invoke a
> user-
> + * provided callback function. Usually this callback would
> be used
> + * to setup or re-configure the U-Boot console UART.
> + */
> + if (config_pm_done_callback)
> + config_pm_done_callback();
> +}
> +
> +static int k3_sysfw_load_mmc_fs(const char *filename, void *buf,
> size_t max_size)
> +{
> + int mmc_dev;
> + struct udevice *mmcdev;
> + struct mmc *mmc;
> + struct udevice *fsdev;
> + struct device_platdata *plat;
> + int ret;
> +
> + /* Bring up the MMC boot device */
> +
> + mmc_dev = spl_mmc_get_device_index(spl_boot_device());
> + if (mmc_dev < 0) {
> + pr_err("%s: Getting MMC device index failed (%d)\n",
> __func__,
> + mmc_dev);
> + return mmc_dev;
> + }
> +
> + ret = uclass_get_device(UCLASS_MMC, mmc_dev, &mmcdev);
> + if (ret < 0) {
> + pr_err("%s: Getting MMC device failed (%d)\n",
> __func__, ret);
> + return ret;
> + }
> +
> + ret = mmc_initialize(NULL);
> + if (ret < 0) {
> + pr_err("%s: Initializing MMC device failed (%d)\n",
> __func__,
> + ret);
> + return ret;
> + }
> +
> + mmc = mmc_get_mmc_dev(mmcdev);
> + if (!mmc) {
> + pr_err("%s: Getting underlying MMC device failed\n",
> __func__);
> + return -ENODEV;
> + }
> +
> + ret = mmc_init(mmc);
> + if (ret) {
> + printf("%s: mmc init failed with error: %d\n",
> __func__, ret);
> + return ret;
> + }
> +
Can use the fs loader probe for mmc init.
> + /* Use the FS loader framework to perform the actual FW
> loading */
> +
> + ret = uclass_get_device(UCLASS_FS_FIRMWARE_LOADER, 0,
> &fsdev);
> + if (ret < 0) {
> + pr_err("%s: Getting FW loader device failed (%d)\n",
> __func__,
> + ret);
> + return ret;
> + }
> +
> + plat = fsdev->platdata;
> + plat->blkdev = mmcdev;
> + plat->blkpart = CONFIG_SYS_MMCSD_FS_BOOT_PARTITION;
> +
> + return request_firmware_into_buf(fsdev, filename, buf,
> max_size, 0);
> +}
> +
> +void k3_sysfw_loader(void (*config_pm_done_callback)(void))
> +{
> + void *addr;
> + struct spl_boot_device bootdev = { 0 };
> + struct ti_sci_handle *ti_sci;
> + u32 boot_mode;
> + int ret;
> +
> + addr = memalign(ARCH_DMA_MINALIGN,
> CONFIG_K3_SYSFW_IMAGE_SIZE_MAX);
> + if (!addr)
> + panic("Error allocating %u bytes of memory for SYSFW
> image\n",
> + CONFIG_K3_SYSFW_IMAGE_SIZE_MAX);
> +
> + debug("%s: allocated %u bytes at 0x%p\n", __func__,
> + CONFIG_K3_SYSFW_IMAGE_SIZE_MAX, addr);
> +
> + bootdev.boot_device = spl_boot_device();
> + boot_mode = spl_boot_mode(bootdev.boot_device);
> +
> + /* Load combined System Controller firmware and config data
> image */
> + switch (bootdev.boot_device) {
> +#if CONFIG_IS_ENABLED(MMC_SUPPORT)
> + case BOOT_DEVICE_MMC1:
> + case BOOT_DEVICE_MMC2:
> + case BOOT_DEVICE_MMC2_2:
> +#ifdef CONFIG_K3_SYSFW_IMAGE_NAME
> + if (boot_mode == MMCSD_MODE_FS) {
> + ret =
> k3_sysfw_load_mmc_fs(CONFIG_K3_SYSFW_IMAGE_NAME,
> + addr,
> + CONFIG_K3_SYSFW_I
> MAGE_SIZE_MAX);
> + } else
> +#endif
> + {
> + panic("Non-FS load of SYSFW image from
> device %u not supported!\n",
> + bootdev.boot_device);
> + }
> + break;
> +#endif
> + default:
> + panic("Loading SYSFW image from device %u not
> supported!\n",
> + bootdev.boot_device);
> + }
> +
> + if (ret < 0)
> + panic("Error %d occurred during loading SYSFW
> image!\n", ret);
> +
> + /* Ensure the SYSFW image is in FIT format */
> + if (image_get_magic((const image_header_t *)addr) !=
> FDT_MAGIC)
> + panic("SYSFW image not in FIT format!\n");
> +
> + /* Extract and start SYSFW */
> + k3_sysfw_load_using_fit(addr, &ti_sci);
> +
> + /* Parse and apply the different SYSFW configuration
> fragments */
> + k3_sysfw_configure_using_fit(addr, ti_sci,
> config_pm_done_callback);
> +
> + /* Output System Firmware version info */
> + printf("SYSFW ABI: %d.%d (firmware rev 0x%04x '%.*s')\n",
> + ti_sci->version.abi_major, ti_sci->version.abi_minor,
> + ti_sci->version.firmware_revision,
> + sizeof(ti_sci->version.firmware_description),
> + ti_sci->version.firmware_description);
> +}
next prev parent reply other threads:[~2019-05-21 5:41 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-16 20:54 [U-Boot] [RFC 00/11] SYSFW Loader for TI K3 family SoCs using FS Loader Andreas Dannenberg
2019-05-16 20:54 ` [U-Boot] [RFC 01/11] mmc: k3_arasan: Allow driver to probe without PDs specified Andreas Dannenberg
2019-05-16 20:54 ` [U-Boot] [RFC 02/11] spl: Allow skipping clearing BSS during relocation Andreas Dannenberg
2019-05-16 20:54 ` [U-Boot] [RFC 03/11] spl: mmc: Export function to get device index Andreas Dannenberg
2019-05-16 20:54 ` [U-Boot] [RFC 04/11] misc: fs_loader: Allow initializing blkdev using platform data Andreas Dannenberg
2019-05-21 5:40 ` Chee, Tien Fong
2019-05-21 18:37 ` dannenberg at ti.com
2019-05-16 20:54 ` [U-Boot] [RFC 05/11] arm: K3: Introduce System Firmware loader framework Andreas Dannenberg
2019-05-21 5:21 ` Chee, Tien Fong
2019-05-21 18:42 ` dannenberg at ti.com
2019-05-21 5:41 ` Chee, Tien Fong [this message]
2019-05-16 20:54 ` [U-Boot] [RFC 06/11] armV7R: K3: am654: Allow using SPL BSS pre-relocation Andreas Dannenberg
2019-05-16 20:54 ` [U-Boot] [RFC 07/11] armv7R: K3: am654: Use full malloc implementation in SPL Andreas Dannenberg
2019-05-16 20:54 ` [U-Boot] [RFC 08/11] armV7R: K3: am654: Load SYSFW binary and config from boot media Andreas Dannenberg
2019-05-16 20:54 ` [U-Boot] [RFC 09/11] armv7R: dts: k3: am654: Update for loading SYSFW from MMC Andreas Dannenberg
2019-05-21 5:40 ` Chee, Tien Fong
2019-05-21 18:53 ` dannenberg at ti.com
2019-05-16 20:54 ` [U-Boot] [RFC 10/11] configs: am65x_evm_r5: All sysfw to be loaded via MMC Andreas Dannenberg
2019-05-16 20:54 ` [U-Boot] [RFC 11/11] configs: am65x_hs_evm_r5: " Andreas Dannenberg
2019-05-17 11:24 ` [U-Boot] [RFC 00/11] SYSFW Loader for TI K3 family SoCs using FS Loader Tom Rini
2019-05-21 19:04 ` Andreas Dannenberg
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1558417312.10391.9.camel@intel.com \
--to=tien.fong.chee@intel.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.