Skip to content

Commit 5351138

Browse files
committed
MIPS: Add GINVT instruction helpers
Add a family of ginvt_* functions making it easy to emit a GINVT instruction to globally invalidate TLB entries. We make use of the _ASM_MACRO infrastructure to support emitting the instructions even if the assembler isn't new enough to support them natively. An associated STYPE_GINV definition & sync_ginv() function are added to emit a sync instruction of type 0x14, which operates as a completion barrier for these new GINVT (and GINVI) instructions. Signed-off-by: Paul Burton <paul.burton@mips.com> Cc: linux-mips@vger.kernel.org
1 parent 0b317c3 commit 5351138

File tree

4 files changed

+84
-0
lines changed

4 files changed

+84
-0
lines changed

arch/mips/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,8 @@ toolchain-crc := $(call cc-option-yn,$(mips-cflags) -Wa$(comma)-mcrc)
233233
cflags-$(toolchain-crc) += -DTOOLCHAIN_SUPPORTS_CRC
234234
toolchain-dsp := $(call cc-option-yn,$(mips-cflags) -Wa$(comma)-mdsp)
235235
cflags-$(toolchain-dsp) += -DTOOLCHAIN_SUPPORTS_DSP
236+
toolchain-ginv := $(call cc-option-yn,$(mips-cflags) -Wa$(comma)-mginv)
237+
cflags-$(toolchain-ginv) += -DTOOLCHAIN_SUPPORTS_GINV
236238

237239
#
238240
# Firmware support

arch/mips/include/asm/barrier.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,20 @@
105105
*/
106106
#define STYPE_SYNC_MB 0x10
107107

108+
/*
109+
* stype 0x14 - A completion barrier specific to global invalidations
110+
*
111+
* When a sync instruction of this type completes any preceding GINVI or GINVT
112+
* operation has been globalized & completed on all coherent CPUs. Anything
113+
* that the GINV* instruction should invalidate will have been invalidated on
114+
* all coherent CPUs when this instruction completes. It is implementation
115+
* specific whether the GINV* instructions themselves will ensure completion,
116+
* or this sync type will.
117+
*
118+
* In systems implementing global invalidates (ie. with Config5.GI == 2 or 3)
119+
* this sync type also requires that previous SYNCI operations have completed.
120+
*/
121+
#define STYPE_GINV 0x14
108122

109123
#ifdef CONFIG_CPU_HAS_SYNC
110124
#define __sync() \
@@ -222,6 +236,11 @@
222236
#define __smp_mb__before_atomic() __smp_mb__before_llsc()
223237
#define __smp_mb__after_atomic() smp_llsc_mb()
224238

239+
static inline void sync_ginv(void)
240+
{
241+
asm volatile("sync\t%0" :: "i"(STYPE_GINV));
242+
}
243+
225244
#include <asm-generic/barrier.h>
226245

227246
#endif /* __ASM_BARRIER_H */

arch/mips/include/asm/ginvt.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef __MIPS_ASM_GINVT_H__
3+
#define __MIPS_ASM_GINVT_H__
4+
5+
#include <asm/mipsregs.h>
6+
7+
enum ginvt_type {
8+
GINVT_FULL,
9+
GINVT_VA,
10+
GINVT_MMID,
11+
};
12+
13+
#ifdef TOOLCHAIN_SUPPORTS_GINV
14+
# define _ASM_SET_GINV ".set ginv\n"
15+
#else
16+
_ASM_MACRO_1R1I(ginvt, rs, type,
17+
_ASM_INSN_IF_MIPS(0x7c0000bd | (__rs << 21) | (\\type << 8))
18+
_ASM_INSN32_IF_MM(0x0000717c | (__rs << 16) | (\\type << 9)));
19+
# define _ASM_SET_GINV
20+
#endif
21+
22+
static inline void ginvt(unsigned long addr, enum ginvt_type type)
23+
{
24+
asm volatile(
25+
".set push\n"
26+
_ASM_SET_GINV
27+
" ginvt %0, %1\n"
28+
".set pop"
29+
: /* no outputs */
30+
: "r"(addr), "i"(type)
31+
: "memory");
32+
}
33+
34+
static inline void ginvt_full(void)
35+
{
36+
ginvt(0, GINVT_FULL);
37+
}
38+
39+
static inline void ginvt_va(unsigned long addr)
40+
{
41+
addr &= PAGE_MASK << 1;
42+
ginvt(addr, GINVT_VA);
43+
}
44+
45+
static inline void ginvt_mmid(void)
46+
{
47+
ginvt(0, GINVT_MMID);
48+
}
49+
50+
static inline void ginvt_va_mmid(unsigned long addr)
51+
{
52+
addr &= PAGE_MASK << 1;
53+
ginvt(addr, GINVT_VA | GINVT_MMID);
54+
}
55+
56+
#endif /* __MIPS_ASM_GINVT_H__ */

arch/mips/include/asm/mipsregs.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,6 +1247,13 @@ __asm__(".macro parse_r var r\n\t"
12471247
ENC \
12481248
".endm")
12491249

1250+
/* Instructions with 1 register operand & 1 immediate operand */
1251+
#define _ASM_MACRO_1R1I(OP, R1, I2, ENC) \
1252+
__asm__(".macro " #OP " " #R1 ", " #I2 "\n\t" \
1253+
"parse_r __" #R1 ", \\" #R1 "\n\t" \
1254+
ENC \
1255+
".endm")
1256+
12501257
/* Instructions with 2 register operands */
12511258
#define _ASM_MACRO_2R(OP, R1, R2, ENC) \
12521259
__asm__(".macro " #OP " " #R1 ", " #R2 "\n\t" \

0 commit comments

Comments
 (0)