This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Cortex A9 WFE instruction not working as expected

Note: This was originally posted on 10th October 2012 at http://forums.arm.com

I'm trying to do a simple test with WFE instruction and EVENTI/O signals. I'm trying to have one A9 enter a wait state with WFE, and have another A9 do some dummy operations while the first is waiting, then do SEV instruction to signal from its SIGNALO to the other A9's SIGNALI. I can verify with my simulation envronment that this signal fires. However, the first A9 is not waiting, it breezes right by the WFE instruction. No assembler warning indicating these instructions aren't supported.

My best clue is in the assembler guide there is the line "If the Event Register is set, WFE clears it and returns immediately," it sounds like this might be happening, but I can't find any reference to "Event Register" in the Cortex A9 TRM, so I'm not sure if this is active by default in my system or what.

Any ideas? Thanks!
Parents
  • Note: This was originally posted on 12th October 2012 at http://forums.arm.com

    More on this...I am trying to implement a lock based on section 7.3 of the barrier cookbook linked to above. Here is my function, called from a C program.

    ; void acquireLock(int* lockAddr)
    acquireLock
    LDREX r1, [r0]
    CMP r1, #0         ; 0 = unlocked
    WFENE
    MOVEQ r2, #1       ; 1 = locked
    STREXEQ r3, r2, [r0]  ; r3 = 1, but the store DOES occur!
    CMPEQ r3, #0
    BNE acquireLock
    DMB
    MOV pc, lr


    On first execution, it reads the value from *lockAddr and it is 0 (i.e. r1=0). So it gets to the STREXEQ instruction, which DOES store value 1 in memory, but the return value r3=1 (failure). So, it branches back to the top, reads that value again and it is 1 (r1=1). So it the does WFENE and enters wait mode (it actually does this twice, the first time it does not go into wait mode but returns just to reach that same WFENE as the logic has not changed and it hangs then).

    My other process eventually enters the same WFENE loop as the value is still 1. According to the assembler guide there are a couple reasons by the STREX could return 1 in r3, but both involve the store failing as well. I see through the code logic and my environment memory tools that the store did occur. The memory location r0 refers to is cacheable, bufferable and shared.

    Any ideas?
Reply
  • Note: This was originally posted on 12th October 2012 at http://forums.arm.com

    More on this...I am trying to implement a lock based on section 7.3 of the barrier cookbook linked to above. Here is my function, called from a C program.

    ; void acquireLock(int* lockAddr)
    acquireLock
    LDREX r1, [r0]
    CMP r1, #0         ; 0 = unlocked
    WFENE
    MOVEQ r2, #1       ; 1 = locked
    STREXEQ r3, r2, [r0]  ; r3 = 1, but the store DOES occur!
    CMPEQ r3, #0
    BNE acquireLock
    DMB
    MOV pc, lr


    On first execution, it reads the value from *lockAddr and it is 0 (i.e. r1=0). So it gets to the STREXEQ instruction, which DOES store value 1 in memory, but the return value r3=1 (failure). So, it branches back to the top, reads that value again and it is 1 (r1=1). So it the does WFENE and enters wait mode (it actually does this twice, the first time it does not go into wait mode but returns just to reach that same WFENE as the logic has not changed and it hangs then).

    My other process eventually enters the same WFENE loop as the value is still 1. According to the assembler guide there are a couple reasons by the STREX could return 1 in r3, but both involve the store failing as well. I see through the code logic and my environment memory tools that the store did occur. The memory location r0 refers to is cacheable, bufferable and shared.

    Any ideas?
Children
No data