1 /*        $NetBSD: cop0.c,v 1.3 2008/04/28 20:23:18 martin 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  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <lib/libsa/stand.h>
33 #include <lib/libkern/libkern.h>
34 
35 #include "cmd.h"
36 #include "local.h"
37 
38 #define   NTLB      48        /* R4000 */
39 struct tlb {
40           uint32_t PageMask;
41           uint32_t EntryHi;
42           uint32_t EntryLo0;
43           uint32_t EntryLo1;
44           uint32_t page_mask;
45           char *page_size;
46           uint32_t vpn, pfn0, pfn1;
47 } entry[NTLB];
48 static void __tlb_pagemask(struct tlb *);
49 
50 
51 /*
52 EWS4800/350. IPL don't handle TLB refill exception.
53 
54 16M-page
55 paddr  0x00000000-0x18000000  M0, M1, M2
56 vaddr  0x00000000-0x18000000
57 
58 paddr  0x38000000-0x40000000  M3
59 vaddr  0x18000000-0x20000000
60 
61 paddr  0xe0000000-0xf8000000  FrameBuffer 0xf0000000 + reg 0xf5000000
62 vaddr  0xe0000000-0xf8000000
63 
64 4K-page
65 paddr  0x20000000-0x20028000  160K
66 vaddr  0x20000000-0x20028000
67  */
68 int
cmd_tlb(int argc,char * argp[],int interactive)69 cmd_tlb(int argc, char *argp[], int interactive)
70 {
71           extern void tlb_read(int, void *);
72           struct tlb  *e;
73           int i;
74 
75           if (argc < 2) {
76                     printf("option: r, d, p entry#\n");
77                     return 1;
78           }
79 
80           switch (*argp[1]) {
81           case 'r': /* Read TLB entry all. */
82                     for (i = 0; i < NTLB; i++)
83                               tlb_read(i, &entry[i]);
84                     printf("done.\n");
85                     break;
86           case 'd': /* Dump TLB summary */
87                     for (i = 0, e = entry; i < NTLB; i++, e++) {
88                               __tlb_pagemask(e);
89                               e->vpn = (e->EntryHi >> 13) << 1;
90                               e->pfn0 = (e->EntryLo0 >> 6);
91                               e->pfn1 = (e->EntryLo1 >> 6);
92                               printf("%d %s %x %x+%x", i, e->page_size, e->vpn,
93                                   e->pfn0, e->pfn1);
94                               putchar((i + 1) & 3 ? '|' : '\n');
95                     }
96                     break;
97           case 'p': /* Print TLB entry */
98                     if (argc < 3) {
99                               printf("tlb p entry#.\n");
100                               return 1;
101                     }
102                     i = strtoul(argp[2], 0, 0);
103                     if (i < 0 || i >= NTLB)
104                               return 1;
105                     e = &entry[i];
106                     printf("[%d] size:%s vaddr:0x%08x paddr:0x%08x+0x%08x "
107                         "mask:0x%08x\n", i, e->page_size, e->vpn << 12,
108                         e->pfn0 << 12, e->pfn1 << 12, e->page_mask);
109                     printf("[%x, %x, %x, %x]\n",
110                         e->PageMask, e->EntryHi, e->EntryLo0, e->EntryLo1);
111 
112                     break;
113           default:
114                     printf("unknown option \"%c\"\n", *argp[1]);
115                     break;
116           }
117 
118           return 0;
119 }
120 
121 int
cmd_cop0(int argc,char * argp[],int interactive)122 cmd_cop0(int argc, char *argp[], int interactive)
123 {
124           int v;
125 
126           __asm volatile("mfc0 %0, $%1" : "=r"(v) : "i"(15));
127           printf("PRId: %x\n", v);
128           __asm volatile("mfc0 %0, $%1" : "=r"(v) : "i"(16));
129           printf("Config: %x\n", v);
130           __asm volatile("mfc0 %0, $%1" : "=r"(v) : "i"(12));
131           printf("Status: %x\n", v);
132           __asm volatile("mfc0 %0, $%1" : "=r"(v) : "i"(13));
133           printf("Cause: %x\n", v);
134           __asm volatile("mfc0 %0, $%1" : "=r"(v) : "i"(8));
135           printf("BadVAddr: %x\n", v);
136           __asm volatile("mfc0 %0, $%1" : "=r"(v) : "i"(14));
137           printf("EPC: %x\n", v);
138 
139           return 0;
140 }
141 
142 void
__tlb_pagemask(struct tlb * e)143 __tlb_pagemask(struct tlb *e)
144 {
145 
146           switch (e->PageMask >> 13) {
147           default:
148                     e->page_size = " ERR";
149                     e->page_mask = 0;
150                     break;
151           case 0:
152                     e->page_size = "  4K";
153                     e->page_mask = 0xfff;
154                     break;
155           case 3:
156                     e->page_size = " 16K";
157                     e->page_mask = 0x3fff;
158                     break;
159           case 0xf:
160                     e->page_size = " 64K";
161                     e->page_mask = 0xffff;
162                     break;
163           case 0x3f:
164                     e->page_size = "256K";
165                     e->page_mask = 0x3ffff;
166                     break;
167           case 0xff:
168                     e->page_size = "  1M";
169                     e->page_mask = 0xfffff;
170                     break;
171           case 0x3ff:
172                     e->page_size = "  4M";
173                     e->page_mask = 0x3fffff;
174                     break;
175           case 0xfff:
176                     e->page_size = " 16M";
177                     e->page_mask = 0xffffff;
178                     break;
179           }
180 }
181