/[dynamips]/trunk/mips64_cp0.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /trunk/mips64_cp0.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (hide annotations)
Sat Oct 6 16:23:47 2007 UTC (16 years, 6 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.7-RC1/mips64_cp0.c
File MIME type: text/plain
File size: 17463 byte(s)
dynamips-0.2.7-RC1

1 dpavlin 7 /*
2     * Cisco router simulation platform.
3     * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)
4     *
5     * MIPS Coprocessor 0 (System Coprocessor) implementation.
6     * We don't use the JIT here, since there is no high performance needed.
7     */
8    
9     #include <stdio.h>
10     #include <stdlib.h>
11     #include <unistd.h>
12     #include <string.h>
13     #include <sys/types.h>
14     #include <sys/stat.h>
15     #include <sys/mman.h>
16     #include <fcntl.h>
17    
18     #include "device.h"
19     #include "mips64.h"
20     #include "mips64_cp0.h"
21     #include "dynamips.h"
22     #include "memory.h"
23    
24     /* MIPS cp0 registers names */
25     char *mips64_cp0_reg_names[MIPS64_CP0_REG_NR] = {
26     "index" ,
27     "random",
28     "entry_lo0",
29     "entry_lo1",
30     "context",
31     "pagemask",
32     "wired",
33     "info",
34     "badvaddr",
35     "count",
36     "entry_hi",
37     "compare",
38     "status",
39     "cause",
40     "epc",
41     "prid",
42     "config",
43     "ll_addr",
44     "watch_lo",
45     "watch_hi",
46     "xcontext",
47     "cp0_r21",
48     "cp0_r22",
49     "cp0_r23",
50     "cp0_r24",
51     "cp0_r25",
52     "ecc",
53     "cache_err",
54     "tag_lo",
55     "tag_hi",
56     "err_epc",
57     "cp0_r31",
58     };
59    
60     /* Get cp0 register index given its name */
61     int mips64_cp0_get_reg_index(char *name)
62     {
63     int i;
64    
65     for(i=0;i<MIPS64_CP0_REG_NR;i++)
66     if (!strcmp(mips64_cp0_reg_names[i],name))
67     return(i);
68    
69     return(-1);
70     }
71    
72     /* Get the CPU operating mode (User,Supervisor or Kernel) - inline version */
73     static forced_inline u_int mips64_cp0_get_mode_inline(cpu_mips_t *cpu)
74     {
75     mips_cp0_t *cp0 = &cpu->cp0;
76     u_int cpu_mode;
77    
78     cpu_mode = cp0->reg[MIPS_CP0_STATUS] >> MIPS_CP0_STATUS_KSU_SHIFT;
79     cpu_mode &= MIPS_CP0_STATUS_KSU_MASK;
80     return(cpu_mode);
81     }
82    
83     /* Get the CPU operating mode (User,Supervisor or Kernel) */
84     u_int mips64_cp0_get_mode(cpu_mips_t *cpu)
85     {
86     return(mips64_cp0_get_mode_inline(cpu));
87     }
88    
89     /* Check that we are running in kernel mode */
90     int mips64_cp0_check_kernel_mode(cpu_mips_t *cpu)
91     {
92     u_int cpu_mode;
93    
94     cpu_mode = mips64_cp0_get_mode(cpu);
95    
96     if (cpu_mode != MIPS_CP0_STATUS_KM) {
97     /* XXX Branch delay slot */
98     mips64_trigger_exception(cpu,MIPS_CP0_CAUSE_ILLOP,0);
99     return(1);
100     }
101    
102     return(0);
103     }
104    
105     /* Get value of random register */
106     static inline u_int mips64_cp0_get_random_reg(cpu_mips_t *cpu)
107     {
108     u_int wired;
109    
110     /* We use the virtual count register as a basic "random" value */
111     wired = cpu->cp0.reg[MIPS_CP0_WIRED];
112     return(wired + (cpu->cp0_virt_cnt_reg % (cpu->cp0.tlb_entries - wired)));
113     }
114    
115     /* Get a cp0 register (fast version) */
116     static inline m_uint64_t mips64_cp0_get_reg_fast(cpu_mips_t *cpu,u_int cp0_reg)
117     {
118     mips_cp0_t *cp0 = &cpu->cp0;
119     m_uint32_t delta,res;
120    
121     switch(cp0_reg) {
122     case MIPS_CP0_COUNT:
123     delta = cpu->cp0_virt_cmp_reg - cpu->cp0_virt_cnt_reg;
124     res = (m_uint32_t)cp0->reg[MIPS_CP0_COMPARE];
125     res -= cpu->vm->clock_divisor * delta;
126     return(sign_extend(res,32));
127    
128     #if 1
129     case MIPS_CP0_COMPARE:
130     return(sign_extend(cp0->reg[MIPS_CP0_COMPARE],32));
131     #else
132     /* really useful and logical ? */
133     case MIPS_CP0_COMPARE:
134     delta = cpu->cp0_virt_cmp_reg - cpu->cp0_virt_cnt_reg;
135     res = (m_uint32_t)cp0->reg[MIPS_CP0_COUNT];
136     res += (cpu->vm->clock_divisor * delta);
137     return(res);
138     #endif
139     case MIPS_CP0_INFO:
140     return(MIPS64_R7000_TLB64_ENABLE);
141    
142     case MIPS_CP0_RANDOM:
143     return(mips64_cp0_get_random_reg(cpu));
144    
145     default:
146     return(cp0->reg[cp0_reg]);
147     }
148     }
149    
150     /* Get a cp0 register */
151     m_uint64_t mips64_cp0_get_reg(cpu_mips_t *cpu,u_int cp0_reg)
152     {
153     return(mips64_cp0_get_reg_fast(cpu,cp0_reg));
154     }
155    
156     /* Set a cp0 register */
157     static inline void mips64_cp0_set_reg(cpu_mips_t *cpu,u_int cp0_reg,
158     m_uint64_t val)
159     {
160     mips_cp0_t *cp0 = &cpu->cp0;
161     m_uint32_t delta;
162    
163     switch(cp0_reg) {
164     case MIPS_CP0_STATUS:
165     case MIPS_CP0_CAUSE:
166     cp0->reg[cp0_reg] = val;
167     mips64_update_irq_flag(cpu);
168     break;
169    
170     case MIPS_CP0_PAGEMASK:
171     cp0->reg[cp0_reg] = val & MIPS_TLB_PAGE_MASK;
172     break;
173    
174     case MIPS_CP0_COMPARE:
175     mips64_clear_irq(cpu,7);
176     mips64_update_irq_flag(cpu);
177     cp0->reg[cp0_reg] = val;
178    
179     delta = val - cp0->reg[MIPS_CP0_COUNT];
180     cpu->cp0_virt_cnt_reg = 0;
181     cpu->cp0_virt_cmp_reg = delta / cpu->vm->clock_divisor;
182     break;
183    
184     case MIPS_CP0_COUNT:
185     cp0->reg[cp0_reg] = val;
186    
187     delta = cp0->reg[MIPS_CP0_COMPARE] - val;
188     cpu->cp0_virt_cnt_reg = 0;
189     cpu->cp0_virt_cmp_reg = delta / cpu->vm->clock_divisor;
190     break;
191    
192     case MIPS_CP0_TLB_HI:
193     cp0->reg[cp0_reg] = val & MIPS_CP0_HI_SAFE_MASK;
194     break;
195    
196     case MIPS_CP0_TLB_LO_0:
197     case MIPS_CP0_TLB_LO_1:
198     cp0->reg[cp0_reg] = val & MIPS_CP0_LO_SAFE_MASK;
199     break;
200    
201     case MIPS_CP0_RANDOM:
202     case MIPS_CP0_PRID:
203     case MIPS_CP0_CONFIG:
204     /* read only registers */
205     break;
206    
207     case MIPS_CP0_WIRED:
208     cp0->reg[cp0_reg] = val & MIPS64_TLB_IDX_MASK;
209     break;
210    
211     default:
212     cp0->reg[cp0_reg] = val;
213     }
214     }
215    
216     /* Get a cp0 "set 1" register (R7000) */
217     m_uint64_t mips64_cp0_s1_get_reg(cpu_mips_t *cpu,u_int cp0_s1_reg)
218     {
219     switch(cp0_s1_reg) {
220     case MIPS_CP0_S1_CONFIG:
221     return(0x7F << 25);
222    
223     case MIPS_CP0_S1_IPLLO:
224     return(cpu->cp0.ipl_lo);
225    
226     case MIPS_CP0_S1_IPLHI:
227     return(cpu->cp0.ipl_hi);
228    
229     case MIPS_CP0_S1_INTCTL:
230     return(cpu->cp0.int_ctl);
231    
232     case MIPS_CP0_S1_DERRADDR0:
233     return(cpu->cp0.derraddr0);
234    
235     case MIPS_CP0_S1_DERRADDR1:
236     return(cpu->cp0.derraddr1);
237    
238     default:
239     /* undefined register */
240     cpu_log(cpu->gen,"CP0_S1","trying to read unknown register %u\n",
241     cp0_s1_reg);
242     return(0);
243     }
244     }
245    
246     /* Set a cp0 "set 1" register (R7000) */
247     static inline void mips64_cp0_s1_set_reg(cpu_mips_t *cpu,u_int cp0_s1_reg,
248     m_uint64_t val)
249     {
250     mips_cp0_t *cp0 = &cpu->cp0;
251    
252     switch(cp0_s1_reg) {
253     case MIPS_CP0_S1_IPLLO:
254     cp0->ipl_lo = val;
255     break;
256    
257     case MIPS_CP0_S1_IPLHI:
258     cp0->ipl_hi = val;
259     break;
260    
261     case MIPS_CP0_S1_INTCTL:
262     cp0->int_ctl = val;
263     break;
264    
265     case MIPS_CP0_S1_DERRADDR0:
266     cp0->derraddr0 = val;
267     break;
268    
269     case MIPS_CP0_S1_DERRADDR1:
270     cp0->derraddr1 = val;
271     break;
272    
273     default:
274     cpu_log(cpu->gen,
275     "CP0_S1","trying to set unknown register %u (val=0x%x)\n",
276     cp0_s1_reg,val);
277     }
278     }
279    
280     /* DMFC0 */
281     fastcall void mips64_cp0_exec_dmfc0(cpu_mips_t *cpu,u_int gp_reg,u_int cp0_reg)
282     {
283     cpu->gpr[gp_reg] = mips64_cp0_get_reg_fast(cpu,cp0_reg);
284     }
285    
286     /* DMTC0 */
287     fastcall void mips64_cp0_exec_dmtc0(cpu_mips_t *cpu,u_int gp_reg,u_int cp0_reg)
288     {
289     mips64_cp0_set_reg(cpu,cp0_reg,cpu->gpr[gp_reg]);
290     }
291    
292     /* MFC0 */
293     fastcall void mips64_cp0_exec_mfc0(cpu_mips_t *cpu,u_int gp_reg,u_int cp0_reg)
294     {
295     cpu->gpr[gp_reg] = sign_extend(mips64_cp0_get_reg_fast(cpu,cp0_reg),32);
296     }
297    
298     /* MTC0 */
299     fastcall void mips64_cp0_exec_mtc0(cpu_mips_t *cpu,u_int gp_reg,u_int cp0_reg)
300     {
301     mips64_cp0_set_reg(cpu,cp0_reg,cpu->gpr[gp_reg] & 0xffffffff);
302     }
303    
304     /* CFC0 */
305     fastcall void mips64_cp0_exec_cfc0(cpu_mips_t *cpu,u_int gp_reg,u_int cp0_reg)
306     {
307     cpu->gpr[gp_reg] = sign_extend(mips64_cp0_s1_get_reg(cpu,cp0_reg),32);
308     }
309    
310     /* CTC0 */
311     fastcall void mips64_cp0_exec_ctc0(cpu_mips_t *cpu,u_int gp_reg,u_int cp0_reg)
312     {
313     mips64_cp0_s1_set_reg(cpu,cp0_reg,cpu->gpr[gp_reg] & 0xffffffff);
314     }
315    
316     /* Get the page size corresponding to a page mask */
317     static inline m_uint32_t get_page_size(m_uint32_t page_mask)
318     {
319     return((page_mask + 0x2000) >> 1);
320     }
321    
322     /* Write page size in buffer */
323     static char *get_page_size_str(char *buffer,size_t len,m_uint32_t page_mask)
324     {
325     m_uint32_t page_size;
326    
327     page_size = get_page_size(page_mask);
328    
329     /* Mb ? */
330     if (page_size >= (1024*1024))
331     snprintf(buffer,len,"%uMB",page_size >> 20);
332     else
333     snprintf(buffer,len,"%uKB",page_size >> 10);
334    
335     return buffer;
336     }
337    
338     /* Get the VPN2 mask */
339     static forced_inline m_uint64_t mips64_cp0_get_vpn2_mask(cpu_mips_t *cpu)
340     {
341     if (cpu->addr_mode == 64)
342     return(MIPS_TLB_VPN2_MASK_64);
343     else
344     return(MIPS_TLB_VPN2_MASK_32);
345     }
346    
347     /* TLB lookup */
348     int mips64_cp0_tlb_lookup(cpu_mips_t *cpu,m_uint64_t vaddr,mts_map_t *res)
349     {
350     mips_cp0_t *cp0 = &cpu->cp0;
351     m_uint64_t vpn_addr,vpn2_mask;
352     m_uint64_t page_mask,hi_addr;
353     m_uint32_t page_size,pca;
354     tlb_entry_t *entry;
355     u_int asid;
356     int i;
357    
358     vpn2_mask = mips64_cp0_get_vpn2_mask(cpu);
359     vpn_addr = vaddr & vpn2_mask;
360    
361     asid = cp0->reg[MIPS_CP0_TLB_HI] & MIPS_TLB_ASID_MASK;
362    
363     for(i=0;i<cp0->tlb_entries;i++) {
364     entry = &cp0->tlb[i];
365    
366     page_mask = ~(entry->mask + 0x1FFF);
367     hi_addr = entry->hi & vpn2_mask;
368    
369     if (((vpn_addr & page_mask) == hi_addr) &&
370     ((entry->hi & MIPS_TLB_G_MASK) ||
371     ((entry->hi & MIPS_TLB_ASID_MASK) == asid)))
372     {
373     page_size = get_page_size(entry->mask);
374    
375     if ((vaddr & page_size) == 0) {
376     /* Even Page */
377     if (entry->lo0 & MIPS_TLB_V_MASK) {
378     res->vaddr = vaddr & MIPS_MIN_PAGE_MASK;
379     res->paddr = (entry->lo0 & MIPS_TLB_PFN_MASK) << 6;
380     res->paddr += (res->vaddr & (page_size-1));
381     res->paddr &= cpu->addr_bus_mask;
382    
383     pca = (entry->lo0 & MIPS_TLB_C_MASK);
384     pca >>= MIPS_TLB_C_SHIFT;
385     res->cached = mips64_cca_cached(pca);
386    
387     res->tlb_index = i;
388     return(TRUE);
389     }
390     } else {
391     /* Odd Page */
392     if (entry->lo1 & MIPS_TLB_V_MASK) {
393    
394     res->vaddr = vaddr & MIPS_MIN_PAGE_MASK;
395     res->paddr = (entry->lo1 & MIPS_TLB_PFN_MASK) << 6;
396     res->paddr += (res->vaddr & (page_size-1));
397     res->paddr &= cpu->addr_bus_mask;
398    
399     pca = (entry->lo1 & MIPS_TLB_C_MASK);
400     pca >>= MIPS_TLB_C_SHIFT;
401     res->cached = mips64_cca_cached(pca);
402    
403     res->tlb_index = i;
404     return(TRUE);
405     }
406     }
407    
408     /* Invalid entry */
409     return(FALSE);
410     }
411     }
412    
413     /* No matching entry */
414     return(FALSE);
415     }
416    
417     /*
418     * Map a TLB entry into the MTS.
419     *
420     * We apply the physical address bus masking here.
421     *
422     * TODO: - Manage ASID
423     * - Manage CPU Mode (user,supervisor or kernel)
424     */
425     void mips64_cp0_map_tlb_to_mts(cpu_mips_t *cpu,int index)
426     {
427     m_uint64_t v0_addr,v1_addr,p0_addr,p1_addr;
428     m_uint32_t page_size,pca;
429     tlb_entry_t *entry;
430     int cacheable;
431    
432     entry = &cpu->cp0.tlb[index];
433    
434     page_size = get_page_size(entry->mask);
435     v0_addr = entry->hi & mips64_cp0_get_vpn2_mask(cpu);
436     v1_addr = v0_addr + page_size;
437    
438     if (entry->lo0 & MIPS_TLB_V_MASK) {
439     pca = (entry->lo0 & MIPS_TLB_C_MASK);
440     pca >>= MIPS_TLB_C_SHIFT;
441     cacheable = mips64_cca_cached(pca);
442    
443     p0_addr = (entry->lo0 & MIPS_TLB_PFN_MASK) << 6;
444     cpu->mts_map(cpu,v0_addr,p0_addr & cpu->addr_bus_mask,page_size,
445     cacheable,index);
446     }
447    
448     if (entry->lo1 & MIPS_TLB_V_MASK) {
449     pca = (entry->lo1 & MIPS_TLB_C_MASK);
450     pca >>= MIPS_TLB_C_SHIFT;
451     cacheable = mips64_cca_cached(pca);
452    
453     p1_addr = (entry->lo1 & MIPS_TLB_PFN_MASK) << 6;
454     cpu->mts_map(cpu,v1_addr,p1_addr & cpu->addr_bus_mask,page_size,
455     cacheable,index);
456     }
457     }
458    
459     /*
460     * Unmap a TLB entry in the MTS.
461     */
462     void mips64_cp0_unmap_tlb_to_mts(cpu_mips_t *cpu,int index)
463     {
464     m_uint64_t v0_addr,v1_addr;
465     m_uint32_t page_size;
466     tlb_entry_t *entry;
467    
468     entry = &cpu->cp0.tlb[index];
469    
470     page_size = get_page_size(entry->mask);
471     v0_addr = entry->hi & mips64_cp0_get_vpn2_mask(cpu);
472     v1_addr = v0_addr + page_size;
473    
474     if (entry->lo0 & MIPS_TLB_V_MASK)
475     cpu->mts_unmap(cpu,v0_addr,page_size,MTS_ACC_T,index);
476    
477     if (entry->lo1 & MIPS_TLB_V_MASK)
478     cpu->mts_unmap(cpu,v1_addr,page_size,MTS_ACC_T,index);
479     }
480    
481     /* Map all TLB entries into the MTS */
482     void mips64_cp0_map_all_tlb_to_mts(cpu_mips_t *cpu)
483     {
484     int i;
485    
486     for(i=0;i<cpu->cp0.tlb_entries;i++)
487     mips64_cp0_map_tlb_to_mts(cpu,i);
488     }
489    
490     /* TLBP: Probe a TLB entry */
491     fastcall void mips64_cp0_exec_tlbp(cpu_mips_t *cpu)
492     {
493     mips_cp0_t *cp0 = &cpu->cp0;
494     m_uint64_t hi_reg,asid;
495     m_uint64_t vpn2,vpn2_mask;
496     tlb_entry_t *entry;
497     int i;
498    
499     vpn2_mask = mips64_cp0_get_vpn2_mask(cpu);
500     hi_reg = cp0->reg[MIPS_CP0_TLB_HI];
501     asid = hi_reg & MIPS_TLB_ASID_MASK;
502     vpn2 = hi_reg & vpn2_mask;
503    
504     cp0->reg[MIPS_CP0_INDEX] = 0xffffffff80000000ULL;
505    
506     for(i=0;i<cp0->tlb_entries;i++) {
507     entry = &cp0->tlb[i];
508    
509     if (((entry->hi & vpn2_mask) == vpn2) &&
510     ((entry->hi & MIPS_TLB_G_MASK) ||
511     ((entry->hi & MIPS_TLB_ASID_MASK) == asid)))
512     {
513     cp0->reg[MIPS_CP0_INDEX] = i;
514     #if DEBUG_TLB_ACTIVITY
515     printf("CPU: CP0_TLBP returned %u\n",i);
516     tlb_dump(cpu);
517     #endif
518     }
519     }
520     }
521    
522     /* TLBR: Read Indexed TLB entry */
523     fastcall void mips64_cp0_exec_tlbr(cpu_mips_t *cpu)
524     {
525     mips_cp0_t *cp0 = &cpu->cp0;
526     tlb_entry_t *entry;
527     u_int index;
528    
529     index = cp0->reg[MIPS_CP0_INDEX];
530    
531     #if DEBUG_TLB_ACTIVITY
532     cpu_log(cpu,"TLB","CP0_TLBR: reading entry %u.\n",index);
533     #endif
534    
535     if (index < cp0->tlb_entries)
536     {
537     entry = &cp0->tlb[index];
538    
539     cp0->reg[MIPS_CP0_PAGEMASK] = entry->mask;
540     cp0->reg[MIPS_CP0_TLB_HI] = entry->hi;
541     cp0->reg[MIPS_CP0_TLB_LO_0] = entry->lo0;
542     cp0->reg[MIPS_CP0_TLB_LO_1] = entry->lo1;
543    
544     /*
545     * The G bit must be reported in both Lo0 and Lo1 registers,
546     * and cleared in Hi register.
547     */
548     if (entry->hi & MIPS_TLB_G_MASK) {
549     cp0->reg[MIPS_CP0_TLB_LO_0] |= MIPS_CP0_LO_G_MASK;
550     cp0->reg[MIPS_CP0_TLB_LO_1] |= MIPS_CP0_LO_G_MASK;
551     cp0->reg[MIPS_CP0_TLB_HI] &= ~MIPS_TLB_G_MASK;
552     }
553     }
554     }
555    
556     /* TLBW: Write a TLB entry */
557     static inline void mips64_cp0_exec_tlbw(cpu_mips_t *cpu,u_int index)
558     {
559     mips_cp0_t *cp0 = &cpu->cp0;
560     tlb_entry_t *entry;
561    
562     #if DEBUG_TLB_ACTIVITY
563     cpu_log(cpu,"TLB","CP0_TLBWI: writing entry %u "
564     "[mask=0x%8.8llx,hi=0x%8.8llx,lo0=0x%8.8llx,lo1=0x%8.8llx]\n",
565     index,cp0->reg[MIPS_CP0_PAGEMASK],cp0->reg[MIPS_CP0_TLB_HI],
566     cp0->reg[MIPS_CP0_TLB_LO_0],cp0->reg[MIPS_CP0_TLB_LO_1]);
567     #endif
568    
569     if (index < cp0->tlb_entries)
570     {
571     entry = &cp0->tlb[index];
572    
573     /* Unmap the old entry if it was valid */
574     mips64_cp0_unmap_tlb_to_mts(cpu,index);
575    
576     entry->mask = cp0->reg[MIPS_CP0_PAGEMASK] & MIPS_TLB_PAGE_MASK;
577     entry->hi = cp0->reg[MIPS_CP0_TLB_HI] & ~entry->mask;
578     entry->hi &= MIPS_CP0_HI_SAFE_MASK; /* clear G bit */
579     entry->lo0 = cp0->reg[MIPS_CP0_TLB_LO_0];
580     entry->lo1 = cp0->reg[MIPS_CP0_TLB_LO_1];
581    
582     /* if G bit is set in lo0 and lo1, set it in hi */
583     if ((entry->lo0 & entry->lo1) & MIPS_CP0_LO_G_MASK)
584     entry->hi |= MIPS_TLB_G_MASK;
585    
586     /* Clear G bit in TLB lo0 and lo1 */
587     entry->lo0 &= ~MIPS_CP0_LO_G_MASK;
588     entry->lo1 &= ~MIPS_CP0_LO_G_MASK;
589    
590     /* Inform the MTS subsystem */
591     mips64_cp0_map_tlb_to_mts(cpu,index);
592    
593     #if DEBUG_TLB_ACTIVITY
594     mips64_tlb_dump_entry(cpu,index);
595     #endif
596     }
597     }
598    
599     /* TLBWI: Write Indexed TLB entry */
600     fastcall void mips64_cp0_exec_tlbwi(cpu_mips_t *cpu)
601     {
602     mips64_cp0_exec_tlbw(cpu,cpu->cp0.reg[MIPS_CP0_INDEX]);
603     }
604    
605     /* TLBWR: Write Random TLB entry */
606     fastcall void mips64_cp0_exec_tlbwr(cpu_mips_t *cpu)
607     {
608     mips64_cp0_exec_tlbw(cpu,mips64_cp0_get_random_reg(cpu));
609     }
610    
611     /* Raw dump of the TLB */
612     void mips64_tlb_raw_dump(cpu_gen_t *cpu)
613     {
614     cpu_mips_t *mcpu = CPU_MIPS64(cpu);
615     tlb_entry_t *entry;
616     u_int i;
617    
618     printf("TLB dump:\n");
619    
620     for(i=0;i<mcpu->cp0.tlb_entries;i++) {
621     entry = &mcpu->cp0.tlb[i];
622     printf(" %2d: mask=0x%16.16llx hi=0x%16.16llx "
623     "lo0=0x%16.16llx lo1=0x%16.16llx\n",
624     i, entry->mask, entry->hi, entry->lo0, entry->lo1);
625     }
626    
627     printf("\n");
628     }
629    
630     /* Dump the specified TLB entry */
631     void mips64_tlb_dump_entry(cpu_mips_t *cpu,u_int index)
632     {
633     tlb_entry_t *entry;
634     char buffer[256];
635    
636     entry = &cpu->cp0.tlb[index];
637    
638     /* virtual Address */
639     printf(" %2d: vaddr=0x%8.8llx ",
640     index, entry->hi & mips64_cp0_get_vpn2_mask(cpu));
641    
642     /* global or ASID */
643     if (entry->hi & MIPS_TLB_G_MASK)
644     printf("(global) ");
645     else
646     printf("(asid 0x%2.2llx) ",entry->hi & MIPS_TLB_ASID_MASK);
647    
648     /* 1st page: Lo0 */
649     printf("p0=");
650    
651     if (entry->lo0 & MIPS_TLB_V_MASK)
652     printf("0x%9.9llx",(entry->lo0 & MIPS_TLB_PFN_MASK) << 6);
653     else
654     printf("(invalid) ");
655    
656     printf(" %c ",(entry->lo0 & MIPS_TLB_D_MASK) ? 'D' : ' ');
657    
658     /* 2nd page: Lo1 */
659     printf("p1=");
660    
661     if (entry->lo1 & MIPS_TLB_V_MASK)
662     printf("0x%9.9llx",(entry->lo1 & MIPS_TLB_PFN_MASK) << 6);
663     else
664     printf("(invalid) ");
665    
666     printf(" %c ",(entry->lo1 & MIPS_TLB_D_MASK) ? 'D' : ' ');
667    
668     /* page size */
669     printf(" (%s)\n",get_page_size_str(buffer,sizeof(buffer),entry->mask));
670     }
671    
672     /* Human-Readable dump of the TLB */
673     void mips64_tlb_dump(cpu_gen_t *cpu)
674     {
675     cpu_mips_t *mcpu = CPU_MIPS64(cpu);
676     u_int i;
677    
678     printf("TLB dump:\n");
679    
680     for(i=0;i<mcpu->cp0.tlb_entries;i++)
681     mips64_tlb_dump_entry(mcpu,i);
682    
683     printf("\n");
684     }

  ViewVC Help
Powered by ViewVC 1.1.26