ARM atomic question
Olivier Houchard
mlfbsd at ci0.org
Tue Mar 24 14:26:18 PDT 2009
Hi Mark,
On Tue, Mar 24, 2009 at 04:05:51PM -0500, Mark Tinguely wrote:
>
> I am rewriting the existing ARM atomic instruction for the new ldrex/strex
> in the ARMv6 architecture.
>
That's great. I really want to get armv6 support.
> I have 3 questions for atomic_fetchadd_32():
>
> #ifdef KERNEL
> static __inline uint32_t
> atomic_fetchadd_32(volatile uint32_t *p, uint32_t v)
> {
> uint32_t value;
>
> __with_interrupts_disabled(
> {
> value = *p;
> *p += v;
> });
> return (value);
> }
>
> #else /* !_KERNEL */
>
> static __inline uint32_t
> atomic_fetchadd_32(volatile uint32_t *p, uint32_t v)
> {
> uint32_t start, ras_start = ARM_RAS_START;
>
> __asm __volatile("1:\n"
> "adr %1, 1b\n"
> "str %1, [%0]\n"
> "adr %1, 2f\n"
> "str %1, [%0, #4]\n"
> "ldr %1, [%2]\n"
>
> 1) how does this make it atomic? no one reads ras_start or ras_end
> to verify that it has not changed since I set it. This applies
> to all non-kernel atomic commands.
>
It is done by the kernel, when a trap occurs. They are issues with that
code, though, which should be worked on.
> "add %1, %1, %3\n"
> ^^
> 2) start is now (*p + v) not *p. It will return the wrong value
> compared to the kernel version.
>
True, that's a bug.
> "str %0, [%2]\n"
> ^^
> 3) *p is assigned the ras_start address.
>
Another bug. Guess we've been lucky not to run into it. Thanks !
> "2:\n"
> "mov %3, #0\n"
> "str %3, [%0]\n"
> "mov %3, #0xffffffff\n"
> "str %3, [%0, #4]\n"
> : "+r" (ras_start), "=r" (start), "+r" (p), "+r" (v)
> : : "memory");
> return (start);
> #endif
>
> 4) Is there a list of atomic commands that should be implemented?
>
All those described in atomic(9) (except 64bits operations).
Regards,
Olivier
More information about the freebsd-arm
mailing list