include upstream ip1000a driver version 2.09f
[linux-2.4.git] / arch / sh64 / lib / dbg.c
1 /*--------------------------------------------------------------------------
2 --
3 -- Identity : Linux50 Debug Funcions
4 --
5 -- File     : arch/sh64/lib/dbg.C
6 --
7 -- Copyright 2000, 2001 STMicroelectronics Limited.
8 --
9 --------------------------------------------------------------------------*/
10 #include <linux/types.h>
11 #include <linux/kernel.h>
12 #include <linux/sched.h>
13 #include <linux/mm.h>
14 #include <asm/mmu_context.h>
15
16 typedef u64 regType_t;
17
18 static regType_t getConfigReg(u64 id)
19 {
20         register u64 reg __asm__("r2");
21         asm volatile ("getcfg   %1, 0, %0":"=r" (reg):"r"(id));
22         return (reg);
23 }
24
25 /* ======================================================================= */
26
27 static char *szTab[] = { "4k", "64k", "1M", "512M" };
28 static char *protTab[] = { "----",
29         "---R",
30         "--X-",
31         "--XR",
32         "-W--",
33         "-W-R",
34         "-WX-",
35         "-WXR",
36         "U---",
37         "U--R",
38         "U-X-",
39         "U-XR",
40         "UW--",
41         "UW-R",
42         "UWX-",
43         "UWXR"
44 };
45 #define  ITLB_BASE      0x00000000
46 #define  DTLB_BASE      0x00800000
47 #define  MAX_TLBs               64
48 /* PTE High */
49 #define  GET_VALID(pte)        ((pte) & 0x1)
50 #define  GET_SHARED(pte)       ((pte) & 0x2)
51 #define  GET_ASID(pte)         ((pte >> 2) & 0x0ff)
52 #define  GET_EPN(pte)          ((pte) & 0xfffff000)
53
54 /* PTE Low */
55 #define  GET_CBEHAVIOR(pte)    ((pte) & 0x3)
56 #define  GET_PAGE_SIZE(pte)    szTab[((pte >> 3) & 0x3)]
57 #define  GET_PROTECTION(pte)   protTab[((pte >> 6) & 0xf)]
58 #define  GET_PPN(pte)          ((pte) & 0xfffff000)
59
60 #define PAGE_1K_MASK           0x00000000
61 #define PAGE_4K_MASK           0x00000010
62 #define PAGE_64K_MASK          0x00000080
63 #define MMU_PAGESIZE_MASK      (PAGE_64K_MASK | PAGE_4K_MASK)
64 #define PAGE_1MB_MASK          MMU_PAGESIZE_MASK
65 #define PAGE_1K                (1024)
66 #define PAGE_4K                (1024 * 4)
67 #define PAGE_64K               (1024 * 64)
68 #define PAGE_1MB               (1024 * 1024)
69
70 #define HOW_TO_READ_TLB_CONTENT  \
71        "[ ID]  PPN         EPN        ASID  Share  CB  P.Size   PROT.\n"
72
73 void print_single_tlb(unsigned long tlb, int single_print)
74 {
75         regType_t pteH;
76         regType_t pteL;
77         unsigned int valid, shared, asid, epn, cb, ppn;
78         char *pSize;
79         char *pProt;
80
81         /*
82            ** in case of single print <single_print> is true, this implies:
83            **   1) print the TLB in any case also if NOT VALID
84            **   2) print out the header
85          */
86
87         pteH = getConfigReg(tlb);
88         valid = GET_VALID(pteH);
89         if (single_print)
90                 printk(HOW_TO_READ_TLB_CONTENT);
91         else if (!valid)
92                 return;
93
94         pteL = getConfigReg(tlb + 1);
95
96         shared = GET_SHARED(pteH);
97         asid = GET_ASID(pteH);
98         epn = GET_EPN(pteH);
99         cb = GET_CBEHAVIOR(pteL);
100         pSize = GET_PAGE_SIZE(pteL);
101         pProt = GET_PROTECTION(pteL);
102         ppn = GET_PPN(pteL);
103         printk("[%c%2ld]  0x%08x  0x%08x  %03d   %02x    %02x   %4s    %s\n",
104                ((valid) ? ' ' : 'u'), ((tlb & 0x0ffff) / TLB_STEP),
105                ppn, epn, asid, shared, cb, pSize, pProt);
106 }
107
108 void print_dtlb(void)
109 {
110         int count;
111         unsigned long tlb;
112
113         printk(" ================= SH-5 D-TLBs Status ===================\n");
114         printk(HOW_TO_READ_TLB_CONTENT);
115         tlb = DTLB_BASE;
116         for (count = 0; count < MAX_TLBs; count++, tlb += TLB_STEP)
117                 print_single_tlb(tlb, 0);
118         printk
119             (" =============================================================\n");
120 }
121
122 void print_itlb(void)
123 {
124         int count;
125         unsigned long tlb;
126
127         printk(" ================= SH-5 I-TLBs Status ===================\n");
128         printk(HOW_TO_READ_TLB_CONTENT);
129         tlb = ITLB_BASE;
130         for (count = 0; count < MAX_TLBs; count++, tlb += TLB_STEP)
131                 print_single_tlb(tlb, 0);
132         printk
133             (" =============================================================\n");
134 }
135
136 /* ======================================================================= */
137
138 #include "syscalltab.h"
139
140 void evt_debug(int evt, int ret_addr, int event, int tra)
141 {
142         int syscallno = tra & 0xff;
143
144         // if (event != 0) printk("<%03x>",evt);
145
146         if ((event == 2) && (evt == 0x160)) {
147                 if (syscallno < NUM_SYSCALL_INFO_ENTRIES)
148                         printk("Task %d: %s()\n",
149                                current->pid,
150                                syscall_info_table[syscallno].name);
151         }
152 }
153
154 void evt_debug2(unsigned int ret)
155 {
156         printk("Task %d: syscall returns %08x\n", current->pid, ret);
157 }
158
159 /* ======================================================================= */
160
161 void show_excp_regs(char *from, int trapnr, int signr, struct pt_regs *regs)
162 {
163
164         unsigned long long ah, al, bh, bl, ch, cl;
165
166         printk("\n");
167         printk("EXCEPTION - %s: task %d; Linux trap # %d; signal = %d\n",
168                ((from) ? from : "???"), current->pid, trapnr, signr);
169
170         asm volatile ("getcon   " __c5 ", %0":"=r"(ah));
171         asm volatile ("getcon   " __c5 ", %0":"=r"(al));
172         ah = (ah) >> 32;
173         al = (al) & 0xffffffff;
174         asm volatile ("getcon   " __c18 ", %0":"=r"(bh));
175         asm volatile ("getcon   " __c18 ", %0":"=r"(bl));
176         bh = (bh) >> 32;
177         bl = (bl) & 0xffffffff;
178         asm volatile ("getcon   " __c4 ", %0":"=r"(ch));
179         asm volatile ("getcon   " __c4 ", %0":"=r"(cl));
180         ch = (ch) >> 32;
181         cl = (cl) & 0xffffffff;
182         printk("EXPE: %08Lx%08Lx KCR1: %08Lx%08Lx INTE: %08Lx%08Lx\n",
183                ah, al, bh, bl, ch, cl);
184
185         asm volatile ("getcon   " __c6 ", %0":"=r"(ah));
186         asm volatile ("getcon   " __c6 ", %0":"=r"(al));
187         ah = (ah) >> 32;
188         al = (al) & 0xffffffff;
189         asm volatile ("getcon   " __c9 ", %0":"=r"(bh));
190         asm volatile ("getcon   " __c9 ", %0":"=r"(bl));
191         bh = (bh) >> 32;
192         bl = (bl) & 0xffffffff;
193         asm volatile ("getcon   " __c2 ", %0":"=r"(ch));
194         asm volatile ("getcon   " __c2 ", %0":"=r"(cl));
195         ch = (ch) >> 32;
196         cl = (cl) & 0xffffffff;
197         printk("PEXP: %08Lx%08Lx PSPC: %08Lx%08Lx PSSR: %08Lx%08Lx\n",
198                ah, al, bh, bl, ch, cl);
199
200         ah = (regs->pc) >> 32;
201         al = (regs->pc) & 0xffffffff;
202         bh = (regs->regs[18]) >> 32;
203         bl = (regs->regs[18]) & 0xffffffff;
204         ch = (regs->regs[15]) >> 32;
205         cl = (regs->regs[15]) & 0xffffffff;
206         printk("PC  : %08Lx%08Lx LINK: %08Lx%08Lx SP  : %08Lx%08Lx\n",
207                ah, al, bh, bl, ch, cl);
208
209         ah = (regs->sr) >> 32;
210         al = (regs->sr) & 0xffffffff;
211         asm volatile ("getcon   " __c13 ", %0":"=r"(bh));
212         asm volatile ("getcon   " __c13 ", %0":"=r"(bl));
213         bh = (bh) >> 32;
214         bl = (bl) & 0xffffffff;
215         asm volatile ("getcon   " __c17 ", %0":"=r"(ch));
216         asm volatile ("getcon   " __c17 ", %0":"=r"(cl));
217         ch = (ch) >> 32;
218         cl = (cl) & 0xffffffff;
219         printk("SR  : %08Lx%08Lx TEA : %08Lx%08Lx KCR0: %08Lx%08Lx\n",
220                ah, al, bh, bl, ch, cl);
221
222         ah = (regs->regs[0]) >> 32;
223         al = (regs->regs[0]) & 0xffffffff;
224         bh = (regs->regs[1]) >> 32;
225         bl = (regs->regs[1]) & 0xffffffff;
226         ch = (regs->regs[2]) >> 32;
227         cl = (regs->regs[2]) & 0xffffffff;
228         printk("R0  : %08Lx%08Lx R1  : %08Lx%08Lx R2  : %08Lx%08Lx\n",
229                ah, al, bh, bl, ch, cl);
230
231         ah = (regs->regs[3]) >> 32;
232         al = (regs->regs[3]) & 0xffffffff;
233         bh = (regs->regs[4]) >> 32;
234         bl = (regs->regs[4]) & 0xffffffff;
235         ch = (regs->regs[5]) >> 32;
236         cl = (regs->regs[5]) & 0xffffffff;
237         printk("R3  : %08Lx%08Lx R4  : %08Lx%08Lx R5  : %08Lx%08Lx\n",
238                ah, al, bh, bl, ch, cl);
239
240         ah = (regs->regs[6]) >> 32;
241         al = (regs->regs[6]) & 0xffffffff;
242         bh = (regs->regs[7]) >> 32;
243         bl = (regs->regs[7]) & 0xffffffff;
244         ch = (regs->regs[8]) >> 32;
245         cl = (regs->regs[8]) & 0xffffffff;
246         printk("R6  : %08Lx%08Lx R7  : %08Lx%08Lx R8  : %08Lx%08Lx\n",
247                ah, al, bh, bl, ch, cl);
248
249         ah = (regs->regs[9]) >> 32;
250         al = (regs->regs[9]) & 0xffffffff;
251         bh = (regs->regs[10]) >> 32;
252         bl = (regs->regs[10]) & 0xffffffff;
253         ch = (regs->regs[11]) >> 32;
254         cl = (regs->regs[11]) & 0xffffffff;
255         printk("R9  : %08Lx%08Lx R10 : %08Lx%08Lx R11 : %08Lx%08Lx\n",
256                ah, al, bh, bl, ch, cl);
257         printk("....\n");
258
259         ah = (regs->tregs[0]) >> 32;
260         al = (regs->tregs[0]) & 0xffffffff;
261         bh = (regs->tregs[1]) >> 32;
262         bl = (regs->tregs[1]) & 0xffffffff;
263         ch = (regs->tregs[2]) >> 32;
264         cl = (regs->tregs[2]) & 0xffffffff;
265         printk("T0  : %08Lx%08Lx T1  : %08Lx%08Lx T2  : %08Lx%08Lx\n",
266                ah, al, bh, bl, ch, cl);
267         printk("....\n");
268
269         print_dtlb();
270         print_itlb();
271 }
272
273 /* ======================================================================= */
274
275 /*
276 ** Depending on <base> scan the MMU, Data or Instrction side
277 ** looking for a valid mapping matching Eaddr & asid.
278 ** Return -1 if not found or the TLB id entry otherwise.
279 ** Note: it works only for 4k pages!
280 */
281 static unsigned long
282 lookup_mmu_side(unsigned long base, unsigned long Eaddr, unsigned long asid)
283 {
284         regType_t pteH;
285         unsigned long epn;
286         int count;
287
288         epn = Eaddr & 0xfffff000;
289
290         for (count = 0; count < MAX_TLBs; count++, base += TLB_STEP) {
291                 pteH = getConfigReg(base);
292                 if (GET_VALID(pteH))
293                         if ((unsigned long) GET_EPN(pteH) == epn)
294                                 if ((unsigned long) GET_ASID(pteH) == asid)
295                                         break;
296         }
297         return ((unsigned long) ((count < MAX_TLBs) ? base : -1));
298 }
299
300 unsigned long lookup_dtlb(unsigned long Eaddr)
301 {
302         unsigned long asid = get_asid();
303         return (lookup_mmu_side((u64) DTLB_BASE, Eaddr, asid));
304 }
305
306 unsigned long lookup_itlb(unsigned long Eaddr)
307 {
308         unsigned long asid = get_asid();
309         return (lookup_mmu_side((u64) ITLB_BASE, Eaddr, asid));
310 }
311
312 void print_page(struct page *page)
313 {
314         printk("  page[%p] -> index 0x%lx,  count 0x%x,  flags 0x%lx\n",
315                page, page->index, atomic_read(&page->count), page->flags);
316         printk("       address_space = %p, pages =%ld\n", page->mapping,
317                page->mapping->nrpages);
318
319 }