refactor(mediatek): update EMI stub implementation
Refactor EMI stub implementation with following changes.
- Move the SiP call handlers to TF-A upstream.
- Move EMI definition used by APUSYS to platform_def.h.
- Remove CONFIG_MTK_APUSYS_EMI_SUPPORT.
Change-Id: I30e1ee7f2ea2d6dc3415adba91cbe310af9b5eeb
Signed-off-by: Yidi Lin <yidilin@chromium.org>
diff --git a/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.c b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.c
index a0d21c6..6edf9c6 100644
--- a/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.c
+++ b/plat/mediatek/drivers/apusys/mt8196/apusys_security_ctrl_plat.c
@@ -6,14 +6,11 @@
#define ENABLE_SMPU_PROTECT (1)
-#if ENABLE_SMPU_PROTECT
-#include "emi.h"
-#endif
-
#include <common/debug.h>
#include <lib/mmio.h>
#include <apusys_security_ctrl_plat.h>
+#include <mtk_bl31_interface.h>
#define APUSYS_SEC_FW_EMI_REGION (23)
@@ -71,9 +68,10 @@
int apusys_plat_setup_sec_mem(void)
{
#if ENABLE_SMPU_PROTECT
- return sip_emi_mpu_set_protection(APU_RESERVE_MEMORY >> EMI_MPU_ALIGN_BITS,
- (APU_RESERVE_MEMORY + APU_RESERVE_SIZE) >> EMI_MPU_ALIGN_BITS,
- APUSYS_SEC_FW_EMI_REGION);
+ return emi_mpu_set_protection(APU_RESERVE_MEMORY >> EMI_MPU_ALIGN_BITS,
+ (APU_RESERVE_MEMORY + APU_RESERVE_SIZE) >>
+ EMI_MPU_ALIGN_BITS,
+ APUSYS_SEC_FW_EMI_REGION);
#else
INFO("%s: Bypass SMPU protection setup.\n", __func__);
return 0;
diff --git a/plat/mediatek/drivers/apusys/mt8196/rules.mk b/plat/mediatek/drivers/apusys/mt8196/rules.mk
index aeb6d3d..67243da 100644
--- a/plat/mediatek/drivers/apusys/mt8196/rules.mk
+++ b/plat/mediatek/drivers/apusys/mt8196/rules.mk
@@ -8,10 +8,6 @@
MODULE := apusys_${MTK_SOC}
-ifeq (${CONFIG_MTK_APUSYS_EMI_SUPPORT}, y)
-PLAT_INCLUDES += -I${MTK_PLAT}/drivers/emi/common
-endif
-
LOCAL_SRCS-y := ${LOCAL_DIR}/apusys_ammu.c
LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_devapc.c
LOCAL_SRCS-y += ${LOCAL_DIR}/apusys_power.c
diff --git a/plat/mediatek/drivers/apusys/rules.mk b/plat/mediatek/drivers/apusys/rules.mk
index 24cc79c..f487c11 100644
--- a/plat/mediatek/drivers/apusys/rules.mk
+++ b/plat/mediatek/drivers/apusys/rules.mk
@@ -13,7 +13,6 @@
PLAT_INCLUDES += -I${LOCAL_DIR} -I${LOCAL_DIR}/${MTK_SOC} -I${LOCAL_DIR}/apusys_rv/2.0
$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_CE_SUPPORT))
-$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_EMI_SUPPORT))
$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_LOGTOP_SUPPORT))
$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT))
$(eval $(call add_defined_option,CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT))
diff --git a/plat/mediatek/drivers/emi/common/emi.h b/plat/mediatek/drivers/emi/common/emi.h
deleted file mode 100644
index eb2a0d3..0000000
--- a/plat/mediatek/drivers/emi/common/emi.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Copyright (c) 2025, Mediatek Inc. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef EMI_H
-#define EMI_H
-
-#include <stdint.h>
-
-#define EMI_MPU_ALIGN_BITS 12
-
-uint64_t sip_emi_mpu_set_protection(u_register_t start, u_register_t end, u_register_t region);
-
-#endif /* EMI_H */
diff --git a/plat/mediatek/drivers/emi/emi_ctrl.c b/plat/mediatek/drivers/emi/emi_ctrl.c
new file mode 100644
index 0000000..00ac7df
--- /dev/null
+++ b/plat/mediatek/drivers/emi/emi_ctrl.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+
+#include <lib/mtk_init/mtk_init.h>
+#include <mtk_bl31_interface.h>
+#include <mtk_sip_svc.h>
+
+#define NO_PROTECTION 0
+#define SEC_RW 1
+#define SEC_RW_NSEC_R 2
+#define SEC_RW_NSEC_W 3
+#define SEC_R_NSEC_R 4
+#define FORBIDDEN 5
+#define SEC_R_NSEC_RW 6
+
+#define EMIMPU_SET 0
+#define EMIMPU_CLEAR 1
+#define EMIMPU_READ 2
+#define EMIMPU_SLVERR 3
+#define EMIDBG_DUMP 4
+#define EMIDBG_MSG 5
+#define AID_TABLE_SET 6
+#define EMIMPU_CLEAR_MD 7
+#define KP_SET 8
+#define KP_CLEAR 9
+
+#define EMIMPU_READ_SA 0
+#define EMIMPU_READ_EA 1
+#define EMIMPU_READ_APC 2
+#define EMIMPU_READ_ENABLE 3
+#define EMIMPU_READ_AID 4
+#define EMIMPU_CHECK_NS_CPU 5
+#define EMIMPU_CHECK_REGION_INFO 6
+#define EMIMPU_PAGE_BASE_REGION 7
+#define SLBMPU_CLEAR 8
+#define EMIMPU_CHECK_HP_MOD 9
+#define EMI_CLE 10
+#define SLC_PARITY_SELECT 11
+#define SLC_PARITY_CLEAR 12
+
+static uint64_t emi_mpu_read_by_type(unsigned int reg_type, unsigned int region,
+ unsigned int aid_shift, struct smccc_res *smccc_ret)
+{
+ switch (reg_type) {
+ case EMIMPU_READ_SA:
+ return emi_mpu_read_addr(region, 0x0);
+ case EMIMPU_READ_EA:
+ return emi_mpu_read_addr(region, 0x8);
+ case EMIMPU_READ_ENABLE:
+ return emi_mpu_read_enable(region);
+ case EMIMPU_READ_AID:
+ return emi_mpu_read_aid(region, aid_shift);
+ case EMIMPU_CHECK_REGION_INFO:
+ return emi_mpu_check_region_info(region, &smccc_ret->a1, &smccc_ret->a2);
+ case EMIMPU_CHECK_NS_CPU:
+ return emi_mpu_check_ns_cpu();
+ case EMIMPU_PAGE_BASE_REGION:
+ return emi_mpu_page_base_region();
+ case EMIMPU_CHECK_HP_MOD:
+ return emi_mpu_smc_hp_mod_check();
+ default:
+ return 0;
+ }
+}
+
+static u_register_t sip_emidbg_control(u_register_t op_id,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
+ void *handle,
+ struct smccc_res *smccc_ret)
+{
+ enum mtk_bl31_status ret;
+
+ switch (op_id) {
+ case EMIDBG_DUMP:
+ return MTK_SIP_E_SUCCESS;
+ case EMIDBG_MSG:
+ return MTK_SIP_E_SUCCESS;
+#ifdef MTK_EMI_MPU_DEBUG
+ case EMIMPU_READ:
+ ret = emi_mpu_read_by_type((unsigned int)x2, (unsigned int)x3,
+ (unsigned int)x4, smccc_ret);
+ break;
+#endif
+ case EMIMPU_CLEAR_MD:
+ ret = emi_clear_md_violation();
+ break;
+ case KP_CLEAR:
+ ret = emi_kp_clear_violation((unsigned int)x2);
+ break;
+#ifdef CONFIG_MTK_SLB_MPU_CLEAR
+ case SLBMPU_CLEAR:
+ ret = slb_clear_violation((unsigned int)x2);
+ break;
+#endif
+#ifdef CONFIG_MTK_EMI_CLEAR
+ case EMI_CLEAR:
+ ret = emi_clear_violation((unsigned int)x2, (unsigned int)x3);
+ break;
+#endif
+#ifdef CONFIG_MTK_SLC_PARITY
+ case SLC_PARITY_SELECT:
+ ret = slc_parity_select((unsigned int)x2, (unsigned int)x3);
+ break;
+ case SLC_PARITY_CLEAR:
+ ret = slc_parity_clear((unsigned int)x2);
+ break;
+#endif
+ default:
+ return MTK_SIP_E_NOT_SUPPORTED;
+ }
+
+ return mtk_bl31_map_to_sip_error(ret);
+}
+DECLARE_SMC_HANDLER(MTK_SIP_EMIDBG_CONTROL, sip_emidbg_control);
+
+static u_register_t sip_emimpu_control(u_register_t op_id,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
+ void *handle,
+ struct smccc_res *smccc_ret)
+{
+ enum mtk_bl31_status ret;
+
+ switch (op_id) {
+ case EMIMPU_SET:
+ ret = emi_mpu_set_protection((uint32_t)x2, (uint32_t)x3, (unsigned int)x4);
+ break;
+ case AID_TABLE_SET:
+ ret = emi_mpu_set_aid((unsigned int)x2, (unsigned int)x3);
+ break;
+ case EMIMPU_READ:
+ ret = emi_mpu_read_by_type((unsigned int)x2, (unsigned int)x3,
+ (unsigned int)x4, smccc_ret);
+ break;
+ case KP_SET:
+ ret = emi_kp_set_protection((size_t)x2, (size_t)x3, (unsigned int)x4);
+ break;
+ case KP_CLEAR:
+ ret = emi_kp_clear_violation((unsigned int)x2);
+ break;
+ default:
+ return MTK_SIP_E_NOT_SUPPORTED;
+ }
+
+ return mtk_bl31_map_to_sip_error(ret);
+}
+DECLARE_SMC_HANDLER(MTK_SIP_BL_EMIMPU_CONTROL, sip_emimpu_control);
+
+static u_register_t sip_tee_emimpu_control(u_register_t op_id,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
+ void *handle,
+ struct smccc_res *smccc_ret)
+{
+ enum mtk_bl31_status ret;
+
+ switch (op_id) {
+ case EMIMPU_SET:
+ ret = emi_mpu_set_protection((uint32_t)x2, (uint32_t)x3, (unsigned int)x4);
+ break;
+ case EMIMPU_CLEAR:
+ ret = emi_clear_protection((unsigned int)x2);
+ break;
+ default:
+ return MTK_SIP_E_NOT_SUPPORTED;
+ }
+
+ return mtk_bl31_map_to_sip_error(ret);
+}
+DECLARE_SMC_HANDLER(MTK_SIP_TEE_EMI_MPU_CONTROL, sip_tee_emimpu_control);
+
+int emi_mpu_init(void)
+{
+ INFO("[%s] emi mpu initialization\n", __func__);
+
+ emi_protection_init();
+
+ return 0;
+}
+MTK_PLAT_SETUP_0_INIT(emi_mpu_init);
diff --git a/plat/mediatek/drivers/emi/emi_stub.c b/plat/mediatek/drivers/emi/emi_stub.c
index 3682bf7..abe559a 100644
--- a/plat/mediatek/drivers/emi/emi_stub.c
+++ b/plat/mediatek/drivers/emi/emi_stub.c
@@ -3,13 +3,95 @@
*
* SPDX-License-Identifier: BSD-3-Clause
*/
-#include <common/debug.h>
-#include "common/emi.h"
-#include <mtk_sip_svc.h>
+#include <mtk_bl31_interface.h>
-uint64_t sip_emi_mpu_set_protection(u_register_t start, u_register_t end,
- u_register_t region)
+uint64_t emi_mpu_read_addr(unsigned int region, unsigned int offset)
+{
+ return 0;
+}
+
+uint64_t emi_mpu_read_enable(unsigned int region)
+{
+ return 0;
+}
+
+uint64_t emi_mpu_read_aid(unsigned int region, unsigned int aid_shift)
+{
+ return 0;
+}
+
+uint64_t emi_mpu_check_ns_cpu(void)
+{
+ return MTK_BL31_STATUS_NOT_SUPPORTED;
+}
+
+enum mtk_bl31_status emi_kp_set_protection(size_t start, size_t end, unsigned int region)
+{
+ return MTK_BL31_STATUS_NOT_SUPPORTED;
+}
+
+enum mtk_bl31_status emi_kp_clear_violation(unsigned int emiid)
+{
+ return MTK_BL31_STATUS_NOT_SUPPORTED;
+}
+
+enum mtk_bl31_status emi_clear_protection(unsigned int region)
+{
+ return MTK_BL31_STATUS_NOT_SUPPORTED;
+}
+
+enum mtk_bl31_status emi_clear_md_violation(void)
+{
+ return MTK_BL31_STATUS_NOT_SUPPORTED;
+}
+
+uint64_t emi_mpu_check_region_info(unsigned int region, uint64_t *sa, uint64_t *ea)
+{
+ return 0;
+}
+
+uint64_t emi_mpu_page_base_region(void)
+{
+ return 0;
+}
+
+uint64_t emi_mpu_smc_hp_mod_check(void)
+{
+ return 0;
+}
+
+enum mtk_bl31_status slb_clear_violation(unsigned int id)
+{
+ return MTK_BL31_STATUS_NOT_SUPPORTED;
+}
+
+enum mtk_bl31_status emi_clear_violation(unsigned int id, unsigned int type)
+{
+ return MTK_BL31_STATUS_NOT_SUPPORTED;
+}
+
+enum mtk_bl31_status slc_parity_select(unsigned int id, unsigned int port)
+{
+ return MTK_BL31_STATUS_NOT_SUPPORTED;
+}
+
+enum mtk_bl31_status slc_parity_clear(unsigned int id)
+{
+ return MTK_BL31_STATUS_NOT_SUPPORTED;
+}
+
+enum mtk_bl31_status emi_mpu_set_aid(unsigned int region, unsigned int num)
+{
+ return MTK_BL31_STATUS_NOT_SUPPORTED;
+}
+
+void emi_protection_init(void)
+{
+}
+
+enum mtk_bl31_status emi_mpu_set_protection(uint32_t start, uint32_t end,
+ unsigned int region)
{
- return MTK_SIP_E_NOT_SUPPORTED;
+ return MTK_BL31_STATUS_NOT_SUPPORTED;
}
diff --git a/plat/mediatek/drivers/emi/rules.mk b/plat/mediatek/drivers/emi/rules.mk
index 9f462bb..ffe1817 100644
--- a/plat/mediatek/drivers/emi/rules.mk
+++ b/plat/mediatek/drivers/emi/rules.mk
@@ -8,8 +8,9 @@
MODULE := emi
+LOCAL_SRCS-y := $(LOCAL_DIR)/emi_ctrl.c
ifeq ($(MTKLIB_PATH),)
-LOCAL_SRCS-y := $(LOCAL_DIR)/emi_stub.c
+LOCAL_SRCS-y += $(LOCAL_DIR)/emi_stub.c
endif
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/include/mtk_bl31_interface.h b/plat/mediatek/include/mtk_bl31_interface.h
index e124cfe..2216553 100644
--- a/plat/mediatek/include/mtk_bl31_interface.h
+++ b/plat/mediatek/include/mtk_bl31_interface.h
@@ -8,6 +8,7 @@
#define __MTK_BL31_INTERFACE_H__
#include <stdbool.h>
+#include <stddef.h>
#include <stdint.h>
enum mtk_bl31_status {
@@ -59,4 +60,25 @@
bool ufs_is_clk_status_off(void);
void ufs_set_clk_status(bool on);
+/* EMI interfaces */
+uint64_t emi_mpu_read_addr(unsigned int region, unsigned int offset);
+uint64_t emi_mpu_read_enable(unsigned int region);
+uint64_t emi_mpu_read_aid(unsigned int region, unsigned int aid_shift);
+uint64_t emi_mpu_check_ns_cpu(void);
+enum mtk_bl31_status emi_mpu_set_protection(uint32_t start, uint32_t end,
+ unsigned int region);
+enum mtk_bl31_status emi_kp_set_protection(size_t start, size_t end, unsigned int region);
+enum mtk_bl31_status emi_kp_clear_violation(unsigned int emiid);
+enum mtk_bl31_status emi_clear_protection(unsigned int region);
+enum mtk_bl31_status emi_clear_md_violation(void);
+uint64_t emi_mpu_check_region_info(unsigned int region, uint64_t *sa, uint64_t *ea);
+uint64_t emi_mpu_page_base_region(void);
+uint64_t emi_mpu_smc_hp_mod_check(void);
+enum mtk_bl31_status slb_clear_violation(unsigned int id);
+enum mtk_bl31_status emi_clear_violation(unsigned int id, unsigned int type);
+enum mtk_bl31_status slc_parity_select(unsigned int id, unsigned int port);
+enum mtk_bl31_status slc_parity_clear(unsigned int id);
+enum mtk_bl31_status emi_mpu_set_aid(unsigned int region, unsigned int num);
+void emi_protection_init(void);
+
#endif /* __MTK_BL31_INTERFACE_H__ */
diff --git a/plat/mediatek/mt8196/include/platform_def.h b/plat/mediatek/mt8196/include/platform_def.h
index ad0bf68..fb5212a 100644
--- a/plat/mediatek/mt8196/include/platform_def.h
+++ b/plat/mediatek/mt8196/include/platform_def.h
@@ -230,6 +230,7 @@
#define SUB_EMI_APB_BASE (IO_PHYS + 0x00529000)
#define SUB_INFRA_EMI_DEBUG_CFG_BASE (IO_PHYS + 0x00525000)
#define SUB_INFRACFG_AO_MEM_BASE (IO_PHYS + 0x00504000)
+#define EMI_MPU_ALIGN_BITS 12
/*******************************************************************************
* System counter frequency related constants
diff --git a/plat/mediatek/mt8196/plat_config.mk b/plat/mediatek/mt8196/plat_config.mk
index 7412756..35a3901 100644
--- a/plat/mediatek/mt8196/plat_config.mk
+++ b/plat/mediatek/mt8196/plat_config.mk
@@ -27,7 +27,6 @@
CONFIG_ARCH_ARM_V9 := y
CONFIG_MTK_APUSYS_CE_SUPPORT := y
-CONFIG_MTK_APUSYS_EMI_SUPPORT := y
CONFIG_MTK_APUSYS_LOGTOP_SUPPORT := y
CONFIG_MTK_APUSYS_RV_APUMMU_SUPPORT := y
CONFIG_MTK_APUSYS_RV_COREDUMP_WA_SUPPORT := y