tlb.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
  4. */
  5. #ifndef __ASM_TLB_H
  6. #define __ASM_TLB_H
  7. #include <linux/mm_types.h>
  8. #include <asm/cpu-features.h>
  9. #include <asm/loongarch.h>
  10. /*
  11. * TLB Invalidate Flush
  12. */
  13. static inline void tlbclr(void)
  14. {
  15. __asm__ __volatile__("tlbclr");
  16. }
  17. static inline void tlbflush(void)
  18. {
  19. __asm__ __volatile__("tlbflush");
  20. }
  21. /*
  22. * TLB R/W operations.
  23. */
  24. static inline void tlb_probe(void)
  25. {
  26. __asm__ __volatile__("tlbsrch");
  27. }
  28. static inline void tlb_read(void)
  29. {
  30. __asm__ __volatile__("tlbrd");
  31. }
  32. static inline void tlb_write_indexed(void)
  33. {
  34. __asm__ __volatile__("tlbwr");
  35. }
  36. static inline void tlb_write_random(void)
  37. {
  38. __asm__ __volatile__("tlbfill");
  39. }
  40. enum invtlb_ops {
  41. /* Invalid all tlb */
  42. INVTLB_ALL = 0x0,
  43. /* Invalid current tlb */
  44. INVTLB_CURRENT_ALL = 0x1,
  45. /* Invalid all global=1 lines in current tlb */
  46. INVTLB_CURRENT_GTRUE = 0x2,
  47. /* Invalid all global=0 lines in current tlb */
  48. INVTLB_CURRENT_GFALSE = 0x3,
  49. /* Invalid global=0 and matched asid lines in current tlb */
  50. INVTLB_GFALSE_AND_ASID = 0x4,
  51. /* Invalid addr with global=0 and matched asid in current tlb */
  52. INVTLB_ADDR_GFALSE_AND_ASID = 0x5,
  53. /* Invalid addr with global=1 or matched asid in current tlb */
  54. INVTLB_ADDR_GTRUE_OR_ASID = 0x6,
  55. /* Invalid matched gid in guest tlb */
  56. INVGTLB_GID = 0x9,
  57. /* Invalid global=1, matched gid in guest tlb */
  58. INVGTLB_GID_GTRUE = 0xa,
  59. /* Invalid global=0, matched gid in guest tlb */
  60. INVGTLB_GID_GFALSE = 0xb,
  61. /* Invalid global=0, matched gid and asid in guest tlb */
  62. INVGTLB_GID_GFALSE_ASID = 0xc,
  63. /* Invalid global=0 , matched gid, asid and addr in guest tlb */
  64. INVGTLB_GID_GFALSE_ASID_ADDR = 0xd,
  65. /* Invalid global=1 , matched gid, asid and addr in guest tlb */
  66. INVGTLB_GID_GTRUE_ASID_ADDR = 0xe,
  67. /* Invalid all gid gva-->gpa guest tlb */
  68. INVGTLB_ALLGID_GVA_TO_GPA = 0x10,
  69. /* Invalid all gid gpa-->hpa tlb */
  70. INVTLB_ALLGID_GPA_TO_HPA = 0x11,
  71. /* Invalid all gid tlb, including gva-->gpa and gpa-->hpa */
  72. INVTLB_ALLGID = 0x12,
  73. /* Invalid matched gid gva-->gpa guest tlb */
  74. INVGTLB_GID_GVA_TO_GPA = 0x13,
  75. /* Invalid matched gid gpa-->hpa tlb */
  76. INVTLB_GID_GPA_TO_HPA = 0x14,
  77. /* Invalid matched gid tlb,including gva-->gpa and gpa-->hpa */
  78. INVTLB_GID_ALL = 0x15,
  79. /* Invalid matched gid and addr gpa-->hpa tlb */
  80. INVTLB_GID_ADDR = 0x16,
  81. };
  82. static __always_inline void invtlb(u32 op, u32 info, u64 addr)
  83. {
  84. __asm__ __volatile__(
  85. "invtlb %0, %1, %2\n\t"
  86. :
  87. : "i"(op), "r"(info), "r"(addr)
  88. : "memory"
  89. );
  90. }
  91. static __always_inline void invtlb_addr(u32 op, u32 info, u64 addr)
  92. {
  93. BUILD_BUG_ON(!__builtin_constant_p(info) || info != 0);
  94. __asm__ __volatile__(
  95. "invtlb %0, $zero, %1\n\t"
  96. :
  97. : "i"(op), "r"(addr)
  98. : "memory"
  99. );
  100. }
  101. static __always_inline void invtlb_info(u32 op, u32 info, u64 addr)
  102. {
  103. BUILD_BUG_ON(!__builtin_constant_p(addr) || addr != 0);
  104. __asm__ __volatile__(
  105. "invtlb %0, %1, $zero\n\t"
  106. :
  107. : "i"(op), "r"(info)
  108. : "memory"
  109. );
  110. }
  111. static __always_inline void invtlb_all(u32 op, u32 info, u64 addr)
  112. {
  113. BUILD_BUG_ON(!__builtin_constant_p(info) || info != 0);
  114. BUILD_BUG_ON(!__builtin_constant_p(addr) || addr != 0);
  115. __asm__ __volatile__(
  116. "invtlb %0, $zero, $zero\n\t"
  117. :
  118. : "i"(op)
  119. : "memory"
  120. );
  121. }
  122. static void tlb_flush(struct mmu_gather *tlb);
  123. #define tlb_flush tlb_flush
  124. #include <asm-generic/tlb.h>
  125. static inline void tlb_flush(struct mmu_gather *tlb)
  126. {
  127. struct vm_area_struct vma;
  128. vma.vm_mm = tlb->mm;
  129. vm_flags_init(&vma, 0);
  130. if (tlb->fullmm) {
  131. flush_tlb_mm(tlb->mm);
  132. return;
  133. }
  134. flush_tlb_range(&vma, tlb->start, tlb->end);
  135. }
  136. extern void handle_tlb_load(void);
  137. extern void handle_tlb_store(void);
  138. extern void handle_tlb_modify(void);
  139. extern void handle_tlb_refill(void);
  140. extern void handle_tlb_protect(void);
  141. extern void handle_tlb_load_ptw(void);
  142. extern void handle_tlb_store_ptw(void);
  143. extern void handle_tlb_modify_ptw(void);
  144. extern void dump_tlb_all(void);
  145. extern void dump_tlb_regs(void);
  146. #endif /* __ASM_TLB_H */