From 901711f79522cf851917443e777684550d285a64 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Thu, 17 Nov 2022 12:48:37 -0500 Subject: [PATCH 11/52] mips: Add a sysctl to dump the TLB --- sys/mips/mips/tlb.c | 74 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/sys/mips/mips/tlb.c b/sys/mips/mips/tlb.c index cb246ad39447..2e39f06c7f31 100644 --- a/sys/mips/mips/tlb.c +++ b/sys/mips/mips/tlb.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -280,7 +281,6 @@ tlb_invalidate_range(pmap_t pmap, vm_offset_t start, vm_offset_t end) intr_restore(s); } -/* XXX Only if DDB? */ void tlb_save(void) { @@ -371,6 +371,78 @@ tlb_invalidate_one(unsigned i) tlb_write_indexed(); } +static int +tlb_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct tlb_state *tlbs; + struct tlb_entry *tlbe; + register_t s; + int error, val; + + val = 0; + error = sysctl_handle_int(oidp, &val, sizeof(val), req); + if (error != 0 || req->newptr == NULL || val == 0) + return (error); + + if (num_tlbentries > MIPS_MAX_TLB_ENTRIES) { + printf("num entries %d is larger than max\n", num_tlbentries); + return (EINVAL); + } + + s = intr_disable(); + tlb_save(); + tlbs = &tlb_state[curcpu]; + for (int i = 0; i < num_tlbentries; i++) { + const char *pagesize, *region; + register_t asid; + vm_offset_t va; + + tlbe = &tlbs->entry[i]; + +#define VAL2STR(var, val, name) \ + case val: \ + var = name; \ + break + + switch (TLBHI_VA_R(tlbe->entryhi)) { + VAL2STR(region, TLBHI_R_USER, "user"); + VAL2STR(region, TLBHI_R_KERNEL, "kern"); + VAL2STR(region, TLBHI_R_SUPERVISOR, "supr"); + default: + panic("unrecognized region for %#jx", tlbe->entryhi); + } + switch (tlbe->pagemask) { + VAL2STR(pagesize, TLBMASK_4K_PAGE, "4K"); + VAL2STR(pagesize, TLBMASK_16K_PAGE, "16K"); + VAL2STR(pagesize, TLBMASK_64K_PAGE, "64K"); + VAL2STR(pagesize, TLBMASK_256K_PAGE, "256K"); + VAL2STR(pagesize, TLBMASK_1M_PAGE, "1M"); + VAL2STR(pagesize, TLBMASK_4M_PAGE, "4M"); + VAL2STR(pagesize, TLBMASK_16M_PAGE, "16M"); + VAL2STR(pagesize, TLBMASK_64M_PAGE, "64M"); +#if 0 + VAL2STR(pagesize, TLBMASK_256M_PAGE, "256M"); +#endif + default: + panic("unrecognized pagemask %#jx", tlbe->pagemask); + } +#undef VAL2STR + + asid = tlbe->entryhi & TLBHI_ASID_MASK; + va = tlbe->entryhi & ~TLBHI_ASID_MASK; + printf("%d%s:\tregion %s va %#016jx asid %#lu pagesize %s lo0 %#jx lo1 %#jx\n", + i, i == tlbs->wired ? "(w)" : "", region, va, asid, pagesize, + TLBLO_PTE_TO_PA(tlbe->entrylo0), + TLBLO_PTE_TO_PA(tlbe->entrylo1)); + } + intr_restore(s); + + return (0); +} +SYSCTL_PROC(_debug, OID_AUTO, dump_tlb, + CTLTYPE_INT | CTLFLAG_MPSAFE | CTLFLAG_RW, + 0, 0, tlb_sysctl, "I", "Dump current CPU's TLB entries"); + #ifdef DDB #include -- 2.41.0