;/**
  ;**************************************************************************
  ;* File   : n32_cm0_STLcpurunIAR.s
  ;* Version: V1.0.0
  ;* Date   : 2024-04-25
  ;* Brief  : This file contains procedures written in assembler for full
  ;           and partial transparent Marching RAM tests to be called during
  ;           start-up and run time
  ;**************************************************************************
  ;*/

  SECTION .text:CODE(2)

  ; Reference to the FailSafe routine to be executed in case of non-recoverable
  ; failure
  EXTERN FailSafePOR

  ; C variables for control flow monitoring
  EXTERN CtrlFlowCnt
  EXTERN CtrlFlowCntInv
  EXTERN conAA
  EXTERN con55
  
;*******************************************************************************
; Function Name  : STL_RunTimeCPUTest
; Description    : Cortex-M4 CPU test during run-time
;                  Note: when possible, BRANCH are 16-bit only (depending on
;                  relative offset to final BL instruction)
; Input          : None.
; Output         : Branch directly to a Fail Safe routine in case of failure
; Return         : CPUTEST_SUCCESS (=1) if test is ok
;*******************************************************************************/

STL_RunTimeCPUTest:
    EXPORT STL_RunTimeCPUTest

    PUSH {R4-R7}              ; Safe registers
    
    ; Register R0 
    ; Immediate permitted values are 0x00 to 0xFF
    LDR R0, =0x55000000
    LSRS R0, R0, #24
    CMP R0, #0x55
    BNE CPUTestFail

    LDR R0, =0xAA000000
    LSRS R0, R0, #24
    CMP R0, #0xAA
    BNE CPUTestFail

    LDR R0, =0x00550000
    LSRS R0, R0, #16
    CMP R0, #0x55
    BNE CPUTestFail

    LDR R0, =0x00AA0000
    LSRS R0, R0, #16
    CMP R0, #0xAA
    BNE CPUTestFail

    LDR R0, =0x00005500
    LSRS R0, R0, #8
    CMP R0, #0x55
    BNE CPUTestFail

    LDR R0, =0x0000AA00
    LSRS R0, R0, #8
    CMP R0, #0xAA
    BNE CPUTestFail

    MOVS R0, #0xA5
    CMP R0, #0xA5
    BNE CPUTestFail  

   	; This is for control flow test (ENTRY point)
	LDR R0,=CtrlFlowCnt
	; Assumes R1 OK; If not, error will be detected by R1 test and Ctrl flow test later on
	LDR R1,[R0]
	ADDS R1,R1,#0x3	 ; CtrlFlowCnt += 0x03
	STR R1,[R0]
    
    ; Register R1
    LDR R0, =conAA
	LDR R1,[R0]
    LDR R0,[R0]
    CMP R0,R1
    BNE CPUTestFail
    LDR R0, =con55
	LDR R1,[R0]
    LDR R0,[R0]
    CMP R0,R1
    BNE CPUTestFail
    MOVS R1, #0x1             ; For ramp test

    ; Register R2
    LDR R0, =conAA
	LDR R2,[R0]
    LDR R0,[R0]
    CMP R0,R2
    BNE CPUTestFail
    LDR R0, =con55
	LDR R2,[R0]
    LDR R0,[R0]
    CMP R0,R2
    BNE CPUTestFail
    MOVS R2, #0x2             ; For ramp test

    ; Register R3
    LDR R0, =conAA
	LDR R3,[R0]
    LDR R0,[R0]
    CMP R0,R3
    BNE CPUTestFail
    LDR R0, =con55
	LDR R3,[R0]
    LDR R0,[R0]
    CMP R0,R3
    BNE CPUTestFail
    MOVS R3, #0x3             ; For ramp test

    ; Register R4
    LDR R0, =conAA
	LDR R4,[R0]
    LDR R0,[R0]
    CMP R0,R4
    BNE CPUTestFail
    LDR R0, =con55
	LDR R4,[R0]
    LDR R0,[R0]
    CMP R0,R4
    BNE CPUTestFail
    MOVS R4, #0x4             ; For ramp test

    ; Register R5
    LDR R0, =conAA
	LDR R5,[R0]
    LDR R0,[R0]
    CMP R0,R5
    BNE CPUTestFail
    LDR R0, =con55
	LDR R5,[R0]
    LDR R0,[R0]
    CMP R0,R5
    BNE CPUTestFail
    MOVS R5, #0x5             ; For ramp test

    ; Register R6
    LDR R0, =conAA
	LDR R6,[R0]
    LDR R0,[R0]
    CMP R0,R6
    BNE CPUTestFail
    LDR R0, =con55
	LDR R6,[R0]
    LDR R0,[R0]
    CMP R0,R6
    BNE CPUTestFail
    MOVS R6, #0x6             ; For ramp test

    ; Register R7
    LDR R0, =conAA
	LDR R7,[R0]
    LDR R0,[R0]
    CMP R0,R7
    BNE CPUTestFail
    LDR R0, =con55
	LDR R7,[R0]
    LDR R0,[R0]
    CMP R0,R7
    BNE CPUTestFail
    MOVS R7, #0x7             ; For ramp test

    ; Register R8
    LDR R0, =conAA
    LDR R0,[R0]
	MOV R8,R0
    CMP R0,R8
    BNE CPUTestFail
    LDR R0, =con55
    LDR R0,[R0]
	MOV R8,R0
    CMP R0,R8
    BNE CPUTestFail
	MOVS R0, #0x08            ; For ramp test
	MOV	R8,R0

	BAL CPUTstCont

