123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- /* SPDX-License-Identifier: GPL-2.0 */
- /*
- * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
- */
- #ifndef __ASM_TLB_H
- #define __ASM_TLB_H
- #include <linux/mm_types.h>
- #include <asm/cpu-features.h>
- #include <asm/loongarch.h>
- /*
- * TLB Invalidate Flush
- */
- static inline void tlbclr(void)
- {
- __asm__ __volatile__("tlbclr");
- }
- static inline void tlbflush(void)
- {
- __asm__ __volatile__("tlbflush");
- }
- /*
- * TLB R/W operations.
- */
- static inline void tlb_probe(void)
- {
- __asm__ __volatile__("tlbsrch");
- }
- static inline void tlb_read(void)
- {
- __asm__ __volatile__("tlbrd");
- }
- static inline void tlb_write_indexed(void)
- {
- __asm__ __volatile__("tlbwr");
- }
- static inline void tlb_write_random(void)
- {
- __asm__ __volatile__("tlbfill");
- }
- enum invtlb_ops {
- /* Invalid all tlb */
- INVTLB_ALL = 0x0,
- /* Invalid current tlb */
- INVTLB_CURRENT_ALL = 0x1,
- /* Invalid all global=1 lines in current tlb */
- INVTLB_CURRENT_GTRUE = 0x2,
- /* Invalid all global=0 lines in current tlb */
- INVTLB_CURRENT_GFALSE = 0x3,
- /* Invalid global=0 and matched asid lines in current tlb */
- INVTLB_GFALSE_AND_ASID = 0x4,
- /* Invalid addr with global=0 and matched asid in current tlb */
- INVTLB_ADDR_GFALSE_AND_ASID = 0x5,
- /* Invalid addr with global=1 or matched asid in current tlb */
- INVTLB_ADDR_GTRUE_OR_ASID = 0x6,
- /* Invalid matched gid in guest tlb */
- INVGTLB_GID = 0x9,
- /* Invalid global=1, matched gid in guest tlb */
- INVGTLB_GID_GTRUE = 0xa,
- /* Invalid global=0, matched gid in guest tlb */
- INVGTLB_GID_GFALSE = 0xb,
- /* Invalid global=0, matched gid and asid in guest tlb */
- INVGTLB_GID_GFALSE_ASID = 0xc,
- /* Invalid global=0 , matched gid, asid and addr in guest tlb */
- INVGTLB_GID_GFALSE_ASID_ADDR = 0xd,
- /* Invalid global=1 , matched gid, asid and addr in guest tlb */
- INVGTLB_GID_GTRUE_ASID_ADDR = 0xe,
- /* Invalid all gid gva-->gpa guest tlb */
- INVGTLB_ALLGID_GVA_TO_GPA = 0x10,
- /* Invalid all gid gpa-->hpa tlb */
- INVTLB_ALLGID_GPA_TO_HPA = 0x11,
- /* Invalid all gid tlb, including gva-->gpa and gpa-->hpa */
- INVTLB_ALLGID = 0x12,
- /* Invalid matched gid gva-->gpa guest tlb */
- INVGTLB_GID_GVA_TO_GPA = 0x13,
- /* Invalid matched gid gpa-->hpa tlb */
- INVTLB_GID_GPA_TO_HPA = 0x14,
- /* Invalid matched gid tlb,including gva-->gpa and gpa-->hpa */
- INVTLB_GID_ALL = 0x15,
- /* Invalid matched gid and addr gpa-->hpa tlb */
- INVTLB_GID_ADDR = 0x16,
- };
- /*
- * invtlb op info addr
- * (0x1 << 26) | (0x24 << 20) | (0x13 << 15) |
- * (addr << 10) | (info << 5) | op
- */
- static inline void invtlb(u32 op, u32 info, u64 addr)
- {
- __asm__ __volatile__(
- "parse_r addr,%0\n\t"
- "parse_r info,%1\n\t"
- ".word ((0x6498000) | (addr << 10) | (info << 5) | %2)\n\t"
- :
- : "r"(addr), "r"(info), "i"(op)
- :
- );
- }
- static inline void invtlb_addr(u32 op, u32 info, u64 addr)
- {
- __asm__ __volatile__(
- "parse_r addr,%0\n\t"
- ".word ((0x6498000) | (addr << 10) | (0 << 5) | %1)\n\t"
- :
- : "r"(addr), "i"(op)
- :
- );
- }
- static inline void invtlb_info(u32 op, u32 info, u64 addr)
- {
- __asm__ __volatile__(
- "parse_r info,%0\n\t"
- ".word ((0x6498000) | (0 << 10) | (info << 5) | %1)\n\t"
- :
- : "r"(info), "i"(op)
- :
- );
- }
- static inline void invtlb_all(u32 op, u32 info, u64 addr)
- {
- __asm__ __volatile__(
- ".word ((0x6498000) | (0 << 10) | (0 << 5) | %0)\n\t"
- :
- : "i"(op)
- :
- );
- }
- #define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
- static void tlb_flush(struct mmu_gather *tlb);
- #define tlb_flush tlb_flush
- #include <asm-generic/tlb.h>
- static inline void tlb_flush(struct mmu_gather *tlb)
- {
- struct vm_area_struct vma;
- vma.vm_mm = tlb->mm;
- vm_flags_init(&vma, 0);
- if (tlb->fullmm) {
- flush_tlb_mm(tlb->mm);
- return;
- }
- flush_tlb_range(&vma, tlb->start, tlb->end);
- }
- extern void handle_tlb_load(void);
- extern void handle_tlb_store(void);
- extern void handle_tlb_modify(void);
- extern void handle_tlb_refill(void);
- extern void handle_tlb_protect(void);
- extern void dump_tlb_all(void);
- extern void dump_tlb_regs(void);
- #endif /* __ASM_TLB_H */
|