Sparc: implement monitor command 'info tlb'

Use existing dump_mmu() to implement monitor command 'info tlb'.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
This commit is contained in:
Blue Swirl 2010-12-19 13:42:56 +00:00
parent cdfe17df88
commit d41160a3e6
5 changed files with 66 additions and 57 deletions

View file

@ -1190,7 +1190,7 @@ show i8259 (PIC) state
@item info pci @item info pci
show emulated PCI device info show emulated PCI device info
@item info tlb @item info tlb
show virtual to physical memory mappings (i386 only) show virtual to physical memory mappings (i386, SH4 and SPARC only)
@item info mem @item info mem
show the active virtual memory mappings (i386 only) show the active virtual memory mappings (i386 only)
@item info jit @item info jit

View file

@ -2272,6 +2272,15 @@ static void tlb_info(Monitor *mon)
#endif #endif
#if defined(TARGET_SPARC)
static void tlb_info(Monitor *mon)
{
CPUState *env1 = mon_get_cpu();
dump_mmu((FILE*)mon, (fprintf_function)monitor_printf, env1);
}
#endif
static void do_info_kvm_print(Monitor *mon, const QObject *data) static void do_info_kvm_print(Monitor *mon, const QObject *data)
{ {
QDict *qdict; QDict *qdict;
@ -2744,7 +2753,7 @@ static const mon_cmd_t info_cmds[] = {
.user_print = do_pci_info_print, .user_print = do_pci_info_print,
.mhandler.info_new = do_pci_info, .mhandler.info_new = do_pci_info,
}, },
#if defined(TARGET_I386) || defined(TARGET_SH4) #if defined(TARGET_I386) || defined(TARGET_SH4) || defined(TARGET_SPARC)
{ {
.name = "tlb", .name = "tlb",
.args_type = "", .args_type = "",

View file

@ -448,7 +448,7 @@ int cpu_sparc_handle_mmu_fault(CPUSPARCState *env1, target_ulong address, int rw
int mmu_idx, int is_softmmu); int mmu_idx, int is_softmmu);
#define cpu_handle_mmu_fault cpu_sparc_handle_mmu_fault #define cpu_handle_mmu_fault cpu_sparc_handle_mmu_fault
target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev); target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev);
void dump_mmu(CPUSPARCState *env); void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env);
/* translate.c */ /* translate.c */
void gen_intermediate_code_init(CPUSPARCState *env); void gen_intermediate_code_init(CPUSPARCState *env);

View file

