Merge "fix(xlat): change MT_DEVICE to map to nGnRnE" into integration
diff --git a/docs/components/ven-el3-service.rst b/docs/components/ven-el3-service.rst
index 13449ba..8be1b39 100644
--- a/docs/components/ven-el3-service.rst
+++ b/docs/components/ven-el3-service.rst
@@ -32,9 +32,13 @@
+-----------------------------------+ Measurement Framework | | 2 - 15 are reserved for future expansion. |
| 0xC7000020 - 0xC700002F (SMC64) | (PMF) | |
+-----------------------------------+-----------------------+---------------------------------------------+
-| 0x87000030 - 0x8700FFFF (SMC32) | Reserved | | reserved for future expansion |
+| 0x87000030 - 0x8700003F (SMC32) | ACS (Architecture | | 0 in use. |
++-----------------------------------+ Compliance Suite) SMC | | 1 - 15 are reserved for future expansion. |
+| 0xC7000030 - 0xC700003F (SMC64) | handler | |
++-----------------------------------+-----------------------+---------------------------------------------+
+| 0x87000040 - 0x8700FFFF (SMC32) | Reserved | | reserved for future expansion |
+-----------------------------------+ | |
-| 0xC7000030 - 0xC700FFFF (SMC64) | | |
+| 0xC7000040 - 0xC700FFFF (SMC64) | | |
+-----------------------------------+-----------------------+---------------------------------------------+
Source definitions for vendor-specific EL3 Monitor Service Calls used by TF-A are located in
@@ -45,6 +49,8 @@
+============================+============================+================================+
| 1 | 0 | Added Debugfs and PMF services.|
+----------------------------+----------------------------+--------------------------------+
+| 1 | 1 | Added ACS SMC handler services.|
++----------------------------+----------------------------+--------------------------------+
*Table 1: Showing different versions of Vendor-specific service and changes done with each version*
@@ -71,8 +77,16 @@
The optional DebugFS interface is accessed through Vendor specific EL3 service. Refer
to :ref:`DebugFS interface` documentation for further details and usage.
+Architecture Compliance Suite (ACS) SMC handler
+-----------------------------------------------
+
+The Architecture Compliance Suite (ACS) SMC handler allows callers to branch
+to their ACS EL3 code based on their respective use-cases.
+For more details on System ACS, `System ACS`_.
+
--------------
-*Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2024-2025, Arm Limited and Contributors. All rights reserved.*
+.. _System ACS: https://developer.arm.com/Architectures/Architectural%20Compliance%20Suite
.. _SMC Calling Convention: https://developer.arm.com/docs/den0028/latest
diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst
index 32daf1e..1b3568e 100644
--- a/docs/getting_started/build-options.rst
+++ b/docs/getting_started/build-options.rst
@@ -1509,6 +1509,11 @@
information using HOB defined in `Platform Initialization specification`_.
This defaults to ``0``.
+- ``ENABLE_ACS_SMC``: When set to ``1``, this enables support for ACS SMC
+ handler code to handle SMC calls from the Architecture Compliance Suite. The
+ handler is intentionally empty to reserve the SMC section and allow
+ project-specific implementations in future ACS use cases.
+
Firmware update options
~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/plat/xilinx-versal-net.rst b/docs/plat/xilinx-versal-net.rst
index d22a46d..acb67a6 100644
--- a/docs/plat/xilinx-versal-net.rst
+++ b/docs/plat/xilinx-versal-net.rst
@@ -24,6 +24,11 @@
make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal_net VERSAL_NET_CONSOLE=dcc bl31
```
+To build TF-A with SDEI_SUPPORT:
+```bash
+make RESET_TO_BL31=1 CROSS_COMPILE=aarch64-none-elf- PLAT=versal_net SDEI_SUPPORT=1 bl31
+```
+
Xilinx Versal NET platform specific build options
-------------------------------------------------
diff --git a/docs/plat/xilinx-versal.rst b/docs/plat/xilinx-versal.rst
index 7185d91..a654a0b 100644
--- a/docs/plat/xilinx-versal.rst
+++ b/docs/plat/xilinx-versal.rst
@@ -59,6 +59,57 @@
- `6` : SGI 6 (Default)
- `7` : SGI 7
+Configurable Stack Size
+-----------------------
+
+The stack size in TF-A for the Versal platform is configurable.
+The custom package can define the desired stack size as per the requirement in
+the makefile as follows:
+
+.. code-block:: shell
+
+ PLATFORM_STACK_SIZE := <value>
+
+ $(eval $(call add_define,PLATFORM_STACK_SIZE))
+
+CUSTOM SIP Service Support
+--------------------------
+
+- Dedicated SMC FID ``VERSAL_SIP_SVC_CUSTOM(0x82002000)`` (32-bit) /
+ ``(0xC2002000)`` (64-bit) is used by a custom package for providing
+ CUSTOM SIP service.
+
+- By default, the platform provides a bare minimum definition for
+ ``custom_smc_handler`` in this service.
+
+- To use this service, the custom package should implement its own SMC handler
+ named ``custom_smc_handler``. Once the custom package is included in the
+ TF-A build, its definition of ``custom_smc_handler`` is enabled.
+
+Custom Package Makefile Fragment Inclusion in TF-A Build
+--------------------------------------------------------
+
+- Custom package is not directly part of the TF-A source.
+
+- ``<CUSTOM_PKG_PATH>`` is the location where the user clones a
+ custom package locally.
+
+- The custom package must implement a makefile fragment named
+ ``custom_pkg.mk`` so it can be included in the TF-A build.
+
+- ``custom_pkg.mk`` should specify all the rules to include custom package
+ specific header files, dependent libraries, and source files that are
+ required to be part of the TF-A build.
+
+- When ``<CUSTOM_PKG_PATH>`` is specified in the TF-A build command,
+ ``custom_pkg.mk`` is included from ``<CUSTOM_PKG_PATH>``.
+
+- Example TF-A build command:
+
+.. code-block:: shell
+
+ make CROSS_COMPILE=aarch64-none-elf- PLAT=versal RESET_TO_BL31=1 bl31 CUSTOM_PKG_PATH=<...>
+
# PLM->TF-A Parameter Passing
------------------------------
The PLM populates a data structure with image information for the TF-A. The TF-A
diff --git a/drivers/st/bsec/bsec3.c b/drivers/st/bsec/bsec3.c
index 3fdaf16..03d8928 100644
--- a/drivers/st/bsec/bsec3.c
+++ b/drivers/st/bsec/bsec3.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2024-2025, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -30,18 +30,6 @@
#define BSEC_OTP_BANK_SHIFT U(5)
#define BSEC_TIMEOUT_VALUE U(0x800000) /* ~7sec @1.2GHz */
-/* Magic use to indicated valid SHADOW = 'B' 'S' 'E' 'C' */
-#define BSEC_MAGIC U(0x42534543)
-
-#define OTP_MAX_SIZE (STM32MP2_OTP_MAX_ID + U(1))
-
-struct bsec_shadow {
- uint32_t magic;
- uint32_t state;
- uint32_t value[OTP_MAX_SIZE];
- uint32_t status[OTP_MAX_SIZE];
-};
-
static uint32_t otp_bank(uint32_t otp)
{
if (otp > STM32MP2_OTP_MAX_ID) {
@@ -167,7 +155,7 @@
ERROR("BSEC reset critical error 0x%x\n", status);
panic();
}
- if ((status & BSEC_OTPSR_FUSEOK) != BSEC_OTPSR_FUSEOK) {
+ if ((status & BSEC_OTPSR_INIT_DONE) != BSEC_OTPSR_INIT_DONE) {
ERROR("BSEC reset critical error 0x%x\n", status);
panic();
}
@@ -467,8 +455,8 @@
uint32_t status = bsec_get_status();
uint32_t bsec_sr = mmio_read_32(BSEC_BASE + BSEC_SR);
- if ((status & BSEC_OTPSR_FUSEOK) == BSEC_OTPSR_FUSEOK) {
- /* NVSTATE is only valid if FUSEOK */
+ if ((status & BSEC_OTPSR_INIT_DONE) == BSEC_OTPSR_INIT_DONE) {
+ /* NVSTATE is only valid if INIT_DONE */
uint32_t nvstates = (bsec_sr & BSEC_SR_NVSTATE_MASK) >> BSEC_SR_NVSTATE_SHIFT;
if (nvstates == BSEC_SR_NVSTATE_OPEN) {
diff --git a/drivers/st/crypto/stm32_saes.c b/drivers/st/crypto/stm32_saes.c
index f4da571..547ff89 100644
--- a/drivers/st/crypto/stm32_saes.c
+++ b/drivers/st/crypto/stm32_saes.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2022-2025, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -211,9 +211,11 @@
uint64_t timeout;
/* Reset IP */
- mmio_setbits_32(ctx->base + _SAES_CR, _SAES_CR_IPRST);
- udelay(SAES_RESET_DELAY);
- mmio_clrbits_32(ctx->base + _SAES_CR, _SAES_CR_IPRST);
+ if ((mmio_read_32(ctx->base + _SAES_SR) & _SAES_SR_BUSY) != _SAES_SR_BUSY) {
+ mmio_setbits_32(ctx->base + _SAES_CR, _SAES_CR_IPRST);
+ udelay(SAES_RESET_DELAY);
+ mmio_clrbits_32(ctx->base + _SAES_CR, _SAES_CR_IPRST);
+ }
timeout = timeout_init_us(SAES_TIMEOUT_US);
while ((mmio_read_32(ctx->base + _SAES_SR) & _SAES_SR_BUSY) == _SAES_SR_BUSY) {
diff --git a/drivers/st/ddr/stm32mp2_ddr_helpers.c b/drivers/st/ddr/stm32mp2_ddr_helpers.c
index a2a4082..8efb7cf 100644
--- a/drivers/st/ddr/stm32mp2_ddr_helpers.c
+++ b/drivers/st/ddr/stm32mp2_ddr_helpers.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2024-2025, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -363,8 +363,6 @@
mmio_write_32(stm32mp_rcc_base() + RCC_DDRCPCFGR,
RCC_DDRCPCFGR_DDRCPLPEN | RCC_DDRCPCFGR_DDRCPEN);
- /* TODO: check if ddr_sr_exit_loop() is needed here */
-
return 0;
}
@@ -390,13 +388,6 @@
return ddr_sr_exit_loop();
}
-uint32_t ddr_get_io_calibration_val(void)
-{
- /* TODO create related service */
-
- return 0U;
-}
-
int ddr_sr_entry(bool standby)
{
int ret = -EINVAL;
diff --git a/drivers/st/ddr/stm32mp2_ram.c b/drivers/st/ddr/stm32mp2_ram.c
index 95f05e7..2b0e317 100644
--- a/drivers/st/ddr/stm32mp2_ram.c
+++ b/drivers/st/ddr/stm32mp2_ram.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2021-2025, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
*/
@@ -142,9 +142,6 @@
ERROR("DDR rw test: can't access memory @ 0x%lx\n", uret);
panic();
}
-
- /* TODO Restore area overwritten by training */
- //stm32_restore_ddr_training_area();
} else {
size_t retsize;
diff --git a/drivers/st/ddr/stm32mp_ddr.c b/drivers/st/ddr/stm32mp_ddr.c
index 98968d5..df2cd83 100644
--- a/drivers/st/ddr/stm32mp_ddr.c
+++ b/drivers/st/ddr/stm32mp_ddr.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022-2024, STMicroelectronics - All Rights Reserved
+ * Copyright (C) 2022-2025, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -277,9 +277,9 @@
/* Toggle rfshctl3.refresh_update_level */
rfshctl3 = mmio_read_32((uintptr_t)&ctl->rfshctl3);
if ((rfshctl3 & refresh_update_level) == refresh_update_level) {
- mmio_setbits_32((uintptr_t)&ctl->rfshctl3, refresh_update_level);
- } else {
mmio_clrbits_32((uintptr_t)&ctl->rfshctl3, refresh_update_level);
+ } else {
+ mmio_setbits_32((uintptr_t)&ctl->rfshctl3, refresh_update_level);
refresh_update_level = 0U;
}
@@ -293,7 +293,7 @@
if (timeout_elapsed(timeout)) {
panic();
}
- } while ((rfshctl3 & DDRCTRL_RFSHCTL3_REFRESH_UPDATE_LEVEL) != refresh_update_level);
+ } while ((rfshctl3 & DDRCTRL_RFSHCTL3_REFRESH_UPDATE_LEVEL) == refresh_update_level);
VERBOSE("[0x%lx] rfshctl3 = 0x%x\n", (uintptr_t)&ctl->rfshctl3, rfshctl3);
}
diff --git a/drivers/st/iwdg/stm32_iwdg.c b/drivers/st/iwdg/stm32_iwdg.c
index 74451d7..3d78c20 100644
--- a/drivers/st/iwdg/stm32_iwdg.c
+++ b/drivers/st/iwdg/stm32_iwdg.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2017-2025, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -33,7 +33,6 @@
uintptr_t base;
unsigned long clock;
uint8_t flags;
- int num_irq;
};
static struct stm32_iwdg_instance stm32_iwdg[IWDG_MAX_INSTANCE];
diff --git a/drivers/st/regulator/regulator_fixed.c b/drivers/st/regulator/regulator_fixed.c
index 6c9d3b1..6b14b5d 100644
--- a/drivers/st/regulator/regulator_fixed.c
+++ b/drivers/st/regulator/regulator_fixed.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021-2023, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2021-2025, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -21,7 +21,6 @@
struct fixed_data {
char name[FIXED_NAME_LEN];
- uint16_t volt;
struct regul_description desc;
};
diff --git a/include/drivers/st/bsec3_reg.h b/include/drivers/st/bsec3_reg.h
index 177e30b..4263f76 100644
--- a/include/drivers/st/bsec3_reg.h
+++ b/include/drivers/st/bsec3_reg.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2024-2025, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -84,7 +84,7 @@
/* BSEC_OTPSR register fields */
#define BSEC_OTPSR_BUSY BIT_32(0)
-#define BSEC_OTPSR_FUSEOK BIT_32(1)
+#define BSEC_OTPSR_INIT_DONE BIT_32(1)
#define BSEC_OTPSR_HIDEUP BIT_32(2)
#define BSEC_OTPSR_OTPNVIR BIT_32(4)
#define BSEC_OTPSR_OTPERR BIT_32(5)
diff --git a/include/drivers/st/stm32mp2_ddr_helpers.h b/include/drivers/st/stm32mp2_ddr_helpers.h
index 9329fff..d9bf7ae 100644
--- a/include/drivers/st/stm32mp2_ddr_helpers.h
+++ b/include/drivers/st/stm32mp2_ddr_helpers.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2024, STMicroelectronics - All Rights Reserved
+ * Copyright (c) 2024-2025, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -22,7 +22,6 @@
void ddr_activate_controller(struct stm32mp_ddrctl *ctl, bool sr_entry);
void ddr_wait_lp3_mode(bool state);
int ddr_sr_exit_loop(void);
-uint32_t ddr_get_io_calibration_val(void);
int ddr_sr_entry(bool standby);
int ddr_sr_exit(void);
enum stm32mp2_ddr_sr_mode ddr_read_sr_mode(void);
diff --git a/include/plat/arm/common/plat_acs_smc_handler.h b/include/plat/arm/common/plat_acs_smc_handler.h
new file mode 100644
index 0000000..4d337cb
--- /dev/null
+++ b/include/plat/arm/common/plat_acs_smc_handler.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2025, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef ACS_SMC_HANDLER_H
+#define ACS_SMC_HANDLER_H
+
+#include <common/runtime_svc.h>
+#include <lib/utils_def.h>
+
+/* ARM ACS SMC service call */
+#define ARM_VEN_EL3_ACS_SMC_HANDLER U(0xC7000030)
+#define is_acs_fid(smc_fid) (smc_fid == ARM_VEN_EL3_ACS_SMC_HANDLER)
+
+uintptr_t plat_arm_acs_smc_handler(unsigned int smc_fid,
+ uint64_t services,
+ uint64_t arg0,
+ uint64_t arg1,
+ uint64_t arg2,
+ void *handle);
+#endif /* ACS_SMC_HANDLER_H */
diff --git a/include/services/ven_el3_svc.h b/include/services/ven_el3_svc.h
index e030b68..0336059 100644
--- a/include/services/ven_el3_svc.h
+++ b/include/services/ven_el3_svc.h
@@ -21,7 +21,7 @@
#define VEN_EL3_SVC_VERSION 0x8700ff03
#define VEN_EL3_SVC_VERSION_MAJOR 1
-#define VEN_EL3_SVC_VERSION_MINOR 0
+#define VEN_EL3_SVC_VERSION_MINOR 1
/* DEBUGFS_SMC_32 0x87000010U */
/* DEBUGFS_SMC_64 0xC7000010U */
@@ -29,4 +29,7 @@
/* PMF_SMC_GET_TIMESTAMP_32 0x87000020U */
/* PMF_SMC_GET_TIMESTAMP_64 0xC7000020U */
+/* ACS_SMC_HANDLER_32 0x87000030U */
+/* ACS_SMC_HANDLER_64 0xC7000030U */
+
#endif /* VEN_EL3_SVC_H */
diff --git a/plat/amd/versal2/plat_psci.c b/plat/amd/versal2/plat_psci.c
index d53d751..cded1f3 100644
--- a/plat/amd/versal2/plat_psci.c
+++ b/plat/amd/versal2/plat_psci.c
@@ -19,7 +19,6 @@
#include <plat_private.h>
#include <pm_defs.h>
-#define PM_RET_ERROR_NOFEATURE U(19)
#define ALWAYSTRUE true
#define LINEAR_MODE BIT(1)
@@ -192,7 +191,7 @@
case IOCTL_USB_SET_STATE:
break;
default:
- ret = PM_RET_ERROR_NOFEATURE;
+ ret = PM_RET_ERROR_IOCTL_NOT_SUPPORTED;
break;
}
diff --git a/plat/arm/board/fvp/fvp_cpu_pwr.c b/plat/arm/board/fvp/fvp_cpu_pwr.c
index f2771c2..a294534 100644
--- a/plat/arm/board/fvp/fvp_cpu_pwr.c
+++ b/plat/arm/board/fvp/fvp_cpu_pwr.c
@@ -20,8 +20,8 @@
bool check_cpupwrctrl_el1_is_available(void)
{
- /* Poupulate list of CPU midr that doesn't support CPUPWRCTL_EL1 */
- const unsigned int midr_no_cpupwrctl[] = {
+ /* Populate list of CPU midr that doesn't support CPUPWRCTL_EL1 */
+ static const unsigned int midr_no_cpupwrctl[] = {
BASE_AEM_MIDR,
CORTEX_A35_MIDR,
CORTEX_A53_MIDR,
diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h
index f412ec0..002674c 100644
--- a/plat/arm/board/fvp/include/platform_def.h
+++ b/plat/arm/board/fvp/include/platform_def.h
@@ -93,15 +93,6 @@
#define FVP_DRAM6_SIZE ULL(0x7800000000000) /* 1920 TB */
#define FVP_DRAM6_END (FVP_DRAM6_BASE + FVP_DRAM6_SIZE - 1U)
-/* Range of kernel DTB load address */
-#define FVP_DTB_DRAM_MAP_START ULL(0x82000000)
-#define FVP_DTB_DRAM_MAP_SIZE ULL(0x02000000) /* 32 MB */
-
-#define ARM_DTB_DRAM_NS MAP_REGION_FLAT( \
- FVP_DTB_DRAM_MAP_START, \
- FVP_DTB_DRAM_MAP_SIZE, \
- MT_MEMORY | MT_RO | MT_NS)
-
/*
* On the FVP platform when using the EL3 SPMC implementation allocate the
* datastore for tracking shared memory descriptors in the TZC DRAM section
diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk
index c94761a..53fe806 100644
--- a/plat/arm/common/arm_common.mk
+++ b/plat/arm/common/arm_common.mk
@@ -79,6 +79,15 @@
$(eval $(call assert_boolean,ARM_BL31_IN_DRAM))
$(eval $(call add_define,ARM_BL31_IN_DRAM))
+# Macro to enable ACS SMC handler
+PLAT_ARM_ACS_SMC_HANDLER := 0
+ifeq (${ENABLE_ACS_SMC}, 1)
+PLAT_ARM_ACS_SMC_HANDLER := 1
+endif
+
+# Build macro necessary for branching to ACS tests
+$(eval $(call add_define,PLAT_ARM_ACS_SMC_HANDLER))
+
# As per CCA security model, all root firmware must execute from on-chip secure
# memory. This means we must not run BL31 from TZC-protected DRAM.
ifeq (${ARM_BL31_IN_DRAM},1)
@@ -305,6 +314,11 @@
plat/arm/common/arm_topology.c \
plat/common/plat_psci_common.c
+ifeq (${PLAT_ARM_ACS_SMC_HANDLER},1)
+BL31_SOURCES += plat/arm/common/plat_acs_smc_handler.c \
+ ${VENDOR_EL3_SRCS}
+endif
+
ifeq (${TRANSFER_LIST}, 1)
include lib/transfer_list/transfer_list.mk
TRANSFER_LIST_SOURCES += plat/arm/common/arm_transfer_list.c
diff --git a/plat/arm/common/plat_acs_smc_handler.c b/plat/arm/common/plat_acs_smc_handler.c
new file mode 100644
index 0000000..6f96874
--- /dev/null
+++ b/plat/arm/common/plat_acs_smc_handler.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2025, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <stdint.h>
+#include <plat/arm/common/plat_acs_smc_handler.h>
+
+/*
+ * Placeholder function for handling ACS SMC calls.
+ * return 0 till the handling is done.
+ */
+uintptr_t plat_arm_acs_smc_handler(unsigned int smc_fid, uint64_t services,
+ uint64_t arg0, uint64_t arg1, uint64_t arg2, void *handle)
+{
+ WARN("Unimplemented ACS Call: 0x%x\n", smc_fid);
+ SMC_RET1(handle, SMC_UNK);
+}
diff --git a/plat/intel/soc/agilex5/bl31_plat_setup.c b/plat/intel/soc/agilex5/bl31_plat_setup.c
index 9cf1e11..66e0ea5 100644
--- a/plat/intel/soc/agilex5/bl31_plat_setup.c
+++ b/plat/intel/soc/agilex5/bl31_plat_setup.c
@@ -217,9 +217,11 @@
NOTICE("SOCFPGA: CPU ID = %x\n", cpuid);
INFO("SOCFPGA: Invalidate Data cache\n");
invalidate_dcache_all();
-
/* Invalidate for NS EL2 and EL1 */
invalidate_cache_low_el();
+
+ NOTICE("SOCFPGA: Setting CLUSTERECTRL_EL1\n");
+ setup_clusterectlr_el1();
}
/* Get non-secure image entrypoint for BL33. Zephyr and Linux */
@@ -303,6 +305,22 @@
mmio_write_32(AGX5_PWRMGR(MPU_PCHCTLR), pch_cpu);
}
+void setup_clusterectlr_el1(void)
+{
+ uint64_t value = 0;
+
+ /* Read CLUSTERECTLR_EL1 */
+ asm volatile("mrs %0, S3_0_C15_C3_4" : "=r"(value));
+
+ /* Disable broadcasting atomics */
+ value |= 0x80; /* set bit 7 */
+ /* Disable sending data with clean evicts */
+ value &= 0xFFFFBFFF; /* Mask out bit 14 */
+
+ /* Write CLUSTERECTLR_EL1 */
+ asm volatile("msr S3_0_C15_C3_4, %0" :: "r"(value));
+}
+
void bl31_plat_runtime_setup(void)
{
/* Dummy override function. */
diff --git a/plat/intel/soc/common/include/socfpga_private.h b/plat/intel/soc/common/include/socfpga_private.h
index fbe18c3..782b2b5 100644
--- a/plat/intel/soc/common/include/socfpga_private.h
+++ b/plat/intel/soc/common/include/socfpga_private.h
@@ -65,4 +65,6 @@
void plat_secondary_cpus_bl31_entry(void);
+void setup_clusterectlr_el1(void);
+
#endif /* SOCFPGA_PRIVATE_H */
diff --git a/plat/mediatek/build_helpers/options.mk b/plat/mediatek/build_helpers/options.mk
index 080e735..d2a8fd3 100644
--- a/plat/mediatek/build_helpers/options.mk
+++ b/plat/mediatek/build_helpers/options.mk
@@ -14,6 +14,7 @@
CONFIG_MTK_MTCMOS \
CONFIG_MTK_PM_ARCH \
CONFIG_MTK_PM_SUPPORT \
+ CONFIG_MTK_SMMU_SID \
CONFIG_MTK_SMP_EN \
CONFIG_MTK_SUPPORT_SYSTEM_SUSPEND \
MTK_ADAPTED \
diff --git a/plat/mediatek/common/mtk_bl31_lib.c b/plat/mediatek/common/mtk_bl31_lib.c
new file mode 100644
index 0000000..3428471
--- /dev/null
+++ b/plat/mediatek/common/mtk_bl31_lib.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2025, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+
+#include <mtk_bl31_interface.h>
+#include <mtk_sip_svc.h>
+
+int mtk_bl31_map_to_sip_error(enum mtk_bl31_status status)
+{
+ switch (status) {
+ case MTK_BL31_STATUS_SUCCESS:
+ return MTK_SIP_E_SUCCESS;
+ case MTK_BL31_STATUS_INVALID_PARAM:
+ return MTK_SIP_E_INVALID_PARAM;
+ case MTK_BL31_STATUS_NOT_SUPPORTED:
+ return MTK_SIP_E_NOT_SUPPORTED;
+ case MTK_BL31_STATUS_INVALID_RANGE:
+ return MTK_SIP_E_INVALID_RANGE;
+ case MTK_BL31_STATUS_PERMISSION_DENY:
+ return MTK_SIP_E_PERMISSION_DENY;
+ case MTK_BL31_STATUS_LOCK_FAIL:
+ return MTK_SIP_E_LOCK_FAIL;
+ default:
+ ERROR("%s: unknown status: %d\n", __func__, status);
+ }
+
+ return MTK_SIP_E_NOT_SUPPORTED;
+}
+
+int mtk_bl31_mmap_add_dynamic_region(unsigned long long base_pa, size_t size,
+ enum mtk_bl31_memory_type type)
+{
+ unsigned int attr;
+
+ switch (type) {
+ case MTK_BL31_DEV_RW_SEC:
+ attr = MT_DEVICE | MT_RW | MT_SECURE;
+ break;
+ default:
+ attr = 0;
+ ERROR("%s: unknown memory type %d\n", __func__, type);
+ break;
+ }
+
+ return mmap_add_dynamic_region(base_pa, base_pa, size, attr);
+}
+
+int mtk_bl31_mmap_remove_dynamic_region(uintptr_t base_va, size_t size)
+{
+ return mmap_remove_dynamic_region(base_va, size);
+}
diff --git a/plat/mediatek/common/rules.mk b/plat/mediatek/common/rules.mk
index 6acc731..66ea8b7 100644
--- a/plat/mediatek/common/rules.mk
+++ b/plat/mediatek/common/rules.mk
@@ -8,7 +8,8 @@
MODULE := mtk_common
-LOCAL_SRCS-y := ${LOCAL_DIR}/mtk_bl31_setup.c
+LOCAL_SRCS-y := ${LOCAL_DIR}/mtk_bl31_lib.c
+LOCAL_SRCS-y += ${LOCAL_DIR}/mtk_bl31_setup.c
LOCAL_SRCS-y += ${LOCAL_DIR}/mtk_smc_handlers.c
LOCAL_SRCS-$(MTK_SIP_KERNEL_BOOT_ENABLE) += ${LOCAL_DIR}/cold_boot.c
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/cpu_qos/mt8196/mtk_cpuqos.c b/plat/mediatek/drivers/cpu_qos/mt8196/mtk_cpuqos.c
new file mode 100644
index 0000000..eb4436c
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_qos/mt8196/mtk_cpuqos.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2025, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/pm/mtk_pm.h>
+#include <mtk_bl31_interface.h>
+
+static void *cpu_qos_handle_cluster_on_event_cb(const void *arg)
+{
+ return cpu_qos_handle_cluster_on_event(arg);
+}
+
+MT_CPUPM_SUBCRIBE_CLUSTER_PWR_ON(cpu_qos_handle_cluster_on_event_cb);
diff --git a/plat/mediatek/drivers/cpu_qos/mt8196/mtk_cpuqos_stub.c b/plat/mediatek/drivers/cpu_qos/mt8196/mtk_cpuqos_stub.c
new file mode 100644
index 0000000..f3540bd
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_qos/mt8196/mtk_cpuqos_stub.c
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2025, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mtk_bl31_interface.h>
+
+void cpu_qos_change_dcc(uint32_t on, uint32_t is_auto)
+{
+}
+
+void *cpu_qos_handle_cluster_on_event(const void *arg)
+{
+ return (void *)arg;
+}
diff --git a/plat/mediatek/drivers/cpu_qos/mt8196/rules.mk b/plat/mediatek/drivers/cpu_qos/mt8196/rules.mk
new file mode 100644
index 0000000..fa12496
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_qos/mt8196/rules.mk
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2025, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := cpu_qos_$(MTK_SOC)
+
+LOCAL_SRCS-y := $(LOCAL_DIR)/mtk_cpuqos.c
+ifeq ($(MTKLIB_PATH),)
+LOCAL_SRCS-y += $(LOCAL_DIR)/mtk_cpuqos_stub.c
+endif
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/cpu_qos/rules.mk b/plat/mediatek/drivers/cpu_qos/rules.mk
new file mode 100644
index 0000000..c67a136
--- /dev/null
+++ b/plat/mediatek/drivers/cpu_qos/rules.mk
@@ -0,0 +1,11 @@
+#
+# Copyright (c) 2025, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+SUB_RULES := $(LOCAL_DIR)/$(MTK_SOC)
+
+$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES)))
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/drivers/iommu/mt8189/mtk_iommu_plat.c b/plat/mediatek/drivers/iommu/mt8189/mtk_iommu_plat.c
new file mode 100644
index 0000000..50fd2e7
--- /dev/null
+++ b/plat/mediatek/drivers/iommu/mt8189/mtk_iommu_plat.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2025, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mtk_iommu_priv.h>
+#include <mtk_mmap_pool.h>
+#include <platform_def.h>
+
+/* mm iommu */
+#define SMI_L0_ID (0)
+#define SMI_L1_ID (1)
+#define SMI_L2_ID (2)
+#define SMI_L4_ID (3)
+#define SMI_L7_ID (4)
+#define SMI_L9_ID (5)
+#define SMI_L11_ID (6)
+#define SMI_L13_ID (7)
+#define SMI_L14_ID (8)
+#define SMI_L16_ID (9)
+#define SMI_L17_ID (10)
+#define SMI_L19_ID (11)
+#define SMI_L20_ID (12)
+
+/* infra iommu */
+#define PERICFG_AO_IOMMU_0 (0x90)
+#define PERICFG_AO_IOMMU_1 (0x94)
+#define MMU_DEV_PCIE_0 (0)
+#define IFR_CFG_GROUP_NUM (1)
+
+static struct mtk_smi_larb_config mt8189_larb_cfg[] = {
+ [SMI_L0_ID] = LARB_CFG_ENTRY(SMI_LARB_0_BASE, 8, 0),
+ [SMI_L1_ID] = LARB_CFG_ENTRY(SMI_LARB_1_BASE, 8, 0),
+ [SMI_L2_ID] = LARB_CFG_ENTRY(SMI_LARB_2_BASE, 11, 0),
+ [SMI_L4_ID] = LARB_CFG_ENTRY(SMI_LARB_4_BASE, 12, 0),
+ [SMI_L7_ID] = LARB_CFG_ENTRY(SMI_LARB_7_BASE, 18, 0),
+ [SMI_L9_ID] = LARB_CFG_ENTRY(SMI_LARB_9_BASE, 29, 0),
+ [SMI_L11_ID] = LARB_CFG_ENTRY(SMI_LARB_11_BASE, 29, 0),
+ [SMI_L13_ID] = LARB_CFG_ENTRY(SMI_LARB_13_BASE, 15, 0),
+ [SMI_L14_ID] = LARB_CFG_ENTRY(SMI_LARB_14_BASE, 10, 0),
+ [SMI_L16_ID] = LARB_CFG_ENTRY(SMI_LARB_16_BASE, 17, 0),
+ [SMI_L17_ID] = LARB_CFG_ENTRY(SMI_LARB_17_BASE, 17, 0),
+ [SMI_L19_ID] = LARB_CFG_ENTRY(SMI_LARB_19_BASE, 4, 0),
+ [SMI_L20_ID] = LARB_CFG_ENTRY(SMI_LARB_20_BASE, 6, 0),
+};
+
+static uint32_t mt8189_ifr_mst_cfg_base[IFR_CFG_GROUP_NUM] = {
+ PERICFG_AO_BASE,
+};
+static uint32_t mt8189_ifr_mst_cfg_offs[IFR_CFG_GROUP_NUM] = {
+ PERICFG_AO_IOMMU_1,
+};
+static struct mtk_ifr_mst_config mt8189_ifr_mst_cfg[] = {
+ [MMU_DEV_PCIE_0] = IFR_MST_CFG_ENTRY(0, 0),
+};
+
+struct mtk_smi_larb_config *g_larb_cfg = &mt8189_larb_cfg[0];
+const unsigned int g_larb_num = ARRAY_SIZE(mt8189_larb_cfg);
+
+static struct mtk_secure_iommu_config mt8189_secure_iommu_config[] = {
+ SEC_IOMMU_CFG_ENTRY(MM_IOMMU_BASE),
+};
+
+struct mtk_secure_iommu_config *g_sec_iommu_cfg = &mt8189_secure_iommu_config[0];
+const unsigned int g_sec_iommu_num = ARRAY_SIZE(mt8189_secure_iommu_config);
+
+struct mtk_ifr_mst_config *g_ifr_mst_cfg = &mt8189_ifr_mst_cfg[0];
+const unsigned int g_ifr_mst_num = ARRAY_SIZE(mt8189_ifr_mst_cfg);
+
+uint32_t *g_ifr_mst_cfg_base = &mt8189_ifr_mst_cfg_base[0];
+uint32_t *g_ifr_mst_cfg_offs = &mt8189_ifr_mst_cfg_offs[0];
+
+/**
+ * Protect infra iommu enable setting registers as secure access.
+ * This is removed in MT8189, just return here.
+ */
+void mtk_infra_iommu_enable_protect(void)
+{
+}
diff --git a/plat/mediatek/drivers/iommu/mt8189/mtk_iommu_plat.h b/plat/mediatek/drivers/iommu/mt8189/mtk_iommu_plat.h
new file mode 100644
index 0000000..935036f
--- /dev/null
+++ b/plat/mediatek/drivers/iommu/mt8189/mtk_iommu_plat.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2025, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IOMMU_PLAT_H
+#define IOMMU_PLAT_H
+
+/* mm iommu */
+#define ATF_MTK_SMI_LARB_CFG_SUPPORT
+
+/* mm iommu, sec bank dump */
+#define ATF_MTK_IOMMU_CFG_SUPPORT
+
+/* infra iommu */
+#define ATF_MTK_INFRA_MASTER_CFG_SUPPORT
+
+#endif /* IOMMU_PLAT_H */
diff --git a/plat/mediatek/drivers/mminfra/mminfra_common.h b/plat/mediatek/drivers/mminfra/mminfra_common.h
new file mode 100644
index 0000000..93820c7
--- /dev/null
+++ b/plat/mediatek/drivers/mminfra/mminfra_common.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MMINFRA_COMMON_H
+#define MMINFRA_COMMON_H
+
+#define mminfra_info(fmt, args...) INFO("[mminfra] %s: "fmt"\n", __func__, ##args)
+#define mminfra_err(fmt, args...) ERROR("[mminfra] %s: "fmt"\n", __func__, ##args)
+
+#endif
diff --git a/plat/mediatek/drivers/mminfra/mminfra_stub.c b/plat/mediatek/drivers/mminfra/mminfra_stub.c
deleted file mode 100644
index dc37280..0000000
--- a/plat/mediatek/drivers/mminfra/mminfra_stub.c
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (c) 2025, MediaTek Inc. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <drivers/mminfra_public.h>
-
-int mminfra_get_if_in_use(void)
-{
- return 0;
-}
-
-int mminfra_put(void)
-{
- return 0;
-}
diff --git a/plat/mediatek/drivers/mminfra/mt8196/mminfra.c b/plat/mediatek/drivers/mminfra/mt8196/mminfra.c
new file mode 100644
index 0000000..1086c75
--- /dev/null
+++ b/plat/mediatek/drivers/mminfra/mt8196/mminfra.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+
+#include <drivers/mminfra_public.h>
+#include <mminfra.h>
+#include <mtk_mmap_pool.h>
+
+static const mmap_region_t mminfra_plat_mmap[] MTK_MMAP_SECTION = {
+ MAP_REGION_FLAT(MMINFRA_HW_VOTER_BASE, PAGE_SIZE, MT_DEVICE | MT_RW | MT_SECURE),
+ {0}
+};
+DECLARE_MTK_MMAP_REGIONS(mminfra_plat_mmap);
+
+static struct mtk_mminfra_pwr_ctrl mminfra_pwr_ctrl = {
+ .hw_voter = {
+ .base = MMINFRA_HW_VOTER_BASE,
+ .set_ofs = 0x104,
+ .clr_ofs = 0x108,
+ .en_ofs = 0x100,
+ .en_shift = 0x1,
+ .done_bits = VLP_AO_RSVD6,
+ },
+ .hw_sema = {
+ .base = SPM_BASE,
+ .offset = SPM_SEMAPHORE_M1,
+ .offset_all = {
+ SPM_SEMAPHORE_M0,
+ SPM_SEMAPHORE_M1,
+ SPM_SEMAPHORE_M2,
+ SPM_SEMAPHORE_M3,
+ SPM_SEMAPHORE_M4,
+ SPM_SEMAPHORE_M5,
+ SPM_SEMAPHORE_M6,
+ SPM_SEMAPHORE_M7,
+ },
+ .set_val = SPM_SEMA_MMINFRA,
+ },
+ .active = true,
+ .ref_cnt = 0,
+};
+
+static int spm_semaphore_get(uint32_t base, uint32_t set_val)
+{
+ int cnt = SEMA_RETRY_CNT;
+ uint32_t val;
+
+ val = mmio_read_32(base);
+ if ((val & set_val) == set_val) {
+ mminfra_err("hw_sem was already got, base:0x%x=0x%x, set_val:0x%x\n",
+ base, val, set_val);
+ return -1;
+ }
+
+ while (cnt > 0) {
+ mmio_write_32(base, set_val);
+ udelay(10);
+ if ((mmio_read_32(base) & set_val) == set_val)
+ return 0;
+ cnt--;
+ }
+
+ mminfra_err("timeout! base:0x%x, set_val:0x%x\n", base, set_val);
+ return -1;
+}
+
+static int spm_semaphore_release(uint32_t base, uint32_t set_val)
+{
+ int cnt = SEMA_RETRY_CNT;
+ uint32_t val;
+
+ val = mmio_read_32(base);
+ if ((val & set_val) != set_val) {
+ mminfra_err("hw_sem was already released, base:0x%x=0x%x, set_val:0x%x\n",
+ base, val, set_val);
+ return -1;
+ }
+ do {
+ mmio_write_32(base, set_val);
+ udelay(10);
+ if (cnt-- < 0) {
+ if ((mmio_read_32(base) & set_val) != set_val)
+ return 0;
+ mminfra_err("timeout! base:0x%x, set_val:0x%x\n", base, set_val);
+ return -1;
+ }
+ } while ((mmio_read_32(base) & set_val) == set_val);
+
+ return 0;
+}
+
+static int mminfra_hw_sema_ctrl(struct mminfra_hw_sema *hw_sema, bool is_get)
+{
+ int i, ret;
+
+ if (!hw_sema)
+ return 0;
+
+ if (is_get)
+ ret = spm_semaphore_get(hw_sema->base + hw_sema->offset, hw_sema->set_val);
+ else
+ ret = spm_semaphore_release(hw_sema->base + hw_sema->offset, hw_sema->set_val);
+
+ if (ret)
+ for (i = 0; i < SPM_SEMA_MMINFRA_NR; i++)
+ mminfra_err("0x%x=0x%x\n", hw_sema->base + hw_sema->offset_all[i],
+ mmio_read_32(hw_sema->base + hw_sema->offset_all[i]));
+
+ return ret;
+}
+
+static bool is_mminfra_ready(struct mminfra_hw_voter *hw_voter)
+{
+ if (!hw_voter)
+ return false;
+
+ return !!(mmio_read_32(hw_voter->done_bits) & MMINFRA_DONE);
+}
+
+static int mminfra_hwv_power_ctrl(struct mminfra_hw_voter *hw_voter, bool is_on)
+{
+ uint32_t vote_ofs, vote_mask, vote_ack;
+ uint32_t val = 0, cnt;
+
+ vote_mask = BIT(hw_voter->en_shift);
+ vote_ofs = is_on ? hw_voter->set_ofs : hw_voter->clr_ofs;
+ vote_ack = is_on ? vote_mask : 0x0;
+
+ /* Vote on off */
+ cnt = 0;
+ do {
+ mmio_write_32(hw_voter->base + vote_ofs, vote_mask);
+ udelay(MTK_POLL_HWV_VOTE_US);
+ val = mmio_read_32(hw_voter->base + hw_voter->en_ofs);
+ if ((val & vote_mask) == vote_ack)
+ break;
+
+ if (cnt > MTK_POLL_HWV_VOTE_CNT) {
+ mminfra_err("vote mminfra timeout, is_on:%d, 0x%x=0x%x\n",
+ is_on, hw_voter->base + hw_voter->en_ofs, val);
+ return -1;
+ }
+ cnt++;
+ } while (1);
+
+ if (!is_on)
+ return 0;
+
+ /* Confirm done bits */
+ cnt = 0;
+ while (cnt < MTK_POLL_DONE_RETRY) {
+ if (is_mminfra_ready(hw_voter))
+ return 0;
+ udelay(MTK_POLL_DONE_DELAY_US);
+ cnt++;
+ }
+
+ mminfra_err("polling mminfra done timeout, 0x%x=0x%x\n",
+ hw_voter->done_bits, val);
+ return -1;
+}
+
+int mminfra_get_if_in_use(void)
+{
+ int ret, is_on = MMINFRA_RET_POWER_OFF;
+
+ if (!mminfra_pwr_ctrl.active) {
+ mminfra_err("not ready\n");
+ return MMINFRA_RET_POWER_OFF;
+ }
+
+ spin_lock(&mminfra_pwr_ctrl.lock);
+ if (mminfra_pwr_ctrl.ref_cnt > 0) {
+ mminfra_pwr_ctrl.ref_cnt++;
+ is_on = MMINFRA_RET_POWER_ON;
+ spin_unlock(&mminfra_pwr_ctrl.lock);
+ return is_on;
+ }
+
+ ret = mminfra_hw_sema_ctrl(&mminfra_pwr_ctrl.hw_sema, true);
+ if (ret)
+ goto err;
+
+ /* Check if mminfra is in use */
+ if (is_mminfra_ready(&mminfra_pwr_ctrl.hw_voter)) {
+ ret = mminfra_hwv_power_ctrl(&mminfra_pwr_ctrl.hw_voter, true);
+ if (ret) {
+ mminfra_err("vote for mminfra fail, ret=%d\n", ret);
+ goto err;
+ }
+ mminfra_pwr_ctrl.ref_cnt++;
+ is_on = MMINFRA_RET_POWER_ON;
+ } else {
+ is_on = MMINFRA_RET_POWER_OFF;
+ }
+
+ ret = mminfra_hw_sema_ctrl(&mminfra_pwr_ctrl.hw_sema, false);
+ if (ret)
+ goto err;
+ ret = is_on; /* Return power is on or off. */
+err:
+ spin_unlock(&mminfra_pwr_ctrl.lock);
+ return ret;
+}
+
+int mminfra_put(void)
+{
+ if (!mminfra_pwr_ctrl.active) {
+ mminfra_err("not ready\n");
+ return 0;
+ }
+
+ spin_lock(&mminfra_pwr_ctrl.lock);
+ mminfra_pwr_ctrl.ref_cnt--;
+ if (mminfra_pwr_ctrl.ref_cnt > 0)
+ goto out;
+
+ mminfra_hwv_power_ctrl(&mminfra_pwr_ctrl.hw_voter, false);
+out:
+ spin_unlock(&mminfra_pwr_ctrl.lock);
+ return 0;
+}
diff --git a/plat/mediatek/drivers/mminfra/mt8196/mminfra.h b/plat/mediatek/drivers/mminfra/mt8196/mminfra.h
new file mode 100644
index 0000000..fcee08c
--- /dev/null
+++ b/plat/mediatek/drivers/mminfra/mt8196/mminfra.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2025, Mediatek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MMINFRA_H
+#define MMINFRA_H
+
+#include <lib/spinlock.h>
+
+#include "../mminfra_common.h"
+#include <platform_def.h>
+
+#define VLP_AO_RSVD6 (MTK_VLP_TRACER_MON_BASE + 0x918)
+#define MMINFRA_DONE (1U << 0)
+
+#define SPM_SEMA_MMINFRA (1U << 5)
+#define SPM_SEMA_MMINFRA_NR (8)
+
+#define SEMA_RETRY_CNT (500)
+
+#define SPM_SEMAPHORE_M0 (0x69C)
+#define SPM_SEMAPHORE_M1 (0x6A0)
+#define SPM_SEMAPHORE_M2 (0x6A4)
+#define SPM_SEMAPHORE_M3 (0x6A8)
+#define SPM_SEMAPHORE_M4 (0x6AC)
+#define SPM_SEMAPHORE_M5 (0x6B0)
+#define SPM_SEMAPHORE_M6 (0x6B4)
+#define SPM_SEMAPHORE_M7 (0x6B8)
+
+#define MMINFRA_HW_VOTER_BASE (0x31A80000)
+#define MTK_POLL_HWV_VOTE_US (2)
+#define MTK_POLL_HWV_VOTE_CNT (2500)
+#define MTK_POLL_DONE_DELAY_US (1)
+#define MTK_POLL_DONE_RETRY (3000)
+
+struct mminfra_hw_sema {
+ uint32_t base;
+ uint32_t offset;
+ uint32_t offset_all[SPM_SEMA_MMINFRA_NR];
+ uint32_t set_val;
+};
+
+struct mminfra_hw_voter {
+ uint32_t base;
+ uint32_t set_ofs;
+ uint32_t clr_ofs;
+ uint32_t en_ofs;
+ uint32_t en_shift;
+ uint32_t done_bits;
+};
+
+struct mtk_mminfra_pwr_ctrl {
+ spinlock_t lock;
+ struct mminfra_hw_voter hw_voter;
+ struct mminfra_hw_sema hw_sema;
+ uint32_t ref_cnt;
+ bool active;
+};
+
+#endif
diff --git a/plat/mediatek/drivers/mminfra/rules.mk b/plat/mediatek/drivers/mminfra/rules.mk
index f3a6822..cd5d607 100644
--- a/plat/mediatek/drivers/mminfra/rules.mk
+++ b/plat/mediatek/drivers/mminfra/rules.mk
@@ -8,10 +8,9 @@
MODULE := mminfra
-PLAT_INCLUDES += -I${MTK_PLAT}/include/drivers/
+PLAT_INCLUDES += -I$(MTK_PLAT)/include/drivers/
+PLAT_INCLUDES += -I$(MTK_PLAT)/drivers/mminfra/$(MTK_SOC)
-ifeq ($(MTKLIB_PATH),)
-LOCAL_SRCS-y := ${LOCAL_DIR}/mminfra_stub.c
-endif
+LOCAL_SRCS-y := $(LOCAL_DIR)/$(MTK_SOC)/mminfra.c
$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/slbc/mt8196/rules.mk b/plat/mediatek/drivers/slbc/mt8196/rules.mk
new file mode 100644
index 0000000..eabddfa
--- /dev/null
+++ b/plat/mediatek/drivers/slbc/mt8196/rules.mk
@@ -0,0 +1,13 @@
+#
+# Copyright (c) 2025, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := slbc_$(MTK_SOC)
+
+LOCAL_SRCS-y := $(LOCAL_DIR)/slbc.c
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/slbc/mt8196/slbc.c b/plat/mediatek/drivers/slbc/mt8196/slbc.c
new file mode 100644
index 0000000..5f7b1e1
--- /dev/null
+++ b/plat/mediatek/drivers/slbc/mt8196/slbc.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2025, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+
+#include <common/debug.h>
+
+#include <mtk_bl31_interface.h>
+#include <mtk_sip_svc.h>
+
+#define MODULE_TAG "[SLBC]"
+
+enum {
+ MTK_SLBC_KERNEL_OP_CPU_DCC = 0,
+};
+
+static u_register_t slbc_kernel_handler(u_register_t x1, u_register_t x2,
+ u_register_t x3, u_register_t x4,
+ void *handle,
+ struct smccc_res *smccc_ret)
+{
+ uint32_t request_ops = (uint32_t)x1;
+ u_register_t ret = 0;
+
+ switch (request_ops) {
+ case MTK_SLBC_KERNEL_OP_CPU_DCC:
+ cpu_qos_change_dcc(x2, x3);
+ break;
+ default:
+ ERROR("%s: %s, unknown request_ops = %x\n", MODULE_TAG, __func__, request_ops);
+ ret = EIO;
+ break;
+ }
+
+ VERBOSE("%s: %s, request_ops = %x, ret = %lu\n", MODULE_TAG, __func__, request_ops, ret);
+ return ret;
+}
+
+/* Register SiP SMC service */
+DECLARE_SMC_HANDLER(MTK_SIP_KERNEL_SLBC_CONTROL, slbc_kernel_handler);
diff --git a/plat/mediatek/drivers/slbc/rules.mk b/plat/mediatek/drivers/slbc/rules.mk
new file mode 100644
index 0000000..93fd1b8
--- /dev/null
+++ b/plat/mediatek/drivers/slbc/rules.mk
@@ -0,0 +1,17 @@
+#
+# Copyright (c) 2025, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := slbc
+
+LOCAL_SOC_DIR := $(LOCAL_DIR)/$(MTK_SOC)
+PLATFORM_DIR_EXIST := $(shell test -f $(LOCAL_SOC_DIR)/rules.mk && echo yes)
+
+ifeq ($(PLATFORM_DIR_EXIST), yes)
+SUB_RULES-y := $(LOCAL_SOC_DIR)
+$(eval $(call INCLUDE_MAKEFILE,$(SUB_RULES-y)))
+endif
diff --git a/plat/mediatek/drivers/smmu_sid/rules.mk b/plat/mediatek/drivers/smmu_sid/rules.mk
new file mode 100644
index 0000000..9c6dfc8
--- /dev/null
+++ b/plat/mediatek/drivers/smmu_sid/rules.mk
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2025, MediaTek Inc. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+LOCAL_DIR := $(call GET_LOCAL_DIR)
+
+MODULE := smmu_sid
+
+LOCAL_SRCS-y := $(LOCAL_DIR)/smmu_sid.c
+ifeq ($(MTKLIB_PATH),)
+LOCAL_SRCS-y += $(LOCAL_DIR)/smmu_sid_stub.c
+endif
+
+$(eval $(call MAKE_MODULE,$(MODULE),$(LOCAL_SRCS-y),$(MTK_BL)))
diff --git a/plat/mediatek/drivers/smmu_sid/smmu_sid.c b/plat/mediatek/drivers/smmu_sid/smmu_sid.c
new file mode 100644
index 0000000..2d852b6
--- /dev/null
+++ b/plat/mediatek/drivers/smmu_sid/smmu_sid.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2025, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mtk_init/mtk_init.h>
+#include <mtk_bl31_interface.h>
+
+static int mtk_smmu_sid_init(void)
+{
+ return smmu_sid_init();
+}
+
+MTK_PLAT_SETUP_0_INIT(mtk_smmu_sid_init);
diff --git a/plat/mediatek/drivers/smmu_sid/smmu_sid_stub.c b/plat/mediatek/drivers/smmu_sid/smmu_sid_stub.c
new file mode 100644
index 0000000..2ed162c
--- /dev/null
+++ b/plat/mediatek/drivers/smmu_sid/smmu_sid_stub.c
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2025, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mtk_bl31_interface.h>
+
+int smmu_sid_init(void)
+{
+ return 0;
+}
diff --git a/plat/mediatek/drivers/ufs/mt8196/ufs_ctrl_soc.c b/plat/mediatek/drivers/ufs/mt8196/ufs_ctrl_soc.c
new file mode 100644
index 0000000..2db07bf
--- /dev/null
+++ b/plat/mediatek/drivers/ufs/mt8196/ufs_ctrl_soc.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2025, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <drivers/pmic/pmic_set_lowpower.h>
+#if defined(CONFIG_MTK_MTCMOS)
+#include <mtcmos.h>
+#endif
+#include <mtk_bl31_interface.h>
+
+static void ufs_vsx_lpm(bool lpm, uint64_t ufs_version)
+{
+ if (lpm) {
+ /* MT6363 VS2 voter LOW byte BIT6 vote reduce VS2 voltage */
+ PMIC_BUCK_VOTER_EN(MT6363, VS2, VOTER_EN_LO_BIT6, VOTER_EN_CLR);
+
+ /* VS2 buck can enter LPM */
+ PMIC_BUCK_SET_LP(MT6363, VS2, HW2, true, OP_MODE_LP, HW_LP);
+ } else {
+ /* MT6363 VS2 voter LOW byte BIT6 vote raise VS2 voltage */
+ PMIC_BUCK_VOTER_EN(MT6363, VS2, VOTER_EN_LO_BIT6, VOTER_EN_SET);
+
+ /* VS2 buck can not enter LPM */
+ PMIC_BUCK_SET_LP(MT6363, VS2, HW2, true, OP_MODE_LP, HW_ONLV);
+ }
+}
+
+void ufs_device_pwr_ctrl_soc(bool vcc_on, uint64_t ufs_version)
+{
+ if (vcc_on)
+ ufs_vsx_lpm(false, ufs_version);
+ else
+ ufs_vsx_lpm(true, ufs_version);
+}
+
+int ufs_spm_mtcmos_power(bool on)
+{
+#if defined(CONFIG_MTK_MTCMOS)
+ return spm_mtcmos_ctrl_ufs0(on ? STA_POWER_ON : STA_POWER_DOWN);
+#else
+ return 0;
+#endif
+}
+
+int ufs_phy_spm_mtcmos_power(bool on)
+{
+#if defined(CONFIG_MTK_MTCMOS)
+ return spm_mtcmos_ctrl_ufs0_phy(on ? STA_POWER_ON : STA_POWER_DOWN);
+#else
+ return 0;
+#endif
+}
diff --git a/plat/mediatek/drivers/ufs/rules.mk b/plat/mediatek/drivers/ufs/rules.mk
index 877cbc7..13d3f53 100644
--- a/plat/mediatek/drivers/ufs/rules.mk
+++ b/plat/mediatek/drivers/ufs/rules.mk
@@ -12,6 +12,7 @@
PLAT_INCLUDES += -I$(MTK_PLAT)/include/drivers/
LOCAL_SRCS-y := $(LOCAL_DIR)/ufs_ctrl.c
+LOCAL_SRCS-y += $(LOCAL_DIR)/$(MTK_SOC)/ufs_ctrl_soc.c
ifeq ($(MTKLIB_PATH),)
LOCAL_SRCS-y += $(LOCAL_DIR)/ufs_stub.c
endif
diff --git a/plat/mediatek/drivers/ufs/ufs_ctrl.c b/plat/mediatek/drivers/ufs/ufs_ctrl.c
index af27e67..14d0616 100644
--- a/plat/mediatek/drivers/ufs/ufs_ctrl.c
+++ b/plat/mediatek/drivers/ufs/ufs_ctrl.c
@@ -8,6 +8,8 @@
/* MTK header */
#include <drivers/pmic/pmic_swap_api.h>
+#include <lpm_v2/mt_lp_api.h>
+#include <lpm_v2/mt_lp_rq.h>
#include <mtk_bl31_interface.h>
#include <mtk_sip_svc.h>
@@ -39,6 +41,63 @@
smccc_ret->a1 = VCC_1;
}
+/* SPM resource control */
+#define RSC_MEM (MT_LP_RQ_DRAM | MT_LP_RQ_EMI)
+#define RSC_PMIC MT_LP_RQ_PMIC
+
+static int ufs_rsc_ctrl(unsigned int rsc, bool hold)
+{
+ static struct mt_lp_resource_user ufs_res_user;
+ int ret = -1;
+
+ if (!ufs_res_user.uid) {
+ ret = mt_lp_resource_user_register("UFS", &ufs_res_user);
+
+ if (ret) {
+ WARN("%s: register lp resource failed\n", __func__);
+ return ret;
+ }
+ }
+
+ if (hold)
+ ret = ufs_res_user.request(&ufs_res_user, rsc);
+ else
+ ret = ufs_res_user.release(&ufs_res_user);
+
+ VERBOSE("%s: rsc=%d, hold=%d\n", __func__, rsc, hold);
+
+ if (ret)
+ WARN("%s: RSC_%d %s failed\n", __func__, rsc, hold ? "request" : "release");
+
+ return ret;
+}
+
+int ufs_rsc_ctrl_mem(bool hold)
+{
+ return ufs_rsc_ctrl(RSC_MEM, hold);
+}
+
+int ufs_rcs_ctrl_pmic(bool hold)
+{
+ return ufs_rsc_ctrl(RSC_PMIC, hold);
+}
+
+/* UFS clock status */
+static uint32_t ufs_clk_sta = UFS_REF_CLK_ON;
+
+bool ufs_is_clk_status_off(void)
+{
+ return ufs_clk_sta == UFS_REF_CLK_OFF;
+}
+
+void ufs_set_clk_status(bool on)
+{
+ if (on)
+ ufs_clk_sta = UFS_REF_CLK_ON;
+ else
+ ufs_clk_sta = UFS_REF_CLK_OFF;
+}
+
static u_register_t ufs_knl_ctrl(u_register_t x1,
u_register_t x2,
u_register_t x3,
@@ -50,10 +109,10 @@
switch (x1) {
case UFS_MTK_SIP_VA09_PWR_CTRL:
- ufs_mphy_va09_cg_ctrl((bool)!!x2);
+ ufs_mphy_va09_cg_ctrl(!!x2);
break;
case UFS_MTK_SIP_DEVICE_RESET:
- ufs_device_reset_ctrl((bool)!!x2);
+ ufs_device_reset_ctrl(!!x2);
break;
case UFS_MTK_SIP_CRYPTO_CTRL:
ufs_crypto_hie_init();
@@ -74,7 +133,9 @@
ufs_mphy_ctrl(x2);
break;
case UFS_MTK_SIP_MTCMOS_CTRL:
- ufs_mtcmos_ctrl(x2);
+#if defined(CONFIG_MTK_MTCMOS)
+ ufs_mtcmos_ctrl(!!x2);
+#endif
break;
default:
ret = -1;
diff --git a/plat/mediatek/include/mtk_bl31_interface.h b/plat/mediatek/include/mtk_bl31_interface.h
index 9650f71..208276c 100644
--- a/plat/mediatek/include/mtk_bl31_interface.h
+++ b/plat/mediatek/include/mtk_bl31_interface.h
@@ -8,8 +8,28 @@
#define __MTK_BL31_INTERFACE_H__
#include <stdbool.h>
+#include <stddef.h>
#include <stdint.h>
+enum mtk_bl31_status {
+ MTK_BL31_STATUS_SUCCESS = 0,
+ MTK_BL31_STATUS_INVALID_PARAM = -1,
+ MTK_BL31_STATUS_NOT_SUPPORTED = -2,
+ MTK_BL31_STATUS_INVALID_RANGE = -3,
+ MTK_BL31_STATUS_PERMISSION_DENY = -4,
+ MTK_BL31_STATUS_LOCK_FAIL = -5,
+};
+
+int mtk_bl31_map_to_sip_error(enum mtk_bl31_status status);
+
+enum mtk_bl31_memory_type {
+ MTK_BL31_DEV_RW_SEC = 0,
+};
+
+int mtk_bl31_mmap_add_dynamic_region(unsigned long long base_pa, size_t size,
+ enum mtk_bl31_memory_type attr);
+int mtk_bl31_mmap_remove_dynamic_region(uintptr_t base_va, size_t size);
+
/* UFS definitions */
enum ufs_mtk_mphy_op {
UFS_MPHY_BACKUP = 0,
@@ -31,4 +51,41 @@
void ufs_mphy_ctrl(enum ufs_mtk_mphy_op op);
void ufs_mtcmos_ctrl(bool on);
+/* UFS functions implemented in the public ATF repo */
+int ufs_rsc_ctrl_mem(bool hold);
+int ufs_rsc_ctrl_pmic(bool hold);
+void ufs_device_pwr_ctrl_soc(bool vcc_on, uint64_t ufs_version);
+int ufs_spm_mtcmos_power(bool on);
+int ufs_phy_spm_mtcmos_power(bool on);
+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);
+
+/* CPU QoS interfaces */
+void cpu_qos_change_dcc(uint32_t on, uint32_t is_auto);
+void *cpu_qos_handle_cluster_on_event(const void *arg);
+
+/* SMMU sid interfaces */
+int smmu_sid_init(void);
+
#endif /* __MTK_BL31_INTERFACE_H__ */
diff --git a/plat/mediatek/mt8189/include/platform_def.h b/plat/mediatek/mt8189/include/platform_def.h
index e61aaa2..067ebcc 100644
--- a/plat/mediatek/mt8189/include/platform_def.h
+++ b/plat/mediatek/mt8189/include/platform_def.h
@@ -45,6 +45,12 @@
#define UART_BAUDRATE (115200)
/*******************************************************************************
+ * Infra IOMMU related constants
+ ******************************************************************************/
+#define PERICFG_AO_BASE (IO_PHYS + 0x01036000)
+#define PERICFG_AO_REG_SIZE (0x1000)
+
+/*******************************************************************************
* CIRQ related constants
******************************************************************************/
#define SYS_CIRQ_BASE (IO_PHYS + 204000)
@@ -54,6 +60,29 @@
#define CIRQ_IRQ_NUM (598)
/*******************************************************************************
+ * MM IOMMU & SMI related constants
+ ******************************************************************************/
+#define SMI_LARB_0_BASE (IO_PHYS + 0x0401c000)
+#define SMI_LARB_1_BASE (IO_PHYS + 0x0401d000)
+#define SMI_LARB_2_BASE (IO_PHYS + 0x0f002000)
+#define SMI_LARB_4_BASE (IO_PHYS + 0x0602e000)
+#define SMI_LARB_7_BASE (IO_PHYS + 0x07010000)
+#define SMI_LARB_9_BASE (IO_PHYS + 0x0502e000)
+#define SMI_LARB_11_BASE (IO_PHYS + 0x0582e000)
+#define SMI_LARB_13_BASE (IO_PHYS + 0x0a001000)
+#define SMI_LARB_14_BASE (IO_PHYS + 0x0a002000)
+#define SMI_LARB_16_BASE (IO_PHYS + 0x0a00f000)
+#define SMI_LARB_17_BASE (IO_PHYS + 0x0a010000)
+#define SMI_LARB_19_BASE (IO_PHYS + 0x0b10f000)
+#define SMI_LARB_20_BASE (IO_PHYS + 0x0b00f000)
+#define SMI_LARB_REG_RNG_SIZE (0x1000)
+
+#define MM_IOMMU_BASE (IO_PHYS + 0x0e802000 + 0x4000)
+#define APU_IOMMU_BASE (IO_PHYS + 0x09010000)
+
+#define IOMMU_REG_RNG_SIZE (0x5000)
+
+/*******************************************************************************
* System counter frequency related constants
******************************************************************************/
#define SYS_COUNTER_FREQ_IN_HZ (13000000)
diff --git a/plat/mediatek/mt8189/platform.mk b/plat/mediatek/mt8189/platform.mk
index 238c76d..c0c0427 100644
--- a/plat/mediatek/mt8189/platform.mk
+++ b/plat/mediatek/mt8189/platform.mk
@@ -29,6 +29,7 @@
MODULES-y += $(MTK_PLAT)/topology
MODULES-y += $(MTK_PLAT)/drivers/cirq
MODULES-y += $(MTK_PLAT)/drivers/gic600
+MODULES-y += $(MTK_PLAT)/drivers/iommu
MODULES-y += $(MTK_PLAT)/drivers/mcusys
MODULES-y += $(MTK_PLAT)/drivers/timer
diff --git a/plat/mediatek/mt8196/include/platform_def.h b/plat/mediatek/mt8196/include/platform_def.h
index 363c8cc..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
@@ -341,4 +342,10 @@
#define SSPM_CFGREG_BASE (IO_PHYS + 0x0C300000 + SSPM_REG_OFFSET)
#define SSPM_CFGREG_SIZE (0x1000)
+/*******************************************************************************
+ * MMinfra related constants
+ ******************************************************************************/
+#define MTK_VLP_TRACER_MON_BASE (IO_PHYS + 0x0c000000)
+#define MTK_VLP_TRACER_MON_REG_SIZE (0x1000)
+
#endif /* PLATFORM_DEF_H */
diff --git a/plat/mediatek/mt8196/plat_config.mk b/plat/mediatek/mt8196/plat_config.mk
index 7412756..e0dd87e 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
@@ -61,6 +60,7 @@
CONFIG_MTK_PMIC_LOWPOWER := y
CONFIG_MTK_PMIC_SHUTDOWN_CFG := y
CONFIG_MTK_PMIC_SPT_SUPPORT := n
+CONFIG_MTK_SMMU_SID := y
CONFIG_MTK_SPMI := y
PMIC_CHIP := mt6363
diff --git a/plat/mediatek/mt8196/platform.mk b/plat/mediatek/mt8196/platform.mk
index 14cd5a0..e98ec4b 100644
--- a/plat/mediatek/mt8196/platform.mk
+++ b/plat/mediatek/mt8196/platform.mk
@@ -45,11 +45,13 @@
MODULES-y += $(MTK_PLAT)/lib/system_reset
MODULES-y += $(MTK_PLAT)/drivers/apusys
MODULES-y += $(MTK_PLAT)/drivers/cirq
+MODULES-y += $(MTK_PLAT)/drivers/cpu_qos
MODULES-y += $(MTK_PLAT)/drivers/dp
MODULES-y += $(MTK_PLAT)/drivers/emi
MODULES-y += $(MTK_PLAT)/drivers/gicv3
MODULES-y += $(MTK_PLAT)/drivers/mcusys
MODULES-y += $(MTK_PLAT)/drivers/mminfra
+MODULES-y += $(MTK_PLAT)/drivers/slbc
MODULES-y += $(MTK_PLAT)/drivers/smmu
MODULES-y += $(MTK_PLAT)/drivers/spm
MODULES-y += $(MTK_PLAT)/drivers/timer
@@ -59,6 +61,7 @@
MODULES-y += $(MTK_PLAT)/topology
MODULES-$(CONFIG_MTK_CPU_PM_SUPPORT) += $(MTK_PLAT)/drivers/cpu_pm
MODULES-$(CONFIG_MTK_PMIC) += $(MTK_PLAT)/drivers/pmic
+MODULES-$(CONFIG_MTK_SMMU_SID) += $(MTK_PLAT)/drivers/smmu_sid
MODULES-$(CONFIG_MTK_SPMI) += $(MTK_PLAT)/drivers/spmi
MODULES-$(CONFIG_MTK_MTCMOS) += $(MTK_PLAT)/drivers/mtcmos
diff --git a/plat/qemu/common/qemu_spm.c b/plat/qemu/common/qemu_spm.c
index abedbe4..873b97b 100644
--- a/plat/qemu/common/qemu_spm.c
+++ b/plat/qemu/common/qemu_spm.c
@@ -129,7 +129,9 @@
{
uintptr_t ns_buf_base;
- dt_add_ns_buf_node(&ns_buf_base);
+ if (dt_add_ns_buf_node(&ns_buf_base) != 0) {
+ panic();
+ }
plat_qemu_secure_partition_mmap[0].base_pa = ns_buf_base;
plat_qemu_secure_partition_mmap[0].base_va = ns_buf_base;
diff --git a/plat/st/stm32mp2/stm32mp2_def.h b/plat/st/stm32mp2/stm32mp2_def.h
index 1b8c4f5..90dbcb8 100644
--- a/plat/st/stm32mp2/stm32mp2_def.h
+++ b/plat/st/stm32mp2/stm32mp2_def.h
@@ -386,7 +386,7 @@
#define DDRPHYC_BASE U(0x48C00000)
/*******************************************************************************
- * Miscellaneous STM32MP1 peripherals base address
+ * Miscellaneous STM32MP2 peripherals base address
******************************************************************************/
#define BSEC_BASE U(0x44000000)
#define DBGMCU_BASE U(0x4A010000)
diff --git a/plat/xilinx/zynqmp/custom_sip_svc.c b/plat/xilinx/common/custom_sip_svc.c
similarity index 90%
rename from plat/xilinx/zynqmp/custom_sip_svc.c
rename to plat/xilinx/common/custom_sip_svc.c
index c39e4be..2cefb78 100644
--- a/plat/xilinx/zynqmp/custom_sip_svc.c
+++ b/plat/xilinx/common/custom_sip_svc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
diff --git a/plat/xilinx/zynqmp/include/custom_svc.h b/plat/xilinx/common/include/custom_svc.h
similarity index 71%
rename from plat/xilinx/zynqmp/include/custom_svc.h
rename to plat/xilinx/common/include/custom_svc.h
index 242f3eb..2884b69 100644
--- a/plat/xilinx/zynqmp/include/custom_svc.h
+++ b/plat/xilinx/common/include/custom_svc.h
@@ -1,13 +1,13 @@
/*
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef CUSTOM_SVC_H
#define CUSTOM_SVC_H
-#define ZYNQMP_SIP_SVC_CUSTOM U(0x82002000)
-#define ZYNQMP_SIP_SVC64_CUSTOM U(0xC2002000)
+#define SOC_SIP_SVC_CUSTOM U(0x82002000)
+#define SOC_SIP_SVC64_CUSTOM U(0xC2002000)
uint64_t custom_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2,
uint64_t x3, uint64_t x4, void *cookie,
diff --git a/plat/xilinx/common/include/ipi.h b/plat/xilinx/common/include/ipi.h
index 71c06c3..c628496 100644
--- a/plat/xilinx/common/include/ipi.h
+++ b/plat/xilinx/common/include/ipi.h
@@ -38,9 +38,9 @@
/* structure to maintain IPI configuration information */
struct ipi_config {
- unsigned int ipi_bit_mask;
- unsigned int ipi_reg_base;
- unsigned char secure_only;
+ uint32_t ipi_bit_mask;
+ uint32_t ipi_reg_base;
+ uint8_t secure_only;
};
/*********************************************************************
@@ -52,7 +52,7 @@
uint32_t total_ipi);
/* Validate IPI mailbox access */
-int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure);
+int32_t ipi_mb_validate(uint32_t local, uint32_t remote, uint32_t is_secure);
/* Open the IPI mailbox */
void ipi_mb_open(uint32_t local, uint32_t remote);
diff --git a/plat/xilinx/common/include/pm_api_sys.h b/plat/xilinx/common/include/pm_api_sys.h
index 793b270..fc55cc3 100644
--- a/plat/xilinx/common/include/pm_api_sys.h
+++ b/plat/xilinx/common/include/pm_api_sys.h
@@ -60,7 +60,8 @@
* Assigning of argument values into array elements.
*/
#define PM_PACK_PAYLOAD1(pl, mid, flag, arg0) { \
- pl[0] = (uint32_t)(((uint32_t)(arg0) & 0xFFU) | ((mid) << 8U) | ((flag) << 24U)); \
+ pl[0] = (uint32_t)(((uint32_t)(arg0) & 0xFFU) | \
+ ((uint32_t)(mid) << 8U) | ((uint32_t)(flag) << 24U)); \
}
#define PM_PACK_PAYLOAD2(pl, mid, flag, arg0, arg1) { \
diff --git a/plat/xilinx/common/include/pm_common.h b/plat/xilinx/common/include/pm_common.h
index 68d1db2..5e53ec6 100644
--- a/plat/xilinx/common/include/pm_common.h
+++ b/plat/xilinx/common/include/pm_common.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.
- * Copyright (c) 2022-2024, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -29,9 +29,9 @@
#define RET_PAYLOAD_ARG_CNT 6U
#define PAYLOAD_ARG_SIZE 4U /* size in bytes */
-#define TZ_VERSION_MAJOR 1
-#define TZ_VERSION_MINOR 0
-#define TZ_VERSION ((TZ_VERSION_MAJOR << 16) | \
+#define TZ_VERSION_MAJOR 1U
+#define TZ_VERSION_MINOR 0U
+#define TZ_VERSION (((uint32_t)TZ_VERSION_MAJOR << 16U) | \
TZ_VERSION_MINOR)
/**
diff --git a/plat/xilinx/common/include/pm_defs.h b/plat/xilinx/common/include/pm_defs.h
index 352257a..3901555 100644
--- a/plat/xilinx/common/include/pm_defs.h
+++ b/plat/xilinx/common/include/pm_defs.h
@@ -22,7 +22,6 @@
#define PM_STATE_SUSPEND_TO_RAM 0xFU
#define MAX_LATENCY (~0U)
-#define MAX_QOS 100U
/* Processor core device IDs */
#define APU_DEVID(IDX) NODEID(XPM_NODECLASS_DEVICE, XPM_NODESUBCL_DEV_CORE, \
@@ -209,7 +208,7 @@
* @PM_RET_SUCCESS: success.
* @PM_RET_ERROR_ARGS: illegal arguments provided (deprecated).
* @PM_RET_ERROR_NOTSUPPORTED: feature not supported (deprecated).
- * @PM_RET_ERROR_NOFEATURE: feature is not available.
+ * @PM_RET_ERROR_IOCTL_NOT_SUPPORTED: IOCTL is not supported.
* @PM_RET_ERROR_INVALID_CRC: invalid crc in IPI communication.
* @PM_RET_ERROR_NOT_ENABLED: feature is not enabled.
* @PM_RET_ERROR_INTERNAL: internal error.
@@ -224,21 +223,21 @@
* supported.
*/
enum pm_ret_status {
- PM_RET_SUCCESS,
- PM_RET_ERROR_ARGS = 1,
- PM_RET_ERROR_NOTSUPPORTED = 4,
- PM_RET_ERROR_NOFEATURE = 19,
- PM_RET_ERROR_INVALID_CRC = 301,
- PM_RET_ERROR_NOT_ENABLED = 29,
- PM_RET_ERROR_INTERNAL = 2000,
- PM_RET_ERROR_CONFLICT = 2001,
- PM_RET_ERROR_ACCESS = 2002,
- PM_RET_ERROR_INVALID_NODE = 2003,
- PM_RET_ERROR_DOUBLE_REQ = 2004,
- PM_RET_ERROR_ABORT_SUSPEND = 2005,
- PM_RET_ERROR_TIMEOUT = 2006,
- PM_RET_ERROR_NODE_USED = 2007,
- PM_RET_ERROR_NO_FEATURE = 2008
+ PM_RET_SUCCESS = 0U,
+ PM_RET_ERROR_ARGS = 1U,
+ PM_RET_ERROR_NOTSUPPORTED = 4U,
+ PM_RET_ERROR_IOCTL_NOT_SUPPORTED = 19U,
+ PM_RET_ERROR_NOT_ENABLED = 29U,
+ PM_RET_ERROR_INVALID_CRC = 301U,
+ PM_RET_ERROR_INTERNAL = 2000U,
+ PM_RET_ERROR_CONFLICT = 2001U,
+ PM_RET_ERROR_ACCESS = 2002U,
+ PM_RET_ERROR_INVALID_NODE = 2003U,
+ PM_RET_ERROR_DOUBLE_REQ = 2004U,
+ PM_RET_ERROR_ABORT_SUSPEND = 2005U,
+ PM_RET_ERROR_TIMEOUT = 2006U,
+ PM_RET_ERROR_NODE_USED = 2007U,
+ PM_RET_ERROR_NO_FEATURE = 2008U
};
/*
diff --git a/plat/xilinx/common/include/pm_node.h b/plat/xilinx/common/include/pm_node.h
index 3ee55c2..0efebdf 100644
--- a/plat/xilinx/common/include/pm_node.h
+++ b/plat/xilinx/common/include/pm_node.h
@@ -22,10 +22,6 @@
#define NODE_SUBCLASS_MASK_BITS GENMASK_32(5, 0)
#define NODE_TYPE_MASK_BITS GENMASK_32(5, 0)
#define NODE_INDEX_MASK_BITS GENMASK_32(13, 0)
-#define NODE_CLASS_MASK (NODE_CLASS_MASK_BITS << NODE_CLASS_SHIFT)
-#define NODE_SUBCLASS_MASK (NODE_SUBCLASS_MASK_BITS << NODE_SUBCLASS_SHIFT)
-#define NODE_TYPE_MASK (NODE_TYPE_MASK_BITS << NODE_TYPE_SHIFT)
-#define NODE_INDEX_MASK (NODE_INDEX_MASK_BITS << NODE_INDEX_SHIFT)
#define NODEID(CLASS, SUBCLASS, TYPE, INDEX) \
((((CLASS) & NODE_CLASS_MASK_BITS) << NODE_CLASS_SHIFT) | \
@@ -33,12 +29,6 @@
(((TYPE) & NODE_TYPE_MASK_BITS) << NODE_TYPE_SHIFT) | \
(((INDEX) & NODE_INDEX_MASK_BITS) << NODE_INDEX_SHIFT))
-#define NODECLASS(ID) (((ID) & NODE_CLASS_MASK) >> NODE_CLASS_SHIFT)
-#define NODESUBCLASS(ID) (((ID) & NODE_SUBCLASS_MASK) >> \
- NODE_SUBCLASS_SHIFT)
-#define NODETYPE(ID) (((ID) & NODE_TYPE_MASK) >> NODE_TYPE_SHIFT)
-#define NODEINDEX(ID) (((ID) & NODE_INDEX_MASK) >> NODE_INDEX_SHIFT)
-
/*********************************************************************
* Enum definitions
********************************************************************/
diff --git a/plat/xilinx/common/ipi.c b/plat/xilinx/common/ipi.c
index 18ae096..8dc6da0 100644
--- a/plat/xilinx/common/ipi.c
+++ b/plat/xilinx/common/ipi.c
@@ -67,12 +67,12 @@
* Return: - 1 if within range, 0 if not.
*
*/
-static inline int is_ipi_mb_within_range(uint32_t local, uint32_t remote)
+static inline uint32_t is_ipi_mb_within_range(uint32_t local, uint32_t remote)
{
- int ret = 1;
+ uint32_t ret = 1U;
if ((remote >= ipi_total) || (local >= ipi_total)) {
- ret = 0;
+ ret = 0U;
}
return ret;
@@ -87,11 +87,11 @@
* Return: 0 success, negative value for errors.
*
*/
-int ipi_mb_validate(uint32_t local, uint32_t remote, unsigned int is_secure)
+int32_t ipi_mb_validate(uint32_t local, uint32_t remote, uint32_t is_secure)
{
- int ret = 0;
+ int32_t ret = 0;
- if (is_ipi_mb_within_range(local, remote) == 0) {
+ if (is_ipi_mb_within_range(local, remote) == 0U) {
ret = -EINVAL;
} else if (IPI_IS_SECURE(local) && (is_secure == 0U)) {
ret = -EPERM;
diff --git a/plat/xilinx/common/pm_service/pm_api_sys.c b/plat/xilinx/common/pm_service/pm_api_sys.c
index 4390b55..efb9286 100644
--- a/plat/xilinx/common/pm_service/pm_api_sys.c
+++ b/plat/xilinx/common/pm_service/pm_api_sys.c
@@ -409,6 +409,7 @@
break;
default:
ret = PM_RET_ERROR_NO_FEATURE;
+ break;
}
return ret;
@@ -439,33 +440,31 @@
case PM_GET_TRUSTZONE_VERSION:
ret_payload[0] = PM_API_VERSION_2;
ret = PM_RET_SUCCESS;
- goto exit_label;
+ break;
case TF_A_PM_REGISTER_SGI:
ret_payload[0] = PM_API_BASE_VERSION;
ret = PM_RET_SUCCESS;
- goto exit_label;
- default:
break;
- }
+ default:
+ module_id = (api_id & MODULE_ID_MASK) >> 8U;
- module_id = (api_id & MODULE_ID_MASK) >> 8U;
+ /*
+ * feature check should be done only for LIBPM module
+ * If module_id is 0, then we consider it LIBPM module as default id
+ */
+ if ((module_id > 0U) && (module_id != LIBPM_MODULE_ID)) {
+ ret = PM_RET_SUCCESS;
+ break;
+ }
- /*
- * feature check should be done only for LIBPM module
- * If module_id is 0, then we consider it LIBPM module as default id
- */
- if ((module_id > 0U) && (module_id != LIBPM_MODULE_ID)) {
- ret = PM_RET_SUCCESS;
- goto exit_label;
- }
+ PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
+ PM_FEATURE_CHECK, api_id);
+ ret = pm_ipi_send_sync(primary_proc, payload, ret_payload, RET_PAYLOAD_ARG_CNT);
- PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, flag,
- PM_FEATURE_CHECK, api_id);
- ret = pm_ipi_send_sync(primary_proc, payload, ret_payload, RET_PAYLOAD_ARG_CNT);
+ break;
+ }
-exit_label:
return ret;
-
}
/**
diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c
index 86b55ab..38c36e5 100644
--- a/plat/xilinx/common/pm_service/pm_ipi.c
+++ b/plat/xilinx/common/pm_service/pm_ipi.c
@@ -312,7 +312,7 @@
}
#if IPI_CRC_CHECK
-uint32_t calculate_crc(uint32_t payload[PAYLOAD_ARG_CNT], uint32_t bufsize)
+uint32_t calculate_crc(uint32_t payload[PAYLOAD_ARG_CNT], uint32_t buffersize)
{
uint32_t crcinit = CRC_INIT_VALUE;
uint32_t order = CRC_ORDER;
@@ -320,20 +320,22 @@
uint32_t i, j, c, bit, datain, crcmask, crchighbit;
uint32_t crc = crcinit;
- crcmask = ((uint32_t)((1U << (order - 1U)) - 1U) << 1U) | 1U;
- crchighbit = (uint32_t)(1U << (order - 1U));
+ crcmask = ((((uint32_t)1U << (order - 1U)) - 1U) << 1U) | 1U;
+ crchighbit = ((uint32_t)1U << (order - 1U));
- for (i = 0U; i < bufsize; i++) {
+ for (i = 0U; i < buffersize; i++) {
datain = mmio_read_8((unsigned long)payload + i);
c = datain;
j = 0x80U;
while (j != 0U) {
bit = crc & crchighbit;
crc <<= 1U;
- if (0U != (c & j))
+ if (0U != (c & j)) {
bit ^= crchighbit;
- if (bit != 0U)
+ }
+ if (bit != 0U) {
crc ^= polynom;
+ }
j >>= 1U;
}
crc &= crcmask;
diff --git a/plat/xilinx/common/pm_service/pm_svc_main.c b/plat/xilinx/common/pm_service/pm_svc_main.c
index cb9273a..77ebb62 100644
--- a/plat/xilinx/common/pm_service/pm_svc_main.c
+++ b/plat/xilinx/common/pm_service/pm_svc_main.c
@@ -29,7 +29,6 @@
#define MODE 0x80000000U
-#define XSCUGIC_SGIR_EL1_INITID_SHIFT 24U
#define INVALID_SGI 0xFFU
#define PM_INIT_SUSPEND_CB (30U)
#define PM_NOTIFY_CB (32U)
@@ -303,7 +302,7 @@
* until their use case in linux driver changes.
*
*/
-static uintptr_t eemi_for_compatibility(uint32_t api_id, uint32_t *pm_arg,
+static uintptr_t eemi_for_compatibility(uint32_t api_id, const uint32_t *pm_arg,
void *handle, uint32_t security_flag)
{
enum pm_ret_status ret;
@@ -348,7 +347,7 @@
* Return: If EEMI API found then, uintptr_t type address, else 0.
*
*/
-static uintptr_t eemi_psci_debugfs_handler(uint32_t api_id, uint32_t *pm_arg,
+static uintptr_t eemi_psci_debugfs_handler(uint32_t api_id, const uint32_t *pm_arg,
void *handle, uint32_t security_flag)
{
enum pm_ret_status ret;
@@ -396,7 +395,7 @@
* Return: If TF-A specific API found then, uintptr_t type address, else 0
*
*/
-static uintptr_t TF_A_specific_handler(uint32_t api_id, uint32_t *pm_arg,
+static uintptr_t TF_A_specific_handler(uint32_t api_id, const uint32_t *pm_arg,
void *handle, uint32_t security_flag)
{
switch (api_id) {
@@ -463,7 +462,7 @@
* Return: If EEMI API found then, uintptr_t type address, else 0
*
*/
-static uintptr_t eemi_handler(uint32_t api_id, uint32_t *pm_arg,
+static uintptr_t eemi_handler(uint32_t api_id, const uint32_t *pm_arg,
void *handle, uint32_t security_flag)
{
enum pm_ret_status ret;
diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c
index befe36c..70b0fa6 100644
--- a/plat/xilinx/versal/bl31_versal_setup.c
+++ b/plat/xilinx/versal/bl31_versal_setup.c
@@ -18,8 +18,9 @@
#include <plat/common/platform.h>
#include <plat_arm.h>
#include <plat_console.h>
-#include <plat_clkfunc.h>
+#include <custom_svc.h>
+#include <plat_clkfunc.h>
#include <plat_fdt.h>
#include <plat_private.h>
#include <plat_startup.h>
@@ -143,6 +144,8 @@
NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc);
NOTICE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc);
+
+ custom_early_setup();
}
static versal_intr_info_type_el3_t type_el3_interrupt_table[MAX_INTR_EL3];
@@ -220,6 +223,8 @@
if (rc != 0) {
panic();
}
+
+ custom_runtime_setup();
}
/*
@@ -248,6 +253,8 @@
{0}
};
+ custom_mmap_add();
+
setup_page_tables(bl_regions, plat_get_mmap());
enable_mmu(0);
}
diff --git a/plat/xilinx/versal/include/platform_def.h b/plat/xilinx/versal/include/platform_def.h
index a3886a4..d8b334a 100644
--- a/plat/xilinx/versal/include/platform_def.h
+++ b/plat/xilinx/versal/include/platform_def.h
@@ -17,7 +17,9 @@
******************************************************************************/
/* Size of cacheable stacks */
+#ifndef PLATFORM_STACK_SIZE
#define PLATFORM_STACK_SIZE U(0x440)
+#endif
#define PLATFORM_CORE_COUNT U(2)
#define PLAT_MAX_PWR_LVL U(1)
diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk
index 8be4be6..83d2d6f 100644
--- a/plat/xilinx/versal/platform.mk
+++ b/plat/xilinx/versal/platform.mk
@@ -144,3 +144,9 @@
CORTEX_A72_H_INC := 1
$(eval $(call add_define, CORTEX_A72_H_INC))
endif
+
+ifdef CUSTOM_PKG_PATH
+include $(CUSTOM_PKG_PATH)/custom_pkg.mk
+else
+BL31_SOURCES += plat/xilinx/common/custom_sip_svc.c
+endif
diff --git a/plat/xilinx/versal/sip_svc_setup.c b/plat/xilinx/versal/sip_svc_setup.c
index bb3f728..5e7ce9e 100644
--- a/plat/xilinx/versal/sip_svc_setup.c
+++ b/plat/xilinx/versal/sip_svc_setup.c
@@ -13,6 +13,7 @@
#include <common/runtime_svc.h>
#include <tools_share/uuid.h>
+#include <custom_svc.h>
#include "ipi_mailbox_svc.h"
#include "pm_svc_main.h"
@@ -105,6 +106,11 @@
case VERSAL_SIP_SVC_VERSION:
SMC_RET2(handle, SIP_SVC_VERSION_MAJOR, SIP_SVC_VERSION_MINOR);
+ case SOC_SIP_SVC_CUSTOM:
+ case SOC_SIP_SVC64_CUSTOM:
+ return custom_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
+ handle, flags);
+
default:
WARN("Unimplemented SiP Service Call: 0x%x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);
diff --git a/plat/xilinx/versal_net/plat_psci.c b/plat/xilinx/versal_net/plat_psci.c
index fcb32b9..399500d 100644
--- a/plat/xilinx/versal_net/plat_psci.c
+++ b/plat/xilinx/versal_net/plat_psci.c
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
* Copyright (c) 2021-2022, Xilinx, Inc. All rights reserved.
- * Copyright (c) 2022-2023, Advanced Micro Devices, Inc. All rights reserved.
+ * Copyright (c) 2022-2025, Advanced Micro Devices, Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -19,8 +19,6 @@
#include <plat_private.h>
#include <pm_defs.h>
-#define PM_RET_ERROR_NOFEATURE U(19)
-
static uintptr_t versal_net_sec_entry;
static void zynqmp_cpu_standby(plat_local_state_t cpu_state)
@@ -175,7 +173,7 @@
mmio_write_32(SLCR_OSPI_QSPI_IOU_AXI_MUX_SEL, arg1);
return 0;
}
- return PM_RET_ERROR_NOFEATURE;
+ return PM_RET_ERROR_IOCTL_NOT_SUPPORTED;
}
static uint64_t no_pm_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3,
diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk
index 27e5427..d2cb220 100644
--- a/plat/xilinx/zynqmp/platform.mk
+++ b/plat/xilinx/zynqmp/platform.mk
@@ -162,7 +162,7 @@
ifdef CUSTOM_PKG_PATH
include $(CUSTOM_PKG_PATH)/custom_pkg.mk
else
-BL31_SOURCES += plat/xilinx/zynqmp/custom_sip_svc.c
+BL31_SOURCES += plat/xilinx/common/custom_sip_svc.c
endif
ifneq (${RESET_TO_BL31},1)
diff --git a/plat/xilinx/zynqmp/sip_svc_setup.c b/plat/xilinx/zynqmp/sip_svc_setup.c
index 1baefb3..6d94422 100644
--- a/plat/xilinx/zynqmp/sip_svc_setup.c
+++ b/plat/xilinx/zynqmp/sip_svc_setup.c
@@ -105,8 +105,8 @@
case ZYNQMP_SIP_SVC_VERSION:
SMC_RET2(handle, SIP_SVC_VERSION_MAJOR, SIP_SVC_VERSION_MINOR);
- case ZYNQMP_SIP_SVC_CUSTOM:
- case ZYNQMP_SIP_SVC64_CUSTOM:
+ case SOC_SIP_SVC_CUSTOM:
+ case SOC_SIP_SVC64_CUSTOM:
return custom_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
handle, flags);
diff --git a/services/el3/ven_el3_svc.c b/services/el3/ven_el3_svc.c
index 32a3dc2..431bfbf 100644
--- a/services/el3/ven_el3_svc.c
+++ b/services/el3/ven_el3_svc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2024-2025, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,6 +10,9 @@
#include <common/runtime_svc.h>
#include <lib/debugfs.h>
#include <lib/pmf/pmf.h>
+#if PLAT_ARM_ACS_SMC_HANDLER
+#include <plat/arm/common/plat_acs_smc_handler.h>
+#endif /* PLAT_ARM_ACS_SMC_HANDLER */
#include <services/ven_el3_svc.h>
#include <tools_share/uuid.h>
@@ -71,6 +74,15 @@
#endif /* ENABLE_PMF */
+#if PLAT_ARM_ACS_SMC_HANDLER
+ /*
+ * Dispatch ACS calls to ACS SMC handler and return its return value
+ */
+ if (is_acs_fid(smc_fid)) {
+ return plat_arm_acs_smc_handler(smc_fid, x1, x2, x3, x4, handle);
+ }
+#endif /* PLAT_ARM_ACS_SMC_HANDLER */
+
switch (smc_fid) {
case VEN_EL3_SVC_UID:
/* Return UID to the caller */