# HG changeset patch # Parent 4a8ebab4db51ea6b64c53788092f9565f0d4236a diff -r 4a8ebab4db51 monitor.c --- a/monitor.c Fri Aug 27 03:15:33 2010 -0400 +++ b/monitor.c Fri Aug 27 04:06:18 2010 -0400 @@ -1841,6 +1841,112 @@ } } } + +static void pg_print(Monitor *mon, uint32_t *pstart, int *plast_prot, + uint32_t end, int prot, + uint32_t *pde_next, int *pde_last_prot, + int pde_prot) +{ + int prot1; + prot1 = *plast_prot; + if (prot != prot1) { + if (*pstart != -1) { + uint32_t pde_start = *pstart & ~((1 << 22) - 1); + if (*pde_last_prot != pde_prot && pde_start >= *pde_next && + !(prot1 & PG_PSE_MASK)) { + *pde_next = (end + ((1 << 22) - 1)) & ~((1 << 22) - 1); + monitor_printf(mon, "PDE(%03x) %08x-%08x %08x %c%c%c\n", + (*pde_next - pde_start) / (1 << 22), + pde_start, *pde_next, *pde_next - pde_start, + pde_prot & PG_USER_MASK ? 'u' : '-', + 'r', + pde_prot & PG_RW_MASK ? 'w' : '-'); + *pde_last_prot = 0; + } + + if (prot1 & PG_PSE_MASK) { + monitor_printf(mon, " PDES(%03x) %08x-%08x %08x %c%c%c\n", + (end - *pstart) / (1 << 22), + *pstart, end, end - *pstart, + prot1 & PG_USER_MASK ? 'u' : '-', + 'r', + prot1 & PG_RW_MASK ? 'w' : '-'); + } else { + monitor_printf(mon, " |-- PTE(%06x) %08x-%08x %08x %c%c%c\n", + (end - *pstart) / (1 << 12), + *pstart, end, end - *pstart, + prot1 & PG_USER_MASK ? 'u' : '-', + 'r', + prot1 & PG_RW_MASK ? 'w' : '-'); + } + } + if (prot != 0) + *pstart = end; + else + *pstart = -1; + *plast_prot = prot; + } +} + +static void pg_info(Monitor *mon) +{ + CPUState *env; + int l1, l2, prot, last_prot; + uint32_t pgd, pde, pte, start, end; + + int pde_prot, pde_last_prot; + uint32_t pde_start, pde_end; + + env = mon_get_cpu(); + if (!env) + return; + + if (!(env->cr[0] & CR0_PG_MASK)) { + monitor_printf(mon, "PG disabled\n"); + return; + } + pgd = env->cr[3] & ~0xfff; + last_prot = 0; + pde_last_prot = 0; + start = -1; + pde_start = 0; + for(l1 = 0; l1 < 1024; l1++) { + cpu_physical_memory_read(pgd + l1 * 4, (uint8_t *)&pde, 4); + pde = le32_to_cpu(pde); + end = l1 << 22; + pde_end = l1 << 22; + pde_prot = pde & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK); + if (pde & PG_PRESENT_MASK) { + if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) { + prot = pde & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK | + PG_PSE_MASK); + pg_print(mon, &start, &last_prot, end, prot, + &pde_start, &pde_last_prot, pde_prot); + } else { + for(l2 = 0; l2 < 1024; l2++) { + cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, + (uint8_t *)&pte, 4); + pte = le32_to_cpu(pte); + end = (l1 << 22) + (l2 << 12); + if (pte & PG_PRESENT_MASK) { + prot = pte & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK); + } else { + prot = 0; + } + pg_print(mon, &start, &last_prot, end, prot, + &pde_start, &pde_last_prot, pde_prot); + } + } + } else { + prot = 0; + pg_print(mon, &start, &last_prot, end, prot, + &pde_start, &pde_last_prot, pde_prot); + } + } + + pg_print(mon, &start, &last_prot, 1024 << 22, 0, + &pde_start, &pde_last_prot, pde_prot); +} #endif #if defined(TARGET_SH4) @@ -2459,6 +2565,13 @@ .mhandler.info = mem_info, }, { + .name = "pg", + .args_type = "", + .params = "", + .help = "show the page table", + .mhandler.info = pg_info, + }, + { .name = "hpet", .args_type = "", .params = "",