1 |
/* |
/* |
2 |
* Copyright (C) 2005-2006 Anders Gavare. All rights reserved. |
* Copyright (C) 2005-2007 Anders Gavare. All rights reserved. |
3 |
* |
* |
4 |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
5 |
* modification, are permitted provided that the following conditions are met: |
* modification, are permitted provided that the following conditions are met: |
25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: cpu_dyntrans.c,v 1.132 2006/10/27 13:12:20 debug Exp $ |
* $Id: cpu_dyntrans.c,v 1.142 2007/02/11 10:47:31 debug Exp $ |
29 |
* |
* |
30 |
* Common dyntrans routines. Included from cpu_*.c. |
* Common dyntrans routines. Included from cpu_*.c. |
31 |
*/ |
*/ |
265 |
any instruction for any ISA: */ |
any instruction for any ISA: */ |
266 |
unsigned char instr[1 << |
unsigned char instr[1 << |
267 |
DYNTRANS_INSTR_ALIGNMENT_SHIFT]; |
DYNTRANS_INSTR_ALIGNMENT_SHIFT]; |
|
#ifdef DYNTRANS_X86 |
|
|
cpu->cd.x86.cursegment = X86_S_CS; |
|
|
cpu->cd.x86.seg_override = 0; |
|
|
#endif |
|
268 |
if (!cpu->memory_rw(cpu, cpu->mem, cached_pc, &instr[0], |
if (!cpu->memory_rw(cpu, cpu->mem, cached_pc, &instr[0], |
269 |
sizeof(instr), MEM_READ, CACHE_INSTRUCTION)) { |
sizeof(instr), MEM_READ, CACHE_INSTRUCTION)) { |
270 |
fatal("XXX_run_instr(): could not read " |
fatal("XXX_run_instr(): could not read " |
346 |
} |
} |
347 |
} else { |
} else { |
348 |
/* Execute multiple instructions: */ |
/* Execute multiple instructions: */ |
349 |
int n = 0; |
n_instrs = 0; |
350 |
for (;;) { |
for (;;) { |
351 |
struct DYNTRANS_IC *ic; |
struct DYNTRANS_IC *ic; |
352 |
|
|
358 |
|
|
359 |
I; I; I; I; I; I; I; I; I; I; |
I; I; I; I; I; I; I; I; I; I; |
360 |
|
|
361 |
n += 60; |
I; I; I; I; I; I; I; I; I; I; |
362 |
|
I; I; I; I; I; I; I; I; I; I; |
363 |
|
I; I; I; I; I; I; I; I; I; I; |
364 |
|
I; I; I; I; I; I; I; I; I; I; |
365 |
|
I; I; I; I; I; I; I; I; I; I; |
366 |
|
|
367 |
|
I; I; I; I; I; I; I; I; I; I; |
368 |
|
|
369 |
if (n + cpu->n_translated_instrs >= |
cpu->n_translated_instrs += 120; |
370 |
N_SAFE_DYNTRANS_LIMIT) |
if (cpu->n_translated_instrs >= N_SAFE_DYNTRANS_LIMIT) |
371 |
break; |
break; |
372 |
} |
} |
|
n_instrs = n; |
|
373 |
} |
} |
374 |
|
|
375 |
n_instrs += cpu->n_translated_instrs; |
n_instrs += cpu->n_translated_instrs; |
412 |
/* Not yet. TODO */ |
/* Not yet. TODO */ |
413 |
if (cpu->machine->emulated_hz > 0) { |
if (cpu->machine->emulated_hz > 0) { |
414 |
if (cpu->cd.mips.compare_interrupts_pending > 0) |
if (cpu->cd.mips.compare_interrupts_pending > 0) |
415 |
cpu_interrupt(cpu, 7); |
INTERRUPT_ASSERT( |
416 |
|
cpu->cd.mips.irq_compare); |
417 |
} else |
} else |
418 |
#endif |
#endif |
419 |
{ |
{ |
420 |
if (diff1 > 0 && diff2 <= 0) |
if (diff1 > 0 && diff2 <= 0) |
421 |
cpu_interrupt(cpu, 7); |
INTERRUPT_ASSERT( |
422 |
|
cpu->cd.mips.irq_compare); |
423 |
} |
} |
424 |
} |
} |
425 |
} |
} |
489 |
*/ |
*/ |
490 |
for (x=0; x<n_args_to_print; x++) { |
for (x=0; x<n_args_to_print; x++) { |
491 |
int64_t d; |
int64_t d; |
492 |
#if defined(DYNTRANS_X86) || defined(DYNTRANS_TRANSPUTER) |
#if defined(DYNTRANS_TRANSPUTER) |
493 |
d = 0; /* TODO */ |
d = 0; /* TODO */ |
494 |
#else |
#else |
495 |
/* Args in registers: */ |
/* Args in registers: */ |
505 |
they go downwards, ie. 22,23 and so on */ |
they go downwards, ie. 22,23 and so on */ |
506 |
r[24 |
r[24 |
507 |
#endif |
#endif |
|
#ifdef DYNTRANS_AVR32 |
|
|
r[0 /* TODO */ |
|
|
#endif |
|
|
#ifdef DYNTRANS_HPPA |
|
|
r[0 /* TODO */ |
|
|
#endif |
|
|
#ifdef DYNTRANS_I960 |
|
|
r[0 /* TODO */ |
|
|
#endif |
|
|
#ifdef DYNTRANS_IA64 |
|
|
r[0 /* TODO */ |
|
|
#endif |
|
508 |
#ifdef DYNTRANS_M68K |
#ifdef DYNTRANS_M68K |
509 |
d[0 /* TODO */ |
d[0 /* TODO */ |
510 |
#endif |
#endif |
565 |
{ |
{ |
566 |
struct DYNTRANS_TC_PHYSPAGE *ppp; |
struct DYNTRANS_TC_PHYSPAGE *ppp; |
567 |
|
|
568 |
|
native_commit(cpu); |
569 |
|
|
570 |
ppp = (struct DYNTRANS_TC_PHYSPAGE *)(cpu->translation_cache |
ppp = (struct DYNTRANS_TC_PHYSPAGE *)(cpu->translation_cache |
571 |
+ cpu->translation_cache_cur_ofs); |
+ cpu->translation_cache_cur_ofs); |
572 |
|
|
678 |
} |
} |
679 |
#else |
#else |
680 |
x1 = (cached_pc >> (64-DYNTRANS_L1N)) & mask1; |
x1 = (cached_pc >> (64-DYNTRANS_L1N)) & mask1; |
681 |
x2 = (cached_pc >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2; |
x2 = (cached_pc >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) |
682 |
x3 = (cached_pc >> (64-DYNTRANS_L1N-DYNTRANS_L2N-DYNTRANS_L3N)) |
& mask2; |
683 |
& mask3; |
x3 = (cached_pc >> (64-DYNTRANS_L1N-DYNTRANS_L2N |
684 |
|
- DYNTRANS_L3N)) & mask3; |
685 |
l2 = cpu->cd.DYNTRANS_ARCH.l1_64[x1]; |
l2 = cpu->cd.DYNTRANS_ARCH.l1_64[x1]; |
686 |
l3 = l2->l3[x2]; |
l3 = l2->l3[x2]; |
687 |
if (l3->host_load[x3] != NULL) { |
if (l3->host_load[x3] != NULL) { |
725 |
} |
} |
726 |
} |
} |
727 |
|
|
728 |
if (cpu->translation_cache_cur_ofs >= DYNTRANS_CACHE_SIZE) { |
if (cpu->translation_cache_cur_ofs >= dyntrans_cache_size) { |
729 |
#ifdef UNSTABLE_DEVEL |
#ifdef UNSTABLE_DEVEL |
730 |
fatal("[ dyntrans: resetting the translation cache ]\n"); |
fatal("[ dyntrans: resetting the translation cache ]\n"); |
731 |
#endif |
#endif |
759 |
/* fatal("CREATING page %lli (physaddr 0x%"PRIx64"), table " |
/* fatal("CREATING page %lli (physaddr 0x%"PRIx64"), table " |
760 |
"index %i\n", (long long)pagenr, (uint64_t)physaddr, |
"index %i\n", (long long)pagenr, (uint64_t)physaddr, |
761 |
(int)table_index); */ |
(int)table_index); */ |
762 |
|
native_commit(cpu); |
763 |
*physpage_entryp = physpage_ofs = |
*physpage_entryp = physpage_ofs = |
764 |
cpu->translation_cache_cur_ofs; |
cpu->translation_cache_cur_ofs; |
765 |
|
|
1249 |
physpage_entryp = &(((uint32_t *)cpu-> |
physpage_entryp = &(((uint32_t *)cpu-> |
1250 |
translation_cache)[table_index]); |
translation_cache)[table_index]); |
1251 |
physpage_ofs = *physpage_entryp; |
physpage_ofs = *physpage_entryp; |
1252 |
|
|
1253 |
|
/* Return immediately if there is no code translation |
1254 |
|
for this page. */ |
1255 |
|
if (physpage_ofs == 0) |
1256 |
|
return; |
1257 |
|
|
1258 |
prev_ppp = ppp = NULL; |
prev_ppp = ppp = NULL; |
1259 |
|
|
1260 |
/* Traverse the physical page chain: */ |
/* Traverse the physical page chain: */ |
1272 |
physpage_ofs = ppp->next_ofs; |
physpage_ofs = ppp->next_ofs; |
1273 |
} |
} |
1274 |
|
|
1275 |
if (physpage_ofs == 0) |
/* If there is no translation, there is no need to go |
1276 |
ppp = NULL; |
on and try to remove it from the vph_tlb_entry array: */ |
1277 |
|
if (ppp == NULL) |
1278 |
|
return; |
1279 |
|
|
1280 |
#if 0 |
#if 0 |
1281 |
/* |
/* |