From owner-freebsd-arm@freebsd.org Mon Nov 9 08:05:06 2015 Return-Path: Delivered-To: freebsd-arm@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D4B44A29B35 for ; Mon, 9 Nov 2015 08:05:06 +0000 (UTC) (envelope-from gabdelmalik@uniridge.com.au) Received: from mail.uniridge.com.au (ec2-54-206-17-100.ap-southeast-2.compute.amazonaws.com [54.206.17.100]) by mx1.freebsd.org (Postfix) with ESMTP id 637DD1038 for ; Mon, 9 Nov 2015 08:05:05 +0000 (UTC) (envelope-from gabdelmalik@uniridge.com.au) Received: from [192.168.11.50] (ip-192-168-11-50.ap-southeast-2.compute.internal [192.168.11.50]) by mail.uniridge.com.au (Postfix) with ESMTP id 6D84F4A6C; Mon, 9 Nov 2015 19:04:58 +1100 (EST) Subject: Re: atomic_testandset_int seems unimplemented To: Konstantin Belousov References: <563DA3E8.2060802@uniridge.com.au> <20151107113011.GW2257@kib.kiev.ua> <563DE43D.7030107@uniridge.com.au> Cc: freebsd-arm@freebsd.org From: George Abdelmalik Organization: Uniridge Pty Ltd Message-ID: <564053A9.3000604@uniridge.com.au> Date: Mon, 9 Nov 2015 19:04:57 +1100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <563DE43D.7030107@uniridge.com.au> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-BeenThere: freebsd-arm@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "Porting FreeBSD to ARM processors." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 09 Nov 2015 08:05:07 -0000 On 07/11/15 22:45, George Abdelmalik wrote: > On 07/11/15 22:30, Konstantin Belousov wrote: >> On Sat, Nov 07, 2015 at 06:10:32PM +1100, George Abdelmalik wrote: >>> Hi, >>> >>> My reading of atomic(9) implies that the atomic_testandset_* family of >>> functions should be present >>> on the arm architecture, however I don't see any evidence of it in any >>> of the expected locations, >>> ./sys/arm/include/atomic-v4.h >>> ./sys/arm/include/atomic-v6.h >>> ./sys/arm/include/atomic.h >>> >>> Is there some impediment within the architecture which doesn't make >>> that >>> semantic possible or is >>> it just that there is no in-tree consumer yet? >> No consumers, apparently. testandset has somewhat rarely needed >> semantic, >> and readandclear semantic is not complimentary, to confuse the users >> even >> more. >> >>> Any thoughts on this matter would be appreciated, or better yet a >>> possible implementation - sadly for >>> me assembly is not my strength. >> Below is the patch for ARMv6. I did not tested the _64 implementation, >> and I also doubt that we run in big endian mode for ARMv6 at all. >> Do you also need an implementation for ARMv5 ? > No I don't need ARMv5, my target is a Xilinx Zynq SOC which is > ARMv7 that we will only run in little endian mode. > > Thanks for the below patch. I will try it out tomorrow and report > back my experience. > > George. >> >> diff --git a/sys/arm/include/atomic-v6.h b/sys/arm/include/atomic-v6.h >> index d22f7e1..9ee8043 100644 >> --- a/sys/arm/include/atomic-v6.h >> +++ b/sys/arm/include/atomic-v6.h >> @@ -593,6 +593,60 @@ atomic_store_rel_long(volatile u_long *p, u_long v) >> *p = v; >> } >> +static __inline int >> +atomic_testandset_32(volatile uint32_t *p, u_int v) >> +{ >> + uint32_t tmp, tmp2, res, mask; >> + >> + mask = 1u << (v & 0x1f); >> + tmp = tmp2 = 0; >> + __asm __volatile( >> + "1: ldrex %0, [%3] \n" >> + " orr %1, %0, %4 \n" >> + " strex %2, %1, [%3] \n" >> + " cmp %2, #0 \n" >> + " it ne \n" >> + " bne 1b \n" >> + : "=&r" (res), "=&r" (tmp), "=&r" (tmp2), "+&r" (p) >> + : "r" (mask) >> + : "cc", "memory"); >> + return ((res & mask) != 0); >> +} >> + >> +static __inline int >> +atomic_testandset_int(volatile u_int *p, u_int v) >> +{ >> + >> + return (atomic_testandset_32((volatile uint32_t *)p, v)); >> +} >> + >> +static __inline int >> +atomic_testandset_long(volatile u_long *p, u_int v) >> +{ >> + >> + return (atomic_testandset_32((volatile uint32_t *)p, v)); >> +} >> + >> +static __inline int >> +atomic_testandset_64(volatile uint64_t *p, u_int v) >> +{ >> + volatile uint32_t *p32; >> + >> + p32 = (volatile uint32_t *)p; >> +#if BYTE_ORDER == LITTLE_ENDIAN >> + if (v >= 32) { >> + v &= 0x1f; >> + p32++; >> + } >> +#else >> + if (v >= 32) >> + v &= 0x1f; >> + else >> + p32++; >> +#endif >> + return (atomic_testandset_32(p32, v)); >> +} >> + >> #undef ATOMIC_ACQ_REL >> #undef ATOMIC_ACQ_REL_LONG > > _______________________________________________ > freebsd-arm@freebsd.org mailing list > https://lists.freebsd.org/mailman/listinfo/freebsd-arm > To unsubscribe, send any mail to "freebsd-arm-unsubscribe@freebsd.org" Hi Konstantin, Thanks again for this. I've not yet run it on my Zedboard, due to unrelated issues of my own making, although it compiles fine into my project. It would be great to see it in the tree whenever you get the chance. Kindest regards, George. -- George Abdelmalik Director Principal Software Engineer Uniridge Pty Ltd http://www.uniridge.com.au/