/* * Copyright 2020-2023 Yuntu Microelectronics co.,ltd * All rights reserved. * * YUNTU Confidential. This software is owned or controlled by YUNTU and may only be * used strictly in accordance with the applicable license terms. By expressly * accepting such terms or by downloading, installing, activating and/or otherwise * using the software, you are agreeing that you have read, and that you agree to * comply with and are bound by, such license terms. If you do not agree to be * bound by the applicable license terms, then you may not retain, install, * activate or otherwise use the software. The production use license in * Section 2.3 is expressly granted for this software. */ /****************************************************************************** * Test summary: * ------------- * * Covers Load/Store exclusive functionality: * - local monitor * - switching between open and exclusive access * - memory write protection for STREX while in open access * * Overall coverage: * ----------------- * Covers CLREX, LDREX, LDREXB, LDREXH, STREX, STREXB, STREXH instructions * * NOTE: Encoding of Load/Store Exclusive instructions is same as encoding of * other Load/Store instructions thus encoding of input/output registers * is fully covered by other load/store tests. ******************************************************************************/ #include "CorTst_Compiler.h" #include "CorTst_M33_Cfg.h" #if (CORTST_M33_LOADSTORE_ENABLE==1) /* Compatible with ABI. */ CST_PRES8 /* Symbols defined in the current module but to be visible to outside */ CST_EXPORT M33_Cst_LoadstoreTest6 /* Symbols defined outside but used within current module */ CST_EXTERN CST_RAM_TARGET0 CST_EXTERN CST_RAM_TARGET1 CST_EXTERN m33_cst_test_tail_end CST_EXTERN VAL1 CST_EXTERN VAL2 CST_EXTERN VAL3 CST_EXTERN VAL4 CST_EXTERN VAL5 CST_EXTERN VAL6 CST_EXTERN VAL7 CST_EXTERN VAL8 CST_EXTERN VAL9 CST_EXTERN VAL10 /*------------------------------------------------------------------------*/ CST_SECTION_EXEC(mcal_text) /*------------------------------------------------------------------------*/ /* The ".type" directive instructs the assembler/linker that the label "M33_Cst_LoadstoreTest6" designates a function. This would cause setting the least significant bit to '1' within any pointer to this function, causing change to Thumb mode whenever this function is called. */ CST_THUMB2 CST_TYPE(M33_Cst_LoadstoreTest6, function) M33_Cst_LoadstoreTest6: PUSH {R4-R12, R14} /*------------------------------------------------------------------------*/ /* Test - preparation */ /*------------------------------------------------------------------------*/ /* Load presignature */ ADR R0, m33_cst_loadstore_test6_presignature LDREX R1, [R0] /* Load presignature and set exclusive access */ ROR R1, R1, #1 /* Destroy signature in R1 */ #if 0 CLREX /* Switch to open access, next STREX is canceled */ STREX R2, R1, [R0] /* Store shall fail in fault-free case otherwise */ #endif DSB /* exception or wrong presignature !! */ LDREX R1, [R0] CLREX /* Switch to open access */ /*------------------------------------------------------------------------*/ /* Test - start */ /*------------------------------------------------------------------------*/ /* Start testing with CST_RAM_TARGET0 */ LDR.W R0, =CST_RAM_TARGET0 BL m33_cst_loadstore_test6_common /* Start testing with CST_RAM_TARGET1 */ LDR.W R0, =CST_RAM_TARGET1 BL m33_cst_loadstore_test6_common /*************************************************************************** * Instructions: * - STREX Encoding T1 (32-bit) * - LDREX Encoding T1 (32-bit) * * NOTE: Operations with stack ***************************************************************************/ PUSH {R1} /* Push signature on stack */ ROR R1, R1, #3 /* Destroy signature in R1 */ /* Check that STREX in open access will not succeed */ STREX R0, R1, [SP] /* Try to destroy signature on stack */ CMP R0, #1 DSB BNE m33_cst_loadstore_test6_stack_failed /* Update signature on stack */ MRS R2, PRIMASK /* Save PRIMASK */ CST_PREPARE_PIPELINE /* Flush pipeline & disable ISRs */ LDREX R1, [SP] /* Switch to exclusive access */ ROR R1, R1, #1 STREX R0, R1, [SP] /* STREX in exclusive access should succeed */ /*------------------------------------------------------------------------*/ MSR PRIMASK, R2 /* Restore PRIMASK (enable ISRs) */ /*------------------------------------------------------------------------*/ CMP R0, #0 DSB BNE m33_cst_loadstore_test6_stack_failed ROR R1, R1, #3 /* Destroy signature in R1 */ /* Check that previous STREX switched to open access */ STREX R0, R1, [SP] /* Try to destroy signature on stack */ CMP R0, #1 DSB BNE m33_cst_loadstore_test6_stack_failed /*************************************************************************** * Instructions: * - STREX Encoding T1 (32-bit) * - LDREX Encoding T1 (32-bit) * * NOTE: Dual issue operations with stack ***************************************************************************/ LDR R2, [SP] /* Load signature */ STR R9, [SP] /* Store parity 1 */ DSB MRS R3, PRIMASK /* Save PRIMASK - Do not overwrite R3 in test! */ /*------------------------------------------------------------------------*/ CST_PREPARE_PIPELINE /* Flush pipeline & disable ISRs */ /*------------------------------------------------------------------------*/ LDREX R1,[SP] /* Slot 0 - Load parity 1 */ STREX R4,R2,[SP] /* Slot 1 - Store signature */ /*------------------------------------------------------------------------*/ MSR PRIMASK, R3 /* Restore PRIMASK (enable ISRs) */ /*------------------------------------------------------------------------*/ /* Check that STREX succeeded */ CMP R4, #0 DSB BNE m33_cst_loadstore_test6_stack_failed EOR R1, R1, R2 /* Calculate parity 2 */ ROR R2, R2, #6 /* Destroy signature in R2 */ /*------------------------------------------------------------------------*/ CST_PREPARE_PIPELINE /* Flush pipeline & disable ISRs */ /*------------------------------------------------------------------------*/ NOP /* Slot 0 */ LDREX R2,[SP] /* Slot 1 - Load signature */ STREX R5,R1,[SP] /* Slot 0 - Store parity 2 */ /*------------------------------------------------------------------------*/ MSR PRIMASK, R3 /* Restore PRIMASK (enable ISRs) */ /*------------------------------------------------------------------------*/ /* Check that STREX succeeded */ CMP R5, #0 DSB BNE m33_cst_loadstore_test6_stack_failed EOR R1, R1, R2 /* Calculate parity 1 */ LDREX R2,[SP] /* Load parity 2 */ EOR R2, R1, R2 /* Calculate signature */ /*------------------------------------------------------------------------*/ CST_PREPARE_PIPELINE /* Flush pipeline & disable ISRs */ /*------------------------------------------------------------------------*/ CLREX /* Slot 0 */ STREX R6,R12,[SP] /* Slot 1 - Try to overwrite parity 2, should fail*/ /*------------------------------------------------------------------------*/ MSR PRIMASK, R3 /* Restore PRIMASK (enable ISRs) */ /*------------------------------------------------------------------------*/ /* Check that STREX failed */ CMP R6, #1 DSB BNE m33_cst_loadstore_test6_stack_failed LDREX R1,[SP] /* Load parity 2 */ /* Check that STREX did not overwrite data */ CMP R1,R12 BEQ m33_cst_loadstore_test6_stack_failed EOR R1,R1,R2 /* Calculate parity 1 */ /*------------------------------------------------------------------------*/ CST_PREPARE_PIPELINE /* Flush pipeline & disable ISRs */ /*------------------------------------------------------------------------*/ NOP /* Slot 0 */ CLREX /* Slot 1 */ STREX R7,R12,[SP] /* Slot 0 - Try to overwrite parity 2, should fail*/ /*------------------------------------------------------------------------*/ MSR PRIMASK, R3 /* Restore PRIMASK (enable ISRs) */ /*------------------------------------------------------------------------*/ /* Check that STREX failed */ CMP R7, #1 DSB BNE m33_cst_loadstore_test6_stack_failed LDR R2,[SP] /* Load parity 2 */ /* Check that STREX did not overwrite data */ CMP R2,R12 BEQ m33_cst_loadstore_test6_stack_failed /* Check that parity 1 was not changed */ CMP R1,R9 BNE m33_cst_loadstore_test6_stack_failed EOR R2,R1,R2 /* Calculate signature */ ROR R2, R2, #1 /* Update signature */ STR R2,[SP] /* Store signature */ DSB m33_cst_loadstore_test6_stack_failed: POP {R1} /*------------------------------------------------------------------------*/ /* Test - end */ /*------------------------------------------------------------------------*/ /* Test result is returned in R0, according to the conventions */ MVN R0, R1 m33_cst_loadstore_test6_end: B m33_cst_test_tail_end /*------------------------------------------------------------------------*/ /* Test routine - start */ /*------------------------------------------------------------------------*/ m33_cst_loadstore_test6_common: MRS R3, PRIMASK /* Save PRIMASK */ PUSH {R1, R3, R14} /* We need to store R1, R3 and R14. */ /* Clear target memory */ MOV R1, #0xFFFFFFFF STR R1, [R0] DSB /* Initialize registers */ LDR.W R1, =VAL1 LDR.W R2, =VAL2 LDR.W R3, =VAL3 LDR.W R4, =VAL4 LDR.W R5, =VAL5 LDR.W R6, =VAL6 LDR.W R7, =VAL7 LDR.W R8, =VAL8 LDR.W R9, =VAL9 LDR.W R10, =VAL10 /*************************************************************************** * Instructions: * - STREXB Encoding T1 (32-bit) - Similar format as STRB.W * - LDREXB Encoding T1 (32-bit) - Similar format as LDR (immediate) T3 ***************************************************************************/ /* Prepare masks */ MVN R11, #0xFF /* R11 = 0xFFFFFF00 */ MVN R12, R11 /* R12 = 0x000000FF */ STRB.W R2, [R0] /* Store data to check that STREXB (Line 306) */ DSB /* will not overwrite it */ B m33_cst_loadstore_test6_strexb m33_cst_loadstore_test6_ldrexb: /* Update signature on stack */ POP {R1} ROR R1, R1, #1 PUSH {R1} CST_PREPARE_PIPELINE /* Flush pipeline & disable ISRs */ LDREXB R3, [R0] /* Load data, switch to exclusive access */ /* Skip CLREX in second pass */ EOR R6, R5, R11 CMP R3, R6 BEQ m33_cst_loadstore_test6_skip_clrex_b /* Check that STREXB (Line 306) didnt overwrite data */ AND R6, R2, R12 CMP R3, R6 BNE m33_cst_loadstore_test6_failed /* Check that CLREX switch to open access */ CLREX STREXB R1, R4, [R0] /* STREXB should not succeed */ CMP R1, #1 DSB BNE m33_cst_loadstore_test6_failed /* Check that STREXB (Line 280) didnt overwrite data */ LDR R1, [R0] EOR R1, R1, R11 CMP R1, R6 BNE m33_cst_loadstore_test6_failed m33_cst_loadstore_test6_skip_clrex_b: /* Check that standard store will succeed and will not change access type */ STRB.W R4, [R0] DSB LDR R3, [R0] ORR R6, R4, R11 CMP R3, R6 BNE m33_cst_loadstore_test6_failed /* Swap values in registers */ MOV R4, R5 MOV R5, R3 MOV R3, R2 m33_cst_loadstore_test6_strexb: STREXB R1, R3, [R0] /* called 3x, third call will successfully store */ CMP R1, #0 DSB BNE m33_cst_loadstore_test6_ldrexb /* branch if not succeeded */ LDR R1, [SP, #4] /* Restore PRIMASK */ MSR PRIMASK, R1 /* Check that STREXB (Line 306) successfully stored data */ LDR R1, [R0] ORR R6, R3, R11 CMP R1, R6 BNE m33_cst_loadstore_test6_failed /* Check that STREXB (Line 306) switched to open access */ STREXB R1, R12, [R0] /* STREXB should not succeed */ CMP R1, #1 DSB BNE m33_cst_loadstore_test6_failed LDR R1, [R0] CMP R1, R6 BNE m33_cst_loadstore_test6_failed /*************************************************************************** * Instructions: * - STREXH Encoding T1 (32-bit) - Similar format as STRH.W * - LDREXH Encoding T1 (32-bit) - Similar format as LDR (immediate) T3 ***************************************************************************/ /* Initialize registers */ MOV R11, R7 MOV R12, R9 MOV R5, R0 EORS R0, R0 /* Clear R0 */ MOV R2, #0xFFFF /* R2 = 0x0000FFFF */ MVN R4, R2 /* R4 = 0xFFFF0000 */ STRH.W R8, [R5] /* Store data to check that STREXH (Line 388) */ DSB /* will not overwrite it */ B m33_cst_loadstore_test6_strexh m33_cst_loadstore_test6_ldrexh: /* Update signature on stack */ POP {R6} ROR R6, R6, #1 PUSH {R6} CST_PREPARE_PIPELINE /* Flush pipeline & disable ISRs */ LDREXH R9, [R5] /* Load data, switch to exclusive access */ /* Skip CLREX in second pass */ EOR R1, R7, R4 CMP R9, R1 BEQ m33_cst_loadstore_test6_skip_clrex_h /* Check that STREXH (Line 388) didnt overwrite data */ AND R1, R8, R2 CMP R9, R1 BNE m33_cst_loadstore_test6_failed /* Check that CLREX switch to open access */ CLREX STREXH R6, R3, [R5] /* STREXH should not succeed */ CMP R6, #1 DSB BNE m33_cst_loadstore_test6_failed /* Check that STREXH (Line 362) didnt overwrite data */ LDR R6, [R5] EOR R6, R6, R4 CMP R6, R1 BNE m33_cst_loadstore_test6_failed m33_cst_loadstore_test6_skip_clrex_h: /* Check that standard store will succeed and will not change access type */ STRH.W R3, [R5] DSB LDR R9, [R5] ORR R1, R3, R4 CMP R9, R1 BNE m33_cst_loadstore_test6_failed /* Swap values in registers */ MOV R3, R7 MOV R7, R9 MOV R9, R8 m33_cst_loadstore_test6_strexh: STREXH R6, R9, [R5] /* called 3x, third call will successfully store */ CMP R6, #0 DSB BNE m33_cst_loadstore_test6_ldrexh /* branch if not succeeded */ LDR R6, [SP, #4] /* Restore PRIMASK */ MSR PRIMASK, R6 /* Check that STREXH (Line 388) successfully stored data */ LDR R6, [R5] ORR R1, R9, R4 CMP R6, R1 BNE m33_cst_loadstore_test6_failed /* Check that STREXH (Line 388) switched to open access */ STREXH R6, R2, [R5] CMP R6, #1 DSB BNE m33_cst_loadstore_test6_failed LDR R6, [R5] CMP R6, R1 BNE m33_cst_loadstore_test6_failed /*************************************************************************** * Instructions: * - STREX Encoding T1 (32-bit) - Similar format as STRD (immediate) * - LDREX Encoding T1 (32-bit) - Similar format as LDR (immediate) T3 ***************************************************************************/ /* Initialize registers */ SUB R5, R5, #0xD4 MOV R3, R5 STR R10, [R3, #0xD4]/* Store data to check that STREX (Line 468) */ DSB /* will not overwrite it */ B m33_cst_loadstore_test6_store_ex m33_cst_loadstore_test6_load_ex: /* Update signature on stack */ POP {R8} ROR R8, R8, #1 PUSH {R8} CST_PREPARE_PIPELINE /* Flush pipeline & disable ISRs */ LDREX R9, [R3, #0xD4] /* Load data, switch to exclusive access */ CMP R3, R5 BNE m33_cst_loadstore_test6_failed /* Skip CLREX in second pass */ CMP R9, R12 BEQ m33_cst_loadstore_test6_skip_clrex /* Check that STREX (Line 468) didnt overwrite data */ CMP R10, R9 BNE m33_cst_loadstore_test6_failed /* Check that CLREX switched to open access */ CLREX STREX R8, R11, [R3, #0xD4] /* STREX should not succeed */ CMP R3, R5 BNE m33_cst_loadstore_test6_failed CMP R8, #1 DSB BNE m33_cst_loadstore_test6_failed /* Check that STREX (Line 440) didnt overwrite data */ LDR R8, [R3, #0xD4]! SUB R3, R3, #0xD4 CMP R8, R10 BNE m33_cst_loadstore_test6_failed m33_cst_loadstore_test6_skip_clrex: /* Check that standard store will succeed and will not change access type */ STR R11, [R3, #0xD4] DSB LDR R9, [R3, #0xD4]! SUB R3, R3, #0xD4 CMP R11, R9 BNE m33_cst_loadstore_test6_failed /* Swap values in registers */ MOV R11, R12 MOV R12, R9 MOV R9, R10 m33_cst_loadstore_test6_store_ex: STREX R8, R9, [R3, #0xD4]/* called 3x, third call will successfully store */ CMP R3, R5 BNE m33_cst_loadstore_test6_failed CMP R8, #0 DSB BNE m33_cst_loadstore_test6_load_ex /* branch if not succeeded */ LDR R8, [SP, #4] /* Restore PRIMASK */ MSR PRIMASK, R8 /* Check that STREX (Line 468) successfully stored data */ LDR R8, [R3, #0xD4]! SUB R3, R3, #0xD4 CMP R8, R9 BNE m33_cst_loadstore_test6_failed /* Check that STREX (Line 468) switched to open access */ STREX R8, R11, [R3, #0xD4] /* STREX should not succeed */ CMP R3, R5 BNE m33_cst_loadstore_test6_failed CMP R8, #1 DSB BNE m33_cst_loadstore_test6_failed LDR R8, [R3, #0xD4]! SUB R3, R3, #0xD4 CMP R8, R9 BNE m33_cst_loadstore_test6_failed /*------------------------------------------------------------------------*/ /* Test routine - end */ /*------------------------------------------------------------------------*/ POP {R1} /* Update signature */ ROR R0, R1, #1 PUSH {R0} /* Store signature back to stack !! */ m33_cst_loadstore_test6_failed: POP.W {R1, R3, PC} /* We need to restore R1, R3 and return back */ MSR PRIMASK, R3 CST_ALIGN_BYTES_4 CST_LABEL m33_cst_loadstore_test6_presignature: CST_WORD(0xAB783DE8) /* Marks the current location for dumping psuedoinstruction pools containing numeric values for used symbolic names used within LDR instruction. */ CST_LTORG #endif /* CORTST_M33_LOADSTORE_ENABLE */ CST_FILE_END