MLK-17044-2 HAB: Add SIP call for ARM64 platform
authorYe Li <ye.li@nxp.com>
Thu, 30 Nov 2017 07:29:54 +0000 (01:29 -0600)
committerYe Li <ye.li@nxp.com>
Wed, 28 Apr 2021 20:37:20 +0000 (13:37 -0700)
When current EL is not EL3, the direct calling to HAB will fail because
CAAM/SNVS can't initialize at non-secure mode. In this case, we use
SIP call to run the HAB in ATF.

Signed-off-by: Ye Li <ye.li@nxp.com>
(cherry picked from commit bca4e251b6083476e987d92c428136a1c81bcb0b)
(cherry picked from commit e31a75cc78ad2d5e6ab5d58851058ab57de1566d)
(cherry picked from commit 6643eac10e3654c62a4acd9c5a4c8c0ac5ee4d0b)
(cherry picked from commit 5542819dfa3e9f0d5dc65117add6ccdcf3ed35ee)

arch/arm/mach-imx/hab.c
include/imx_sip.h

index 08eb851..a39c787 100644 (file)
@@ -14,6 +14,8 @@
 #include <asm/arch/clock.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/mach-imx/hab.h>
+#include <imx_sip.h>
+#include <linux/arm-smccc.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -79,6 +81,18 @@ enum hab_status hab_rvt_report_event(enum hab_status status, uint32_t index,
        hab_rvt_report_event_t *hab_rvt_report_event_func;
        hab_rvt_report_event_func =  (hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT;
 
+#if defined(CONFIG_ARM64)
+       if (current_el() != 3) {
+               /* call sip */
+               struct arm_smccc_res res;
+               arm_smccc_smc(IMX_SIP_HAB, IMX_SIP_HAB_REPORT_EVENT, (unsigned long)index,
+                       (unsigned long)event, (unsigned long)bytes, 0, 0, 0, &res);
+               ret = (enum hab_status)res.a0;
+
+               return ret;
+       }
+#endif
+
        save_gd();
        ret = hab_rvt_report_event_func(status, index, event, bytes);
        restore_gd();
@@ -94,6 +108,17 @@ enum hab_status hab_rvt_report_status(enum hab_config *config,
        hab_rvt_report_status_t *hab_rvt_report_status_func;
        hab_rvt_report_status_func = (hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS;
 
+#if defined(CONFIG_ARM64)
+       if (current_el() != 3) {
+               /* call sip */
+               struct arm_smccc_res res;
+               arm_smccc_smc(IMX_SIP_HAB, IMX_SIP_HAB_REPORT_STATUS,
+                       (unsigned long)config, (unsigned long)state, 0, 0, 0, 0, &res);
+               ret = (enum hab_status)res.a0;
+               return ret;
+       }
+#endif
+
        save_gd();
        ret = hab_rvt_report_status_func(config, state);
        restore_gd();
@@ -107,6 +132,16 @@ enum hab_status hab_rvt_entry(void)
        hab_rvt_entry_t *hab_rvt_entry_func;
        hab_rvt_entry_func = (hab_rvt_entry_t *)HAB_RVT_ENTRY;
 
+#if defined(CONFIG_ARM64)
+       if (current_el() != 3) {
+               /* call sip */
+               struct arm_smccc_res res;
+               arm_smccc_smc(IMX_SIP_HAB, IMX_SIP_HAB_ENTRY, 0, 0, 0, 0, 0, 0, &res);
+               ret = (enum hab_status)res.a0;
+               return ret;
+       }
+#endif
+
        save_gd();
        ret = hab_rvt_entry_func();
        restore_gd();
@@ -120,6 +155,16 @@ enum hab_status hab_rvt_exit(void)
        hab_rvt_exit_t *hab_rvt_exit_func;
        hab_rvt_exit_func =  (hab_rvt_exit_t *)HAB_RVT_EXIT;
 
+#if defined(CONFIG_ARM64)
+       if (current_el() != 3) {
+               /* call sip */
+               struct arm_smccc_res res;
+               arm_smccc_smc(IMX_SIP_HAB, IMX_SIP_HAB_EXIT, 0, 0, 0, 0, 0, 0, &res);
+               ret = (enum hab_status)res.a0;
+               return ret;
+       }
+#endif
+
        save_gd();
        ret = hab_rvt_exit_func();
        restore_gd();
@@ -132,6 +177,14 @@ void hab_rvt_failsafe(void)
        hab_rvt_failsafe_t *hab_rvt_failsafe_func;
        hab_rvt_failsafe_func = (hab_rvt_failsafe_t *)HAB_RVT_FAILSAFE;
 
+#if defined(CONFIG_ARM64)
+       if (current_el() != 3) {
+               /* call sip */
+               arm_smccc_smc(IMX_SIP_HAB, IMX_SIP_HAB_FAILSAFE, 0, 0, 0, 0, 0, 0, NULL);
+               return;
+       }
+#endif
+
        save_gd();
        hab_rvt_failsafe_func();
        restore_gd();
@@ -144,6 +197,17 @@ enum hab_status hab_rvt_check_target(enum hab_target type, const void *start,
        hab_rvt_check_target_t *hab_rvt_check_target_func;
        hab_rvt_check_target_func =  (hab_rvt_check_target_t *)HAB_RVT_CHECK_TARGET;
 
+#if defined(CONFIG_ARM64)
+       if (current_el() != 3) {
+               /* call sip */
+               struct arm_smccc_res res;
+               arm_smccc_smc(IMX_SIP_HAB, IMX_SIP_HAB_CHECK_TARGET, (unsigned long)type,
+                       (unsigned long)start, (unsigned long)bytes, 0, 0, 0, &res);
+               ret = (enum hab_status)res.a0;
+               return ret;
+       }
+#endif
+
        save_gd();
        ret = hab_rvt_check_target_func(type, start, bytes);
        restore_gd();
@@ -158,6 +222,17 @@ void *hab_rvt_authenticate_image(uint8_t cid, ptrdiff_t ivt_offset,
        hab_rvt_authenticate_image_t *hab_rvt_authenticate_image_func;
        hab_rvt_authenticate_image_func = (hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE;
 
+#if defined(CONFIG_ARM64)
+       if (current_el() != 3) {
+               /* call sip */
+               struct arm_smccc_res res;
+               arm_smccc_smc(IMX_SIP_HAB, IMX_SIP_HAB_AUTHENTICATE, (unsigned long)ivt_offset,
+                       (unsigned long)start, (unsigned long)bytes, 0, 0, 0, &res);
+               ret = (void *)res.a0;
+               return ret;
+       }
+#endif
+
        save_gd();
        ret = hab_rvt_authenticate_image_func(cid, ivt_offset, start, bytes, loader);
        restore_gd();
index 26dbe04..4bfc32a 100644 (file)
 #define IMX_SIP_SRC_M4_START   0x00
 #define IMX_SIP_SRC_M4_STARTED 0x01
 
+#define IMX_SIP_HAB            0xC2000007
+#define IMX_SIP_HAB_AUTHENTICATE       0x00
+#define IMX_SIP_HAB_ENTRY              0x01
+#define IMX_SIP_HAB_EXIT               0x02
+#define IMX_SIP_HAB_REPORT_EVENT       0x03
+#define IMX_SIP_HAB_REPORT_STATUS      0x04
+#define IMX_SIP_HAB_FAILSAFE           0x05
+#define IMX_SIP_HAB_CHECK_TARGET       0x06
+
 #endif