162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Dump R3000 TLB for debugging purposes. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle. 662306a36Sopenharmony_ci * Copyright (C) 1999 by Silicon Graphics, Inc. 762306a36Sopenharmony_ci * Copyright (C) 1999 by Harald Koerfgen 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci#include <linux/kernel.h> 1062306a36Sopenharmony_ci#include <linux/mm.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <asm/mipsregs.h> 1362306a36Sopenharmony_ci#include <asm/mmu_context.h> 1462306a36Sopenharmony_ci#include <asm/page.h> 1562306a36Sopenharmony_ci#include <asm/tlbdebug.h> 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_civoid dump_tlb_regs(void) 1862306a36Sopenharmony_ci{ 1962306a36Sopenharmony_ci pr_info("Index : %0x\n", read_c0_index()); 2062306a36Sopenharmony_ci pr_info("EntryHi : %0lx\n", read_c0_entryhi()); 2162306a36Sopenharmony_ci pr_info("EntryLo : %0lx\n", read_c0_entrylo0()); 2262306a36Sopenharmony_ci} 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistatic void dump_tlb(int first, int last) 2562306a36Sopenharmony_ci{ 2662306a36Sopenharmony_ci int i; 2762306a36Sopenharmony_ci unsigned int asid; 2862306a36Sopenharmony_ci unsigned long entryhi, entrylo0, asid_mask; 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci asid_mask = cpu_asid_mask(¤t_cpu_data); 3162306a36Sopenharmony_ci asid = read_c0_entryhi() & asid_mask; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci for (i = first; i <= last; i++) { 3462306a36Sopenharmony_ci write_c0_index(i<<8); 3562306a36Sopenharmony_ci __asm__ __volatile__( 3662306a36Sopenharmony_ci ".set\tnoreorder\n\t" 3762306a36Sopenharmony_ci "tlbr\n\t" 3862306a36Sopenharmony_ci "nop\n\t" 3962306a36Sopenharmony_ci ".set\treorder"); 4062306a36Sopenharmony_ci entryhi = read_c0_entryhi(); 4162306a36Sopenharmony_ci entrylo0 = read_c0_entrylo0(); 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci /* Unused entries have a virtual address of KSEG0. */ 4462306a36Sopenharmony_ci if ((entryhi & PAGE_MASK) != KSEG0 && 4562306a36Sopenharmony_ci (entrylo0 & R3K_ENTRYLO_G || 4662306a36Sopenharmony_ci (entryhi & asid_mask) == asid)) { 4762306a36Sopenharmony_ci /* 4862306a36Sopenharmony_ci * Only print entries in use 4962306a36Sopenharmony_ci */ 5062306a36Sopenharmony_ci printk("Index: %2d ", i); 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci pr_cont("va=%08lx asid=%08lx" 5362306a36Sopenharmony_ci " [pa=%06lx n=%d d=%d v=%d g=%d]", 5462306a36Sopenharmony_ci entryhi & PAGE_MASK, 5562306a36Sopenharmony_ci entryhi & asid_mask, 5662306a36Sopenharmony_ci entrylo0 & PAGE_MASK, 5762306a36Sopenharmony_ci (entrylo0 & R3K_ENTRYLO_N) ? 1 : 0, 5862306a36Sopenharmony_ci (entrylo0 & R3K_ENTRYLO_D) ? 1 : 0, 5962306a36Sopenharmony_ci (entrylo0 & R3K_ENTRYLO_V) ? 1 : 0, 6062306a36Sopenharmony_ci (entrylo0 & R3K_ENTRYLO_G) ? 1 : 0); 6162306a36Sopenharmony_ci } 6262306a36Sopenharmony_ci } 6362306a36Sopenharmony_ci printk("\n"); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci write_c0_entryhi(asid); 6662306a36Sopenharmony_ci} 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_civoid dump_tlb_all(void) 6962306a36Sopenharmony_ci{ 7062306a36Sopenharmony_ci dump_tlb(0, current_cpu_data.tlbsize - 1); 7162306a36Sopenharmony_ci} 72