diff --git a/arch/arm/cpu/armv7/qca/common/scm.c b/arch/arm/cpu/armv7/qca/common/scm.c index d519848c08..d8fd523ed1 100644 --- a/arch/arm/cpu/armv7/qca/common/scm.c +++ b/arch/arm/cpu/armv7/qca/common/scm.c @@ -417,6 +417,26 @@ void __attribute__ ((noreturn)) execute_tzt(void *entry_addr) static uint8_t tz_buf[CONFIG_SYS_CACHELINE_SIZE] __aligned(CONFIG_SYS_CACHELINE_SIZE); #ifndef CONFIG_QCA_DISABLE_SCM +int qca_scm_get_secure_state(void *buf, size_t len) +{ + int ret; + if (is_scm_armv8()) + { + struct qca_scm_desc desc = {0}; + desc.arginfo = QCA_SCM_ARGS(0); + + ret = scm_call_64(SCM_SVC_INFO, GET_SECURE_STATE_CMD, &desc); + memcpy(buf, &desc.ret, len); + } + else + { + ret = scm_call(SCM_SVC_INFO, GET_SECURE_STATE_CMD, NULL, 0, + buf, len); + } + + return ret; +} + int qca_scm_call(u32 svc_id, u32 cmd_id, void *buf, size_t len) { int ret = 0; @@ -676,6 +696,10 @@ int qti_pas_and_auth_reset(u32 peripheral) #endif #else +int qca_scm_get_secure_state(void *buf, size_t len) +{ + return 0; +} int qca_scm_call(u32 svc_id, u32 cmd_id, void *buf, size_t len) { return 0; diff --git a/arch/arm/include/asm/arch-qca-common/qca_common.h b/arch/arm/include/asm/arch-qca-common/qca_common.h index f97133e41b..12ae9b8d71 100644 --- a/arch/arm/include/asm/arch-qca-common/qca_common.h +++ b/arch/arm/include/asm/arch-qca-common/qca_common.h @@ -114,6 +114,7 @@ int bring_sec_core_up(unsigned int cpuid, unsigned int entry, unsigned int arg); int is_secondary_core_off(unsigned int cpuid); int smem_read_cpu_count(void); int get_soc_hw_version(void); +int is_atf_enabled(void); struct dumpinfo_t{ char name[16]; /* use only file name in 8.3 format */ diff --git a/arch/arm/include/asm/arch-qca-common/scm.h b/arch/arm/include/asm/arch-qca-common/scm.h index 2088e388ce..5192f1d24b 100644 --- a/arch/arm/include/asm/arch-qca-common/scm.h +++ b/arch/arm/include/asm/arch-qca-common/scm.h @@ -34,6 +34,7 @@ #define SCM_SVC_ID_SHIFT 0xA #define IS_CALL_AVAIL_CMD 0x1 #define PART_INFO_CMD 0x22 +#define GET_SECURE_STATE_CMD 0x4 #ifdef CONFIG_IPQ_BT_SUPPORT #define SCM_PAS_INIT_IMAGE_CMD 0x1 @@ -135,6 +136,7 @@ int qca_scm_part_info(void *cmd_buf, size_t cmd_len); s32 qca_scm_call_atomic_ver2_32(u32 svc, u32 cmd, u32 arg1, u32 arg2); int qca_scm_auth_kernel(void *cmd_buf, size_t cmd_len); int is_scm_sec_auth_available(u32 svc_id, u32 cmd_id); +int qca_scm_get_secure_state(void *buf, size_t len); #ifdef CONFIG_IPQ_TZT int qca_scm(u32 svc_id, u32 cmd_id, u32 ownr_id, u32 *addr, u32 len); #endif diff --git a/board/qca/arm/common/board_init.c b/board/qca/arm/common/board_init.c index 7041ed78b1..68eca0cf0f 100644 --- a/board/qca/arm/common/board_init.c +++ b/board/qca/arm/common/board_init.c @@ -53,6 +53,12 @@ loff_t board_env_offset; loff_t board_env_range; loff_t board_env_size; +static enum atf_status_t { + ATF_STATE_DISABLED, + ATF_STATE_ENABLED, + ATF_STATE_UNKNOWN, +} atf_status = ATF_STATE_UNKNOWN; + __weak int ipq_board_usb_init(void) { @@ -309,6 +315,29 @@ void get_kernel_fs_part_details(void) return; } +int is_atf_enabled(void) +{ + int ret; + u32 val[2] = {0}; + + if (likely(atf_status != ATF_STATE_UNKNOWN)) + return (atf_status == ATF_STATE_ENABLED); + + /* + * Understanding is this smc call will not be implemented in ATF in + * future as well. If its implemented, Bit 7 should be made to 1. + */ + atf_status = ATF_STATE_DISABLED; + ret = is_scm_sec_auth_available(SCM_SVC_INFO, GET_SECURE_STATE_CMD); + if (ret > 0) { + ret = qca_scm_get_secure_state(&val, sizeof(val)); + if ((ret == 0) && (val[0] & 0x80)) + atf_status = ATF_STATE_ENABLED; + } + + return (atf_status == ATF_STATE_ENABLED); +} + /* * This function is called in the very beginning. * Retreive the machtype info from SMEM and map the board specific diff --git a/board/qca/arm/common/cmd_bootqca.c b/board/qca/arm/common/cmd_bootqca.c index 90d6ef50d4..ed289060db 100644 --- a/board/qca/arm/common/cmd_bootqca.c +++ b/board/qca/arm/common/cmd_bootqca.c @@ -897,7 +897,7 @@ static int do_bootipq(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) || if atf is enable in env ,do_boot_signedimg is skip. || Note: This features currently support in ipq50XX. */ - if (ret == 0 && buf == 1 && !getenv("atf")) { + if (ret == 0 && buf == 1 && !is_atf_enabled()) { ret = do_boot_signedimg(cmdtp, flag, argc, argv); } else if (ret == 0 || ret == -EOPNOTSUPP) { ret = do_boot_unsignedimg(cmdtp, flag, argc, argv); diff --git a/board/qca/arm/common/fdt_fixup.c b/board/qca/arm/common/fdt_fixup.c index ca56a84070..54e3c40e97 100644 --- a/board/qca/arm/common/fdt_fixup.c +++ b/board/qca/arm/common/fdt_fixup.c @@ -1067,8 +1067,7 @@ int ft_board_setup(void *blob, bd_t *bd) s = getenv("qce_fixed_key"); if (s) fdt_fixup_set_qce_fixed_key(blob); - s = getenv("atf"); - if (s) { + if (is_atf_enabled()) { fdt_fixup_set_qca_cold_reboot_enable(blob); fdt_fixup_wcss_rproc_for_atf(blob); } diff --git a/board/qca/arm/ipq6018/ipq6018.c b/board/qca/arm/ipq6018/ipq6018.c index 3756b1f7fc..2e98fa7c34 100644 --- a/board/qca/arm/ipq6018/ipq6018.c +++ b/board/qca/arm/ipq6018/ipq6018.c @@ -1266,7 +1266,7 @@ void reset_cpu(unsigned long a) { reset_crashdump(); - if(getenv("atf")) + if(is_atf_enabled()) atf_reset(); else psci_sys_reset();