UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Participant mberemand
Participant
240 Views
Registered: ‎10-22-2018

STREX instruction writes to memory but indicates failure

Jump to solution

I'm trying to use a std::atomic_flag object as a mutex in shared memory between my two CPUs (Zynq ZC702). I'll refer to it as "lockFlag". Starting from a point where neither CPU has acquired the lock yet, calling 

lockFlag.test_and_set()

results in the application being stuck in a loop.

10020014:   ldr     r3, [r11, #-8]      ; Loads the address of lockFlag
10020018:   mov     r2, #1
1002001c:   mov     r1, r2
10020020:   dmb     ish
10020024:   ldrexb  r2, [r3]
10020028:   strexb  r0, r1, [r3]        ; This instruction is behaving strangely.
1002002c:   cmp     r0, #0
10020030:   bne     -20     ; addr=0x10020024: wait + 0x00000030
10020034:   dmb     ish
10020038:   uxtb    r3, r2

The STREXB instruction does not behave like the ARM documentation says.

 

It is successfully writing the value in R1 to the address at R3, but also indicates failure by setting R0 to 1. I saw this similar thread and AR# 47586 but my memory region is non-caching and has to be sharable (attributes 0x14de2 I think), and there is nothing between the ldrexb and strexb instructions.

0 Kudos
1 Solution

Accepted Solutions
Voyager
Voyager
171 Views
Registered: ‎04-13-2015

Re: STREX instruction writes to memory but indicates failure

Jump to solution

@mberemand 

I do know when the cache is not enable the LDREX / STREX don't work.  I cannot confirm if with the cache enable and the memory access set as non-cached it's the same.

As for making the region non-cached because both CPUs are sharing it, there is no needs for that.  The cache is coherent meaning when one CPU update a memory location, although it could remains in the cache, the other CPU  will get the updated value copied into its cache  when accessing that memory location.  All you need to make sure is to have the SMP bit set in the A.CTLR register and have the SCU enabled.

0 Kudos
8 Replies
Voyager
Voyager
211 Views
Registered: ‎04-13-2015

Re: STREX instruction writes to memory but indicates failure

Jump to solution

@mberemand 

You are missing a conditional on the strex.

The sequence with ldrex / strex is the following:

1 - ldrex reads the memory space (you can use the value read it to see it's an OK value) and at the same time it tries to acquire a lock on all memory accesses.

2 - Two things can happen

 2a - it got the lock --- strex will write to the memory and remove the lock

 2b - it did not get the lock - strex will write to the memory and remove the lock......... this is bad as the lock wasn't acquired

Make your STREX instruction conditional with STREXEQ as the LDREX sets the zero flag when it gets the lock.

0 Kudos
Voyager
Voyager
202 Views
Registered: ‎04-13-2015

Re: STREX instruction writes to memory but indicates failure

Jump to solution

@mberemand 

--- correction:  ldrex does not report if it has the lock. You need to check the value read by ldrex and compare it to set the condition for strex, e.g. When the unlock value in memory is 0 for example:

TryLock:

   ldrex r0, [r1]

   cmp r0, #0

   strexeq r0, r2, [r1]

   cmpeq r0, #0

   bne TryLock

 

0 Kudos
Participant mberemand
Participant
189 Views
Registered: ‎10-22-2018

Re: STREX instruction writes to memory but indicates failure

Jump to solution

I should clarify; I did not write the assembly shown. This is the test_and_set() function in atomic.h.

I'm thinking that the issue has to do with the attributes for this region of memory. Right now I'm setting it to 0x11de2 (sharable, non-caching, domain 0b1111). I previously tried 0x14de2 which I think is identical. The lock acquisition works if I leave the TLB attributes at their default value but I need to have caching disabled since this region is shared between the CPUs.

0 Kudos
Voyager
Voyager
172 Views
Registered: ‎04-13-2015

Re: STREX instruction writes to memory but indicates failure

Jump to solution

@mberemand 

I do know when the cache is not enable the LDREX / STREX don't work.  I cannot confirm if with the cache enable and the memory access set as non-cached it's the same.

As for making the region non-cached because both CPUs are sharing it, there is no needs for that.  The cache is coherent meaning when one CPU update a memory location, although it could remains in the cache, the other CPU  will get the updated value copied into its cache  when accessing that memory location.  All you need to make sure is to have the SMP bit set in the A.CTLR register and have the SCU enabled.

0 Kudos
Participant mberemand
Participant
144 Views
Registered: ‎10-22-2018

Re: STREX instruction writes to memory but indicates failure

Jump to solution

@ericv

What implications does enabling cache coherency have? The CPUs are in an AMP configuration. The applications I'm running will need to share a small portion of DDR memory but otherwise regions should be dedicated to one CPU and completely inaccessible to the other.

I'm reading the Cortex A9 documentation from ARM regarding the SCU and ACTLR but I'm afraid I'm not grasping all of the concepts.

The STREX instruction executes successfully if both sharing and caching are disabled (TLB attributes 0x1de2) but that certainly isn't the right approach.

0 Kudos
Voyager
Voyager
135 Views
Registered: ‎04-13-2015

Re: STREX instruction writes to memory but indicates failure

Jump to solution

@mberemand 

The cache coherency doesn't really create problems.  As you desire to have exclusive memory assigned to each cores then it's only a matter of to use one MMU table per core and set the "off-limit" memory areas to invalid (a value of 0x00000000 does that).

0 Kudos
Participant mberemand
Participant
120 Views
Registered: ‎10-22-2018

Re: STREX instruction writes to memory but indicates failure

Jump to solution

That's very helpful, I hadn't thought to use a value of 0. I think that just leaves one final question. Is there a way I can prevent the MMU table from being modified once I've set the desired values?

0 Kudos
Voyager
Voyager
111 Views
Registered: ‎04-13-2015

Re: STREX instruction writes to memory but indicates failure

Jump to solution

@mberemand 

That a good question... I never tried it but one way I can think of would be to locate the table in an invalid memory region. Will this work? Again never tried but the ARM doc seems to indicates the MMU reads the table and then uses that info to validate memory access requets.  That seems to indicate the MMU, when accessing the table, ignores if is in an invalid region. But .... when the table is in cached memory instead of non-cached a MMU register bit must be set to inform the MMU of that.

0 Kudos