target-xtensa: implement info tlb monitor command

Command dumps valid ITLB and DTLB entries.

Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
This commit is contained in:
Max Filippov 2012-01-07 20:02:40 +04:00
parent b96ac3e4cc
commit 692f737cc2
4 changed files with 71 additions and 3 deletions

View File

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

View File

@ -1935,7 +1935,7 @@ static void tlb_info(Monitor *mon)
#endif
#if defined(TARGET_SPARC) || defined(TARGET_PPC)
#if defined(TARGET_SPARC) || defined(TARGET_PPC) || defined(TARGET_XTENSA)
static void tlb_info(Monitor *mon)
{
CPUState *env1 = mon_get_cpu();
@ -2382,7 +2382,7 @@ static mon_cmd_t info_cmds[] = {
.mhandler.info = hmp_info_pci,
},
#if defined(TARGET_I386) || defined(TARGET_SH4) || defined(TARGET_SPARC) || \
defined(TARGET_PPC)
defined(TARGET_PPC) || defined(TARGET_XTENSA)
{
.name = "tlb",
.args_type = "",

View File

@ -344,6 +344,7 @@ void xtensa_tlb_set_entry(CPUState *env, bool dtlb,
int xtensa_get_physical_addr(CPUState *env,
uint32_t vaddr, int is_write, int mmu_idx,
uint32_t *paddr, uint32_t *page_size, unsigned *access);
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env);
#define XTENSA_OPTION_BIT(opt) (((uint64_t)1) << (opt))

View File

@ -540,3 +540,70 @@ int xtensa_get_physical_addr(CPUState *env,
return 0;
}
}
static void dump_tlb(FILE *f, fprintf_function cpu_fprintf,
CPUState *env, bool dtlb)
{
unsigned wi, ei;
const xtensa_tlb *conf =
dtlb ? &env->config->dtlb : &env->config->itlb;
unsigned (*attr_to_access)(uint32_t) =
xtensa_option_enabled(env->config, XTENSA_OPTION_MMU) ?
mmu_attr_to_access : region_attr_to_access;
for (wi = 0; wi < conf->nways; ++wi) {
uint32_t sz = ~xtensa_tlb_get_addr_mask(env, dtlb, wi) + 1;
const char *sz_text;
bool print_header = true;
if (sz >= 0x100000) {
sz >>= 20;
sz_text = "MB";
} else {
sz >>= 10;
sz_text = "KB";
}
for (ei = 0; ei < conf->way_size[wi]; ++ei) {
const xtensa_tlb_entry *entry =
xtensa_tlb_get_entry(env, dtlb, wi, ei);
if (entry->asid) {
unsigned access = attr_to_access(entry->attr);
if (print_header) {
print_header = false;
cpu_fprintf(f, "Way %u (%d %s)\n", wi, sz, sz_text);
cpu_fprintf(f,
"\tVaddr Paddr ASID Attr RWX\n"
"\t---------- ---------- ---- ---- ---\n");
}
cpu_fprintf(f,
"\t0x%08x 0x%08x 0x%02x 0x%02x %c%c%c\n",
entry->vaddr,
entry->paddr,
entry->asid,
entry->attr,
(access & PAGE_READ) ? 'R' : '-',
(access & PAGE_WRITE) ? 'W' : '-',
(access & PAGE_EXEC) ? 'X' : '-');
}
}
}
}
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env)
{
if (xtensa_option_bits_enabled(env->config,
XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_PROTECTION) |
XTENSA_OPTION_BIT(XTENSA_OPTION_REGION_TRANSLATION) |
XTENSA_OPTION_BIT(XTENSA_OPTION_MMU))) {
cpu_fprintf(f, "ITLB:\n");
dump_tlb(f, cpu_fprintf, env, false);
cpu_fprintf(f, "\nDTLB:\n");
dump_tlb(f, cpu_fprintf, env, true);
} else {
cpu_fprintf(f, "No TLB for this CPU core\n");
}
}