Received: by 2002:ac0:a581:0:0:0:0:0 with SMTP id m1-v6csp3027060imm; Sun, 1 Jul 2018 10:34:47 -0700 (PDT) X-Google-Smtp-Source: ADUXVKJidBPit1rUKMIwrtvcmSkj8pBA2ToRtkaOHOfVfFu4Yau8Ig+QVKzo55FGu4SZR2FARdxC X-Received: by 2002:a17:902:6f02:: with SMTP id w2-v6mr22381043plk.216.1530466486988; Sun, 01 Jul 2018 10:34:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1530466486; cv=none; d=google.com; s=arc-20160816; b=F7Zrdc/Y6XywZJ0Z9ZKg7TrlvC3ijsRIg9pWBJru957e+s9qENz+DKuyeP6kKs+Vi1 eq/TAipQUyuSBcYmjEn6m35kBVwfJi/g/4dfn3lzYj1+pobodPv8O+Kw6JSa5+h8URDi SQzqAhOCdo90lQHqwNJBGvwJV23LpecID24MYPZIMWnmf4Zt5O/jASwExsSMwPQmtWuv R6wJxF0rrzrvuyTWsgbiMX+eKntIL0MmzCVIxhOauB15+2gqrd5A+yaF8nLdLhfB7Xvw 4eejBV/1MtE/KsBQluiyiS2YdqW13T5Kru2sQiJp+FuxJAcdnkjzE8wYC+QojwNZh1Pt 7UjA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=9rvGEOxBT4ZcV6F4gO+g2KVrNeE4PHWd2FEMnJqsBFE=; b=ypzneg8Mmpj/La/3O3PcvZF0LlLXXZ1wf3g9Z7pZ/ixLpULpdynfpUCbhZD605mHYF XOF+KVyKZW86/accKaTOxJcSiXduAFuvIh2OtUguTrq4Pwdhu/bzl9NOrlnPyRrZwx5W SMAWinf/l6nJjeOkbcsY0oJMKSgYFMMqYolWH9mVXYVdFcu33Fo1o7IUuRjLjvGnRBBj 1mT3nTArza7UD40F+dra/RJszq+yrxbWRhRoPr7+1Ntlq5URpG8ER6x8KV+HP8DKsWOs rtozcdXMc1z2jKTdPre1SoT+1fJ2QS7Ep0mPn3tBhlgUl+f6I389LLwl+jYhYZmAalzh ND+g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q185-v6si13985462pfb.216.2018.07.01.10.34.32; Sun, 01 Jul 2018 10:34:46 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934129AbeGARcu (ORCPT + 99 others); Sun, 1 Jul 2018 13:32:50 -0400 Received: from smtp2200-217.mail.aliyun.com ([121.197.200.217]:44544 "EHLO smtp2200-217.mail.aliyun.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1031403AbeGARcR (ORCPT ); Sun, 1 Jul 2018 13:32:17 -0400 X-Alimail-AntiSpam: AC=CONTINUE;BC=0.0744162|-1;CH=green;FP=0|0|0|0|0|-1|-1|-1;HT=e02c03272;MF=ren_guo@c-sky.com;NM=1;PH=DS;RN=12;RT=12;SR=0;TI=SMTPD_---.CKwjpWO_1530466296; Received: from localhost(mailfrom:ren_guo@c-sky.com fp:SMTPD_---.CKwjpWO_1530466296) by smtp.aliyun-inc.com(10.147.41.178); Mon, 02 Jul 2018 01:31:36 +0800 From: Guo Ren To: linux-arch@vger.kernel.org, linux-kernel@vger.kernel.org, tglx@linutronix.de, daniel.lezcano@linaro.org, jason@lakedaemon.net, arnd@arndb.de Cc: c-sky_gcc_upstream@c-sky.com, gnu-csky@mentor.com, thomas.petazzoni@bootlin.com, wbx@uclibc-ng.org, ren_guo@c-sky.com, green.hu@gmail.com Subject: [PATCH V2 11/19] csky: Atomic operations Date: Mon, 2 Jul 2018 01:30:14 +0800 Message-Id: <860b8db036b33d7b3648cb1f4ec827a53dc1a01b.1530465326.git.ren_guo@c-sky.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Signed-off-by: Guo Ren --- arch/csky/include/asm/cmpxchg.h | 68 +++++++++++++ arch/csky/include/asm/spinlock.h | 174 +++++++++++++++++++++++++++++++++ arch/csky/include/asm/spinlock_types.h | 20 ++++ arch/csky/kernel/atomic.S | 87 +++++++++++++++++ 4 files changed, 349 insertions(+) create mode 100644 arch/csky/include/asm/cmpxchg.h create mode 100644 arch/csky/include/asm/spinlock.h create mode 100644 arch/csky/include/asm/spinlock_types.h create mode 100644 arch/csky/kernel/atomic.S diff --git a/arch/csky/include/asm/cmpxchg.h b/arch/csky/include/asm/cmpxchg.h new file mode 100644 index 0000000..1c30a28 --- /dev/null +++ b/arch/csky/include/asm/cmpxchg.h @@ -0,0 +1,68 @@ +#ifndef __ASM_CSKY_CMPXCHG_H +#define __ASM_CSKY_CMPXCHG_H + +#ifdef CONFIG_CPU_HAS_LDSTEX +#include +#include + +#define __xchg(new, ptr, size) \ +({ \ + __typeof__(ptr) __ptr = (ptr); \ + __typeof__(new) __new = (new); \ + __typeof__(*(ptr)) __ret; \ + unsigned long tmp; \ + switch (size) { \ + case 4: \ + asm volatile ( \ + "1: ldex.w %0, (%3) \n" \ + " mov %1, %2 \n" \ + " stex.w %1, (%3) \n" \ + " bez %1, 1b \n" \ + : "=&r" (__ret), "=&r" (tmp) \ + : "r" (__new), "r"(__ptr) \ + : "memory"); \ + smp_mb(); \ + break; \ + default: \ + BUILD_BUG(); \ + } \ + __ret; \ +}) + +#define xchg(ptr, x) (__xchg((x), (ptr), sizeof(*(ptr)))) + +#define __cmpxchg(ptr, old, new, size) \ +({ \ + __typeof__(ptr) __ptr = (ptr); \ + __typeof__(new) __new = (new); \ + __typeof__(new) __tmp; \ + __typeof__(old) __old = (old); \ + __typeof__(*(ptr)) __ret; \ + switch (size) { \ + case 4: \ + asm volatile ( \ + "1: ldex.w %0, (%3) \n" \ + " cmpne %0, %4 \n" \ + " bt 2f \n" \ + " mov %1, %2 \n" \ + " stex.w %1, (%3) \n" \ + " bez %1, 1b \n" \ + "2: \n" \ + : "=&r" (__ret), "=&r" (__tmp) \ + : "r" (__new), "r"(__ptr), "r"(__old) \ + : "memory"); \ + smp_mb(); \ + break; \ + default: \ + BUILD_BUG(); \ + } \ + __ret; \ +}) + +#define cmpxchg(ptr, o, n) \ + (__cmpxchg((ptr), (o), (n), sizeof(*(ptr)))) +#else +#include +#endif + +#endif /* __ASM_CSKY_CMPXCHG_H */ diff --git a/arch/csky/include/asm/spinlock.h b/arch/csky/include/asm/spinlock.h new file mode 100644 index 0000000..ca10d0e --- /dev/null +++ b/arch/csky/include/asm/spinlock.h @@ -0,0 +1,174 @@ +#ifndef __ASM_CSKY_SPINLOCK_H +#define __ASM_CSKY_SPINLOCK_H + +#include +#include + +#define arch_spin_is_locked(x) (READ_ONCE((x)->lock) != 0) + +/****** spin lock/unlock/trylock ******/ +static inline void arch_spin_lock(arch_spinlock_t *lock) +{ + unsigned int *p = &lock->lock; + unsigned int tmp; + + asm volatile ( + "1: ldex.w %0, (%1) \n" + " bnez %0, 1b \n" + " movi %0, 1 \n" + " stex.w %0, (%1) \n" + " bez %0, 1b \n" + : "=&r" (tmp) + : "r"(p) + : "memory"); + smp_mb(); +} + +static inline void arch_spin_unlock(arch_spinlock_t *lock) +{ + unsigned int *p = &lock->lock; + unsigned int tmp; + + smp_mb(); + asm volatile ( + "1: ldex.w %0, (%1) \n" + " movi %0, 0 \n" + " stex.w %0, (%1) \n" + " bez %0, 1b \n" + : "=&r" (tmp) + : "r"(p) + : "memory"); +} + +static inline int arch_spin_trylock(arch_spinlock_t *lock) +{ + unsigned int *p = &lock->lock; + unsigned int tmp; + + asm volatile ( + "1: ldex.w %0, (%1) \n" + " bnez %0, 2f \n" + " movi %0, 1 \n" + " stex.w %0, (%1) \n" + " bez %0, 1b \n" + " movi %0, 0 \n" + "2: \n" + : "=&r" (tmp) + : "r"(p) + : "memory"); + smp_mb(); + + return !tmp; +} + +/****** read lock/unlock/trylock ******/ +static inline void arch_read_lock(arch_rwlock_t *lock) +{ + unsigned int *p = &lock->lock; + unsigned int tmp; + + asm volatile ( + "1: ldex.w %0, (%1) \n" + " blz %0, 1b \n" + " addi %0, 1 \n" + " stex.w %0, (%1) \n" + " bez %0, 1b \n" + : "=&r" (tmp) + : "r"(p) + : "memory"); + smp_mb(); +} + +static inline void arch_read_unlock(arch_rwlock_t *lock) +{ + unsigned int *p = &lock->lock; + unsigned int tmp; + + smp_mb(); + asm volatile ( + "1: ldex.w %0, (%1) \n" + " subi %0, 1 \n" + " stex.w %0, (%1) \n" + " bez %0, 1b \n" + : "=&r" (tmp) + : "r"(p) + : "memory"); +} + +static inline int arch_read_trylock(arch_rwlock_t *lock) +{ + unsigned int *p = &lock->lock; + unsigned int tmp; + + asm volatile ( + "1: ldex.w %0, (%1) \n" + " blz %0, 2f \n" + " addi %0, 1 \n" + " stex.w %0, (%1) \n" + " bez %0, 1b \n" + " movi %0, 0 \n" + "2: \n" + : "=&r" (tmp) + : "r"(p) + : "memory"); + smp_mb(); + + return !tmp; +} + +/****** write lock/unlock/trylock ******/ +static inline void arch_write_lock(arch_rwlock_t *lock) +{ + unsigned int *p = &lock->lock; + unsigned int tmp; + + asm volatile ( + "1: ldex.w %0, (%1) \n" + " bnez %0, 1b \n" + " subi %0, 1 \n" + " stex.w %0, (%1) \n" + " bez %0, 1b \n" + : "=&r" (tmp) + : "r"(p) + : "memory"); + smp_mb(); +} + +static inline void arch_write_unlock(arch_rwlock_t *lock) +{ + unsigned int *p = &lock->lock; + unsigned int tmp; + + smp_mb(); + asm volatile ( + "1: ldex.w %0, (%1) \n" + " movi %0, 0 \n" + " stex.w %0, (%1) \n" + " bez %0, 1b \n" + : "=&r" (tmp) + : "r"(p) + : "memory"); +} + +static inline int arch_write_trylock(arch_rwlock_t *lock) +{ + unsigned int *p = &lock->lock; + unsigned int tmp; + + asm volatile ( + "1: ldex.w %0, (%1) \n" + " bnez %0, 2f \n" + " subi %0, 1 \n" + " stex.w %0, (%1) \n" + " bez %0, 1b \n" + " movi %0, 0 \n" + "2: \n" + : "=&r" (tmp) + : "r"(p) + : "memory"); + smp_mb(); + + return !tmp; +} + +#endif /* __ASM_CSKY_SPINLOCK_H */ diff --git a/arch/csky/include/asm/spinlock_types.h b/arch/csky/include/asm/spinlock_types.h new file mode 100644 index 0000000..ea890ef --- /dev/null +++ b/arch/csky/include/asm/spinlock_types.h @@ -0,0 +1,20 @@ +#ifndef __ASM_CSKY_SPINLOCK_TYPES_H +#define __ASM_CSKY_SPINLOCK_TYPES_H + +#ifndef __LINUX_SPINLOCK_TYPES_H +# error "please don't include this file directly" +#endif + +typedef struct { + unsigned int lock; +} arch_spinlock_t; + +#define __ARCH_SPIN_LOCK_UNLOCKED { 0 } + +typedef struct { + unsigned int lock; +} arch_rwlock_t; + +#define __ARCH_RW_LOCK_UNLOCKED { 0 } + +#endif diff --git a/arch/csky/kernel/atomic.S b/arch/csky/kernel/atomic.S new file mode 100644 index 0000000..95ae696 --- /dev/null +++ b/arch/csky/kernel/atomic.S @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. +#include +#include + +.text + +/* + * int csky_cmpxchg(int oldval, int newval, int *ptr) + * + * If *ptr != oldval && return 1, + * else *ptr = newval return 0. + */ +#ifdef CONFIG_CPU_HAS_LDSTEX +ENTRY(csky_cmpxchg) + USPTOKSP + mfcr a3, epc + INCTRAP a3 + + subi sp, 8 + stw a3, (sp, 0) + mfcr a3, epsr + stw a3, (sp, 4) + + psrset ee +1: + ldex a3, (a2) + cmpne a0, a3 + bt16 2f + mov a3, a1 + stex a3, (a2) + bez a3, 1b +2: + sync.is + mvc a0 + ldw a3, (sp, 0) + mtcr a3, epc + ldw a3, (sp, 4) + mtcr a3, epsr + addi sp, 8 + KSPTOUSP + rte +END(csky_cmpxchg) +#else +ENTRY(csky_cmpxchg) + USPTOKSP + mfcr a3, epc + INCTRAP a3 + + subi sp, 8 + stw a3, (sp, 0) + mfcr a3, epsr + stw a3, (sp, 4) + + psrset ee +1: + ldw a3, (a2) + cmpne a0, a3 + bt16 3f +2: + stw a1, (a2) +3: + mvc a0 + ldw a3, (sp, 0) + mtcr a3, epc + ldw a3, (sp, 4) + mtcr a3, epsr + addi sp, 8 + KSPTOUSP + rte +END(csky_cmpxchg) + +/* + * Called from tlbmodified exception + */ +ENTRY(csky_cmpxchg_fixup) + mfcr a0, epc + lrw a1, 2b + cmpne a1, a0 + bt 1f + subi a1, (2b - 1b) + stw a1, (sp, LSAVE_PC) +1: + rts +END(csky_cmpxchg_fixup) +#endif + -- 2.7.4