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