| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723 |
- /*-----------------------------------------------------------------------------
- * Name: CV_CoreFunc.c
- * Purpose: CMSIS CORE validation tests implementation
- *-----------------------------------------------------------------------------
- * Copyright (c) 2017 - 2023 Arm Limited. All rights reserved.
- *----------------------------------------------------------------------------*/
- #include "CV_Framework.h"
- #include "cmsis_cv.h"
- /*-----------------------------------------------------------------------------
- * Test implementation
- *----------------------------------------------------------------------------*/
- static volatile uint32_t irqTaken = 0U;
- #if defined(__CORTEX_M) && (__CORTEX_M > 0)
- static volatile uint32_t irqActive = 0U;
- #endif
- static void TC_CoreFunc_EnDisIRQIRQHandler(void) {
- ++irqTaken;
- #if defined(__CORTEX_M) && (__CORTEX_M > 0)
- irqActive = NVIC_GetActive(Interrupt0_IRQn);
- #endif
- }
- static volatile uint32_t irqIPSR = 0U;
- static volatile uint32_t irqXPSR = 0U;
- static void TC_CoreFunc_IPSR_IRQHandler(void) {
- irqIPSR = __get_IPSR();
- irqXPSR = __get_xPSR();
- }
- /*-----------------------------------------------------------------------------
- * Test cases
- *----------------------------------------------------------------------------*/
- /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
- /**
- \brief Test case: TC_CoreFunc_EnDisIRQ
- \details
- Check expected behavior of interrupt related control functions:
- - __disable_irq() and __enable_irq()
- - NVIC_EnableIRQ, NVIC_DisableIRQ, and NVIC_GetEnableIRQ
- - NVIC_SetPendingIRQ, NVIC_ClearPendingIRQ, and NVIC_GetPendingIRQ
- - NVIC_GetActive (not on Cortex-M0/M0+)
- */
- void TC_CoreFunc_EnDisIRQ (void)
- {
- // Globally disable all interrupt servicing
- __disable_irq();
- // Enable the interrupt
- NVIC_EnableIRQ(Interrupt0_IRQn);
- ASSERT_TRUE(NVIC_GetEnableIRQ(Interrupt0_IRQn) != 0U);
- // Clear its pending state
- NVIC_ClearPendingIRQ(Interrupt0_IRQn);
- ASSERT_TRUE(NVIC_GetPendingIRQ(Interrupt0_IRQn) == 0U);
- // Register test interrupt handler.
- TST_IRQHandler = TC_CoreFunc_EnDisIRQIRQHandler;
- irqTaken = 0U;
- #if defined(__CORTEX_M) && (__CORTEX_M > 0)
- irqActive = UINT32_MAX;
- #endif
- // Set the interrupt pending state
- NVIC_SetPendingIRQ(Interrupt0_IRQn);
- for(uint32_t i = 10U; i > 0U; --i) {__NOP();}
- // Interrupt is not taken
- ASSERT_TRUE(irqTaken == 0U);
- ASSERT_TRUE(NVIC_GetPendingIRQ(Interrupt0_IRQn) != 0U);
- #if defined(__CORTEX_M) && (__CORTEX_M > 0)
- ASSERT_TRUE(NVIC_GetActive(Interrupt0_IRQn) == 0U);
- #endif
- // Globally enable interrupt servicing
- __enable_irq();
- for(uint32_t i = 10U; i > 0U; --i) {__NOP();}
- // Interrupt was taken
- ASSERT_TRUE(irqTaken == 1U);
- #if defined(__CORTEX_M) && (__CORTEX_M > 0)
- ASSERT_TRUE(irqActive != 0U);
- ASSERT_TRUE(NVIC_GetActive(Interrupt0_IRQn) == 0U);
- #endif
- // Interrupt it not pending anymore.
- ASSERT_TRUE(NVIC_GetPendingIRQ(Interrupt0_IRQn) == 0U);
- // Disable interrupt
- NVIC_DisableIRQ(Interrupt0_IRQn);
- ASSERT_TRUE(NVIC_GetEnableIRQ(Interrupt0_IRQn) == 0U);
- // Set interrupt pending
- NVIC_SetPendingIRQ(Interrupt0_IRQn);
- for(uint32_t i = 10U; i > 0U; --i) {__NOP();}
- // Interrupt is not taken again
- ASSERT_TRUE(irqTaken == 1U);
- ASSERT_TRUE(NVIC_GetPendingIRQ(Interrupt0_IRQn) != 0U);
- // Clear interrupt pending
- NVIC_ClearPendingIRQ(Interrupt0_IRQn);
- for(uint32_t i = 10U; i > 0U; --i) {__NOP();}
- // Interrupt it not pending anymore.
- ASSERT_TRUE(NVIC_GetPendingIRQ(Interrupt0_IRQn) == 0U);
- // Globally disable interrupt servicing
- __disable_irq();
- }
- /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
- /**
- \brief Test case: TC_CoreFunc_IRQPrio
- \details
- Check expected behavior of interrupt priority control functions:
- - NVIC_SetPriority, NVIC_GetPriority
- */
- void TC_CoreFunc_IRQPrio (void)
- {
- /* Test Exception Priority */
- uint32_t orig = NVIC_GetPriority(SVCall_IRQn);
- NVIC_SetPriority(SVCall_IRQn, orig+1U);
- uint32_t prio = NVIC_GetPriority(SVCall_IRQn);
- ASSERT_TRUE(prio == orig+1U);
- NVIC_SetPriority(SVCall_IRQn, orig);
- /* Test Interrupt Priority */
- orig = NVIC_GetPriority(Interrupt0_IRQn);
- NVIC_SetPriority(Interrupt0_IRQn, orig+1U);
- prio = NVIC_GetPriority(Interrupt0_IRQn);
- ASSERT_TRUE(prio == orig+1U);
- NVIC_SetPriority(Interrupt0_IRQn, orig);
- }
- /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
- /** Helper function for TC_CoreFunc_EncDecIRQPrio
- \details
- The helper encodes and decodes the given priority configuration.
- \param[in] prigroup The PRIGROUP setting to be considered for encoding/decoding.
- \param[in] pre The preempt priority value.
- \param[in] sub The subpriority value.
- */
- static void TC_CoreFunc_EncDecIRQPrio_Step(uint32_t prigroup, uint32_t pre, uint32_t sub) {
- uint32_t prio = NVIC_EncodePriority(prigroup, pre, sub);
- uint32_t ret_pre = UINT32_MAX;
- uint32_t ret_sub = UINT32_MAX;
- NVIC_DecodePriority(prio, prigroup, &ret_pre, &ret_sub);
- ASSERT_TRUE(ret_pre == pre);
- ASSERT_TRUE(ret_sub == sub);
- }
- /**
- \brief Test case: TC_CoreFunc_EncDecIRQPrio
- \details
- Check expected behavior of interrupt priority encoding/decoding functions:
- - NVIC_EncodePriority, NVIC_DecodePriority
- */
- void TC_CoreFunc_EncDecIRQPrio (void)
- {
- /* Check only the valid range of PRIGROUP and preempt-/sub-priority values. */
- static const uint32_t priobits = (__NVIC_PRIO_BITS > 7U) ? 7U : __NVIC_PRIO_BITS;
- for(uint32_t prigroup = 7U-priobits; prigroup<7U; prigroup++) {
- for(uint32_t pre = 0U; pre<(128U>>prigroup); pre++) {
- for(uint32_t sub = 0U; sub<(256U>>(8U-__NVIC_PRIO_BITS+7U-prigroup)); sub++) {
- TC_CoreFunc_EncDecIRQPrio_Step(prigroup, pre, sub);
- }
- }
- }
- }
- /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
- /**
- \brief Test case: TC_CoreFunc_IRQVect
- \details
- Check expected behavior of interrupt vector relocation functions:
- - NVIC_SetVector, NVIC_GetVector
- */
- void TC_CoreFunc_IRQVect(void) {
- #if defined(__VTOR_PRESENT) && __VTOR_PRESENT
- /* relocate vector table */
- extern const VECTOR_TABLE_Type __VECTOR_TABLE[48];
- static VECTOR_TABLE_Type vectors[sizeof(__VECTOR_TABLE)/sizeof(__VECTOR_TABLE[0])] __ALIGNED(1024) __NO_INIT;
- memcpy(vectors, __VECTOR_TABLE, sizeof(__VECTOR_TABLE));
- const uint32_t orig_vtor = SCB->VTOR;
- const uint32_t vtor = ((uint32_t)vectors) & SCB_VTOR_TBLOFF_Msk;
- SCB->VTOR = vtor;
- ASSERT_TRUE(vtor == SCB->VTOR);
- /* check exception vectors */
- extern void HardFault_Handler(void);
- extern void SVC_Handler(void);
- extern void PendSV_Handler(void);
- extern void SysTick_Handler(void);
- ASSERT_TRUE(NVIC_GetVector(HardFault_IRQn) == (uint32_t)HardFault_Handler);
- ASSERT_TRUE(NVIC_GetVector(SVCall_IRQn) == (uint32_t)SVC_Handler);
- ASSERT_TRUE(NVIC_GetVector(PendSV_IRQn) == (uint32_t)PendSV_Handler);
- ASSERT_TRUE(NVIC_GetVector(SysTick_IRQn) == (uint32_t)SysTick_Handler);
- /* reconfigure WDT IRQ vector */
- extern void Interrupt0_Handler(void);
- const uint32_t wdtvec = NVIC_GetVector(Interrupt0_IRQn);
- ASSERT_TRUE(wdtvec == (uint32_t)Interrupt0_Handler);
- NVIC_SetVector(Interrupt0_IRQn, wdtvec + 32U);
- ASSERT_TRUE(NVIC_GetVector(Interrupt0_IRQn) == (wdtvec + 32U));
- /* restore vector table */
- SCB->VTOR = orig_vtor;
- #endif
- }
- /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
- /**
- \brief Test case: TC_CoreFunc_GetCtrl
- \details
- - Check if __set_CONTROL and __get_CONTROL() sets/gets control register
- */
- void TC_CoreFunc_Control (void) {
- // don't use stack for this variables
- static uint32_t orig;
- static uint32_t ctrl;
- static uint32_t result;
- orig = __get_CONTROL();
- ctrl = orig;
- result = UINT32_MAX;
- #ifdef CONTROL_SPSEL_Msk
- // SPSEL set to 0 (MSP)
- ASSERT_TRUE((ctrl & CONTROL_SPSEL_Msk) == 0U);
- // SPSEL set to 1 (PSP)
- ctrl |= CONTROL_SPSEL_Msk;
- // Move MSP to PSP
- __set_PSP(__get_MSP());
- #endif
- __set_CONTROL(ctrl);
- __ISB();
- result = __get_CONTROL();
- __set_CONTROL(orig);
- __ISB();
- ASSERT_TRUE(result == ctrl);
- ASSERT_TRUE(__get_CONTROL() == orig);
- }
- /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
- /**
- \brief Test case: TC_CoreFunc_IPSR
- \details
- - Check if __get_IPSR intrinsic is available
- - Check if __get_xPSR intrinsic is available
- - Result differentiates between thread and exception modes
- */
- void TC_CoreFunc_IPSR (void) {
- uint32_t result = __get_IPSR();
- ASSERT_TRUE(result == 0U); // Thread Mode
- result = __get_xPSR();
- ASSERT_TRUE((result & xPSR_ISR_Msk) == 0U); // Thread Mode
- TST_IRQHandler = TC_CoreFunc_IPSR_IRQHandler;
- irqIPSR = 0U;
- irqXPSR = 0U;
- NVIC_ClearPendingIRQ(Interrupt0_IRQn);
- NVIC_EnableIRQ(Interrupt0_IRQn);
- __enable_irq();
- NVIC_SetPendingIRQ(Interrupt0_IRQn);
- for(uint32_t i = 10U; i > 0U; --i) {__NOP();}
- __disable_irq();
- NVIC_DisableIRQ(Interrupt0_IRQn);
- ASSERT_TRUE(irqIPSR != 0U); // Exception Mode
- ASSERT_TRUE((irqXPSR & xPSR_ISR_Msk) != 0U); // Exception Mode
- }
- /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
- #if defined(__CC_ARM)
- #define SUBS(Rd, Rm, Rn) __ASM volatile("SUBS " # Rd ", " # Rm ", " # Rn)
- #define ADDS(Rd, Rm, Rn) __ASM volatile("ADDS " # Rd ", " # Rm ", " # Rn)
- #elif defined( __GNUC__ ) && (!defined(__ti__)) && (!defined(__ARMCC_VERSION)) && (defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_8M_BASE__))
- #define SUBS(Rd, Rm, Rn) __ASM volatile("SUB %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
- #define ADDS(Rd, Rm, Rn) __ASM volatile("ADD %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
- #elif defined(_lint)
- //lint -save -e(9026) allow function-like macro
- #define SUBS(Rd, Rm, Rn) ((Rd) = (Rm) - (Rn))
- #define ADDS(Rd, Rm, Rn) ((Rd) = (Rm) + (Rn))
- //lint -restore
- #else
- #define SUBS(Rd, Rm, Rn) __ASM volatile("SUBS %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
- #define ADDS(Rd, Rm, Rn) __ASM volatile("ADDS %0, %1, %2" : "=r"(Rd) : "r"(Rm), "r"(Rn) : "cc")
- #endif
- /**
- \brief Test case: TC_CoreFunc_APSR
- \details
- - Check if __get_APSR intrinsic is available
- - Check if __get_xPSR intrinsic is available
- - Check negative, zero and overflow flags
- */
- void TC_CoreFunc_APSR (void) {
- volatile uint32_t result;
- //lint -esym(838, Rm) unused values
- //lint -esym(438, Rm) unused values
- // Check negative flag
- volatile int32_t Rm = 5;
- volatile int32_t Rn = 7;
- SUBS(Rm, Rm, Rn);
- result = __get_APSR();
- ASSERT_TRUE((result & APSR_N_Msk) == APSR_N_Msk);
- Rm = 5;
- Rn = 7;
- SUBS(Rm, Rm, Rn);
- result = __get_xPSR();
- ASSERT_TRUE((result & xPSR_N_Msk) == xPSR_N_Msk);
- // Check zero and compare flag
- Rm = 5;
- SUBS(Rm, Rm, Rm);
- result = __get_APSR();
- ASSERT_TRUE((result & APSR_Z_Msk) == APSR_Z_Msk);
- ASSERT_TRUE((result & APSR_C_Msk) == APSR_C_Msk);
- Rm = 5;
- SUBS(Rm, Rm, Rm);
- result = __get_xPSR();
- ASSERT_TRUE((result & xPSR_Z_Msk) == xPSR_Z_Msk);
- ASSERT_TRUE((result & APSR_C_Msk) == APSR_C_Msk);
- // Check overflow flag
- Rm = 5;
- Rn = INT32_MAX;
- ADDS(Rm, Rm, Rn);
- result = __get_APSR();
- ASSERT_TRUE((result & APSR_V_Msk) == APSR_V_Msk);
- Rm = 5;
- Rn = INT32_MAX;
- ADDS(Rm, Rm, Rn);
- result = __get_xPSR();
- ASSERT_TRUE((result & xPSR_V_Msk) == xPSR_V_Msk);
- }
- /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
- /**
- \brief Test case: TC_CoreFunc_PSP
- \details
- - Check if __get_PSP and __set_PSP intrinsic can be used to manipulate process stack pointer.
- */
- void TC_CoreFunc_PSP (void) {
- // don't use stack for this variables
- static uint32_t orig;
- static uint32_t psp;
- static uint32_t result;
- orig = __get_PSP();
- psp = orig + 0x12345678U;
- __set_PSP(psp);
- result = __get_PSP();
- __set_PSP(orig);
- ASSERT_TRUE(result == psp);
- }
- /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
- /**
- \brief Test case: TC_CoreFunc_MSP
- \details
- - Check if __get_MSP and __set_MSP intrinsic can be used to manipulate main stack pointer.
- */
- void TC_CoreFunc_MSP (void) {
- // don't use stack for this variables
- static uint32_t orig;
- static uint32_t msp;
- static uint32_t result;
- static uint32_t ctrl;
- ctrl = __get_CONTROL();
- orig = __get_MSP();
- __set_PSP(orig);
- __set_CONTROL(ctrl | CONTROL_SPSEL_Msk); // switch to PSP
- msp = orig + 0x12345678U;
- __set_MSP(msp);
- result = __get_MSP();
- __set_MSP(orig);
- __set_CONTROL(ctrl);
- ASSERT_TRUE(result == msp);
- }
- /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
- /**
- \brief Test case: TC_CoreFunc_PSPLIM
- \details
- - Check if __get_PSPLIM and __set_PSPLIM intrinsic can be used to manipulate process stack pointer limit.
- */
- void TC_CoreFunc_PSPLIM (void) {
- #if ((defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
- (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
- (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
- // don't use stack for this variables
- static uint32_t orig;
- static uint32_t psplim;
- static uint32_t result;
- orig = __get_PSPLIM();
- psplim = orig + 0x12345678U;
- __set_PSPLIM(psplim);
- result = __get_PSPLIM();
- __set_PSPLIM(orig);
- #if (!(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) && \
- !(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
- (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)) )
- // without main extensions, the non-secure PSPLIM is RAZ/WI
- ASSERT_TRUE(result == 0U);
- #else
- ASSERT_TRUE(result == psplim);
- #endif
- #endif
- }
- /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
- /**
- \brief Test case: TC_CoreFunc_PSPLIM_NS
- \details
- - Check if __TZ_get_PSPLIM_NS and __TZ_set_PSPLIM_NS intrinsic can be used to manipulate process stack pointer limit.
- */
- void TC_CoreFunc_PSPLIM_NS (void) {
- #if ((defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
- (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
- (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
- #if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3))
- uint32_t orig;
- uint32_t psplim;
- uint32_t result;
- orig = __TZ_get_PSPLIM_NS();
- psplim = orig + 0x12345678U;
- __TZ_set_PSPLIM_NS(psplim);
- result = __TZ_get_PSPLIM_NS();
- __TZ_set_PSPLIM_NS(orig);
- #if (!(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) && \
- !(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
- // without main extensions, the non-secure PSPLIM is RAZ/WI
- ASSERT_TRUE(result == 0U);
- #else
- ASSERT_TRUE(result == psplim);
- #endif
- #endif
- #endif
- }
- /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
- /**
- \brief Test case: TC_CoreFunc_MSPLIM
- \details
- - Check if __get_MSPLIM and __set_MSPLIM intrinsic can be used to manipulate main stack pointer limit.
- */
- void TC_CoreFunc_MSPLIM (void) {
- #if ((defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
- (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
- (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
- // don't use stack for this variables
- static uint32_t orig;
- static uint32_t msplim;
- static uint32_t result;
- static uint32_t ctrl;
- ctrl = __get_CONTROL();
- __set_CONTROL(ctrl | CONTROL_SPSEL_Msk); // switch to PSP
- orig = __get_MSPLIM();
- msplim = orig + 0x12345678U;
- __set_MSPLIM(msplim);
- result = __get_MSPLIM();
- __set_MSPLIM(orig);
- __set_CONTROL(ctrl);
- #if (!(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) && \
- !(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
- (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)) )
- // without main extensions, the non-secure MSPLIM is RAZ/WI
- ASSERT_TRUE(result == 0U);
- #else
- ASSERT_TRUE(result == msplim);
- #endif
- #endif
- }
- /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
- /**
- \brief Test case: TC_CoreFunc_MSPLIM_NS
- \details
- - Check if __TZ_get_MSPLIM_NS and __TZ_set_MSPLIM_NS intrinsic can be used to manipulate process stack pointer limit.
- */
- void TC_CoreFunc_MSPLIM_NS (void) {
- #if ((defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) || \
- (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
- (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
- #if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3))
- uint32_t orig;
- uint32_t msplim;
- uint32_t result;
- orig = __TZ_get_MSPLIM_NS();
- msplim = orig + 0x12345678U;
- __TZ_set_MSPLIM_NS(msplim);
- result = __TZ_get_MSPLIM_NS();
- __TZ_set_MSPLIM_NS(orig);
- #if (!(defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) && \
- !(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
- // without main extensions, the non-secure MSPLIM is RAZ/WI
- ASSERT_TRUE(result == 0U);
- #else
- ASSERT_TRUE(result == msplim);
- #endif
- #endif
- #endif
- }
- /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
- /**
- \brief Test case: TC_CoreFunc_PRIMASK
- \details
- - Check if __get_PRIMASK and __set_PRIMASK intrinsic can be used to manipulate PRIMASK.
- - Check if __enable_irq and __disable_irq are reflected in PRIMASK.
- */
- void TC_CoreFunc_PRIMASK (void) {
- uint32_t orig = __get_PRIMASK();
- // toggle primask
- uint32_t primask = (orig & ~0x01U) | (~orig & 0x01U);
- __set_PRIMASK(primask);
- uint32_t result = __get_PRIMASK();
- ASSERT_TRUE(result == primask);
- __disable_irq();
- result = __get_PRIMASK();
- ASSERT_TRUE((result & 0x01U) == 1U);
- __enable_irq();
- result = __get_PRIMASK();
- ASSERT_TRUE((result & 0x01U) == 0U);
- __disable_irq();
- result = __get_PRIMASK();
- ASSERT_TRUE((result & 0x01U) == 1U);
- __set_PRIMASK(orig);
- }
- /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
- /**
- \brief Test case: TC_CoreFunc_FAULTMASK
- \details
- - Check if __get_FAULTMASK and __set_FAULTMASK intrinsic can be used to manipulate FAULTMASK.
- - Check if __enable_fault_irq and __disable_fault_irq are reflected in FAULTMASK.
- */
- void TC_CoreFunc_FAULTMASK (void) {
- #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
- (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
- (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
- (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) )
- uint32_t orig = __get_FAULTMASK();
- // toggle faultmask
- uint32_t faultmask = (orig & ~0x01U) | (~orig & 0x01U);
- __set_FAULTMASK(faultmask);
- uint32_t result = __get_FAULTMASK();
- ASSERT_TRUE(result == faultmask);
- __disable_fault_irq();
- result = __get_FAULTMASK();
- ASSERT_TRUE((result & 0x01U) == 1U);
- __enable_fault_irq();
- result = __get_FAULTMASK();
- ASSERT_TRUE((result & 0x01U) == 0U);
- __disable_fault_irq();
- result = __get_FAULTMASK();
- ASSERT_TRUE((result & 0x01U) == 1U);
- __set_FAULTMASK(orig);
- #endif
- }
- /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
- /**
- \brief Test case: TC_CoreFunc_BASEPRI
- \details
- - Check if __get_BASEPRI and __set_BASEPRI intrinsic can be used to manipulate BASEPRI.
- - Check if __set_BASEPRI_MAX intrinsic can be used to manipulate BASEPRI.
- */
- void TC_CoreFunc_BASEPRI(void) {
- #if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
- (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
- (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
- (defined (__ARM_ARCH_8_1M_MAIN__ ) && (__ARM_ARCH_8_1M_MAIN__ == 1)) )
- uint32_t orig = __get_BASEPRI();
- uint32_t basepri = ~orig & 0x80U;
- __set_BASEPRI(basepri);
- uint32_t result = __get_BASEPRI();
- ASSERT_TRUE(result == basepri);
- __set_BASEPRI(orig);
- __set_BASEPRI_MAX(basepri);
- result = __get_BASEPRI();
- ASSERT_TRUE(result == basepri);
- #endif
- }
- /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
- /**
- \brief Test case: TC_CoreFunc_FPUType
- \details
- Check SCB_GetFPUType returns information.
- */
- void TC_CoreFunc_FPUType(void) {
- uint32_t fpuType = SCB_GetFPUType();
- #if defined(__FPU_PRESENT) && (__FPU_PRESENT != 0)
- ASSERT_TRUE(fpuType > 0U);
- #else
- ASSERT_TRUE(fpuType == 0U);
- #endif
- }
- /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
- /**
- \brief Test case: TC_CoreFunc_FPSCR
- \details
- - Check if __get_FPSCR and __set_FPSCR intrinsics can be used
- */
- void TC_CoreFunc_FPSCR(void) {
- uint32_t fpscr = __get_FPSCR();
- __ISB();
- __DSB();
- __set_FPSCR(~fpscr);
- __ISB();
- __DSB();
- uint32_t result = __get_FPSCR();
- __set_FPSCR(fpscr);
- #if (defined (__FPU_USED ) && (__FPU_USED == 1U))
- ASSERT_TRUE(result != fpscr);
- #else
- ASSERT_TRUE(result == 0U);
- #endif
- }
|