CPUTestFail
	BL FailSafePOR

CPUTstCont
    ; Register R9
    LDR R0, =conAA
    LDR R0,[R0]
	MOV R9,R0
    CMP R0,R9
    BNE CPUTestFail
    LDR R0, =con55
    LDR R0,[R0]
	MOV R9,R0
    CMP R0,R9
    BNE CPUTestFail
	MOVS R0, #0x09            ; For ramp test
	MOV	R9,R0

    ; Register R10
    LDR R0, =conAA
    LDR R0,[R0]
	MOV R10,R0
    CMP R0,R10
    BNE CPUTestFail
    LDR R0, =con55
    LDR R0,[R0]
	MOV R10,R0
    CMP R0,R10
    BNE CPUTestFail
	MOVS R0, #0x0A            ; For ramp test
	MOV	R10,R0

    ; Register R11
    LDR R0, =conAA
    LDR R0,[R0]
	MOV R11,R0
    CMP R0,R11
    BNE CPUTestFail
    LDR R0, =con55
    LDR R0,[R0]
	MOV R11,R0
    CMP R0,R11
    BNE CPUTestFail
	MOVS R0, #0x0B            ; For ramp test
	MOV	R11,R0

    ; Register R12
    LDR R0, =conAA
    LDR R0,[R0]
	MOV R12,R0
    CMP R0,R12
    BNE CPUTestFail
    LDR R0, =con55
    LDR R0,[R0]
	MOV R12,R0
    CMP R0,R12
    BNE CPUTestFail
	MOVS R0, #0x0C            ; For ramp test
	MOV	R12,R0
	LDR R0, =CPUTstCont

    ; Link register R14	cannot be tested an error should be detected by	Ctrl flow test later

    ; Ramp pattern verification	(R0 is not padded)
    CMP R1, #0x01
    BNE CPUTestFail
    CMP R2, #0x02
    BNE CPUTestFail
    CMP R3, #0x03
    BNE CPUTestFail
    CMP R4, #0x04
    BNE CPUTestFail
    CMP R5, #0x05
    BNE CPUTestFail
    CMP R6, #0x06
    BNE CPUTestFail
    CMP R7, #0x07
    BNE CPUTestFail
	MOVS R0, #0x08
    CMP R0,R8
    BNE CPUTestFail
	MOVS R0, #0x09
    CMP R0,R9
    BNE CPUTestFail
	MOVS R0, #0x0A
    CMP R0,R10
    BNE CPUTestFail
	MOVS R0, #0x0B
    CMP R0,R11
    BNE CPUTestFail
	MOVS R0, #0x0C
    CMP R0,R12
    BNE CPUTestFail

    ; Control flow test (EXIT point)
	LDR R0,=CtrlFlowCntInv
	LDR R1,[R0]
	SUBS R1,R1,#0x3	 ; CtrlFlowCntInv -= 0x03
	STR R1,[R0]

	POP {R4-R7}              ; Restore registers

    MOVS R0, #0x1       ; CPUTEST_SUCCESS
    BX LR               ; return to the caller

  END

;******************* (C) COPYRIGHT  *****END OF FILE*****
