aboutsummaryrefslogtreecommitdiff
path: root/platform/ext/target/arm/mps2/an519/target_cfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'platform/ext/target/arm/mps2/an519/target_cfg.c')
-rw-r--r--platform/ext/target/arm/mps2/an519/target_cfg.c478
1 files changed, 478 insertions, 0 deletions
diff --git a/platform/ext/target/arm/mps2/an519/target_cfg.c b/platform/ext/target/arm/mps2/an519/target_cfg.c
new file mode 100644
index 0000000000..e61858b86b
--- /dev/null
+++ b/platform/ext/target/arm/mps2/an519/target_cfg.c
@@ -0,0 +1,478 @@
+/*
+ * Copyright (c) 2018-2024, Arm Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "tfm_hal_device_header.h"
+#include "target_cfg.h"
+#include "Driver_MPC.h"
+#include "platform_retarget_dev.h"
+#include "region_defs.h"
+#include "tfm_plat_defs.h"
+#include "region.h"
+
+#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
+
+/* The section names come from the scatter file */
+REGION_DECLARE(Load$$LR$$, LR_NS_PARTITION, $$Base);
+REGION_DECLARE(Image$$, ER_VENEER, $$Base);
+REGION_DECLARE(Image$$, VENEER_ALIGN, $$Limit);
+#ifdef BL2
+REGION_DECLARE(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base);
+#endif /* BL2 */
+
+const struct memory_region_limits memory_regions = {
+ .non_secure_code_start =
+ (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
+ BL2_HEADER_SIZE,
+
+ .non_secure_partition_base =
+ (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base),
+
+ .non_secure_partition_limit =
+ (uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
+ NS_PARTITION_SIZE - 1,
+
+ .veneer_base =
+ (uint32_t)&REGION_NAME(Image$$, ER_VENEER, $$Base),
+
+ .veneer_limit =
+ (uint32_t)&REGION_NAME(Image$$, VENEER_ALIGN, $$Limit),
+
+#ifdef BL2
+ .secondary_partition_base =
+ (uint32_t)&REGION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base),
+
+ .secondary_partition_limit =
+ (uint32_t)&REGION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base) +
+ SECONDARY_PARTITION_SIZE - 1,
+#endif /* BL2 */
+};
+
+/* Allows software, via SAU, to define the code region as a NSC */
+#define NSCCFG_CODENSC 1
+
+/* Import MPC driver */
+extern ARM_DRIVER_MPC Driver_SRAM1_MPC, Driver_SRAM2_MPC;
+
+/* Define Peripherals NS address range for the platform */
+#define PERIPHERALS_BASE_NS_START (0x40000000)
+#define PERIPHERALS_BASE_NS_END (0x4FFFFFFF)
+
+/* Enable system reset request for CPU 0 */
+#define ENABLE_CPU0_SYSTEM_RESET_REQUEST (1U << 4U)
+
+/* To write into AIRCR register, 0x5FA value must be write to the VECTKEY field,
+ * otherwise the processor ignores the write.
+ */
+#define SCB_AIRCR_WRITE_MASK ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos))
+
+/* Debug configuration flags */
+#define SPNIDEN_SEL_STATUS (0x01u << 7)
+#define SPNIDEN_STATUS (0x01u << 6)
+#define SPIDEN_SEL_STATUS (0x01u << 5)
+#define SPIDEN_STATUS (0x01u << 4)
+#define NIDEN_SEL_STATUS (0x01u << 3)
+#define NIDEN_STATUS (0x01u << 2)
+#define DBGEN_SEL_STATUS (0x01u << 1)
+#define DBGEN_STATUS (0x01u << 0)
+
+#define All_SEL_STATUS (SPNIDEN_SEL_STATUS | SPIDEN_SEL_STATUS | \
+ NIDEN_SEL_STATUS | DBGEN_SEL_STATUS)
+
+struct platform_data_t tfm_peripheral_std_uart = {
+ UART0_BASE_NS,
+ UART0_BASE_NS + 0xFFF,
+ PPC_SP_DO_NOT_CONFIGURE,
+ -1
+};
+
+struct platform_data_t tfm_peripheral_uart1 = {
+ UART1_BASE_S,
+ UART1_BASE_S + 0xFFF,
+ PPC_SP_APB_PPC_EXP1,
+ CMSDK_UART1_APB_PPC_POS
+};
+
+struct platform_data_t tfm_peripheral_timer0 = {
+ CMSDK_TIMER0_BASE_S,
+ CMSDK_TIMER1_BASE_S - 1,
+ PPC_SP_APB_PPC0,
+ CMSDK_TIMER0_APB_PPC_POS
+};
+
+enum tfm_plat_err_t enable_fault_handlers(void)
+{
+ /* Secure fault is not present in the Baseline implementation. */
+ /* Fault handler enable registers are not present in a Baseline
+ * implementation.
+ */
+ return TFM_PLAT_ERR_SUCCESS;
+}
+
+enum tfm_plat_err_t system_reset_cfg(void)
+{
+ struct sysctrl_t *sysctrl = (struct sysctrl_t *)CMSDK_SYSCTRL_BASE_S;
+ uint32_t reg_value = SCB->AIRCR;
+
+ /* Enable system reset request for CPU 0, to be triggered via
+ * NVIC_SystemReset function.
+ */
+ sysctrl->resetmask |= ENABLE_CPU0_SYSTEM_RESET_REQUEST;
+
+ /* Clear SCB_AIRCR_VECTKEY value */
+ reg_value &= ~(uint32_t)(SCB_AIRCR_VECTKEY_Msk);
+
+ /* Enable system reset request for the secure world only */
+ reg_value |= (uint32_t)(SCB_AIRCR_WRITE_MASK | SCB_AIRCR_SYSRESETREQS_Msk);
+
+ SCB->AIRCR = reg_value;
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
+
+enum tfm_plat_err_t init_debug(void)
+{
+ volatile struct sysctrl_t *sys_ctrl =
+ (struct sysctrl_t *)CMSDK_SYSCTRL_BASE_S;
+
+#if defined(DAUTH_NONE)
+ /* Set all the debug enable selector bits to 1 */
+ sys_ctrl->secdbgset = All_SEL_STATUS;
+ /* Set all the debug enable bits to 0 */
+ sys_ctrl->secdbgclr =
+ DBGEN_STATUS | NIDEN_STATUS | SPIDEN_STATUS | SPNIDEN_STATUS;
+#elif defined(DAUTH_NS_ONLY)
+ /* Set all the debug enable selector bits to 1 */
+ sys_ctrl->secdbgset = All_SEL_STATUS;
+ /* Set the debug enable bits to 1 for NS, and 0 for S mode */
+ sys_ctrl->secdbgset = DBGEN_STATUS | NIDEN_STATUS;
+ sys_ctrl->secdbgclr = SPIDEN_STATUS | SPNIDEN_STATUS;
+#elif defined(DAUTH_FULL)
+ /* Set all the debug enable selector bits to 1 */
+ sys_ctrl->secdbgset = All_SEL_STATUS;
+ /* Set all the debug enable bits to 1 */
+ sys_ctrl->secdbgset =
+ DBGEN_STATUS | NIDEN_STATUS | SPIDEN_STATUS | SPNIDEN_STATUS;
+#else
+
+#if !defined(DAUTH_CHIP_DEFAULT)
+#error "No debug authentication setting is provided."
+#endif
+
+ /* Set all the debug enable selector bits to 0 */
+ sys_ctrl->secdbgclr = All_SEL_STATUS;
+
+ /* No need to set any enable bits because the value depends on
+ * input signals.
+ */
+#endif
+ return TFM_PLAT_ERR_SUCCESS;
+}
+
+/*----------------- NVIC interrupt target state to NS configuration ----------*/
+enum tfm_plat_err_t nvic_interrupt_target_state_cfg(void)
+{
+ /* Target every interrupt to NS; unimplemented interrupts will be WI */
+ for (uint8_t i=0; i<sizeof(NVIC->ITNS)/sizeof(NVIC->ITNS[0]); i++) {
+ NVIC->ITNS[i] = 0xFFFFFFFF;
+ }
+
+ /* Make sure that MPC and PPC are targeted to S state */
+ NVIC_ClearTargetState(MPC_IRQn);
+ NVIC_ClearTargetState(PPC_IRQn);
+
+#ifdef SECURE_UART1
+ /* UART1 is a secure peripheral, so its IRQs have to target S state */
+ NVIC_ClearTargetState(UARTRX1_IRQn);
+ NVIC_ClearTargetState(UARTTX1_IRQn);
+ NVIC_ClearTargetState(UART1_IRQn);
+#endif
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
+
+/*----------------- NVIC interrupt enabling for S peripherals ----------------*/
+enum tfm_plat_err_t nvic_interrupt_enable(void)
+{
+ struct spctrl_def* spctrl = CMSDK_SPCTRL;
+ int32_t ret = ARM_DRIVER_OK;
+
+ /* MPC interrupt enabling */
+ ret = Driver_SRAM1_MPC.EnableInterrupt();
+ if (ret != ARM_DRIVER_OK) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+ ret = Driver_SRAM2_MPC.EnableInterrupt();
+ if (ret != ARM_DRIVER_OK) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+ NVIC_EnableIRQ(MPC_IRQn);
+
+ /* PPC interrupt enabling */
+ /* Clear pending PPC interrupts */
+ /* In the PPC configuration function, we have used the Non-Secure
+ * Privilege Control Block to grant unprivilged NS access to some
+ * peripherals used by NS. That triggers a PPC0 exception as that
+ * register is meant for NS privileged access only. Clear it here
+ */
+ spctrl->secppcintclr = CMSDK_APB_PPC0_INT_POS_MASK;
+
+ /* Enable PPC interrupts for APB PPC */
+ spctrl->secppcinten |= CMSDK_APB_PPC0_INT_POS_MASK |
+ CMSDK_APB_PPC1_INT_POS_MASK |
+ CMSDK_APB_PPCEXP0_INT_POS_MASK |
+ CMSDK_APB_PPCEXP1_INT_POS_MASK |
+ CMSDK_APB_PPCEXP2_INT_POS_MASK |
+ CMSDK_APB_PPCEXP3_INT_POS_MASK;
+ NVIC_EnableIRQ(PPC_IRQn);
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
+
+/*------------------- SAU/IDAU configuration functions -----------------------*/
+struct sau_cfg_t {
+ uint32_t RBAR;
+ uint32_t RLAR;
+ bool nsc;
+};
+
+const struct sau_cfg_t sau_cfg[] = {
+ {
+ ((uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base)),
+ ((uint32_t)&REGION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
+ NS_PARTITION_SIZE - 1),
+ false,
+ },
+ {
+ NS_DATA_START,
+ NS_DATA_LIMIT,
+ false,
+ },
+ {
+ (uint32_t)&REGION_NAME(Image$$, ER_VENEER, $$Base),
+ (uint32_t)&REGION_NAME(Image$$, VENEER_ALIGN, $$Limit) - 1,
+ true,
+ },
+ {
+ PERIPHERALS_BASE_NS_START,
+#ifdef SECURE_UART1
+ (UART1_BASE_NS - 1),
+ false,
+ },
+ {
+ UART2_BASE_NS,
+#endif
+ PERIPHERALS_BASE_NS_END,
+ false,
+ },
+#ifdef BL2
+ {
+ (uint32_t)&REGION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base),
+ (uint32_t)&REGION_NAME(Load$$LR$$, LR_SECONDARY_PARTITION, $$Base) +
+ SECONDARY_PARTITION_SIZE - 1,
+ false,
+ },
+#endif
+};
+
+void sau_and_idau_cfg(void)
+{
+ struct spctrl_def *spctrl = CMSDK_SPCTRL;
+ uint32_t i;
+
+ /* Ensure all memory accesses are completed */
+ __DMB();
+
+ /* Enables SAU */
+ TZ_SAU_Enable();
+
+ for (i = 0; i < ARRAY_SIZE(sau_cfg); i++) {
+ SAU->RNR = i;
+ SAU->RBAR = sau_cfg[i].RBAR & SAU_RBAR_BADDR_Msk;
+ SAU->RLAR = (sau_cfg[i].RLAR & SAU_RLAR_LADDR_Msk) |
+ (sau_cfg[i].nsc ? SAU_RLAR_NSC_Msk : 0U) |
+ SAU_RLAR_ENABLE_Msk;
+ }
+
+ /* Allows SAU to define the code region as a NSC */
+ spctrl->nsccfg |= NSCCFG_CODENSC;
+
+ /* Ensure the write is completed and flush pipeline */
+ __DSB();
+ __ISB();
+}
+
+/*------------------- Memory configuration functions -------------------------*/
+
+int32_t mpc_init_cfg(void)
+{
+ int32_t ret = ARM_DRIVER_OK;
+
+ ret = Driver_SRAM1_MPC.Initialize();
+ if (ret != ARM_DRIVER_OK) {
+ return ret;
+ }
+
+ ret = Driver_SRAM1_MPC.ConfigRegion(
+ memory_regions.non_secure_partition_base,
+ memory_regions.non_secure_partition_limit,
+ ARM_MPC_ATTR_NONSECURE);
+ if (ret != ARM_DRIVER_OK) {
+ return ret;
+ }
+
+#ifdef BL2
+ /* Secondary image region */
+ ret = Driver_SRAM1_MPC.ConfigRegion(memory_regions.secondary_partition_base,
+ memory_regions.secondary_partition_limit,
+ ARM_MPC_ATTR_NONSECURE);
+ if (ret != ARM_DRIVER_OK) {
+ return ret;
+ }
+#endif /* BL2 */
+
+ ret = Driver_SRAM2_MPC.Initialize();
+ if (ret != ARM_DRIVER_OK) {
+ return ret;
+ }
+
+ ret = Driver_SRAM2_MPC.ConfigRegion(NS_DATA_START, NS_DATA_LIMIT,
+ ARM_MPC_ATTR_NONSECURE);
+ if (ret != ARM_DRIVER_OK) {
+ return ret;
+ }
+
+ /* Lock down the MPC configuration */
+ ret = Driver_SRAM1_MPC.LockDown();
+ if (ret != ARM_DRIVER_OK) {
+ return ret;
+ }
+
+ ret = Driver_SRAM2_MPC.LockDown();
+ if (ret != ARM_DRIVER_OK) {
+ return ret;
+ }
+
+ /* Add barriers to assure the MPC configuration is done before continue
+ * the execution.
+ */
+ __DSB();
+ __ISB();
+
+ return ARM_DRIVER_OK;
+}
+
+/*---------------------- PPC configuration functions -------------------------*/
+
+void ppc_init_cfg(void)
+{
+ struct spctrl_def* spctrl = CMSDK_SPCTRL;
+ struct nspctrl_def* nspctrl = CMSDK_NSPCTRL;
+
+ /* Grant non-secure access to peripherals in the PPC0
+ * (timer0 and 1, dualtimer, watchdog, mhu 0 and 1)
+ */
+ spctrl->apbnsppc0 |= (1U << CMSDK_TIMER0_APB_PPC_POS) |
+ (1U << CMSDK_TIMER1_APB_PPC_POS) |
+ (1U << CMSDK_DTIMER_APB_PPC_POS) |
+ (1U << CMSDK_MHU0_APB_PPC_POS) |
+ (1U << CMSDK_MHU1_APB_PPC_POS);
+
+ /* Grant non-secure access for APB peripherals on EXP1 */
+ spctrl->apbnsppcexp1 |= (1U << CMSDK_SPI0_APB_PPC_POS) |
+ (1U << CMSDK_SPI1_APB_PPC_POS) |
+ (1U << CMSDK_SPI2_APB_PPC_POS) |
+ (1U << CMSDK_SPI3_APB_PPC_POS) |
+ (1U << CMSDK_SPI4_APB_PPC_POS) |
+ (1U << CMSDK_UART0_APB_PPC_POS) |
+#ifdef SECURE_UART1
+ /* To statically configure a peripheral as secure, skip PPC NS peripheral
+ * configuration for the given device.
+ */
+#else
+ (1U << CMSDK_UART1_APB_PPC_POS) |
+#endif
+ (1U << CMSDK_UART2_APB_PPC_POS) |
+ (1U << CMSDK_UART3_APB_PPC_POS) |
+ (1U << CMSDK_UART4_APB_PPC_POS) |
+ (1U << CMSDK_I2C0_APB_PPC_POS) |
+ (1U << CMSDK_I2C1_APB_PPC_POS) |
+ (1U << CMSDK_I2C2_APB_PPC_POS) |
+ (1U << CMSDK_I2C3_APB_PPC_POS);
+ /* Grant non-secure access for APB peripherals on EXP2 */
+ spctrl->apbnsppcexp2 |= (1U << CMSDK_FPGA_SCC_PPC_POS) |
+ (1U << CMSDK_FPGA_AUDIO_PPC_POS) |
+ (1U << CMSDK_FPGA_IO_PPC_POS);
+
+ /* Grant non-secure access to all peripherals on AHB EXP:
+ * Make sure that all possible peripherals are enabled by default
+ */
+ spctrl->ahbnsppcexp0 |= (1U << CMSDK_VGA_PPC_POS) |
+ (1U << CMSDK_GPIO0_PPC_POS) |
+ (1U << CMSDK_GPIO1_PPC_POS) |
+ (1U << CMSDK_GPIO2_PPC_POS) |
+ (1U << CMSDK_GPIO3_PPC_POS) |
+ (1U << MPS2_ETHERNET_PPC_POS);
+
+ spctrl->ahbnsppcexp1 |= (1U << CMSDK_DMA0_PPC_POS) |
+ (1U << CMSDK_DMA1_PPC_POS) |
+ (1U << CMSDK_DMA2_PPC_POS) |
+ (1U << CMSDK_DMA3_PPC_POS);
+
+ /* in NS, grant un-privileged for UART0 */
+ nspctrl->apbnspppcexp1 |= (1U << CMSDK_UART0_APB_PPC_POS);
+
+ /* in NS, grant un-privileged access for LEDs */
+ nspctrl->apbnspppcexp2 |= (1U << CMSDK_FPGA_SCC_PPC_POS) |
+ (1U << CMSDK_FPGA_IO_PPC_POS);
+
+ /* Configure the response to a security violation as a
+ * bus error instead of RAZ/WI
+ */
+ spctrl->secrespcfg |= 1U;
+}
+
+void ppc_configure_to_non_secure(enum ppc_bank_e bank, uint16_t pos)
+{
+ /* Setting NS flag for peripheral to enable NS access */
+ struct spctrl_def* spctrl = CMSDK_SPCTRL;
+ ((uint32_t*)&(spctrl->ahbnsppc0))[bank] |= (1U << pos);
+}
+
+void ppc_configure_to_secure(enum ppc_bank_e bank, uint16_t pos)
+{
+ /* Clear NS flag for peripheral to prevent NS access */
+ struct spctrl_def* spctrl = CMSDK_SPCTRL;
+ ((uint32_t*)&(spctrl->ahbnsppc0))[bank] &= ~(1U << pos);
+}
+
+void ppc_en_secure_unpriv(enum ppc_bank_e bank, uint16_t pos)
+{
+ struct spctrl_def* spctrl = CMSDK_SPCTRL;
+ ((uint32_t*)&(spctrl->ahbspppc0))[bank] |= (1U << pos);
+}
+
+void ppc_clr_secure_unpriv(enum ppc_bank_e bank, uint16_t pos)
+{
+ struct spctrl_def* spctrl = CMSDK_SPCTRL;
+ ((uint32_t*)&(spctrl->ahbspppc0))[bank] &= ~(1U << pos);
+}
+
+void ppc_clear_irq(void)
+{
+ struct spctrl_def* spctrl = CMSDK_SPCTRL;
+ /* Clear APB PPC EXP2 IRQ */
+ spctrl->secppcintclr = CMSDK_APB_PPCEXP2_INT_POS_MASK;
+}