/[dynamips]/upstream/dynamips-0.2.7-RC2/mips_mts.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.7-RC2/mips_mts.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8 - (show annotations)
Sat Oct 6 16:24:54 2007 UTC (12 years, 1 month ago) by dpavlin
File MIME type: text/plain
File size: 19459 byte(s)
dynamips-0.2.7-RC2

1 /*
2 * Cisco router simulation platform.
3 * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)
4 *
5 * Template code for MTS.
6 */
7
8 #define MTS_ENTRY MTS_NAME(entry_t)
9 #define MTS_CACHE(cpu) ( cpu->mts_u. MTS_NAME(cache) )
10
11 /* Forward declarations */
12 static forced_inline void *MTS_PROTO(access)(cpu_mips_t *cpu,m_uint64_t vaddr,
13 u_int op_code,u_int op_size,
14 u_int op_type,m_uint64_t *data,
15 u_int *exc);
16
17 static fastcall int MTS_PROTO(translate)(cpu_mips_t *cpu,m_uint64_t vaddr,
18 m_uint32_t *phys_page);
19
20 /* Initialize the MTS subsystem for the specified CPU */
21 int MTS_PROTO(init)(cpu_mips_t *cpu)
22 {
23 size_t len;
24
25 /* Initialize the cache entries to 0 (empty) */
26 len = MTS_NAME_UP(HASH_SIZE) * sizeof(MTS_ENTRY);
27 if (!(MTS_CACHE(cpu) = malloc(len)))
28 return(-1);
29
30 memset(MTS_CACHE(cpu),0xFF,len);
31 cpu->mts_lookups = 0;
32 cpu->mts_misses = 0;
33 return(0);
34 }
35
36 /* Free memory used by MTS */
37 void MTS_PROTO(shutdown)(cpu_mips_t *cpu)
38 {
39 /* Free the cache itself */
40 free(MTS_CACHE(cpu));
41 MTS_CACHE(cpu) = NULL;
42 }
43
44 /* Show MTS detailed information (debugging only!) */
45 void MTS_PROTO(show_stats)(cpu_gen_t *gen_cpu)
46 {
47 cpu_mips_t *cpu = CPU_MIPS64(gen_cpu);
48 #if DEBUG_MTS_MAP_VIRT
49 MTS_ENTRY *entry;
50 u_int i,count;
51 #endif
52
53 printf("\nCPU%u: MTS%d statistics:\n",cpu->gen->id,MTS_ADDR_SIZE);
54
55 #if DEBUG_MTS_MAP_VIRT
56 /* Valid hash entries */
57 for(count=0,i=0;i<MTS_NAME_UP(HASH_SIZE);i++) {
58 entry = &(MTS_CACHE(cpu)[i]);
59
60 if (!(entry->gvpa & MTS_INV_ENTRY_MASK)) {
61 printf(" %4u: vaddr=0x%8.8llx, paddr=0x%8.8llx, hpa=%p\n",
62 i,(m_uint64_t)entry->gvpa,(m_uint64_t)entry->gppa,
63 (void *)entry->hpa);
64 count++;
65 }
66 }
67
68 printf(" %u/%u valid hash entries.\n",count,MTS_NAME_UP(HASH_SIZE));
69 #endif
70
71 printf(" Total lookups: %llu, misses: %llu, efficiency: %g%%\n",
72 cpu->mts_lookups, cpu->mts_misses,
73 100 - ((double)(cpu->mts_misses*100)/
74 (double)cpu->mts_lookups));
75 }
76
77 /* Invalidate the complete MTS cache */
78 void MTS_PROTO(invalidate_cache)(cpu_mips_t *cpu)
79 {
80 size_t len;
81
82 len = MTS_NAME_UP(HASH_SIZE) * sizeof(MTS_ENTRY);
83 memset(MTS_CACHE(cpu),0xFF,len);
84 }
85
86 /* Invalidate partially the MTS cache, given a TLB entry index */
87 void MTS_PROTO(invalidate_tlb_entry)(cpu_mips_t *cpu,u_int tlb_index)
88 {
89 MTS_PROTO(invalidate_cache)(cpu);
90 }
91
92 /*
93 * MTS mapping.
94 *
95 * It is NOT inlined since it triggers a GCC bug on my config (x86, GCC 3.3.5)
96 */
97 static no_inline MTS_ENTRY *
98 MTS_PROTO(map)(cpu_mips_t *cpu,u_int op_type,mts_map_t *map,
99 MTS_ENTRY *entry,MTS_ENTRY *alt_entry)
100 {
101 struct vdevice *dev;
102 m_uint32_t offset;
103 m_iptr_t host_ptr;
104 int cow;
105
106 if (!(dev = dev_lookup(cpu->vm,map->paddr,map->cached)))
107 return NULL;
108
109 if (dev->flags & VDEVICE_FLAG_SPARSE) {
110 host_ptr = dev_sparse_get_host_addr(cpu->vm,dev,map->paddr,op_type,&cow);
111
112 entry->gvpa = map->vaddr;
113 entry->gppa = map->paddr;
114 entry->hpa = host_ptr;
115 entry->flags = (cow) ? MTS_FLAG_COW : 0;
116 return entry;
117 }
118
119 if (!dev->host_addr || (dev->flags & VDEVICE_FLAG_NO_MTS_MMAP)) {
120 offset = map->paddr - dev->phys_addr;
121
122 alt_entry->gvpa = map->vaddr;
123 alt_entry->gppa = map->paddr;
124 alt_entry->hpa = (dev->id << MTS_DEVID_SHIFT) + offset;
125 alt_entry->flags = MTS_FLAG_DEV;
126 return alt_entry;
127 }
128
129 entry->gvpa = map->vaddr;
130 entry->gppa = map->paddr;
131 entry->hpa = dev->host_addr + (map->paddr - dev->phys_addr);
132 entry->flags = 0;
133
134 return entry;
135 }
136
137 /* MTS lookup */
138 static void *MTS_PROTO(lookup)(cpu_mips_t *cpu,m_uint64_t vaddr)
139 {
140 m_uint64_t data;
141 u_int exc;
142 return(MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LOOKUP,4,MTS_READ,
143 &data,&exc));
144 }
145
146 /* === MIPS Memory Operations ============================================= */
147
148 /* LB: Load Byte */
149 fastcall u_int MTS_PROTO(lb)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
150 {
151 m_uint64_t data;
152 void *haddr;
153 u_int exc;
154
155 haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LB,1,MTS_READ,&data,&exc);
156 if (likely(haddr != NULL)) data = *(m_uint8_t *)haddr;
157 if (likely(!exc)) cpu->gpr[reg] = sign_extend(data,8);
158 return(exc);
159 }
160
161 /* LBU: Load Byte Unsigned */
162 fastcall u_int MTS_PROTO(lbu)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
163 {
164 m_uint64_t data;
165 void *haddr;
166 u_int exc;
167
168 haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LBU,1,MTS_READ,&data,&exc);
169 if (likely(haddr != NULL)) data = *(m_uint8_t *)haddr;
170 if (likely(!exc)) cpu->gpr[reg] = data & 0xff;
171 return(exc);
172 }
173
174 /* LH: Load Half-Word */
175 fastcall u_int MTS_PROTO(lh)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
176 {
177 m_uint64_t data;
178 void *haddr;
179 u_int exc;
180
181 haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LH,2,MTS_READ,&data,&exc);
182 if (likely(haddr != NULL)) data = vmtoh16(*(m_uint16_t *)haddr);
183 if (likely(!exc)) cpu->gpr[reg] = sign_extend(data,16);
184 return(exc);
185 }
186
187 /* LHU: Load Half-Word Unsigned */
188 fastcall u_int MTS_PROTO(lhu)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
189 {
190 m_uint64_t data;
191 void *haddr;
192 u_int exc;
193
194 haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LHU,2,MTS_READ,&data,&exc);
195 if (likely(haddr != NULL)) data = vmtoh16(*(m_uint16_t *)haddr);
196 if (likely(!exc)) cpu->gpr[reg] = data & 0xffff;
197 return(exc);
198 }
199
200 /* LW: Load Word */
201 fastcall u_int MTS_PROTO(lw)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
202 {
203 m_uint64_t data;
204 void *haddr;
205 u_int exc;
206
207 haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LW,4,MTS_READ,&data,&exc);
208 if (likely(haddr != NULL)) data = vmtoh32(*(m_uint32_t *)haddr);
209 if (likely(!exc)) cpu->gpr[reg] = sign_extend(data,32);
210 return(exc);
211 }
212
213 /* LWU: Load Word Unsigned */
214 fastcall u_int MTS_PROTO(lwu)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
215 {
216 m_uint64_t data;
217 void *haddr;
218 u_int exc;
219
220 haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LWU,4,MTS_READ,&data,&exc);
221 if (likely(haddr != NULL)) data = vmtoh32(*(m_uint32_t *)haddr);
222 if (likely(!exc)) cpu->gpr[reg] = data & 0xffffffff;
223 return(exc);
224 }
225
226 /* LD: Load Double-Word */
227 fastcall u_int MTS_PROTO(ld)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
228 {
229 m_uint64_t data;
230 void *haddr;
231 u_int exc;
232
233 haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LD,8,MTS_READ,&data,&exc);
234 if (likely(haddr != NULL)) data = vmtoh64(*(m_uint64_t *)haddr);
235 if (likely(!exc)) cpu->gpr[reg] = data;
236 return(exc);
237 }
238
239 /* SB: Store Byte */
240 fastcall u_int MTS_PROTO(sb)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
241 {
242 m_uint64_t data;
243 void *haddr;
244 u_int exc;
245
246 data = cpu->gpr[reg] & 0xff;
247 haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SB,1,MTS_WRITE,&data,&exc);
248 if (likely(haddr != NULL)) *(m_uint8_t *)haddr = data;
249 return(exc);
250 }
251
252 /* SH: Store Half-Word */
253 fastcall u_int MTS_PROTO(sh)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
254 {
255 m_uint64_t data;
256 void *haddr;
257 u_int exc;
258
259 data = cpu->gpr[reg] & 0xffff;
260 haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SH,2,MTS_WRITE,&data,&exc);
261 if (likely(haddr != NULL)) *(m_uint16_t *)haddr = htovm16(data);
262 return(exc);
263 }
264
265 /* SW: Store Word */
266 fastcall u_int MTS_PROTO(sw)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
267 {
268 m_uint64_t data;
269 void *haddr;
270 u_int exc;
271
272 data = cpu->gpr[reg] & 0xffffffff;
273 haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SW,4,MTS_WRITE,&data,&exc);
274 if (likely(haddr != NULL)) *(m_uint32_t *)haddr = htovm32(data);
275 return(exc);
276 }
277
278 /* SD: Store Double-Word */
279 fastcall u_int MTS_PROTO(sd)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
280 {
281 m_uint64_t data;
282 void *haddr;
283 u_int exc;
284
285 data = cpu->gpr[reg];
286 haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SD,8,MTS_WRITE,&data,&exc);
287 if (likely(haddr != NULL)) *(m_uint64_t *)haddr = htovm64(data);
288 return(exc);
289 }
290
291 /* LDC1: Load Double-Word To Coprocessor 1 */
292 fastcall u_int MTS_PROTO(ldc1)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
293 {
294 m_uint64_t data;
295 void *haddr;
296 u_int exc;
297
298 haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LDC1,8,MTS_READ,&data,&exc);
299 if (likely(haddr != NULL)) data = vmtoh64(*(m_uint64_t *)haddr);
300 if (likely(!exc)) cpu->fpu.reg[reg] = data;
301 return(exc);
302 }
303
304 /* LWL: Load Word Left */
305 fastcall u_int MTS_PROTO(lwl)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
306 {
307 m_uint64_t r_mask,naddr;
308 m_uint64_t data;
309 u_int m_shift;
310 void *haddr;
311 u_int exc;
312
313 naddr = vaddr & ~(0x03);
314 haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_LWL,4,MTS_READ,&data,&exc);
315
316 if (likely(haddr != NULL))
317 data = vmtoh32(*(m_uint32_t *)haddr);
318
319 if (likely(!exc)) {
320 m_shift = (vaddr & 0x03) << 3;
321 r_mask = (1ULL << m_shift) - 1;
322 data <<= m_shift;
323
324 cpu->gpr[reg] &= r_mask;
325 cpu->gpr[reg] |= data;
326 cpu->gpr[reg] = sign_extend(cpu->gpr[reg],32);
327 }
328 return(exc);
329 }
330
331 /* LWR: Load Word Right */
332 fastcall u_int MTS_PROTO(lwr)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
333 {
334 m_uint64_t r_mask,naddr;
335 m_uint64_t data;
336 u_int m_shift;
337 void *haddr;
338 u_int exc;
339
340 naddr = vaddr & ~(0x03);
341 haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_LWR,4,MTS_READ,&data,&exc);
342
343 if (likely(haddr != NULL))
344 data = vmtoh32(*(m_uint32_t *)haddr);
345
346 if (likely(!exc)) {
347 m_shift = ((vaddr & 0x03) + 1) << 3;
348 r_mask = (1ULL << m_shift) - 1;
349
350 data = sign_extend(data >> (32 - m_shift),32);
351 r_mask = sign_extend(r_mask,32);
352
353 cpu->gpr[reg] &= ~r_mask;
354 cpu->gpr[reg] |= data;
355 }
356 return(exc);
357 }
358
359 /* LDL: Load Double-Word Left */
360 fastcall u_int MTS_PROTO(ldl)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
361 {
362 m_uint64_t r_mask,naddr;
363 m_uint64_t data;
364 u_int m_shift;
365 void *haddr;
366 u_int exc;
367
368 naddr = vaddr & ~(0x07);
369 haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_LDL,8,MTS_READ,&data,&exc);
370
371 if (likely(haddr != NULL))
372 data = vmtoh64(*(m_uint64_t *)haddr);
373
374 if (likely(!exc)) {
375 m_shift = (vaddr & 0x07) << 3;
376 r_mask = (1ULL << m_shift) - 1;
377 data <<= m_shift;
378
379 cpu->gpr[reg] &= r_mask;
380 cpu->gpr[reg] |= data;
381 }
382 return(exc);
383 }
384
385 /* LDR: Load Double-Word Right */
386 fastcall u_int MTS_PROTO(ldr)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
387 {
388 m_uint64_t r_mask,naddr;
389 m_uint64_t data;
390 u_int m_shift;
391 void *haddr;
392 u_int exc;
393
394 naddr = vaddr & ~(0x07);
395 haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_LDR,8,MTS_READ,&data,&exc);
396
397 if (likely(haddr != NULL))
398 data = vmtoh64(*(m_uint64_t *)haddr);
399
400 if (likely(!exc)) {
401 m_shift = ((vaddr & 0x07) + 1) << 3;
402 r_mask = (1ULL << m_shift) - 1;
403 data >>= (64 - m_shift);
404
405 cpu->gpr[reg] &= ~r_mask;
406 cpu->gpr[reg] |= data;
407 }
408 return(exc);
409 }
410
411 /* SWL: Store Word Left */
412 fastcall u_int MTS_PROTO(swl)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
413 {
414 m_uint64_t d_mask,naddr;
415 m_uint64_t data;
416 u_int r_shift;
417 void *haddr;
418 u_int exc;
419
420 naddr = vaddr & ~(0x03ULL);
421 haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SWL,4,MTS_READ,&data,&exc);
422 if (unlikely(exc)) return(exc);
423
424 if (likely(haddr != NULL))
425 data = vmtoh32(*(m_uint32_t *)haddr);
426
427 r_shift = (vaddr & 0x03) << 3;
428 d_mask = 0xffffffff >> r_shift;
429
430 data &= ~d_mask;
431 data |= (cpu->gpr[reg] & 0xffffffff) >> r_shift;
432
433 haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SWL,4,MTS_WRITE,&data,&exc);
434 if (likely(haddr != NULL)) *(m_uint32_t *)haddr = htovm32(data);
435 return(exc);
436 }
437
438 /* SWR: Store Word Right */
439 fastcall u_int MTS_PROTO(swr)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
440 {
441 m_uint64_t d_mask,naddr;
442 m_uint64_t data;
443 u_int r_shift;
444 void *haddr;
445 u_int exc;
446
447 naddr = vaddr & ~(0x03);
448 haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SWR,4,MTS_READ,&data,&exc);
449 if (unlikely(exc)) return(exc);
450
451 if (likely(haddr != NULL))
452 data = vmtoh32(*(m_uint32_t *)haddr);
453
454 r_shift = ((vaddr & 0x03) + 1) << 3;
455 d_mask = 0xffffffff >> r_shift;
456
457 data &= d_mask;
458 data |= (cpu->gpr[reg] << (32 - r_shift)) & 0xffffffff;
459
460 haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SWR,4,MTS_WRITE,&data,&exc);
461 if (likely(haddr != NULL)) *(m_uint32_t *)haddr = htovm32(data);
462 return(exc);
463 }
464
465 /* SDL: Store Double-Word Left */
466 fastcall u_int MTS_PROTO(sdl)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
467 {
468 m_uint64_t d_mask,naddr;
469 m_uint64_t data;
470 u_int r_shift;
471 void *haddr;
472 u_int exc;
473
474 naddr = vaddr & ~(0x07);
475 haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SDL,8,MTS_READ,&data,&exc);
476 if (unlikely(exc)) return(exc);
477
478 if (likely(haddr != NULL))
479 data = vmtoh64(*(m_uint64_t *)haddr);
480
481 r_shift = (vaddr & 0x07) << 3;
482 d_mask = 0xffffffffffffffffULL >> r_shift;
483
484 data &= ~d_mask;
485 data |= cpu->gpr[reg] >> r_shift;
486
487 haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SDL,8,MTS_WRITE,&data,&exc);
488 if (likely(haddr != NULL)) *(m_uint64_t *)haddr = htovm64(data);
489 return(exc);
490 }
491
492 /* SDR: Store Double-Word Right */
493 fastcall u_int MTS_PROTO(sdr)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
494 {
495 m_uint64_t d_mask,naddr;
496 m_uint64_t data;
497 u_int r_shift;
498 void *haddr;
499 u_int exc;
500
501 naddr = vaddr & ~(0x07);
502 haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SDR,8,MTS_READ,&data,&exc);
503 if (unlikely(exc)) return(exc);
504
505 if (likely(haddr != NULL))
506 data = vmtoh64(*(m_uint64_t *)haddr);
507
508 r_shift = ((vaddr & 0x07) + 1) << 3;
509 d_mask = 0xffffffffffffffffULL >> r_shift;
510
511 data &= d_mask;
512 data |= cpu->gpr[reg] << (64 - r_shift);
513
514 haddr = MTS_PROTO(access)(cpu,naddr,MIPS_MEMOP_SDR,8,MTS_WRITE,&data,&exc);
515 if (likely(haddr != NULL)) *(m_uint64_t *)haddr = htovm64(data);
516 return(exc);
517 }
518
519 /* LL: Load Linked */
520 fastcall u_int MTS_PROTO(ll)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
521 {
522 m_uint64_t data;
523 void *haddr;
524 u_int exc;
525
526 haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_LL,4,MTS_READ,&data,&exc);
527 if (likely(haddr != NULL)) data = vmtoh32(*(m_uint32_t *)haddr);
528
529 if (likely(!exc)) {
530 cpu->gpr[reg] = sign_extend(data,32);
531 cpu->ll_bit = 1;
532 }
533
534 return(exc);
535 }
536
537 /* SC: Store Conditional */
538 fastcall u_int MTS_PROTO(sc)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
539 {
540 m_uint64_t data;
541 void *haddr;
542 u_int exc = 0;
543
544 if (cpu->ll_bit) {
545 data = cpu->gpr[reg] & 0xffffffff;
546 haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SC,4,MTS_WRITE,
547 &data,&exc);
548 if (likely(haddr != NULL)) *(m_uint32_t *)haddr = htovm32(data);
549 }
550
551 if (likely(!exc))
552 cpu->gpr[reg] = cpu->ll_bit;
553 return(exc);
554 }
555
556 /* SDC1: Store Double-Word from Coprocessor 1 */
557 fastcall u_int MTS_PROTO(sdc1)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int reg)
558 {
559 m_uint64_t data;
560 void *haddr;
561 u_int exc;
562
563 data = cpu->fpu.reg[reg];
564 haddr = MTS_PROTO(access)(cpu,vaddr,MIPS_MEMOP_SDC1,8,MTS_WRITE,
565 &data,&exc);
566 if (likely(haddr != NULL)) *(m_uint64_t *)haddr = htovm64(data);
567 return(exc);
568 }
569
570 /* CACHE: Cache operation */
571 fastcall u_int MTS_PROTO(cache)(cpu_mips_t *cpu,m_uint64_t vaddr,u_int op)
572 {
573 mips64_jit_tcb_t *block;
574 m_uint32_t pc_hash;
575
576 #if DEBUG_CACHE
577 cpu_log(cpu->gen,
578 "MTS","CACHE: PC=0x%llx, vaddr=0x%llx, cache=%u, code=%u\n",
579 cpu->pc, vaddr, op & 0x3, op >> 2);
580 #endif
581
582 if (cpu->exec_blk_map) {
583 pc_hash = mips64_jit_get_pc_hash(cpu->pc);
584 block = cpu->exec_blk_map[pc_hash];
585
586 if (block && mips64_jit_tcb_match(cpu,block)) {
587 #if DEBUG_CACHE
588 cpu_log(cpu->gen,"MTS",
589 "CACHE: removing compiled page at 0x%llx, pc=0x%llx\n",
590 block->start_pc,cpu->pc);
591 #endif
592 cpu->exec_blk_map[pc_hash] = NULL;
593 mips64_jit_tcb_free(cpu,block,TRUE);
594 }
595 else
596 {
597 #if DEBUG_CACHE
598 cpu_log(cpu->gen,"MTS",
599 "CACHE: trying to remove page 0x%llx with pc=0x%llx\n",
600 block->start_pc,cpu->pc);
601 #endif
602 }
603 }
604
605 return(0);
606 }
607
608 /* === MTS Cache Management ============================================= */
609
610 /* MTS map/unmap/rebuild "API" functions */
611 void MTS_PROTO(api_map)(cpu_mips_t *cpu,m_uint64_t vaddr,m_uint64_t paddr,
612 m_uint32_t len,int cache_access,int tlb_index)
613 {
614 /* nothing to do, the cache will be filled on-the-fly */
615 }
616
617 void MTS_PROTO(api_unmap)(cpu_mips_t *cpu,m_uint64_t vaddr,m_uint32_t len,
618 m_uint32_t val,int tlb_index)
619 {
620 /* Invalidate the TLB entry or the full cache if no index is specified */
621 if (tlb_index != -1)
622 MTS_PROTO(invalidate_tlb_entry)(cpu,tlb_index);
623 else
624 MTS_PROTO(invalidate_cache)(cpu);
625 }
626
627 void MTS_PROTO(api_rebuild)(cpu_gen_t *cpu)
628 {
629 MTS_PROTO(invalidate_cache)(CPU_MIPS64(cpu));
630 }
631
632 /* ======================================================================== */
633
634 /* Initialize memory access vectors */
635 void MTS_PROTO(init_memop_vectors)(cpu_mips_t *cpu)
636 {
637 /* XXX TODO:
638 * - LD/SD forbidden in Supervisor/User modes with 32-bit addresses.
639 */
640
641 cpu->addr_mode = MTS_ADDR_SIZE;
642
643 /* API vectors */
644 cpu->mts_map = MTS_PROTO(api_map);
645 cpu->mts_unmap = MTS_PROTO(api_unmap);
646
647 /* Memory lookup operation */
648 cpu->mem_op_lookup = MTS_PROTO(lookup);
649
650 /* Translation operation */
651 cpu->translate = MTS_PROTO(translate);
652
653 /* Shutdown operation */
654 cpu->mts_shutdown = MTS_PROTO(shutdown);
655
656 /* Rebuild MTS data structures */
657 cpu->gen->mts_rebuild = MTS_PROTO(api_rebuild);
658
659 /* Show statistics */
660 cpu->gen->mts_show_stats = MTS_PROTO(show_stats);
661
662 /* Load Operations */
663 cpu->mem_op_fn[MIPS_MEMOP_LB] = MTS_PROTO(lb);
664 cpu->mem_op_fn[MIPS_MEMOP_LBU] = MTS_PROTO(lbu);
665 cpu->mem_op_fn[MIPS_MEMOP_LH] = MTS_PROTO(lh);
666 cpu->mem_op_fn[MIPS_MEMOP_LHU] = MTS_PROTO(lhu);
667 cpu->mem_op_fn[MIPS_MEMOP_LW] = MTS_PROTO(lw);
668 cpu->mem_op_fn[MIPS_MEMOP_LWU] = MTS_PROTO(lwu);
669 cpu->mem_op_fn[MIPS_MEMOP_LD] = MTS_PROTO(ld);
670 cpu->mem_op_fn[MIPS_MEMOP_LDL] = MTS_PROTO(ldl);
671 cpu->mem_op_fn[MIPS_MEMOP_LDR] = MTS_PROTO(ldr);
672
673 /* Store Operations */
674 cpu->mem_op_fn[MIPS_MEMOP_SB] = MTS_PROTO(sb);
675 cpu->mem_op_fn[MIPS_MEMOP_SH] = MTS_PROTO(sh);
676 cpu->mem_op_fn[MIPS_MEMOP_SW] = MTS_PROTO(sw);
677 cpu->mem_op_fn[MIPS_MEMOP_SD] = MTS_PROTO(sd);
678
679 /* Load Left/Right operations */
680 cpu->mem_op_fn[MIPS_MEMOP_LWL] = MTS_PROTO(lwl);
681 cpu->mem_op_fn[MIPS_MEMOP_LWR] = MTS_PROTO(lwr);
682 cpu->mem_op_fn[MIPS_MEMOP_LDL] = MTS_PROTO(ldl);
683 cpu->mem_op_fn[MIPS_MEMOP_LDR] = MTS_PROTO(ldr);
684
685 /* Store Left/Right operations */
686 cpu->mem_op_fn[MIPS_MEMOP_SWL] = MTS_PROTO(swl);
687 cpu->mem_op_fn[MIPS_MEMOP_SWR] = MTS_PROTO(swr);
688 cpu->mem_op_fn[MIPS_MEMOP_SDL] = MTS_PROTO(sdl);
689 cpu->mem_op_fn[MIPS_MEMOP_SDR] = MTS_PROTO(sdr);
690
691 /* LL/SC - Load Linked / Store Conditional */
692 cpu->mem_op_fn[MIPS_MEMOP_LL] = MTS_PROTO(ll);
693 cpu->mem_op_fn[MIPS_MEMOP_SC] = MTS_PROTO(sc);
694
695 /* Coprocessor 1 memory access functions */
696 cpu->mem_op_fn[MIPS_MEMOP_LDC1] = MTS_PROTO(ldc1);
697 cpu->mem_op_fn[MIPS_MEMOP_SDC1] = MTS_PROTO(sdc1);
698
699 /* Cache Operation */
700 cpu->mem_op_fn[MIPS_MEMOP_CACHE] = MTS_PROTO(cache);
701 }
702
703 #undef MTS_ADDR_SIZE
704 #undef MTS_NAME
705 #undef MTS_NAME_UP
706 #undef MTS_PROTO
707 #undef MTS_PROTO_UP
708 #undef MTS_ENTRY
709 #undef MTS_CHUNK

  ViewVC Help
Powered by ViewVC 1.1.26