Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Dump R4x00 TLB for debugging purposes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 1994, 1995 by Waldorf Electronics, written by Ralf Baechle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright (C) 1999 by Silicon Graphics, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <asm/hazards.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <asm/mipsregs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <asm/mmu_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <asm/tlbdebug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) void dump_tlb_regs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	const int field = 2 * sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	pr_info("Index    : %0x\n", read_c0_index());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	pr_info("PageMask : %0x\n", read_c0_pagemask());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	if (cpu_has_guestid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 		pr_info("GuestCtl1: %0x\n", read_c0_guestctl1());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	pr_info("EntryHi  : %0*lx\n", field, read_c0_entryhi());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	pr_info("EntryLo0 : %0*lx\n", field, read_c0_entrylo0());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	pr_info("EntryLo1 : %0*lx\n", field, read_c0_entrylo1());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	pr_info("Wired    : %0x\n", read_c0_wired());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	switch (current_cpu_type()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	case CPU_R10000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	case CPU_R12000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	case CPU_R14000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	case CPU_R16000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 		pr_info("FrameMask: %0x\n", read_c0_framemask());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	if (cpu_has_small_pages || cpu_has_rixi || cpu_has_xpa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 		pr_info("PageGrain: %0x\n", read_c0_pagegrain());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	if (cpu_has_htw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		pr_info("PWField  : %0*lx\n", field, read_c0_pwfield());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		pr_info("PWSize   : %0*lx\n", field, read_c0_pwsize());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 		pr_info("PWCtl    : %0x\n", read_c0_pwctl());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) static inline const char *msk2str(unsigned int mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	case PM_4K:	return "4kb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	case PM_16K:	return "16kb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	case PM_64K:	return "64kb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	case PM_256K:	return "256kb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #ifdef CONFIG_CPU_CAVIUM_OCTEON
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	case PM_8K:	return "8kb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	case PM_32K:	return "32kb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	case PM_128K:	return "128kb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	case PM_512K:	return "512kb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	case PM_2M:	return "2Mb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	case PM_8M:	return "8Mb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	case PM_32M:	return "32Mb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) #ifndef CONFIG_CPU_VR41XX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	case PM_1M:	return "1Mb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	case PM_4M:	return "4Mb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	case PM_16M:	return "16Mb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	case PM_64M:	return "64Mb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	case PM_256M:	return "256Mb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	case PM_1G:	return "1Gb";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	return "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) static void dump_tlb(int first, int last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	unsigned long s_entryhi, entryhi, asid, mmid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	unsigned long long entrylo0, entrylo1, pa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	unsigned int s_index, s_pagemask, s_guestctl1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	unsigned int pagemask, guestctl1 = 0, c0, c1, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	unsigned long asidmask = cpu_asid_mask(&current_cpu_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	int asidwidth = DIV_ROUND_UP(ilog2(asidmask) + 1, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	unsigned long s_mmid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) #ifdef CONFIG_32BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	bool xpa = cpu_has_xpa && (read_c0_pagegrain() & PG_ELPA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	int pwidth = xpa ? 11 : 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	int vwidth = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	bool xpa = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	int pwidth = 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	int vwidth = 11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	s_pagemask = read_c0_pagemask();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	s_entryhi = read_c0_entryhi();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	s_index = read_c0_index();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	if (cpu_has_mmid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		asid = s_mmid = read_c0_memorymapid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		asid = s_entryhi & asidmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	if (cpu_has_guestid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		s_guestctl1 = read_c0_guestctl1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	for (i = first; i <= last; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		write_c0_index(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		mtc0_tlbr_hazard();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		tlb_read();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		tlb_read_hazard();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		pagemask = read_c0_pagemask();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		entryhi	 = read_c0_entryhi();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		entrylo0 = read_c0_entrylo0();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		entrylo1 = read_c0_entrylo1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		if (cpu_has_mmid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 			mmid = read_c0_memorymapid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 			mmid = entryhi & asidmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		if (cpu_has_guestid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 			guestctl1 = read_c0_guestctl1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		/* EHINV bit marks entire entry as invalid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		if (cpu_has_tlbinv && entryhi & MIPS_ENTRYHI_EHINV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		 * Prior to tlbinv, unused entries have a virtual address of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		 * CKSEG0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		if ((entryhi & ~0x1ffffUL) == CKSEG0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 		 * ASID takes effect in absence of G (global) bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		 * We check both G bits, even though architecturally they should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		 * match one another, because some revisions of the SB1 core may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		 * leave only a single G bit set after a machine check exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		 * due to duplicate TLB entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		if (!((entrylo0 | entrylo1) & ENTRYLO_G) && (mmid != asid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		 * Only print entries in use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		printk("Index: %2d pgmask=%s ", i, msk2str(pagemask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		c0 = (entrylo0 & ENTRYLO_C) >> ENTRYLO_C_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		c1 = (entrylo1 & ENTRYLO_C) >> ENTRYLO_C_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		pr_cont("va=%0*lx asid=%0*lx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 			vwidth, (entryhi & ~0x1fffUL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 			asidwidth, mmid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		if (cpu_has_guestid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 			pr_cont(" gid=%02lx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 				(guestctl1 & MIPS_GCTL1_RID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 					>> MIPS_GCTL1_RID_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		/* RI/XI are in awkward places, so mask them off separately */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		pa = entrylo0 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		if (xpa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			pa |= (unsigned long long)readx_c0_entrylo0() << 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		pa = (pa << 6) & PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		pr_cont("\n\t[");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		if (cpu_has_rixi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 			pr_cont("ri=%d xi=%d ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 				(entrylo0 & MIPS_ENTRYLO_RI) ? 1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 				(entrylo0 & MIPS_ENTRYLO_XI) ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		pr_cont("pa=%0*llx c=%d d=%d v=%d g=%d] [",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 			pwidth, pa, c0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 			(entrylo0 & ENTRYLO_D) ? 1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 			(entrylo0 & ENTRYLO_V) ? 1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 			(entrylo0 & ENTRYLO_G) ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		/* RI/XI are in awkward places, so mask them off separately */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		pa = entrylo1 & ~(MIPS_ENTRYLO_RI | MIPS_ENTRYLO_XI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		if (xpa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 			pa |= (unsigned long long)readx_c0_entrylo1() << 30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		pa = (pa << 6) & PAGE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		if (cpu_has_rixi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 			pr_cont("ri=%d xi=%d ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 				(entrylo1 & MIPS_ENTRYLO_RI) ? 1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 				(entrylo1 & MIPS_ENTRYLO_XI) ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		pr_cont("pa=%0*llx c=%d d=%d v=%d g=%d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 			pwidth, pa, c1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 			(entrylo1 & ENTRYLO_D) ? 1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 			(entrylo1 & ENTRYLO_V) ? 1 : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 			(entrylo1 & ENTRYLO_G) ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	printk("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	write_c0_entryhi(s_entryhi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	write_c0_index(s_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	write_c0_pagemask(s_pagemask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	if (cpu_has_guestid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		write_c0_guestctl1(s_guestctl1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) void dump_tlb_all(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	dump_tlb(0, current_cpu_data.tlbsize - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }