From owner-freebsd-arm@FreeBSD.ORG Tue Mar 24 21:05:52 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 E71A81065688 for ; Tue, 24 Mar 2009 21:05:52 +0000 (UTC) (envelope-from tinguely@casselton.net) Received: from casselton.net (casselton.net [63.165.140.2]) by mx1.freebsd.org (Postfix) with ESMTP id A1A0E8FC0A for ; Tue, 24 Mar 2009 21:05:52 +0000 (UTC) (envelope-from tinguely@casselton.net) Received: from casselton.net (localhost [127.0.0.1]) by casselton.net (8.14.3/8.14.3) with ESMTP id n2OL5pTW074751 for ; Tue, 24 Mar 2009 16:05:51 -0500 (CDT) (envelope-from tinguely@casselton.net) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=casselton.net; s=ccnMail; t=1237928751; bh=W5KGy1dXTAUvyyfEbj6UgUFdPnl9TpW8tuVvTbJcfgs=; h=Date:From:Message-Id:To:Subject; b=CzF3lJJaR5B098yXHeD7YQxg+uPvqbKcSXVBhbvFSXOz0dG2P+5YyC0qTTML3Ze1W zfVw6bVredyC4W5g4s26D+LCfffdDeWFrpMzsFBNDtDJiNEfgrqDG+AjDS9bmvSayP jjbFWLSpedOqNWiaVzXjeyodgn93JZBY+dQexJCs= Received: (from tinguely@localhost) by casselton.net (8.14.3/8.14.2/Submit) id n2OL5phe074750 for freebsd-arm@freebsd.org; Tue, 24 Mar 2009 16:05:51 -0500 (CDT) (envelope-from tinguely) Date: Tue, 24 Mar 2009 16:05:51 -0500 (CDT) From: Mark Tinguely Message-Id: <200903242105.n2OL5phe074750@casselton.net> To: freebsd-arm@freebsd.org X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.1.10 (casselton.net [127.0.0.1]); Tue, 24 Mar 2009 16:05:51 -0500 (CDT) Subject: 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:05:54 -0000 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. "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. "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? --Mark Tinguely