ginvt.h 1.1 KB

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