x86: expose APIs for dumping MMU entry flags
Add two new non-static APIs for dumping out the page table entries for a specified memory address, and move to the main MMU code. Has debugging uses when trying to figure out why memory domains are not set up correctly. Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
7c293831c6
commit
e45c6eeebc
3 changed files with 66 additions and 57 deletions
|
@ -237,61 +237,6 @@ static void log_exception(uintptr_t vector, uintptr_t code)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_MMU
|
||||
static bool dump_entry_flags(const char *name, u64_t flags)
|
||||
{
|
||||
if ((flags & Z_X86_MMU_P) == 0) {
|
||||
LOG_ERR("%s: Non-present", name);
|
||||
return false;
|
||||
} else {
|
||||
LOG_ERR("%s: 0x%016llx %s, %s, %s", name, flags,
|
||||
flags & MMU_ENTRY_WRITE ?
|
||||
"Writable" : "Read-only",
|
||||
flags & MMU_ENTRY_USER ?
|
||||
"User" : "Supervisor",
|
||||
flags & MMU_ENTRY_EXECUTE_DISABLE ?
|
||||
"Execute Disable" : "Execute Enabled");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_mmu_flags(struct x86_page_tables *ptables, uintptr_t addr)
|
||||
{
|
||||
u64_t entry;
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
entry = *z_x86_get_pml4e(ptables, addr);
|
||||
if (!dump_entry_flags("PML4E", entry)) {
|
||||
return;
|
||||
}
|
||||
|
||||
entry = *z_x86_pdpt_get_pdpte(z_x86_pml4e_get_pdpt(entry), addr);
|
||||
if (!dump_entry_flags("PDPTE", entry)) {
|
||||
return;
|
||||
}
|
||||
#else
|
||||
/* 32-bit doesn't have anything interesting in the PDPTE except
|
||||
* the present bit
|
||||
*/
|
||||
entry = *z_x86_get_pdpte(ptables, addr);
|
||||
if ((entry & Z_X86_MMU_P) == 0) {
|
||||
LOG_ERR("PDPTE: Non-present");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
entry = *z_x86_pd_get_pde(z_x86_pdpte_get_pd(entry), addr);
|
||||
if (!dump_entry_flags(" PDE", entry)) {
|
||||
return;
|
||||
}
|
||||
|
||||
entry = *z_x86_pt_get_pte(z_x86_pde_get_pt(entry), addr);
|
||||
if (!dump_entry_flags(" PTE", entry)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_X86_MMU */
|
||||
|
||||
/* Page fault error code flags */
|
||||
#define PRESENT BIT(0)
|
||||
#define WR BIT(1)
|
||||
|
@ -331,11 +276,12 @@ static void dump_page_fault(z_arch_esf_t *esf)
|
|||
#ifdef CONFIG_X86_MMU
|
||||
#ifdef CONFIG_USERSPACE
|
||||
if (err & US) {
|
||||
dump_mmu_flags(z_x86_thread_page_tables_get(_current), cr2);
|
||||
z_x86_dump_mmu_flags(z_x86_thread_page_tables_get(_current),
|
||||
cr2);
|
||||
} else
|
||||
#endif /* CONFIG_USERSPACE */
|
||||
{
|
||||
dump_mmu_flags(&z_x86_kernel_ptables, cr2);
|
||||
z_x86_dump_mmu_flags(&z_x86_kernel_ptables, cr2);
|
||||
}
|
||||
#endif /* CONFIG_X86_MMU */
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include <init.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <logging/log.h>
|
||||
LOG_MODULE_DECLARE(os);
|
||||
|
||||
/* Despite our use of PAE page tables, we do not (and will never) actually
|
||||
* support PAE. Use a 64-bit x86 target if you have that much RAM.
|
||||
|
@ -116,6 +118,59 @@ static inline void pte_update_addr(u64_t *pte, uintptr_t addr)
|
|||
* Not trying to capture every flag, just the most interesting stuff,
|
||||
* Present, write, XD, user, in typically encountered combinations.
|
||||
*/
|
||||
static bool dump_entry_flags(const char *name, u64_t flags)
|
||||
{
|
||||
if ((flags & Z_X86_MMU_P) == 0) {
|
||||
LOG_ERR("%s: Non-present", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_ERR("%s: 0x%016llx %s, %s, %s", name, flags,
|
||||
flags & MMU_ENTRY_WRITE ?
|
||||
"Writable" : "Read-only",
|
||||
flags & MMU_ENTRY_USER ?
|
||||
"User" : "Supervisor",
|
||||
flags & MMU_ENTRY_EXECUTE_DISABLE ?
|
||||
"Execute Disable" : "Execute Enabled");
|
||||
return true;
|
||||
}
|
||||
|
||||
void z_x86_dump_mmu_flags(struct x86_page_tables *ptables, uintptr_t addr)
|
||||
{
|
||||
u64_t entry;
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
entry = *z_x86_get_pml4e(ptables, addr);
|
||||
if (!dump_entry_flags("PML4E", entry)) {
|
||||
return;
|
||||
}
|
||||
|
||||
entry = *z_x86_pdpt_get_pdpte(z_x86_pml4e_get_pdpt(entry), addr);
|
||||
if (!dump_entry_flags("PDPTE", entry)) {
|
||||
return;
|
||||
}
|
||||
#else
|
||||
/* 32-bit doesn't have anything interesting in the PDPTE except
|
||||
* the present bit
|
||||
*/
|
||||
entry = *z_x86_get_pdpte(ptables, addr);
|
||||
if ((entry & Z_X86_MMU_P) == 0) {
|
||||
LOG_ERR("PDPTE: Non-present");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
entry = *z_x86_pd_get_pde(z_x86_pdpte_get_pd(entry), addr);
|
||||
if (!dump_entry_flags(" PDE", entry)) {
|
||||
return;
|
||||
}
|
||||
|
||||
entry = *z_x86_pt_get_pte(z_x86_pde_get_pt(entry), addr);
|
||||
if (!dump_entry_flags(" PTE", entry)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static char get_entry_code(u64_t value)
|
||||
{
|
||||
char ret;
|
||||
|
|
|
@ -328,6 +328,14 @@ static inline u64_t *z_x86_get_pte(struct x86_page_tables *ptables,
|
|||
return z_x86_pt_get_pte(z_x86_get_pt(ptables, addr), addr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump out page table entries for a particular memory address
|
||||
*
|
||||
* For the provided memory address, dump out the P, W, XD, US flags
|
||||
* at each paging level to the error log.
|
||||
*/
|
||||
void z_x86_dump_mmu_flags(struct x86_page_tables *ptables, uintptr_t addr);
|
||||
|
||||
/**
|
||||
* Debug function for dumping out page tables
|
||||
*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue