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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * arch/sh/mm/tlb-debugfs.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * debugfs ops for SH-4 ITLB/UTLBs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright (C) 2010  Matt Fleming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * License.  See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <asm/mmu_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <asm/tlbflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) enum tlb_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	TLB_TYPE_ITLB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	TLB_TYPE_UTLB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) static struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	int bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	const char *size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) } tlb_sizes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	{ 0x0, "  1KB" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	{ 0x1, "  4KB" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	{ 0x2, "  8KB" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	{ 0x4, " 64KB" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	{ 0x5, "256KB" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	{ 0x7, "  1MB" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	{ 0x8, "  4MB" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	{ 0xc, " 64MB" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) static int tlb_seq_show(struct seq_file *file, void *iter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	unsigned int tlb_type = (unsigned int)file->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	unsigned long addr1, addr2, data1, data2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	unsigned long mmucr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	unsigned int nentries, entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	unsigned int urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	mmucr = __raw_readl(MMUCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	if ((mmucr & 0x1) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		seq_printf(file, "address translation disabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	if (tlb_type == TLB_TYPE_ITLB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		addr1 = MMU_ITLB_ADDRESS_ARRAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		addr2 = MMU_ITLB_ADDRESS_ARRAY2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		data1 = MMU_ITLB_DATA_ARRAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		data2 = MMU_ITLB_DATA_ARRAY2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		nentries = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		addr1 = MMU_UTLB_ADDRESS_ARRAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		addr2 = MMU_UTLB_ADDRESS_ARRAY2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		data1 = MMU_UTLB_DATA_ARRAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		data2 = MMU_UTLB_DATA_ARRAY2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		nentries = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	jump_to_uncached();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	urb = (mmucr & MMUCR_URB) >> MMUCR_URB_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	/* Make the "entry >= urb" test fail. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	if (urb == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		urb = MMUCR_URB_NENTRIES + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	if (tlb_type == TLB_TYPE_ITLB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		addr1 = MMU_ITLB_ADDRESS_ARRAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		addr2 = MMU_ITLB_ADDRESS_ARRAY2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		data1 = MMU_ITLB_DATA_ARRAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		data2 = MMU_ITLB_DATA_ARRAY2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		nentries = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		addr1 = MMU_UTLB_ADDRESS_ARRAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		addr2 = MMU_UTLB_ADDRESS_ARRAY2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		data1 = MMU_UTLB_DATA_ARRAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		data2 = MMU_UTLB_DATA_ARRAY2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		nentries = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	seq_printf(file, "entry:     vpn        ppn     asid  size valid wired\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	for (entry = 0; entry < nentries; entry++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		unsigned long vpn, ppn, asid, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		unsigned long valid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		const char *sz = "    ?";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		val = __raw_readl(addr1 | (entry << MMU_TLB_ENTRY_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		ctrl_barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		vpn = val & 0xfffffc00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		valid = val & 0x100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		val = __raw_readl(addr2 | (entry << MMU_TLB_ENTRY_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		ctrl_barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		asid = val & MMU_CONTEXT_ASID_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		val = __raw_readl(data1 | (entry << MMU_TLB_ENTRY_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		ctrl_barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		ppn = (val & 0x0ffffc00) << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		val = __raw_readl(data2 | (entry << MMU_TLB_ENTRY_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		ctrl_barrier();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		size = (val & 0xf0) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		for (i = 0; i < ARRAY_SIZE(tlb_sizes); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 			if (tlb_sizes[i].bits == size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		if (i != ARRAY_SIZE(tlb_sizes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 			sz = tlb_sizes[i].size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		seq_printf(file, "%2d:    0x%08lx 0x%08lx %5lu %s   %s     %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 			   entry, vpn, ppn, asid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 			   sz, valid ? "V" : "-",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 			   (urb <= entry) ? "W" : "-");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	back_to_cached();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static int tlb_debugfs_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	return single_open(file, tlb_seq_show, inode->i_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static const struct file_operations tlb_debugfs_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	.owner		= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	.open		= tlb_debugfs_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	.read		= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	.llseek		= seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	.release	= single_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static int __init tlb_debugfs_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	debugfs_create_file("itlb", S_IRUSR, arch_debugfs_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 			    (void *)TLB_TYPE_ITLB, &tlb_debugfs_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	debugfs_create_file("utlb", S_IRUSR, arch_debugfs_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 			    (void *)TLB_TYPE_UTLB, &tlb_debugfs_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) module_init(tlb_debugfs_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) MODULE_LICENSE("GPL v2");