@ -320,47 +320,45 @@ target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev)
return 0; return 0;
} }
#ifdef DEBUG_MMU void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env)
void dump_mmu(CPUState *env)
{ {
target_ulong va, va1, va2; target_ulong va, va1, va2;
unsigned int n, m, o; unsigned int n, m, o;
target_phys_addr_t pde_ptr, pa; target_phys_addr_t pde_ptr, pa;
uint32_t pde; uint32_t pde;
printf("MMU dump:\n");
pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2); pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
pde = ldl_phys(pde_ptr); pde = ldl_phys(pde_ptr);
printf("Root ptr: " TARGET_FMT_plx ", ctx: %d\n", (*cpu_fprintf)(f, "Root ptr: " TARGET_FMT_plx ", ctx: %d\n",
(target_phys_addr_t)env->mmuregs[1] << 4, env->mmuregs[2]); (target_phys_addr_t)env->mmuregs[1] << 4, env->mmuregs[2]);
for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) { for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
pde = mmu_probe(env, va, 2); pde = mmu_probe(env, va, 2);
if (pde) { if (pde) {
pa = cpu_get_phys_page_debug(env, va); pa = cpu_get_phys_page_debug(env, va);
printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx (*cpu_fprintf)(f, "VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx
" PDE: " TARGET_FMT_lx "\n", va, pa, pde); " PDE: " TARGET_FMT_lx "\n", va, pa, pde);
for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) { for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
pde = mmu_probe(env, va1, 1); pde = mmu_probe(env, va1, 1);
if (pde) { if (pde) {
pa = cpu_get_phys_page_debug(env, va1); pa = cpu_get_phys_page_debug(env, va1);
printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_plx (*cpu_fprintf)(f, " VA: " TARGET_FMT_lx ", PA: "
" PDE: " TARGET_FMT_lx "\n", va1, pa, pde); TARGET_FMT_plx " PDE: " TARGET_FMT_lx "\n",
va1, pa, pde);
for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) { for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
pde = mmu_probe(env, va2, 0); pde = mmu_probe(env, va2, 0);
if (pde) { if (pde) {
pa = cpu_get_phys_page_debug(env, va2); pa = cpu_get_phys_page_debug(env, va2);
printf(" VA: " TARGET_FMT_lx ", PA: " (*cpu_fprintf)(f, " VA: " TARGET_FMT_lx ", PA: "
TARGET_FMT_plx " PTE: " TARGET_FMT_lx "\n", TARGET_FMT_plx " PTE: "
va2, pa, pde); TARGET_FMT_lx "\n",
va2, pa, pde);
} }
} }
} }
} }
} }
} }
printf("MMU dump ends\n");
} }
#endif /* DEBUG_MMU */
#else /* !TARGET_SPARC64 */ #else /* !TARGET_SPARC64 */
@ -622,18 +620,19 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
return 1; return 1;
} }
#ifdef DEBUG_MMU void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env)
void dump_mmu(CPUState *env)
{ {
unsigned int i; unsigned int i;
const char *mask; const char *mask;
printf("MMU contexts: Primary: %" PRId64 ", Secondary: %" PRId64 "\n", (*cpu_fprintf)(f, "MMU contexts: Primary: %" PRId64 ", Secondary: %"
env->dmmu.mmu_primary_context, env->dmmu.mmu_secondary_context); PRId64 "\n",
env->dmmu.mmu_primary_context,
env->dmmu.mmu_secondary_context);
if ((env->lsu & DMMU_E) == 0) { if ((env->lsu & DMMU_E) == 0) {
printf("DMMU disabled\n"); (*cpu_fprintf)(f, "DMMU disabled\n");
} else { } else {
printf("DMMU dump:\n"); (*cpu_fprintf)(f, "DMMU dump\n");
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
switch ((env->dtlb[i].tte >> 61) & 3) { switch ((env->dtlb[i].tte >> 61) & 3) {
default: default:
@ -651,24 +650,25 @@ void dump_mmu(CPUState *env)
break; break;
} }
if ((env->dtlb[i].tte & 0x8000000000000000ULL) != 0) { if ((env->dtlb[i].tte & 0x8000000000000000ULL) != 0) {
printf("[%02u] VA: %" PRIx64 ", PA: %" PRIx64 (*cpu_fprintf)(f, "[%02u] VA: %" PRIx64 ", PA: %" PRIx64
", %s, %s, %s, %s, ctx %" PRId64 " %s\n", ", %s, %s, %s, %s, ctx %" PRId64 " %s\n",
i, i,
env->dtlb[i].tag & (uint64_t)~0x1fffULL, env->dtlb[i].tag & (uint64_t)~0x1fffULL,
env->dtlb[i].tte & (uint64_t)0x1ffffffe000ULL, env->dtlb[i].tte & (uint64_t)0x1ffffffe000ULL,
mask, mask,
env->dtlb[i].tte & 0x4? "priv": "user", env->dtlb[i].tte & 0x4? "priv": "user",
env->dtlb[i].tte & 0x2? "RW": "RO", env->dtlb[i].tte & 0x2? "RW": "RO",
env->dtlb[i].tte & 0x40? "locked": "unlocked", env->dtlb[i].tte & 0x40? "locked": "unlocked",
env->dtlb[i].tag & (uint64_t)0x1fffULL, env->dtlb[i].tag & (uint64_t)0x1fffULL,
TTE_IS_GLOBAL(env->dtlb[i].tte)? "global" : "local"); TTE_IS_GLOBAL(env->dtlb[i].tte)?
"global" : "local");
} }
} }
} }
if ((env->lsu & IMMU_E) == 0) { if ((env->lsu & IMMU_E) == 0) {
printf("IMMU disabled\n"); (*cpu_fprintf)(f, "IMMU disabled\n");
} else { } else {
printf("IMMU dump:\n"); (*cpu_fprintf)(f, "IMMU dump\n");
for (i = 0; i < 64; i++) { for (i = 0; i < 64; i++) {
switch ((env->itlb[i].tte >> 61) & 3) { switch ((env->itlb[i].tte >> 61) & 3) {
default: default:
@ -686,21 +686,21 @@ void dump_mmu(CPUState *env)
break; break;
} }
if ((env->itlb[i].tte & 0x8000000000000000ULL) != 0) { if ((env->itlb[i].tte & 0x8000000000000000ULL) != 0) {
printf("[%02u] VA: %" PRIx64 ", PA: %" PRIx64 (*cpu_fprintf)(f, "[%02u] VA: %" PRIx64 ", PA: %" PRIx64
", %s, %s, %s, ctx %" PRId64 " %s\n", ", %s, %s, %s, ctx %" PRId64 " %s\n",
i, i,
env->itlb[i].tag & (uint64_t)~0x1fffULL, env->itlb[i].tag & (uint64_t)~0x1fffULL,
env->itlb[i].tte & (uint64_t)0x1ffffffe000ULL, env->itlb[i].tte & (uint64_t)0x1ffffffe000ULL,
mask, mask,
env->itlb[i].tte & 0x4? "priv": "user", env->itlb[i].tte & 0x4? "priv": "user",
env->itlb[i].tte & 0x40? "locked": "unlocked", env->itlb[i].tte & 0x40? "locked": "unlocked",
env->itlb[i].tag & (uint64_t)0x1fffULL, env->itlb[i].tag & (uint64_t)0x1fffULL,
TTE_IS_GLOBAL(env->itlb[i].tte)? "global" : "local"); TTE_IS_GLOBAL(env->itlb[i].tte)?
"global" : "local");
} }
} }
} }
} }
#endif /* DEBUG_MMU */
#endif /* TARGET_SPARC64 */ #endif /* TARGET_SPARC64 */
#endif /* !CONFIG_USER_ONLY */ #endif /* !CONFIG_USER_ONLY */

