mirror of https://github.com/ARMmbed/mbed-os.git
579 lines
18 KiB
C
579 lines
18 KiB
C
/**************************************************************************//**
|
|
* @file system_M2351.c
|
|
* @version V2.00
|
|
* @brief System Setting Source File
|
|
*
|
|
* @note
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Copyright (C) 2016 Nuvoton Technology Corp. All rights reserved.
|
|
*
|
|
******************************************************************************/
|
|
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) /* ARM Compiler 6 */
|
|
#include <arm_cmse.h>
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include "NuMicro.h"
|
|
|
|
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
|
|
#include "partition_M2351.h"
|
|
#include "platform/mbed_error.h"
|
|
#endif
|
|
|
|
#if defined(__ICCARM__)
|
|
extern void *__vector_table; /* see startup file */
|
|
#else
|
|
extern void *__vector_handlers; /* see startup file */
|
|
#endif
|
|
|
|
|
|
/*----------------------------------------------------------------------------
|
|
Clock Variable definitions
|
|
*----------------------------------------------------------------------------*/
|
|
uint32_t SystemCoreClock = __HSI; /*!< System Clock Frequency (Core Clock) */
|
|
uint32_t CyclesPerUs = (__HSI / 1000000UL);/*!< Cycles per micro second */
|
|
uint32_t PllClock = __HSI; /*!< PLL Output Clock Frequency */
|
|
const uint32_t gau32ClkSrcTbl[] = {__HXT, __LXT, 0UL, __LIRC, 0UL, __HIRC48, 0UL, __HIRC};
|
|
|
|
|
|
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
|
|
|
|
#if TFM_LVL > 0
|
|
|
|
#include "tfm_secure_api.h"
|
|
#include "platform/mbed_assert.h"
|
|
|
|
/* The configuration of TDB internal storage area defined in "partition_M2351_mem.h"
|
|
* must match "tdb_internal/mbed_lib.json", so it can pass to linker files for
|
|
* memory layout check. */
|
|
static_assert(NU_TDB_INTERNAL_STORAGE_START == MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_BASE_ADDRESS,
|
|
"NU_TDB_INTERNAL_STORAGE_START must be equal to MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_BASE_ADDRESS");
|
|
static_assert(NU_TDB_INTERNAL_STORAGE_SIZE == MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_SIZE,
|
|
"NU_TDB_INTERNAL_STORAGE_SIZE must be equal to MBED_CONF_STORAGE_TDB_INTERNAL_INTERNAL_SIZE");
|
|
|
|
#endif
|
|
|
|
/**
|
|
* @brief Setup Non-secure boundary
|
|
*
|
|
* @param None
|
|
*
|
|
* @return None
|
|
*
|
|
* @details This function is used to set Non-secure boundary according to
|
|
* the configuration of partition header file
|
|
*/
|
|
void FMC_NSBA_Setup(void)
|
|
{
|
|
/* Skip NSBA Setupt according config */
|
|
if(FMC_INIT_NSBA == 0)
|
|
return;
|
|
|
|
/* Check if NSBA value with current active NSBA */
|
|
if(SCU->FNSADDR != FMC_SECURE_ROM_SIZE)
|
|
{
|
|
/* Unlock Protected Register */
|
|
SYS_UnlockReg();
|
|
|
|
/* Enable ISP and config update */
|
|
FMC->ISPCTL = FMC_ISPCTL_ISPEN_Msk | FMC_ISPCTL_CFGUEN_Msk;
|
|
|
|
/* Config Base of NSBA */
|
|
FMC->ISPADDR = FMC_NSCBA_BASE ;
|
|
|
|
/* Read Non-secure base address config */
|
|
FMC->ISPCMD = FMC_ISPCMD_READ;
|
|
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
|
|
while(FMC->ISPTRG);
|
|
|
|
/* Setting NSBA when it is empty */
|
|
if(FMC->ISPDAT != 0xfffffffful)
|
|
{
|
|
/* Erase old setting */
|
|
FMC->ISPCMD = FMC_ISPCMD_PAGE_ERASE;
|
|
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
|
|
while(FMC->ISPTRG);
|
|
}
|
|
|
|
/* Set new base */
|
|
FMC->ISPDAT = FMC_SECURE_ROM_SIZE;
|
|
FMC->ISPCMD = FMC_ISPCMD_PROGRAM;
|
|
FMC->ISPTRG = FMC_ISPTRG_ISPGO_Msk;
|
|
while(FMC->ISPTRG);
|
|
|
|
/* Force Chip Reset to valid new setting */
|
|
SYS->IPRST0 = SYS_IPRST0_CHIPRST_Msk;
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
\brief Setup SCU Configuration Unit
|
|
\details
|
|
|
|
*/
|
|
void SCU_Setup(void)
|
|
{
|
|
int32_t i;
|
|
|
|
SCU->PNSSET[0] = SCU_INIT_PNSSET0_VAL;
|
|
SCU->PNSSET[1] = SCU_INIT_PNSSET1_VAL;
|
|
SCU->PNSSET[2] = SCU_INIT_PNSSET2_VAL;
|
|
SCU->PNSSET[3] = SCU_INIT_PNSSET3_VAL;
|
|
SCU->PNSSET[4] = SCU_INIT_PNSSET4_VAL;
|
|
SCU->PNSSET[5] = SCU_INIT_PNSSET5_VAL;
|
|
SCU->PNSSET[6] = SCU_INIT_PNSSET6_VAL;
|
|
|
|
|
|
SCU->IONSSET = SCU_INIT_IONSSET_VAL;
|
|
|
|
/* Set Non-secure SRAM */
|
|
for(i = 11; i >= SCU_SECURE_SRAM_SIZE / 8192; i--)
|
|
{
|
|
SCU->SRAMNSSET |= (1U << i);
|
|
}
|
|
}
|
|
|
|
void TZ_NVIC_Setup(void)
|
|
{
|
|
/* Set interrupt to non-secure according to PNNSET settings */
|
|
if(SCU_INIT_PNSSET0_VAL & BIT9 ) NVIC->ITNS[1] |= BIT22; /* Int of USBH_INT */
|
|
if(SCU_INIT_PNSSET0_VAL & BIT13) NVIC->ITNS[2] |= BIT0 ; /* Int of SDHOST0_INT */
|
|
if(SCU_INIT_PNSSET0_VAL & BIT24) NVIC->ITNS[3] |= BIT2 ; /* Int of PDMA1_INT */
|
|
if(SCU_INIT_PNSSET1_VAL & BIT18) NVIC->ITNS[2] |= BIT7 ; /* Int of CRYPTO */
|
|
if(SCU_INIT_PNSSET2_VAL & BIT2 ) NVIC->ITNS[3] |= BIT15; /* Int of EWDT_INT */
|
|
if(SCU_INIT_PNSSET2_VAL & BIT2 ) NVIC->ITNS[3] |= BIT16; /* Int of EWWDT_INT */
|
|
if(SCU_INIT_PNSSET2_VAL & BIT3 ) NVIC->ITNS[1] |= BIT10; /* Int of EADC0_INT */
|
|
if(SCU_INIT_PNSSET2_VAL & BIT3 ) NVIC->ITNS[1] |= BIT11; /* Int of EADC1_INT */
|
|
if(SCU_INIT_PNSSET2_VAL & BIT3 ) NVIC->ITNS[1] |= BIT14; /* Int of EADC2_INT */
|
|
if(SCU_INIT_PNSSET2_VAL & BIT3 ) NVIC->ITNS[1] |= BIT15; /* Int of EADC3_INT */
|
|
if(SCU_INIT_PNSSET2_VAL & BIT5 ) NVIC->ITNS[1] |= BIT12; /* Int of ACMP01_INT */
|
|
if(SCU_INIT_PNSSET2_VAL & BIT7 ) NVIC->ITNS[1] |= BIT9 ; /* Int of DAC_INT */
|
|
if(SCU_INIT_PNSSET2_VAL & BIT8 ) NVIC->ITNS[2] |= BIT4 ; /* Int of I2S0_INT */
|
|
if(SCU_INIT_PNSSET2_VAL & BIT13) NVIC->ITNS[1] |= BIT23; /* Int of USBOTG_INT */
|
|
if(SCU_INIT_PNSSET2_VAL & BIT17) NVIC->ITNS[1] |= BIT2 ; /* Int of TMR2_INT */
|
|
if(SCU_INIT_PNSSET2_VAL & BIT17) NVIC->ITNS[1] |= BIT3 ; /* Int of TMR3_INT */
|
|
if(SCU_INIT_PNSSET2_VAL & BIT24) NVIC->ITNS[0] |= BIT25; /* Int of EPWM0_P0_INT */
|
|
if(SCU_INIT_PNSSET2_VAL & BIT24) NVIC->ITNS[0] |= BIT26; /* Int of EPWM0_P1_INT */
|
|
if(SCU_INIT_PNSSET2_VAL & BIT24) NVIC->ITNS[0] |= BIT27; /* Int of EPWM0_P2_INT */
|
|
if(SCU_INIT_PNSSET2_VAL & BIT25) NVIC->ITNS[0] |= BIT29; /* Int of EPWM1_P0_INT */
|
|
if(SCU_INIT_PNSSET2_VAL & BIT25) NVIC->ITNS[0] |= BIT30; /* Int of EPWM1_P1_INT */
|
|
if(SCU_INIT_PNSSET2_VAL & BIT25) NVIC->ITNS[0] |= BIT31; /* Int of EPWM1_P2_INT */
|
|
if(SCU_INIT_PNSSET2_VAL & BIT26) NVIC->ITNS[2] |= BIT14; /* Int of BPWM0_INT */
|
|
if(SCU_INIT_PNSSET2_VAL & BIT27) NVIC->ITNS[2] |= BIT15; /* Int of BPWM1_INT */
|
|
if(SCU_INIT_PNSSET3_VAL & BIT0 ) NVIC->ITNS[0] |= BIT22; /* Int of QSPI0_INT */
|
|
if(SCU_INIT_PNSSET3_VAL & BIT1 ) NVIC->ITNS[0] |= BIT23; /* Int of SPI0_INT */
|
|
if(SCU_INIT_PNSSET3_VAL & BIT2 ) NVIC->ITNS[1] |= BIT19; /* Int of SPI1_INT */
|
|
if(SCU_INIT_PNSSET3_VAL & BIT3 ) NVIC->ITNS[1] |= BIT20; /* Int of SPI2_INT */
|
|
if(SCU_INIT_PNSSET3_VAL & BIT4 ) NVIC->ITNS[1] |= BIT30; /* Int of SPI3_INT */
|
|
if(SCU_INIT_PNSSET3_VAL & BIT16) NVIC->ITNS[1] |= BIT4 ; /* Int of UART0_INT */
|
|
if(SCU_INIT_PNSSET3_VAL & BIT17) NVIC->ITNS[1] |= BIT5 ; /* Int of UART1_INT */
|
|
if(SCU_INIT_PNSSET3_VAL & BIT18) NVIC->ITNS[1] |= BIT16; /* Int of UART2_INT */
|
|
if(SCU_INIT_PNSSET3_VAL & BIT19) NVIC->ITNS[1] |= BIT17; /* Int of UART3_INT */
|
|
if(SCU_INIT_PNSSET3_VAL & BIT20) NVIC->ITNS[2] |= BIT10; /* Int of UART4_INT */
|
|
if(SCU_INIT_PNSSET3_VAL & BIT21) NVIC->ITNS[2] |= BIT11; /* Int of UART5_INT */
|
|
if(SCU_INIT_PNSSET4_VAL & BIT0 ) NVIC->ITNS[1] |= BIT6 ; /* Int of I2C0_INT */
|
|
if(SCU_INIT_PNSSET4_VAL & BIT1 ) NVIC->ITNS[1] |= BIT7 ; /* Int of I2C1_INT */
|
|
if(SCU_INIT_PNSSET4_VAL & BIT2 ) NVIC->ITNS[2] |= BIT18; /* Int of I2C2_INT */
|
|
if(SCU_INIT_PNSSET4_VAL & BIT16) NVIC->ITNS[1] |= BIT26; /* Int of SC0_INT */
|
|
if(SCU_INIT_PNSSET4_VAL & BIT17) NVIC->ITNS[1] |= BIT27; /* Int of SC1_INT */
|
|
if(SCU_INIT_PNSSET4_VAL & BIT18) NVIC->ITNS[1] |= BIT28; /* Int of SC2_INT */
|
|
if(SCU_INIT_PNSSET5_VAL & BIT0 ) NVIC->ITNS[1] |= BIT24; /* Int of CAN0_INT */
|
|
if(SCU_INIT_PNSSET5_VAL & BIT16) NVIC->ITNS[2] |= BIT20; /* Int of QEI0_INT */
|
|
if(SCU_INIT_PNSSET5_VAL & BIT17) NVIC->ITNS[2] |= BIT21; /* Int of QEI1_INT */
|
|
if(SCU_INIT_PNSSET5_VAL & BIT20) NVIC->ITNS[2] |= BIT22; /* Int of ECAP0_INT */
|
|
if(SCU_INIT_PNSSET5_VAL & BIT21) NVIC->ITNS[2] |= BIT23; /* Int of ECAP1_INT */
|
|
if(SCU_INIT_PNSSET5_VAL & BIT25) NVIC->ITNS[3] |= BIT5 ; /* Int of TRNG_INT */
|
|
if(SCU_INIT_PNSSET5_VAL & BIT27) NVIC->ITNS[3] |= BIT4 ; /* Int of LCD_INT */
|
|
if(SCU_INIT_PNSSET5_VAL & BIT29) NVIC->ITNS[3] |= BIT14; /* Int of TAMPER_INT */
|
|
if(SCU_INIT_PNSSET6_VAL & BIT0 ) NVIC->ITNS[1] |= BIT21; /* Int of USBD_INT */
|
|
if(SCU_INIT_PNSSET6_VAL & BIT16) NVIC->ITNS[2] |= BIT12; /* Int of USCI0_INT */
|
|
if(SCU_INIT_PNSSET6_VAL & BIT17) NVIC->ITNS[2] |= BIT13; /* Int of USCI1_INT */
|
|
if(SCU_INIT_IONSSET_VAL & BIT0 ) NVIC->ITNS[0] |= BIT16; /* Int of PA */
|
|
if(SCU_INIT_IONSSET_VAL & BIT1 ) NVIC->ITNS[0] |= BIT17; /* Int of PB */
|
|
if(SCU_INIT_IONSSET_VAL & BIT2 ) NVIC->ITNS[0] |= BIT18; /* Int of PC */
|
|
if(SCU_INIT_IONSSET_VAL & BIT3 ) NVIC->ITNS[0] |= BIT19; /* Int of PD */
|
|
if(SCU_INIT_IONSSET_VAL & BIT4 ) NVIC->ITNS[0] |= BIT20; /* Int of PE */
|
|
if(SCU_INIT_IONSSET_VAL & BIT5 ) NVIC->ITNS[0] |= BIT21; /* Int of PF */
|
|
if(SCU_INIT_IONSSET_VAL & BIT6 ) NVIC->ITNS[2] |= BIT8 ; /* Int of PG */
|
|
if(SCU_INIT_IONSSET_VAL & BIT7 ) NVIC->ITNS[2] |= BIT24; /* Int of PH */
|
|
|
|
|
|
/* Enable SCU Int status */
|
|
SCU->SVIOIEN = -1;
|
|
NVIC_EnableIRQ(SCU_IRQn);
|
|
|
|
}
|
|
|
|
#if defined( __ICCARM__ )
|
|
__WEAK
|
|
#else
|
|
__attribute__((weak))
|
|
#endif
|
|
|
|
void SCU_IRQHandler(void)
|
|
{
|
|
char const *master[] = {"CPU", 0, 0, "PDMA0", "SDH0", "CRPT", "USBH", 0,0,0,0,"PDMA1"};
|
|
char const *ipname[] = {"APB0","APB1",0,0,"GPIO","EBI","USBH","CRC","SDH0",0,"PDMA0","PDMA1"
|
|
,"SRAM0","SRAM1","FMC","FLASH","SCU","SYS","CRPT"};
|
|
const uint8_t info[] = {0x34,0x3C,0,0, 0x44,0x4C,0x54,0x5C,0x64,0,0x74,0x7C,0x84,0x8C,0x94,0x9C,0xA4,0xAC,0xB4};
|
|
|
|
uint32_t u32Reg, u32Addr;
|
|
int32_t i;
|
|
|
|
/* TrustZone access policy */
|
|
u32Reg = SCU->SVINTSTS;
|
|
if(u32Reg)
|
|
{
|
|
|
|
/* Get violation address and source */
|
|
for(i=0;i< sizeof(ipname);i++)
|
|
{
|
|
if(u32Reg & (1 << i))
|
|
{
|
|
u32Addr = M32(SCU_BASE+info[i]+4);
|
|
/* We cannot call printf(...) from interrupt context. Change to error(...) instead. */
|
|
error(" %s(0x%08x) Alarm! illegal access by %s\n",ipname[i], u32Addr,master[M32(SCU_BASE+info[i])]);
|
|
SCU->SVINTSTS = (1 << i);
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
\brief Setup a Nonsecure callable Region
|
|
\details The base and limit of Nonsecure callable region is dependent on the
|
|
application code size.
|
|
*/
|
|
void NSC_Init(int32_t i32Region)
|
|
{
|
|
uint32_t u32Base, u32Limit;
|
|
|
|
u32Base = NU_TZ_NSC_REGION_START;
|
|
u32Limit = (NU_TZ_NSC_REGION_START + NU_TZ_NSC_REGION_SIZE - 1);
|
|
|
|
SAU->RNR = (i32Region & SAU_RNR_REGION_Msk);
|
|
SAU->RBAR = (u32Base & SAU_RBAR_BADDR_Msk);
|
|
SAU->RLAR = (u32Limit & SAU_RLAR_LADDR_Msk) |
|
|
((1ul << SAU_RLAR_NSC_Pos) & SAU_RLAR_NSC_Msk) | 1ul;
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
\brief Setup a SAU Region
|
|
\details Writes the region information contained in SAU_Region to the
|
|
registers SAU_RNR, SAU_RBAR, and SAU_RLAR
|
|
*/
|
|
void TZ_SAU_Setup(void)
|
|
{
|
|
|
|
#if defined (__SAU_PRESENT) && (__SAU_PRESENT == 1U)
|
|
|
|
#if defined (SAU_INIT_REGION0) && (SAU_INIT_REGION0 == 1U)
|
|
#if TFM_LVL == 0
|
|
SAU_INIT_REGION(0);
|
|
#else
|
|
#error("TFM doesn't support SAU_INIT_REGION0")
|
|
#endif
|
|
#endif
|
|
|
|
#if defined (SAU_INIT_REGION1) && (SAU_INIT_REGION1 == 1U)
|
|
#if TFM_LVL == 0
|
|
SAU_INIT_REGION(1);
|
|
#else
|
|
#error("TFM doesn't support SAU_INIT_REGION1")
|
|
#endif
|
|
#endif
|
|
|
|
#if defined (SAU_INIT_REGION2) && (SAU_INIT_REGION2 == 1U)
|
|
#if TFM_LVL == 0
|
|
SAU_INIT_REGION(2);
|
|
#else
|
|
#error("TFM doesn't support SAU_INIT_REGION2")
|
|
#endif
|
|
#endif
|
|
|
|
#if defined (SAU_INIT_REGION3) && (SAU_INIT_REGION3 == 1U)
|
|
#if TFM_LVL == 0
|
|
SAU_INIT_REGION(3);
|
|
#else
|
|
SAU_INIT_REGION(3, TFM_NS_REGION_VENEER);
|
|
#endif
|
|
#else
|
|
/* To align with BSP code, we add NSC_Init(...) here. Actually, we can configure
|
|
* NSC region through SAU_INIT_REGION3. */
|
|
#if TFM_LVL == 0
|
|
NSC_Init(3);
|
|
#else
|
|
NSC_Init(TFM_NS_REGION_VENEER);
|
|
#endif
|
|
#endif
|
|
|
|
#if defined (SAU_INIT_REGION4) && (SAU_INIT_REGION4 == 1U)
|
|
#if TFM_LVL == 0
|
|
SAU_INIT_REGION(4);
|
|
#else
|
|
SAU_INIT_REGION(4, TFM_NS_REGION_CODE);
|
|
#endif
|
|
#endif
|
|
|
|
#if defined (SAU_INIT_REGION5) && (SAU_INIT_REGION5 == 1U)
|
|
#if TFM_LVL == 0
|
|
SAU_INIT_REGION(5);
|
|
#else
|
|
#warning("TFM doesn't support SAU_INIT_REGION5")
|
|
#endif
|
|
#endif
|
|
|
|
#if defined (SAU_INIT_REGION6) && (SAU_INIT_REGION6 == 1U)
|
|
#if TFM_LVL == 0
|
|
SAU_INIT_REGION(6);
|
|
#else
|
|
SAU_INIT_REGION(6, TFM_NS_REGION_DATA);
|
|
#endif
|
|
#endif
|
|
|
|
#if defined (SAU_INIT_REGION7) && (SAU_INIT_REGION7 == 1U)
|
|
#if TFM_LVL == 0
|
|
SAU_INIT_REGION(7);
|
|
#else
|
|
SAU_INIT_REGION(7, TFM_NS_REGION_PERIPH_1);
|
|
#endif
|
|
#endif
|
|
|
|
/* repeat this for all possible SAU regions */
|
|
|
|
|
|
#if defined (SAU_INIT_CTRL) && (SAU_INIT_CTRL == 1U)
|
|
SAU->CTRL = ((SAU_INIT_CTRL_ENABLE << SAU_CTRL_ENABLE_Pos) & SAU_CTRL_ENABLE_Msk) |
|
|
((SAU_INIT_CTRL_ALLNS << SAU_CTRL_ALLNS_Pos) & SAU_CTRL_ALLNS_Msk) ;
|
|
#endif
|
|
|
|
#endif /* defined (__SAU_PRESENT) && (__SAU_PRESENT == 1U) */
|
|
}
|
|
|
|
void SCB_Setup(void)
|
|
{
|
|
#if defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U)
|
|
SCB->SCR = (SCB->SCR & ~(SCB_SCR_SLEEPDEEPS_Msk)) |
|
|
((SCB_CSR_DEEPSLEEPS_VAL << SCB_SCR_SLEEPDEEPS_Pos) & SCB_SCR_SLEEPDEEPS_Msk);
|
|
|
|
SCB->AIRCR = (0x05FA << 16) |
|
|
((SCB_AIRCR_SYSRESETREQS_VAL << SCB_AIRCR_SYSRESETREQS_Pos) & SCB_AIRCR_SYSRESETREQS_Msk) |
|
|
((SCB_AIRCR_BFHFNMINS_VAL << SCB_AIRCR_BFHFNMINS_Pos) & SCB_AIRCR_BFHFNMINS_Msk) |
|
|
((SCB_AIRCR_PRIS_VAL << SCB_AIRCR_PRIS_Pos) & SCB_AIRCR_PRIS_Msk);
|
|
|
|
|
|
|
|
#endif /* defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) */
|
|
|
|
#if defined (SCB_ICSR_INIT) && (SCB_ICSR_INIT == 1U)
|
|
SCB->ICSR = (SCB->ICSR & ~(SCB_ICSR_STTNS_Msk)) |
|
|
((SCB_ICSR_STTNS_VAL << SCB_ICSR_STTNS_Pos) & SCB_ICSR_STTNS_Msk);
|
|
#endif /* defined (SCB_ICSR_INIT) && (SCB_ICSR_INIT == 1U) */
|
|
|
|
/* repeat this for all possible ITNS elements */
|
|
}
|
|
#else
|
|
void SCU_IRQHandler(void)
|
|
{
|
|
while(1);
|
|
}
|
|
#endif
|
|
|
|
|
|
/**
|
|
* @brief Update the Variable SystemCoreClock
|
|
*
|
|
* @param None
|
|
*
|
|
* @return None
|
|
*
|
|
* @details This function is used to update the variable SystemCoreClock
|
|
* and must be called whenever the core clock is changed.
|
|
*/
|
|
void SystemCoreClockUpdate(void)
|
|
{
|
|
/* Update PLL Clock */
|
|
PllClock = CLK_GetPLLClockFreq();
|
|
|
|
/* Update System Core Clock */
|
|
SystemCoreClock = CLK_GetCPUFreq();
|
|
|
|
/* Update Cycles per micro second */
|
|
CyclesPerUs = (SystemCoreClock + 500000UL) / 1000000UL;
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* @brief System Initialization
|
|
*
|
|
* @param None
|
|
*
|
|
* @return None
|
|
*
|
|
* @details The necessary initialization of system. Global variables are forbidden here.
|
|
*/
|
|
void SystemInit(void)
|
|
{
|
|
|
|
#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U)
|
|
#if defined(__ICCARM__)
|
|
SCB->VTOR = (uint32_t) &__vector_table;
|
|
#else
|
|
SCB->VTOR = (uint32_t) &__vector_handlers;
|
|
#endif
|
|
#endif
|
|
|
|
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
|
|
#if TFM_LVL == 0
|
|
TZ_SAU_Setup();
|
|
SCB_Setup();
|
|
TZ_NVIC_Setup();
|
|
SCU_Setup();
|
|
FMC_NSBA_Setup();
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef INIT_SYSCLK_AT_BOOTING
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
#if USE_ASSERT
|
|
|
|
/**
|
|
* @brief Assert Error Message
|
|
*
|
|
* @param[in] file the source file name
|
|
* @param[in] line line number
|
|
*
|
|
* @return None
|
|
*
|
|
* @details The function prints the source file name and line number where
|
|
* the ASSERT_PARAM() error occurs, and then stops in an infinite loop.
|
|
*/
|
|
void AssertError(uint8_t * file, uint32_t line)
|
|
{
|
|
|
|
printf("[%s] line %d : wrong parameters.\r\n", file, line);
|
|
|
|
/* Infinite loop */
|
|
while(1) ;
|
|
}
|
|
#endif
|
|
|
|
|
|
#if (defined(__ICCARM__) && (__VER__ >= 7080000) && (__VER__ < 8020000))
|
|
|
|
#if (__ARM_FEATURE_CMSE == 3U)
|
|
/**
|
|
\brief Get Process Stack Pointer (non-secure)
|
|
\details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state.
|
|
\return PSP Register value
|
|
*/
|
|
uint32_t __TZ_get_PSP_NS(void)
|
|
{
|
|
register uint32_t result;
|
|
|
|
__ASM volatile("MRS %0, psp_ns" : "=r"(result));
|
|
return(result);
|
|
}
|
|
|
|
|
|
/**
|
|
\brief Set Process Stack Pointer (non-secure)
|
|
\details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state.
|
|
\param [in] topOfProcStack Process Stack Pointer value to set
|
|
*/
|
|
void __TZ_set_PSP_NS(uint32_t topOfProcStack)
|
|
{
|
|
__ASM volatile("MSR psp_ns, %0" : : "r"(topOfProcStack));
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
\brief Get Main Stack Pointer (non-secure)
|
|
\details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state.
|
|
\return MSP Register value
|
|
*/
|
|
int32_t __TZ_get_MSP_NS(void)
|
|
{
|
|
register uint32_t result;
|
|
|
|
__ASM volatile("MRS %0, msp_ns" : "=r"(result));
|
|
return(result);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
\brief Set Main Stack Pointer (non-secure)
|
|
\details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state.
|
|
\param [in] topOfMainStack Main Stack Pointer value to set
|
|
*/
|
|
void __TZ_set_MSP_NS(uint32_t topOfMainStack)
|
|
{
|
|
__ASM volatile("MSR msp_ns, %0" : : "r"(topOfMainStack));
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
\brief Get Priority Mask (non-secure)
|
|
\details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state.
|
|
\return Priority Mask value
|
|
*/
|
|
uint32_t __TZ_get_PRIMASK_NS(void)
|
|
{
|
|
uint32_t result;
|
|
|
|
__ASM volatile("MRS %0, primask_ns" : "=r"(result));
|
|
return(result);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
\brief Set Priority Mask (non-secure)
|
|
\details Assigns the given value to the non-secure Priority Mask Register when in secure state.
|
|
\param [in] priMask Priority Mask
|
|
*/
|
|
void __TZ_set_PRIMASK_NS(uint32_t priMask)
|
|
{
|
|
__ASM volatile("MSR primask_ns, %0" : : "r"(priMask) : "memory");
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
#endif
|
|
|
|
|
|
/* Return program counter for checking in secure/non-secure domain */
|
|
__attribute__((naked)) uint32_t __PC(void)
|
|
{
|
|
#if defined(__GNUC__)
|
|
__asm(".syntax unified \n");
|
|
#endif
|
|
|
|
__asm("mov r0, lr \n");
|
|
__asm("blx lr \n");
|
|
}
|