1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
6 * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
7 * Copyright (C) 1999 by Silicon Graphics, Inc.
9 #include <linux/kernel.h>
12 #include <asm/loongarch.h>
14 #include <asm/pgtable.h>
17 void dump_tlb_regs(void)
19 const int field
= 2 * sizeof(unsigned long);
21 pr_info("Index : 0x%0x\n", read_csr_tlbidx());
22 pr_info("PageSize : 0x%0x\n", read_csr_pagesize());
23 pr_info("EntryHi : 0x%0*lx\n", field
, read_csr_entryhi());
24 pr_info("EntryLo0 : 0x%0*lx\n", field
, read_csr_entrylo0());
25 pr_info("EntryLo1 : 0x%0*lx\n", field
, read_csr_entrylo1());
28 static void dump_tlb(int first
, int last
)
30 unsigned long s_entryhi
, entryhi
, asid
;
31 unsigned long long entrylo0
, entrylo1
, pa
;
33 unsigned int s_index
, s_asid
;
34 unsigned int pagesize
, c0
, c1
, i
;
35 unsigned long asidmask
= cpu_asid_mask(¤t_cpu_data
);
38 int asidwidth
= DIV_ROUND_UP(ilog2(asidmask
) + 1, 4);
40 s_entryhi
= read_csr_entryhi();
41 s_index
= read_csr_tlbidx();
42 s_asid
= read_csr_asid();
44 for (i
= first
; i
<= last
; i
++) {
47 pagesize
= read_csr_pagesize();
48 entryhi
= read_csr_entryhi();
49 entrylo0
= read_csr_entrylo0();
50 entrylo1
= read_csr_entrylo1();
51 index
= read_csr_tlbidx();
52 asid
= read_csr_asid();
54 /* EHINV bit marks entire entry as invalid */
55 if (index
& CSR_TLBIDX_EHINV
)
58 * ASID takes effect in absence of G (global) bit.
60 if (!((entrylo0
| entrylo1
) & ENTRYLO_G
) &&
65 * Only print entries in use
67 pr_info("Index: %4d pgsize=0x%x ", i
, (1 << pagesize
));
69 c0
= (entrylo0
& ENTRYLO_C
) >> ENTRYLO_C_SHIFT
;
70 c1
= (entrylo1
& ENTRYLO_C
) >> ENTRYLO_C_SHIFT
;
72 pr_cont("va=0x%0*lx asid=0x%0*lx",
73 vwidth
, (entryhi
& ~0x1fffUL
), asidwidth
, asid
& asidmask
);
75 /* NR/NX are in awkward places, so mask them off separately */
76 pa
= entrylo0
& ~(ENTRYLO_NR
| ENTRYLO_NX
);
79 pr_cont("nr=%d nx=%d ",
80 (entrylo0
& ENTRYLO_NR
) ? 1 : 0,
81 (entrylo0
& ENTRYLO_NX
) ? 1 : 0);
82 pr_cont("pa=0x%0*llx c=%d d=%d v=%d g=%d plv=%lld] [",
84 (entrylo0
& ENTRYLO_D
) ? 1 : 0,
85 (entrylo0
& ENTRYLO_V
) ? 1 : 0,
86 (entrylo0
& ENTRYLO_G
) ? 1 : 0,
87 (entrylo0
& ENTRYLO_PLV
) >> ENTRYLO_PLV_SHIFT
);
88 /* NR/NX are in awkward places, so mask them off separately */
89 pa
= entrylo1
& ~(ENTRYLO_NR
| ENTRYLO_NX
);
91 pr_cont("nr=%d nx=%d ",
92 (entrylo1
& ENTRYLO_NR
) ? 1 : 0,
93 (entrylo1
& ENTRYLO_NX
) ? 1 : 0);
94 pr_cont("pa=0x%0*llx c=%d d=%d v=%d g=%d plv=%lld]\n",
96 (entrylo1
& ENTRYLO_D
) ? 1 : 0,
97 (entrylo1
& ENTRYLO_V
) ? 1 : 0,
98 (entrylo1
& ENTRYLO_G
) ? 1 : 0,
99 (entrylo1
& ENTRYLO_PLV
) >> ENTRYLO_PLV_SHIFT
);
103 write_csr_entryhi(s_entryhi
);
104 write_csr_tlbidx(s_index
);
105 write_csr_asid(s_asid
);
108 void dump_tlb_all(void)
110 dump_tlb(0, current_cpu_data
.tlbsize
- 1);