/[dynamips]/upstream/dynamips-0.2.6-RC5/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

Contents of /upstream/dynamips-0.2.6-RC5/cp0.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3 - (show annotations)
Sat Oct 6 16:05:34 2007 UTC (16 years, 5 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.6-RC2/cp0.c
File MIME type: text/plain
File size: 16121 byte(s)
dynamips-0.2.6-RC2

1 /*
2 * Cisco 7200 (Predator) 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 "rbtree.h"
19 #include "mips64.h"
20 #include "dynamips.h"
21 #include "memory.h"
22 #include "device.h"
23 #include "cp0.h"
24
25 /* MIPS cp0 registers names */
26 char *mips64_cp0_reg_names[MIPS64_CP0_REG_NR] = {
27 "index" ,
28 "random",
29 "entry_lo0",
30 "entry_lo1",
31 "context",
32 "pagemask",
33 "wired",
34 "info",
35 "badvaddr",
36 "count",
37 "entry_hi",
38 "compare",
39 "status",
40 "cause",
41 "epc",
42 "prid",
43 "config",
44 "ll_addr",
45 "watch_lo",
46 "watch_hi",
47 "xcontext",
48 "cp0_r21",
49 "cp0_r22",
50 "cp0_r23",
51 "cp0_r24",
52 "cp0_r25",
53 "ecc",
54 "cache_err",
55 "tag_lo",
56 "tag_hi",
57 "err_epc",
58 "cp0_r31",
59 };
60
61 /* Get cp0 register index given its name */
62 int cp0_get_reg_index(char *name)
63 {
64 int i;
65
66 for(i=0;i<MIPS64_CP0_REG_NR;i++)
67 if (!strcmp(mips64_cp0_reg_names[i],name))
68 return(i);
69
70 return(-1);
71 }
72
73 /* Get the CPU operating mode (User,Supervisor or Kernel) - inline version */
74 static forced_inline u_int cp0_get_mode_inline(cpu_mips_t *cpu)
75 {
76 mips_cp0_t *cp0 = &cpu->cp0;
77 u_int cpu_mode;
78
79 cpu_mode = cp0->reg[MIPS_CP0_STATUS] >> MIPS_CP0_STATUS_KSU_SHIFT;
80 cpu_mode &= MIPS_CP0_STATUS_KSU_MASK;
81 return(cpu_mode);
82 }
83
84 /* Get the CPU operating mode (User,Supervisor or Kernel) */
85 u_int cp0_get_mode(cpu_mips_t *cpu)
86 {
87 return(cp0_get_mode_inline(cpu));
88 }
89
90 /* Check that we are running in kernel mode */
91 int cp0_check_kernel_mode(cpu_mips_t *cpu)
92 {
93 u_int cpu_mode;
94
95 cpu_mode = cp0_get_mode(cpu);
96
97 if (cpu_mode != MIPS_CP0_STATUS_KM) {
98 /* XXX Branch delay slot */
99 mips64_trigger_exception(cpu,MIPS_CP0_CAUSE_ILLOP,0);
100 return(1);
101 }
102
103 return(0);
104 }
105
106 /* Get value of random register */
107 static inline u_int cp0_get_random_reg(cpu_mips_t *cpu)
108 {
109 u_int wired;
110
111 /* We use the virtual count register as a basic "random" value */
112 wired = cpu->cp0.reg[MIPS_CP0_WIRED];
113 return(wired + (cpu->cp0_virt_cnt_reg % (cpu->cp0.tlb_entries - wired)));
114 }
115
116 /* Get a cp0 register (fast version) */
117 static inline m_uint64_t cp0_get_reg_fast(cpu_mips_t *cpu,u_int cp0_reg)
118 {
119 mips_cp0_t *cp0 = &cpu->cp0;
120 m_uint32_t delta,res;
121
122 switch(cp0_reg) {
123 case MIPS_CP0_COUNT:
124 delta = cpu->cp0_virt_cmp_reg - cpu->cp0_virt_cnt_reg;
125 res = (m_uint32_t)cp0->reg[MIPS_CP0_COMPARE];
126 res -= cpu->vm->clock_divisor * delta;
127 return(sign_extend(res,32));
128
129 #if 1
130 case MIPS_CP0_COMPARE:
131 return(sign_extend(cp0->reg[MIPS_CP0_COMPARE],32));
132 #else
133 /* really useful and logical ? */
134 case MIPS_CP0_COMPARE:
135 delta = cpu->cp0_virt_cmp_reg - cpu->cp0_virt_cnt_reg;
136 res = (m_uint32_t)cp0->reg[MIPS_CP0_COUNT];
137 res += (cpu->vm->clock_divisor * delta);
138 return(res);
139 #endif
140 case MIPS_CP0_INFO:
141 return(MIPS64_R7000_TLB64_ENABLE);
142
143 case MIPS_CP0_RANDOM:
144 return(cp0_get_random_reg(cpu));
145
146 default:
147 return(cp0->reg[cp0_reg]);
148 }
149 }
150
151 /* Get a cp0 register */
152 m_uint64_t cp0_get_reg(cpu_mips_t *cpu,u_int cp0_reg)
153 {
154 return(cp0_get_reg_fast(cpu,cp0_reg));
155 }
156
157 /* Set a cp0 register */
158 static inline void cp0_set_reg(cpu_mips_t *cpu,u_int cp0_reg,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 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,"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 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,"CP0_S1","trying to set unknown register %u (val=0x%x)\n",
275 cp0_s1_reg,val);
276 }
277 }
278
279 /* DMFC0 */
280 fastcall void cp0_exec_dmfc0(cpu_mips_t *cpu,u_int gp_reg,u_int cp0_reg)
281 {
282 cpu->gpr[gp_reg] = cp0_get_reg_fast(cpu,cp0_reg);
283 }
284
285 /* DMTC0 */
286 fastcall void cp0_exec_dmtc0(cpu_mips_t *cpu,u_int gp_reg,u_int cp0_reg)
287 {
288 cp0_set_reg(cpu,cp0_reg,cpu->gpr[gp_reg]);
289 }
290
291 /* MFC0 */
292 fastcall void cp0_exec_mfc0(cpu_mips_t *cpu,u_int gp_reg,u_int cp0_reg)
293 {
294 cpu->gpr[gp_reg] = sign_extend(cp0_get_reg_fast(cpu,cp0_reg),32);
295 }
296
297 /* MTC0 */
298 fastcall void cp0_exec_mtc0(cpu_mips_t *cpu,u_int gp_reg,u_int cp0_reg)
299 {
300 cp0_set_reg(cpu,cp0_reg,cpu->gpr[gp_reg] & 0xffffffff);
301 }
302
303 /* CFC0 */
304 fastcall void cp0_exec_cfc0(cpu_mips_t *cpu,u_int gp_reg,u_int cp0_reg)
305 {
306 cpu->gpr[gp_reg] = sign_extend(cp0_s1_get_reg(cpu,cp0_reg),32);
307 }
308
309 /* CTC0 */
310 fastcall void cp0_exec_ctc0(cpu_mips_t *cpu,u_int gp_reg,u_int cp0_reg)
311 {
312 cp0_s1_set_reg(cpu,cp0_reg,cpu->gpr[gp_reg] & 0xffffffff);
313 }
314
315 /* Get the page size corresponding to a page mask */
316 static inline m_uint32_t get_page_size(m_uint32_t page_mask)
317 {
318 return((page_mask + 0x2000) >> 1);
319 }
320
321 /* Write page size in buffer */
322 static char *get_page_size_str(char *buffer,size_t len,m_uint32_t page_mask)
323 {
324 m_uint32_t page_size;
325
326 page_size = get_page_size(page_mask);
327
328 /* Mb ? */
329 if (page_size >= (1024*1024))
330 snprintf(buffer,len,"%uMB",page_size >> 20);
331 else
332 snprintf(buffer,len,"%uKB",page_size >> 10);
333
334 return buffer;
335 }
336
337 /* TLB lookup */
338 int cp0_tlb_lookup(cpu_mips_t *cpu,m_uint64_t vaddr,mts_map_t *res)
339 {
340 mips_cp0_t *cp0 = &cpu->cp0;
341 m_uint64_t v0_addr,v1_addr;
342 m_uint32_t page_size,pca;
343 tlb_entry_t *entry;
344 int i;
345
346 for(i=0;i<cp0->tlb_entries;i++) {
347 entry = &cp0->tlb[i];
348
349 page_size = get_page_size(entry->mask);
350 v0_addr = entry->hi & MIPS_TLB_VPN2_MASK;
351 v1_addr = v0_addr + page_size;
352
353 /* virtual address in entry 0 ? */
354 if ((entry->lo0 & MIPS_TLB_V_MASK) &&
355 (vaddr >= v0_addr) && (vaddr < v1_addr))
356 {
357 res->vaddr = v0_addr;
358 res->paddr = (entry->lo0 & MIPS_TLB_PFN_MASK) << 6;
359 res->paddr &= cpu->addr_bus_mask;
360 res->len = page_size;
361
362 pca = (entry->lo0 & MIPS_TLB_C_MASK);
363 pca >>= MIPS_TLB_C_SHIFT;
364 res->cached = mips64_cca_cached(pca);
365
366 res->tlb_index = i;
367 return(TRUE);
368 }
369
370 /* virtual address in entry 1 ? */
371 if ((entry->lo1 & MIPS_TLB_V_MASK) &&
372 (vaddr >= v1_addr) && ((vaddr - v1_addr) < page_size))
373 {
374 res->vaddr = v1_addr;
375 res->paddr = (entry->lo1 & MIPS_TLB_PFN_MASK) << 6;
376 res->paddr &= cpu->addr_bus_mask;
377 res->len = page_size;
378
379 pca = (entry->lo1 & MIPS_TLB_C_MASK);
380 pca >>= MIPS_TLB_C_SHIFT;
381 res->cached = mips64_cca_cached(pca);
382
383 res->tlb_index = i;
384 return(TRUE);
385 }
386 }
387
388 return(FALSE);
389 }
390
391 /*
392 * Map a TLB entry into the MTS.
393 *
394 * We apply the physical address bus masking here.
395 *
396 * TODO: - Manage ASID
397 * - Manage CPU Mode (user,supervisor or kernel)
398 */
399 void cp0_map_tlb_to_mts(cpu_mips_t *cpu,int index)
400 {
401 m_uint64_t v0_addr,v1_addr,p0_addr,p1_addr;
402 m_uint32_t page_size,pca;
403 tlb_entry_t *entry;
404 int cacheable;
405
406 entry = &cpu->cp0.tlb[index];
407
408 page_size = get_page_size(entry->mask);
409 v0_addr = entry->hi & MIPS_TLB_VPN2_MASK;
410 v1_addr = v0_addr + page_size;
411
412 if (entry->lo0 & MIPS_TLB_V_MASK) {
413 pca = (entry->lo0 & MIPS_TLB_C_MASK);
414 pca >>= MIPS_TLB_C_SHIFT;
415 cacheable = mips64_cca_cached(pca);
416
417 p0_addr = (entry->lo0 & MIPS_TLB_PFN_MASK) << 6;
418 cpu->mts_map(cpu,v0_addr,p0_addr & cpu->addr_bus_mask,page_size,
419 cacheable,index);
420 }
421
422 if (entry->lo1 & MIPS_TLB_V_MASK) {
423 pca = (entry->lo1 & MIPS_TLB_C_MASK);
424 pca >>= MIPS_TLB_C_SHIFT;
425 cacheable = mips64_cca_cached(pca);
426
427 p1_addr = (entry->lo1 & MIPS_TLB_PFN_MASK) << 6;
428 cpu->mts_map(cpu,v1_addr,p1_addr & cpu->addr_bus_mask,page_size,
429 cacheable,index);
430 }
431 }
432
433 /*
434 * Unmap a TLB entry in the MTS.
435 */
436 void cp0_unmap_tlb_to_mts(cpu_mips_t *cpu,int index)
437 {
438 m_uint64_t v0_addr,v1_addr;
439 m_uint32_t page_size;
440 tlb_entry_t *entry;
441
442 entry = &cpu->cp0.tlb[index];
443
444 page_size = get_page_size(entry->mask);
445 v0_addr = entry->hi & MIPS_TLB_VPN2_MASK;
446 v1_addr = v0_addr + page_size;
447
448 if (entry->lo0 & MIPS_TLB_V_MASK)
449 cpu->mts_unmap(cpu,v0_addr,page_size,MTS_ACC_T,index);
450
451 if (entry->lo1 & MIPS_TLB_V_MASK)
452 cpu->mts_unmap(cpu,v1_addr,page_size,MTS_ACC_T,index);
453 }
454
455 /* Map all TLB entries into the MTS */
456 void cp0_map_all_tlb_to_mts(cpu_mips_t *cpu)
457 {
458 int i;
459
460 for(i=0;i<cpu->cp0.tlb_entries;i++)
461 cp0_map_tlb_to_mts(cpu,i);
462 }
463
464 /* TLBP: Probe a TLB entry */
465 fastcall void cp0_exec_tlbp(cpu_mips_t *cpu)
466 {
467 mips_cp0_t *cp0 = &cpu->cp0;
468 m_uint64_t hi_reg,asid,vpn2;
469 tlb_entry_t *entry;
470 int i;
471
472 hi_reg = cp0->reg[MIPS_CP0_TLB_HI];
473 asid = hi_reg & MIPS_TLB_ASID_MASK;
474 vpn2 = hi_reg & MIPS_TLB_VPN2_MASK;
475
476 cp0->reg[MIPS_CP0_INDEX] = 0xffffffff80000000ULL;
477
478 for(i=0;i<cp0->tlb_entries;i++) {
479 entry = &cp0->tlb[i];
480
481 if (((entry->hi & MIPS_TLB_VPN2_MASK) == vpn2) &&
482 ((entry->hi & MIPS_TLB_G_MASK) ||
483 ((entry->hi & MIPS_TLB_ASID_MASK) == asid)))
484 {
485 cp0->reg[MIPS_CP0_INDEX] = i;
486 #if DEBUG_TLB_ACTIVITY
487 printf("CPU: CP0_TLBP returned %u\n",i);
488 tlb_dump(cpu);
489 #endif
490 }
491 }
492 }
493
494 /* TLBR: Read Indexed TLB entry */
495 fastcall void cp0_exec_tlbr(cpu_mips_t *cpu)
496 {
497 mips_cp0_t *cp0 = &cpu->cp0;
498 tlb_entry_t *entry;
499 u_int index;
500
501 index = cp0->reg[MIPS_CP0_INDEX];
502
503 #if DEBUG_TLB_ACTIVITY
504 cpu_log(cpu,"TLB","CP0_TLBR: reading entry %u.\n",index);
505 #endif
506
507 if (index < cp0->tlb_entries)
508 {
509 entry = &cp0->tlb[index];
510
511 cp0->reg[MIPS_CP0_PAGEMASK] = entry->mask;
512 cp0->reg[MIPS_CP0_TLB_HI] = entry->hi;
513 cp0->reg[MIPS_CP0_TLB_LO_0] = entry->lo0;
514 cp0->reg[MIPS_CP0_TLB_LO_1] = entry->lo1;
515
516 /*
517 * The G bit must be reported in both Lo0 and Lo1 registers,
518 * and cleared in Hi register.
519 */
520 if (entry->hi & MIPS_TLB_G_MASK) {
521 cp0->reg[MIPS_CP0_TLB_LO_0] |= MIPS_CP0_LO_G_MASK;
522 cp0->reg[MIPS_CP0_TLB_LO_1] |= MIPS_CP0_LO_G_MASK;
523 cp0->reg[MIPS_CP0_TLB_HI] &= ~MIPS_TLB_G_MASK;
524 }
525 }
526 }
527
528 /* TLBW: Write a TLB entry */
529 static inline void cp0_exec_tlbw(cpu_mips_t *cpu,u_int index)
530 {
531 mips_cp0_t *cp0 = &cpu->cp0;
532 tlb_entry_t *entry;
533
534 #if DEBUG_TLB_ACTIVITY
535 cpu_log(cpu,"TLB","CP0_TLBWI: writing entry %u "
536 "[mask=0x%8.8llx,hi=0x%8.8llx,lo0=0x%8.8llx,lo1=0x%8.8llx]\n",
537 index,cp0->reg[MIPS_CP0_PAGEMASK],cp0->reg[MIPS_CP0_TLB_HI],
538 cp0->reg[MIPS_CP0_TLB_LO_0],cp0->reg[MIPS_CP0_TLB_LO_1]);
539 #endif
540
541 if (index < cp0->tlb_entries)
542 {
543 entry = &cp0->tlb[index];
544
545 /* Unmap the old entry if it was valid */
546 cp0_unmap_tlb_to_mts(cpu,index);
547
548 entry->mask = cp0->reg[MIPS_CP0_PAGEMASK] & MIPS_TLB_PAGE_MASK;
549 entry->hi = cp0->reg[MIPS_CP0_TLB_HI] & ~entry->mask;
550 entry->hi &= MIPS_CP0_HI_SAFE_MASK; /* clear G bit */
551 entry->lo0 = cp0->reg[MIPS_CP0_TLB_LO_0];
552 entry->lo1 = cp0->reg[MIPS_CP0_TLB_LO_1];
553
554 /* if G bit is set in lo0 and lo1, set it in hi */
555 if ((entry->lo0 & entry->lo1) & MIPS_CP0_LO_G_MASK)
556 entry->hi |= MIPS_TLB_G_MASK;
557
558 /* Clear G bit in TLB lo0 and lo1 */
559 entry->lo0 &= ~MIPS_CP0_LO_G_MASK;
560 entry->lo1 &= ~MIPS_CP0_LO_G_MASK;
561
562 /* Inform the MTS subsystem */
563 cp0_map_tlb_to_mts(cpu,index);
564
565 #if DEBUG_TLB_ACTIVITY
566 tlb_dump_entry(cpu,index);
567 #endif
568 }
569 }
570
571 /* TLBWI: Write Indexed TLB entry */
572 fastcall void cp0_exec_tlbwi(cpu_mips_t *cpu)
573 {
574 cp0_exec_tlbw(cpu,cpu->cp0.reg[MIPS_CP0_INDEX]);
575 }
576
577 /* TLBWR: Write Random TLB entry */
578 fastcall void cp0_exec_tlbwr(cpu_mips_t *cpu)
579 {
580 cp0_exec_tlbw(cpu,cp0_get_random_reg(cpu));
581 }
582
583 /* Raw dump of the TLB */
584 void tlb_raw_dump(cpu_mips_t *cpu)
585 {
586 tlb_entry_t *entry;
587 u_int i;
588
589 printf("TLB dump:\n");
590
591 for(i=0;i<cpu->cp0.tlb_entries;i++) {
592 entry = &cpu->cp0.tlb[i];
593 printf(" %2d: mask=0x%16.16llx hi=0x%16.16llx "
594 "lo0=0x%16.16llx lo1=0x%16.16llx\n",
595 i, entry->mask, entry->hi, entry->lo0, entry->lo1);
596 }
597
598 printf("\n");
599 }
600
601 /* Dump the specified TLB entry */
602 void tlb_dump_entry(cpu_mips_t *cpu,u_int index)
603 {
604 tlb_entry_t *entry;
605 char buffer[256];
606
607 entry = &cpu->cp0.tlb[index];
608
609 /* virtual Address */
610 printf(" %2d: vaddr=0x%8.8llx ", index, entry->hi & MIPS_TLB_VPN2_MASK);
611
612 /* global or ASID */
613 if (entry->hi & MIPS_TLB_G_MASK)
614 printf("(global) ");
615 else
616 printf("(asid 0x%2.2llx) ",entry->hi & MIPS_TLB_ASID_MASK);
617
618 /* 1st page: Lo0 */
619 printf("p0=");
620
621 if (entry->lo0 & MIPS_TLB_V_MASK)
622 printf("0x%9.9llx",(entry->lo0 & MIPS_TLB_PFN_MASK) << 6);
623 else
624 printf("(invalid) ");
625
626 printf(" %c ",(entry->lo0 & MIPS_TLB_D_MASK) ? 'D' : ' ');
627
628 /* 2nd page: Lo1 */
629 printf("p1=");
630
631 if (entry->lo1 & MIPS_TLB_V_MASK)
632 printf("0x%9.9llx",(entry->lo1 & MIPS_TLB_PFN_MASK) << 6);
633 else
634 printf("(invalid) ");
635
636 printf(" %c ",(entry->lo1 & MIPS_TLB_D_MASK) ? 'D' : ' ');
637
638 /* page size */
639 printf(" (%s)\n",get_page_size_str(buffer,sizeof(buffer),entry->mask));
640 }
641
642 /* Human-Readable dump of the TLB */
643 void tlb_dump(cpu_mips_t *cpu)
644 {
645 u_int i;
646
647 printf("TLB dump:\n");
648
649 for(i=0;i<cpu->cp0.tlb_entries;i++)
650 tlb_dump_entry(cpu,i);
651
652 printf("\n");
653 }

  ViewVC Help
Powered by ViewVC 1.1.26