View file

@ -180,7 +180,7 @@ static void demap_tlb(SparcTLBEntry *tlb, target_ulong demap_addr,
replace_tlb_entry(&tlb[i], 0, 0, env1); replace_tlb_entry(&tlb[i], 0, 0, env1);
#ifdef DEBUG_MMU #ifdef DEBUG_MMU
DPRINTF_MMU("%s demap invalidated entry [%02u]\n", strmmu, i); DPRINTF_MMU("%s demap invalidated entry [%02u]\n", strmmu, i);
dump_mmu(env1); dump_mmu(stdout, fprintf, env1);
#endif #endif
} }
} }
@ -198,7 +198,7 @@ static void replace_tlb_1bit_lru(SparcTLBEntry *tlb,
replace_tlb_entry(&tlb[i], tlb_tag, tlb_tte, env1); replace_tlb_entry(&tlb[i], tlb_tag, tlb_tte, env1);
#ifdef DEBUG_MMU #ifdef DEBUG_MMU
DPRINTF_MMU("%s lru replaced invalid entry [%i]\n", strmmu, i); DPRINTF_MMU("%s lru replaced invalid entry [%i]\n", strmmu, i);
dump_mmu(env1); dump_mmu(stdout, fprintf, env1);
#endif #endif
return; return;
} }
@ -217,7 +217,7 @@ static void replace_tlb_1bit_lru(SparcTLBEntry *tlb,
#ifdef DEBUG_MMU #ifdef DEBUG_MMU
DPRINTF_MMU("%s lru replaced unlocked %s entry [%i]\n", DPRINTF_MMU("%s lru replaced unlocked %s entry [%i]\n",
strmmu, (replace_used?"used":"unused"), i); strmmu, (replace_used?"used":"unused"), i);
dump_mmu(env1); dump_mmu(stdout, fprintf, env1);
#endif #endif
return; return;
} }
@ -1959,7 +1959,7 @@ void helper_st_asi(target_ulong addr, uint64_t val, int asi, int size)
break; break;
} }
#ifdef DEBUG_MMU #ifdef DEBUG_MMU
dump_mmu(env); dump_mmu(stdout, fprintf, env);
#endif #endif
} }
break; break;
@ -2011,7 +2011,7 @@ void helper_st_asi(target_ulong addr, uint64_t val, int asi, int size)
reg, oldreg, env->mmuregs[reg]); reg, oldreg, env->mmuregs[reg]);
} }
#ifdef DEBUG_MMU #ifdef DEBUG_MMU
dump_mmu(env); dump_mmu(stdout, fprintf, env);
#endif #endif
} }
break; break;
@ -2912,7 +2912,7 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
DPRINTF_MMU("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", DPRINTF_MMU("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
oldreg, env->lsu); oldreg, env->lsu);
#ifdef DEBUG_MMU #ifdef DEBUG_MMU
dump_mmu(env); dump_mmu(stdout, fprintf, env1);
#endif #endif
tlb_flush(env, 1); tlb_flush(env, 1);
} }
@ -2957,7 +2957,7 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
PRIx64 "\n", reg, oldreg, env->immuregs[reg]); PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
} }
#ifdef DEBUG_MMU #ifdef DEBUG_MMU
dump_mmu(env); dump_mmu(stdout, fprintf, env);
#endif #endif
return; return;
} }
@ -2974,7 +2974,7 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
#ifdef DEBUG_MMU #ifdef DEBUG_MMU
DPRINTF_MMU("immu data access replaced entry [%i]\n", i); DPRINTF_MMU("immu data access replaced entry [%i]\n", i);
dump_mmu(env); dump_mmu(stdout, fprintf, env);
#endif #endif
return; return;
} }
@ -3030,7 +3030,7 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]); PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
} }
#ifdef DEBUG_MMU #ifdef DEBUG_MMU
dump_mmu(env); dump_mmu(stdout, fprintf, env);
#endif #endif
return; return;
} }
@ -3045,7 +3045,7 @@ void helper_st_asi(target_ulong addr, target_ulong val, int asi, int size)
#ifdef DEBUG_MMU #ifdef DEBUG_MMU
DPRINTF_MMU("dmmu data access replaced entry [%i]\n", i); DPRINTF_MMU("dmmu data access replaced entry [%i]\n", i);
dump_mmu(env); dump_mmu(stdout, fprintf, env);
#endif #endif
return; return;
} }