Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
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         : /* no outputs */
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 /* __MIPS_ASM_GINVT_H__ */