1 /* $NetBSD: cop0.c,v 1.2 2006/01/26 16:26:58 tsutsui Exp $ */ 2 3 /*- 4 * Copyright (c) 2004 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by UCHIYAMA Yasushi. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed by the NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include <lib/libsa/stand.h> 40 #include <lib/libkern/libkern.h> 41 42 #include "cmd.h" 43 #include "local.h" 44 45 #define NTLB 48 /* R4000 */ 46 struct tlb { 47 uint32_t PageMask; 48 uint32_t EntryHi; 49 uint32_t EntryLo0; 50 uint32_t EntryLo1; 51 uint32_t page_mask; 52 char *page_size; 53 uint32_t vpn, pfn0, pfn1; 54 } entry[NTLB]; 55 static void __tlb_pagemask(struct tlb *); 56 57 58 /* 59 EWS4800/350. IPL don't handle TLB refill exception. 60 61 16M-page 62 paddr 0x00000000-0x18000000 M0, M1, M2 63 vaddr 0x00000000-0x18000000 64 65 paddr 0x38000000-0x40000000 M3 66 vaddr 0x18000000-0x20000000 67 68 paddr 0xe0000000-0xf8000000 FrameBuffer 0xf0000000 + reg 0xf5000000 69 vaddr 0xe0000000-0xf8000000 70 71 4K-page 72 paddr 0x20000000-0x20028000 160K 73 vaddr 0x20000000-0x20028000 74 */ 75 int 76 cmd_tlb(int argc, char *argp[], int interactive) 77 { 78 extern void tlb_read(int, void *); 79 struct tlb *e; 80 int i; 81 82 if (argc < 2) { 83 printf("option: r, d, p entry#\n"); 84 return 1; 85 } 86 87 switch (*argp[1]) { 88 case 'r': /* Read TLB entry all. */ 89 for (i = 0; i < NTLB; i++) 90 tlb_read(i, &entry[i]); 91 printf("done.\n"); 92 break; 93 case 'd': /* Dump TLB summary */ 94 for (i = 0, e = entry; i < NTLB; i++, e++) { 95 __tlb_pagemask(e); 96 e->vpn = (e->EntryHi >> 13) << 1; 97 e->pfn0 = (e->EntryLo0 >> 6); 98 e->pfn1 = (e->EntryLo1 >> 6); 99 printf("%d %s %x %x+%x", i, e->page_size, e->vpn, 100 e->pfn0, e->pfn1); 101 putchar((i + 1) & 3 ? '|' : '\n'); 102 } 103 break; 104 case 'p': /* Print TLB entry */ 105 if (argc < 3) { 106 printf("tlb p entry#.\n"); 107 return 1; 108 } 109 i = strtoul(argp[2], 0, 0); 110 if (i < 0 || i >= NTLB) 111 return 1; 112 e = &entry[i]; 113 printf("[%d] size:%s vaddr:0x%08x paddr:0x%08x+0x%08x " 114 "mask:0x%08x\n", i, e->page_size, e->vpn << 12, 115 e->pfn0 << 12, e->pfn1 << 12, e->page_mask); 116 printf("[%x, %x, %x, %x]\n", 117 e->PageMask, e->EntryHi, e->EntryLo0, e->EntryLo1); 118 119 break; 120 default: 121 printf("unknown option \"%c\"\n", *argp[1]); 122 break; 123 } 124 125 return 0; 126 } 127 128 int 129 cmd_cop0(int argc, char *argp[], int interactive) 130 { 131 int v; 132 133 __asm volatile("mfc0 %0, $%1" : "=r"(v) : "i"(15)); 134 printf("PRId: %x\n", v); 135 __asm volatile("mfc0 %0, $%1" : "=r"(v) : "i"(16)); 136 printf("Config: %x\n", v); 137 __asm volatile("mfc0 %0, $%1" : "=r"(v) : "i"(12)); 138 printf("Status: %x\n", v); 139 __asm volatile("mfc0 %0, $%1" : "=r"(v) : "i"(13)); 140 printf("Cause: %x\n", v); 141 __asm volatile("mfc0 %0, $%1" : "=r"(v) : "i"(8)); 142 printf("BadVAddr: %x\n", v); 143 __asm volatile("mfc0 %0, $%1" : "=r"(v) : "i"(14)); 144 printf("EPC: %x\n", v); 145 146 return 0; 147 } 148 149 void 150 __tlb_pagemask(struct tlb *e) 151 { 152 153 switch (e->PageMask >> 13) { 154 default: 155 e->page_size = " ERR"; 156 e->page_mask = 0; 157 break; 158 case 0: 159 e->page_size = " 4K"; 160 e->page_mask = 0xfff; 161 break; 162 case 3: 163 e->page_size = " 16K"; 164 e->page_mask = 0x3fff; 165 break; 166 case 0xf: 167 e->page_size = " 64K"; 168 e->page_mask = 0xffff; 169 break; 170 case 0x3f: 171 e->page_size = "256K"; 172 e->page_mask = 0x3ffff; 173 break; 174 case 0xff: 175 e->page_size = " 1M"; 176 e->page_mask = 0xfffff; 177 break; 178 case 0x3ff: 179 e->page_size = " 4M"; 180 e->page_mask = 0x3fffff; 181 break; 182 case 0xfff: 183 e->page_size = " 16M"; 184 e->page_mask = 0xffffff; 185 break; 186 } 187 } 188