Merge pull request #1761 from satheesbalya-arm/sb1/sb1_2661_bl31_overlay
plat/arm: Save BL2 descriptors to reserved memory.
diff --git a/docs/plat/warp7.rst b/docs/plat/warp7.rst
index 51c2609..6c04d91 100644
--- a/docs/plat/warp7.rst
+++ b/docs/plat/warp7.rst
@@ -31,36 +31,84 @@
make warp7_bl33_defconfig;
make u-boot.imx arch=ARM CROSS_COMPILE=arm-linux-gnueabihf-
-## TF-A:
+## OP-TEE:
-https://github.com/ARM-software/arm-trusted-firmware.git
+https://github.com/OP-TEE/optee_os.git
.. code:: shell
- make CROSS_COMPILE=arm-linux-gnueabihf- PLAT=warp7 ARCH=aarch32 ARM_ARCH_MAJOR=7 ARM_CORTEX_A7=yes AARCH32_SP=optee all
- /path/to/u-boot/tools/mkimage -n /path/to/u-boot/u-boot.cfgout -T imximage -e 0x9df00000 -d ./build/warp7/debug/bl2.bin ./build/warp7/debug/bl2.bin.imx
+ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- PLATFORM=imx PLATFORM_FLAVOR=mx7swarp7 ARCH=arm CFG_PAGEABLE_ADDR=0 CFG_DT_ADDR=0x83000000 CFG_NS_ENTRY_ADDR=0x87800000
-## OP-TEE:
+## TF-A:
-https://github.com/OP-TEE/optee_os.git
+https://github.com/ARM-software/arm-trusted-firmware.git
-.. code:: shell
+The following commands assume that a directory exits in the top-level TFA build
+directory "fiptool_images". "fiptool_images" contains
- make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- PLATFORM=imx PLATFORM_FLAVOR=mx7swarp7 ARCH=arm CFG_PAGEABLE_ADDR=0 CFG_DT_ADDR=0x83000000 CFG_NS_ENTRY_ADDR=0x87800000
+- u-boot.bin
+ The binary output from the u-boot instructions above
+- tee-header_v2.bin
+- tee-pager_v2.bin
+- tee-pageable_v2.bin
+ Binary outputs from the previous OPTEE build steps
-## FIP:
+It is also assumed copy of mbedtls is available on the path path ../mbedtls
+ https://github.com/ARMmbed/mbedtls.git
+ At the time of writing HEAD points to 0592ea772aee48ca1e6d9eb84eca8e143033d973
.. code:: shell
mkdir fiptool_images
- cp /path/to/uboot/u-boot.bin fiptool_images
cp /path/to/optee/out/arm-plat-imx/core/tee-header_v2.bin fiptool_images
cp /path/to/optee/out/arm-plat-imx/core/tee-pager_v2.bin fiptool_images
cp /path/to/optee/out/arm-plat-imx/core/tee-pageable_v2.bin fiptool_images
+
+ make CROSS_COMPILE=${CROSS_COMPILE} PLAT=warp7 ARCH=aarch32 ARM_ARCH_MAJOR=7 \
+ ARM_CORTEX_A7=yes AARCH32_SP=optee PLAT_WARP7_UART=1 GENERATE_COT=1 \
+ TRUSTED_BOARD_BOOT=1 USE_TBBR_DEFS=1 MBEDTLS_DIR=../mbedtls \
+ NEED_BL32=yes BL32=fiptool_images/tee-header_v2.bin \
+ BL32_EXTRA1=fiptool_images/tee-pager_v2.bin \
+ BL32_EXTRA2=fiptool_images/tee-pageable_v2.bin \
+ BL33=fiptool_images/u-boot.bin certificates all
+
+ /path/to/u-boot/tools/mkimage -n /path/to/u-boot/u-boot.cfgout -T imximage -e 0x9df00000 -d ./build/warp7/debug/bl2.bin ./build/warp7/debug/bl2.bin.imx
+
+## FIP:
+
+.. code:: shell
+
+ cp /path/to/uboot/u-boot.bin fiptool_images
cp /path/to/linux/arch/boot/dts/imx7s-warp.dtb fiptool_images
- tools/fiptool/fiptool create --tos-fw fiptool_images/tee-header_v2.bin --tos-fw-extra1 fiptool_images/tee-pager_v2.bin --tos-fw-extra2 fiptool_images/tee-pageable_v2.bin --nt-fw fiptool_images/u-boot.bin --hw-config fiptool_images/imx7s-warp.dtb warp7.fip
+
+ tools/cert_create/cert_create -n --rot-key "build/warp7/debug/rot_key.pem" \
+ --tfw-nvctr 0 \
+ --ntfw-nvctr 0 \
+ --trusted-key-cert fiptool_images/trusted-key-cert.key-crt \
+ --tb-fw=build/warp7/debug/bl2.bin \
+ --tb-fw-cert fiptool_images/trusted-boot-fw.key-crt\
+ --tos-fw fiptool_images/tee-header_v2.bin \
+ --tos-fw-cert fiptool_images/tee-header_v2.bin.crt \
+ --tos-fw-key-cert fiptool_images/tee-header_v2.bin.key-crt \
+ --tos-fw-extra1 fiptool_images/tee-pager_v2.bin \
+ --tos-fw-extra2 fiptool_images/tee-pageable_v2.bin \
+ --nt-fw fiptool_images/u-boot.bin \
+ --nt-fw-cert fiptool_images/u-boot.bin.crt \
+ --nt-fw-key-cert fiptool_images/u-boot.bin.key-crt \
+ --hw-config fiptool_images/imx7s-warp.dtb
+ tools/fiptool/fiptool create --tos-fw fiptool_images/tee-header_v2.bin \
+ --tos-fw-extra1 fiptool_images/tee-pager_v2.bin \
+ --tos-fw-extra2 fiptool_images/tee-pageable_v2.bin \
+ --nt-fw fiptool_images/u-boot.bin \
+ --hw-config fiptool_images/imx7s-warp.dtb \
+ --tos-fw-cert fiptool_images/tee-header_v2.bin.crt \
+ --tos-fw-key-cert fiptool_images/tee-header_v2.bin.key-crt \
+ --nt-fw-cert fiptool_images/u-boot.bin.crt \
+ --nt-fw-key-cert fiptool_images/u-boot.bin.key-crt \
+ --trusted-key-cert fiptool_images/trusted-key-cert.key-crt \
+ --tb-fw-cert fiptool_images/trusted-boot-fw.key-crt warp7.fip
# Deploy Images
diff --git a/include/arch/aarch64/arch_helpers.h b/include/arch/aarch64/arch_helpers.h
index d3f0df7..4e459bb 100644
--- a/include/arch/aarch64/arch_helpers.h
+++ b/include/arch/aarch64/arch_helpers.h
@@ -185,6 +185,7 @@
DEFINE_SYSREG_READ_FUNC(id_aa64isar1_el1)
DEFINE_SYSREG_READ_FUNC(id_aa64pfr0_el1)
DEFINE_SYSREG_READ_FUNC(id_aa64dfr0_el1)
+DEFINE_SYSREG_READ_FUNC(id_afr0_el1)
DEFINE_SYSREG_READ_FUNC(CurrentEl)
DEFINE_SYSREG_READ_FUNC(ctr_el0)
DEFINE_SYSREG_RW_FUNCS(daif)
diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h
index 2382697..72221ac 100644
--- a/include/drivers/arm/gicv3.h
+++ b/include/drivers/arm/gicv3.h
@@ -84,6 +84,7 @@
#define GICR_PCPUBASE_SHIFT 0x11
#define GICR_SGIBASE_OFFSET U(65536) /* 64 KB */
#define GICR_CTLR U(0x0)
+#define GICR_IIDR U(0x04)
#define GICR_TYPER U(0x08)
#define GICR_WAKER U(0x14)
#define GICR_PROPBASER U(0x70)
diff --git a/plat/imx/common/imx_sip_handler.c b/plat/imx/common/imx_sip_handler.c
index 22a7f2b..55639cd 100644
--- a/plat/imx/common/imx_sip_handler.c
+++ b/plat/imx/common/imx_sip_handler.c
@@ -7,6 +7,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <std_svc.h>
+#include <string.h>
#include <platform_def.h>
#include <common/debug.h>
#include <common/runtime_svc.h>
@@ -76,3 +77,107 @@
return 0;
}
+
+static bool wakeup_src_irqsteer;
+
+bool imx_is_wakeup_src_irqsteer(void)
+{
+ return wakeup_src_irqsteer;
+}
+
+int imx_wakeup_src_handler(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3)
+{
+ switch (x1) {
+ case IMX_SIP_WAKEUP_SRC_IRQSTEER:
+ wakeup_src_irqsteer = true;
+ break;
+ case IMX_SIP_WAKEUP_SRC_SCU:
+ wakeup_src_irqsteer = false;
+ break;
+ default:
+ return SMC_UNK;
+ }
+
+ return SMC_OK;
+}
+
+int imx_otp_handler(uint32_t smc_fid,
+ void *handle,
+ u_register_t x1,
+ u_register_t x2)
+{
+ int ret;
+ uint32_t fuse;
+
+ switch (smc_fid) {
+ case IMX_SIP_OTP_READ:
+ ret = sc_misc_otp_fuse_read(ipc_handle, x1, &fuse);
+ SMC_RET2(handle, ret, fuse);
+ break;
+ case IMX_SIP_OTP_WRITE:
+ ret = sc_misc_otp_fuse_write(ipc_handle, x1, x2);
+ SMC_RET1(handle, ret);
+ break;
+ default:
+ ret = SMC_UNK;
+ SMC_RET1(handle, ret);
+ break;
+ }
+
+ return ret;
+}
+
+int imx_misc_set_temp_handler(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4)
+{
+ return sc_misc_set_temp(ipc_handle, x1, x2, x3, x4);
+}
+
+static uint64_t imx_get_commit_hash(u_register_t x2,
+ u_register_t x3,
+ u_register_t x4)
+{
+ /* Parse the version_string */
+ char *parse = (char *)version_string;
+ uint64_t hash = 0;
+
+ do {
+ parse = strchr(parse, '-');
+ if (parse) {
+ parse += 1;
+ if (*(parse) == 'g') {
+ /* Default is 7 hexadecimal digits */
+ memcpy((void *)&hash, (void *)(parse + 1), 7);
+ break;
+ }
+ }
+
+ } while (parse != NULL);
+
+ return hash;
+}
+
+uint64_t imx_buildinfo_handler(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4)
+{
+ uint64_t ret;
+
+ switch (x1) {
+ case IMX_SIP_BUILDINFO_GET_COMMITHASH:
+ ret = imx_get_commit_hash(x2, x3, x4);
+ break;
+ default:
+ return SMC_UNK;
+ }
+
+ return ret;
+}
diff --git a/plat/imx/common/imx_sip_svc.c b/plat/imx/common/imx_sip_svc.c
index 89b9df8..c27fbf2 100644
--- a/plat/imx/common/imx_sip_svc.c
+++ b/plat/imx/common/imx_sip_svc.c
@@ -32,7 +32,16 @@
case IMX_SIP_CPUFREQ:
SMC_RET1(handle, imx_cpufreq_handler(smc_fid, x1, x2, x3));
break;
+ case IMX_SIP_WAKEUP_SRC:
+ SMC_RET1(handle, imx_wakeup_src_handler(smc_fid, x1, x2, x3));
+ case IMX_SIP_OTP_READ:
+ case IMX_SIP_OTP_WRITE:
+ return imx_otp_handler(smc_fid, handle, x1, x2);
+ case IMX_SIP_MISC_SET_TEMP:
+ SMC_RET1(handle, imx_misc_set_temp_handler(smc_fid, x1, x2, x3, x4));
#endif
+ case IMX_SIP_BUILDINFO:
+ SMC_RET1(handle, imx_buildinfo_handler(smc_fid, x1, x2, x3, x4));
default:
WARN("Unimplemented i.MX SiP Service Call: 0x%x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);
diff --git a/plat/imx/common/include/imx_sip_svc.h b/plat/imx/common/include/imx_sip_svc.h
index 4ba7b87..648be37 100644
--- a/plat/imx/common/include/imx_sip_svc.h
+++ b/plat/imx/common/include/imx_sip_svc.h
@@ -14,11 +14,33 @@
#define IMX_SIP_SRTC 0xC2000002
#define IMX_SIP_SRTC_SET_TIME 0x00
+#define IMX_SIP_BUILDINFO 0xC2000003
+#define IMX_SIP_BUILDINFO_GET_COMMITHASH 0x00
+
+#define IMX_SIP_WAKEUP_SRC 0xC2000009
+#define IMX_SIP_WAKEUP_SRC_SCU 0x1
+#define IMX_SIP_WAKEUP_SRC_IRQSTEER 0x2
+
+#define IMX_SIP_OTP_READ 0xC200000A
+#define IMX_SIP_OTP_WRITE 0xC200000B
+
+#define IMX_SIP_MISC_SET_TEMP 0xC200000C
+
#if (defined(PLAT_IMX8QM) || defined(PLAT_IMX8QX))
int imx_cpufreq_handler(uint32_t smc_fid, u_register_t x1,
u_register_t x2, u_register_t x3);
int imx_srtc_handler(uint32_t smc_fid, void *handle, u_register_t x1,
u_register_t x2, u_register_t x3, u_register_t x4);
+int imx_wakeup_src_handler(uint32_t smc_fid, u_register_t x1,
+ u_register_t x2, u_register_t x3);
+int imx_otp_handler(uint32_t smc_fid, void *handle,
+ u_register_t x1, u_register_t x2);
+int imx_misc_set_temp_handler(uint32_t smc_fid, u_register_t x1,
+ u_register_t x2, u_register_t x3,
+ u_register_t x4);
+uint64_t imx_buildinfo_handler(uint32_t smc_fid, u_register_t x1,
+ u_register_t x2, u_register_t x3,
+ u_register_t x4);
#endif
#endif /* __IMX_SIP_SVC_H__ */
diff --git a/plat/imx/common/include/plat_imx8.h b/plat/imx/common/include/plat_imx8.h
index 8d83173..952ad53 100644
--- a/plat/imx/common/include/plat_imx8.h
+++ b/plat/imx/common/include/plat_imx8.h
@@ -23,5 +23,6 @@
int imx_validate_power_state(unsigned int power_state,
psci_power_state_t *req_state);
void imx_get_sys_suspend_power_state(psci_power_state_t *req_state);
+bool imx_is_wakeup_src_irqsteer(void);
#endif /* PLAT_IMX8_H */
diff --git a/plat/imx/common/include/sci/sci.h b/plat/imx/common/include/sci/sci.h
index 1b2f699..2c45bb8 100644
--- a/plat/imx/common/include/sci/sci.h
+++ b/plat/imx/common/include/sci/sci.h
@@ -16,5 +16,6 @@
#include <sci/svc/pm/sci_pm_api.h>
#include <sci/svc/rm/sci_rm_api.h>
#include <sci/svc/timer/sci_timer_api.h>
+#include <sci/svc/misc/sci_misc_api.h>
#endif /* SCI_H */
diff --git a/plat/imx/common/include/sci/svc/misc/sci_misc_api.h b/plat/imx/common/include/sci/svc/misc/sci_misc_api.h
new file mode 100644
index 0000000..d9dd49d
--- /dev/null
+++ b/plat/imx/common/include/sci/svc/misc/sci_misc_api.h
@@ -0,0 +1,539 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ * Header file containing the public API for the System Controller (SC)
+ * Miscellaneous (MISC) function.
+ *
+ * @addtogroup MISC_SVC (SVC) Miscellaneous Service
+ *
+ * Module for the Miscellaneous (MISC) service.
+ *
+ * @{
+ */
+
+#ifndef SC_MISC_API_H
+#define SC_MISC_API_H
+
+/* Includes */
+
+#include <sci/svc/rm/sci_rm_api.h>
+#include <sci/sci_types.h>
+
+/* Defines */
+
+/*!
+ * @name Defines for type widths
+ */
+/*@{*/
+#define SC_MISC_DMA_GRP_W 5U /* Width of sc_misc_dma_group_t */
+/*@}*/
+
+/*! Max DMA channel priority group */
+#define SC_MISC_DMA_GRP_MAX 31U
+
+/*!
+ * @name Defines for sc_misc_boot_status_t
+ */
+/*@{*/
+#define SC_MISC_BOOT_STATUS_SUCCESS 0U /* Success */
+#define SC_MISC_BOOT_STATUS_SECURITY 1U /* Security violation */
+/*@}*/
+
+/*!
+ * @name Defines for sc_misc_seco_auth_cmd_t
+ */
+/*@{*/
+#define SC_MISC_SECO_AUTH_SECO_FW 0U /* SECO Firmware */
+#define SC_MISC_SECO_AUTH_HDMI_TX_FW 1U /* HDMI TX Firmware */
+#define SC_MISC_SECO_AUTH_HDMI_RX_FW 2U /* HDMI RX Firmware */
+/*@}*/
+
+/*!
+ * @name Defines for sc_misc_temp_t
+ */
+/*@{*/
+#define SC_MISC_TEMP 0U /* Temp sensor */
+#define SC_MISC_TEMP_HIGH 1U /* Temp high alarm */
+#define SC_MISC_TEMP_LOW 2U /* Temp low alarm */
+/*@}*/
+
+/*!
+ * @name Defines for sc_misc_seco_auth_cmd_t
+ */
+/*@{*/
+#define SC_MISC_AUTH_CONTAINER 0U /* Authenticate container */
+#define SC_MISC_VERIFY_IMAGE 1U /* Verify image */
+#define SC_MISC_REL_CONTAINER 2U /* Release container */
+/*@}*/
+
+/* Types */
+
+/*!
+ * This type is used to store a DMA channel priority group.
+ */
+typedef uint8_t sc_misc_dma_group_t;
+
+/*!
+ * This type is used report boot status.
+ */
+typedef uint8_t sc_misc_boot_status_t;
+
+/*!
+ * This type is used to issue SECO authenticate commands.
+ */
+typedef uint8_t sc_misc_seco_auth_cmd_t;
+
+/*!
+ * This type is used report boot status.
+ */
+typedef uint8_t sc_misc_temp_t;
+
+/* Functions */
+
+/*!
+ * @name Control Functions
+ * @{
+ */
+
+/*!
+ * This function sets a miscellaneous control value.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource resource the control is associated with
+ * @param[in] ctrl control to change
+ * @param[in] val value to apply to the control
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the resource owner or parent
+ * of the owner
+ *
+ * Refer to the [Control List](@ref CONTROLS) for valid control values.
+ */
+sc_err_t sc_misc_set_control(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_ctrl_t ctrl, uint32_t val);
+
+/*!
+ * This function gets a miscellaneous control value.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource resource the control is associated with
+ * @param[in] ctrl control to get
+ * @param[out] val pointer to return the control value
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the resource owner or parent
+ * of the owner
+ *
+ * Refer to the [Control List](@ref CONTROLS) for valid control values.
+ */
+sc_err_t sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_ctrl_t ctrl, uint32_t *val);
+
+/* @} */
+
+/*!
+ * @name DMA Functions
+ * @{
+ */
+
+/*!
+ * This function configures the max DMA channel priority group for a
+ * partition.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] pt handle of partition to assign \a max
+ * @param[in] max max priority group (0-31)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the parent
+ * of the affected partition
+ *
+ * Valid \a max range is 0-31 with 0 being the lowest and 31 the highest.
+ * Default is the max priority group for the parent partition of \a pt.
+ */
+sc_err_t sc_misc_set_max_dma_group(sc_ipc_t ipc, sc_rm_pt_t pt,
+ sc_misc_dma_group_t max);
+
+/*!
+ * This function configures the priority group for a DMA channel.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource DMA channel resource
+ * @param[in] group priority group (0-31)
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the owner or parent
+ * of the owner of the DMA channel
+ *
+ * Valid \a group range is 0-31 with 0 being the lowest and 31 the highest.
+ * The max value of \a group is limited by the partition max set using
+ * sc_misc_set_max_dma_group().
+ */
+sc_err_t sc_misc_set_dma_group(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_misc_dma_group_t group);
+
+/* @} */
+
+/*!
+ * @name Security Functions
+ * @{
+ */
+
+/*!
+ * This function loads a SECO image.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] addr_src address of image source
+ * @param[in] addr_dst address of image destination
+ * @param[in] len length of image to load
+ * @param[in] fw SC_TRUE = firmware load
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This is used to load images via the SECO. Examples include SECO
+ * Firmware and IVT/CSF data used for authentication. These are usually
+ * loaded into SECO TCM. \a addr_src is in secure memory.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_image_load(sc_ipc_t ipc, sc_faddr_t addr_src,
+ sc_faddr_t addr_dst, uint32_t len,
+ sc_bool_t fw);
+
+/*!
+ * This function is used to authenticate a SECO image or command.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] cmd authenticate command
+ * @param[in] addr address of/or metadata
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This is used to authenticate a SECO image or issue a security
+ * command. \a addr often points to an container. It is also
+ * just data (or even unused) for some commands.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_authenticate(sc_ipc_t ipc,
+ sc_misc_seco_auth_cmd_t cmd,
+ sc_faddr_t addr);
+
+/*!
+ * This function securely writes a group of fuse words.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] addr address of message block
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * Note \a addr must be a pointer to a signed message block.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_fuse_write(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * This function securely enables debug.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] addr address of message block
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * Note \a addr must be a pointer to a signed message block.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_enable_debug(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * This function updates the lifecycle of the device.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] lifecycle new lifecycle
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * This message is used for going from Open to NXP Closed to OEM Closed.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_forward_lifecycle(sc_ipc_t ipc, uint32_t lifecycle);
+
+/*!
+ * This function updates the lifecycle to one of the return lifecycles.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] addr address of message block
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_UNAVAILABLE if SECO not available
+ *
+ * Note \a addr must be a pointer to a signed message block.
+ *
+ * To switch back to NXP states (Full Field Return), message must be signed
+ * by NXP SRK. For OEM States (Partial Field Return), must be signed by OEM
+ * SRK.
+ *
+ * See the Security Reference Manual (SRM) for more info.
+ */
+sc_err_t sc_misc_seco_return_lifecycle(sc_ipc_t ipc, sc_faddr_t addr);
+
+/*!
+ * This function is used to return the SECO FW build info.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] version pointer to return build number
+ * @param[out] commit pointer to return commit ID (git SHA-1)
+ */
+void sc_misc_seco_build_info(sc_ipc_t ipc, uint32_t *version, uint32_t *commit);
+
+/*!
+ * This function is used to return SECO chip info.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] lc pointer to return lifecycle
+ * @param[out] monotonic pointer to return monotonic counter
+ * @param[out] uid_l pointer to return UID (lower 32 bits)
+ * @param[out] uid_h pointer to return UID (upper 32 bits)
+ */
+sc_err_t sc_misc_seco_chip_info(sc_ipc_t ipc, uint16_t *lc,
+ uint16_t *monotonic, uint32_t *uid_l,
+ uint32_t *uid_h);
+
+/* @} */
+
+/*!
+ * @name Debug Functions
+ * @{
+ */
+
+/*!
+ * This function is used output a debug character from the SCU UART.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] ch character to output
+ */
+void sc_misc_debug_out(sc_ipc_t ipc, uint8_t ch);
+
+/*!
+ * This function starts/stops emulation waveform capture.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] enable flag to enable/disable capture
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_ERR_UNAVAILABLE if not running on emulation
+ */
+sc_err_t sc_misc_waveform_capture(sc_ipc_t ipc, sc_bool_t enable);
+
+/*!
+ * This function is used to return the SCFW build info.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] build pointer to return build number
+ * @param[out] commit pointer to return commit ID (git SHA-1)
+ */
+void sc_misc_build_info(sc_ipc_t ipc, uint32_t *build, uint32_t *commit);
+
+/*!
+ * This function is used to return the device's unique ID.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] id_l pointer to return lower 32-bit of ID [31:0]
+ * @param[out] id_h pointer to return upper 32-bits of ID [63:32]
+ */
+void sc_misc_unique_id(sc_ipc_t ipc, uint32_t *id_l, uint32_t *id_h);
+
+/* @} */
+
+/*!
+ * @name Other Functions
+ * @{
+ */
+
+/*!
+ * This function configures the ARI match value for PCIe/SATA resources.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource match resource
+ * @param[in] resource_mst PCIe/SATA master to match
+ * @param[in] ari ARI to match
+ * @param[in] enable enable match or not
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the owner or parent
+ * of the owner of the resource and translation
+ *
+ * For PCIe, the ARI is the 16-bit value that includes the bus number,
+ * device number, and function number. For SATA, this value includes the
+ * FISType and PM_Port.
+ */
+sc_err_t sc_misc_set_ari(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_rsrc_t resource_mst, uint16_t ari,
+ sc_bool_t enable);
+
+/*!
+ * This function reports boot status.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] status boot status
+ *
+ * This is used by SW partitions to report status of boot. This is
+ * normally used to report a boot failure.
+ */
+void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status);
+
+/*!
+ * This function tells the SCFW that a CPU is done booting.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] cpu CPU that is done booting
+ *
+ * This is called by early booting CPUs to report they are done with
+ * initialization. After starting early CPUs, the SCFW halts the
+ * booting process until they are done. During this time, early
+ * CPUs can call the SCFW with lower latency as the SCFW is idle.
+ *
+ * @return Returns an error code (SC_ERR_NONE = success).
+ *
+ * Return errors:
+ * - SC_PARM if arguments out of range or invalid,
+ * - SC_ERR_NOACCESS if caller's partition is not the CPU owner
+ */
+sc_err_t sc_misc_boot_done(sc_ipc_t ipc, sc_rsrc_t cpu);
+
+/*!
+ * This function reads a given fuse word index.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] word fuse word index
+ * @param[out] val fuse read value
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_NOACCESS if read operation failed
+ * - SC_ERR_LOCKED if read operation is locked
+ */
+sc_err_t sc_misc_otp_fuse_read(sc_ipc_t ipc, uint32_t word, uint32_t *val);
+
+/*!
+ * This function writes a given fuse word index.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] word fuse word index
+ * @param[in] val fuse write value
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if word fuse index param out of range or invalid
+ * - SC_ERR_NOACCESS if write operation failed
+ * - SC_ERR_LOCKED if write operation is locked
+ */
+sc_err_t sc_misc_otp_fuse_write(sc_ipc_t ipc, uint32_t word, uint32_t val);
+
+/*!
+ * This function sets a temp sensor alarm.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource resource with sensor
+ * @param[in] temp alarm to set
+ * @param[in] celsius whole part of temp to set
+ * @param[in] tenths fractional part of temp to set
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * This function will enable the alarm interrupt if the temp requested is
+ * not the min/max temp. This enable automatically clears when the alarm
+ * occurs and this function has to be called again to re-enable.
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if parameters invalid
+ */
+sc_err_t sc_misc_set_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_misc_temp_t temp, int16_t celsius, int8_t tenths);
+
+/*!
+ * This function gets a temp sensor value.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] resource resource with sensor
+ * @param[in] temp value to get (sensor or alarm)
+ * @param[out] celsius whole part of temp to get
+ * @param[out] tenths fractional part of temp to get
+ *
+ * @return Returns and error code (SC_ERR_NONE = success).
+ *
+ * Return errors codes:
+ * - SC_ERR_PARM if parameters invalid
+ */
+sc_err_t sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_misc_temp_t temp, int16_t *celsius,
+ int8_t *tenths);
+
+/*!
+ * This function returns the boot device.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] dev pointer to return boot device
+ */
+void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *dev);
+
+/*!
+ * This function returns the current status of the ON/OFF button.
+ *
+ * @param[in] ipc IPC handle
+ * @param[out] status pointer to return button status
+ */
+void sc_misc_get_button_status(sc_ipc_t ipc, sc_bool_t *status);
+
+/* @} */
+
+#endif /* SC_MISC_API_H */
+
+/**@}*/
diff --git a/plat/imx/common/sci/sci_api.mk b/plat/imx/common/sci/sci_api.mk
index edaef4d..92c7190 100644
--- a/plat/imx/common/sci/sci_api.mk
+++ b/plat/imx/common/sci/sci_api.mk
@@ -9,4 +9,5 @@
plat/imx/common/sci/svc/pad/pad_rpc_clnt.c \
plat/imx/common/sci/svc/pm/pm_rpc_clnt.c \
plat/imx/common/sci/svc/rm/rm_rpc_clnt.c \
- plat/imx/common/sci/svc/timer/timer_rpc_clnt.c
+ plat/imx/common/sci/svc/timer/timer_rpc_clnt.c \
+ plat/imx/common/sci/svc/misc/misc_rpc_clnt.c
diff --git a/plat/imx/common/sci/svc/misc/misc_rpc_clnt.c b/plat/imx/common/sci/svc/misc/misc_rpc_clnt.c
new file mode 100644
index 0000000..080de6a
--- /dev/null
+++ b/plat/imx/common/sci/svc/misc/misc_rpc_clnt.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2018 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ * File containing client-side RPC functions for the MISC service. These
+ * functions are ported to clients that communicate to the SC.
+ *
+ * @addtogroup MISC_SVC
+ * @{
+ */
+
+/* Includes */
+
+#include <sci/sci_types.h>
+#include <sci/svc/rm/sci_rm_api.h>
+#include <sci/svc/misc/sci_misc_api.h>
+#include <sci/sci_rpc.h>
+#include <stdlib.h>
+#include "sci_misc_rpc.h"
+
+/* Local Defines */
+
+/* Local Types */
+
+/* Local Functions */
+
+sc_err_t sc_misc_set_control(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_ctrl_t ctrl, uint32_t val)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_CONTROL;
+ RPC_U32(&msg, 0U) = (uint32_t)ctrl;
+ RPC_U32(&msg, 4U) = (uint32_t)val;
+ RPC_U16(&msg, 8U) = (uint16_t)resource;
+ RPC_SIZE(&msg) = 4U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_get_control(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_ctrl_t ctrl, uint32_t *val)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_GET_CONTROL;
+ RPC_U32(&msg, 0U) = (uint32_t)ctrl;
+ RPC_U16(&msg, 4U) = (uint16_t)resource;
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (val != NULL)
+ *val = RPC_U32(&msg, 0U);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_set_max_dma_group(sc_ipc_t ipc, sc_rm_pt_t pt,
+ sc_misc_dma_group_t max)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_MAX_DMA_GROUP;
+ RPC_U8(&msg, 0U) = (uint8_t)pt;
+ RPC_U8(&msg, 1U) = (uint8_t)max;
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_set_dma_group(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_misc_dma_group_t group)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_DMA_GROUP;
+ RPC_U16(&msg, 0U) = (uint16_t)resource;
+ RPC_U8(&msg, 2U) = (uint8_t)group;
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_image_load(sc_ipc_t ipc, sc_faddr_t addr_src,
+ sc_faddr_t addr_dst, uint32_t len,
+ sc_bool_t fw)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_IMAGE_LOAD;
+ RPC_U32(&msg, 0U) = (uint32_t)(addr_src >> 32U);
+ RPC_U32(&msg, 4U) = (uint32_t)addr_src;
+ RPC_U32(&msg, 8U) = (uint32_t)(addr_dst >> 32U);
+ RPC_U32(&msg, 12U) = (uint32_t)addr_dst;
+ RPC_U32(&msg, 16U) = (uint32_t)len;
+ RPC_U8(&msg, 20U) = (uint8_t)fw;
+ RPC_SIZE(&msg) = 7U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_authenticate(sc_ipc_t ipc,
+ sc_misc_seco_auth_cmd_t cmd, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_AUTHENTICATE;
+ RPC_U32(&msg, 0U) = (uint32_t)(addr >> 32U);
+ RPC_U32(&msg, 4U) = (uint32_t)addr;
+ RPC_U8(&msg, 8U) = (uint8_t)cmd;
+ RPC_SIZE(&msg) = 4U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_fuse_write(sc_ipc_t ipc, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_FUSE_WRITE;
+ RPC_U32(&msg, 0U) = (uint32_t)(addr >> 32U);
+ RPC_U32(&msg, 4U) = (uint32_t)addr;
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_enable_debug(sc_ipc_t ipc, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_ENABLE_DEBUG;
+ RPC_U32(&msg, 0U) = (uint32_t)(addr >> 32U);
+ RPC_U32(&msg, 4U) = (uint32_t)addr;
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_forward_lifecycle(sc_ipc_t ipc, uint32_t lifecycle)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_FORWARD_LIFECYCLE;
+ RPC_U32(&msg, 0U) = (uint32_t)lifecycle;
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_seco_return_lifecycle(sc_ipc_t ipc, sc_faddr_t addr)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_RETURN_LIFECYCLE;
+ RPC_U32(&msg, 0U) = (uint32_t)(addr >> 32U);
+ RPC_U32(&msg, 4U) = (uint32_t)addr;
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+void sc_misc_seco_build_info(sc_ipc_t ipc, uint32_t *version, uint32_t *commit)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_BUILD_INFO;
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (version != NULL)
+ *version = RPC_U32(&msg, 0U);
+
+ if (commit != NULL)
+ *commit = RPC_U32(&msg, 4U);
+}
+
+sc_err_t sc_misc_seco_chip_info(sc_ipc_t ipc, uint16_t *lc,
+ uint16_t *monotonic, uint32_t *uid_l,
+ uint32_t *uid_h)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SECO_CHIP_INFO;
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (uid_l != NULL)
+ *uid_l = RPC_U32(&msg, 0U);
+
+ if (uid_h != NULL)
+ *uid_h = RPC_U32(&msg, 4U);
+
+ if (lc != NULL)
+ *lc = RPC_U16(&msg, 8U);
+
+ if (monotonic != NULL)
+ *monotonic = RPC_U16(&msg, 10U);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+void sc_misc_debug_out(sc_ipc_t ipc, uint8_t ch)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_DEBUG_OUT;
+ RPC_U8(&msg, 0U) = (uint8_t)ch;
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+}
+
+sc_err_t sc_misc_waveform_capture(sc_ipc_t ipc, sc_bool_t enable)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_WAVEFORM_CAPTURE;
+ RPC_U8(&msg, 0U) = (uint8_t)enable;
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+void sc_misc_build_info(sc_ipc_t ipc, uint32_t *build, uint32_t *commit)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_BUILD_INFO;
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (build != NULL)
+ *build = RPC_U32(&msg, 0U);
+
+ if (commit != NULL)
+ *commit = RPC_U32(&msg, 4U);
+}
+
+void sc_misc_unique_id(sc_ipc_t ipc, uint32_t *id_l, uint32_t *id_h)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_UNIQUE_ID;
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (id_l != NULL)
+ *id_l = RPC_U32(&msg, 0U);
+
+ if (id_h != NULL)
+ *id_h = RPC_U32(&msg, 4U);
+}
+
+sc_err_t sc_misc_set_ari(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_rsrc_t resource_mst, uint16_t ari, sc_bool_t enable)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_ARI;
+ RPC_U16(&msg, 0U) = (uint16_t)resource;
+ RPC_U16(&msg, 2U) = (uint16_t)resource_mst;
+ RPC_U16(&msg, 4U) = (uint16_t)ari;
+ RPC_U8(&msg, 6U) = (uint8_t)enable;
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+void sc_misc_boot_status(sc_ipc_t ipc, sc_misc_boot_status_t status)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_BOOT_STATUS;
+ RPC_U8(&msg, 0U) = (uint8_t)status;
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_TRUE);
+}
+
+sc_err_t sc_misc_boot_done(sc_ipc_t ipc, sc_rsrc_t cpu)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_BOOT_DONE;
+ RPC_U16(&msg, 0U) = (uint16_t)cpu;
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_otp_fuse_read(sc_ipc_t ipc, uint32_t word, uint32_t *val)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_OTP_FUSE_READ;
+ RPC_U32(&msg, 0U) = (uint32_t)word;
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (val != NULL)
+ *val = RPC_U32(&msg, 0U);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_otp_fuse_write(sc_ipc_t ipc, uint32_t word, uint32_t val)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_OTP_FUSE_WRITE;
+ RPC_U32(&msg, 0U) = (uint32_t)word;
+ RPC_U32(&msg, 4U) = (uint32_t)val;
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_set_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_misc_temp_t temp, int16_t celsius, int8_t tenths)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_SET_TEMP;
+ RPC_U16(&msg, 0U) = (uint16_t)resource;
+ RPC_I16(&msg, 2U) = (int16_t) celsius;
+ RPC_U8(&msg, 4U) = (uint8_t)temp;
+ RPC_I8(&msg, 5U) = (int8_t) tenths;
+ RPC_SIZE(&msg) = 3U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ result = RPC_R8(&msg);
+ return (sc_err_t)result;
+}
+
+sc_err_t sc_misc_get_temp(sc_ipc_t ipc, sc_rsrc_t resource,
+ sc_misc_temp_t temp, int16_t *celsius,
+ int8_t *tenths)
+{
+ sc_rpc_msg_t msg;
+ uint8_t result;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_GET_TEMP;
+ RPC_U16(&msg, 0U) = (uint16_t)resource;
+ RPC_U8(&msg, 2U) = (uint8_t)temp;
+ RPC_SIZE(&msg) = 2U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (celsius != NULL)
+ *celsius = RPC_I16(&msg, 0U);
+
+ result = RPC_R8(&msg);
+ if (tenths != NULL)
+ *tenths = RPC_I8(&msg, 2U);
+
+ return (sc_err_t)result;
+}
+
+void sc_misc_get_boot_dev(sc_ipc_t ipc, sc_rsrc_t *dev)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_GET_BOOT_DEV;
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (dev != NULL)
+ *dev = RPC_U16(&msg, 0U);
+}
+
+void sc_misc_get_button_status(sc_ipc_t ipc, sc_bool_t *status)
+{
+ sc_rpc_msg_t msg;
+
+ RPC_VER(&msg) = SC_RPC_VERSION;
+ RPC_SVC(&msg) = (uint8_t)SC_RPC_SVC_MISC;
+ RPC_FUNC(&msg) = (uint8_t)MISC_FUNC_GET_BUTTON_STATUS;
+ RPC_SIZE(&msg) = 1U;
+
+ sc_call_rpc(ipc, &msg, SC_FALSE);
+
+ if (status != NULL)
+ *status = RPC_U8(&msg, 0U);
+}
+
+/**@}*/
diff --git a/plat/imx/common/sci/svc/misc/sci_misc_rpc.h b/plat/imx/common/sci/svc/misc/sci_misc_rpc.h
new file mode 100644
index 0000000..03b1a51
--- /dev/null
+++ b/plat/imx/common/sci/svc/misc/sci_misc_rpc.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2016 Freescale Semiconductor, Inc.
+ * Copyright 2017-2019 NXP
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ * Header file for the MISC RPC implementation.
+ *
+ * @addtogroup MISC_SVC
+ * @{
+ */
+
+#ifndef SC_MISC_RPC_H
+#define SC_MISC_RPC_H
+
+/* Includes */
+
+/* Defines */
+
+/*!
+ * @name Defines for RPC MISC function calls
+ */
+/*@{*/
+#define MISC_FUNC_UNKNOWN 0 /* Unknown function */
+#define MISC_FUNC_SET_CONTROL 1U /* Index for misc_set_control() RPC call */
+#define MISC_FUNC_GET_CONTROL 2U /* Index for misc_get_control() RPC call */
+#define MISC_FUNC_SET_MAX_DMA_GROUP 4U /* Index for misc_set_max_dma_group() RPC call */
+#define MISC_FUNC_SET_DMA_GROUP 5U /* Index for misc_set_dma_group() RPC call */
+#define MISC_FUNC_SECO_IMAGE_LOAD 8U /* Index for misc_seco_image_load() RPC call */
+#define MISC_FUNC_SECO_AUTHENTICATE 9U /* Index for misc_seco_authenticate() RPC call */
+#define MISC_FUNC_SECO_FUSE_WRITE 20U /* Index for misc_seco_fuse_write() RPC call */
+#define MISC_FUNC_SECO_ENABLE_DEBUG 21U /* Index for misc_seco_enable_debug() RPC call */
+#define MISC_FUNC_SECO_FORWARD_LIFECYCLE 22U /* Index for misc_seco_forward_lifecycle() RPC call */
+#define MISC_FUNC_SECO_RETURN_LIFECYCLE 23U /* Index for misc_seco_return_lifecycle() RPC call */
+#define MISC_FUNC_SECO_BUILD_INFO 24U /* Index for misc_seco_build_info() RPC call */
+#define MISC_FUNC_SECO_CHIP_INFO 25U /* Index for misc_seco_chip_info() RPC call */
+#define MISC_FUNC_DEBUG_OUT 10U /* Index for misc_debug_out() RPC call */
+#define MISC_FUNC_WAVEFORM_CAPTURE 6U /* Index for misc_waveform_capture() RPC call */
+#define MISC_FUNC_BUILD_INFO 15U /* Index for misc_build_info() RPC call */
+#define MISC_FUNC_UNIQUE_ID 19U /* Index for misc_unique_id() RPC call */
+#define MISC_FUNC_SET_ARI 3U /* Index for misc_set_ari() RPC call */
+#define MISC_FUNC_BOOT_STATUS 7U /* Index for misc_boot_status() RPC call */
+#define MISC_FUNC_BOOT_DONE 14U /* Index for misc_boot_done() RPC call */
+#define MISC_FUNC_OTP_FUSE_READ 11U /* Index for misc_otp_fuse_read() RPC call */
+#define MISC_FUNC_OTP_FUSE_WRITE 17U /* Index for misc_otp_fuse_write() RPC call */
+#define MISC_FUNC_SET_TEMP 12U /* Index for misc_set_temp() RPC call */
+#define MISC_FUNC_GET_TEMP 13U /* Index for misc_get_temp() RPC call */
+#define MISC_FUNC_GET_BOOT_DEV 16U /* Index for misc_get_boot_dev() RPC call */
+#define MISC_FUNC_GET_BUTTON_STATUS 18U /* Index for misc_get_button_status() RPC call */
+/*@}*/
+
+/* Types */
+
+/* Functions */
+
+/*!
+ * This function dispatches an incoming MISC RPC request.
+ *
+ * @param[in] caller_pt caller partition
+ * @param[in] msg pointer to RPC message
+ */
+void misc_dispatch(sc_rm_pt_t caller_pt, sc_rpc_msg_t *msg);
+
+/*!
+ * This function translates and dispatches an MISC RPC request.
+ *
+ * @param[in] ipc IPC handle
+ * @param[in] msg pointer to RPC message
+ */
+void misc_xlate(sc_ipc_t ipc, sc_rpc_msg_t *msg);
+
+#endif /* SC_MISC_RPC_H */
+
+/**@}*/
diff --git a/plat/imx/imx7/warp7/include/platform_def.h b/plat/imx/imx7/warp7/include/platform_def.h
index a931c80..d58382f 100644
--- a/plat/imx/imx7/warp7/include/platform_def.h
+++ b/plat/imx/imx7/warp7/include/platform_def.h
@@ -106,6 +106,12 @@
#define WARP7_DTB_BASE (DRAM_BASE + 0x03000000)
#define WARP7_DTB_LIMIT (WARP7_DTB_BASE + WARP7_DTB_SIZE)
+/* Define the absolute location of DTB Overlay 0x83100000 - 0x83101000 */
+#define WARP7_DTB_OVERLAY_SIZE 0x00001000
+#define WARP7_DTB_OVERLAY_BASE WARP7_DTB_LIMIT
+#define WARP7_DTB_OVERLAY_LIMIT (WARP7_DTB_OVERLAY_BASE + \
+ WARP7_DTB_OVERLAY_SIZE)
+
/*
* BL2 specific defines.
*
@@ -142,6 +148,8 @@
* | DDR | BL33/U-BOOT
* 0x87800000 +-----------------+
* | DDR | Unallocated
+ * 0x83101000 +-----------------+
+ * | DDR | DTB Overlay
* 0x83100000 +-----------------+
* | DDR | DTB
* 0x83000000 +-----------------+
diff --git a/plat/imx/imx7/warp7/platform.mk b/plat/imx/imx7/warp7/platform.mk
index a771865..f7bd4ae 100644
--- a/plat/imx/imx7/warp7/platform.mk
+++ b/plat/imx/imx7/warp7/platform.mk
@@ -62,6 +62,43 @@
plat/imx/imx7/warp7/warp7_image_load.c \
${XLAT_TABLES_LIB_SRCS}
+ifneq (${TRUSTED_BOARD_BOOT},0)
+
+include drivers/auth/mbedtls/mbedtls_crypto.mk
+include drivers/auth/mbedtls/mbedtls_x509.mk
+
+AUTH_SOURCES := drivers/auth/auth_mod.c \
+ drivers/auth/crypto_mod.c \
+ drivers/auth/img_parser_mod.c \
+ drivers/auth/tbbr/tbbr_cot.c
+
+BL2_SOURCES += ${AUTH_SOURCES} \
+ plat/common/tbbr/plat_tbbr.c \
+ plat/imx/imx7/warp7/warp7_trusted_boot.c \
+ plat/imx/imx7/warp7/warp7_rotpk.S
+
+ROT_KEY = $(BUILD_PLAT)/rot_key.pem
+ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin
+
+$(eval $(call add_define_val,ROTPK_HASH,'"$(ROTPK_HASH)"'))
+$(eval $(call MAKE_LIB_DIRS))
+
+$(BUILD_PLAT)/bl2/warp7_rotpk.o: $(ROTPK_HASH)
+
+certificates: $(ROT_KEY)
+
+$(ROT_KEY): | $(BUILD_PLAT)
+ @echo " OPENSSL $@"
+ @if [ ! -f $(ROT_KEY) ]; then \
+ openssl genrsa 2048 > $@ 2>/dev/null; \
+ fi
+
+$(ROTPK_HASH): $(ROT_KEY)
+ @echo " OPENSSL $@"
+ $(Q)openssl rsa -in $< -pubout -outform DER 2>/dev/null |\
+ openssl dgst -sha256 -binary > $@ 2>/dev/null
+endif
+
# Build config flags
# ------------------
@@ -86,6 +123,21 @@
PLAT_WARP7_UART :=1
$(eval $(call add_define,PLAT_WARP7_UART))
+# Add the build options to pack BLx images and kernel device tree
+# in the FIP if the platform requires.
+ifneq ($(BL2),)
+$(eval $(call TOOL_ADD_PAYLOAD,${BUILD_PLAT}/tb_fw.crt,--tb-fw-cert))
+endif
+ifneq ($(BL32_EXTRA1),)
+$(eval $(call TOOL_ADD_IMG,BL32_EXTRA1,--tos-fw-extra1))
+endif
+ifneq ($(BL32_EXTRA2),)
+$(eval $(call TOOL_ADD_IMG,BL32_EXTRA2,--tos-fw-extra2))
+endif
+ifneq ($(HW_CONFIG),)
+$(eval $(call TOOL_ADD_IMG,HW_CONFIG,--hw-config))
+endif
+
# Verify build config
# -------------------
diff --git a/plat/imx/imx7/warp7/warp7_bl2_el3_setup.c b/plat/imx/imx7/warp7/warp7_bl2_el3_setup.c
index 032ed7b..08baf19 100644
--- a/plat/imx/imx7/warp7/warp7_bl2_el3_setup.c
+++ b/plat/imx/imx7/warp7/warp7_bl2_el3_setup.c
@@ -290,12 +290,13 @@
imx_wdog_init();
/* Print out the expected memory map */
- VERBOSE("\tOPTEE 0x%08x-0x%08x\n", WARP7_OPTEE_BASE, WARP7_OPTEE_LIMIT);
- VERBOSE("\tATF/BL2 0x%08x-0x%08x\n", BL2_RAM_BASE, BL2_RAM_LIMIT);
- VERBOSE("\tSHRAM 0x%08x-0x%08x\n", SHARED_RAM_BASE, SHARED_RAM_LIMIT);
- VERBOSE("\tFIP 0x%08x-0x%08x\n", WARP7_FIP_BASE, WARP7_FIP_LIMIT);
- VERBOSE("\tDTB 0x%08x-0x%08x\n", WARP7_DTB_BASE, WARP7_DTB_LIMIT);
- VERBOSE("\tUBOOT/BL33 0x%08x-0x%08x\n", WARP7_UBOOT_BASE, WARP7_UBOOT_LIMIT);
+ VERBOSE("\tOPTEE 0x%08x-0x%08x\n", WARP7_OPTEE_BASE, WARP7_OPTEE_LIMIT);
+ VERBOSE("\tATF/BL2 0x%08x-0x%08x\n", BL2_RAM_BASE, BL2_RAM_LIMIT);
+ VERBOSE("\tSHRAM 0x%08x-0x%08x\n", SHARED_RAM_BASE, SHARED_RAM_LIMIT);
+ VERBOSE("\tFIP 0x%08x-0x%08x\n", WARP7_FIP_BASE, WARP7_FIP_LIMIT);
+ VERBOSE("\tDTB-OVERLAY 0x%08x-0x%08x\n", WARP7_DTB_OVERLAY_BASE, WARP7_DTB_OVERLAY_LIMIT);
+ VERBOSE("\tDTB 0x%08x-0x%08x\n", WARP7_DTB_BASE, WARP7_DTB_LIMIT);
+ VERBOSE("\tUBOOT/BL33 0x%08x-0x%08x\n", WARP7_UBOOT_BASE, WARP7_UBOOT_LIMIT);
}
/*
diff --git a/plat/imx/imx7/warp7/warp7_bl2_mem_params_desc.c b/plat/imx/imx7/warp7/warp7_bl2_mem_params_desc.c
index a29e141..c670d42 100644
--- a/plat/imx/imx7/warp7/warp7_bl2_mem_params_desc.c
+++ b/plat/imx/imx7/warp7/warp7_bl2_mem_params_desc.c
@@ -28,16 +28,6 @@
.next_handoff_image_id = BL33_IMAGE_ID,
},
{
- .image_id = HW_CONFIG_ID,
- SET_STATIC_PARAM_HEAD(ep_info, PARAM_IMAGE_BINARY,
- VERSION_2, entry_point_info_t, SECURE | NON_EXECUTABLE),
- SET_STATIC_PARAM_HEAD(image_info, PARAM_IMAGE_BINARY,
- VERSION_2, image_info_t, 0),
- .image_info.image_base = WARP7_DTB_BASE,
- .image_info.image_max_size = WARP7_DTB_SIZE,
- .next_handoff_image_id = INVALID_IMAGE_ID,
- },
- {
.image_id = BL32_EXTRA1_IMAGE_ID,
SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2,
diff --git a/plat/imx/imx7/warp7/warp7_io_storage.c b/plat/imx/imx7/warp7/warp7_io_storage.c
index b9cace0..fcfb503 100644
--- a/plat/imx/imx7/warp7/warp7_io_storage.c
+++ b/plat/imx/imx7/warp7/warp7_io_storage.c
@@ -60,10 +60,6 @@
.uuid = UUID_SECURE_PAYLOAD_BL32,
};
-static const io_uuid_spec_t hw_config_uuid_spec = {
- .uuid = UUID_HW_CONFIG,
-};
-
static const io_uuid_spec_t bl32_extra1_uuid_spec = {
.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
};
@@ -76,6 +72,32 @@
.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
};
+#if TRUSTED_BOARD_BOOT
+static const io_uuid_spec_t tb_fw_cert_uuid_spec = {
+ .uuid = UUID_TRUSTED_BOOT_FW_CERT,
+};
+
+static const io_uuid_spec_t trusted_key_cert_uuid_spec = {
+ .uuid = UUID_TRUSTED_KEY_CERT,
+};
+
+static const io_uuid_spec_t tos_fw_key_cert_uuid_spec = {
+ .uuid = UUID_TRUSTED_OS_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t tos_fw_cert_uuid_spec = {
+ .uuid = UUID_TRUSTED_OS_FW_CONTENT_CERT,
+};
+
+static const io_uuid_spec_t nt_fw_key_cert_uuid_spec = {
+ .uuid = UUID_NON_TRUSTED_FW_KEY_CERT,
+};
+
+static const io_uuid_spec_t nt_fw_cert_uuid_spec = {
+ .uuid = UUID_NON_TRUSTED_FW_CONTENT_CERT,
+};
+#endif /* TRUSTED_BOARD_BOOT */
+
/* TODO: this structure is replicated multiple times. rationalize it ! */
struct plat_io_policy {
uintptr_t *dev_handle;
@@ -112,16 +134,43 @@
(uintptr_t)&bl32_extra2_uuid_spec,
open_fip
},
- [HW_CONFIG_ID] = {
+ [BL33_IMAGE_ID] = {
&fip_dev_handle,
- (uintptr_t)&hw_config_uuid_spec,
+ (uintptr_t)&bl33_uuid_spec,
open_fip
},
- [BL33_IMAGE_ID] = {
+#if TRUSTED_BOARD_BOOT
+ [TRUSTED_BOOT_FW_CERT_ID] = {
&fip_dev_handle,
- (uintptr_t)&bl33_uuid_spec,
+ (uintptr_t)&tb_fw_cert_uuid_spec,
open_fip
- }
+ },
+ [TRUSTED_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&trusted_key_cert_uuid_spec,
+ open_fip
+ },
+ [TRUSTED_OS_FW_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&tos_fw_key_cert_uuid_spec,
+ open_fip
+ },
+ [NON_TRUSTED_FW_KEY_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&nt_fw_key_cert_uuid_spec,
+ open_fip
+ },
+ [TRUSTED_OS_FW_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&tos_fw_cert_uuid_spec,
+ open_fip
+ },
+ [NON_TRUSTED_FW_CONTENT_CERT_ID] = {
+ &fip_dev_handle,
+ (uintptr_t)&nt_fw_cert_uuid_spec,
+ open_fip
+ },
+#endif /* TRUSTED_BOARD_BOOT */
};
static int open_fip(const uintptr_t spec)
diff --git a/plat/imx/imx7/warp7/warp7_rotpk.S b/plat/imx/imx7/warp7/warp7_rotpk.S
new file mode 100644
index 0000000..f74b6d25b
--- /dev/null
+++ b/plat/imx/imx7/warp7/warp7_rotpk.S
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+ .global warp7_rotpk_hash
+ .global warp7_rotpk_hash_end
+warp7_rotpk_hash:
+ /* DER header */
+ .byte 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48
+ .byte 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
+ /* SHA256 */
+ .incbin ROTPK_HASH
+warp7_rotpk_hash_end:
diff --git a/plat/imx/imx7/warp7/warp7_trusted_boot.c b/plat/imx/imx7/warp7/warp7_trusted_boot.c
new file mode 100644
index 0000000..8157cd5
--- /dev/null
+++ b/plat/imx/imx7/warp7/warp7_trusted_boot.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <plat/common/platform.h>
+
+extern char warp7_rotpk_hash[], warp7_rotpk_hash_end[];
+
+int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
+ unsigned int *flags)
+{
+ *key_ptr = warp7_rotpk_hash;
+ *key_len = warp7_rotpk_hash_end - warp7_rotpk_hash;
+ *flags = ROTPK_IS_HASH;
+
+ return 0;
+}
+
+int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
+{
+ *nv_ctr = 0;
+
+ return 0;
+}
+
+int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
+{
+ return 1;
+}
diff --git a/plat/imx/imx8m/imx8mq/platform.mk b/plat/imx/imx8m/imx8mq/platform.mk
index 0255268..2681e57 100644
--- a/plat/imx/imx8m/imx8mq/platform.mk
+++ b/plat/imx/imx8m/imx8mq/platform.mk
@@ -34,3 +34,7 @@
RESET_TO_BL31 := 1
A53_DISABLE_NON_TEMPORAL_HINT := 0
MULTI_CONSOLE_API := 1
+
+ERRATA_A53_835769 := 1
+ERRATA_A53_843419 := 1
+ERRATA_A53_855873 := 1
diff --git a/plat/imx/imx8qm/platform.mk b/plat/imx/imx8qm/platform.mk
index 9113d33..ed6108d 100644
--- a/plat/imx/imx8qm/platform.mk
+++ b/plat/imx/imx8qm/platform.mk
@@ -38,3 +38,7 @@
A53_DISABLE_NON_TEMPORAL_HINT := 0
MULTI_CONSOLE_API := 1
ERRATA_A72_859971 := 1
+
+ERRATA_A53_835769 := 1
+ERRATA_A53_843419 := 1
+ERRATA_A53_855873 := 1
diff --git a/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c b/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c
index 1867511..1c5d2e1 100644
--- a/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c
+++ b/plat/nvidia/tegra/common/drivers/bpmp/bpmp.c
@@ -125,7 +125,7 @@
val = mmio_read_32(TEGRA_RES_SEMA_BASE + STA_OFFSET);
if (val != SIGN_OF_LIFE) {
ERROR("BPMP precessor not available\n");
- ret = -ENOTSUP;
+ return -ENOTSUP;
}
/* check if clock for the atomics block is enabled */
@@ -158,8 +158,7 @@
}
/* mark state as "initialized" */
- if (ret == 0)
- bpmp_init_state = BPMP_INIT_COMPLETE;
+ bpmp_init_state = BPMP_INIT_COMPLETE;
/* the channel values have to be visible across all cpus */
flush_dcache_range((uint64_t)channel_base, sizeof(channel_base));
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c
new file mode 100644
index 0000000..7faa2f0
--- /dev/null
+++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <bpmp_ipc.h>
+#include <debug.h>
+#include <delay_timer.h>
+#include <errno.h>
+#include <mmio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <tegra_def.h>
+#include <utils_def.h>
+
+#include "intf.h"
+#include "ivc.h"
+
+/**
+ * Holds IVC channel data
+ */
+struct ccplex_bpmp_channel_data {
+ /* Buffer for incoming data */
+ struct frame_data *ib;
+
+ /* Buffer for outgoing data */
+ struct frame_data *ob;
+};
+
+static struct ccplex_bpmp_channel_data s_channel;
+static struct ivc ivc_ccplex_bpmp_channel;
+
+/*
+ * Helper functions to access the HSP doorbell registers
+ */
+static inline uint32_t hsp_db_read(uint32_t reg)
+{
+ return mmio_read_32((uint32_t)(TEGRA_HSP_DBELL_BASE + reg));
+}
+
+static inline void hsp_db_write(uint32_t reg, uint32_t val)
+{
+ mmio_write_32((uint32_t)(TEGRA_HSP_DBELL_BASE + reg), val);
+}
+
+/*******************************************************************************
+ * IVC wrappers for CCPLEX <-> BPMP communication.
+ ******************************************************************************/
+
+static void tegra_bpmp_ring_bpmp_doorbell(void);
+
+/*
+ * Get the next frame where data can be written.
+ */
+static struct frame_data *tegra_bpmp_get_next_out_frame(void)
+{
+ struct frame_data *frame;
+ const struct ivc *ch = &ivc_ccplex_bpmp_channel;
+
+ frame = (struct frame_data *)tegra_ivc_write_get_next_frame(ch);
+ if (frame == NULL) {
+ ERROR("%s: Error in getting next frame, exiting\n", __func__);
+ } else {
+ s_channel.ob = frame;
+ }
+
+ return frame;
+}
+
+static void tegra_bpmp_signal_slave(void)
+{
+ (void)tegra_ivc_write_advance(&ivc_ccplex_bpmp_channel);
+ tegra_bpmp_ring_bpmp_doorbell();
+}
+
+static int32_t tegra_bpmp_free_master(void)
+{
+ return tegra_ivc_read_advance(&ivc_ccplex_bpmp_channel);
+}
+
+static bool tegra_bpmp_slave_acked(void)
+{
+ struct frame_data *frame;
+ bool ret = true;
+
+ frame = (struct frame_data *)tegra_ivc_read_get_next_frame(&ivc_ccplex_bpmp_channel);
+ if (frame == NULL) {
+ ret = false;
+ } else {
+ s_channel.ib = frame;
+ }
+
+ return ret;
+}
+
+static struct frame_data *tegra_bpmp_get_cur_in_frame(void)
+{
+ return s_channel.ib;
+}
+
+/*
+ * Enables BPMP to ring CCPlex doorbell
+ */
+static void tegra_bpmp_enable_ccplex_doorbell(void)
+{
+ uint32_t reg;
+
+ reg = hsp_db_read(HSP_DBELL_1_ENABLE);
+ reg |= HSP_MASTER_BPMP_BIT;
+ hsp_db_write(HSP_DBELL_1_ENABLE, reg);
+}
+
+/*
+ * CCPlex rings the BPMP doorbell
+ */
+static void tegra_bpmp_ring_bpmp_doorbell(void)
+{
+ /*
+ * Any writes to this register has the same effect,
+ * uses master ID of the write transaction and set
+ * corresponding flag.
+ */
+ hsp_db_write(HSP_DBELL_3_TRIGGER, HSP_MASTER_CCPLEX_BIT);
+}
+
+/*
+ * Returns true if CCPLex can ring BPMP doorbell, otherwise false.
+ * This also signals that BPMP is up and ready.
+ */
+static bool tegra_bpmp_can_ccplex_ring_doorbell(void)
+{
+ uint32_t reg;
+
+ /* check if ccplex can communicate with bpmp */
+ reg = hsp_db_read(HSP_DBELL_3_ENABLE);
+
+ return ((reg & HSP_MASTER_CCPLEX_BIT) != 0U);
+}
+
+static int32_t tegra_bpmp_wait_for_slave_ack(void)
+{
+ uint32_t timeout = TIMEOUT_RESPONSE_FROM_BPMP_US;
+
+ while (!tegra_bpmp_slave_acked() && (timeout != 0U)) {
+ udelay(1);
+ timeout--;
+ };
+
+ return ((timeout == 0U) ? -ETIMEDOUT : 0);
+}
+
+/*
+ * Notification from the ivc layer
+ */
+static void tegra_bpmp_ivc_notify(const struct ivc *ivc)
+{
+ (void)(ivc);
+
+ tegra_bpmp_ring_bpmp_doorbell();
+}
+
+/*
+ * Atomic send/receive API, which means it waits until slave acks
+ */
+static int32_t tegra_bpmp_ipc_send_req_atomic(uint32_t mrq, void *p_out,
+ uint32_t size_out, void *p_in, uint32_t size_in)
+{
+ struct frame_data *frame = tegra_bpmp_get_next_out_frame();
+ const struct frame_data *f_in = NULL;
+ int32_t ret = 0;
+ void *p_fdata;
+
+ if ((p_out == NULL) || (size_out > IVC_DATA_SZ_BYTES) ||
+ (frame == NULL)) {
+ ERROR("%s: invalid parameters, exiting\n", __func__);
+ ret = -EINVAL;
+ }
+
+ if (ret == 0) {
+
+ /* prepare the command frame */
+ frame->mrq = mrq;
+ frame->flags = FLAG_DO_ACK;
+ p_fdata = frame->data;
+ (void)memcpy(p_fdata, p_out, (size_t)size_out);
+
+ /* signal the slave */
+ tegra_bpmp_signal_slave();
+
+ /* wait for slave to ack */
+ ret = tegra_bpmp_wait_for_slave_ack();
+ if (ret != 0) {
+ ERROR("failed waiting for the slave to ack\n");
+ }
+
+ /* retrieve the response frame */
+ if ((size_in <= IVC_DATA_SZ_BYTES) && (p_in != NULL) &&
+ (ret == 0)) {
+
+ f_in = tegra_bpmp_get_cur_in_frame();
+ if (f_in != NULL) {
+ ERROR("Failed to get next input frame!\n");
+ } else {
+ (void)memcpy(p_in, p_fdata, (size_t)size_in);
+ }
+ }
+
+ if (ret == 0) {
+ ret = tegra_bpmp_free_master();
+ if (ret != 0) {
+ ERROR("Failed to free master\n");
+ }
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * Initializes the BPMP<--->CCPlex communication path.
+ */
+int32_t tegra_bpmp_ipc_init(void)
+{
+ size_t msg_size;
+ uint32_t frame_size, timeout;
+ int32_t error = 0;
+
+ /* allow bpmp to ring CCPLEX's doorbell */
+ tegra_bpmp_enable_ccplex_doorbell();
+
+ /* wait for BPMP to actually ring the doorbell */
+ timeout = TIMEOUT_RESPONSE_FROM_BPMP_US;
+ while ((timeout != 0U) && !tegra_bpmp_can_ccplex_ring_doorbell()) {
+ udelay(1); /* bpmp turn-around time */
+ timeout--;
+ }
+
+ if (timeout == 0U) {
+ ERROR("%s: BPMP firmware is not ready\n", __func__);
+ return -ENOTSUP;
+ }
+
+ INFO("%s: BPMP handshake completed\n", __func__);
+
+ msg_size = tegra_ivc_align(IVC_CMD_SZ_BYTES);
+ frame_size = (uint32_t)tegra_ivc_total_queue_size(msg_size);
+ if (frame_size > TEGRA_BPMP_IPC_CH_MAP_SIZE) {
+ ERROR("%s: carveout size is not sufficient\n", __func__);
+ return -EINVAL;
+ }
+
+ error = tegra_ivc_init(&ivc_ccplex_bpmp_channel,
+ (uint32_t)TEGRA_BPMP_IPC_RX_PHYS_BASE,
+ (uint32_t)TEGRA_BPMP_IPC_TX_PHYS_BASE,
+ 1U, frame_size, tegra_bpmp_ivc_notify);
+ if (error != 0) {
+
+ ERROR("%s: IVC init failed (%d)\n", __func__, error);
+
+ } else {
+
+ /* reset channel */
+ tegra_ivc_channel_reset(&ivc_ccplex_bpmp_channel);
+
+ /* wait for notification from BPMP */
+ while (tegra_ivc_channel_notified(&ivc_ccplex_bpmp_channel) != 0) {
+ /*
+ * Interrupt BPMP with doorbell each time after
+ * tegra_ivc_channel_notified() returns non zero
+ * value.
+ */
+ tegra_bpmp_ring_bpmp_doorbell();
+ }
+
+ INFO("%s: All communication channels initialized\n", __func__);
+ }
+
+ return error;
+}
+
+/* Handler to reset a hardware module */
+int32_t tegra_bpmp_ipc_reset_module(uint32_t rst_id)
+{
+ int32_t ret;
+ struct mrq_reset_request req = {
+ .cmd = (uint32_t)CMD_RESET_MODULE,
+ .reset_id = rst_id
+ };
+
+ /* only GPCDMA/XUSB_PADCTL resets are supported */
+ assert((rst_id == TEGRA_RESET_ID_XUSB_PADCTL) ||
+ (rst_id == TEGRA_RESET_ID_GPCDMA));
+
+ ret = tegra_bpmp_ipc_send_req_atomic(MRQ_RESET, &req,
+ (uint32_t)sizeof(req), NULL, 0);
+ if (ret != 0) {
+ ERROR("%s: failed for module %d with error %d\n", __func__,
+ rst_id, ret);
+ }
+
+ return ret;
+}
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h
new file mode 100644
index 0000000..689f8bb
--- /dev/null
+++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef INTF_H
+#define INTF_H
+
+/**
+ * Flags used in IPC req
+ */
+#define FLAG_DO_ACK (U(1) << 0)
+#define FLAG_RING_DOORBELL (U(1) << 1)
+
+/* Bit 1 is designated for CCPlex in secure world */
+#define HSP_MASTER_CCPLEX_BIT (U(1) << 1)
+/* Bit 19 is designated for BPMP in non-secure world */
+#define HSP_MASTER_BPMP_BIT (U(1) << 19)
+/* Timeout to receive response from BPMP is 1 sec */
+#define TIMEOUT_RESPONSE_FROM_BPMP_US U(1000000) /* in microseconds */
+
+/**
+ * IVC protocol defines and command/response frame
+ */
+
+/**
+ * IVC specific defines
+ */
+#define IVC_CMD_SZ_BYTES U(128)
+#define IVC_DATA_SZ_BYTES U(120)
+
+/**
+ * Holds frame data for an IPC request
+ */
+struct frame_data {
+ /* Identification as to what kind of data is being transmitted */
+ uint32_t mrq;
+
+ /* Flags for slave as to how to respond back */
+ uint32_t flags;
+
+ /* Actual data being sent */
+ uint8_t data[IVC_DATA_SZ_BYTES];
+};
+
+/**
+ * Commands send to the BPMP firmware
+ */
+
+/**
+ * MRQ code to issue a module reset command to BPMP
+ */
+#define MRQ_RESET U(20)
+
+/**
+ * Reset sub-commands
+ */
+#define CMD_RESET_ASSERT U(1)
+#define CMD_RESET_DEASSERT U(2)
+#define CMD_RESET_MODULE U(3)
+
+/**
+ * Used by the sender of an #MRQ_RESET message to request BPMP to
+ * assert or deassert a given reset line.
+ */
+struct __attribute__((packed)) mrq_reset_request {
+ /* reset action to perform (mrq_reset_commands) */
+ uint32_t cmd;
+ /* id of the reset to affected */
+ uint32_t reset_id;
+};
+
+#endif /* INTF_H */
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c
new file mode 100644
index 0000000..4212eca
--- /dev/null
+++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c
@@ -0,0 +1,653 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "ivc.h"
+
+/*
+ * IVC channel reset protocol.
+ *
+ * Each end uses its tx_channel.state to indicate its synchronization state.
+ */
+enum {
+ /*
+ * This value is zero for backwards compatibility with services that
+ * assume channels to be initially zeroed. Such channels are in an
+ * initially valid state, but cannot be asynchronously reset, and must
+ * maintain a valid state at all times.
+ *
+ * The transmitting end can enter the established state from the sync or
+ * ack state when it observes the receiving endpoint in the ack or
+ * established state, indicating that has cleared the counters in our
+ * rx_channel.
+ */
+ ivc_state_established = U(0),
+
+ /*
+ * If an endpoint is observed in the sync state, the remote endpoint is
+ * allowed to clear the counters it owns asynchronously with respect to
+ * the current endpoint. Therefore, the current endpoint is no longer
+ * allowed to communicate.
+ */
+ ivc_state_sync = U(1),
+
+ /*
+ * When the transmitting end observes the receiving end in the sync
+ * state, it can clear the w_count and r_count and transition to the ack
+ * state. If the remote endpoint observes us in the ack state, it can
+ * return to the established state once it has cleared its counters.
+ */
+ ivc_state_ack = U(2)
+};
+
+/*
+ * This structure is divided into two-cache aligned parts, the first is only
+ * written through the tx_channel pointer, while the second is only written
+ * through the rx_channel pointer. This delineates ownership of the cache lines,
+ * which is critical to performance and necessary in non-cache coherent
+ * implementations.
+ */
+struct ivc_channel_header {
+ struct {
+ /* fields owned by the transmitting end */
+ uint32_t w_count;
+ uint32_t state;
+ uint32_t w_rsvd[IVC_CHHDR_TX_FIELDS - 2];
+ };
+ struct {
+ /* fields owned by the receiving end */
+ uint32_t r_count;
+ uint32_t r_rsvd[IVC_CHHDR_RX_FIELDS - 1];
+ };
+};
+
+static inline bool ivc_channel_empty(const struct ivc *ivc,
+ volatile const struct ivc_channel_header *ch)
+{
+ /*
+ * This function performs multiple checks on the same values with
+ * security implications, so sample the counters' current values in
+ * shared memory to ensure that these checks use the same values.
+ */
+ uint32_t wr_count = ch->w_count;
+ uint32_t rd_count = ch->r_count;
+ bool ret = false;
+
+ (void)ivc;
+
+ /*
+ * Perform an over-full check to prevent denial of service attacks where
+ * a server could be easily fooled into believing that there's an
+ * extremely large number of frames ready, since receivers are not
+ * expected to check for full or over-full conditions.
+ *
+ * Although the channel isn't empty, this is an invalid case caused by
+ * a potentially malicious peer, so returning empty is safer, because it
+ * gives the impression that the channel has gone silent.
+ */
+ if (((wr_count - rd_count) > ivc->nframes) || (wr_count == rd_count)) {
+ ret = true;
+ }
+
+ return ret;
+}
+
+static inline bool ivc_channel_full(const struct ivc *ivc,
+ volatile const struct ivc_channel_header *ch)
+{
+ uint32_t wr_count = ch->w_count;
+ uint32_t rd_count = ch->r_count;
+
+ (void)ivc;
+
+ /*
+ * Invalid cases where the counters indicate that the queue is over
+ * capacity also appear full.
+ */
+ return ((wr_count - rd_count) >= ivc->nframes);
+}
+
+static inline uint32_t ivc_channel_avail_count(const struct ivc *ivc,
+ volatile const struct ivc_channel_header *ch)
+{
+ uint32_t wr_count = ch->w_count;
+ uint32_t rd_count = ch->r_count;
+
+ (void)ivc;
+
+ /*
+ * This function isn't expected to be used in scenarios where an
+ * over-full situation can lead to denial of service attacks. See the
+ * comment in ivc_channel_empty() for an explanation about special
+ * over-full considerations.
+ */
+ return (wr_count - rd_count);
+}
+
+static inline void ivc_advance_tx(struct ivc *ivc)
+{
+ ivc->tx_channel->w_count++;
+
+ if (ivc->w_pos == (ivc->nframes - (uint32_t)1U)) {
+ ivc->w_pos = 0U;
+ } else {
+ ivc->w_pos++;
+ }
+}
+
+static inline void ivc_advance_rx(struct ivc *ivc)
+{
+ ivc->rx_channel->r_count++;
+
+ if (ivc->r_pos == (ivc->nframes - (uint32_t)1U)) {
+ ivc->r_pos = 0U;
+ } else {
+ ivc->r_pos++;
+ }
+}
+
+static inline int32_t ivc_check_read(const struct ivc *ivc)
+{
+ /*
+ * tx_channel->state is set locally, so it is not synchronized with
+ * state from the remote peer. The remote peer cannot reset its
+ * transmit counters until we've acknowledged its synchronization
+ * request, so no additional synchronization is required because an
+ * asynchronous transition of rx_channel->state to ivc_state_ack is not
+ * allowed.
+ */
+ if (ivc->tx_channel->state != ivc_state_established) {
+ return -ECONNRESET;
+ }
+
+ /*
+ * Avoid unnecessary invalidations when performing repeated accesses to
+ * an IVC channel by checking the old queue pointers first.
+ * Synchronization is only necessary when these pointers indicate empty
+ * or full.
+ */
+ if (!ivc_channel_empty(ivc, ivc->rx_channel)) {
+ return 0;
+ }
+
+ return ivc_channel_empty(ivc, ivc->rx_channel) ? -ENOMEM : 0;
+}
+
+static inline int32_t ivc_check_write(const struct ivc *ivc)
+{
+ if (ivc->tx_channel->state != ivc_state_established) {
+ return -ECONNRESET;
+ }
+
+ if (!ivc_channel_full(ivc, ivc->tx_channel)) {
+ return 0;
+ }
+
+ return ivc_channel_full(ivc, ivc->tx_channel) ? -ENOMEM : 0;
+}
+
+bool tegra_ivc_can_read(const struct ivc *ivc)
+{
+ return ivc_check_read(ivc) == 0;
+}
+
+bool tegra_ivc_can_write(const struct ivc *ivc)
+{
+ return ivc_check_write(ivc) == 0;
+}
+
+bool tegra_ivc_tx_empty(const struct ivc *ivc)
+{
+ return ivc_channel_empty(ivc, ivc->tx_channel);
+}
+
+static inline uintptr_t calc_frame_offset(uint32_t frame_index,
+ uint32_t frame_size, uint32_t frame_offset)
+{
+ return ((uintptr_t)frame_index * (uintptr_t)frame_size) +
+ (uintptr_t)frame_offset;
+}
+
+static void *ivc_frame_pointer(const struct ivc *ivc,
+ volatile const struct ivc_channel_header *ch,
+ uint32_t frame)
+{
+ assert(frame < ivc->nframes);
+ return (void *)((uintptr_t)(&ch[1]) +
+ calc_frame_offset(frame, ivc->frame_size, 0));
+}
+
+int32_t tegra_ivc_read(struct ivc *ivc, void *buf, size_t max_read)
+{
+ const void *src;
+ int32_t result;
+
+ if (buf == NULL) {
+ return -EINVAL;
+ }
+
+ if (max_read > ivc->frame_size) {
+ return -E2BIG;
+ }
+
+ result = ivc_check_read(ivc);
+ if (result != 0) {
+ return result;
+ }
+
+ /*
+ * Order observation of w_pos potentially indicating new data before
+ * data read.
+ */
+ dmbish();
+
+ src = ivc_frame_pointer(ivc, ivc->rx_channel, ivc->r_pos);
+
+ (void)memcpy(buf, src, max_read);
+
+ ivc_advance_rx(ivc);
+
+ /*
+ * Ensure our write to r_pos occurs before our read from w_pos.
+ */
+ dmbish();
+
+ /*
+ * Notify only upon transition from full to non-full.
+ * The available count can only asynchronously increase, so the
+ * worst possible side-effect will be a spurious notification.
+ */
+ if (ivc_channel_avail_count(ivc, ivc->rx_channel) == (ivc->nframes - (uint32_t)1U)) {
+ ivc->notify(ivc);
+ }
+
+ return (int32_t)max_read;
+}
+
+/* directly peek at the next frame rx'ed */
+void *tegra_ivc_read_get_next_frame(const struct ivc *ivc)
+{
+ if (ivc_check_read(ivc) != 0) {
+ return NULL;
+ }
+
+ /*
+ * Order observation of w_pos potentially indicating new data before
+ * data read.
+ */
+ dmbld();
+
+ return ivc_frame_pointer(ivc, ivc->rx_channel, ivc->r_pos);
+}
+
+int32_t tegra_ivc_read_advance(struct ivc *ivc)
+{
+ /*
+ * No read barriers or synchronization here: the caller is expected to
+ * have already observed the channel non-empty. This check is just to
+ * catch programming errors.
+ */
+ int32_t result = ivc_check_read(ivc);
+ if (result != 0) {
+ return result;
+ }
+
+ ivc_advance_rx(ivc);
+
+ /*
+ * Ensure our write to r_pos occurs before our read from w_pos.
+ */
+ dmbish();
+
+ /*
+ * Notify only upon transition from full to non-full.
+ * The available count can only asynchronously increase, so the
+ * worst possible side-effect will be a spurious notification.
+ */
+ if (ivc_channel_avail_count(ivc, ivc->rx_channel) == (ivc->nframes - (uint32_t)1U)) {
+ ivc->notify(ivc);
+ }
+
+ return 0;
+}
+
+int32_t tegra_ivc_write(struct ivc *ivc, const void *buf, size_t size)
+{
+ void *p;
+ int32_t result;
+
+ if ((buf == NULL) || (ivc == NULL)) {
+ return -EINVAL;
+ }
+
+ if (size > ivc->frame_size) {
+ return -E2BIG;
+ }
+
+ result = ivc_check_write(ivc);
+ if (result != 0) {
+ return result;
+ }
+
+ p = ivc_frame_pointer(ivc, ivc->tx_channel, ivc->w_pos);
+
+ (void)memset(p, 0, ivc->frame_size);
+ (void)memcpy(p, buf, size);
+
+ /*
+ * Ensure that updated data is visible before the w_pos counter
+ * indicates that it is ready.
+ */
+ dmbst();
+
+ ivc_advance_tx(ivc);
+
+ /*
+ * Ensure our write to w_pos occurs before our read from r_pos.
+ */
+ dmbish();
+
+ /*
+ * Notify only upon transition from empty to non-empty.
+ * The available count can only asynchronously decrease, so the
+ * worst possible side-effect will be a spurious notification.
+ */
+ if (ivc_channel_avail_count(ivc, ivc->tx_channel) == 1U) {
+ ivc->notify(ivc);
+ }
+
+ return (int32_t)size;
+}
+
+/* directly poke at the next frame to be tx'ed */
+void *tegra_ivc_write_get_next_frame(const struct ivc *ivc)
+{
+ if (ivc_check_write(ivc) != 0) {
+ return NULL;
+ }
+
+ return ivc_frame_pointer(ivc, ivc->tx_channel, ivc->w_pos);
+}
+
+/* advance the tx buffer */
+int32_t tegra_ivc_write_advance(struct ivc *ivc)
+{
+ int32_t result = ivc_check_write(ivc);
+
+ if (result != 0) {
+ return result;
+ }
+
+ /*
+ * Order any possible stores to the frame before update of w_pos.
+ */
+ dmbst();
+
+ ivc_advance_tx(ivc);
+
+ /*
+ * Ensure our write to w_pos occurs before our read from r_pos.
+ */
+ dmbish();
+
+ /*
+ * Notify only upon transition from empty to non-empty.
+ * The available count can only asynchronously decrease, so the
+ * worst possible side-effect will be a spurious notification.
+ */
+ if (ivc_channel_avail_count(ivc, ivc->tx_channel) == (uint32_t)1U) {
+ ivc->notify(ivc);
+ }
+
+ return 0;
+}
+
+void tegra_ivc_channel_reset(const struct ivc *ivc)
+{
+ ivc->tx_channel->state = ivc_state_sync;
+ ivc->notify(ivc);
+}
+
+/*
+ * ===============================================================
+ * IVC State Transition Table - see tegra_ivc_channel_notified()
+ * ===============================================================
+ *
+ * local remote action
+ * ----- ------ -----------------------------------
+ * SYNC EST <none>
+ * SYNC ACK reset counters; move to EST; notify
+ * SYNC SYNC reset counters; move to ACK; notify
+ * ACK EST move to EST; notify
+ * ACK ACK move to EST; notify
+ * ACK SYNC reset counters; move to ACK; notify
+ * EST EST <none>
+ * EST ACK <none>
+ * EST SYNC reset counters; move to ACK; notify
+ *
+ * ===============================================================
+ */
+int32_t tegra_ivc_channel_notified(struct ivc *ivc)
+{
+ uint32_t peer_state;
+
+ /* Copy the receiver's state out of shared memory. */
+ peer_state = ivc->rx_channel->state;
+
+ if (peer_state == (uint32_t)ivc_state_sync) {
+ /*
+ * Order observation of ivc_state_sync before stores clearing
+ * tx_channel.
+ */
+ dmbld();
+
+ /*
+ * Reset tx_channel counters. The remote end is in the SYNC
+ * state and won't make progress until we change our state,
+ * so the counters are not in use at this time.
+ */
+ ivc->tx_channel->w_count = 0U;
+ ivc->rx_channel->r_count = 0U;
+
+ ivc->w_pos = 0U;
+ ivc->r_pos = 0U;
+
+ /*
+ * Ensure that counters appear cleared before new state can be
+ * observed.
+ */
+ dmbst();
+
+ /*
+ * Move to ACK state. We have just cleared our counters, so it
+ * is now safe for the remote end to start using these values.
+ */
+ ivc->tx_channel->state = ivc_state_ack;
+
+ /*
+ * Notify remote end to observe state transition.
+ */
+ ivc->notify(ivc);
+
+ } else if ((ivc->tx_channel->state == (uint32_t)ivc_state_sync) &&
+ (peer_state == (uint32_t)ivc_state_ack)) {
+ /*
+ * Order observation of ivc_state_sync before stores clearing
+ * tx_channel.
+ */
+ dmbld();
+
+ /*
+ * Reset tx_channel counters. The remote end is in the ACK
+ * state and won't make progress until we change our state,
+ * so the counters are not in use at this time.
+ */
+ ivc->tx_channel->w_count = 0U;
+ ivc->rx_channel->r_count = 0U;
+
+ ivc->w_pos = 0U;
+ ivc->r_pos = 0U;
+
+ /*
+ * Ensure that counters appear cleared before new state can be
+ * observed.
+ */
+ dmbst();
+
+ /*
+ * Move to ESTABLISHED state. We know that the remote end has
+ * already cleared its counters, so it is safe to start
+ * writing/reading on this channel.
+ */
+ ivc->tx_channel->state = ivc_state_established;
+
+ /*
+ * Notify remote end to observe state transition.
+ */
+ ivc->notify(ivc);
+
+ } else if (ivc->tx_channel->state == (uint32_t)ivc_state_ack) {
+ /*
+ * At this point, we have observed the peer to be in either
+ * the ACK or ESTABLISHED state. Next, order observation of
+ * peer state before storing to tx_channel.
+ */
+ dmbld();
+
+ /*
+ * Move to ESTABLISHED state. We know that we have previously
+ * cleared our counters, and we know that the remote end has
+ * cleared its counters, so it is safe to start writing/reading
+ * on this channel.
+ */
+ ivc->tx_channel->state = ivc_state_established;
+
+ /*
+ * Notify remote end to observe state transition.
+ */
+ ivc->notify(ivc);
+
+ } else {
+ /*
+ * There is no need to handle any further action. Either the
+ * channel is already fully established, or we are waiting for
+ * the remote end to catch up with our current state. Refer
+ * to the diagram in "IVC State Transition Table" above.
+ */
+ }
+
+ return ((ivc->tx_channel->state == (uint32_t)ivc_state_established) ? 0 : -EAGAIN);
+}
+
+size_t tegra_ivc_align(size_t size)
+{
+ return (size + (IVC_ALIGN - 1U)) & ~(IVC_ALIGN - 1U);
+}
+
+size_t tegra_ivc_total_queue_size(size_t queue_size)
+{
+ if ((queue_size & (IVC_ALIGN - 1U)) != 0U) {
+ ERROR("queue_size (%d) must be %d-byte aligned\n",
+ (int32_t)queue_size, IVC_ALIGN);
+ return 0;
+ }
+ return queue_size + sizeof(struct ivc_channel_header);
+}
+
+static int32_t check_ivc_params(uintptr_t queue_base1, uintptr_t queue_base2,
+ uint32_t nframes, uint32_t frame_size)
+{
+ assert((offsetof(struct ivc_channel_header, w_count)
+ & (IVC_ALIGN - 1U)) == 0U);
+ assert((offsetof(struct ivc_channel_header, r_count)
+ & (IVC_ALIGN - 1U)) == 0U);
+ assert((sizeof(struct ivc_channel_header) & (IVC_ALIGN - 1U)) == 0U);
+
+ if (((uint64_t)nframes * (uint64_t)frame_size) >= 0x100000000ULL) {
+ ERROR("nframes * frame_size overflows\n");
+ return -EINVAL;
+ }
+
+ /*
+ * The headers must at least be aligned enough for counters
+ * to be accessed atomically.
+ */
+ if ((queue_base1 & (IVC_ALIGN - 1U)) != 0U) {
+ ERROR("ivc channel start not aligned: %lx\n", queue_base1);
+ return -EINVAL;
+ }
+ if ((queue_base2 & (IVC_ALIGN - 1U)) != 0U) {
+ ERROR("ivc channel start not aligned: %lx\n", queue_base2);
+ return -EINVAL;
+ }
+
+ if ((frame_size & (IVC_ALIGN - 1U)) != 0U) {
+ ERROR("frame size not adequately aligned: %u\n",
+ frame_size);
+ return -EINVAL;
+ }
+
+ if (queue_base1 < queue_base2) {
+ if ((queue_base1 + ((uint64_t)frame_size * nframes)) > queue_base2) {
+ ERROR("queue regions overlap: %lx + %x, %x\n",
+ queue_base1, frame_size,
+ frame_size * nframes);
+ return -EINVAL;
+ }
+ } else {
+ if ((queue_base2 + ((uint64_t)frame_size * nframes)) > queue_base1) {
+ ERROR("queue regions overlap: %lx + %x, %x\n",
+ queue_base2, frame_size,
+ frame_size * nframes);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+int32_t tegra_ivc_init(struct ivc *ivc, uintptr_t rx_base, uintptr_t tx_base,
+ uint32_t nframes, uint32_t frame_size,
+ ivc_notify_function notify)
+{
+ int32_t result;
+
+ /* sanity check input params */
+ if ((ivc == NULL) || (notify == NULL)) {
+ return -EINVAL;
+ }
+
+ result = check_ivc_params(rx_base, tx_base, nframes, frame_size);
+ if (result != 0) {
+ return result;
+ }
+
+ /*
+ * All sizes that can be returned by communication functions should
+ * fit in a 32-bit integer.
+ */
+ if (frame_size > (1u << 31)) {
+ return -E2BIG;
+ }
+
+ ivc->rx_channel = (struct ivc_channel_header *)rx_base;
+ ivc->tx_channel = (struct ivc_channel_header *)tx_base;
+ ivc->notify = notify;
+ ivc->frame_size = frame_size;
+ ivc->nframes = nframes;
+ ivc->w_pos = 0U;
+ ivc->r_pos = 0U;
+
+ INFO("%s: done\n", __func__);
+
+ return 0;
+}
diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h
new file mode 100644
index 0000000..f34d6cf
--- /dev/null
+++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IVC_H
+#define IVC_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <utils_def.h>
+
+#define IVC_ALIGN U(64)
+#define IVC_CHHDR_TX_FIELDS U(16)
+#define IVC_CHHDR_RX_FIELDS U(16)
+
+struct ivc;
+struct ivc_channel_header;
+
+/* callback handler for notify on receiving a response */
+typedef void (* ivc_notify_function)(const struct ivc *);
+
+struct ivc {
+ struct ivc_channel_header *rx_channel;
+ struct ivc_channel_header *tx_channel;
+ uint32_t w_pos;
+ uint32_t r_pos;
+ ivc_notify_function notify;
+ uint32_t nframes;
+ uint32_t frame_size;
+};
+
+int32_t tegra_ivc_init(struct ivc *ivc, uintptr_t rx_base, uintptr_t tx_base,
+ uint32_t nframes, uint32_t frame_size,
+ ivc_notify_function notify);
+size_t tegra_ivc_total_queue_size(size_t queue_size);
+size_t tegra_ivc_align(size_t size);
+int32_t tegra_ivc_channel_notified(struct ivc *ivc);
+void tegra_ivc_channel_reset(const struct ivc *ivc);
+int32_t tegra_ivc_write_advance(struct ivc *ivc);
+void *tegra_ivc_write_get_next_frame(const struct ivc *ivc);
+int32_t tegra_ivc_write(struct ivc *ivc, const void *buf, size_t size);
+int32_t tegra_ivc_read_advance(struct ivc *ivc);
+void *tegra_ivc_read_get_next_frame(const struct ivc *ivc);
+int32_t tegra_ivc_read(struct ivc *ivc, void *buf, size_t max_read);
+bool tegra_ivc_tx_empty(const struct ivc *ivc);
+bool tegra_ivc_can_write(const struct ivc *ivc);
+bool tegra_ivc_can_read(const struct ivc *ivc);
+
+#endif /* IVC_H */
diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
index 1b221c2..a3ef5e1 100644
--- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
+++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
@@ -25,316 +25,15 @@
static uint64_t video_mem_base;
static uint64_t video_mem_size_mb;
-static void tegra_memctrl_reconfig_mss_clients(void)
-{
-#if ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS
- uint32_t val, wdata_0, wdata_1;
-
- /*
- * Assert Memory Controller's HOTRESET_FLUSH_ENABLE signal for
- * boot and strongly ordered MSS clients to flush existing memory
- * traffic and stall future requests.
- */
- val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0);
- assert(val == MC_CLIENT_HOTRESET_CTRL0_RESET_VAL);
-
- wdata_0 = MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB |
-#if ENABLE_AFI_DEVICE
- MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB |
-#endif
- MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB;
- tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
-
- /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
- do {
- val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
- } while ((val & wdata_0) != wdata_0);
-
- /* Wait one more time due to SW WAR for known legacy issue */
- do {
- val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
- } while ((val & wdata_0) != wdata_0);
-
- val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1);
- assert(val == MC_CLIENT_HOTRESET_CTRL1_RESET_VAL);
-
- wdata_1 = MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB |
- MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB;
- tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
-
- /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
- do {
- val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
- } while ((val & wdata_1) != wdata_1);
-
- /* Wait one more time due to SW WAR for known legacy issue */
- do {
- val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
- } while ((val & wdata_1) != wdata_1);
-
- /*
- * Change MEMTYPE_OVERRIDE from SO_DEV -> PASSTHRU for boot and
- * strongly ordered MSS clients. ROC needs to be single point
- * of control on overriding the memory type. So, remove TSA's
- * memtype override.
- *
- * MC clients with default SO_DEV override still enabled at TSA:
- * AONW, BPMPW, SCEW, APEW
- */
-#if ENABLE_AFI_DEVICE
- mc_set_tsa_passthrough(AFIW);
-#endif
- mc_set_tsa_passthrough(HDAW);
- mc_set_tsa_passthrough(SATAW);
- mc_set_tsa_passthrough(XUSB_HOSTW);
- mc_set_tsa_passthrough(XUSB_DEVW);
- mc_set_tsa_passthrough(SDMMCWAB);
- mc_set_tsa_passthrough(APEDMAW);
- mc_set_tsa_passthrough(SESWR);
- mc_set_tsa_passthrough(ETRW);
- mc_set_tsa_passthrough(AXISW);
- mc_set_tsa_passthrough(EQOSW);
- mc_set_tsa_passthrough(UFSHCW);
- mc_set_tsa_passthrough(BPMPDMAW);
- mc_set_tsa_passthrough(AONDMAW);
- mc_set_tsa_passthrough(SCEDMAW);
-
- /* Parker has no IO Coherency support and need the following:
- * Ordered MC Clients on Parker are AFI, EQOS, SATA, XUSB.
- * ISO clients(DISP, VI, EQOS) should never snoop caches and
- * don't need ROC/PCFIFO ordering.
- * ISO clients(EQOS) that need ordering should use PCFIFO ordering
- * and bypass ROC ordering by using FORCE_NON_COHERENT path.
- * FORCE_NON_COHERENT/FORCE_COHERENT config take precedence
- * over SMMU attributes.
- * Force all Normal memory transactions from ISO and non-ISO to be
- * non-coherent(bypass ROC, avoid cache snoop to avoid perf hit).
- * Force the SO_DEV transactions from ordered ISO clients(EQOS) to
- * non-coherent path and enable MC PCFIFO interlock for ordering.
- * Force the SO_DEV transactions from ordered non-ISO clients (PCIe,
- * XUSB, SATA) to coherent so that the transactions are
- * ordered by ROC.
- * PCFIFO ensure write ordering.
- * Read after Write ordering is maintained/enforced by MC clients.
- * Clients that need PCIe type write ordering must
- * go through ROC ordering.
- * Ordering enable for Read clients is not necessary.
- * R5's and A9 would get necessary ordering from AXI and
- * don't need ROC ordering enable:
- * - MMIO ordering is through dev mapping and MMIO
- * accesses bypass SMMU.
- * - Normal memory is accessed through SMMU and ordering is
- * ensured by client and AXI.
- * - Ack point for Normal memory is WCAM in MC.
- * - MMIO's can be early acked and AXI ensures dev memory ordering,
- * Client ensures read/write direction change ordering.
- * - See Bug 200312466 for more details.
- *
- * CGID_TAG_ADR is only present from T186 A02. As this code is common
- * between A01 and A02, tegra_memctrl_set_overrides() programs
- * CGID_TAG_ADR for the necessary clients on A02.
- */
- mc_set_txn_override(HDAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(BPMPW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(PTCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(NVDISPLAYR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(EQOSW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(NVJPGSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(ISPRA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SDMMCWAA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(VICSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(MPCOREW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(GPUSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(AXISR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SCEDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SDMMCW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(EQOSR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- /* See bug 200131110 comment #35*/
- mc_set_txn_override(APEDMAR, CGID_TAG_CLIENT_AXI_ID, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(NVENCSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SDMMCRAB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(VICSRD1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(BPMPDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(VIW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SDMMCRAA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(AXISW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(XUSB_DEVR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(UFSHCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(TSECSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(GPUSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SATAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(XUSB_HOSTW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(TSECSWRB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(GPUSRD2, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SCEDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(GPUSWR2, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(AONDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- /* See bug 200131110 comment #35*/
- mc_set_txn_override(APEDMAW, CGID_TAG_CLIENT_AXI_ID, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(AONW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(HOST1XDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(ETRR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SESWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(NVJPGSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(NVDECSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(TSECSRDB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(BPMPDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(APER, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(NVDECSRD1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(XUSB_HOSTR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(ISPWA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SESRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SCER, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(AONR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(MPCORER, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
- mc_set_txn_override(SDMMCWA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(HDAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(NVDECSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(UFSHCW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(AONDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SATAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(ETRW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(VICSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(NVENCSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- /* See bug 200131110 comment #35 */
- mc_set_txn_override(AFIR, CGID_TAG_DEFAULT, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SDMMCWAB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SDMMCRA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(NVDISPLAYR1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(ISPWB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(BPMPR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(APEW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(SDMMCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- mc_set_txn_override(XUSB_DEVW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(TSECSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
- /*
- * See bug 200131110 comment #35 - there are no normal requests
- * and AWID for SO/DEV requests is hardcoded in RTL for a
- * particular PCIE controller
- */
- mc_set_txn_override(AFIW, CGID_TAG_DEFAULT, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_COHERENT);
- mc_set_txn_override(SCEW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
-
- /*
- * At this point, ordering can occur at ROC. So, remove PCFIFO's
- * control over ordering requests.
- *
- * Change PCFIFO_*_ORDERED_CLIENT from ORDERED -> UNORDERED for
- * boot and strongly ordered MSS clients
- */
- val = MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL &
-#if ENABLE_AFI_DEVICE
- mc_set_pcfifo_unordered_boot_so_mss(1, AFIW) &
-#endif
- mc_set_pcfifo_unordered_boot_so_mss(1, HDAW) &
- mc_set_pcfifo_unordered_boot_so_mss(1, SATAW);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG1, val);
-
- val = MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL &
- mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_HOSTW) &
- mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_DEVW);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG2, val);
-
- val = MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL &
- mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWAB);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG3, val);
-
- val = MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL &
- mc_set_pcfifo_unordered_boot_so_mss(4, SESWR) &
- mc_set_pcfifo_unordered_boot_so_mss(4, ETRW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, AXISW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, UFSHCW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, BPMPDMAW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, AONDMAW) &
- mc_set_pcfifo_unordered_boot_so_mss(4, SCEDMAW);
- /* EQOSW is the only client that has PCFIFO order enabled. */
- val |= mc_set_pcfifo_ordered_boot_so_mss(4, EQOSW);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG4, val);
-
- val = MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL &
- mc_set_pcfifo_unordered_boot_so_mss(5, APEDMAW);
- tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG5, val);
-
- /*
- * Deassert HOTRESET FLUSH_ENABLE for boot and strongly ordered MSS
- * clients to allow memory traffic from all clients to start passing
- * through ROC
- */
- val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0);
- assert(val == wdata_0);
-
- wdata_0 = MC_CLIENT_HOTRESET_CTRL0_RESET_VAL;
- tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
-
- val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1);
- assert(val == wdata_1);
-
- wdata_1 = MC_CLIENT_HOTRESET_CTRL1_RESET_VAL;
- tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
-
-#endif
-}
+/*
+ * The following platform setup functions are weakly defined. They
+ * provide typical implementations that will be overridden by a SoC.
+ */
+#pragma weak plat_memctrl_tzdram_setup
-static void tegra_memctrl_set_overrides(void)
+void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes)
{
- const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
- const mc_txn_override_cfg_t *mc_txn_override_cfgs;
- uint32_t num_txn_override_cfgs;
- uint32_t i, val;
-
- /* Get the settings from the platform */
- assert(plat_mc_settings != NULL);
- mc_txn_override_cfgs = plat_mc_settings->txn_override_cfg;
- num_txn_override_cfgs = plat_mc_settings->num_txn_override_cfgs;
-
- /*
- * Set the MC_TXN_OVERRIDE registers for write clients.
- */
- if ((tegra_chipid_is_t186()) &&
- (!tegra_platform_is_silicon() ||
- (tegra_platform_is_silicon() && (tegra_get_chipid_minor() == 1U)))) {
-
- /*
- * GPU and NVENC settings for Tegra186 simulation and
- * Silicon rev. A01
- */
- val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR);
- val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK;
- tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR,
- val | MC_TXN_OVERRIDE_CGID_TAG_ZERO);
-
- val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2);
- val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK;
- tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2,
- val | MC_TXN_OVERRIDE_CGID_TAG_ZERO);
-
- val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR);
- val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK;
- tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR,
- val | MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID);
-
- } else {
-
- /*
- * Settings for Tegra186 silicon rev. A02 and onwards.
- */
- for (i = 0; i < num_txn_override_cfgs; i++) {
- val = tegra_mc_read_32(mc_txn_override_cfgs[i].offset);
- val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK;
- tegra_mc_write_32(mc_txn_override_cfgs[i].offset,
- val | mc_txn_override_cfgs[i].cgid_tag);
- }
- }
+ ; /* do nothing */
}
/*
@@ -352,10 +51,9 @@
INFO("Tegra Memory Controller (v2)\n");
-#if ENABLE_SMMU_DEVICE
/* Program the SMMU pagesize */
tegra_smmu_init();
-#endif
+
/* Get the settings from the platform */
assert(plat_mc_settings != NULL);
mc_streamid_override_regs = plat_mc_settings->streamid_override_cfg;
@@ -398,10 +96,14 @@
* boots with MSS having all control, but ROC provides a performance
* boost as compared to MSS.
*/
- tegra_memctrl_reconfig_mss_clients();
+ if (plat_mc_settings->reconfig_mss_clients != NULL) {
+ plat_mc_settings->reconfig_mss_clients();
+ }
/* Program overrides for MC transactions */
- tegra_memctrl_set_overrides();
+ if (plat_mc_settings->set_txn_overrides != NULL) {
+ plat_mc_settings->set_txn_overrides();
+ }
}
/*
@@ -409,16 +111,24 @@
*/
void tegra_memctrl_restore_settings(void)
{
+ const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
+
+ assert(plat_mc_settings != NULL);
+
/*
* Re-configure MSS to allow ROC to deal with ordering of the
* Memory Controller traffic. This is needed as the Memory Controller
* resets during System Suspend with MSS having all control, but ROC
* provides a performance boost as compared to MSS.
*/
- tegra_memctrl_reconfig_mss_clients();
+ if (plat_mc_settings->reconfig_mss_clients != NULL) {
+ plat_mc_settings->reconfig_mss_clients();
+ }
/* Program overrides for MC transactions */
- tegra_memctrl_set_overrides();
+ if (plat_mc_settings->set_txn_overrides != NULL) {
+ plat_mc_settings->set_txn_overrides();
+ }
/* video memory carveout region */
if (video_mem_base != 0ULL) {
@@ -444,42 +154,10 @@
*/
void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes)
{
- uint32_t val;
-
- /*
- * Setup the Memory controller to allow only secure accesses to
- * the TZDRAM carveout
- */
- INFO("Configuring TrustZone DRAM Memory Carveout\n");
-
- tegra_mc_write_32(MC_SECURITY_CFG0_0, (uint32_t)phys_base);
- tegra_mc_write_32(MC_SECURITY_CFG3_0, (uint32_t)(phys_base >> 32));
- tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20);
-
- /*
- * When TZ encryption enabled,
- * We need setup TZDRAM before CPU to access TZ Carveout,
- * otherwise CPU will fetch non-decrypted data.
- * So save TZDRAM setting for restore by SC7 resume FW.
- * Scratch registers map:
- * RSV55_0 = CFG1[12:0] | CFG0[31:20]
- * RSV55_1 = CFG3[1:0]
- */
-
- val = tegra_mc_read_32(MC_SECURITY_CFG1_0) & MC_SECURITY_SIZE_MB_MASK;
- mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV54_HI, val);
-
- val |= tegra_mc_read_32(MC_SECURITY_CFG0_0) & MC_SECURITY_BOM_MASK;
- mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV55_LO, val);
-
- val = tegra_mc_read_32(MC_SECURITY_CFG3_0) & MC_SECURITY_BOM_HI_MASK;
- mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV55_HI, val);
-
/*
- * MCE propagates the security configuration values across the
- * CCPLEX.
+ * Perform platform specific steps.
*/
- mce_update_gsc_tzdram();
+ plat_memctrl_tzdram_setup(phys_base, size_in_bytes);
}
/*
@@ -501,13 +179,22 @@
* Reset the access configuration registers to restrict access
* to the TZRAM aperture
*/
- for (index = MC_TZRAM_CLIENT_ACCESS_CFG0;
+ for (index = MC_TZRAM_CLIENT_ACCESS0_CFG0;
index < ((uint32_t)MC_TZRAM_CARVEOUT_CFG + (uint32_t)MC_GSC_CONFIG_REGS_SIZE);
index += 4U) {
tegra_mc_write_32(index, 0);
}
/*
+ * Enable CPU access configuration registers to access the TZRAM aperture
+ */
+ if (!tegra_chipid_is_t186()) {
+ val = tegra_mc_read_32(MC_TZRAM_CLIENT_ACCESS1_CFG0);
+ val |= TZRAM_ALLOW_MPCORER | TZRAM_ALLOW_MPCOREW;
+ tegra_mc_write_32(MC_TZRAM_CLIENT_ACCESS1_CFG0, val);
+ }
+
+ /*
* Set the TZRAM base. TZRAM base must be 4k aligned, at least.
*/
assert((phys_base & (uint64_t)0xFFF) == 0U);
@@ -534,6 +221,9 @@
val = tegra_mc_read_32(MC_TZRAM_CARVEOUT_CFG);
val &= (uint32_t)~MC_GSC_ENABLE_TZ_LOCK_BIT;
val |= MC_GSC_LOCK_CFG_SETTINGS_BIT;
+ if (!tegra_chipid_is_t186()) {
+ val |= MC_GSC_ENABLE_CPU_SECURE_BIT;
+ }
tegra_mc_write_32(MC_TZRAM_CARVEOUT_CFG, val);
/*
diff --git a/plat/nvidia/tegra/common/drivers/smmu/smmu.c b/plat/nvidia/tegra/common/drivers/smmu/smmu.c
index 789f11c..8c1b899 100644
--- a/plat/nvidia/tegra/common/drivers/smmu/smmu.c
+++ b/plat/nvidia/tegra/common/drivers/smmu/smmu.c
@@ -101,12 +101,13 @@
* the last entry. Sanity check the table size before we start with
* the context save operation.
*/
- while (smmu_ctx_regs[num_entries].val != 0xFFFFFFFFU) {
+ while ((smmu_ctx_regs[num_entries].reg != 0xFFFFFFFFU)) {
num_entries++;
}
/* panic if the sizes do not match */
if (num_entries != smmu_ctx_regs[0].val) {
+ ERROR("SMMU context size mismatch!");
panic();
}
@@ -123,9 +124,9 @@
(sizeof(smmu_regs_t) * num_entries));
/* save the SMMU table address */
- mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV11_LO,
+ mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SMMU_TABLE_ADDR_LO,
(uint32_t)smmu_ctx_addr);
- mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV11_HI,
+ mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SMMU_TABLE_ADDR_HI,
(uint32_t)(smmu_ctx_addr >> 32));
}
diff --git a/plat/nvidia/tegra/common/drivers/spe/shared_console.S b/plat/nvidia/tegra/common/drivers/spe/shared_console.S
new file mode 100644
index 0000000..a9f0334
--- /dev/null
+++ b/plat/nvidia/tegra/common/drivers/spe/shared_console.S
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <asm_macros.S>
+
+#define CONSOLE_NUM_BYTES_SHIFT 24
+#define CONSOLE_FLUSH_DATA_TO_PORT (1 << 26)
+#define CONSOLE_RING_DOORBELL (1 << 31)
+#define CONSOLE_IS_BUSY (1 << 31)
+#define CONSOLE_WRITE (CONSOLE_RING_DOORBELL | CONSOLE_FLUSH_DATA_TO_PORT)
+
+ /*
+ * This file contains a driver implementation to make use of the
+ * real console implementation provided by the SPE firmware running
+ * SoCs after Tegra186.
+ *
+ * This console is shared by multiple components and the SPE firmware
+ * finally displays everything on the UART port.
+ */
+
+ .globl console_core_init
+ .globl console_core_putc
+ .globl console_core_getc
+ .globl console_core_flush
+
+ /* -----------------------------------------------
+ * int console_core_init(uintptr_t base_addr,
+ * unsigned int uart_clk, unsigned int baud_rate)
+ * Function to initialize the console without a
+ * C Runtime to print debug information. This
+ * function will be accessed by console_init and
+ * crash reporting.
+ * In: x0 - console base address
+ * w1 - Uart clock in Hz
+ * w2 - Baud rate
+ * Out: return 1 on success else 0 on error
+ * Clobber list : x1, x2
+ * -----------------------------------------------
+ */
+func console_core_init
+ /* Check the input base address */
+ cbz x0, core_init_fail
+ mov w0, #1
+ ret
+core_init_fail:
+ mov w0, wzr
+ ret
+endfunc console_core_init
+
+ /* --------------------------------------------------------
+ * int console_core_putc(int c, uintptr_t base_addr)
+ * Function to output a character over the console. It
+ * returns the character printed on success or -1 on error.
+ * In : w0 - character to be printed
+ * x1 - console base address
+ * Out : return -1 on error else return character.
+ * Clobber list : x2
+ * --------------------------------------------------------
+ */
+func console_core_putc
+ /* Check the input parameter */
+ cbz x1, putc_error
+
+ /* wait until spe is ready */
+1: ldr w2, [x1]
+ and w2, w2, #CONSOLE_IS_BUSY
+ cbnz w2, 1b
+
+ /* spe is ready */
+ mov w2, w0
+ and w2, w2, #0xFF
+ mov w3, #(CONSOLE_WRITE | (1 << CONSOLE_NUM_BYTES_SHIFT))
+ orr w2, w2, w3
+ str w2, [x1]
+
+ ret
+putc_error:
+ mov w0, #-1
+ ret
+endfunc console_core_putc
+
+ /* ---------------------------------------------
+ * int console_core_getc(uintptr_t base_addr)
+ * Function to get a character from the console.
+ * It returns the character grabbed on success
+ * or -1 on error.
+ * In : x0 - console base address
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func console_core_getc
+ mov w0, #-1
+ ret
+endfunc console_core_getc
+
+ /* ---------------------------------------------
+ * int console_core_flush(uintptr_t base_addr)
+ * Function to force a write of all buffered
+ * data that hasn't been output.
+ * In : x0 - console base address
+ * Out : return -1 on error else return 0.
+ * Clobber list : x0, x1
+ * ---------------------------------------------
+ */
+func console_core_flush
+ cbz x0, flush_error
+
+ /* flush console */
+ mov w1, #CONSOLE_WRITE
+ str w1, [x0]
+ mov w0, #0
+ ret
+flush_error:
+ mov w0, #-1
+ ret
+endfunc console_core_flush
diff --git a/plat/nvidia/tegra/common/lib/debug/profiler.c b/plat/nvidia/tegra/common/lib/debug/profiler.c
index f40244b..d4c3f95 100644
--- a/plat/nvidia/tegra/common/lib/debug/profiler.c
+++ b/plat/nvidia/tegra/common/lib/debug/profiler.c
@@ -26,8 +26,6 @@
#include <mmio.h>
#include <profiler.h>
#include <stdbool.h>
-#include <stdio.h>
-#include <stdint.h>
#include <string.h>
#include <utils_def.h>
#include <xlat_tables_v2.h>
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index afb10fe..908e4f2 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -70,6 +70,7 @@
#pragma weak plat_early_platform_setup
#pragma weak plat_get_bl31_params
#pragma weak plat_get_bl31_plat_params
+#pragma weak plat_late_platform_setup
void plat_early_platform_setup(void)
{
@@ -86,6 +87,11 @@
return NULL;
}
+void plat_late_platform_setup(void)
+{
+ ; /* do nothing */
+}
+
/*******************************************************************************
* Return a pointer to the 'entry_point_info' structure of the next image for
* security state specified. BL33 corresponds to the non-secure image type
@@ -227,6 +233,9 @@
*/
tegra_delay_timer_init();
+ /* Early platform setup for Tegra SoCs */
+ plat_early_platform_setup();
+
/*
* Do initial security configuration to allow DRAM/device access.
*/
@@ -269,9 +278,6 @@
}
}
- /* Early platform setup for Tegra SoCs */
- plat_early_platform_setup();
-
/*
* Add timestamp for platform early setup exit.
*/
@@ -329,6 +335,13 @@
tegra_memctrl_tzram_setup(TEGRA_TZRAM_BASE, TEGRA_TZRAM_SIZE);
/*
+ * Late setup handler to allow platforms to performs additional
+ * functionality.
+ * This handler gets called with MMU enabled.
+ */
+ plat_late_platform_setup();
+
+ /*
* Add timestamp for platform setup exit.
*/
boot_profiler_add_record("[TF] plat setup exit");
diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk
index 9428f43..d9eec4d 100644
--- a/plat/nvidia/tegra/common/tegra_common.mk
+++ b/plat/nvidia/tegra/common/tegra_common.mk
@@ -22,7 +22,6 @@
BL31_SOURCES += drivers/console/aarch64/console.S \
drivers/delay_timer/delay_timer.c \
- drivers/ti/uart/aarch64/16550_console.S \
${TEGRA_GICv2_SOURCES} \
${COMMON_DIR}/aarch64/tegra_helpers.S \
${COMMON_DIR}/drivers/pmc/pmc.c \
diff --git a/plat/nvidia/tegra/include/drivers/bpmp_ipc.h b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h
new file mode 100644
index 0000000..9304150
--- /dev/null
+++ b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __BPMP_IPC_H__
+#define __BPMP_IPC_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <utils_def.h>
+
+/**
+ * Currently supported reset identifiers
+ */
+#define TEGRA_RESET_ID_XUSB_PADCTL U(114)
+#define TEGRA_RESET_ID_GPCDMA U(70)
+
+/**
+ * Function to initialise the IPC with the bpmp
+ */
+int32_t tegra_bpmp_ipc_init(void);
+
+/**
+ * Handler to reset a module
+ */
+int32_t tegra_bpmp_ipc_reset_module(uint32_t rst_id);
+
+#endif /* __BPMP_IPC_H__ */
diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
index 7eb2952..f5b0ed4 100644
--- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h
+++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h
@@ -11,185 +11,10 @@
#ifndef __ASSEMBLY__
+#include <mmio.h>
#include <stdint.h>
/*******************************************************************************
- * StreamID to indicate no SMMU translations (requests to be steered on the
- * SMMU bypass path)
- ******************************************************************************/
-#define MC_STREAM_ID_MAX 0x7FU
-
-/*******************************************************************************
- * Stream ID Override Config registers
- ******************************************************************************/
-#define MC_STREAMID_OVERRIDE_CFG_PTCR 0x000U
-#define MC_STREAMID_OVERRIDE_CFG_AFIR 0x070U
-#define MC_STREAMID_OVERRIDE_CFG_HDAR 0x0A8U
-#define MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR 0x0B0U
-#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD 0x0E0U
-#define MC_STREAMID_OVERRIDE_CFG_SATAR 0x0F8U
-#define MC_STREAMID_OVERRIDE_CFG_MPCORER 0x138U
-#define MC_STREAMID_OVERRIDE_CFG_NVENCSWR 0x158U
-#define MC_STREAMID_OVERRIDE_CFG_AFIW 0x188U
-#define MC_STREAMID_OVERRIDE_CFG_HDAW 0x1A8U
-#define MC_STREAMID_OVERRIDE_CFG_MPCOREW 0x1C8U
-#define MC_STREAMID_OVERRIDE_CFG_SATAW 0x1E8U
-#define MC_STREAMID_OVERRIDE_CFG_ISPRA 0x220U
-#define MC_STREAMID_OVERRIDE_CFG_ISPWA 0x230U
-#define MC_STREAMID_OVERRIDE_CFG_ISPWB 0x238U
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR 0x250U
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW 0x258U
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR 0x260U
-#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW 0x268U
-#define MC_STREAMID_OVERRIDE_CFG_TSECSRD 0x2A0U
-#define MC_STREAMID_OVERRIDE_CFG_TSECSWR 0x2A8U
-#define MC_STREAMID_OVERRIDE_CFG_GPUSRD 0x2C0U
-#define MC_STREAMID_OVERRIDE_CFG_GPUSWR 0x2C8U
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCRA 0x300U
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAA 0x308U
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCR 0x310U
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAB 0x318U
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCWA 0x320U
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAA 0x328U
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCW 0x330U
-#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAB 0x338U
-#define MC_STREAMID_OVERRIDE_CFG_VICSRD 0x360U
-#define MC_STREAMID_OVERRIDE_CFG_VICSWR 0x368U
-#define MC_STREAMID_OVERRIDE_CFG_VIW 0x390U
-#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD 0x3C0U
-#define MC_STREAMID_OVERRIDE_CFG_NVDECSWR 0x3C8U
-#define MC_STREAMID_OVERRIDE_CFG_APER 0x3D0U
-#define MC_STREAMID_OVERRIDE_CFG_APEW 0x3D8U
-#define MC_STREAMID_OVERRIDE_CFG_NVJPGSRD 0x3F0U
-#define MC_STREAMID_OVERRIDE_CFG_NVJPGSWR 0x3F8U
-#define MC_STREAMID_OVERRIDE_CFG_SESRD 0x400U
-#define MC_STREAMID_OVERRIDE_CFG_SESWR 0x408U
-#define MC_STREAMID_OVERRIDE_CFG_ETRR 0x420U
-#define MC_STREAMID_OVERRIDE_CFG_ETRW 0x428U
-#define MC_STREAMID_OVERRIDE_CFG_TSECSRDB 0x430U
-#define MC_STREAMID_OVERRIDE_CFG_TSECSWRB 0x438U
-#define MC_STREAMID_OVERRIDE_CFG_GPUSRD2 0x440U
-#define MC_STREAMID_OVERRIDE_CFG_GPUSWR2 0x448U
-#define MC_STREAMID_OVERRIDE_CFG_AXISR 0x460U
-#define MC_STREAMID_OVERRIDE_CFG_AXISW 0x468U
-#define MC_STREAMID_OVERRIDE_CFG_EQOSR 0x470U
-#define MC_STREAMID_OVERRIDE_CFG_EQOSW 0x478U
-#define MC_STREAMID_OVERRIDE_CFG_UFSHCR 0x480U
-#define MC_STREAMID_OVERRIDE_CFG_UFSHCW 0x488U
-#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR 0x490U
-#define MC_STREAMID_OVERRIDE_CFG_BPMPR 0x498U
-#define MC_STREAMID_OVERRIDE_CFG_BPMPW 0x4A0U
-#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAR 0x4A8U
-#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAW 0x4B0U
-#define MC_STREAMID_OVERRIDE_CFG_AONR 0x4B8U
-#define MC_STREAMID_OVERRIDE_CFG_AONW 0x4C0U
-#define MC_STREAMID_OVERRIDE_CFG_AONDMAR 0x4C8U
-#define MC_STREAMID_OVERRIDE_CFG_AONDMAW 0x4D0U
-#define MC_STREAMID_OVERRIDE_CFG_SCER 0x4D8U
-#define MC_STREAMID_OVERRIDE_CFG_SCEW 0x4E0U
-#define MC_STREAMID_OVERRIDE_CFG_SCEDMAR 0x4E8U
-#define MC_STREAMID_OVERRIDE_CFG_SCEDMAW 0x4F0U
-#define MC_STREAMID_OVERRIDE_CFG_APEDMAR 0x4F8U
-#define MC_STREAMID_OVERRIDE_CFG_APEDMAW 0x500U
-#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1 0x508U
-#define MC_STREAMID_OVERRIDE_CFG_VICSRD1 0x510U
-#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD1 0x518U
-
-/*******************************************************************************
- * Macro to calculate Security cfg register addr from StreamID Override register
- ******************************************************************************/
-#define MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(addr) ((addr) + (uint32_t)sizeof(uint32_t))
-
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_SO_DEV (0U << 4)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_SO_DEV (1U << 4)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SO_DEV (2U << 4)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_SO_DEV (3U << 4)
-
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_NORMAL (0U << 8)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_NORMAL (1U << 8)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_NORMAL (2U << 8)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_NORMAL (3U << 8)
-
-#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_ZERO (0U << 12)
-#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_CLIENT_AXI_ID (1U << 12)
-
-/*******************************************************************************
- * Memory Controller transaction override config registers
- ******************************************************************************/
-#define MC_TXN_OVERRIDE_CONFIG_HDAR 0x10a8U
-#define MC_TXN_OVERRIDE_CONFIG_BPMPW 0x14a0U
-#define MC_TXN_OVERRIDE_CONFIG_PTCR 0x1000U
-#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR 0x1490U
-#define MC_TXN_OVERRIDE_CONFIG_EQOSW 0x1478U
-#define MC_TXN_OVERRIDE_CONFIG_NVJPGSWR 0x13f8U
-#define MC_TXN_OVERRIDE_CONFIG_ISPRA 0x1220U
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAA 0x1328U
-#define MC_TXN_OVERRIDE_CONFIG_VICSRD 0x1360U
-#define MC_TXN_OVERRIDE_CONFIG_MPCOREW 0x11c8U
-#define MC_TXN_OVERRIDE_CONFIG_GPUSRD 0x12c0U
-#define MC_TXN_OVERRIDE_CONFIG_AXISR 0x1460U
-#define MC_TXN_OVERRIDE_CONFIG_SCEDMAW 0x14f0U
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCW 0x1330U
-#define MC_TXN_OVERRIDE_CONFIG_EQOSR 0x1470U
-#define MC_TXN_OVERRIDE_CONFIG_APEDMAR 0x14f8U
-#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD 0x10e0U
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAB 0x1318U
-#define MC_TXN_OVERRIDE_CONFIG_VICSRD1 0x1510U
-#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAR 0x14a8U
-#define MC_TXN_OVERRIDE_CONFIG_VIW 0x1390U
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAA 0x1308U
-#define MC_TXN_OVERRIDE_CONFIG_AXISW 0x1468U
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVR 0x1260U
-#define MC_TXN_OVERRIDE_CONFIG_UFSHCR 0x1480U
-#define MC_TXN_OVERRIDE_CONFIG_TSECSWR 0x12a8U
-#define MC_TXN_OVERRIDE_CONFIG_GPUSWR 0x12c8U
-#define MC_TXN_OVERRIDE_CONFIG_SATAR 0x10f8U
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTW 0x1258U
-#define MC_TXN_OVERRIDE_CONFIG_TSECSWRB 0x1438U
-#define MC_TXN_OVERRIDE_CONFIG_GPUSRD2 0x1440U
-#define MC_TXN_OVERRIDE_CONFIG_SCEDMAR 0x14e8U
-#define MC_TXN_OVERRIDE_CONFIG_GPUSWR2 0x1448U
-#define MC_TXN_OVERRIDE_CONFIG_AONDMAW 0x14d0U
-#define MC_TXN_OVERRIDE_CONFIG_APEDMAW 0x1500U
-#define MC_TXN_OVERRIDE_CONFIG_AONW 0x14c0U
-#define MC_TXN_OVERRIDE_CONFIG_HOST1XDMAR 0x10b0U
-#define MC_TXN_OVERRIDE_CONFIG_ETRR 0x1420U
-#define MC_TXN_OVERRIDE_CONFIG_SESWR 0x1408U
-#define MC_TXN_OVERRIDE_CONFIG_NVJPGSRD 0x13f0U
-#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD 0x13c0U
-#define MC_TXN_OVERRIDE_CONFIG_TSECSRDB 0x1430U
-#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAW 0x14b0U
-#define MC_TXN_OVERRIDE_CONFIG_APER 0x13d0U
-#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD1 0x1518U
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTR 0x1250U
-#define MC_TXN_OVERRIDE_CONFIG_ISPWA 0x1230U
-#define MC_TXN_OVERRIDE_CONFIG_SESRD 0x1400U
-#define MC_TXN_OVERRIDE_CONFIG_SCER 0x14d8U
-#define MC_TXN_OVERRIDE_CONFIG_AONR 0x14b8U
-#define MC_TXN_OVERRIDE_CONFIG_MPCORER 0x1138U
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCWA 0x1320U
-#define MC_TXN_OVERRIDE_CONFIG_HDAW 0x11a8U
-#define MC_TXN_OVERRIDE_CONFIG_NVDECSWR 0x13c8U
-#define MC_TXN_OVERRIDE_CONFIG_UFSHCW 0x1488U
-#define MC_TXN_OVERRIDE_CONFIG_AONDMAR 0x14c8U
-#define MC_TXN_OVERRIDE_CONFIG_SATAW 0x11e8U
-#define MC_TXN_OVERRIDE_CONFIG_ETRW 0x1428U
-#define MC_TXN_OVERRIDE_CONFIG_VICSWR 0x1368U
-#define MC_TXN_OVERRIDE_CONFIG_NVENCSWR 0x1158U
-#define MC_TXN_OVERRIDE_CONFIG_AFIR 0x1070U
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAB 0x1338U
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCRA 0x1300U
-#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR1 0x1508U
-#define MC_TXN_OVERRIDE_CONFIG_ISPWB 0x1238U
-#define MC_TXN_OVERRIDE_CONFIG_BPMPR 0x1498U
-#define MC_TXN_OVERRIDE_CONFIG_APEW 0x13d8U
-#define MC_TXN_OVERRIDE_CONFIG_SDMMCR 0x1310U
-#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVW 0x1268U
-#define MC_TXN_OVERRIDE_CONFIG_TSECSRD 0x12a0U
-#define MC_TXN_OVERRIDE_CONFIG_AFIW 0x1188U
-#define MC_TXN_OVERRIDE_CONFIG_SCEW 0x14e0U
-
-/*******************************************************************************
* Structure to hold the transaction override settings to use to override
* client inputs
******************************************************************************/
@@ -229,6 +54,25 @@
#define CLIENT_FLAG_NON_SECURE 1U
#define CLIENT_INPUTS_OVERRIDE 1U
#define CLIENT_INPUTS_NO_OVERRIDE 0U
+/*******************************************************************************
+ * StreamID to indicate no SMMU translations (requests to be steered on the
+ * SMMU bypass path)
+ ******************************************************************************/
+#define MC_STREAM_ID_MAX 0x7FU
+
+/*******************************************************************************
+ * Memory Controller SMMU Bypass config register
+ ******************************************************************************/
+#define MC_SMMU_BYPASS_CONFIG 0x1820U
+#define MC_SMMU_BYPASS_CTRL_MASK 0x3U
+#define MC_SMMU_BYPASS_CTRL_SHIFT 0U
+#define MC_SMMU_CTRL_TBU_BYPASS_ALL (0U << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_CTRL_TBU_RSVD (1U << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID (2U << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_CTRL_TBU_BYPASS_NONE (3U << MC_SMMU_BYPASS_CTRL_SHIFT)
+#define MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT (1U << 31)
+#define MC_SMMU_BYPASS_CONFIG_SETTINGS (MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT | \
+ MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID)
#define mc_make_sec_cfg(off, ns, ovrrd, access) \
{ \
@@ -250,131 +94,10 @@
uint32_t num_streamid_security_cfgs;
const mc_txn_override_cfg_t *txn_override_cfg;
uint32_t num_txn_override_cfgs;
+ void (*reconfig_mss_clients)(void);
+ void (*set_txn_overrides)(void);
} tegra_mc_settings_t;
-#endif /* __ASSEMBLY__ */
-
-/*******************************************************************************
- * Memory Controller SMMU Bypass config register
- ******************************************************************************/
-#define MC_SMMU_BYPASS_CONFIG 0x1820U
-#define MC_SMMU_BYPASS_CTRL_MASK 0x3U
-#define MC_SMMU_BYPASS_CTRL_SHIFT 0U
-#define MC_SMMU_CTRL_TBU_BYPASS_ALL (0U << MC_SMMU_BYPASS_CTRL_SHIFT)
-#define MC_SMMU_CTRL_TBU_RSVD (1U << MC_SMMU_BYPASS_CTRL_SHIFT)
-#define MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID (2U << MC_SMMU_BYPASS_CTRL_SHIFT)
-#define MC_SMMU_CTRL_TBU_BYPASS_NONE (3U << MC_SMMU_BYPASS_CTRL_SHIFT)
-#define MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT (1U << 31)
-#define MC_SMMU_BYPASS_CONFIG_SETTINGS (MC_SMMU_BYPASS_CONFIG_WRITE_ACCESS_BIT | \
- MC_SMMU_CTRL_TBU_BYPASS_SPL_STREAMID)
-
-#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID (1U << 0)
-#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV (2U << 4)
-#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT (1U << 12)
-
-/*******************************************************************************
- * Non-SO_DEV transactions override values for CGID_TAG bitfield for the
- * MC_TXN_OVERRIDE_CONFIG_{module} registers
- ******************************************************************************/
-#define MC_TXN_OVERRIDE_CGID_TAG_DEFAULT 0U
-#define MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID 1U
-#define MC_TXN_OVERRIDE_CGID_TAG_ZERO 2U
-#define MC_TXN_OVERRIDE_CGID_TAG_ADR 3U
-#define MC_TXN_OVERRIDE_CGID_TAG_MASK 3U
-
-/*******************************************************************************
- * Memory Controller Reset Control registers
- ******************************************************************************/
-#define MC_CLIENT_HOTRESET_CTRL0 0x200U
-#define MC_CLIENT_HOTRESET_CTRL0_RESET_VAL 0U
-#define MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB (1U << 0)
-#define MC_CLIENT_HOTRESET_CTRL0_HC_FLUSH_ENB (1U << 6)
-#define MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB (1U << 7)
-#define MC_CLIENT_HOTRESET_CTRL0_ISP2_FLUSH_ENB (1U << 8)
-#define MC_CLIENT_HOTRESET_CTRL0_MPCORE_FLUSH_ENB (1U << 9)
-#define MC_CLIENT_HOTRESET_CTRL0_NVENC_FLUSH_ENB (1U << 11)
-#define MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB (1U << 15)
-#define MC_CLIENT_HOTRESET_CTRL0_VI_FLUSH_ENB (1U << 17)
-#define MC_CLIENT_HOTRESET_CTRL0_VIC_FLUSH_ENB (1U << 18)
-#define MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB (1U << 19)
-#define MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB (1U << 20)
-#define MC_CLIENT_HOTRESET_CTRL0_TSEC_FLUSH_ENB (1U << 22)
-#define MC_CLIENT_HOTRESET_CTRL0_SDMMC1A_FLUSH_ENB (1U << 29)
-#define MC_CLIENT_HOTRESET_CTRL0_SDMMC2A_FLUSH_ENB (1U << 30)
-#define MC_CLIENT_HOTRESET_CTRL0_SDMMC3A_FLUSH_ENB (1U << 31)
-#define MC_CLIENT_HOTRESET_STATUS0 0x204U
-#define MC_CLIENT_HOTRESET_CTRL1 0x970U
-#define MC_CLIENT_HOTRESET_CTRL1_RESET_VAL 0U
-#define MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB (1U << 0)
-#define MC_CLIENT_HOTRESET_CTRL1_GPU_FLUSH_ENB (1U << 2)
-#define MC_CLIENT_HOTRESET_CTRL1_NVDEC_FLUSH_ENB (1U << 5)
-#define MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB (1U << 6)
-#define MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB (1U << 7)
-#define MC_CLIENT_HOTRESET_CTRL1_NVJPG_FLUSH_ENB (1U << 8)
-#define MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB (1U << 12)
-#define MC_CLIENT_HOTRESET_CTRL1_TSECB_FLUSH_ENB (1U << 13)
-#define MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB (1U << 18)
-#define MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB (1U << 19)
-#define MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB (1U << 20)
-#define MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB (1U << 21)
-#define MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB (1U << 22)
-#define MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB (1U << 23)
-#define MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB (1U << 24)
-#define MC_CLIENT_HOTRESET_STATUS1 0x974U
-
-/*******************************************************************************
- * Memory Controller's PCFIFO client configuration registers
- ******************************************************************************/
-#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4UL
-#define MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL 0x20000UL
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_UNORDERED (0UL << 17)
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_MASK (1UL << 17)
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_UNORDERED (0UL << 21)
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_MASK (1UL << 21)
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_UNORDERED (0UL << 29)
-#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_MASK (1UL << 29)
-
-#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8UL
-#define MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL 0x20000UL
-#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_UNORDERED (0UL << 11)
-#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_MASK (1UL << 11)
-#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_UNORDERED (0UL << 13)
-#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_MASK (1UL << 13)
-
-#define MC_PCFIFO_CLIENT_CONFIG3 0xddcUL
-#define MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL 0UL
-#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_UNORDERED (0UL << 7)
-#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_MASK (1UL << 7)
-
-#define MC_PCFIFO_CLIENT_CONFIG4 0xde0UL
-#define MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL 0UL
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_UNORDERED (0UL << 1)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_MASK (1UL << 1)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_UNORDERED (0UL << 5)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_MASK (1UL << 5)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_UNORDERED (0UL << 13)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_MASK (1UL << 13)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_UNORDERED (0UL << 15)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_ORDERED (1UL << 15)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_MASK (1UL << 15)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_UNORDERED (0UL << 17)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_MASK (1UL << 17)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_UNORDERED (0UL << 22)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_MASK (1UL << 22)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_UNORDERED (0UL << 26)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_MASK (1UL << 26)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_UNORDERED (0UL << 30)
-#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_MASK (1UL << 30)
-
-#define MC_PCFIFO_CLIENT_CONFIG5 0xbf4UL
-#define MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL 0UL
-#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_UNORDERED (0UL << 0)
-#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_MASK (1UL << 0)
-
-#ifndef __ASSEMBLY__
-
-#include <lib/mmio.h>
-
static inline uint32_t tegra_mc_read_32(uint32_t off)
{
return mmio_read_32(TEGRA_MC_BASE + off);
@@ -410,6 +133,22 @@
(uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
}
+#define mc_set_tsa_w_passthrough(client) \
+ { \
+ mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \
+ (TSA_CONFIG_STATIC0_CSW_RESET_W & \
+ (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
+ (uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
+ }
+
+#define mc_set_tsa_r_passthrough(client) \
+ { \
+ mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSR_##client, \
+ (TSA_CONFIG_STATIC0_CSR_RESET_R & \
+ (uint32_t)~TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK) | \
+ (uint32_t)TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU); \
+ }
+
#define mc_set_txn_override(client, normal_axi_id, so_dev_axi_id, normal_override, so_dev_override) \
{ \
tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_##client, \
@@ -426,6 +165,14 @@
******************************************************************************/
tegra_mc_settings_t *tegra_get_mc_settings(void);
+/*******************************************************************************
+ * Handler to program the scratch registers with TZDRAM settings for the
+ * resume firmware.
+ *
+ * Implemented by SoCs under tegra/soc/txxx
+ ******************************************************************************/
+void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes);
+
-#endif /* __ASSMEBLY__ */
+#endif /* __ASSEMBLY__ */
#endif /* MEMCTRL_V2_H */
diff --git a/plat/nvidia/tegra/include/t186/tegra186_private.h b/plat/nvidia/tegra/include/t186/tegra186_private.h
new file mode 100644
index 0000000..9e2c02b
--- /dev/null
+++ b/plat/nvidia/tegra/include/t186/tegra186_private.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TEGRA186_PRIVATE_H
+#define TEGRA186_PRIVATE_H
+
+void tegra186_cpu_reset_handler(void);
+uint64_t tegra186_get_cpu_reset_handler_base(void);
+uint64_t tegra186_get_cpu_reset_handler_size(void);
+uint64_t tegra186_get_smmu_ctx_offset(void);
+void tegra186_set_system_suspend_entry(void);
+
+#endif /* TEGRA186_PRIVATE_H */
diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h
index 20a7994..231f93a 100644
--- a/plat/nvidia/tegra/include/t186/tegra_def.h
+++ b/plat/nvidia/tegra/include/t186/tegra_def.h
@@ -135,6 +135,7 @@
#define MC_GSC_BASE_LO_MASK U(0xFFFFF)
#define MC_GSC_BASE_HI_SHIFT U(0)
#define MC_GSC_BASE_HI_MASK U(3)
+#define MC_GSC_ENABLE_CPU_SECURE_BIT (U(1) << 31)
/* TZDRAM carveout configuration registers */
#define MC_SECURITY_CFG0_0 U(0x70)
@@ -165,7 +166,10 @@
#define MC_TZRAM_BASE_LO U(0x2194)
#define MC_TZRAM_BASE_HI U(0x2198)
#define MC_TZRAM_SIZE U(0x219C)
-#define MC_TZRAM_CLIENT_ACCESS_CFG0 U(0x21A0)
+#define MC_TZRAM_CLIENT_ACCESS0_CFG0 U(0x21A0)
+#define MC_TZRAM_CLIENT_ACCESS1_CFG0 U(0x21A4)
+#define TZRAM_ALLOW_MPCORER (U(1) << 7)
+#define TZRAM_ALLOW_MPCOREW (U(1) << 25)
/*******************************************************************************
* Tegra UART Controller constants
@@ -232,10 +236,19 @@
#define SECURE_SCRATCH_RSV11_HI U(0x6AC)
#define SECURE_SCRATCH_RSV53_LO U(0x7F8)
#define SECURE_SCRATCH_RSV53_HI U(0x7FC)
-#define SECURE_SCRATCH_RSV54_HI U(0x804)
#define SECURE_SCRATCH_RSV55_LO U(0x808)
#define SECURE_SCRATCH_RSV55_HI U(0x80C)
+#define SCRATCH_RESET_VECTOR_LO SECURE_SCRATCH_RSV1_LO
+#define SCRATCH_RESET_VECTOR_HI SECURE_SCRATCH_RSV1_HI
+#define SCRATCH_SECURE_BOOTP_FCFG SECURE_SCRATCH_RSV6
+#define SCRATCH_SMMU_TABLE_ADDR_LO SECURE_SCRATCH_RSV11_LO
+#define SCRATCH_SMMU_TABLE_ADDR_HI SECURE_SCRATCH_RSV11_HI
+#define SCRATCH_BL31_PARAMS_ADDR SECURE_SCRATCH_RSV53_LO
+#define SCRATCH_BL31_PLAT_PARAMS_ADDR SECURE_SCRATCH_RSV53_HI
+#define SCRATCH_TZDRAM_ADDR_LO SECURE_SCRATCH_RSV55_LO
+#define SCRATCH_TZDRAM_ADDR_HI SECURE_SCRATCH_RSV55_HI
+
/*******************************************************************************
* Tegra Memory Mapped Control Register Access constants
******************************************************************************/
diff --git a/plat/nvidia/tegra/include/t186/tegra_mc_def.h b/plat/nvidia/tegra/include/t186/tegra_mc_def.h
new file mode 100644
index 0000000..d051a15
--- /dev/null
+++ b/plat/nvidia/tegra/include/t186/tegra_mc_def.h
@@ -0,0 +1,285 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TEGRA_MC_DEF_H
+#define TEGRA_MC_DEF_H
+
+/*******************************************************************************
+ * Memory Controller's PCFIFO client configuration registers
+ ******************************************************************************/
+#define MC_PCFIFO_CLIENT_CONFIG0 0xdd0U
+
+#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4U
+#define MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL 0x20000U
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_UNORDERED (0U << 17)
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_MASK (1U << 17)
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_UNORDERED (0U << 21)
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_MASK (1U << 21)
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_UNORDERED (0U << 29)
+#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_MASK (1U << 29)
+
+#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8U
+#define MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL 0x20000U
+#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_UNORDERED (0U << 11)
+#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_MASK (1U << 11)
+#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_UNORDERED (0U << 13)
+#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_MASK (1U << 13)
+
+#define MC_PCFIFO_CLIENT_CONFIG3 0xddcU
+#define MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL 0U
+#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_UNORDERED (0U << 7)
+#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_MASK (1U << 7)
+
+#define MC_PCFIFO_CLIENT_CONFIG4 0xde0U
+#define MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL 0U
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_UNORDERED (0U << 1)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_MASK (1U << 1)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_UNORDERED (0U << 5)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_MASK (1U << 5)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_UNORDERED (0U << 13)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_MASK (1U << 13)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_UNORDERED (0U << 15)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_ORDERED (1U << 15)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_MASK (1U << 15)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_UNORDERED (0U << 17)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_MASK (1U << 17)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_UNORDERED (0U << 22)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_MASK (1U << 22)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_UNORDERED (0U << 26)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_MASK (1U << 26)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_UNORDERED (0U << 30)
+#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_MASK (1U << 30)
+
+#define MC_PCFIFO_CLIENT_CONFIG5 0xbf4U
+#define MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL 0U
+#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_UNORDERED (0U << 0)
+#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_MASK (1U << 0)
+
+/*******************************************************************************
+ * Stream ID Override Config registers
+ ******************************************************************************/
+#define MC_STREAMID_OVERRIDE_CFG_PTCR 0x000U
+#define MC_STREAMID_OVERRIDE_CFG_AFIR 0x070U
+#define MC_STREAMID_OVERRIDE_CFG_HDAR 0x0A8U
+#define MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR 0x0B0U
+#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD 0x0E0U
+#define MC_STREAMID_OVERRIDE_CFG_SATAR 0x0F8U
+#define MC_STREAMID_OVERRIDE_CFG_MPCORER 0x138U
+#define MC_STREAMID_OVERRIDE_CFG_NVENCSWR 0x158U
+#define MC_STREAMID_OVERRIDE_CFG_AFIW 0x188U
+#define MC_STREAMID_OVERRIDE_CFG_HDAW 0x1A8U
+#define MC_STREAMID_OVERRIDE_CFG_MPCOREW 0x1C8U
+#define MC_STREAMID_OVERRIDE_CFG_SATAW 0x1E8U
+#define MC_STREAMID_OVERRIDE_CFG_ISPRA 0x220U
+#define MC_STREAMID_OVERRIDE_CFG_ISPWA 0x230U
+#define MC_STREAMID_OVERRIDE_CFG_ISPWB 0x238U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR 0x250U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW 0x258U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR 0x260U
+#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW 0x268U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSRD 0x2A0U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSWR 0x2A8U
+#define MC_STREAMID_OVERRIDE_CFG_GPUSRD 0x2C0U
+#define MC_STREAMID_OVERRIDE_CFG_GPUSWR 0x2C8U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCRA 0x300U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAA 0x308U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCR 0x310U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAB 0x318U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCWA 0x320U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAA 0x328U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCW 0x330U
+#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAB 0x338U
+#define MC_STREAMID_OVERRIDE_CFG_VICSRD 0x360U
+#define MC_STREAMID_OVERRIDE_CFG_VICSWR 0x368U
+#define MC_STREAMID_OVERRIDE_CFG_VIW 0x390U
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD 0x3C0U
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSWR 0x3C8U
+#define MC_STREAMID_OVERRIDE_CFG_APER 0x3D0U
+#define MC_STREAMID_OVERRIDE_CFG_APEW 0x3D8U
+#define MC_STREAMID_OVERRIDE_CFG_NVJPGSRD 0x3F0U
+#define MC_STREAMID_OVERRIDE_CFG_NVJPGSWR 0x3F8U
+#define MC_STREAMID_OVERRIDE_CFG_SESRD 0x400U
+#define MC_STREAMID_OVERRIDE_CFG_SESWR 0x408U
+#define MC_STREAMID_OVERRIDE_CFG_ETRR 0x420U
+#define MC_STREAMID_OVERRIDE_CFG_ETRW 0x428U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSRDB 0x430U
+#define MC_STREAMID_OVERRIDE_CFG_TSECSWRB 0x438U
+#define MC_STREAMID_OVERRIDE_CFG_GPUSRD2 0x440U
+#define MC_STREAMID_OVERRIDE_CFG_GPUSWR2 0x448U
+#define MC_STREAMID_OVERRIDE_CFG_AXISR 0x460U
+#define MC_STREAMID_OVERRIDE_CFG_AXISW 0x468U
+#define MC_STREAMID_OVERRIDE_CFG_EQOSR 0x470U
+#define MC_STREAMID_OVERRIDE_CFG_EQOSW 0x478U
+#define MC_STREAMID_OVERRIDE_CFG_UFSHCR 0x480U
+#define MC_STREAMID_OVERRIDE_CFG_UFSHCW 0x488U
+#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR 0x490U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPR 0x498U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPW 0x4A0U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAR 0x4A8U
+#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAW 0x4B0U
+#define MC_STREAMID_OVERRIDE_CFG_AONR 0x4B8U
+#define MC_STREAMID_OVERRIDE_CFG_AONW 0x4C0U
+#define MC_STREAMID_OVERRIDE_CFG_AONDMAR 0x4C8U
+#define MC_STREAMID_OVERRIDE_CFG_AONDMAW 0x4D0U
+#define MC_STREAMID_OVERRIDE_CFG_SCER 0x4D8U
+#define MC_STREAMID_OVERRIDE_CFG_SCEW 0x4E0U
+#define MC_STREAMID_OVERRIDE_CFG_SCEDMAR 0x4E8U
+#define MC_STREAMID_OVERRIDE_CFG_SCEDMAW 0x4F0U
+#define MC_STREAMID_OVERRIDE_CFG_APEDMAR 0x4F8U
+#define MC_STREAMID_OVERRIDE_CFG_APEDMAW 0x500U
+#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1 0x508U
+#define MC_STREAMID_OVERRIDE_CFG_VICSRD1 0x510U
+#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD1 0x518U
+
+/*******************************************************************************
+ * Macro to calculate Security cfg register addr from StreamID Override register
+ ******************************************************************************/
+#define MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(addr) ((addr) + (uint32_t)sizeof(uint32_t))
+
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_SO_DEV (0U << 4)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_SO_DEV (1U << 4)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SO_DEV (2U << 4)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_SO_DEV (3U << 4)
+
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_NORMAL (0U << 8)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_NORMAL (1U << 8)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_NORMAL (2U << 8)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_NORMAL (3U << 8)
+
+#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_ZERO (0U << 12)
+#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_CLIENT_AXI_ID (1U << 12)
+
+/*******************************************************************************
+ * Memory Controller transaction override config registers
+ ******************************************************************************/
+#define MC_TXN_OVERRIDE_CONFIG_HDAR 0x10a8U
+#define MC_TXN_OVERRIDE_CONFIG_BPMPW 0x14a0U
+#define MC_TXN_OVERRIDE_CONFIG_PTCR 0x1000U
+#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR 0x1490U
+#define MC_TXN_OVERRIDE_CONFIG_EQOSW 0x1478U
+#define MC_TXN_OVERRIDE_CONFIG_NVJPGSWR 0x13f8U
+#define MC_TXN_OVERRIDE_CONFIG_ISPRA 0x1220U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAA 0x1328U
+#define MC_TXN_OVERRIDE_CONFIG_VICSRD 0x1360U
+#define MC_TXN_OVERRIDE_CONFIG_MPCOREW 0x11c8U
+#define MC_TXN_OVERRIDE_CONFIG_GPUSRD 0x12c0U
+#define MC_TXN_OVERRIDE_CONFIG_AXISR 0x1460U
+#define MC_TXN_OVERRIDE_CONFIG_SCEDMAW 0x14f0U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCW 0x1330U
+#define MC_TXN_OVERRIDE_CONFIG_EQOSR 0x1470U
+#define MC_TXN_OVERRIDE_CONFIG_APEDMAR 0x14f8U
+#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD 0x10e0U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAB 0x1318U
+#define MC_TXN_OVERRIDE_CONFIG_VICSRD1 0x1510U
+#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAR 0x14a8U
+#define MC_TXN_OVERRIDE_CONFIG_VIW 0x1390U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAA 0x1308U
+#define MC_TXN_OVERRIDE_CONFIG_AXISW 0x1468U
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVR 0x1260U
+#define MC_TXN_OVERRIDE_CONFIG_UFSHCR 0x1480U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSWR 0x12a8U
+#define MC_TXN_OVERRIDE_CONFIG_GPUSWR 0x12c8U
+#define MC_TXN_OVERRIDE_CONFIG_SATAR 0x10f8U
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTW 0x1258U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSWRB 0x1438U
+#define MC_TXN_OVERRIDE_CONFIG_GPUSRD2 0x1440U
+#define MC_TXN_OVERRIDE_CONFIG_SCEDMAR 0x14e8U
+#define MC_TXN_OVERRIDE_CONFIG_GPUSWR2 0x1448U
+#define MC_TXN_OVERRIDE_CONFIG_AONDMAW 0x14d0U
+#define MC_TXN_OVERRIDE_CONFIG_APEDMAW 0x1500U
+#define MC_TXN_OVERRIDE_CONFIG_AONW 0x14c0U
+#define MC_TXN_OVERRIDE_CONFIG_HOST1XDMAR 0x10b0U
+#define MC_TXN_OVERRIDE_CONFIG_ETRR 0x1420U
+#define MC_TXN_OVERRIDE_CONFIG_SESWR 0x1408U
+#define MC_TXN_OVERRIDE_CONFIG_NVJPGSRD 0x13f0U
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD 0x13c0U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSRDB 0x1430U
+#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAW 0x14b0U
+#define MC_TXN_OVERRIDE_CONFIG_APER 0x13d0U
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD1 0x1518U
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTR 0x1250U
+#define MC_TXN_OVERRIDE_CONFIG_ISPWA 0x1230U
+#define MC_TXN_OVERRIDE_CONFIG_SESRD 0x1400U
+#define MC_TXN_OVERRIDE_CONFIG_SCER 0x14d8U
+#define MC_TXN_OVERRIDE_CONFIG_AONR 0x14b8U
+#define MC_TXN_OVERRIDE_CONFIG_MPCORER 0x1138U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCWA 0x1320U
+#define MC_TXN_OVERRIDE_CONFIG_HDAW 0x11a8U
+#define MC_TXN_OVERRIDE_CONFIG_NVDECSWR 0x13c8U
+#define MC_TXN_OVERRIDE_CONFIG_UFSHCW 0x1488U
+#define MC_TXN_OVERRIDE_CONFIG_AONDMAR 0x14c8U
+#define MC_TXN_OVERRIDE_CONFIG_SATAW 0x11e8U
+#define MC_TXN_OVERRIDE_CONFIG_ETRW 0x1428U
+#define MC_TXN_OVERRIDE_CONFIG_VICSWR 0x1368U
+#define MC_TXN_OVERRIDE_CONFIG_NVENCSWR 0x1158U
+#define MC_TXN_OVERRIDE_CONFIG_AFIR 0x1070U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAB 0x1338U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCRA 0x1300U
+#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR1 0x1508U
+#define MC_TXN_OVERRIDE_CONFIG_ISPWB 0x1238U
+#define MC_TXN_OVERRIDE_CONFIG_BPMPR 0x1498U
+#define MC_TXN_OVERRIDE_CONFIG_APEW 0x13d8U
+#define MC_TXN_OVERRIDE_CONFIG_SDMMCR 0x1310U
+#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVW 0x1268U
+#define MC_TXN_OVERRIDE_CONFIG_TSECSRD 0x12a0U
+#define MC_TXN_OVERRIDE_CONFIG_AFIW 0x1188U
+#define MC_TXN_OVERRIDE_CONFIG_SCEW 0x14e0U
+
+#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID (1U << 0)
+#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV (2U << 4)
+#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT (1U << 12)
+
+/*******************************************************************************
+ * Non-SO_DEV transactions override values for CGID_TAG bitfield for the
+ * MC_TXN_OVERRIDE_CONFIG_{module} registers
+ ******************************************************************************/
+#define MC_TXN_OVERRIDE_CGID_TAG_DEFAULT 0U
+#define MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID 1U
+#define MC_TXN_OVERRIDE_CGID_TAG_ZERO 2U
+#define MC_TXN_OVERRIDE_CGID_TAG_ADR 3U
+#define MC_TXN_OVERRIDE_CGID_TAG_MASK 3ULL
+
+/*******************************************************************************
+ * Memory Controller Reset Control registers
+ ******************************************************************************/
+#define MC_CLIENT_HOTRESET_CTRL0 0x200U
+#define MC_CLIENT_HOTRESET_CTRL0_RESET_VAL 0U
+#define MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB (1U << 0)
+#define MC_CLIENT_HOTRESET_CTRL0_HC_FLUSH_ENB (1U << 6)
+#define MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB (1U << 7)
+#define MC_CLIENT_HOTRESET_CTRL0_ISP2_FLUSH_ENB (1U << 8)
+#define MC_CLIENT_HOTRESET_CTRL0_MPCORE_FLUSH_ENB (1U << 9)
+#define MC_CLIENT_HOTRESET_CTRL0_NVENC_FLUSH_ENB (1U << 11)
+#define MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB (1U << 15)
+#define MC_CLIENT_HOTRESET_CTRL0_VI_FLUSH_ENB (1U << 17)
+#define MC_CLIENT_HOTRESET_CTRL0_VIC_FLUSH_ENB (1U << 18)
+#define MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB (1U << 19)
+#define MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB (1U << 20)
+#define MC_CLIENT_HOTRESET_CTRL0_TSEC_FLUSH_ENB (1U << 22)
+#define MC_CLIENT_HOTRESET_CTRL0_SDMMC1A_FLUSH_ENB (1U << 29)
+#define MC_CLIENT_HOTRESET_CTRL0_SDMMC2A_FLUSH_ENB (1U << 30)
+#define MC_CLIENT_HOTRESET_CTRL0_SDMMC3A_FLUSH_ENB (1U << 31)
+#define MC_CLIENT_HOTRESET_STATUS0 0x204U
+#define MC_CLIENT_HOTRESET_CTRL1 0x970U
+#define MC_CLIENT_HOTRESET_CTRL1_RESET_VAL 0U
+#define MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB (1U << 0)
+#define MC_CLIENT_HOTRESET_CTRL1_GPU_FLUSH_ENB (1U << 2)
+#define MC_CLIENT_HOTRESET_CTRL1_NVDEC_FLUSH_ENB (1U << 5)
+#define MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB (1U << 6)
+#define MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB (1U << 7)
+#define MC_CLIENT_HOTRESET_CTRL1_NVJPG_FLUSH_ENB (1U << 8)
+#define MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB (1U << 12)
+#define MC_CLIENT_HOTRESET_CTRL1_TSECB_FLUSH_ENB (1U << 13)
+#define MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB (1U << 18)
+#define MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB (1U << 19)
+#define MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB (1U << 20)
+#define MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB (1U << 21)
+#define MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB (1U << 22)
+#define MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB (1U << 23)
+#define MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB (1U << 24)
+#define MC_CLIENT_HOTRESET_STATUS1 0x974U
+
+#endif /* TEGRA_MC_DEF_H */
diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h
index f55f5df..68b4624 100644
--- a/plat/nvidia/tegra/include/tegra_private.h
+++ b/plat/nvidia/tegra/include/tegra_private.h
@@ -75,6 +75,8 @@
void plat_gic_setup(void);
struct tegra_bl31_params *plat_get_bl31_params(void);
plat_params_from_bl2_t *plat_get_bl31_plat_params(void);
+void plat_early_platform_setup(void);
+void plat_late_platform_setup(void);
/* Declarations for plat_secondary.c */
void plat_secondary_setup(void);
@@ -126,7 +128,6 @@
/* Declarations for tegra_bl31_setup.c */
plat_params_from_bl2_t *bl31_get_plat_params(void);
int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes);
-void plat_early_platform_setup(void);
/* Declarations for tegra_delay_timer.c */
void tegra_delay_timer_init(void);
diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk
index ac110cc..614d2a2 100644
--- a/plat/nvidia/tegra/platform.mk
+++ b/plat/nvidia/tegra/platform.mk
@@ -40,5 +40,5 @@
# modify BUILD_PLAT to point to SoC specific build directory
BUILD_PLAT := ${BUILD_BASE}/${PLAT}/${TARGET_SOC}/${BUILD_TYPE}
-# enable signed comparison checks
-TF_CFLAGS += -Wsign-compare
+# platform cflags (enable signed comparisons, disable stdlib)
+TF_CFLAGS += -Wsign-compare -nostdlib
diff --git a/plat/nvidia/tegra/soc/t132/platform_t132.mk b/plat/nvidia/tegra/soc/t132/platform_t132.mk
index f15ee74..bb7b7ee 100644
--- a/plat/nvidia/tegra/soc/t132/platform_t132.mk
+++ b/plat/nvidia/tegra/soc/t132/platform_t132.mk
@@ -19,7 +19,8 @@
MAX_MMAP_REGIONS := 8
$(eval $(call add_define,MAX_MMAP_REGIONS))
-BL31_SOURCES += lib/cpus/aarch64/denver.S \
+BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \
+ lib/cpus/aarch64/denver.S \
${COMMON_DIR}/drivers/flowctrl/flowctrl.c \
${COMMON_DIR}/drivers/memctrl/memctrl_v1.c \
${SOC_DIR}/plat_psci_handlers.c \
diff --git a/plat/nvidia/tegra/soc/t186/drivers/include/mce_private.h b/plat/nvidia/tegra/soc/t186/drivers/include/mce_private.h
index 96a5525..203f61a 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/include/mce_private.h
+++ b/plat/nvidia/tegra/soc/t186/drivers/include/mce_private.h
@@ -64,19 +64,17 @@
#define MCA_ARG_FINISH_MASK U(0xFF)
/*******************************************************************************
- * Uncore PERFMON ARI struct
+ * Uncore PERFMON ARI macros
******************************************************************************/
#define UNCORE_PERFMON_CMD_READ U(0)
#define UNCORE_PERFMON_CMD_WRITE U(1)
#define UNCORE_PERFMON_CMD_MASK U(0xFF)
-#define UNCORE_PERFMON_CMD_SHIFT U(24)
#define UNCORE_PERFMON_UNIT_GRP_MASK U(0xF)
#define UNCORE_PERFMON_SELECTOR_MASK U(0xF)
#define UNCORE_PERFMON_REG_MASK U(0xFF)
#define UNCORE_PERFMON_CTR_MASK U(0xFF)
#define UNCORE_PERFMON_RESP_STATUS_MASK U(0xFF)
-#define UNCORE_PERFMON_RESP_STATUS_SHIFT U(24)
/*******************************************************************************
* Structure populated by arch specific code to export routines which perform
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
index 9c4e57c..a57bc11 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
@@ -35,8 +35,8 @@
#define ARI_REQUEST_VALID_BIT (1U << 8)
#define ARI_EVT_MASK_STANDBYWFI_BIT (1U << 7)
-/* default timeout (ms) to wait for ARI completion */
-#define ARI_MAX_RETRY_COUNT 2000
+/* default timeout (us) to wait for ARI completion */
+#define ARI_MAX_RETRY_COUNT U(2000000)
/*******************************************************************************
* ARI helper functions
@@ -80,7 +80,7 @@
static int32_t ari_request_wait(uint32_t ari_base, uint32_t evt_mask, uint32_t req,
uint32_t lo, uint32_t hi)
{
- uint32_t retries = ARI_MAX_RETRY_COUNT;
+ uint32_t retries = (uint32_t)ARI_MAX_RETRY_COUNT;
uint32_t status;
int32_t ret = 0;
@@ -115,8 +115,8 @@
break;
}
- /* delay 1 ms */
- mdelay(1);
+ /* delay 1 us */
+ udelay(1);
/* decrement the retry count */
retries--;
@@ -503,7 +503,7 @@
uint32_t val, req_status;
uint8_t req_cmd;
- req_cmd = (uint8_t)(req >> UNCORE_PERFMON_CMD_SHIFT);
+ req_cmd = (uint8_t)(req & UNCORE_PERFMON_CMD_MASK);
/* clean the previous response state */
ari_clobber_response(ari_base);
@@ -533,7 +533,7 @@
* For "read" commands get the data from the uncore
* perfmon registers
*/
- req_status >>= UNCORE_PERFMON_RESP_STATUS_SHIFT;
+ req_status &= UNCORE_PERFMON_RESP_STATUS_MASK;
if ((req_status == 0U) && (req_cmd == UNCORE_PERFMON_CMD_READ)) {
*data = ari_get_response_low(ari_base);
}
diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
index 1e8d482..376ee86 100644
--- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c
+++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c
@@ -4,9 +4,13 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <assert.h>
#include <common/bl_common.h>
+#include <mce.h>
#include <memctrl_v2.h>
+#include <tegra_mc_def.h>
+#include <tegra_platform.h>
/*******************************************************************************
* Array to hold stream_id override config register offsets
@@ -201,6 +205,318 @@
mc_make_txn_override_cfg(SCEW, CGID_TAG_ADR),
};
+static void tegra186_memctrl_reconfig_mss_clients(void)
+{
+#if ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS
+ uint32_t val, wdata_0, wdata_1;
+
+ /*
+ * Assert Memory Controller's HOTRESET_FLUSH_ENABLE signal for
+ * boot and strongly ordered MSS clients to flush existing memory
+ * traffic and stall future requests.
+ */
+ val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0);
+ assert(val == MC_CLIENT_HOTRESET_CTRL0_RESET_VAL);
+
+ wdata_0 = MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB |
+#if ENABLE_AFI_DEVICE
+ MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB |
+#endif
+ MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB;
+ tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
+
+ /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
+ do {
+ val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
+ } while ((val & wdata_0) != wdata_0);
+
+ /* Wait one more time due to SW WAR for known legacy issue */
+ do {
+ val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0);
+ } while ((val & wdata_0) != wdata_0);
+
+ val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1);
+ assert(val == MC_CLIENT_HOTRESET_CTRL1_RESET_VAL);
+
+ wdata_1 = MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB |
+ MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB;
+ tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
+
+ /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */
+ do {
+ val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
+ } while ((val & wdata_1) != wdata_1);
+
+ /* Wait one more time due to SW WAR for known legacy issue */
+ do {
+ val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1);
+ } while ((val & wdata_1) != wdata_1);
+
+ /*
+ * Change MEMTYPE_OVERRIDE from SO_DEV -> PASSTHRU for boot and
+ * strongly ordered MSS clients. ROC needs to be single point
+ * of control on overriding the memory type. So, remove TSA's
+ * memtype override.
+ *
+ * MC clients with default SO_DEV override still enabled at TSA:
+ * AONW, BPMPW, SCEW, APEW
+ */
+#if ENABLE_AFI_DEVICE
+ mc_set_tsa_passthrough(AFIW);
+#endif
+ mc_set_tsa_passthrough(HDAW);
+ mc_set_tsa_passthrough(SATAW);
+ mc_set_tsa_passthrough(XUSB_HOSTW);
+ mc_set_tsa_passthrough(XUSB_DEVW);
+ mc_set_tsa_passthrough(SDMMCWAB);
+ mc_set_tsa_passthrough(APEDMAW);
+ mc_set_tsa_passthrough(SESWR);
+ mc_set_tsa_passthrough(ETRW);
+ mc_set_tsa_passthrough(AXISW);
+ mc_set_tsa_passthrough(EQOSW);
+ mc_set_tsa_passthrough(UFSHCW);
+ mc_set_tsa_passthrough(BPMPDMAW);
+ mc_set_tsa_passthrough(AONDMAW);
+ mc_set_tsa_passthrough(SCEDMAW);
+
+ /* Parker has no IO Coherency support and need the following:
+ * Ordered MC Clients on Parker are AFI, EQOS, SATA, XUSB.
+ * ISO clients(DISP, VI, EQOS) should never snoop caches and
+ * don't need ROC/PCFIFO ordering.
+ * ISO clients(EQOS) that need ordering should use PCFIFO ordering
+ * and bypass ROC ordering by using FORCE_NON_COHERENT path.
+ * FORCE_NON_COHERENT/FORCE_COHERENT config take precedence
+ * over SMMU attributes.
+ * Force all Normal memory transactions from ISO and non-ISO to be
+ * non-coherent(bypass ROC, avoid cache snoop to avoid perf hit).
+ * Force the SO_DEV transactions from ordered ISO clients(EQOS) to
+ * non-coherent path and enable MC PCFIFO interlock for ordering.
+ * Force the SO_DEV transactions from ordered non-ISO clients (PCIe,
+ * XUSB, SATA) to coherent so that the transactions are
+ * ordered by ROC.
+ * PCFIFO ensure write ordering.
+ * Read after Write ordering is maintained/enforced by MC clients.
+ * Clients that need PCIe type write ordering must
+ * go through ROC ordering.
+ * Ordering enable for Read clients is not necessary.
+ * R5's and A9 would get necessary ordering from AXI and
+ * don't need ROC ordering enable:
+ * - MMIO ordering is through dev mapping and MMIO
+ * accesses bypass SMMU.
+ * - Normal memory is accessed through SMMU and ordering is
+ * ensured by client and AXI.
+ * - Ack point for Normal memory is WCAM in MC.
+ * - MMIO's can be early acked and AXI ensures dev memory ordering,
+ * Client ensures read/write direction change ordering.
+ * - See Bug 200312466 for more details.
+ *
+ * CGID_TAG_ADR is only present from T186 A02. As this code is common
+ * between A01 and A02, tegra_memctrl_set_overrides() programs
+ * CGID_TAG_ADR for the necessary clients on A02.
+ */
+ mc_set_txn_override(HDAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(BPMPW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(PTCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVDISPLAYR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(EQOSW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVJPGSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(ISPRA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SDMMCWAA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(VICSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(MPCOREW, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+ mc_set_txn_override(GPUSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(AXISR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SCEDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SDMMCW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(EQOSR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ /* See bug 200131110 comment #35*/
+ mc_set_txn_override(APEDMAR, CGID_TAG_CLIENT_AXI_ID, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVENCSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SDMMCRAB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(VICSRD1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(BPMPDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(VIW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SDMMCRAA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(AXISW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(XUSB_DEVR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(UFSHCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(TSECSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(GPUSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SATAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(XUSB_HOSTW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT);
+ mc_set_txn_override(TSECSWRB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(GPUSRD2, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SCEDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(GPUSWR2, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(AONDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ /* See bug 200131110 comment #35*/
+ mc_set_txn_override(APEDMAW, CGID_TAG_CLIENT_AXI_ID, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(AONW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(HOST1XDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(ETRR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SESWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVJPGSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVDECSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(TSECSRDB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(BPMPDMAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(APER, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVDECSRD1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(XUSB_HOSTR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(ISPWA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SESRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SCER, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(AONR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(MPCORER, CGID_TAG_DEFAULT, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE);
+ mc_set_txn_override(SDMMCWA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(HDAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVDECSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(UFSHCW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(AONDMAR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SATAW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT);
+ mc_set_txn_override(ETRW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(VICSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVENCSWR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ /* See bug 200131110 comment #35 */
+ mc_set_txn_override(AFIR, CGID_TAG_DEFAULT, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SDMMCWAB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SDMMCRA, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(NVDISPLAYR1, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(ISPWB, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(BPMPR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(APEW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(SDMMCR, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ mc_set_txn_override(XUSB_DEVW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_COHERENT);
+ mc_set_txn_override(TSECSRD, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+ /*
+ * See bug 200131110 comment #35 - there are no normal requests
+ * and AWID for SO/DEV requests is hardcoded in RTL for a
+ * particular PCIE controller
+ */
+ mc_set_txn_override(AFIW, CGID_TAG_DEFAULT, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_COHERENT);
+ mc_set_txn_override(SCEW, CGID_TAG_DEFAULT, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT);
+
+ /*
+ * At this point, ordering can occur at ROC. So, remove PCFIFO's
+ * control over ordering requests.
+ *
+ * Change PCFIFO_*_ORDERED_CLIENT from ORDERED -> UNORDERED for
+ * boot and strongly ordered MSS clients
+ */
+ val = MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL &
+#if ENABLE_AFI_DEVICE
+ mc_set_pcfifo_unordered_boot_so_mss(1, AFIW) &
+#endif
+ mc_set_pcfifo_unordered_boot_so_mss(1, HDAW) &
+ mc_set_pcfifo_unordered_boot_so_mss(1, SATAW);
+ tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG1, val);
+
+ val = MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL &
+ mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_HOSTW) &
+ mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_DEVW);
+ tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG2, val);
+
+ val = MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL &
+ mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWAB);
+ tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG3, val);
+
+ val = MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL &
+ mc_set_pcfifo_unordered_boot_so_mss(4, SESWR) &
+ mc_set_pcfifo_unordered_boot_so_mss(4, ETRW) &
+ mc_set_pcfifo_unordered_boot_so_mss(4, AXISW) &
+ mc_set_pcfifo_unordered_boot_so_mss(4, UFSHCW) &
+ mc_set_pcfifo_unordered_boot_so_mss(4, BPMPDMAW) &
+ mc_set_pcfifo_unordered_boot_so_mss(4, AONDMAW) &
+ mc_set_pcfifo_unordered_boot_so_mss(4, SCEDMAW);
+ /* EQOSW is the only client that has PCFIFO order enabled. */
+ val |= mc_set_pcfifo_ordered_boot_so_mss(4, EQOSW);
+ tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG4, val);
+
+ val = MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL &
+ mc_set_pcfifo_unordered_boot_so_mss(5, APEDMAW);
+ tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG5, val);
+
+ /*
+ * Deassert HOTRESET FLUSH_ENABLE for boot and strongly ordered MSS
+ * clients to allow memory traffic from all clients to start passing
+ * through ROC
+ */
+ val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL0);
+ assert(val == wdata_0);
+
+ wdata_0 = MC_CLIENT_HOTRESET_CTRL0_RESET_VAL;
+ tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0);
+
+ val = tegra_mc_read_32(MC_CLIENT_HOTRESET_CTRL1);
+ assert(val == wdata_1);
+
+ wdata_1 = MC_CLIENT_HOTRESET_CTRL1_RESET_VAL;
+ tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1);
+
+#endif
+}
+
+static void tegra186_memctrl_set_overrides(void)
+{
+ const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings();
+ const mc_txn_override_cfg_t *mc_txn_override_cfgs;
+ uint32_t num_txn_override_cfgs;
+ uint32_t i, val;
+
+ /* Get the settings from the platform */
+ assert(plat_mc_settings != NULL);
+ mc_txn_override_cfgs = plat_mc_settings->txn_override_cfg;
+ num_txn_override_cfgs = plat_mc_settings->num_txn_override_cfgs;
+
+ /*
+ * Set the MC_TXN_OVERRIDE registers for write clients.
+ */
+ if ((tegra_chipid_is_t186()) &&
+ (!tegra_platform_is_silicon() ||
+ (tegra_platform_is_silicon() && (tegra_get_chipid_minor() == 1U)))) {
+
+ /*
+ * GPU and NVENC settings for Tegra186 simulation and
+ * Silicon rev. A01
+ */
+ val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR);
+ val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK;
+ tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR,
+ val | MC_TXN_OVERRIDE_CGID_TAG_ZERO);
+
+ val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2);
+ val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK;
+ tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_GPUSWR2,
+ val | MC_TXN_OVERRIDE_CGID_TAG_ZERO);
+
+ val = tegra_mc_read_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR);
+ val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK;
+ tegra_mc_write_32(MC_TXN_OVERRIDE_CONFIG_NVENCSWR,
+ val | MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID);
+
+ } else {
+
+ /*
+ * Settings for Tegra186 silicon rev. A02 and onwards.
+ */
+ for (i = 0; i < num_txn_override_cfgs; i++) {
+ val = tegra_mc_read_32(mc_txn_override_cfgs[i].offset);
+ val &= (uint32_t)~MC_TXN_OVERRIDE_CGID_TAG_MASK;
+ tegra_mc_write_32(mc_txn_override_cfgs[i].offset,
+ val | mc_txn_override_cfgs[i].cgid_tag);
+ }
+ }
+}
+
/*******************************************************************************
* Struct to hold the memory controller settings
******************************************************************************/
@@ -210,7 +526,9 @@
.streamid_security_cfg = tegra186_streamid_sec_cfgs,
.num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra186_streamid_sec_cfgs),
.txn_override_cfg = tegra186_txn_override_cfgs,
- .num_txn_override_cfgs = (uint32_t)ARRAY_SIZE(tegra186_txn_override_cfgs)
+ .num_txn_override_cfgs = (uint32_t)ARRAY_SIZE(tegra186_txn_override_cfgs),
+ .reconfig_mss_clients = tegra186_memctrl_reconfig_mss_clients,
+ .set_txn_overrides = tegra186_memctrl_set_overrides,
};
/*******************************************************************************
@@ -220,3 +538,45 @@
{
return &tegra186_mc_settings;
}
+
+/*******************************************************************************
+ * Handler to program the scratch registers with TZDRAM settings for the
+ * resume firmware
+ ******************************************************************************/
+void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes)
+{
+ uint32_t val;
+
+ /*
+ * Setup the Memory controller to allow only secure accesses to
+ * the TZDRAM carveout
+ */
+ INFO("Configuring TrustZone DRAM Memory Carveout\n");
+
+ tegra_mc_write_32(MC_SECURITY_CFG0_0, (uint32_t)phys_base);
+ tegra_mc_write_32(MC_SECURITY_CFG3_0, (uint32_t)(phys_base >> 32));
+ tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20);
+
+ /*
+ * When TZ encryption is enabled, we need to setup TZDRAM
+ * before CPU accesses TZ Carveout, else CPU will fetch
+ * non-decrypted data. So save TZDRAM setting for SC7 resume
+ * FW to restore.
+ *
+ * Scratch registers map:
+ * RSV55_0 = CFG1[12:0] | CFG0[31:20]
+ * RSV55_1 = CFG3[1:0]
+ */
+ val = tegra_mc_read_32(MC_SECURITY_CFG1_0) & MC_SECURITY_SIZE_MB_MASK;
+ val |= tegra_mc_read_32(MC_SECURITY_CFG0_0) & MC_SECURITY_BOM_MASK;
+ mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_TZDRAM_ADDR_LO, val);
+
+ val = tegra_mc_read_32(MC_SECURITY_CFG3_0) & MC_SECURITY_BOM_HI_MASK;
+ mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_TZDRAM_ADDR_HI, val);
+
+ /*
+ * MCE propagates the security configuration values across the
+ * CCPLEX.
+ */
+ (void)mce_update_gsc_tzdram();
+}
diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
index a490bcc..09e257d 100644
--- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
@@ -22,15 +22,11 @@
#include <smmu.h>
#include <stdbool.h>
#include <t18x_ari.h>
+#include <tegra186_private.h>
#include <tegra_private.h>
extern void memcpy16(void *dest, const void *src, unsigned int length);
-extern void prepare_cpu_pwr_dwn(void);
-extern void tegra186_cpu_reset_handler(void);
-extern uint64_t __tegra186_cpu_reset_handler_end,
- __tegra186_smmu_context;
-
/* state id mask */
#define TEGRA186_STATE_ID_MASK 0xFU
/* constants to get power state's wake time */
@@ -125,12 +121,11 @@
/* save 'Secure Boot' Processor Feature Config Register */
val = mmio_read_32(TEGRA_MISC_BASE + MISCREG_PFCFG);
- mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV6, val);
+ mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_BOOTP_FCFG, val);
/* save SMMU context to TZDRAM */
smmu_ctx_base = params_from_bl2->tzdram_base +
- ((uintptr_t)&__tegra186_smmu_context -
- (uintptr_t)&tegra186_cpu_reset_handler);
+ tegra186_get_smmu_ctx_offset();
tegra_smmu_save_context((uintptr_t)smmu_ctx_base);
/* Prepare for system suspend */
@@ -139,6 +134,7 @@
cstate_info.system_state_force = 1;
cstate_info.update_wake_mask = 1;
mce_update_cstate_info(&cstate_info);
+
/* Loop until system suspend is allowed */
do {
val = (uint32_t)mce_command_handler(
@@ -151,6 +147,10 @@
/* Instruct the MCE to enter system suspend state */
(void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE,
(uint64_t)TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U);
+
+ /* set system suspend state for house-keeping */
+ tegra186_set_system_suspend_entry();
+
} else {
; /* do nothing */
}
@@ -281,8 +281,7 @@
* BL3-1 over to TZDRAM.
*/
val = params_from_bl2->tzdram_base +
- ((uintptr_t)&__tegra186_cpu_reset_handler_end -
- (uintptr_t)&tegra186_cpu_reset_handler);
+ tegra186_get_cpu_reset_handler_size();
memcpy16((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE,
(uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE);
}
@@ -297,7 +296,7 @@
uint64_t target_cluster = (mpidr & MPIDR_CLUSTER_MASK) >>
MPIDR_AFFINITY_BITS;
- if (target_cluster > MPIDR_AFFLVL1) {
+ if (target_cluster > ((uint32_t)PLATFORM_CLUSTER_COUNT - 1U)) {
ERROR("%s: unsupported CPU (0x%lx)\n", __func__, mpidr);
ret = PSCI_E_NOT_PRESENT;
diff --git a/plat/nvidia/tegra/soc/t186/plat_secondary.c b/plat/nvidia/tegra/soc/t186/plat_secondary.c
index 577cc38..1650809 100644
--- a/plat/nvidia/tegra/soc/t186/plat_secondary.c
+++ b/plat/nvidia/tegra/soc/t186/plat_secondary.c
@@ -11,6 +11,7 @@
#include <lib/mmio.h>
#include <mce.h>
+#include <tegra186_private.h>
#include <tegra_def.h>
#include <tegra_private.h>
@@ -24,9 +25,6 @@
extern void memcpy16(void *dest, const void *src, unsigned int length);
-extern uint64_t tegra_bl31_phys_base;
-extern uint64_t __tegra186_cpu_reset_handler_end;
-
/*******************************************************************************
* Setup secondary CPU vectors
******************************************************************************/
@@ -34,38 +32,33 @@
{
uint32_t addr_low, addr_high;
const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
- uint64_t cpu_reset_handler_base;
+ uint64_t cpu_reset_handler_base, cpu_reset_handler_size;
INFO("Setting up secondary CPU boot\n");
- if ((tegra_bl31_phys_base >= TEGRA_TZRAM_BASE) &&
- (tegra_bl31_phys_base <= (TEGRA_TZRAM_BASE + TEGRA_TZRAM_SIZE))) {
-
- /*
- * The BL31 code resides in the TZSRAM which loses state
- * when we enter System Suspend. Copy the wakeup trampoline
- * code to TZDRAM to help us exit from System Suspend.
- */
- cpu_reset_handler_base = params_from_bl2->tzdram_base;
- memcpy16((void *)((uintptr_t)cpu_reset_handler_base),
- (void *)(uintptr_t)tegra186_cpu_reset_handler,
- (uintptr_t)&tegra186_cpu_reset_handler);
+ /*
+ * The BL31 code resides in the TZSRAM which loses state
+ * when we enter System Suspend. Copy the wakeup trampoline
+ * code to TZDRAM to help us exit from System Suspend.
+ */
+ cpu_reset_handler_base = tegra186_get_cpu_reset_handler_base();
+ cpu_reset_handler_size = tegra186_get_cpu_reset_handler_size();
+ (void)memcpy16((void *)(uintptr_t)params_from_bl2->tzdram_base,
+ (const void *)(uintptr_t)cpu_reset_handler_base,
+ cpu_reset_handler_size);
- } else {
- cpu_reset_handler_base = (uintptr_t)&tegra_secure_entrypoint;
- }
-
- addr_low = (uint32_t)cpu_reset_handler_base | CPU_RESET_MODE_AA64;
- addr_high = (uint32_t)((cpu_reset_handler_base >> 32U) & 0x7ffU);
+ /* TZDRAM base will be used as the "resume" address */
+ addr_low = (uint32_t)params_from_bl2->tzdram_base | CPU_RESET_MODE_AA64;
+ addr_high = (uint32_t)((params_from_bl2->tzdram_base >> 32U) & 0x7ffU);
/* write lower 32 bits first, then the upper 11 bits */
mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW, addr_low);
mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_HIGH, addr_high);
/* save reset vector to be used during SYSTEM_SUSPEND exit */
- mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_RSV1_SCRATCH_0,
+ mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO,
addr_low);
- mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_RSV1_SCRATCH_1,
+ mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI,
addr_high);
/* update reset vector address to the CCPLEX */
diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c
index bbd19c1..fd109e5 100644
--- a/plat/nvidia/tegra/soc/t186/plat_setup.c
+++ b/plat/nvidia/tegra/soc/t186/plat_setup.c
@@ -40,7 +40,7 @@
* the number of power domains at the highest power level.
*******************************************************************************
*/
-const uint8_t tegra_power_domain_tree_desc[] = {
+static const uint8_t tegra_power_domain_tree_desc[] = {
/* No of root nodes */
1,
/* No of clusters */
@@ -211,7 +211,7 @@
{
uint32_t val;
- val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_LO);
+ val = mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_BL31_PARAMS_ADDR);
return (struct tegra_bl31_params *)(uintptr_t)val;
}
@@ -223,7 +223,7 @@
{
uint32_t val;
- val = mmio_read_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV53_HI);
+ val = mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_BL31_PLAT_PARAMS_ADDR);
return (plat_params_from_bl2_t *)(uintptr_t)val;
}
diff --git a/plat/nvidia/tegra/soc/t186/plat_smmu.c b/plat/nvidia/tegra/soc/t186/plat_smmu.c
index b9541e8..95f6def 100644
--- a/plat/nvidia/tegra/soc/t186/plat_smmu.c
+++ b/plat/nvidia/tegra/soc/t186/plat_smmu.c
@@ -8,6 +8,7 @@
#include <smmu.h>
#include <tegra_def.h>
+#include <tegra_mc_def.h>
#define MAX_NUM_SMMU_DEVICES U(1)
diff --git a/plat/nvidia/tegra/soc/t186/plat_trampoline.S b/plat/nvidia/tegra/soc/t186/plat_trampoline.S
index 69ca798..e3393e9 100644
--- a/plat/nvidia/tegra/soc/t186/plat_trampoline.S
+++ b/plat/nvidia/tegra/soc/t186/plat_trampoline.S
@@ -10,23 +10,32 @@
#include <plat/common/common_def.h>
#include <tegra_def.h>
+#define TEGRA186_STATE_SYSTEM_SUSPEND 0x5C7
+#define TEGRA186_STATE_SYSTEM_RESUME 0x600D
#define TEGRA186_SMMU_CTX_SIZE 0x420
.globl tegra186_cpu_reset_handler
/* CPU reset handler routine */
func tegra186_cpu_reset_handler _align=4
- /*
- * The TZRAM loses state during System Suspend. We use this
- * information to decide if the reset handler is running after a
- * System Suspend. Resume from system suspend requires restoring
- * the entire state from TZDRAM to TZRAM.
- */
- mov x0, #BL31_BASE
- ldr x0, [x0]
- cbnz x0, boot_cpu
+ /* check if we are exiting system suspend state */
+ adr x0, __tegra186_system_suspend_state
+ ldr x1, [x0]
+ mov x2, #TEGRA186_STATE_SYSTEM_SUSPEND
+ lsl x2, x2, #16
+ add x2, x2, #TEGRA186_STATE_SYSTEM_SUSPEND
+ cmp x1, x2
+ bne boot_cpu
- /* resume from system suspend */
+ /* set system resume state */
+ mov x1, #TEGRA186_STATE_SYSTEM_RESUME
+ lsl x1, x1, #16
+ mov x2, #TEGRA186_STATE_SYSTEM_RESUME
+ add x1, x1, x2
+ str x1, [x0]
+ dsb sy
+
+ /* prepare to relocate to TZSRAM */
mov x0, #BL31_BASE
adr x1, __tegra186_cpu_reset_handler_end
adr x2, __tegra186_cpu_reset_handler_data
@@ -69,6 +78,12 @@
__tegra186_cpu_reset_handler_data:
.quad tegra_secure_entrypoint
.quad __BL31_END__ - BL31_BASE
+
+ .globl __tegra186_system_suspend_state
+__tegra186_system_suspend_state:
+ .quad 0
+
+ .align 4
.globl __tegra186_smmu_context
__tegra186_smmu_context:
.rept TEGRA186_SMMU_CTX_SIZE
@@ -80,3 +95,50 @@
.align 4
.globl __tegra186_cpu_reset_handler_end
__tegra186_cpu_reset_handler_end:
+
+ .globl tegra186_get_cpu_reset_handler_size
+ .globl tegra186_get_cpu_reset_handler_base
+ .globl tegra186_get_smmu_ctx_offset
+ .globl tegra186_set_system_suspend_entry
+
+/* return size of the CPU reset handler */
+func tegra186_get_cpu_reset_handler_size
+ adr x0, __tegra186_cpu_reset_handler_end
+ adr x1, tegra186_cpu_reset_handler
+ sub x0, x0, x1
+ ret
+endfunc tegra186_get_cpu_reset_handler_size
+
+/* return the start address of the CPU reset handler */
+func tegra186_get_cpu_reset_handler_base
+ adr x0, tegra186_cpu_reset_handler
+ ret
+endfunc tegra186_get_cpu_reset_handler_base
+
+/* return the size of the SMMU context */
+func tegra186_get_smmu_ctx_offset
+ adr x0, __tegra186_smmu_context
+ adr x1, tegra186_cpu_reset_handler
+ sub x0, x0, x1
+ ret
+endfunc tegra186_get_smmu_ctx_offset
+
+/* set system suspend state before SC7 entry */
+func tegra186_set_system_suspend_entry
+ mov x0, #TEGRA_MC_BASE
+ mov x3, #MC_SECURITY_CFG3_0
+ ldr w1, [x0, x3]
+ lsl x1, x1, #32
+ mov x3, #MC_SECURITY_CFG0_0
+ ldr w2, [x0, x3]
+ orr x3, x1, x2 /* TZDRAM base */
+ adr x0, __tegra186_system_suspend_state
+ adr x1, tegra186_cpu_reset_handler
+ sub x2, x0, x1 /* offset in TZDRAM */
+ mov x0, #TEGRA186_STATE_SYSTEM_SUSPEND
+ lsl x0, x0, #16
+ add x0, x0, #TEGRA186_STATE_SYSTEM_SUSPEND
+ str x0, [x3, x2] /* set value in TZDRAM */
+ dsb sy
+ ret
+endfunc tegra186_set_system_suspend_entry
diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk
index 9dae8cd..fdeb886 100644
--- a/plat/nvidia/tegra/soc/t186/platform_t186.mk
+++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk
@@ -11,15 +11,9 @@
ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS := 1
$(eval $(call add_define,ENABLE_ROC_FOR_ORDERING_CLIENT_REQUESTS))
-RELOCATE_TO_BL31_BASE := 1
-$(eval $(call add_define,RELOCATE_TO_BL31_BASE))
-
ENABLE_CHIP_VERIFICATION_HARNESS := 0
$(eval $(call add_define,ENABLE_CHIP_VERIFICATION_HARNESS))
-ENABLE_SMMU_DEVICE := 1
-$(eval $(call add_define,ENABLE_SMMU_DEVICE))
-
RESET_TO_BL31 := 1
PROGRAMMABLE_RESET_ADDRESS := 1
@@ -45,7 +39,8 @@
# platform files
PLAT_INCLUDES += -I${SOC_DIR}/drivers/include
-BL31_SOURCES += lib/cpus/aarch64/denver.S \
+BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \
+ lib/cpus/aarch64/denver.S \
lib/cpus/aarch64/cortex_a57.S \
${COMMON_DIR}/drivers/gpcdma/gpcdma.c \
${COMMON_DIR}/drivers/memctrl/memctrl_v2.c \
diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
index 958aa92..f52d975 100644
--- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
@@ -104,41 +104,55 @@
if ((lvl == MPIDR_AFFLVL1) && (target == PSTATE_ID_CLUSTER_IDLE)) {
/* initialize the bpmp interface */
- (void)tegra_bpmp_init();
-
- /* Cluster idle */
- data[0] = (uint32_t)cpu;
- data[1] = TEGRA_PM_CC6;
- data[2] = TEGRA_PM_SC1;
- ret = tegra_bpmp_send_receive_atomic(MRQ_DO_IDLE,
- (void *)&data, (int)sizeof(data),
- (void *)&bpmp_reply, (int)sizeof(bpmp_reply));
-
- /* check if cluster idle entry is allowed */
- if ((ret != 0L) || (bpmp_reply != BPMP_CCx_ALLOWED)) {
+ ret = tegra_bpmp_init();
+ if (ret != 0U) {
/* Cluster idle not allowed */
target = PSCI_LOCAL_STATE_RUN;
+ } else {
+
+ /* Cluster idle */
+ data[0] = (uint32_t)cpu;
+ data[1] = TEGRA_PM_CC6;
+ data[2] = TEGRA_PM_SC1;
+ ret = tegra_bpmp_send_receive_atomic(MRQ_DO_IDLE,
+ (void *)&data, (int)sizeof(data),
+ (void *)&bpmp_reply,
+ (int)sizeof(bpmp_reply));
+
+ /* check if cluster idle entry is allowed */
+ if ((ret != 0L) || (bpmp_reply != BPMP_CCx_ALLOWED)) {
+
+ /* Cluster idle not allowed */
+ target = PSCI_LOCAL_STATE_RUN;
+ }
}
} else if ((lvl == MPIDR_AFFLVL1) && (target == PSTATE_ID_CLUSTER_POWERDN)) {
/* initialize the bpmp interface */
- (void)tegra_bpmp_init();
-
- /* Cluster power-down */
- data[0] = (uint32_t)cpu;
- data[1] = TEGRA_PM_CC7;
- data[2] = TEGRA_PM_SC1;
- ret = tegra_bpmp_send_receive_atomic(MRQ_DO_IDLE,
- (void *)&data, (int)sizeof(data),
- (void *)&bpmp_reply, (int)sizeof(bpmp_reply));
-
- /* check if cluster power down is allowed */
- if ((ret != 0L) || (bpmp_reply != BPMP_CCx_ALLOWED)) {
+ ret = tegra_bpmp_init();
+ if (ret != 0U) {
/* Cluster power down not allowed */
target = PSCI_LOCAL_STATE_RUN;
+ } else {
+
+ /* Cluster power-down */
+ data[0] = (uint32_t)cpu;
+ data[1] = TEGRA_PM_CC7;
+ data[2] = TEGRA_PM_SC1;
+ ret = tegra_bpmp_send_receive_atomic(MRQ_DO_IDLE,
+ (void *)&data, (int)sizeof(data),
+ (void *)&bpmp_reply,
+ (int)sizeof(bpmp_reply));
+
+ /* check if cluster power down is allowed */
+ if ((ret != 0L) || (bpmp_reply != BPMP_CCx_ALLOWED)) {
+
+ /* Cluster power down not allowed */
+ target = PSCI_LOCAL_STATE_RUN;
+ }
}
} else if (((lvl == MPIDR_AFFLVL2) || (lvl == MPIDR_AFFLVL1)) &&
diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk
index b8dbf18..e23d7e3 100644
--- a/plat/nvidia/tegra/soc/t210/platform_t210.mk
+++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk
@@ -24,9 +24,10 @@
PLAT_INCLUDES += -I${SOC_DIR}/drivers/se
-BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \
+BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \
+ lib/cpus/aarch64/cortex_a53.S \
lib/cpus/aarch64/cortex_a57.S \
- ${COMMON_DIR}/drivers/bpmp/bpmp.c \
+ ${COMMON_DIR}/drivers/bpmp/bpmp.c \
${COMMON_DIR}/drivers/flowctrl/flowctrl.c \
${COMMON_DIR}/drivers/memctrl/memctrl_v1.c \
${SOC_DIR}/plat_psci_handlers.c \
diff --git a/plat/ti/k3/common/k3_bl31_setup.c b/plat/ti/k3/common/k3_bl31_setup.c
index 3fa11b2..78fb696 100644
--- a/plat/ti/k3/common/k3_bl31_setup.c
+++ b/plat/ti/k3/common/k3_bl31_setup.c
@@ -23,8 +23,7 @@
const mmap_region_t plat_k3_mmap[] = {
MAP_REGION_FLAT(SHARED_RAM_BASE, SHARED_RAM_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(K3_USART_BASE_ADDRESS, K3_USART_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(K3_GICD_BASE, K3_GICD_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
- MAP_REGION_FLAT(K3_GICR_BASE, K3_GICR_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+ MAP_REGION_FLAT(K3_GIC_BASE, K3_GIC_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(SEC_PROXY_RT_BASE, SEC_PROXY_RT_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(SEC_PROXY_SCFG_BASE, SEC_PROXY_SCFG_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
MAP_REGION_FLAT(SEC_PROXY_DATA_BASE, SEC_PROXY_DATA_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
@@ -116,7 +115,7 @@
void bl31_platform_setup(void)
{
- k3_gic_driver_init(K3_GICD_BASE, K3_GICR_BASE);
+ k3_gic_driver_init(K3_GIC_BASE);
k3_gic_init();
ti_sci_init();
diff --git a/plat/ti/k3/common/k3_gicv3.c b/plat/ti/k3/common/k3_gicv3.c
index b7c7880..1932eaa 100644
--- a/plat/ti/k3/common/k3_gicv3.c
+++ b/plat/ti/k3/common/k3_gicv3.c
@@ -6,10 +6,12 @@
#include <platform_def.h>
+#include <assert.h>
#include <common/bl_common.h>
#include <common/interrupt_props.h>
#include <drivers/arm/gicv3.h>
#include <lib/utils.h>
+#include <lib/mmio.h>
#include <plat/common/platform.h>
#include <k3_gicv3.h>
@@ -35,8 +37,25 @@
.mpidr_to_core_pos = k3_mpidr_to_core_pos,
};
-void k3_gic_driver_init(uintptr_t gicd_base, uintptr_t gicr_base)
+void k3_gic_driver_init(uintptr_t gic_base)
{
+ /* GIC Distributor is always at the base of the IP */
+ uintptr_t gicd_base = gic_base;
+ /* GIC Redistributor base is run-time detected */
+ uintptr_t gicr_base = 0;
+
+ for (unsigned int gicr_shift = 18; gicr_shift < 21; gicr_shift++) {
+ uintptr_t gicr_check = gic_base + BIT(gicr_shift);
+ uint32_t iidr = mmio_read_32(gicr_check + GICR_IIDR);
+ if (iidr != 0) {
+ /* Found the GICR base */
+ gicr_base = gicr_check;
+ break;
+ }
+ }
+ /* Assert if we have not found the GICR base */
+ assert(gicr_base != 0);
+
/*
* The GICv3 driver is initialized in EL3 and does not need
* to be initialized again in SEL1. This is because the S-EL1
diff --git a/plat/ti/k3/include/k3_gicv3.h b/plat/ti/k3/include/k3_gicv3.h
index 52f34ff..2329a16 100644
--- a/plat/ti/k3/include/k3_gicv3.h
+++ b/plat/ti/k3/include/k3_gicv3.h
@@ -9,7 +9,7 @@
#include <stdint.h>
-void k3_gic_driver_init(uintptr_t gicd_base, uintptr_t gicr_base);
+void k3_gic_driver_init(uintptr_t gic_base);
void k3_gic_init(void);
void k3_gic_cpuif_enable(void);
void k3_gic_cpuif_disable(void);
diff --git a/plat/ti/k3/include/platform_def.h b/plat/ti/k3/include/platform_def.h
index 9447f04..f1511c1 100644
--- a/plat/ti/k3/include/platform_def.h
+++ b/plat/ti/k3/include/platform_def.h
@@ -185,10 +185,8 @@
INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \
GIC_INTR_CFG_EDGE)
-#define K3_GICD_BASE 0x01800000
-#define K3_GICD_SIZE 0x10000
-#define K3_GICR_BASE 0x01880000
-#define K3_GICR_SIZE 0x100000
+#define K3_GIC_BASE 0x01800000
+#define K3_GIC_SIZE 0x200000
#define SEC_PROXY_DATA_BASE 0x32C00000
#define SEC_PROXY_DATA_SIZE 0x80000
diff --git a/services/spd/trusty/smcall.h b/services/spd/trusty/smcall.h
index 742c8c4..9c1c38c 100644
--- a/services/spd/trusty/smcall.h
+++ b/services/spd/trusty/smcall.h
@@ -7,69 +7,68 @@
#ifndef SMCALL_H
#define SMCALL_H
-#define SMC_NUM_ENTITIES 64
-#define SMC_NUM_ARGS 4
-#define SMC_NUM_PARAMS (SMC_NUM_ARGS - 1)
+#define SMC_NUM_ENTITIES 64U
+#define SMC_NUM_ARGS 4U
+#define SMC_NUM_PARAMS (SMC_NUM_ARGS - 1U)
-#define SMC_IS_FASTCALL(smc_nr) ((smc_nr) & 0x80000000)
-#define SMC_IS_SMC64(smc_nr) ((smc_nr) & 0x40000000)
-#define SMC_ENTITY(smc_nr) (((smc_nr) & 0x3F000000) >> 24)
-#define SMC_FUNCTION(smc_nr) ((smc_nr) & 0x0000FFFF)
+#define SMC_IS_FASTCALL(smc_nr) ((smc_nr) & 0x80000000U)
+#define SMC_IS_SMC64(smc_nr) ((smc_nr) & 0x40000000U)
+#define SMC_ENTITY(smc_nr) (((smc_nr) & 0x3F000000U) >> 24U)
+#define SMC_FUNCTION(smc_nr) ((smc_nr) & 0x0000FFFFU)
#define SMC_NR(entity, fn, fastcall, smc64) \
- (((((unsigned int) (fastcall)) & 0x1) << 31) | \
- (((smc64) & 0x1) << 30) | \
- (((entity) & 0x3F) << 24) | \
- ((fn) & 0xFFFF) \
- )
+ (((((uint32_t)(fastcall)) & 0x1U) << 31U) | \
+ (((smc64) & 0x1U) << 30U) | \
+ (((entity) & 0x3FU) << 24U) | \
+ ((fn) & 0xFFFFU))
-#define SMC_FASTCALL_NR(entity, fn) SMC_NR((entity), (fn), 1, 0)
-#define SMC_FASTCALL64_NR(entity, fn) SMC_NR((entity), (fn), 1, 1)
-#define SMC_YIELDCALL_NR(entity, fn) SMC_NR((entity), (fn), 0, 0)
-#define SMC_YIELDCALL64_NR(entity, fn) SMC_NR((entity), (fn), 0, 1)
+#define SMC_FASTCALL_NR(entity, fn) SMC_NR((entity), (fn), 1U, 0U)
+#define SMC_FASTCALL64_NR(entity, fn) SMC_NR((entity), (fn), 1U, 1U)
+#define SMC_YIELDCALL_NR(entity, fn) SMC_NR((entity), (fn), 0U, 0U)
+#define SMC_YIELDCALL64_NR(entity, fn) SMC_NR((entity), (fn), 0U, 1U)
-#define SMC_ENTITY_ARCH 0 /* ARM Architecture calls */
-#define SMC_ENTITY_CPU 1 /* CPU Service calls */
-#define SMC_ENTITY_SIP 2 /* SIP Service calls */
-#define SMC_ENTITY_OEM 3 /* OEM Service calls */
-#define SMC_ENTITY_STD 4 /* Standard Service calls */
-#define SMC_ENTITY_RESERVED 5 /* Reserved for future use */
-#define SMC_ENTITY_TRUSTED_APP 48 /* Trusted Application calls */
-#define SMC_ENTITY_TRUSTED_OS 50 /* Trusted OS calls */
-#define SMC_ENTITY_LOGGING 51 /* Used for secure -> nonsecure logging */
-#define SMC_ENTITY_SECURE_MONITOR 60 /* Trusted OS calls internal to secure monitor */
+#define SMC_ENTITY_ARCH 0U /* ARM Architecture calls */
+#define SMC_ENTITY_CPU 1U /* CPU Service calls */
+#define SMC_ENTITY_SIP 2U /* SIP Service calls */
+#define SMC_ENTITY_OEM 3U /* OEM Service calls */
+#define SMC_ENTITY_STD 4U /* Standard Service calls */
+#define SMC_ENTITY_RESERVED 5U /* Reserved for future use */
+#define SMC_ENTITY_TRUSTED_APP 48U /* Trusted Application calls */
+#define SMC_ENTITY_TRUSTED_OS 50U /* Trusted OS calls */
+#define SMC_ENTITY_LOGGING 51U /* Used for secure -> nonsecure logging */
+#define SMC_ENTITY_SECURE_MONITOR 60U /* Trusted OS calls internal to secure monitor */
/* FC = Fast call, YC = Yielding call */
-#define SMC_YC_RESTART_LAST SMC_YIELDCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0)
-#define SMC_YC_NOP SMC_YIELDCALL_NR (SMC_ENTITY_SECURE_MONITOR, 1)
+#define SMC_YC_RESTART_LAST SMC_YIELDCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0U)
+#define SMC_YC_NOP SMC_YIELDCALL_NR (SMC_ENTITY_SECURE_MONITOR, 1U)
/*
* Return from secure os to non-secure os with return value in r1
*/
-#define SMC_YC_NS_RETURN SMC_YIELDCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0)
+#define SMC_YC_NS_RETURN SMC_YIELDCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0U)
-#define SMC_FC_RESERVED SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0)
-#define SMC_FC_FIQ_EXIT SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 1)
-#define SMC_FC_REQUEST_FIQ SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 2)
-#define SMC_FC_GET_NEXT_IRQ SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 3)
-#define SMC_FC_FIQ_ENTER SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 4)
+#define SMC_FC_RESERVED SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 0U)
+#define SMC_FC_FIQ_EXIT SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 1U)
+#define SMC_FC_REQUEST_FIQ SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 2U)
+#define SMC_FC_GET_NEXT_IRQ SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 3U)
+#define SMC_FC_FIQ_ENTER SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 4U)
-#define SMC_FC64_SET_FIQ_HANDLER SMC_FASTCALL64_NR(SMC_ENTITY_SECURE_MONITOR, 5)
-#define SMC_FC64_GET_FIQ_REGS SMC_FASTCALL64_NR (SMC_ENTITY_SECURE_MONITOR, 6)
+#define SMC_FC64_SET_FIQ_HANDLER SMC_FASTCALL64_NR(SMC_ENTITY_SECURE_MONITOR, 5U)
+#define SMC_FC64_GET_FIQ_REGS SMC_FASTCALL64_NR (SMC_ENTITY_SECURE_MONITOR, 6U)
-#define SMC_FC_CPU_SUSPEND SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 7)
-#define SMC_FC_CPU_RESUME SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 8)
+#define SMC_FC_CPU_SUSPEND SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 7U)
+#define SMC_FC_CPU_RESUME SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 8U)
-#define SMC_FC_AARCH_SWITCH SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 9)
-#define SMC_FC_GET_VERSION_STR SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 10)
+#define SMC_FC_AARCH_SWITCH SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 9U)
+#define SMC_FC_GET_VERSION_STR SMC_FASTCALL_NR (SMC_ENTITY_SECURE_MONITOR, 10U)
/* Trusted OS entity calls */
-#define SMC_YC_VIRTIO_GET_DESCR SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 20)
-#define SMC_YC_VIRTIO_START SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 21)
-#define SMC_YC_VIRTIO_STOP SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 22)
+#define SMC_YC_VIRTIO_GET_DESCR SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 20U)
+#define SMC_YC_VIRTIO_START SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 21U)
+#define SMC_YC_VIRTIO_STOP SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 22U)
-#define SMC_YC_VDEV_RESET SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 23)
-#define SMC_YC_VDEV_KICK_VQ SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 24)
-#define SMC_YC_SET_ROT_PARAMS SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 65535)
+#define SMC_YC_VDEV_RESET SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 23U)
+#define SMC_YC_VDEV_KICK_VQ SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 24U)
+#define SMC_YC_SET_ROT_PARAMS SMC_YIELDCALL_NR(SMC_ENTITY_TRUSTED_OS, 65535U)
#endif /* SMCALL_H */
diff --git a/services/spd/trusty/trusty.c b/services/spd/trusty/trusty.c
index c9d73f0..83c14b4 100644
--- a/services/spd/trusty/trusty.c
+++ b/services/spd/trusty/trusty.c
@@ -21,7 +21,10 @@
#include "smcall.h"
/* macro to check if Hypervisor is enabled in the HCR_EL2 register */
-#define HYP_ENABLE_FLAG 0x286001
+#define HYP_ENABLE_FLAG 0x286001U
+
+/* length of Trusty's input parameters (in bytes) */
+#define TRUSTY_PARAMS_LEN_BYTES (4096U * 2)
struct trusty_stack {
uint8_t space[PLATFORM_STACK_SIZE] __aligned(16);
@@ -32,7 +35,7 @@
cpu_context_t cpu_ctx;
void *saved_sp;
uint32_t saved_security_state;
- int fiq_handler_active;
+ int32_t fiq_handler_active;
uint64_t fiq_handler_pc;
uint64_t fiq_handler_cpsr;
uint64_t fiq_handler_sp;
@@ -43,7 +46,7 @@
struct trusty_stack secure_stack;
};
-struct args {
+struct smc_args {
uint64_t r0;
uint64_t r1;
uint64_t r2;
@@ -56,8 +59,8 @@
static struct trusty_cpu_ctx trusty_cpu_ctx[PLATFORM_CORE_COUNT];
-struct args trusty_init_context_stack(void **sp, void *new_stack);
-struct args trusty_context_switch_helper(void **sp, void *smc_params);
+struct smc_args trusty_init_context_stack(void **sp, void *new_stack);
+struct smc_args trusty_context_switch_helper(void **sp, void *smc_params);
static uint32_t current_vmid;
@@ -66,37 +69,37 @@
return &trusty_cpu_ctx[plat_my_core_pos()];
}
-static uint32_t is_hypervisor_mode(void)
+static bool is_hypervisor_mode(void)
{
uint64_t hcr = read_hcr();
- return !!(hcr & HYP_ENABLE_FLAG);
+ return ((hcr & HYP_ENABLE_FLAG) != 0U) ? true : false;
}
-static struct args trusty_context_switch(uint32_t security_state, uint64_t r0,
+static struct smc_args trusty_context_switch(uint32_t security_state, uint64_t r0,
uint64_t r1, uint64_t r2, uint64_t r3)
{
- struct args ret;
+ struct smc_args args, ret_args;
struct trusty_cpu_ctx *ctx = get_trusty_ctx();
struct trusty_cpu_ctx *ctx_smc;
assert(ctx->saved_security_state != security_state);
- ret.r7 = 0;
+ args.r7 = 0;
if (is_hypervisor_mode()) {
/* According to the ARM DEN0028A spec, VMID is stored in x7 */
ctx_smc = cm_get_context(NON_SECURE);
- assert(ctx_smc);
- ret.r7 = SMC_GET_GP(ctx_smc, CTX_GPREG_X7);
+ assert(ctx_smc != NULL);
+ args.r7 = SMC_GET_GP(ctx_smc, CTX_GPREG_X7);
}
/* r4, r5, r6 reserved for future use. */
- ret.r6 = 0;
- ret.r5 = 0;
- ret.r4 = 0;
- ret.r3 = r3;
- ret.r2 = r2;
- ret.r1 = r1;
- ret.r0 = r0;
+ args.r6 = 0;
+ args.r5 = 0;
+ args.r4 = 0;
+ args.r3 = r3;
+ args.r2 = r2;
+ args.r1 = r1;
+ args.r0 = r0;
/*
* To avoid the additional overhead in PSCI flow, skip FP context
@@ -109,9 +112,9 @@
cm_el1_sysregs_context_save(security_state);
ctx->saved_security_state = security_state;
- ret = trusty_context_switch_helper(&ctx->saved_sp, &ret);
+ ret_args = trusty_context_switch_helper(&ctx->saved_sp, &args);
- assert(ctx->saved_security_state == !security_state);
+ assert(ctx->saved_security_state == ((security_state == 0U) ? 1U : 0U));
cm_el1_sysregs_context_restore(security_state);
if (r0 != SMC_FC_CPU_SUSPEND && r0 != SMC_FC_CPU_RESUME)
@@ -119,7 +122,7 @@
cm_set_next_eret_context(security_state);
- return ret;
+ return ret_args;
}
static uint64_t trusty_fiq_handler(uint32_t id,
@@ -127,29 +130,29 @@
void *handle,
void *cookie)
{
- struct args ret;
+ struct smc_args ret;
struct trusty_cpu_ctx *ctx = get_trusty_ctx();
assert(!is_caller_secure(flags));
ret = trusty_context_switch(NON_SECURE, SMC_FC_FIQ_ENTER, 0, 0, 0);
- if (ret.r0) {
+ if (ret.r0 != 0U) {
SMC_RET0(handle);
}
- if (ctx->fiq_handler_active) {
+ if (ctx->fiq_handler_active != 0) {
INFO("%s: fiq handler already active\n", __func__);
SMC_RET0(handle);
}
ctx->fiq_handler_active = 1;
- memcpy(&ctx->fiq_gpregs, get_gpregs_ctx(handle), sizeof(ctx->fiq_gpregs));
+ (void)memcpy(&ctx->fiq_gpregs, get_gpregs_ctx(handle), sizeof(ctx->fiq_gpregs));
ctx->fiq_pc = SMC_GET_EL3(handle, CTX_ELR_EL3);
ctx->fiq_cpsr = SMC_GET_EL3(handle, CTX_SPSR_EL3);
ctx->fiq_sp_el1 = read_ctx_reg(get_sysregs_ctx(handle), CTX_SP_EL1);
write_ctx_reg(get_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_handler_sp);
- cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_handler_pc, ctx->fiq_handler_cpsr);
+ cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_handler_pc, (uint32_t)ctx->fiq_handler_cpsr);
SMC_RET0(handle);
}
@@ -159,9 +162,9 @@
{
struct trusty_cpu_ctx *ctx;
- if (cpu >= PLATFORM_CORE_COUNT) {
+ if (cpu >= (uint64_t)PLATFORM_CORE_COUNT) {
ERROR("%s: cpu %lld >= %d\n", __func__, cpu, PLATFORM_CORE_COUNT);
- return SM_ERR_INVALID_PARAMETERS;
+ return (uint64_t)SM_ERR_INVALID_PARAMETERS;
}
ctx = &trusty_cpu_ctx[cpu];
@@ -182,16 +185,16 @@
static uint64_t trusty_fiq_exit(void *handle, uint64_t x1, uint64_t x2, uint64_t x3)
{
- struct args ret;
+ struct smc_args ret;
struct trusty_cpu_ctx *ctx = get_trusty_ctx();
- if (!ctx->fiq_handler_active) {
+ if (ctx->fiq_handler_active == 0) {
NOTICE("%s: fiq handler not active\n", __func__);
- SMC_RET1(handle, SM_ERR_INVALID_PARAMETERS);
+ SMC_RET1(handle, (uint64_t)SM_ERR_INVALID_PARAMETERS);
}
ret = trusty_context_switch(NON_SECURE, SMC_FC_FIQ_EXIT, 0, 0, 0);
- if (ret.r0 != 1) {
+ if (ret.r0 != 1U) {
INFO("%s(%p) SMC_FC_FIQ_EXIT returned unexpected value, %lld\n",
__func__, handle, ret.r0);
}
@@ -205,10 +208,10 @@
* x1-x4 and x8-x17 need to be restored here because smc_handler64
* corrupts them (el1 code also restored them).
*/
- memcpy(get_gpregs_ctx(handle), &ctx->fiq_gpregs, sizeof(ctx->fiq_gpregs));
+ (void)memcpy(get_gpregs_ctx(handle), &ctx->fiq_gpregs, sizeof(ctx->fiq_gpregs));
ctx->fiq_handler_active = 0;
write_ctx_reg(get_sysregs_ctx(handle), CTX_SP_EL1, ctx->fiq_sp_el1);
- cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_pc, ctx->fiq_cpsr);
+ cm_set_elr_spsr_el3(NON_SECURE, ctx->fiq_pc, (uint32_t)ctx->fiq_cpsr);
SMC_RET0(handle);
}
@@ -222,8 +225,8 @@
void *handle,
u_register_t flags)
{
- struct args ret;
- uint32_t vmid = 0;
+ struct smc_args ret;
+ uint32_t vmid = 0U;
entry_point_info_t *ep_info = bl31_plat_get_next_image_ep_info(SECURE);
/*
@@ -231,10 +234,12 @@
* Verified Boot is not even supported and returning success here
* would not compromise the boot process.
*/
- if (!ep_info && (smc_fid == SMC_YC_SET_ROT_PARAMS)) {
+ if ((ep_info == NULL) && (smc_fid == SMC_YC_SET_ROT_PARAMS)) {
SMC_RET1(handle, 0);
- } else if (!ep_info) {
+ } else if (ep_info == NULL) {
SMC_RET1(handle, SMC_UNK);
+ } else {
+ ; /* do nothing */
}
if (is_caller_secure(flags)) {
@@ -279,12 +284,11 @@
static int32_t trusty_init(void)
{
- void el3_exit(void);
entry_point_info_t *ep_info;
- struct args zero_args = {0};
+ struct smc_args zero_args = {0};
struct trusty_cpu_ctx *ctx = get_trusty_ctx();
uint32_t cpu = plat_my_core_pos();
- int reg_width = GET_RW(read_ctx_reg(get_el3state_ctx(&ctx->cpu_ctx),
+ uint64_t reg_width = GET_RW(read_ctx_reg(get_el3state_ctx(&ctx->cpu_ctx),
CTX_SPSR_EL3));
/*
@@ -292,7 +296,7 @@
* failure.
*/
ep_info = bl31_plat_get_next_image_ep_info(SECURE);
- assert(ep_info);
+ assert(ep_info != NULL);
fpregs_context_save(get_fpregs_ctx(cm_get_context(NON_SECURE)));
cm_el1_sysregs_context_save(NON_SECURE);
@@ -304,7 +308,7 @@
* Adjust secondary cpu entry point for 32 bit images to the
* end of exception vectors
*/
- if ((cpu != 0) && (reg_width == MODE_RW_32)) {
+ if ((cpu != 0U) && (reg_width == MODE_RW_32)) {
INFO("trusty: cpu %d, adjust entry point to 0x%lx\n",
cpu, ep_info->pc + (1U << 5));
cm_set_elr_el3(SECURE, ep_info->pc + (1U << 5));
@@ -314,10 +318,10 @@
fpregs_context_restore(get_fpregs_ctx(cm_get_context(SECURE)));
cm_set_next_eret_context(SECURE);
- ctx->saved_security_state = ~0; /* initial saved state is invalid */
- trusty_init_context_stack(&ctx->saved_sp, &ctx->secure_stack.end);
+ ctx->saved_security_state = ~0U; /* initial saved state is invalid */
+ (void)trusty_init_context_stack(&ctx->saved_sp, &ctx->secure_stack.end);
- trusty_context_switch_helper(&ctx->saved_sp, &zero_args);
+ (void)trusty_context_switch_helper(&ctx->saved_sp, &zero_args);
cm_el1_sysregs_context_restore(NON_SECURE);
fpregs_context_restore(get_fpregs_ctx(cm_get_context(NON_SECURE)));
@@ -328,10 +332,10 @@
static void trusty_cpu_suspend(uint32_t off)
{
- struct args ret;
+ struct smc_args ret;
ret = trusty_context_switch(NON_SECURE, SMC_FC_CPU_SUSPEND, off, 0, 0);
- if (ret.r0 != 0) {
+ if (ret.r0 != 0U) {
INFO("%s: cpu %d, SMC_FC_CPU_SUSPEND returned unexpected value, %lld\n",
__func__, plat_my_core_pos(), ret.r0);
}
@@ -339,10 +343,10 @@
static void trusty_cpu_resume(uint32_t on)
{
- struct args ret;
+ struct smc_args ret;
ret = trusty_context_switch(NON_SECURE, SMC_FC_CPU_RESUME, on, 0, 0);
- if (ret.r0 != 0) {
+ if (ret.r0 != 0U) {
INFO("%s: cpu %d, SMC_FC_CPU_RESUME returned unexpected value, %lld\n",
__func__, plat_my_core_pos(), ret.r0);
}
@@ -359,8 +363,8 @@
{
struct trusty_cpu_ctx *ctx = get_trusty_ctx();
- if (!ctx->saved_sp) {
- trusty_init();
+ if (ctx->saved_sp == NULL) {
+ (void)trusty_init();
} else {
trusty_cpu_resume(1);
}
@@ -398,12 +402,12 @@
entry_point_info_t *ep_info;
uint32_t instr;
uint32_t flags;
- int ret;
+ int32_t ret;
bool aarch32 = false;
/* Get trusty's entry point info */
ep_info = bl31_plat_get_next_image_ep_info(SECURE);
- if (!ep_info) {
+ if (ep_info == NULL) {
INFO("Trusty image missing.\n");
return -1;
}
@@ -416,7 +420,8 @@
} else if (instr >> 8 == 0xd53810U || instr >> 16 == 0x9400U) {
INFO("trusty: Found 64 bit image\n");
} else {
- NOTICE("trusty: Found unknown image, 0x%x\n", instr);
+ ERROR("trusty: Found unknown image, 0x%x\n", instr);
+ return -1;
}
SET_PARAM_HEAD(ep_info, PARAM_EP, VERSION_1, SECURE | EP_ST_ENABLE);
@@ -444,8 +449,9 @@
ret = register_interrupt_type_handler(INTR_TYPE_S_EL1,
trusty_fiq_handler,
flags);
- if (ret)
+ if (ret != 0) {
ERROR("trusty: failed to register fiq handler, ret = %d\n", ret);
+ }
if (aarch32) {
entry_point_info_t *ns_ep_info;