Platform: nuvoton m2354: update for tf-m v1.6
Change-Id: I937f4a8148fe2c161be584c9a462c1886ff50b9f
diff --git a/platform/ext/platform_introduction.rst b/platform/ext/platform_introduction.rst
index b9e043e..656e1aa 100644
--- a/platform/ext/platform_introduction.rst
+++ b/platform/ext/platform_introduction.rst
@@ -49,6 +49,8 @@
<https://developer.arm.com/products/system-design/development-boards/cortex-m-prototyping-systems/mps2>`_
- `M2351.
<https://www.nuvoton.com/products/iot-solution/iot-platform/numaker-pfm-m2351/>`_
+ - `M2354.
+ <https://www.nuvoton.com/board/numaker-m2354/>`_
- Dual Core Cortex-M system:
diff --git a/platform/ext/target/nuvoton/common/bsp/StdDriver/inc/tamper.h b/platform/ext/target/nuvoton/common/bsp/StdDriver/inc/tamper.h
deleted file mode 100644
index 466f69a..0000000
--- a/platform/ext/target/nuvoton/common/bsp/StdDriver/inc/tamper.h
+++ /dev/null
@@ -1,463 +0,0 @@
-/**************************************************************************//**
- * @file tamper.h
- * @version V3.00
- * @brief TAMPER driver header file
- *
- * @copyright SPDX-License-Identifier: Apache-2.0
- * @copyright Copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
- *****************************************************************************/
-#ifndef __TAMPER_H__
-#define __TAMPER_H__
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-
-/** @addtogroup Standard_Driver Standard Driver
- @{
-*/
-
-/** @addtogroup TAMPER_Driver Tamper Driver
- @{
-*/
-
-/** @addtogroup TAMPER_EXPORTED_CONSTANTS Tamper Exported Constants
- @{
-*/
-
-#define TAMPER_TAMPER0_SELECT (0x1UL << 0) /*!< Select Tamper 0 */
-#define TAMPER_TAMPER1_SELECT (0x1UL << 1) /*!< Select Tamper 1 */
-#define TAMPER_TAMPER2_SELECT (0x1UL << 2) /*!< Select Tamper 2 */
-#define TAMPER_TAMPER3_SELECT (0x1UL << 3) /*!< Select Tamper 3 */
-#define TAMPER_TAMPER4_SELECT (0x1UL << 4) /*!< Select Tamper 4 */
-#define TAMPER_TAMPER5_SELECT (0x1UL << 5) /*!< Select Tamper 5 */
-#define TAMPER_MAX_TAMPER_PIN_NUM 6UL /*!< Tamper Pin number */
-
-#define TAMPER_TAMPER_HIGH_LEVEL_DETECT 1UL /*!< Tamper pin detect voltage level is high */
-#define TAMPER_TAMPER_LOW_LEVEL_DETECT 0UL /*!< Tamper pin detect voltage level is low */
-
-#define TAMPER_TAMPER_DEBOUNCE_ENABLE 1UL /*!< Enable tamper pin de-bounce function */
-#define TAMPER_TAMPER_DEBOUNCE_DISABLE 0UL /*!< Disable tamper pin de-bounce function */
-
-#define TAMPER_PAIR0_SELECT (0x1UL << 0) /*!< Select Pair 0 */
-#define TAMPER_PAIR1_SELECT (0x1UL << 1) /*!< Select Pair 1 */
-#define TAMPER_PAIR2_SELECT (0x1UL << 2) /*!< Select Pair 2 */
-#define TAMPER_MAX_PAIR_NUM 3UL /*!< Pair number */
-
-#define TAMPER_2POW6_CLK (0x0UL << TAMPER_TIOCTL_DYNRATE_Pos) /*!< 64 RTC clock cycles */
-#define TAMPER_2POW7_CLK (0x1UL << TAMPER_TIOCTL_DYNRATE_Pos) /*!< 64 x 2 RTC clock cycles */
-#define TAMPER_2POW8_CLK (0x2UL << TAMPER_TIOCTL_DYNRATE_Pos) /*!< 64 x 4 RTC clock cycles */
-#define TAMPER_2POW9_CLK (0x3UL << TAMPER_TIOCTL_DYNRATE_Pos) /*!< 64 x 6 RTC clock cycles */
-#define TAMPER_2POW10_CLK (0x4UL << TAMPER_TIOCTL_DYNRATE_Pos) /*!< 64 x 8 RTC clock cycles */
-#define TAMPER_2POW11_CLK (0x5UL << TAMPER_TIOCTL_DYNRATE_Pos) /*!< 64 x 10 RTC clock cycles */
-#define TAMPER_2POW12_CLK (0x6UL << TAMPER_TIOCTL_DYNRATE_Pos) /*!< 64 x 12 RTC clock cycles */
-#define TAMPER_2POW13_CLK (0x7UL << TAMPER_TIOCTL_DYNRATE_Pos) /*!< 64 x 14 RTC clock cycles */
-
-#define TAMPER_ACTS_2POW10_CLK (0x0UL << 5) /*!< 1024 LIRC32K clock cycles */
-#define TAMPER_ACTS_2POW11_CLK (0x1UL << 5) /*!< 1024 x 2 LIRC32K clock cycles */
-#define TAMPER_ACTS_2POW12_CLK (0x2UL << 5) /*!< 1024 x 4 LIRC32K clock cycles */
-#define TAMPER_ACTS_2POW13_CLK (0x3UL << 5) /*!< 1024 x 6 LIRC32K clock cycles */
-#define TAMPER_ACTS_2POW14_CLK (0x4UL << 5) /*!< 1024 x 8 LIRC32K clock cycles */
-#define TAMPER_ACTS_2POW15_CLK (0x5UL << 5) /*!< 1024 x 16 LIRC32K clock cycles */
-#define TAMPER_ACTS_2POW16_CLK (0x6UL << 5) /*!< 1024 x 32 LIRC32K clock cycles */
-#define TAMPER_ACTS_2POW17_CLK (0x7UL << 5) /*!< 1024 x 64 LIRC32K clock cycles */
-
-#define TAMPER_REF_RANDOM_PATTERN 0x0UL /*!< The new reference pattern is generated by random number generator when the reference pattern run out */
-#define TAMPER_REF_SEED 0x1UL /*!< The new reference pattern is repeated from SEED (TAMPER_SEED[31:0]) when the reference pattern run out */
-
-#define TAMPER_VG_192M_SAMPLE 0x0UL /*!< Select voltage glitch 192M sampleing rate */
-
-/**@}*/ /* end of group TAMPER_EXPORTED_CONSTANTS */
-
-
-/** @addtogroup TAMPER_EXPORTED_FUNCTIONS Tamper Exported Functions
- @{
-*/
-
-/**
- * @brief Reset Tamper Coreblock
- *
- * @param None
- *
- * @return None
- *
- * @details To set TAMPER INIT control register to reset the tamper coreblock.
- *
- */
-#define TAMPER_CORE_RESET() ((uint32_t)(TAMPER->INIT = 0x55AA))
-
-/**
- * @brief Release Tamper Coreblock
- *
- * @param None
- *
- * @return None
- *
- * @details To set TAMPER INIT control register to release the tamper coreblock.
- *
- */
-#define TAMPER_CORE_RELEASE() ((uint32_t)(TAMPER->INIT = 0x5500))
-
-/**
- * @brief Get the Voltage Regulator Power Ready Status
- *
- * @param None
- *
- * @retval 0 The power status of voltage regulator is not ready.
- * @retval 1 The power status of voltage regulator is ready.
- *
- * @details This macro will return the power status of voltage regulator.
- *
- */
-#define TAMPER_TLDO_IS_READY() (TAMPER->INIT & TAMPER_INIT_TLDORDY_Msk ? 1:0)
-
-/**
- * @brief Enable LXT Clock Detection
- *
- * @param None
- *
- * @return None
- *
- * @details To set TAMPER FUNEN control register to enable LXT clock detection.
- *
- */
-#define TAMPER_ENABLE_LXTDET() ((uint32_t)(TAMPER->FUNEN = (TAMPER->FUNEN & ~0xFFUL) | 0x44))
-
-/**
- * @brief Disable LXT Clock Detection
- *
- * @param None
- *
- * @return None
- *
- * @details To set TAMPER FUNEN control register to disable LXT clock detection.
- *
- */
-#define TAMPER_DISABLE_LXTDET() ((uint32_t)(TAMPER->FUNEN = (TAMPER->FUNEN & ~0xFFUL) | 0x40))
-
-/**
- * @brief Tamper I/O TAMPER Block Detection Selection
- *
- * @param[in] u32TamperSelect Tamper pin select. Possible options are
- * - \ref TAMPER_TAMPER0_SELECT
- * - \ref TAMPER_TAMPER1_SELECT
- * - \ref TAMPER_TAMPER2_SELECT
- * - \ref TAMPER_TAMPER3_SELECT
- * - \ref TAMPER_TAMPER4_SELECT
- * - \ref TAMPER_TAMPER5_SELECT
- *
- * @return None
- *
- * @details To set TAMPER FUNEN control register to select tamper I/O 0~5 and its function is detected through TAMPER block.
- *
- */
-__STATIC_INLINE void TAMPER_IOSEL_TAMPER(uint32_t u32TamperSelect)
-{
- uint32_t i;
-
- for(i = 0UL; i < (uint32_t)TAMPER_MAX_TAMPER_PIN_NUM; i++)
- {
- if(u32TamperSelect & (0x1UL << i))
- {
- TAMPER->FUNEN = (TAMPER->FUNEN & ~0xFFUL) | (0x94 + i * 0x10UL);
- }
- }
-}
-
-/**
- * @brief Tamper I/O RTC Block Detection Selection
- *
- * @param[in] u32TamperSelect Tamper pin select. Possible options are
- * - \ref TAMPER_TAMPER0_SELECT
- * - \ref TAMPER_TAMPER1_SELECT
- * - \ref TAMPER_TAMPER2_SELECT
- * - \ref TAMPER_TAMPER3_SELECT
- * - \ref TAMPER_TAMPER4_SELECT
- * - \ref TAMPER_TAMPER5_SELECT
- *
- * @return None
- *
- * @details To set TAMPER FUNEN control register to select tamper I/O 0~5 and its function is detected through RTC block.
- *
- */
-__STATIC_INLINE void TAMPER_IOSEL_RTC(uint32_t u32TamperSelect)
-{
- uint32_t i;
-
- for(i = 0UL; i < (uint32_t)TAMPER_MAX_TAMPER_PIN_NUM; i++)
- {
- if(u32TamperSelect & (0x1UL << i))
- {
- TAMPER->FUNEN = (TAMPER->FUNEN & ~0xFFUL) | (0x90 + i * 0x10UL);
- }
- }
-}
-
-/**
- * @brief Enable HIRC48M
- *
- * @param None
- *
- * @return None
- *
- * @details To set TAMPER FUNEN control register to enable HIRC48M.
- *
- */
-#define TAMPER_ENABLE_HIRC48M() ((uint32_t)(TAMPER->FUNEN &= (~TAMPER_FUNEN_HIRC48MEN_Msk)))
-
-/**
- * @brief Disable HIRC48M
- *
- * @param None
- *
- * @return None
- *
- * @details To set TAMPER FUNEN control register to disable HIRC48M.
- *
- */
-#define TAMPER_DISABLE_HIRC48M() ((uint32_t)(TAMPER->FUNEN = (TAMPER->FUNEN & (~TAMPER_FUNEN_HIRC48MEN_Msk)) | (0x5A << TAMPER_FUNEN_HIRC48MEN_Pos)))
-
-/**
- * @brief Voltage Glitch Sampling Rate Selection
- *
- * @param[in] u32VGSampleRate Voltage Glitch sampling rate select. Possible option is
- * - \ref TAMPER_VG_192M_SAMPLE
- *
- * @return None
- *
- * @details To set TAMPER FUNEN control register to enable voltage glitch channel 0~3 to select voltage glitch sampling rate.
- *
- */
-__STATIC_INLINE void TAMPER_VG_SAMPLE_SEL(uint32_t u32VGSampleRate)
-{
- TAMPER->FUNEN &= ~0xF000000UL;
-
- if(u32VGSampleRate == TAMPER_VG_192M_SAMPLE)
- {
- TAMPER->FUNEN |= TAMPER_FUNEN_VGCHEN0_Msk | TAMPER_FUNEN_VGCHEN1_Msk | TAMPER_FUNEN_VGCHEN2_Msk | TAMPER_FUNEN_VGCHEN3_Msk;
- }
-}
-
-/**
- * @brief Enable to Trigger Key Store
- *
- * @param None
- *
- * @return None
- *
- * @details Set KSTRIGEN bit of TAMPER TRIEN control register to trigger Key Store when Tamper event is detected.
- *
- */
-#define TAMPER_ENABLE_KS_TRIG() ((uint32_t)(TAMPER->TRIEN |= TAMPER_TRIEN_KSTRIGEN_Msk))
-
-/**
- * @brief Disable to Trigger Key Store
- *
- * @param None
- *
- * @return None
- *
- * @details Clear KSTRIGEN bit of TAMPER TRIEN control register to not trigger Key Store when Tamper event is detected.
- *
- */
-#define TAMPER_DISABLE_KS_TRIG() ((uint32_t)(TAMPER->TRIEN &= (~TAMPER_TRIEN_KSTRIGEN_Msk)))
-
-/**
- * @brief Enable Wake-up Function
- *
- * @param None
- *
- * @return None
- *
- * @details Set WAKEUPEN bit of TAMPER TRIEN control register to wake-up the system when Tamper event is detected.
- *
- */
-#define TAMPER_ENABLE_WAKEUP() ((uint32_t)(TAMPER->TRIEN |= TAMPER_TRIEN_WAKEUPEN_Msk))
-
-/**
- * @brief Disable Wake-up Function
- *
- * @param None
- *
- * @return None
- *
- * @details Clear WAKEUPEN bit of TAMPER TRIEN control register to not wake-up the system when Tamper event is detected.
- *
- */
-#define TAMPER_DISABLE_WAKEUP() ((uint32_t)(TAMPER->TRIEN &= (~TAMPER_TRIEN_WAKEUPEN_Msk)))
-
-/**
- * @brief Enable to Clear Crypto Function
- *
- * @param None
- *
- * @return None
- *
- * @details Set CRYPTOEN bit of TAMPER TRIEN control register to reset Crypto when Tamper event is detected.
- *
- */
-#define TAMPER_ENABLE_CRYPTO() ((uint32_t)(TAMPER->TRIEN |= TAMPER_TRIEN_CRYPTOEN_Msk))
-
-/**
- * @brief Disable to Clear Crypto Function
- *
- * @param None
- *
- * @return None
- *
- * @details Clear CRYPTOEN bit of TAMPER TRIEN control register to not reset Crypto when Tamper event is detected.
- *
- */
-#define TAMPER_DISABLE_CRYPTO() ((uint32_t)(TAMPER->TRIEN &= (~TAMPER_TRIEN_CRYPTOEN_Msk)))
-
-/**
- * @brief Enable to Trigger Chip Reset
- *
- * @param None
- *
- * @return None
- *
- * @details Set CHIPRSTEN bit of TAMPER TRIEN control register to reset the system when Tamper event is detected.
- *
- */
-#define TAMPER_ENABLE_CHIPRST() ((uint32_t)(TAMPER->TRIEN |= TAMPER_TRIEN_CHIPRSTEN_Msk))
-
-/**
- * @brief Disable to Trigger Chip Reset
- *
- * @param None
- *
- * @return None
- *
- * @details Clear CHIPRSTEN bit of TAMPER TRIEN control register to not reset the system when Tamper event is detected.
- *
- */
-#define TAMPER_DISABLE_CHIPRST() ((uint32_t)(TAMPER->TRIEN &= (~TAMPER_TRIEN_CHIPRSTEN_Msk)))
-
-/**
- * @brief Enable to Clear RTC Spare Register
- *
- * @param None
- *
- * @return None
- *
- * @details Set RTCSPCLREN bit of TAMPER TRIEN control register to reset RTC spare register when Tamper event is detected.
- *
- */
-#define TAMPER_ENABLE_RTCSPCLR() ((uint32_t)(TAMPER->TRIEN |= TAMPER_TRIEN_RTCSPCLREN_Msk))
-
-/**
- * @brief Disable to Clear RTC Spare Register
- *
- * @param None
- *
- * @return None
- *
- * @details Clear RTCSPCLREN bit of TAMPER TRIEN control register to not reset RTC spare register when Tamper event is detected.
- *
- */
-#define TAMPER_DISABLE_RTCSPCLR() ((uint32_t)(TAMPER->TRIEN &= (~TAMPER_TRIEN_RTCSPCLREN_Msk)))
-
-/**
- * @brief Get Tamper Interrupt Flag
- *
- * @param None
- *
- * @retval 0 Tamper event Interrupt did not occur
- * @retval 1 Tamper event Interrupt occurred
- *
- * @details This macro indicates Tamper event intertupt occurred or not.
- *
- */
-#define TAMPER_GET_INT_FLAG() ((TAMPER->INTSTS & (0xAA7FAFFF))? 1:0)
-
-/**
- * @brief Clear Tamper Interrupt Status
- *
- * @param[in] u32TamperFlag Tamper event interrupt flag. It consists of:
- * - \ref TAMPER_INTSTS_TAMP0IF_Msk
- * - \ref TAMPER_INTSTS_TAMP1IF_Msk
- * - \ref TAMPER_INTSTS_TAMP2IF_Msk
- * - \ref TAMPER_INTSTS_TAMP3IF_Msk
- * - \ref TAMPER_INTSTS_TAMP4IF_Msk
- * - \ref TAMPER_INTSTS_TAMP5IF_Msk
- * - \ref TAMPER_INTSTS_CLKFAILIF_Msk
- * - \ref TAMPER_INTSTS_CLKSTOPIF_Msk
- * - \ref TAMPER_INTSTS_OVPOUTIF_Msk
- * - \ref TAMPER_INTSTS_VGPEVIF_Msk
- * - \ref TAMPER_INTSTS_VGNEVIF_Msk
- * - \ref TAMPER_INTSTS_ACTSEIF_Msk
- * - \ref TAMPER_INTSTS_ACTST5IF_Msk
- * - \ref TAMPER_INTSTS_ACTST25IF_Msk
- * - \ref TAMPER_INTSTS_BODIF_Msk
- * - \ref TAMPER_INTSTS_ACTST1IF_Msk
- * - \ref TAMPER_INTSTS_ACTST3IF_Msk
- * - \ref TAMPER_INTSTS_ACTST21IF_Msk
- * - \ref TAMPER_INTSTS_ACTST23IF_Msk
- *
- * @return None
- *
- * @details This macro is used to clear Tamper event flag.
- *
- */
-#define TAMPER_CLR_INT_STATUS(u32TamperFlag) (TAMPER->INTSTS = (u32TamperFlag))
-
-/**
- * @brief Get Tamper Interrupt Status
- *
- * @param None
- *
- * @retval TAMPER_INTSTS_TAMP0IF_Msk
- * @retval TAMPER_INTSTS_TAMP1IF_Msk
- * @retval TAMPER_INTSTS_TAMP2IF_Msk
- * @retval TAMPER_INTSTS_TAMP3IF_Msk
- * @retval TAMPER_INTSTS_TAMP4IF_Msk
- * @retval TAMPER_INTSTS_TAMP5IF_Msk
- * @retval TAMPER_INTSTS_CLKFAILIF_Msk
- * @retval TAMPER_INTSTS_CLKSTOPIF_Msk
- * @retval TAMPER_INTSTS_OVPOUTIF_Msk
- * @retval TAMPER_INTSTS_VGPEVIF_Msk
- * @retval TAMPER_INTSTS_VGNEVIF_Msk
- * @retval TAMPER_INTSTS_ACTSEFIF_Msk
- * @retval TAMPER_INTSTS_ACTST5IF_Msk
- * @retval TAMPER_INTSTS_ACTST25IF_Msk
- * @retval TAMPER_INTSTS_RTCLVRIF_Msk
- * @retval TAMPER_INTSTS_RIOTRIGIF_Msk
- * @retval TAMPER_INTSTS_RCLKTRIGIF_Msk
- * @retval TAMPER_INTSTS_BODIF_Msk
- * @retval TAMPER_INTSTS_ACTST1IF_Msk
- * @retval TAMPER_INTSTS_ACTST3IF_Msk
- * @retval TAMPER_INTSTS_ACTST21IF_Msk
- * @retval TAMPER_INTSTS_ACTST23IF_Msk
- *
- * @details This macro indicates Tamper event status.
- *
- */
-#define TAMPER_GET_INT_STATUS() ((TAMPER->INTSTS & (0xAA7FAFFF)))
-
-void TAMPER_EnableInt(uint32_t u32IntFlagMask);
-void TAMPER_DisableInt(uint32_t u32IntFlagMask);
-void TAMPER_StaticTamperEnable(uint32_t u32TamperSelect, uint32_t u32DetecLevel, uint32_t u32DebounceEn);
-void TAMPER_StaticTamperDisable(uint32_t u32TamperSelect);
-void TAMPER_DynamicTamperEnable(uint32_t u32PairSel, uint32_t u32DebounceEn, uint32_t u32Pair1Source, uint32_t u32Pair2Source);
-void TAMPER_DynamicTamperDisable(uint32_t u32PairSel);
-void TAMPER_DynamicTamperConfig(uint32_t u32ChangeRate, uint32_t u32SeedReload, uint32_t u32RefPattern, uint32_t u32Seed);
-void TAMPER_ActiveShieldDynamicTamperEnable(uint32_t u32PairSel1, uint32_t u32Pair1Source1, uint32_t u32PairSel2, uint32_t u32Pair1Source2);
-void TAMPER_ActiveShieldDynamicTamperDisable(uint32_t u32PairSel1, uint32_t u32PairSe2);
-void TAMPER_ActiveShieldDynamicTamperConfig(uint32_t u32ChangeRate1, uint32_t u32SeedReload1, uint32_t u32RefPattern1, uint32_t u32Seed,
- uint32_t u32ChangeRate2, uint32_t u32SeedReload2, uint32_t u32RefPattern2, uint32_t u32Seed2);
-
-
-/**@}*/ /* end of group TAMPER_EXPORTED_FUNCTIONS */
-
-/**@}*/ /* end of group TAMPER_Driver */
-
-/**@}*/ /* end of group Standard_Driver */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __TAMPER_H__ */
diff --git a/platform/ext/target/nuvoton/common/cmsis_drivers/Driver_Flash.c b/platform/ext/target/nuvoton/common/cmsis_drivers/Driver_Flash.c
index 3170879..8b6b033 100644
--- a/platform/ext/target/nuvoton/common/cmsis_drivers/Driver_Flash.c
+++ b/platform/ext/target/nuvoton/common/cmsis_drivers/Driver_Flash.c
@@ -79,13 +79,12 @@
static int32_t is_range_valid(struct arm_flash_dev_t *flash_dev,
uint32_t offset)
{
- uint32_t flash_limit = 0;
+ uint32_t flash_size = 0;
int32_t rc = 0;
- flash_limit = (flash_dev->data->sector_count * flash_dev->data->sector_size)
- - 1;
+ flash_size = (flash_dev->data->sector_count * flash_dev->data->sector_size);
- if(offset > flash_limit)
+ if(offset >= flash_size)
{
rc = -1;
}
@@ -204,7 +203,7 @@
cnt *= data_width_byte[DriverCapabilities.data_width];
/* Check flash memory boundaries */
- rc = is_range_valid(FLASH0_DEV, addr + cnt - 1);
+ rc = is_range_valid(FLASH0_DEV, addr + cnt);
if (rc != 0) {
return ARM_DRIVER_ERROR_PARAMETER;
}
@@ -214,7 +213,7 @@
for(i = 0; i < cnt; i++)
{
taddr = start_addr + i;
- if(taddr >= (FLASH_AREA_0_OFFSET+FLASH_S_PARTITION_SIZE))
+ if(taddr >= SCU->FNSADDR)
taddr += NS_OFFSET;
pu8[i] = *(uint8_t*)taddr;
}
@@ -234,7 +233,7 @@
cnt *= data_width_byte[DriverCapabilities.data_width];
/* Check flash memory boundaries and alignment with minimal write size */
- rc = is_range_valid(FLASH0_DEV, addr + cnt - 1);
+ rc = is_range_valid(FLASH0_DEV, addr + cnt);
rc |= is_write_aligned(FLASH0_DEV, addr);
rc |= is_write_aligned(FLASH0_DEV, cnt);
if(rc != 0)
@@ -258,8 +257,15 @@
if(j>=4)
{
FMC_Write(start_addr+(i+1-4), u32Data);
+ // verify
+ if(M32(start_addr + i - 3) != u32Data)
+ {
+ printf("flash write verify fail @ %08x W:%08x R:%08x\r\n", start_addr + i - 3, u32Data, M32(start_addr + i - 3));
+ }
+
j = 0;
u32Data = 0;
+
}
}
diff --git a/platform/ext/target/nuvoton/common/mmio_defs.h b/platform/ext/target/nuvoton/common/mmio_defs.h
new file mode 100644
index 0000000..34e4e31
--- /dev/null
+++ b/platform/ext/target/nuvoton/common/mmio_defs.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __MMIO_DEFS_H__
+#define __MMIO_DEFS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include "tfm_peripherals_def.h"
+
+/* Boundary handle binding macros. */
+#define HANDLE_PER_ATTR_BITS (0x4)
+#define HANDLE_ATTR_PRIV_MASK ((1 << HANDLE_PER_ATTR_BITS) - 1)
+#if TFM_LVL == 3
+#define HANDLE_ATTR_RW_POS (1 << (HANDLE_PER_ATTR_BITS - 1))
+#define HANDLE_ATTR_INDEX_MASK (HANDLE_ATTR_RW_POS - 1)
+#define HANDLE_INDEX_BITS (0x8)
+#define HANDLE_INDEX_MASK (((1 << HANDLE_INDEX_BITS) -1) << 24)
+#define HANDLE_ENCODE_INDEX(attr, idx) \
+ do { \
+ (attr) |= (((idx) << 24) & HANDLE_INDEX_MASK); \
+ (idx)++; \
+ } while (0)
+#endif
+
+/* Allowed named MMIO of this platform */
+const uintptr_t partition_named_mmio_list[] = {
+ (uintptr_t)TFM_PERIPHERAL_TIMER0,
+ (uintptr_t)TFM_PERIPHERAL_STD_UART,
+#ifdef PSA_API_TEST_IPC
+ (uintptr_t)FF_TEST_UART_REGION,
+ (uintptr_t)FF_TEST_WATCHDOG_REGION,
+ (uintptr_t)FF_TEST_NVMEM_REGION,
+ (uintptr_t)FF_TEST_SERVER_PARTITION_MMIO,
+ (uintptr_t)FF_TEST_DRIVER_PARTITION_MMIO,
+#endif
+};
+
+/*
+ * Platform AN521 only has named MMIO.
+ * If the platform has numbered MMIO, define them in another list.
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MMIO_DEFS_H__ */
diff --git a/platform/ext/target/nuvoton/common/native_drivers/arm_uart_drv.c b/platform/ext/target/nuvoton/common/native_drivers/arm_uart_drv.c
new file mode 100644
index 0000000..d61ae48
--- /dev/null
+++ b/platform/ext/target/nuvoton/common/native_drivers/arm_uart_drv.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2016-2017 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 "arm_uart_drv.h"
+
+#include <stddef.h>
+
+/* UART register map structure */
+struct _arm_uart_reg_map_t {
+ volatile uint32_t data; /* Offset: 0x000 (R/W) data register */
+ volatile uint32_t state; /* Offset: 0x004 (R/W) status register */
+ volatile uint32_t ctrl; /* Offset: 0x008 (R/W) control register */
+ union {
+ volatile uint32_t intrstatus; /* Offset: 0x00c (R/ ) interrupt status
+ * register */
+ volatile uint32_t intrclear; /* Offset: 0x00c ( /W) interrupt clear
+ * register */
+ }intr_reg;
+ volatile uint32_t bauddiv; /* Offset: 0x010 (R/W) Baudrate divider
+ * register */
+};
+
+/* CTRL Register */
+#define ARM_UART_TX_EN (1ul << 0)
+#define ARM_UART_RX_EN (1ul << 1)
+#define ARM_UART_TX_INTR_EN (1ul << 2)
+#define ARM_UART_RX_INTR_EN (1ul << 3)
+
+/* STATE Register */
+#define ARM_UART_TX_BF (1ul << 0)
+#define ARM_UART_RX_BF (1ul << 1)
+
+/* INTSTATUS Register */
+#define ARM_UART_TX_INTR (1ul << 0)
+#define ARM_UART_RX_INTR (1ul << 1)
+
+/* UART state definitions */
+#define ARM_UART_INITIALIZED (1ul << 0)
+
+enum arm_uart_error_t arm_uart_init(struct arm_uart_dev_t* dev,
+ uint32_t system_clk)
+{
+ struct _arm_uart_reg_map_t* p_uart =
+ (struct _arm_uart_reg_map_t*)dev->cfg->base;
+ if(system_clk == 0) {
+ return ARM_UART_ERR_INVALID_ARG;
+ }
+
+ /* Sets baudrate and system clock */
+ dev->data->system_clk = system_clk;
+ dev->data->baudrate = dev->cfg->default_baudrate;
+
+ /* Sets baudrate */
+ p_uart->bauddiv = (dev->data->system_clk / dev->cfg->default_baudrate);
+
+ /* Enables receiver and transmitter */
+ p_uart->ctrl = ARM_UART_RX_EN | ARM_UART_TX_EN;
+
+ dev->data->state = ARM_UART_INITIALIZED;
+
+ return ARM_UART_ERR_NONE;
+}
+
+enum arm_uart_error_t arm_uart_set_baudrate(struct arm_uart_dev_t* dev,
+ uint32_t baudrate)
+{
+ uint32_t bauddiv;
+ struct _arm_uart_reg_map_t* p_uart =
+ (struct _arm_uart_reg_map_t*)dev->cfg->base;
+
+ if(baudrate == 0) {
+ return ARM_UART_ERR_INVALID_BAUD;
+ }
+
+ if(!(dev->data->state & ARM_UART_INITIALIZED)) {
+ return ARM_UART_ERR_NOT_INIT;
+ }
+
+ /* Sets baudrate */
+ bauddiv = (dev->data->system_clk / baudrate);
+ dev->data->baudrate = baudrate;
+
+ /* Minimum bauddiv value */
+ if(bauddiv < 16) {
+ return ARM_UART_ERR_INVALID_BAUD;
+ }
+
+ p_uart->bauddiv = bauddiv;
+
+ return ARM_UART_ERR_NONE;
+}
+
+uint32_t arm_uart_get_baudrate(struct arm_uart_dev_t* dev)
+{
+ return dev->data->baudrate;
+}
+
+enum arm_uart_error_t arm_uart_set_clock(struct arm_uart_dev_t* dev,
+ uint32_t system_clk)
+{
+ struct _arm_uart_reg_map_t* p_uart =
+ (struct _arm_uart_reg_map_t*)dev->cfg->base;
+
+ if(system_clk == 0) {
+ return ARM_UART_ERR_INVALID_ARG;
+ }
+
+ if(!(dev->data->state & ARM_UART_INITIALIZED)) {
+ return ARM_UART_ERR_NOT_INIT;
+ }
+
+ /* Sets system clock */
+ dev->data->system_clk = system_clk;
+
+ /* Updates baudrate divider */
+ p_uart->bauddiv = (dev->data->system_clk / dev->data->baudrate);
+
+ /* Enables receiver and transmitter */
+ return ARM_UART_ERR_NONE;
+}
+
+enum arm_uart_error_t arm_uart_read(struct arm_uart_dev_t* dev, uint8_t* byte)
+{
+ struct _arm_uart_reg_map_t* p_uart =
+ (struct _arm_uart_reg_map_t*)dev->cfg->base;
+
+ if(!(p_uart->state & ARM_UART_RX_BF)) {
+ return ARM_UART_ERR_NOT_READY;
+ }
+
+ /* Reads data */
+ *byte = (uint8_t)p_uart->data;
+
+ return ARM_UART_ERR_NONE;
+}
+
+enum arm_uart_error_t arm_uart_write(struct arm_uart_dev_t* dev, uint8_t byte)
+{
+ struct _arm_uart_reg_map_t* p_uart =
+ (struct _arm_uart_reg_map_t*)dev->cfg->base;
+
+ if(p_uart->state & ARM_UART_TX_BF) {
+ return ARM_UART_ERR_NOT_READY;
+ }
+
+ /* Sends data */
+ p_uart->data = byte;
+
+ return ARM_UART_ERR_NONE;
+}
+
+enum arm_uart_error_t arm_uart_irq_tx_enable(struct arm_uart_dev_t* dev)
+{
+ struct _arm_uart_reg_map_t* p_uart =
+ (struct _arm_uart_reg_map_t*)dev->cfg->base;
+
+ if(!(dev->data->state & ARM_UART_INITIALIZED)) {
+ return ARM_UART_ERR_NOT_INIT;
+ }
+
+ p_uart->ctrl |= ARM_UART_TX_INTR_EN;
+
+ return ARM_UART_ERR_NONE;
+}
+
+void arm_uart_irq_tx_disable(struct arm_uart_dev_t* dev)
+{
+ struct _arm_uart_reg_map_t* p_uart =
+ (struct _arm_uart_reg_map_t*)dev->cfg->base;
+
+ if(dev->data->state & ARM_UART_INITIALIZED ) {
+ p_uart->ctrl &= ~ARM_UART_TX_INTR_EN;
+ }
+}
+
+uint32_t arm_uart_tx_ready(struct arm_uart_dev_t* dev)
+{
+ struct _arm_uart_reg_map_t* p_uart =
+ (struct _arm_uart_reg_map_t*)dev->cfg->base;
+
+ if(!(dev->data->state & ARM_UART_INITIALIZED)) {
+ return 0;
+ }
+
+ return !(p_uart->state & ARM_UART_TX_BF);
+}
+
+enum arm_uart_error_t arm_uart_irq_rx_enable(struct arm_uart_dev_t* dev)
+{
+ struct _arm_uart_reg_map_t* p_uart =
+ (struct _arm_uart_reg_map_t*)dev->cfg->base;
+
+ if(!(dev->data->state & ARM_UART_INITIALIZED)) {
+ return ARM_UART_ERR_NOT_INIT;
+ }
+
+ p_uart->ctrl |= ARM_UART_RX_INTR_EN;
+
+ return ARM_UART_ERR_NONE;
+}
+
+void arm_uart_irq_rx_disable(struct arm_uart_dev_t* dev)
+{
+ struct _arm_uart_reg_map_t* p_uart =
+ (struct _arm_uart_reg_map_t*)dev->cfg->base;
+
+ if(dev->data->state & ARM_UART_INITIALIZED) {
+ p_uart->ctrl &= ~ARM_UART_RX_INTR_EN;
+ }
+}
+
+uint32_t arm_uart_rx_ready(struct arm_uart_dev_t* dev)
+{
+ struct _arm_uart_reg_map_t* p_uart =
+ (struct _arm_uart_reg_map_t*)dev->cfg->base;
+
+ if(!(dev->data->state & ARM_UART_INITIALIZED)) {
+ return 0;
+ }
+
+ return (p_uart->state & ARM_UART_RX_BF);
+}
+
+void arm_uart_clear_interrupt(struct arm_uart_dev_t* dev,
+ enum arm_uart_irq_t irq)
+{
+ struct _arm_uart_reg_map_t* p_uart =
+ (struct _arm_uart_reg_map_t*)dev->cfg->base;
+
+ if(dev->data->state & ARM_UART_INITIALIZED) {
+ /* Clears pending interrupts */
+ switch(irq) {
+ case ARM_UART_IRQ_RX:
+ p_uart->intr_reg.intrclear = ARM_UART_RX_INTR;
+ break;
+ case ARM_UART_IRQ_TX:
+ p_uart->intr_reg.intrclear = ARM_UART_TX_INTR;
+ break;
+ case ARM_UART_IRQ_COMBINED:
+ p_uart->intr_reg.intrclear = (ARM_UART_RX_INTR | ARM_UART_TX_INTR);
+ break;
+ /* default: not defined to force all cases to be handled */
+ }
+ }
+}
diff --git a/platform/ext/target/nuvoton/common/native_drivers/arm_uart_drv.h b/platform/ext/target/nuvoton/common/native_drivers/arm_uart_drv.h
new file mode 100644
index 0000000..64d8200
--- /dev/null
+++ b/platform/ext/target/nuvoton/common/native_drivers/arm_uart_drv.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2016-2017 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.
+ */
+
+/**
+ * \file arm_uart_drv.h
+ * \brief Generic driver for ARM UART.
+ */
+
+#ifndef __ARM_UART_DRV_H__
+#define __ARM_UART_DRV_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ARM UART device configuration structure */
+struct arm_uart_dev_cfg_t {
+ const uint32_t base; /*!< UART base address */
+ const uint32_t default_baudrate; /*!< Default baudrate */
+};
+
+/* ARM UART device data structure */
+struct arm_uart_dev_data_t {
+ uint32_t state; /*!< Indicates if the uart driver
+ is initialized and enabled */
+ uint32_t system_clk; /*!< System clock */
+ uint32_t baudrate; /*!< Baudrate */
+};
+
+/* ARM UART device structure */
+struct arm_uart_dev_t {
+ const struct arm_uart_dev_cfg_t* const cfg; /*!< UART configuration */
+ struct arm_uart_dev_data_t* const data; /*!< UART data */
+};
+
+/* ARM UART enumeration types */
+enum arm_uart_error_t {
+ ARM_UART_ERR_NONE = 0, /*!< No error */
+ ARM_UART_ERR_INVALID_ARG, /*!< Error invalid input argument */
+ ARM_UART_ERR_INVALID_BAUD, /*!< Invalid baudrate */
+ ARM_UART_ERR_NOT_INIT, /*!< Error UART not initialized */
+ ARM_UART_ERR_NOT_READY, /*!< Error UART not ready */
+};
+
+enum arm_uart_irq_t {
+ ARM_UART_IRQ_RX, /*!< RX interrupt source */
+ ARM_UART_IRQ_TX, /*!< TX interrupt source */
+ ARM_UART_IRQ_COMBINED /*!< RX-TX combined interrupt source */
+};
+
+/**
+ * \brief Initializes UART. It uses the default baudrate to configure
+ * the peripheral at this point.
+ *
+ * \param[in] dev UART device struct \ref arm_uart_dev_t
+ * \param[in] system_clk System clock used by the device.
+ *
+ * \return Returns error code as specified in \ref arm_uart_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum arm_uart_error_t arm_uart_init(struct arm_uart_dev_t* dev,
+ uint32_t system_clk);
+
+/**
+ * \brief Sets the UART baudrate.
+ *
+ * \param[in] dev UART device struct \ref arm_uart_dev_t
+ * \param[in] baudrate New baudrate.
+ *
+ * \return Returns error code as specified in \ref arm_uart_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum arm_uart_error_t arm_uart_set_baudrate(struct arm_uart_dev_t* dev,
+ uint32_t baudrate);
+
+/**
+ * \brief Gets the UART baudrate.
+ *
+ * \param[in] dev UART device struct \ref arm_uart_dev_t
+ *
+ * \return Returns the UART baudrate.
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint32_t arm_uart_get_baudrate(struct arm_uart_dev_t* dev);
+
+/**
+ * \brief Sets system clock.
+ *
+ * \param[in] dev UART device struct \ref arm_uart_dev_t
+ * \param[in] system_clk System clock used by the device.
+ *
+ * \return Returns error code as specified in \ref arm_uart_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum arm_uart_error_t arm_uart_set_clock(struct arm_uart_dev_t* dev,
+ uint32_t system_clk);
+/**
+ * \brief Reads one byte from UART dev.
+ *
+ * \param[in] dev UART device struct \ref arm_uart_dev_t
+ * \param[in] byte Pointer to byte.
+ *
+ * \return Returns error code as specified in \ref arm_uart_error_t
+ *
+ * \note For better performance, this function doesn't check if dev and byte
+ * pointer are NULL, and if the driver is initialized.
+ */
+enum arm_uart_error_t arm_uart_read(struct arm_uart_dev_t* dev, uint8_t* byte);
+
+/**
+ * \brief Writes a byte to UART dev.
+ *
+ * \param[in] dev UART device struct \ref arm_uart_dev_t
+ * \param[in] byte Byte to write.
+ *
+ * \return Returns error code as specified in \ref arm_uart_error_t
+ *
+ * \note For better performance, this function doesn't check if dev is NULL and
+ * if the driver is initialized to have better performance.
+ */
+enum arm_uart_error_t arm_uart_write(struct arm_uart_dev_t* dev, uint8_t byte);
+
+/**
+ * \brief Enables TX interrupt.
+ *
+ * \param[in] dev UART device struct \ref arm_uart_dev_t
+ *
+ * \return Returns error code as specified in \ref arm_uart_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum arm_uart_error_t arm_uart_irq_tx_enable(struct arm_uart_dev_t* dev);
+
+/**
+ * \brief Disables TX interrupt.
+ *
+ * \param[in] dev UART device struct \ref arm_uart_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void arm_uart_irq_tx_disable(struct arm_uart_dev_t* dev);
+
+/**
+ * \brief Verifies if Tx is ready to send more data.
+ *
+ * \param[in] dev UART device struct \ref arm_uart_dev_t
+ *
+ * \return 1 if TX is ready, 0 otherwise.
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint32_t arm_uart_tx_ready(struct arm_uart_dev_t* dev);
+
+/**
+ * \brief Enables RX interrupt.
+ *
+ * \param[in] dev UART device struct \ref arm_uart_dev_t
+ *
+ * \return Returns error code as specified in \ref arm_uart_error_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+enum arm_uart_error_t arm_uart_irq_rx_enable(struct arm_uart_dev_t* dev);
+
+/**
+ * \brief Disables RX interrupt
+ *
+ * \param[in] dev UART device struct \ref arm_uart_dev_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void arm_uart_irq_rx_disable(struct arm_uart_dev_t* dev);
+
+/**
+ * \brief Verifies if Rx has data.
+ *
+ * \param[in] dev UART device struct \ref arm_uart_dev_t
+ *
+ * \return 1 if RX has data, 0 otherwise.
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+uint32_t arm_uart_rx_ready(struct arm_uart_dev_t* dev);
+
+/**
+ * \brief Clears UART interrupt.
+ *
+ * \param[in] dev UART device struct \ref arm_uart_dev_t
+ * \param[in] irq IRQ source to clean \ref arm_uart_irq_t
+ *
+ * \note This function doesn't check if dev is NULL.
+ */
+void arm_uart_clear_interrupt(struct arm_uart_dev_t* dev,
+ enum arm_uart_irq_t irq);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __ARM_UART_DRV_H__ */
diff --git a/platform/ext/target/nuvoton/common/spm_hal.c b/platform/ext/target/nuvoton/common/spm_hal.c
index a7aa327..acaced1 100644
--- a/platform/ext/target/nuvoton/common/spm_hal.c
+++ b/platform/ext/target/nuvoton/common/spm_hal.c
@@ -81,6 +81,8 @@
uint32_t tfm_spm_hal_get_ns_entry_point(void)
{
+ printf("ns entry point = 0x%08x\r\n", memory_regions.non_secure_code_start + 4);
+
return *((uint32_t *)(memory_regions.non_secure_code_start+ 4));
}
diff --git a/platform/ext/target/nuvoton/common/target_cfg.h b/platform/ext/target/nuvoton/common/target_cfg.h
index c876880..f427b5f 100644
--- a/platform/ext/target/nuvoton/common/target_cfg.h
+++ b/platform/ext/target/nuvoton/common/target_cfg.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2019-2020 Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2020 Arm Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,26 +17,38 @@
#ifndef __TARGET_CFG_H__
#define __TARGET_CFG_H__
-#include <stdint.h>
+#include "uart_stdout.h"
+#include "tfm_peripherals_def.h"
+#include "tfm_plat_defs.h"
+#include "arm_uart_drv.h"
#define TFM_DRIVER_STDIO Driver_USART0
#define NS_DRIVER_STDIO Driver_USART0
-enum ppc_bank_e {
- PPC_SP_DO_NOT_CONFIGURE = -1,
- PPC_SP_AHB_PPC_EXP0 = 0,
- PPC_SP_APB_PPC = 1,
- PPC_SP_APB_PPC_EXP0 = 2,
- PPC_SP_APB_PPC_EXP1 = 3,
- PPC_SP_APB_PPC_EXP2 = 4,
- PPC_SP_APB_PPC_EXP3 = 5,
-};
-
/**
- * \brief MPU configs
+ * \brief Defines the word offsets of Slave Peripheral Protection Controller
+ * Registers
*/
-#define PRIVILEGED_DEFAULT_ENABLE 1
-#define HARDFAULT_NMI_ENABLE 1
+enum ppc_bank_e
+{
+ PPC_SP_DO_NOT_CONFIGURE = -1,
+ PPC_SP_AHB_PPC0 = 0,
+ PPC_SP_RES0,
+ PPC_SP_RES1,
+ PPC_SP_RES2,
+ PPC_SP_AHB_PPC_EXP0,
+ PPC_SP_AHB_PPC_EXP1,
+ PPC_SP_AHB_PPC_EXP2,
+ PPC_SP_AHB_PPC_EXP3,
+ PPC_SP_APB_PPC0,
+ PPC_SP_APB_PPC1,
+ PPC_SP_RES3,
+ PPC_SP_RES4,
+ PPC_SP_APB_PPC_EXP0,
+ PPC_SP_APB_PPC_EXP1,
+ PPC_SP_APB_PPC_EXP2,
+ PPC_SP_APB_PPC_EXP3,
+};
/**
* \brief Store the addresses of memory regions
@@ -56,7 +68,8 @@
/**
* \brief Holds the data necessary to do isolation for a specific peripheral.
*/
-struct platform_data_t {
+struct platform_data_t
+{
uint32_t periph_start;
uint32_t periph_limit;
enum ppc_bank_e periph_ppc_bank;
@@ -64,13 +77,51 @@
};
/**
- * \brief Forward declaration
+ * \brief Configures the Memory Protection Controller.
+ *
+ * \return Returns error code.
*/
-struct mpu_armv8m_region_cfg_t;
+int32_t mpc_init_cfg(void);
/**
- * \brief Enables the fault handlers BusFault, UsageFault,
- * MemManageFault and SecureFault.
+ * \brief Configures the Peripheral Protection Controller.
+ */
+void ppc_init_cfg(void);
+
+/**
+ * \brief Restict access to peripheral to secure
+ */
+void ppc_configure_to_secure(enum ppc_bank_e bank, uint16_t loc);
+
+/**
+ * \brief Allow non-secure access to peripheral
+ */
+void ppc_configure_to_non_secure(enum ppc_bank_e bank, uint16_t loc);
+
+/**
+ * \brief Enable secure unprivileged access to peripheral
+ */
+void ppc_en_secure_unpriv(enum ppc_bank_e bank, uint16_t pos);
+
+/**
+ * \brief Clear secure unprivileged access to peripheral
+ */
+void ppc_clr_secure_unpriv(enum ppc_bank_e bank, uint16_t pos);
+
+/**
+ * \brief Clears PPC interrupt.
+ */
+void ppc_clear_irq(void);
+
+/**
+ * \brief Configures SAU and IDAU.
+ */
+void sau_and_idau_cfg(void);
+
+/**
+ * \brief Enables the fault handlers and sets priorities.
+ *
+ * \return Returns values as specified by the \ref tfm_plat_err_t
*/
enum tfm_plat_err_t enable_fault_handlers(void);
@@ -92,88 +143,18 @@
* \brief Configures all external interrupts to target the
* NS state, apart for the ones associated to secure
* peripherals (plus MPC and PPC)
+ *
+ * \return Returns values as specified by the \ref tfm_plat_err_t
*/
enum tfm_plat_err_t nvic_interrupt_target_state_cfg(void);
/**
* \brief This function enable the interrupts associated
- * to the secure peripherals (plus MPC and PPC)
+ * to the secure peripherals (plus the isolation boundary violation
+ * interrupts)
+ *
+ * \return Returns values as specified by the \ref tfm_plat_err_t
*/
enum tfm_plat_err_t nvic_interrupt_enable(void);
-/**
- * \brief This function enables the MPU
- */
-enum mpu_armv8m_error_t mpu_enable(uint32_t privdef_en, uint32_t hfnmi_en);
-
-/**
- * \brief This function disables the MPU
- */
-enum mpu_armv8m_error_t mpu_disable(void);
-
-/**
- * \brief This function enables the given MPU region
- */
-enum mpu_armv8m_error_t mpu_region_enable(
- struct mpu_armv8m_region_cfg_t *region_cfg);
-
-/**
- * \brief This function dsables the given MPU region
- */
-enum mpu_armv8m_error_t mpu_region_disable(uint32_t region_nr);
-
-/**
- * \brief This function cleans all the MPU regions configs
- */
-enum mpu_armv8m_error_t mpu_clean(void);
-
-/**
- * \brief Configures the Memory Protection Controller.
- */
-enum tfm_plat_err_t mpc_init_cfg(void);
-
-/**
- * \brief Clear MPC interrupt.
- */
-void mpc_clear_irq(void);
-
-/**
- * \brief Configures the Peripheral Protection Controller.
- */
-enum tfm_plat_err_t ppc_init_cfg(void);
-
-/**
- * \brief Restict peripheral access to secure access only
- *
- * \note The function does not configure privilege
- */
-void ppc_configure_to_secure(enum ppc_bank_e bank, uint32_t pos);
-
-/**
- * \brief Allow non-secure access to peripheral
- *
- * \note The function does not configure privilege
- */
-void ppc_configure_to_non_secure(enum ppc_bank_e bank, uint32_t pos);
-
-/**
- * \brief Enable secure unprivileged access to peripheral
- */
-void ppc_en_secure_unpriv(enum ppc_bank_e bank, uint16_t pos);
-
-/**
- * \brief Clear secure unprivileged access to peripheral
- */
-void ppc_clr_secure_unpriv(enum ppc_bank_e bank, uint16_t pos);
-
-/**
- * \brief Clears PPC interrupt.
- */
-void ppc_clear_irq(void);
-
-/**
- * \brief Configures SAU and IDAU.
- */
-void sau_and_idau_cfg(void);
-
#endif /* __TARGET_CFG_H__ */
diff --git a/platform/ext/target/nuvoton/common/tfm_hal_isolation.c b/platform/ext/target/nuvoton/common/tfm_hal_isolation.c
index d5e033b..1cfa416 100644
--- a/platform/ext/target/nuvoton/common/tfm_hal_isolation.c
+++ b/platform/ext/target/nuvoton/common/tfm_hal_isolation.c
@@ -5,26 +5,78 @@
*
*/
+#include "array.h"
#include "cmsis.h"
#include "Driver_Common.h"
+#include "mmio_defs.h"
#include "mpu_armv8m_drv.h"
#include "region.h"
#include "target_cfg.h"
#include "tfm_hal_isolation.h"
-#include "tfm_plat_defs.h"
+#include "tfm_peripherals_def.h"
+#include "tfm_core_utils.h"
+#ifdef TFM_PSA_API
+#include "load/partition_defs.h"
+#include "load/asset_defs.h"
+#include "load/spm_load_api.h"
+#endif
+
+/* It can be retrieved from the MPU_TYPE register. */
+#define MPU_REGION_NUM 8
#ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT
-#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
+static uint32_t n_configured_regions = 0;
+struct mpu_armv8m_dev_t dev_mpu_s = {MPU_BASE};
-#define MPU_REGION_VENEERS 0
-#define MPU_REGION_TFM_UNPRIV_CODE 1
-#define MPU_REGION_NS_STACK 2
-#define PARTITION_REGION_RO 3
-#define PARTITION_REGION_RW_STACK 4
#ifdef CONFIG_TFM_PARTITION_META
-#define MPU_REGION_SP_META_PTR 7
+REGION_DECLARE(Image$$, TFM_SP_META_PTR, $$ZI$$Base);
+REGION_DECLARE(Image$$, TFM_SP_META_PTR, $$ZI$$Limit);
#endif /* CONFIG_TFM_PARTITION_META */
+#if TFM_LVL == 3
+static uint32_t idx_boundary_handle = 0;
+REGION_DECLARE(Image$$, PT_RO_START, $$Base);
+REGION_DECLARE(Image$$, PT_RO_END, $$Base);
+REGION_DECLARE(Image$$, PT_PRIV_RWZI_START, $$Base);
+REGION_DECLARE(Image$$, PT_PRIV_RWZI_END, $$Base);
+
+const static struct mpu_armv8m_region_cfg_t isolation_regions[] = {
+ {
+ 0, /* will be updated before using */
+ (uint32_t)®ION_NAME(Image$$, PT_RO_START, $$Base),
+ (uint32_t)®ION_NAME(Image$$, PT_RO_END, $$Base),
+ MPU_ARMV8M_MAIR_ATTR_CODE_IDX,
+ MPU_ARMV8M_XN_EXEC_OK,
+ MPU_ARMV8M_AP_RO_PRIV_UNPRIV,
+ MPU_ARMV8M_SH_NONE,
+ },
+ /* For isolation Level 3, set up static isolation for privileged data.
+ * Unprivileged data is dynamically set during Partition scheduling.
+ */
+ {
+ 0, /* will be updated before using */
+ (uint32_t)®ION_NAME(Image$$, PT_PRIV_RWZI_START, $$Base),
+ (uint32_t)®ION_NAME(Image$$, PT_PRIV_RWZI_END, $$Base),
+ MPU_ARMV8M_MAIR_ATTR_DATA_IDX,
+ MPU_ARMV8M_XN_EXEC_NEVER,
+ MPU_ARMV8M_AP_RW_PRIV_ONLY,
+ MPU_ARMV8M_SH_NONE,
+ },
+#ifdef CONFIG_TFM_PARTITION_META
+ /* TFM partition metadata pointer region */
+ {
+ 0, /* will be updated before using */
+ (uint32_t)®ION_NAME(Image$$, TFM_SP_META_PTR, $$ZI$$Base),
+ (uint32_t)®ION_NAME(Image$$, TFM_SP_META_PTR, $$ZI$$Limit),
+ MPU_ARMV8M_MAIR_ATTR_DATA_IDX,
+ MPU_ARMV8M_XN_EXEC_NEVER,
+ MPU_ARMV8M_AP_RW_PRIV_UNPRIV,
+ MPU_ARMV8M_SH_NONE
+ }
+#endif
+};
+#else /* TFM_LVL == 3 */
+
REGION_DECLARE(Image$$, ER_VENEER, $$Base);
REGION_DECLARE(Image$$, VENEER_ALIGN, $$Limit);
REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Base);
@@ -33,15 +85,11 @@
REGION_DECLARE(Image$$, TFM_APP_CODE_END, $$Base);
REGION_DECLARE(Image$$, TFM_APP_RW_STACK_START, $$Base);
REGION_DECLARE(Image$$, TFM_APP_RW_STACK_END, $$Base);
-#ifdef CONFIG_TFM_PARTITION_META
-REGION_DECLARE(Image$$, TFM_SP_META_PTR, $$ZI$$Base);
-REGION_DECLARE(Image$$, TFM_SP_META_PTR, $$ZI$$Limit);
-#endif /* CONFIG_TFM_PARTITION_META */
const struct mpu_armv8m_region_cfg_t region_cfg[] = {
/* Veneer region */
{
- MPU_REGION_VENEERS,
+ 0, /* will be updated before using */
(uint32_t)®ION_NAME(Image$$, ER_VENEER, $$Base),
(uint32_t)®ION_NAME(Image$$, VENEER_ALIGN, $$Limit),
MPU_ARMV8M_MAIR_ATTR_CODE_IDX,
@@ -51,7 +99,7 @@
},
/* TFM Core unprivileged code region */
{
- MPU_REGION_TFM_UNPRIV_CODE,
+ 0, /* will be updated before using */
(uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_CODE, $$RO$$Base),
(uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_CODE, $$RO$$Limit),
MPU_ARMV8M_MAIR_ATTR_CODE_IDX,
@@ -61,7 +109,7 @@
},
/* RO region */
{
- PARTITION_REGION_RO,
+ 0, /* will be updated before using */
(uint32_t)®ION_NAME(Image$$, TFM_APP_CODE_START, $$Base),
(uint32_t)®ION_NAME(Image$$, TFM_APP_CODE_END, $$Base),
MPU_ARMV8M_MAIR_ATTR_CODE_IDX,
@@ -71,7 +119,7 @@
},
/* RW, ZI and stack as one region */
{
- PARTITION_REGION_RW_STACK,
+ 0, /* will be updated before using */
(uint32_t)®ION_NAME(Image$$, TFM_APP_RW_STACK_START, $$Base),
(uint32_t)®ION_NAME(Image$$, TFM_APP_RW_STACK_END, $$Base),
MPU_ARMV8M_MAIR_ATTR_DATA_IDX,
@@ -82,7 +130,7 @@
#ifdef CONFIG_TFM_PARTITION_META
/* TFM partition metadata pointer region */
{
- MPU_REGION_SP_META_PTR,
+ 0, /* will be updated before using */
(uint32_t)®ION_NAME(Image$$, TFM_SP_META_PTR, $$ZI$$Base),
(uint32_t)®ION_NAME(Image$$, TFM_SP_META_PTR, $$ZI$$Limit),
MPU_ARMV8M_MAIR_ATTR_DATA_IDX,
@@ -92,39 +140,296 @@
}
#endif
};
+#endif /* TFM_LVL == 3 */
#endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */
enum tfm_hal_status_t tfm_hal_set_up_static_boundaries(void)
{
/* Set up isolation boundaries between SPE and NSPE */
sau_and_idau_cfg();
-
- if (mpc_init_cfg() != TFM_PLAT_ERR_SUCCESS) {
+ if (mpc_init_cfg() != ARM_DRIVER_OK) {
return TFM_HAL_ERROR_GENERIC;
}
-
- if (ppc_init_cfg() != TFM_PLAT_ERR_SUCCESS) {
- return TFM_HAL_ERROR_GENERIC;
- }
+ ppc_init_cfg();
/* Set up static isolation boundaries inside SPE */
#ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT
+ struct mpu_armv8m_region_cfg_t localcfg;
int32_t i;
- struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE };
mpu_armv8m_clean(&dev_mpu_s);
+#if TFM_LVL == 3
+ /*
+ * Update MPU region numbers. The numbers start from 0 and are continuous.
+ * Under isolation level3, at lease one MPU region is reserved for private
+ * data asset.
+ */
+ if (ARRAY_SIZE(isolation_regions) >= MPU_REGION_NUM) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
+ for (i = 0; i < ARRAY_SIZE(isolation_regions); i++) {
+ spm_memcpy(&localcfg, &isolation_regions[i], sizeof(localcfg));
+ /* Update region number */
+ localcfg.region_nr = i;
+ /* Enable regions */
+ if (mpu_armv8m_region_enable(&dev_mpu_s, &localcfg) != MPU_ARMV8M_OK) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
+ }
+ n_configured_regions = i;
+#else /* TFM_LVL == 3 */
+ if (ARRAY_SIZE(region_cfg) > MPU_REGION_NUM) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
for (i = 0; i < ARRAY_SIZE(region_cfg); i++) {
+ spm_memcpy(&localcfg, ®ion_cfg[i], sizeof(localcfg));
+ localcfg.region_nr = i;
if (mpu_armv8m_region_enable(&dev_mpu_s,
- (struct mpu_armv8m_region_cfg_t *)®ion_cfg[i])
+ (struct mpu_armv8m_region_cfg_t *)&localcfg)
!= MPU_ARMV8M_OK) {
return TFM_HAL_ERROR_GENERIC;
}
}
+ n_configured_regions = i;
+#endif /* TFM_LVL == 3 */
- mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE,
- HARDFAULT_NMI_ENABLE);
+ /* Enable MPU */
+ if (mpu_armv8m_enable(&dev_mpu_s,
+ PRIVILEGED_DEFAULT_ENABLE,
+ HARDFAULT_NMI_ENABLE) != MPU_ARMV8M_OK) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
#endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */
return TFM_HAL_SUCCESS;
}
+
+#ifdef TFM_PSA_API
+/*
+ * Implementation of tfm_hal_bind_boundaries() on AN521:
+ *
+ * The API encodes some attributes into a handle and returns it to SPM.
+ * The attributes include isolation boundaries, privilege, and mmio information.
+ * When scheduler switches running partitions, SPM compares the handle between
+ * partitions to know if boundary update is necessary. If update is required,
+ * SPM passes the handle to platform to do platform settings and update
+ * isolation boundaries.
+ *
+ * The handle should be unique under isolation level 3. The implementation
+ * encodes an index at the highest 8 bits to assure handle uniqueness. While
+ * under isolation level 1/2, handles may not be unique.
+ *
+ * The encoding format assignment:
+ * - For isolation level 3
+ * BIT | 31 24 | 23 20 | ... | 7 4 | 3 0 |
+ * | Unique Index | Region Attr 5 | ... | Region Attr 1 | Privileged |
+ *
+ * In which the "Region Attr i" is:
+ * BIT | 3 | 2 0 |
+ * | 1: RW, 0: RO | MMIO Index |
+ *
+ * - For isolation level 1/2
+ * BIT | 31 0 |
+ * | 1: privileged, 0: unprivileged |
+ *
+ * This is a reference implementation on AN521, and may have some limitations.
+ * 1. The maximum number of allowed MMIO regions is 5.
+ * 2. Highest 8 bits are for index. It supports 256 unique handles at most.
+ */
+enum tfm_hal_status_t tfm_hal_bind_boundaries(
+ const struct partition_load_info_t *p_ldinf,
+ void **pp_boundaries)
+{
+ uint32_t i, j;
+ bool privileged;
+ const struct asset_desc_t *p_asset;
+ struct platform_data_t *plat_data_ptr;
+#if TFM_LVL == 2
+ struct mpu_armv8m_region_cfg_t localcfg;
+#elif TFM_LVL == 3
+ uint32_t partition_attrs = 0;
+#endif
+
+ if (!p_ldinf || !pp_boundaries) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
+
+#if TFM_LVL == 1
+ privileged = true;
+#else
+ privileged = IS_PARTITION_PSA_ROT(p_ldinf);
+#endif
+
+ p_asset = (const struct asset_desc_t *)LOAD_INFO_ASSET(p_ldinf);
+
+ /*
+ * Validate if the named MMIO of partition is allowed by the platform.
+ * Otherwise, skip validation.
+ *
+ * NOTE: Need to add validation of numbered MMIO if platform requires.
+ */
+ for (i = 0; i < p_ldinf->nassets; i++) {
+ if (!(p_asset[i].attr & ASSET_ATTR_NAMED_MMIO)) {
+ continue;
+ }
+ for (j = 0; j < ARRAY_SIZE(partition_named_mmio_list); j++) {
+ if (p_asset[i].dev.dev_ref == partition_named_mmio_list[j]) {
+ break;
+ }
+ }
+
+ if (j == ARRAY_SIZE(partition_named_mmio_list)) {
+ /* The MMIO asset is not in the allowed list of platform. */
+ return TFM_HAL_ERROR_GENERIC;
+ }
+ /* Assume PPC & MPC settings are required even under level 1 */
+ plat_data_ptr = REFERENCE_TO_PTR(p_asset[i].dev.dev_ref,
+ struct platform_data_t *);
+
+ if (plat_data_ptr->periph_ppc_bank != PPC_SP_DO_NOT_CONFIGURE) {
+ ppc_configure_to_secure(plat_data_ptr->periph_ppc_bank,
+ plat_data_ptr->periph_ppc_loc);
+ if (privileged) {
+ ppc_clr_secure_unpriv(plat_data_ptr->periph_ppc_bank,
+ plat_data_ptr->periph_ppc_loc);
+ } else {
+ ppc_en_secure_unpriv(plat_data_ptr->periph_ppc_bank,
+ plat_data_ptr->periph_ppc_loc);
+ }
+ }
+#if TFM_LVL == 2
+ /*
+ * Static boundaries are set. Set up MPU region for MMIO.
+ * Setup regions for unprivileged assets only.
+ */
+ if (!privileged) {
+ localcfg.region_base = plat_data_ptr->periph_start;
+ localcfg.region_limit = plat_data_ptr->periph_limit;
+ localcfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DEVICE_IDX;
+ localcfg.attr_access = MPU_ARMV8M_AP_RW_PRIV_UNPRIV;
+ localcfg.attr_sh = MPU_ARMV8M_SH_NONE;
+ localcfg.attr_exec = MPU_ARMV8M_XN_EXEC_NEVER;
+ localcfg.region_nr = n_configured_regions++;
+
+ if (mpu_armv8m_region_enable(&dev_mpu_s, &localcfg)
+ != MPU_ARMV8M_OK) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
+ }
+#elif TFM_LVL == 3
+ /* Encode MMIO attributes into the "partition_attrs". */
+ partition_attrs <<= HANDLE_PER_ATTR_BITS;
+ partition_attrs |= ((j + 1) & HANDLE_ATTR_INDEX_MASK);
+ if (p_asset[i].attr & ASSET_ATTR_READ_WRITE) {
+ partition_attrs |= HANDLE_ATTR_RW_POS;
+ }
+#endif
+ }
+
+#if TFM_LVL == 3
+ partition_attrs <<= HANDLE_PER_ATTR_BITS;
+ partition_attrs |= ((uint8_t)privileged) & HANDLE_ATTR_PRIV_MASK;
+ /*
+ * Highest 8 bits are reserved for index, if they are non-zero, MMIO numbers
+ * must have exceeded the limit of 5.
+ */
+ if (partition_attrs & HANDLE_INDEX_MASK) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
+ HANDLE_ENCODE_INDEX(partition_attrs, idx_boundary_handle);
+ *pp_boundaries = (void *)partition_attrs;
+#else
+ *pp_boundaries = (void *)(((uint32_t)privileged) & HANDLE_ATTR_PRIV_MASK);
+#endif
+
+ return TFM_HAL_SUCCESS;
+}
+
+enum tfm_hal_status_t tfm_hal_update_boundaries(
+ const struct partition_load_info_t *p_ldinf,
+ void *p_boundaries)
+{
+ CONTROL_Type ctrl;
+ uint32_t local_handle = (uint32_t)p_boundaries;
+ bool privileged = !!(local_handle & HANDLE_ATTR_PRIV_MASK);
+#if TFM_LVL == 3
+ struct mpu_armv8m_region_cfg_t localcfg;
+ uint32_t i, mmio_index;
+ struct platform_data_t *plat_data_ptr;
+ struct asset_desc_t *rt_mem;
+#endif
+
+ /* Privileged level is required to be set always */
+ ctrl.w = __get_CONTROL();
+ ctrl.b.nPRIV = privileged ? 0 : 1;
+ __set_CONTROL(ctrl.w);
+
+#if TFM_LVL == 3
+ if (!p_ldinf) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
+
+ /* Update regions, for unprivileged partitions only */
+ if (privileged) {
+ return TFM_HAL_SUCCESS;
+ }
+
+ /* Setup runtime memory first */
+ localcfg.attr_exec = MPU_ARMV8M_XN_EXEC_NEVER;
+ localcfg.attr_sh = MPU_ARMV8M_SH_NONE;
+ localcfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DATA_IDX;
+ localcfg.attr_access = MPU_ARMV8M_AP_RW_PRIV_UNPRIV;
+ rt_mem = (struct asset_desc_t *)LOAD_INFO_ASSET(p_ldinf);
+ /*
+ * AN521 shortcut: The first item is the only runtime memory asset.
+ * Platforms with many memory assets please check this part.
+ */
+ for (i = 0;
+ i < p_ldinf->nassets && !(rt_mem[i].attr & ASSET_ATTR_MMIO);
+ i++) {
+ localcfg.region_nr = n_configured_regions + i;
+ localcfg.region_base = rt_mem[i].mem.start;
+ localcfg.region_limit = rt_mem[i].mem.limit;
+
+ if (mpu_armv8m_region_enable(&dev_mpu_s, &localcfg) != MPU_ARMV8M_OK) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
+ }
+
+ /* Named MMIO part */
+ local_handle = local_handle & (~HANDLE_INDEX_MASK);
+ local_handle >>= HANDLE_PER_ATTR_BITS;
+ mmio_index = local_handle & HANDLE_ATTR_INDEX_MASK;
+
+ localcfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DEVICE_IDX;
+
+ i = n_configured_regions + i;
+ while (mmio_index && i < MPU_REGION_NUM) {
+ plat_data_ptr =
+ (struct platform_data_t *)partition_named_mmio_list[mmio_index - 1];
+ localcfg.region_nr = i++;
+ localcfg.attr_access = (local_handle & HANDLE_ATTR_RW_POS)?
+ MPU_ARMV8M_AP_RW_PRIV_UNPRIV :
+ MPU_ARMV8M_AP_RO_PRIV_UNPRIV;
+ localcfg.region_base = plat_data_ptr->periph_start;
+ localcfg.region_limit = plat_data_ptr->periph_limit;
+
+ if (mpu_armv8m_region_enable(&dev_mpu_s, &localcfg) != MPU_ARMV8M_OK) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
+
+ local_handle >>= HANDLE_PER_ATTR_BITS;
+ mmio_index = local_handle & HANDLE_ATTR_INDEX_MASK;
+ }
+
+ /* Disable unused regions */
+ while (i < MPU_REGION_NUM) {
+ if (mpu_armv8m_region_disable(&dev_mpu_s, i++)!= MPU_ARMV8M_OK) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
+ }
+#endif
+ return TFM_HAL_SUCCESS;
+}
+#endif /* TFM_PSA_API */
diff --git a/platform/ext/target/nuvoton/common/tfm_hal_platform.c b/platform/ext/target/nuvoton/common/tfm_hal_platform.c
index de04d70..c087635 100644
--- a/platform/ext/target/nuvoton/common/tfm_hal_platform.c
+++ b/platform/ext/target/nuvoton/common/tfm_hal_platform.c
@@ -13,39 +13,53 @@
extern const struct memory_region_limits memory_regions;
+#ifdef TFM_FIH_PROFILE_ON
+fih_int tfm_hal_platform_init(void)
+#else
enum tfm_hal_status_t tfm_hal_platform_init(void)
+#endif
{
enum tfm_plat_err_t plat_err = TFM_PLAT_ERR_SYSTEM_ERR;
+#ifdef TFM_FIH_PROFILE_ON
+ fih_int fih_rc = FIH_FAILURE;
+#endif
plat_err = enable_fault_handlers();
if (plat_err != TFM_PLAT_ERR_SUCCESS) {
- return TFM_HAL_ERROR_GENERIC;
+ FIH_RET(fih_int_encode(TFM_HAL_ERROR_GENERIC));
}
plat_err = system_reset_cfg();
if (plat_err != TFM_PLAT_ERR_SUCCESS) {
- return TFM_HAL_ERROR_GENERIC;
+ FIH_RET(fih_int_encode(TFM_HAL_ERROR_GENERIC));
}
+#ifdef TFM_FIH_PROFILE_ON
+ FIH_CALL(init_debug, fih_rc);
+ if (fih_not_eq(fih_rc, fih_int_encode(TFM_PLAT_ERR_SUCCESS))) {
+ FIH_RET(fih_int_encode(TFM_HAL_ERROR_GENERIC));
+ }
+#else
plat_err = init_debug();
if (plat_err != TFM_PLAT_ERR_SUCCESS) {
return TFM_HAL_ERROR_GENERIC;
}
+#endif
__enable_irq();
stdio_init();
plat_err = nvic_interrupt_target_state_cfg();
if (plat_err != TFM_PLAT_ERR_SUCCESS) {
- return TFM_HAL_ERROR_GENERIC;
+ FIH_RET(fih_int_encode(TFM_HAL_ERROR_GENERIC));
}
plat_err = nvic_interrupt_enable();
if (plat_err != TFM_PLAT_ERR_SUCCESS) {
- return TFM_HAL_ERROR_GENERIC;
+ FIH_RET(fih_int_encode(TFM_HAL_ERROR_GENERIC));
}
- return TFM_HAL_SUCCESS;
+ FIH_RET(fih_int_encode(TFM_HAL_SUCCESS));
}
uint32_t tfm_hal_get_ns_VTOR(void)
diff --git a/platform/ext/target/nuvoton/m2354/CMakeLists.txt b/platform/ext/target/nuvoton/m2354/CMakeLists.txt
index 779400f..84057bc 100644
--- a/platform/ext/target/nuvoton/m2354/CMakeLists.txt
+++ b/platform/ext/target/nuvoton/m2354/CMakeLists.txt
@@ -25,7 +25,7 @@
$<$<C_COMPILER_ID:IAR>:${CMAKE_CURRENT_SOURCE_DIR}/device/source/iar/startup_cmsdk_m2354_s.s>
)
target_add_scatter_file(tfm_s
- $<$<C_COMPILER_ID:ARMClang>:${CMAKE_CURRENT_SOURCE_DIR}/device/source/armclang/m2354_s.sct>
+ $<$<AND:$<VERSION_LESS:${TFM_ISOLATION_LEVEL},3>,$<C_COMPILER_ID:ARMClang>>:${CMAKE_SOURCE_DIR}/platform/ext/common/armclang/tfm_common_s.sct>
$<$<AND:$<VERSION_LESS:${TFM_ISOLATION_LEVEL},3>,$<C_COMPILER_ID:GNU>>:${CMAKE_SOURCE_DIR}/platform/ext/common/gcc/tfm_common_s.ld>
$<$<AND:$<VERSION_LESS:${TFM_ISOLATION_LEVEL},3>,$<C_COMPILER_ID:IAR>>:${CMAKE_SOURCE_DIR}/platform/ext/common/iar/tfm_common_s.icf>
)
@@ -88,11 +88,12 @@
device/source/device_definition.c
../common/cmsis_drivers/Driver_Flash.c
../common/cmsis_drivers/Driver_USART.c
- ../common/native_drivers/uart_cmsdk_drv.c
+ ../common/native_drivers/arm_uart_drv.c
../common/native_drivers/mpu_armv8m_drv.c
../common/native_drivers/timer_cmsdk_drv.c
bsp/Library/StdDriver/src/timer.c
bsp/Library/StdDriver/src/fmc.c
+ bsp/Library/StdDriver/src/tamper.c
../common/services/src/tfm_platform_system.c
target_cfg.c
../common/spm_hal.c
@@ -114,7 +115,7 @@
target_sources(platform_ns
PRIVATE
- ../common/native_drivers/uart_cmsdk_drv.c
+ ../common/native_drivers/arm_uart_drv.c
../common/cmsis_drivers/Driver_USART.c
device/source/device_definition.c
device/source/system_core_init.c
@@ -144,9 +145,10 @@
device/source/device_definition.c
device/source/system_core_init.c
../common/cmsis_drivers/Driver_Flash.c
- ../common/native_drivers/uart_cmsdk_drv.c
+ ../common/native_drivers/arm_uart_drv.c
../common/cmsis_drivers/Driver_USART.c
bsp/Library/StdDriver/src/fmc.c
+ bsp/Library/StdDriver/src/tamper.c
)
target_include_directories(platform_bl2
PUBLIC
diff --git a/platform/ext/target/nuvoton/m2354/README.rst b/platform/ext/target/nuvoton/m2354/README.rst
index 20558e9..b978f74 100644
--- a/platform/ext/target/nuvoton/m2354/README.rst
+++ b/platform/ext/target/nuvoton/m2354/README.rst
@@ -14,6 +14,7 @@
-G"Unix Makefiles" \
-DTFM_PLATFORM=nuvoton/m2354 \
-DTFM_TOOLCHAIN_FILE=../toolchain_GNUARM.cmake \
+ -DMCUBOOT_FIH_PROFILE=MEDIUM \
-DTEST_S=ON \
-DTEST_NS=ON \
-DTFM_ISOLATION_LEVEL=2 \
@@ -45,4 +46,4 @@
--------------
-*Copyright (c) 2021, Nuvoton Technology Corp. All rights reserved.*
+*Copyright (c) 2021-2022, Nuvoton Technology Corp. All rights reserved.*
diff --git a/platform/ext/target/nuvoton/common/bsp/Include/tamper_reg.h b/platform/ext/target/nuvoton/m2354/bsp/Device/Nuvoton/M2354/Include/tamper_reg.h
similarity index 100%
rename from platform/ext/target/nuvoton/common/bsp/Include/tamper_reg.h
rename to platform/ext/target/nuvoton/m2354/bsp/Device/Nuvoton/M2354/Include/tamper_reg.h
diff --git a/platform/ext/target/nuvoton/m2354/bsp/Library/StdDriver/inc/tamper.h b/platform/ext/target/nuvoton/m2354/bsp/Library/StdDriver/inc/tamper.h
index 2baa12a..ab4e766 100644
--- a/platform/ext/target/nuvoton/m2354/bsp/Library/StdDriver/inc/tamper.h
+++ b/platform/ext/target/nuvoton/m2354/bsp/Library/StdDriver/inc/tamper.h
@@ -68,6 +68,20 @@
#define TAMPER_REF_SEED 0x1UL /*!< The new reference pattern is repeated from SEED (TAMPER_SEED[31:0]) when the reference pattern run out */
#define TAMPER_VG_192M_SAMPLE 0x0UL /*!< Select voltage glitch 192M sampleing rate */
+#define TAMPER_VG_96M_SAMPLE 0x1UL /*!< Select voltage glitch 96M sampleing rate */
+#define TAMPER_VG_48M_SAMPLE 0x2UL /*!< Select voltage glitch 48M sampleing rate */
+
+#define TAMPER_LBSTRIM_TLVDSEL_1_25V 0x0UL /*!< Select the trim value of the under-shoot detection level as 1.25V */
+#define TAMPER_LBSTRIM_TLVDSEL_1_20V 0x1UL /*!< Select the trim value of the under-shoot detection level as 1.2V */
+#define TAMPER_LBSTRIM_TLVDSEL_1_15V 0x2UL /*!< Select the trim value of the under-shoot detection level as 1.15V */
+#define TAMPER_LBSTRIM_TLVDSEL_1_10V 0x3UL /*!< Select the trim value of the under-shoot detection level as 1.1V */
+#define TAMPER_LBSTRIM_TLVDSEL_1_05V 0x4UL /*!< Select the trim value of the under-shoot detection level as 1.05V */
+#define TAMPER_LBSTRIM_TLVDSEL_1_00V 0x5UL /*!< Select the trim value of the under-shoot detection level as 1.0V */
+#define TAMPER_LBSTRIM_TLVDSEL_0_95V 0x6UL /*!< Select the trim value of the under-shoot detection level as 0.95V */
+#define TAMPER_LBSTRIM_TLVDSEL_0_90V 0x7UL /*!< Select the trim value of the under-shoot detection level as 0.9V */
+
+#define TAMPER_LBSTRIM_TOVDSEL_1_35V 0x0UL /*!< Select the trim value of the over-shoot detection level as 1.35V */
+#define TAMPER_LBSTRIM_TOVDSEL_1_40V 0x1UL /*!< Select the trim value of the over-shoot detection level as 1.4V */
/**@}*/ /* end of group TAMPER_EXPORTED_CONSTANTS */
@@ -79,10 +93,6 @@
/**
* @brief Reset Tamper Coreblock
*
- * @param None
- *
- * @return None
- *
* @details To set TAMPER INIT control register to reset the tamper coreblock.
*
*/
@@ -91,10 +101,6 @@
/**
* @brief Release Tamper Coreblock
*
- * @param None
- *
- * @return None
- *
* @details To set TAMPER INIT control register to release the tamper coreblock.
*
*/
@@ -103,8 +109,6 @@
/**
* @brief Get the Voltage Regulator Power Ready Status
*
- * @param None
- *
* @retval 0 The power status of voltage regulator is not ready.
* @retval 1 The power status of voltage regulator is ready.
*
@@ -116,10 +120,6 @@
/**
* @brief Enable LXT Clock Detection
*
- * @param None
- *
- * @return None
- *
* @details To set TAMPER FUNEN control register to enable LXT clock detection.
*
*/
@@ -128,10 +128,6 @@
/**
* @brief Disable LXT Clock Detection
*
- * @param None
- *
- * @return None
- *
* @details To set TAMPER FUNEN control register to disable LXT clock detection.
*
*/
@@ -148,8 +144,6 @@
* - \ref TAMPER_TAMPER4_SELECT
* - \ref TAMPER_TAMPER5_SELECT
*
- * @return None
- *
* @details To set TAMPER FUNEN control register to select tamper I/O 0~5 and its function is detected through TAMPER block.
*
*/
@@ -177,8 +171,6 @@
* - \ref TAMPER_TAMPER4_SELECT
* - \ref TAMPER_TAMPER5_SELECT
*
- * @return None
- *
* @details To set TAMPER FUNEN control register to select tamper I/O 0~5 and its function is detected through RTC block.
*
*/
@@ -198,10 +190,6 @@
/**
* @brief Enable HIRC48M
*
- * @param None
- *
- * @return None
- *
* @details To set TAMPER FUNEN control register to enable HIRC48M.
*
*/
@@ -210,10 +198,6 @@
/**
* @brief Disable HIRC48M
*
- * @param None
- *
- * @return None
- *
* @details To set TAMPER FUNEN control register to disable HIRC48M.
*
*/
@@ -222,10 +206,10 @@
/**
* @brief Voltage Glitch Sampling Rate Selection
*
- * @param[in] u32VGSampleRate Voltage Glitch sampling rate select. Possible option is
+ * @param[in] u32VGSampleRate Voltage glitch sampling rate select. Possible options are
* - \ref TAMPER_VG_192M_SAMPLE
- *
- * @return None
+ * - \ref TAMPER_VG_96M_SAMPLE
+ * - \ref TAMPER_VG_48M_SAMPLE
*
* @details To set TAMPER FUNEN control register to enable voltage glitch channel 0~3 to select voltage glitch sampling rate.
*
@@ -238,15 +222,76 @@
{
TAMPER->FUNEN |= TAMPER_FUNEN_VGCHEN0_Msk | TAMPER_FUNEN_VGCHEN1_Msk | TAMPER_FUNEN_VGCHEN2_Msk | TAMPER_FUNEN_VGCHEN3_Msk;
}
+ else if(u32VGSampleRate == TAMPER_VG_96M_SAMPLE)
+ {
+ TAMPER->FUNEN |= TAMPER_FUNEN_VGCHEN0_Msk | TAMPER_FUNEN_VGCHEN1_Msk;
+ }
+ else if(u32VGSampleRate == TAMPER_VG_48M_SAMPLE)
+ {
+ TAMPER->FUNEN |= TAMPER_FUNEN_VGCHEN0_Msk;
+ }
}
/**
+ * @brief Voltage Glitch Reference Trim Value Initialization
+ *
+ * @details To set TAMPER VG or VG2 control register to initialize a reference trim value that provides voltage glitch detection
+ * error tolerance within 15%.
+ *
+ */
+__STATIC_INLINE void TAMPER_VG_TRIM_INIT()
+{
+ if(SYS->PLSTS & SYS_PLSTS_PLSTATUS_PL0)
+ {
+ TAMPER->VG = (TAMPER->VG & ~0xFFFFUL) | 0x8CC8UL;
+ }
+ else if(SYS->PLSTS & SYS_PLSTS_PLSTATUS_PL1)
+ {
+ TAMPER->VG = (TAMPER->VG & ~0xFFFF0000UL) | 0x7CC90000UL;
+ }
+ else if(SYS->PLSTS & SYS_PLSTS_PLSTATUS_PL2)
+ {
+ TAMPER->VG2 = (TAMPER->VG2 & ~0xFFFFUL) | 0x5CCBUL;
+ }
+ else if(SYS->PLSTS & SYS_PLSTS_PLSTATUS_PL3)
+ {
+ TAMPER->VG2 = (TAMPER->VG2 & ~0xFFFF0000UL) | 0x2CCD0000UL;
+ }
+}
+
+/**
+ * @brief Under-shoot Detection Level Trim Value Initialization
+ *
+ * @param[in] u32TLVDTrim Under-shoot detect level trim value select. Possible options are
+ * - \ref TAMPER_LBSTRIM_TLVDSEL_1_25V
+ * - \ref TAMPER_LBSTRIM_TLVDSEL_1_20V
+ * - \ref TAMPER_LBSTRIM_TLVDSEL_1_15V
+ * - \ref TAMPER_LBSTRIM_TLVDSEL_1_10V
+ * - \ref TAMPER_LBSTRIM_TLVDSEL_1_05V
+ * - \ref TAMPER_LBSTRIM_TLVDSEL_1_00V
+ * - \ref TAMPER_LBSTRIM_TLVDSEL_0_95V
+ * - \ref TAMPER_LBSTRIM_TLVDSEL_0_90V
+ *
+ * @details To set TAMPER LBSTRIM control register to select under-shoot detection level trim value.
+ *
+ */
+#define TAMPER_TLVD_TRIM_INIT(u32TLVDTrim) ((uint32_t)(TAMPER->LBSTRIM = (TAMPER->LBSTRIM & (~TAMPER_LBSTRIM_TLVDSEL_Msk)) | (u32TLVDTrim << TAMPER_LBSTRIM_TLVDSEL_Pos)))
+
+/**
+ * @brief Over-shoot Detection Level Trim Value Initialization
+ *
+ * @param[in] u32TOVDTrim Over-shoot detect level trim value select. Possible options are
+ * - \ref TAMPER_LBSTRIM_TOVDSEL_1_35V
+ * - \ref TAMPER_LBSTRIM_TOVDSEL_1_40V
+ *
+ * @details To set TAMPER LBSTRIM control register to select over-shoot detection level trim value.
+ *
+ */
+#define TAMPER_TOVD_TRIM_INIT(u32TOVDTrim) ((uint32_t)(TAMPER->LBSTRIM = (TAMPER->LBSTRIM & (~TAMPER_LBSTRIM_TOVDSEL_Msk)) | (u32TOVDTrim << TAMPER_LBSTRIM_TOVDSEL_Pos)))
+
+/**
* @brief Enable to Trigger Key Store
*
- * @param None
- *
- * @return None
- *
* @details Set KSTRIGEN bit of TAMPER TRIEN control register to trigger Key Store when Tamper event is detected.
*
*/
@@ -255,10 +300,6 @@
/**
* @brief Disable to Trigger Key Store
*
- * @param None
- *
- * @return None
- *
* @details Clear KSTRIGEN bit of TAMPER TRIEN control register to not trigger Key Store when Tamper event is detected.
*
*/
@@ -267,10 +308,6 @@
/**
* @brief Enable Wake-up Function
*
- * @param None
- *
- * @return None
- *
* @details Set WAKEUPEN bit of TAMPER TRIEN control register to wake-up the system when Tamper event is detected.
*
*/
@@ -279,10 +316,6 @@
/**
* @brief Disable Wake-up Function
*
- * @param None
- *
- * @return None
- *
* @details Clear WAKEUPEN bit of TAMPER TRIEN control register to not wake-up the system when Tamper event is detected.
*
*/
@@ -291,10 +324,6 @@
/**
* @brief Enable to Clear Crypto Function
*
- * @param None
- *
- * @return None
- *
* @details Set CRYPTOEN bit of TAMPER TRIEN control register to reset Crypto when Tamper event is detected.
*
*/
@@ -303,10 +332,6 @@
/**
* @brief Disable to Clear Crypto Function
*
- * @param None
- *
- * @return None
- *
* @details Clear CRYPTOEN bit of TAMPER TRIEN control register to not reset Crypto when Tamper event is detected.
*
*/
@@ -315,10 +340,6 @@
/**
* @brief Enable to Trigger Chip Reset
*
- * @param None
- *
- * @return None
- *
* @details Set CHIPRSTEN bit of TAMPER TRIEN control register to reset the system when Tamper event is detected.
*
*/
@@ -327,10 +348,6 @@
/**
* @brief Disable to Trigger Chip Reset
*
- * @param None
- *
- * @return None
- *
* @details Clear CHIPRSTEN bit of TAMPER TRIEN control register to not reset the system when Tamper event is detected.
*
*/
@@ -339,10 +356,6 @@
/**
* @brief Enable to Clear RTC Spare Register
*
- * @param None
- *
- * @return None
- *
* @details Set RTCSPCLREN bit of TAMPER TRIEN control register to reset RTC spare register when Tamper event is detected.
*
*/
@@ -351,10 +364,6 @@
/**
* @brief Disable to Clear RTC Spare Register
*
- * @param None
- *
- * @return None
- *
* @details Clear RTCSPCLREN bit of TAMPER TRIEN control register to not reset RTC spare register when Tamper event is detected.
*
*/
@@ -363,15 +372,13 @@
/**
* @brief Get Tamper Interrupt Flag
*
- * @param None
- *
* @retval 0 Tamper event Interrupt did not occur
* @retval 1 Tamper event Interrupt occurred
*
* @details This macro indicates Tamper event intertupt occurred or not.
*
*/
-#define TAMPER_GET_INT_FLAG() ((TAMPER->INTSTS & (0xAA7FAFFF))? 1:0)
+#define TAMPER_GET_INT_FLAG() ((TAMPER->INTSTS & (0xAA77AFFF))? 1:0)
/**
* @brief Clear Tamper Interrupt Status
@@ -391,14 +398,14 @@
* - \ref TAMPER_INTSTS_ACTSEIF_Msk
* - \ref TAMPER_INTSTS_ACTST5IF_Msk
* - \ref TAMPER_INTSTS_ACTST25IF_Msk
+ * - \ref TAMPER_INTSTS_VBATLOSSIF_Msk
+ * - \ref TAMPER_INTSTS_SECWDTIF_Msk
* - \ref TAMPER_INTSTS_BODIF_Msk
* - \ref TAMPER_INTSTS_ACTST1IF_Msk
* - \ref TAMPER_INTSTS_ACTST3IF_Msk
* - \ref TAMPER_INTSTS_ACTST21IF_Msk
* - \ref TAMPER_INTSTS_ACTST23IF_Msk
*
- * @return None
- *
* @details This macro is used to clear Tamper event flag.
*
*/
@@ -407,8 +414,6 @@
/**
* @brief Get Tamper Interrupt Status
*
- * @param None
- *
* @retval TAMPER_INTSTS_TAMP0IF_Msk
* @retval TAMPER_INTSTS_TAMP1IF_Msk
* @retval TAMPER_INTSTS_TAMP2IF_Msk
@@ -426,6 +431,8 @@
* @retval TAMPER_INTSTS_RTCLVRIF_Msk
* @retval TAMPER_INTSTS_RIOTRIGIF_Msk
* @retval TAMPER_INTSTS_RCLKTRIGIF_Msk
+ * @retval TAMPER_INTSTS_VBATLOSSIF_Msk
+ * @retval TAMPER_INTSTS_SECWDTIF_Msk
* @retval TAMPER_INTSTS_BODIF_Msk
* @retval TAMPER_INTSTS_ACTST1IF_Msk
* @retval TAMPER_INTSTS_ACTST3IF_Msk
@@ -435,7 +442,7 @@
* @details This macro indicates Tamper event status.
*
*/
-#define TAMPER_GET_INT_STATUS() ((TAMPER->INTSTS & (0xAA7FAFFF)))
+#define TAMPER_GET_INT_STATUS() ((TAMPER->INTSTS & (0xAA77AFFF)))
void TAMPER_EnableInt(uint32_t u32IntFlagMask);
void TAMPER_DisableInt(uint32_t u32IntFlagMask);
@@ -461,3 +468,4 @@
#endif
#endif /* __TAMPER_H__ */
+
diff --git a/platform/ext/target/nuvoton/common/bsp/StdDriver/src/tamper.c b/platform/ext/target/nuvoton/m2354/bsp/Library/StdDriver/src/tamper.c
similarity index 100%
rename from platform/ext/target/nuvoton/common/bsp/StdDriver/src/tamper.c
rename to platform/ext/target/nuvoton/m2354/bsp/Library/StdDriver/src/tamper.c
diff --git a/platform/ext/target/nuvoton/m2354/device/source/system_core_init.c b/platform/ext/target/nuvoton/m2354/device/source/system_core_init.c
index 89f1899..460f1f8 100644
--- a/platform/ext/target/nuvoton/m2354/device/source/system_core_init.c
+++ b/platform/ext/target/nuvoton/m2354/device/source/system_core_init.c
@@ -64,63 +64,147 @@
#endif
//#if __DOMAIN_NS == 0
-#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3L)
- /* Initial the system */
- SYS_UnlockReg();
+#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3L) && defined(BL2))
- /* Enable HIRC and waiting for stable */
- CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
- while((CLK->STATUS & CLK_STATUS_HIRCSTB_Msk) == 0);
+ /* Initial the system */
+ SYS_UnlockReg();
- /* Enable PLL and waiting for stable */
- CLK->PLLCTL = CLK_PLLCTL_96MHz_HIRC;
- while((CLK->STATUS & CLK_STATUS_PLLSTB_Msk) == 0);
+#ifdef NV_ENABLE_ETM
+ /* Init ETM Trace */
+ SYS->GPE_MFPH = (SYS->GPE_MFPH & (~(TRACE_CLK_PE12_Msk | TRACE_DATA0_PE11_Msk | TRACE_DATA1_PE10_Msk | TRACE_DATA2_PE9_Msk | TRACE_DATA3_PE8_Msk))) |
+ TRACE_CLK_PE12 | TRACE_DATA0_PE11 | TRACE_DATA1_PE10 | TRACE_DATA2_PE9 | TRACE_DATA3_PE8;
- /* Set flash access delay cycle */
- FMC->CYCCTL = 3;
-
- /* Switch HCLK clock source to PLL */
- CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLKSEL_Msk)) | CLK_CLKSEL0_HCLKSEL_PLL;
- CLK->CLKDIV0 = 0;
-
- /* Enable IP clock */
- CLK->APBCLK0 |= CLK_APBCLK0_UART0CKEN_Msk | CLK_APBCLK0_TMR0CKEN_Msk | CLK_APBCLK0_TMR2CKEN_Msk;
-
- /* Select UART clock source */
- CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_UART0SEL_Msk)) | CLK_CLKSEL2_UART0SEL_HIRC;
-
- /* Timer clock source */
- CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_TMR0SEL_Msk)) | CLK_CLKSEL1_TMR0SEL_HIRC;
- CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_TMR2SEL_Msk)) | CLK_CLKSEL1_TMR2SEL_HIRC;
-
- /* Set multi-function pins for UART0 RXD and TXD */
- SYS->GPA_MFPL = (SYS->GPA_MFPL & (~(UART0_RXD_PA6_Msk | UART0_TXD_PA7_Msk))) | UART0_RXD_PA6 | UART0_TXD_PA7;
-
- /* Set UART 0 to Non-secure */
- SCU_SET_PNSSET(UART0_Attr);
-
- /* Set SAU */
- SAU->RNR = 3;
- SAU->RBAR = 0x50000000;
- SAU->RLAR = (0x5FFFFFFF & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk;
-
- /* Init ETM Trace */
- SYS->GPE_MFPH = (SYS->GPE_MFPH & (~(TRACE_CLK_PE12_Msk | TRACE_DATA0_PE11_Msk | TRACE_DATA1_PE10_Msk | TRACE_DATA2_PE9_Msk | TRACE_DATA3_PE8_Msk))) |
- TRACE_CLK_PE12 | TRACE_DATA0_PE11 | TRACE_DATA1_PE10 | TRACE_DATA2_PE9 | TRACE_DATA3_PE8;
-
- /* power gating */
- M32(0x400001f4) = 0xfffffffful;
- M32(0x400000dC) = 0ul;
- /* GPIO clk */
- CLK->AHBCLK |= (0xffful << 20) | (1ul << 14);
-
- /* PD2 LED */
- PD2 = 1;
- PD->MODE = (PD->MODE & (~(0x3 << 2))) | (1 << 2);
-
+ CLK->AHBCLK |= CLK_AHBCLK_TRACECKEN_Msk;
#endif
+ /* power gating */
+ M32(0x400001f4) = 0xfffffffful;
+ M32(0x400000dC) = 0ul;
+
+ /* Enable SRAM Clock */
+ CLK->AHBCLK |= CLK_AHBCLK_SRAM0CKEN_Msk | CLK_AHBCLK_SRAM1CKEN_Msk | CLK_AHBCLK_SRAM2CKEN_Msk;
+
+ /* Enable GPIO Clock */
+ CLK->AHBCLK |= CLK_AHBCLK_GPACKEN_Msk | CLK_AHBCLK_GPBCKEN_Msk | CLK_AHBCLK_GPCCKEN_Msk | CLK_AHBCLK_GPDCKEN_Msk |
+ CLK_AHBCLK_GPECKEN_Msk | CLK_AHBCLK_GPFCKEN_Msk | CLK_AHBCLK_GPGCKEN_Msk | CLK_AHBCLK_GPHCKEN_Msk;
+
+ /* Enable HIRC and waiting for stable */
+ CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk;
+ while((CLK->STATUS & CLK_STATUS_HIRCSTB_Msk) == 0);
+
+ /* Force to use HIRC */
+ CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLKSEL_Msk)) | CLK_CLKSEL0_HCLKSEL_HIRC;
+
+ /* Enable PLL and waiting for stable */
+ CLK->PLLCTL = CLK_PLLCTL_96MHz_HIRC;
+ while((CLK->STATUS & CLK_STATUS_PLLSTB_Msk) == 0);
+
+ /* Set flash access delay cycle */
+ FMC->CYCCTL = (FMC->CYCCTL & (~FMC_CYCCTL_CYCLE_Msk)) | (4 << FMC_CYCCTL_CYCLE_Pos);
+
+ /* Switch HCLK clock source to PLL */
+ CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLKSEL_Msk)) | CLK_CLKSEL0_HCLKSEL_PLL;
+ CLK->CLKDIV0 = (CLK->CLKDIV0 & (~CLK_CLKDIV0_HCLKDIV_Msk)) | (0 << CLK_CLKDIV0_HCLKDIV_Pos);
+
+ /* Enable Crypto Accelerator */
+ CLK->AHBCLK |= CLK_AHBCLK_CRPTCKEN_Msk;
+
+ /* Enable SDH for secondary slot */
+ CLK->AHBCLK |= CLK_AHBCLK_SDH0CKEN_Msk;
+
+ /* Set multi-function pin for SDH */
+ /* CD: PB12(9) */
+ SYS->GPB_MFPH = (SYS->GPB_MFPH & (~SYS_GPB_MFPH_PB12MFP_Msk)) | SD0_nCD_PB12;
+
+ /* CLK: PB1(3), PE6(3) */
+ SYS->GPB_MFPL = (SYS->GPB_MFPL & (~SYS_GPB_MFPL_PB1MFP_Msk)) | SD0_CLK_PB1;
+ //SYS->GPE_MFPL = (SYS->GPE_MFPL & (~SYS_GPE_MFPL_PE6MFP_Msk)) | SD0_CLK_PE6;
+
+ /* CMD: PB0(3), PE7(3) */
+ SYS->GPB_MFPL = (SYS->GPB_MFPL & (~SYS_GPB_MFPL_PB0MFP_Msk)) | SD0_CMD_PB0;
+ //SYS->GPE_MFPL = (SYS->GPE_MFPL & (~SYS_GPE_MFPL_PE7MFP_Msk)) | SD0_CMD_PE7;
+
+ /* D0: PB2(3), PE2(3) */
+ SYS->GPB_MFPL = (SYS->GPB_MFPL & (~SYS_GPB_MFPL_PB2MFP_Msk)) | SD0_DAT0_PB2;
+ //SYS->GPE_MFPL = (SYS->GPE_MFPL & (~SYS_GPE_MFPL_PE2MFP_Msk)) | SD0_DAT0_PE2;
+
+ /* D1: PB3(3), PE3(3) */
+ SYS->GPB_MFPL = (SYS->GPB_MFPL & (~SYS_GPB_MFPL_PB3MFP_Msk)) | SD0_DAT1_PB3;
+ //SYS->GPE_MFPL = (SYS->GPE_MFPL & (~SYS_GPE_MFPL_PE3MFP_Msk)) | SD0_DAT1_PE3;
+
+ /* D2: PB4(3), PE4(3) */
+ SYS->GPB_MFPL = (SYS->GPB_MFPL & (~SYS_GPB_MFPL_PB4MFP_Msk)) | SD0_DAT2_PB4;
+ //SYS->GPE_MFPL = (SYS->GPE_MFPL & (~SYS_GPE_MFPL_PE4MFP_Msk)) | SD0_DAT2_PE4;
+
+ /* D3: PB5(3)-, PE5(3) */
+ SYS->GPB_MFPL = (SYS->GPB_MFPL & (~SYS_GPB_MFPL_PB5MFP_Msk)) | SD0_DAT3_PB5;
+ //SYS->GPE_MFPL = (SYS->GPE_MFPL & (~SYS_GPE_MFPL_PE5MFP_Msk)) | SD0_DAT3_PE5;
+
+ NVIC_DisableIRQ(SDH0_IRQn);
+
+
+ /* Enable IP clock */
+ CLK->APBCLK0 |= CLK_APBCLK0_UART0CKEN_Msk | CLK_APBCLK0_TMR0CKEN_Msk | CLK_APBCLK0_TMR2CKEN_Msk;
+
+ /* Select UART clock source */
+ CLK->CLKSEL2 = (CLK->CLKSEL2 & (~CLK_CLKSEL2_UART0SEL_Msk)) | CLK_CLKSEL2_UART0SEL_HIRC;
+
+ /* Timer clock source */
+ CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_TMR0SEL_Msk)) | CLK_CLKSEL1_TMR0SEL_HIRC;
+ CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_TMR2SEL_Msk)) | CLK_CLKSEL1_TMR2SEL_HIRC;
+
+ /* Set multi-function pins for UART0 RXD and TXD */
+ SYS->GPA_MFPL = (SYS->GPA_MFPL & (~(UART0_RXD_PA6_Msk | UART0_TXD_PA7_Msk))) | UART0_RXD_PA6 | UART0_TXD_PA7;
+
+ /* Set UART 0 to Non-secure */
+ SCU_SET_PNSSET(UART0_Attr);
+
+ /* Set SAU */
+ SAU->RNR = 3;
+ SAU->RBAR = 0x50000000;
+ SAU->RLAR = (0x5FFFFFFF & SAU_RLAR_LADDR_Msk) | SAU_RLAR_ENABLE_Msk;
+
+#ifndef NU_DISABLE_TAMPER
+ CLK->APBCLK0 |= CLK_APBCLK0_TAMPERCKEN_Msk;
+
+ /* Reset tamper coreblock */
+ TAMPER_CORE_RESET();
+ TAMPER_CORE_RELEASE();
+
+ /* Enable voltage glitch detection clock source and select sampling rate */
+ TAMPER_ENABLE_HIRC48M();
+ TAMPER_VG_SAMPLE_SEL(TAMPER_VG_192M_SAMPLE);
+
+ /* Initialize a reference trim value according to the power level of the system */
+ TAMPER_VG_TRIM_INIT();
+
+ /* Enable voltage glitch positive/negative detection interrupt */
+ TAMPER_EnableInt(TAMPER_INTEN_VGPIEN_Msk | TAMPER_INTEN_VGNIEN_Msk);
+
+ /* Clear voltage glitch positive/negative interrupt flag */
+ TAMPER_CLR_INT_STATUS(TAMPER_INTSTS_VGPEVIF_Msk | TAMPER_INTSTS_VGNEVIF_Msk);
+
+ /* Enable over voltage detector and wait until stable */
+ SYS->OVDCTL = SYS_OVDCTL_OVDEN_Msk;
+ while(!(SYS->OVDCTL & SYS_OVDCTL_OVDSTB_Msk));
+
+ /* Initialize the trim value of under-shoot and over-shoot detection level */
+ TAMPER_TLVD_TRIM_INIT(TAMPER_LBSTRIM_TLVDSEL_0_90V);
+ TAMPER_TOVD_TRIM_INIT(TAMPER_LBSTRIM_TOVDSEL_1_40V);
+
+ /* Clear different voltage interrupt flag */
+ TAMPER_CLR_INT_STATUS(TAMPER_INTSTS_OVPOUTIF_Msk | TAMPER_INTSTS_BODIF_Msk);
+
+ /* Enable different voltage detection interrupt */
+ TAMPER_EnableInt(TAMPER_INTEN_OVPIEN_Msk | TAMPER_INTEN_BODIEN_Msk);
+
+ /* Enable to trigger chip reset */
+ TAMPER_ENABLE_CHIPRST();
+#endif
+#endif
+
+
SystemCoreClock = SYSTEM_CLOCK;
diff --git a/platform/ext/target/nuvoton/m2354/partition/flash_layout.h b/platform/ext/target/nuvoton/m2354/partition/flash_layout.h
index bc6eb46..399c489 100644
--- a/platform/ext/target/nuvoton/m2354/partition/flash_layout.h
+++ b/platform/ext/target/nuvoton/m2354/partition/flash_layout.h
@@ -94,7 +94,7 @@
/* Protected Storage (PS) Service definitions */
#define FLASH_PS_AREA_OFFSET (0x10000)
-#define FLASH_PS_AREA_SIZE (0x7000)
+#define FLASH_PS_AREA_SIZE (0x8000)
/* Internal Trusted Storage (ITS) Service definitions */
#define FLASH_ITS_AREA_OFFSET (FLASH_PS_AREA_OFFSET + \
diff --git a/platform/ext/target/nuvoton/m2354/target_cfg.c b/platform/ext/target/nuvoton/m2354/target_cfg.c
index e0504a7..9030477 100644
--- a/platform/ext/target/nuvoton/m2354/target_cfg.c
+++ b/platform/ext/target/nuvoton/m2354/target_cfg.c
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2018-2021 Arm Limited
- * Copyright (c) 2020 Nuvoton Technology Corp. All rights reserved.
+ * Copyright (c) 2017-2021 Arm Limited
+ * Copyright (c) 2021 Nuvoton Technology Corp. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,16 +15,17 @@
* limitations under the License.
*/
-#include "partition_M2354.h"
#include "cmsis.h"
#include "target_cfg.h"
#include "Driver_MPC.h"
-#include "platform_description.h"
-#include "device_definition.h"
#include "region_defs.h"
#include "tfm_plat_defs.h"
#include "region.h"
-#include "tfm_secure_api.h"
+#include "NuMicro.h"
+
+#ifdef PSA_API_TEST_IPC
+#define PSA_FF_TEST_SECURE_UART2
+#endif
#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
@@ -48,11 +49,8 @@
(uint32_t)®ION_NAME(Load$$LR$$, LR_NS_PARTITION, $$Base) +
NS_PARTITION_SIZE - 1,
- .veneer_base =
- (uint32_t)®ION_NAME(Image$$, ER_VENEER, $$Base),
-
- .veneer_limit =
- (uint32_t)®ION_NAME(Image$$, VENEER_ALIGN, $$Limit),
+ .veneer_base = (uint32_t)®ION_NAME(Image$$, ER_VENEER, $$Base),
+ .veneer_limit = (uint32_t)®ION_NAME(Image$$, VENEER_ALIGN, $$Limit),
#ifdef BL2
.secondary_partition_base =
@@ -96,8 +94,8 @@
NIDEN_SEL_STATUS | DBGEN_SEL_STATUS)
struct platform_data_t tfm_peripheral_std_uart = {
- UART0_BASE + NS_OFFSET,
- UART0_BASE + NS_OFFSET + 0xFFF,
+ UART0_BASE+NS_OFFSET,
+ UART0_BASE+NS_OFFSET+0xFFF,
PPC_SP_DO_NOT_CONFIGURE,
-1
};
@@ -116,12 +114,66 @@
-1
};
+#ifdef PSA_API_TEST_IPC
+
+/* Below data structure are only used for PSA FF tests, and this pattern is
+ * definitely not to be followed for real life use cases, as it can break
+ * security.
+ */
+
+struct platform_data_t
+ tfm_peripheral_FF_TEST_UART_REGION = {
+ UART2_BASE_S,
+ UART2_BASE_S + 0xFFF,
+ PPC_SP_APB_PPC_EXP2,
+ CMSDK_UART2_APB_PPC_POS
+};
+
+struct platform_data_t
+ tfm_peripheral_FF_TEST_WATCHDOG_REGION = {
+ APB_WATCHDOG_BASE_S,
+ APB_WATCHDOG_BASE_S + 0xFFF,
+ PPC_SP_DO_NOT_CONFIGURE,
+ -1
+};
+
+#define FF_TEST_NVMEM_REGION_START 0x102FFC00
+#define FF_TEST_NVMEM_REGION_END 0x102FFFFF
+#define FF_TEST_SERVER_PARTITION_MMIO_START 0x3801FC00
+#define FF_TEST_SERVER_PARTITION_MMIO_END 0x3801FD00
+#define FF_TEST_DRIVER_PARTITION_MMIO_START 0x3801FE00
+#define FF_TEST_DRIVER_PARTITION_MMIO_END 0x3801FF00
+
+struct platform_data_t
+ tfm_peripheral_FF_TEST_NVMEM_REGION = {
+ FF_TEST_NVMEM_REGION_START,
+ FF_TEST_NVMEM_REGION_END,
+ PPC_SP_DO_NOT_CONFIGURE,
+ -1
+};
+
+struct platform_data_t
+ tfm_peripheral_FF_TEST_SERVER_PARTITION_MMIO = {
+ FF_TEST_SERVER_PARTITION_MMIO_START,
+ FF_TEST_SERVER_PARTITION_MMIO_END,
+ PPC_SP_DO_NOT_CONFIGURE,
+ -1
+};
+
+struct platform_data_t
+ tfm_peripheral_FF_TEST_DRIVER_PARTITION_MMIO = {
+ FF_TEST_DRIVER_PARTITION_MMIO_START,
+ FF_TEST_DRIVER_PARTITION_MMIO_END,
+ PPC_SP_DO_NOT_CONFIGURE,
+ -1
+};
+#endif
+
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.
- */
+ /* Explicitly set secure fault priority to the highest */
+ NVIC_SetPriority(SCU_IRQn, 0);
+
return TFM_PLAT_ERR_SUCCESS;
}
@@ -132,7 +184,7 @@
/* Clear SCB_AIRCR_VECTKEY value */
reg_value &= ~(uint32_t)(SCB_AIRCR_VECTKEY_Msk);
- /* Enable system reset request for the secure world only */
+ /* Enable system reset request only to the secure world */
reg_value |= (uint32_t)(SCB_AIRCR_WRITE_MASK | SCB_AIRCR_SYSRESETREQS_Msk);
SCB->AIRCR = reg_value;
@@ -142,13 +194,37 @@
enum tfm_plat_err_t init_debug(void)
{
- /* Set UART0 to NS for debug message */
- SCU_SET_PNSSET(UART0_Attr);
+
+#if defined(DAUTH_NONE)
+
+ /* Disable secure and non-secure debug */
+ DPM->NSCTL = 0x5a000000 | DPM_NSCTL_DBGDIS_Msk;
+
+#elif defined(DAUTH_NS_ONLY)
+
+ /* Disable secure debug */
+ DPM->CTL = 0x5a000000 | DPM_CTL_DBGDIS_Msk;
+
+#elif defined(DAUTH_FULL)
+ /* By default, all debug is available */
+ /* If secure or all debug is disable, it may need erase whole chip to alow debug again. */
+#else
+
+#if !defined(DAUTH_CHIP_DEFAULT)
+#error "No debug authentication setting is provided."
+#endif
+
+ /* Set all the debug enable selector bits to 0 */
+
+
+ /* 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)
{
@@ -157,10 +233,11 @@
NVIC->ITNS[i] = 0xFFFFFFFF;
}
+ /* Make sure that SCU are targeted to S state */
+ NVIC_ClearTargetState(SCU_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
@@ -170,6 +247,11 @@
/*----------------- NVIC interrupt enabling for S peripherals ----------------*/
enum tfm_plat_err_t nvic_interrupt_enable(void)
{
+ NVIC_EnableIRQ(SCU_IRQn);
+
+#ifdef PSA_FF_TEST_SECURE_UART2
+# error "Not support PSA_FF_TEST_SECURE_UART2 in M2354"
+#endif
return TFM_PLAT_ERR_SUCCESS;
}
@@ -197,14 +279,11 @@
(uint32_t)®ION_NAME(Image$$, ER_VENEER, $$Base),
(uint32_t)®ION_NAME(Image$$, VENEER_ALIGN, $$Limit),
true,
- },
- {
- (PERIPH_BASE + NS_OFFSET),
- (PERIPH_BASE + NS_OFFSET + 0x10000000 - 1),
- false,
}
};
+#define NR_SAU_INIT_STEP 3
+
void sau_and_idau_cfg(void)
{
uint32_t i;
@@ -212,19 +291,24 @@
/* Enables SAU */
TZ_SAU_Enable();
- for(i = 0; i < ARRAY_SIZE(sau_cfg); i++) {
+ 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;
+ (sau_cfg[i].nsc ? SAU_RLAR_NSC_Msk : 0U) |
+ SAU_RLAR_ENABLE_Msk;
}
}
/*------------------- Memory configuration functions -------------------------*/
+#ifdef BL2
+#define NR_MPC_INIT_STEP 7
+#else
+#define NR_MPC_INIT_STEP 6
+#endif
-enum tfm_plat_err_t mpc_init_cfg(void)
+int32_t mpc_init_cfg(void)
{
int32_t i;
@@ -333,22 +417,27 @@
/* Set TIMER2 for Non-secure */
SCU_SET_PNSSET(TMR23_Attr);
- return TFM_PLAT_ERR_SUCCESS;
-}
+ /* Add barriers to assure the MPC configuration is done before continue
+ * the execution.
+ */
+ __DSB();
+ __ISB();
+ return ARM_DRIVER_OK;
+}
/*---------------------- PPC configuration functions -------------------------*/
+#define NR_PPC_INIT_STEP 4
-enum tfm_plat_err_t ppc_init_cfg(void)
-{
- return TFM_PLAT_ERR_SUCCESS;
-}
-
-void ppc_configure_to_secure(enum ppc_bank_e bank, uint32_t pos)
+void ppc_init_cfg(void)
{
}
-void ppc_configure_to_non_secure(enum ppc_bank_e bank, uint32_t pos)
+void ppc_configure_to_non_secure(enum ppc_bank_e bank, uint16_t pos)
+{
+}
+
+void ppc_configure_to_secure(enum ppc_bank_e bank, uint16_t pos)
{
}