From owner-freebsd-arm@FreeBSD.ORG Tue Mar 24 21:50:03 2009 Return-Path: Delivered-To: freebsd-arm@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B54A3106564A for ; Tue, 24 Mar 2009 21:50:03 +0000 (UTC) (envelope-from imp@bsdimp.com) Received: from harmony.bsdimp.com (bsdimp.com [199.45.160.85]) by mx1.freebsd.org (Postfix) with ESMTP id 6FB1C8FC22 for ; Tue, 24 Mar 2009 21:50:03 +0000 (UTC) (envelope-from imp@bsdimp.com) Received: from localhost (localhost [127.0.0.1]) by harmony.bsdimp.com (8.14.2/8.14.1) with ESMTP id n2OLkFLt099943; Tue, 24 Mar 2009 15:46:15 -0600 (MDT) (envelope-from imp@bsdimp.com) Date: Tue, 24 Mar 2009 15:46:50 -0600 (MDT) Message-Id: <20090324.154650.-679995243.imp@bsdimp.com> To: tinguely@casselton.net From: "M. Warner Losh" In-Reply-To: <200903242105.n2OL5phe074750@casselton.net> References: <200903242105.n2OL5phe074750@casselton.net> X-Mailer: Mew version 5.2 on Emacs 21.3 / Mule 5.0 (SAKAKI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Cc: freebsd-arm@FreeBSD.org Subject: Re: ARM atomic question X-BeenThere: freebsd-arm@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Porting FreeBSD to the StrongARM Processor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Mar 2009 21:50:04 -0000 In message: <200903242105.n2OL5phe074750@casselton.net> Mark Tinguely writes: : : I am rewriting the existing ARM atomic instruction for the new ldrex/strex : in the ARMv6 architecture. : : 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. The kernel looks at these addresses when it does a context switch. Since there are no atomic ops, and you can't disable interrupts in userland, we settle for the next worse thing: set critical sections that are restarted if the kernel interrupts them. : "add %1, %1, %3\n" : ^^ : 2) start is now (*p + v) not *p. It will return the wrong value : compared to the kernel version. : : "str %0, [%2]\n" : ^^ : 3) *p is assigned the ras_start address. That I'm not sure of... : "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? Someone else will have to answer this. Warner