Skip to content

Commit 1065766

Browse files
mips-hptsbogend
authored andcommitted
MIPS: rework local_t operation on MIPS64
+. remove "asm/war.h" since R10000_LLSC_WAR became a config option +. clean up Suggested-by: Maciej W. Rozycki <[email protected]> Signed-off-by: Huang Pei <[email protected]> Signed-off-by: Thomas Bogendoerfer <[email protected]>
1 parent 277c8cb commit 1065766

File tree

2 files changed

+32
-45
lines changed

2 files changed

+32
-45
lines changed

arch/mips/include/asm/asm.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include <asm/sgidefs.h>
2121
#include <asm/asm-eva.h>
22+
#include <asm/isa-rev.h>
2223

2324
#ifndef __VDSO__
2425
/*
@@ -211,6 +212,8 @@ symbol = value
211212
#define LONG_SUB sub
212213
#define LONG_SUBU subu
213214
#define LONG_L lw
215+
#define LONG_LL ll
216+
#define LONG_SC sc
214217
#define LONG_S sw
215218
#define LONG_SP swp
216219
#define LONG_SLL sll
@@ -236,6 +239,8 @@ symbol = value
236239
#define LONG_SUB dsub
237240
#define LONG_SUBU dsubu
238241
#define LONG_L ld
242+
#define LONG_LL lld
243+
#define LONG_SC scd
239244
#define LONG_S sd
240245
#define LONG_SP sdp
241246
#define LONG_SLL dsll
@@ -320,6 +325,19 @@ symbol = value
320325

321326
#define SSNOP sll zero, zero, 1
322327

328+
/*
329+
* Using a branch-likely instruction to check the result of an sc instruction
330+
* works around a bug present in R10000 CPUs prior to revision 3.0 that could
331+
* cause ll-sc sequences to execute non-atomically.
332+
*/
333+
#ifdef CONFIG_WAR_R10000_LLSC
334+
# define SC_BEQZ beqzl
335+
#elif MIPS_ISA_REV >= 6
336+
# define SC_BEQZ beqzc
337+
#else
338+
# define SC_BEQZ beqz
339+
#endif
340+
323341
#ifdef CONFIG_SGI_IP28
324342
/* Inhibit speculative stores to volatile (e.g.DMA) or invalid addresses. */
325343
#include <asm/cacheops.h>

arch/mips/include/asm/local.h

Lines changed: 14 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include <asm/asm.h>
99
#include <asm/cmpxchg.h>
1010
#include <asm/compiler.h>
11-
#include <asm/war.h>
11+
#include <asm/asm.h>
1212

1313
typedef struct
1414
{
@@ -32,34 +32,18 @@ static __inline__ long local_add_return(long i, local_t * l)
3232
{
3333
unsigned long result;
3434

35-
if (kernel_uses_llsc && IS_ENABLED(CONFIG_WAR_R10000_LLSC)) {
36-
unsigned long temp;
37-
38-
__asm__ __volatile__(
39-
" .set push \n"
40-
" .set arch=r4000 \n"
41-
__SYNC(full, loongson3_war) " \n"
42-
"1:" __LL "%1, %2 # local_add_return \n"
43-
__stringify(LONG_ADDU) " %0, %1, %3 \n"
44-
__SC "%0, %2 \n"
45-
" beqzl %0, 1b \n"
46-
" addu %0, %1, %3 \n"
47-
" .set pop \n"
48-
: "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
49-
: "Ir" (i), "m" (l->a.counter)
50-
: "memory");
51-
} else if (kernel_uses_llsc) {
35+
if (kernel_uses_llsc) {
5236
unsigned long temp;
5337

5438
__asm__ __volatile__(
5539
" .set push \n"
5640
" .set "MIPS_ISA_ARCH_LEVEL" \n"
57-
__SYNC(full, loongson3_war) " \n"
58-
"1:" __LL "%1, %2 # local_add_return \n"
41+
__SYNC(full, loongson3_war) " \n"
42+
"1:" __stringify(LONG_LL) " %1, %2 \n"
43+
__stringify(LONG_ADDU) " %0, %1, %3 \n"
44+
__stringify(LONG_SC) " %0, %2 \n"
45+
__stringify(SC_BEQZ) " %0, 1b \n"
5946
__stringify(LONG_ADDU) " %0, %1, %3 \n"
60-
__SC "%0, %2 \n"
61-
" beqz %0, 1b \n"
62-
" addu %0, %1, %3 \n"
6347
" .set pop \n"
6448
: "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
6549
: "Ir" (i), "m" (l->a.counter)
@@ -81,34 +65,19 @@ static __inline__ long local_sub_return(long i, local_t * l)
8165
{
8266
unsigned long result;
8367

84-
if (kernel_uses_llsc && IS_ENABLED(CONFIG_WAR_R10000_LLSC)) {
85-
unsigned long temp;
86-
87-
__asm__ __volatile__(
88-
" .set push \n"
89-
" .set arch=r4000 \n"
90-
__SYNC(full, loongson3_war) " \n"
91-
"1:" __LL "%1, %2 # local_sub_return \n"
92-
__stringify(LONG_SUBU) " %0, %1, %3 \n"
93-
__SC "%0, %2 \n"
94-
" beqzl %0, 1b \n"
95-
" subu %0, %1, %3 \n"
96-
" .set pop \n"
97-
: "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
98-
: "Ir" (i), "m" (l->a.counter)
99-
: "memory");
100-
} else if (kernel_uses_llsc) {
68+
if (kernel_uses_llsc) {
10169
unsigned long temp;
10270

10371
__asm__ __volatile__(
10472
" .set push \n"
10573
" .set "MIPS_ISA_ARCH_LEVEL" \n"
106-
__SYNC(full, loongson3_war) " \n"
107-
"1:" __LL "%1, %2 # local_sub_return \n"
74+
__SYNC(full, loongson3_war) " \n"
75+
"1:" __stringify(LONG_LL) " %1, %2 \n"
76+
__stringify(LONG_SUBU) " %0, %1, %3 \n"
77+
__stringify(LONG_SUBU) " %0, %1, %3 \n"
78+
__stringify(LONG_SC) " %0, %2 \n"
79+
__stringify(SC_BEQZ) " %0, 1b \n"
10880
__stringify(LONG_SUBU) " %0, %1, %3 \n"
109-
__SC "%0, %2 \n"
110-
" beqz %0, 1b \n"
111-
" subu %0, %1, %3 \n"
11281
" .set pop \n"
11382
: "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
11483
: "Ir" (i), "m" (l->a.counter)

0 commit comments

Comments
 (0)