0001
0002 #ifndef __MIPS_ASM_GINVT_H__
0003 #define __MIPS_ASM_GINVT_H__
0004
0005 #include <asm/mipsregs.h>
0006
0007 enum ginvt_type {
0008 GINVT_FULL,
0009 GINVT_VA,
0010 GINVT_MMID,
0011 };
0012
0013 #ifdef TOOLCHAIN_SUPPORTS_GINV
0014 # define _ASM_SET_GINV ".set ginv\n"
0015 # define _ASM_UNSET_GINV
0016 #else
0017 # define _ASM_SET_GINV \
0018 _ASM_MACRO_1R1I(ginvt, rs, type, \
0019 _ASM_INSN_IF_MIPS(0x7c0000bd | (__rs << 21) | (\\type << 8)) \
0020 _ASM_INSN32_IF_MM(0x0000717c | (__rs << 16) | (\\type << 9)))
0021 # define _ASM_UNSET_GINV ".purgem ginvt\n"
0022 #endif
0023
0024 static __always_inline void ginvt(unsigned long addr, enum ginvt_type type)
0025 {
0026 asm volatile(
0027 ".set push\n"
0028 _ASM_SET_GINV
0029 " ginvt %0, %1\n"
0030 _ASM_UNSET_GINV
0031 ".set pop"
0032 :
0033 : "r"(addr), "i"(type)
0034 : "memory");
0035 }
0036
0037 static inline void ginvt_full(void)
0038 {
0039 ginvt(0, GINVT_FULL);
0040 }
0041
0042 static inline void ginvt_va(unsigned long addr)
0043 {
0044 addr &= PAGE_MASK << 1;
0045 ginvt(addr, GINVT_VA);
0046 }
0047
0048 static inline void ginvt_mmid(void)
0049 {
0050 ginvt(0, GINVT_MMID);
0051 }
0052
0053 static inline void ginvt_va_mmid(unsigned long addr)
0054 {
0055 addr &= PAGE_MASK << 1;
0056 ginvt(addr, GINVT_VA | GINVT_MMID);
0057 }
0058
0059 #endif