capDL: Add kernel debugging tool for capDL
Add Arm debugging features of capDL Kernel Printing Signed-off-by: Jingyao Zhou <Jingyao.Zhou@data61.csiro.au>
This commit is contained in:
parent
7c91c1c88a
commit
9feaba02fe
4 changed files with 1061 additions and 8 deletions
|
|
@ -6,4 +6,18 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <machine/capdl.h>
|
||||
|
||||
#ifdef CONFIG_ARM_SMMU
|
||||
static inline void arm_obj_iospace_print_attrs(cap_t iospace_cap)
|
||||
{
|
||||
printf("(armiospace: %lu)\n", (long unsigned int)cap_io_space_cap_get_capModuleID(io_space));
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void obj_asidpool_print_attrs(cap_t asid_cap)
|
||||
{
|
||||
printf("(asid_high: 0x%lx)\n", (long unsigned int)ASID_HIGH(cap_asid_pool_cap_get_capASIDBase(asid_cap)));
|
||||
}
|
||||
|
||||
void capDL(void);
|
||||
|
|
|
|||
|
|
@ -5,13 +5,513 @@
|
|||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <machine/capdl.h>
|
||||
#include <arch/machine/capdl.h>
|
||||
#include <string.h>
|
||||
#include <kernel/cspace.h>
|
||||
|
||||
#ifdef CONFIG_DEBUG_BUILD
|
||||
|
||||
void capDL(void)
|
||||
{
|
||||
#define MAX_UL 0xffffffff
|
||||
#define PT_INDEX(vptr) ((vptr >> PAGE_BITS) & MASK(PT_INDEX_BITS))
|
||||
#define PD_INDEX(vptr) (vptr >> (PAGE_BITS + PT_INDEX_BITS))
|
||||
|
||||
static void obj_frame_print_attrs(resolve_ret_t ret);
|
||||
static void cap_frame_print_attrs_pt(pte_t *pte);
|
||||
static void cap_frame_print_attrs_pd(pde_t *pde);
|
||||
static void cap_frame_print_attrs_impl(word_t AP, word_t XN, word_t TEX);
|
||||
static void arm32_obj_pt_print_slots(pte_t *pt);
|
||||
static void arm32_cap_pt_print_slots(pte_t *pt);
|
||||
|
||||
/*
|
||||
* Caps
|
||||
*/
|
||||
word_t get_tcb_sp(tcb_t *tcb)
|
||||
{
|
||||
return tcb->tcbArch.tcbContext.registers[SP];
|
||||
}
|
||||
|
||||
#endif
|
||||
/*
|
||||
* AP S R Privileged permissions User permissions
|
||||
* 00 0 0 No access No access
|
||||
* 00 1 0 Read-only No access
|
||||
* 00 0 1 Read-only Read-only
|
||||
* 00 1 1 Unpredictable Unpredictable
|
||||
* 01 x x Read/write No access
|
||||
* 10 x x Read/write Read-only
|
||||
* 11 x x Read/write Read/write
|
||||
*/
|
||||
/* use when only have access to pte of frames */
|
||||
static void cap_frame_print_attrs_pt(pte_t *pte)
|
||||
{
|
||||
word_t AP, XN, TEX;
|
||||
switch (pte_ptr_get_pteType(pte)) {
|
||||
case pte_pte_small:
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
AP = pte_pte_small_ptr_get_HAP(pte);
|
||||
TEX = pte_pte_small_ptr_get_MemAttr(pte);
|
||||
#else
|
||||
AP = pte_pte_small_ptr_get_AP(pte);
|
||||
TEX = pte_pte_small_ptr_get_TEX(pte);
|
||||
#endif
|
||||
XN = pte_pte_small_ptr_get_XN(pte);
|
||||
break;
|
||||
|
||||
#ifndef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
case pte_pte_large:
|
||||
AP = pte_pte_large_ptr_get_AP(pte);
|
||||
TEX = pte_pte_large_ptr_get_TEX(pte);
|
||||
XN = pte_pte_large_ptr_get_XN(pte);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
assert(!"should not happend");
|
||||
}
|
||||
cap_frame_print_attrs_impl(AP, XN, TEX);
|
||||
}
|
||||
|
||||
static void cap_frame_print_attrs_pd(pde_t *pde)
|
||||
{
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
cap_frame_print_attrs_impl(pde_pde_section_ptr_get_HAP(pde),
|
||||
pde_pde_section_ptr_get_XN(pde),
|
||||
pde_pde_section_ptr_get_MemAttr(pde));
|
||||
#else
|
||||
cap_frame_print_attrs_impl(pde_pde_section_ptr_get_AP(pde),
|
||||
pde_pde_section_ptr_get_XN(pde),
|
||||
pde_pde_section_ptr_get_TEX(pde));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void cap_frame_print_attrs_impl(word_t AP, word_t XN, word_t TEX)
|
||||
{
|
||||
printf("(");
|
||||
|
||||
/* rights */
|
||||
switch (AP) {
|
||||
case 0b00:
|
||||
case 0b01:
|
||||
break;
|
||||
case 0b10:
|
||||
printf("R");
|
||||
break;
|
||||
case 0b11:
|
||||
printf("RW");
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!XN) {
|
||||
printf("X");
|
||||
}
|
||||
|
||||
if (!TEX) {
|
||||
printf(", uncached");
|
||||
}
|
||||
|
||||
printf(")\n");
|
||||
}
|
||||
|
||||
static void arm32_cap_pt_print_slots(pte_t *pt)
|
||||
{
|
||||
vm_page_size_t page_size;
|
||||
word_t i = 0;
|
||||
while (i < BIT(PT_INDEX_BITS + PAGE_BITS)) {
|
||||
pte_t *pte = lookupPTSlot_nofail(pt, i);
|
||||
switch (pte_ptr_get_pteType(pte)) {
|
||||
case pte_pte_small: {
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
if (pte_pte_small_ptr_get_contiguous_hint(pte)) {
|
||||
page_size = ARMLargePage;
|
||||
} else {
|
||||
page_size = ARMSmallPage;
|
||||
}
|
||||
#else
|
||||
page_size = ARMSmallPage;
|
||||
#endif
|
||||
printf("0x%lx: frame_%p_%04lu ", PT_INDEX(i), pte, PT_INDEX(i));
|
||||
cap_frame_print_attrs_pt(pte);
|
||||
break;
|
||||
}
|
||||
#ifndef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
case pte_pte_large: {
|
||||
page_size = ARMLargePage;
|
||||
printf("0x%lx: frame_%p_%04lu ", PT_INDEX(i), pte, PT_INDEX(i));
|
||||
cap_frame_print_attrs_pt(pte);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
page_size = ARMSmallPage;
|
||||
}
|
||||
i += (1 << pageBitsForSize(page_size));
|
||||
}
|
||||
}
|
||||
|
||||
void obj_vtable_print_slots(tcb_t *tcb)
|
||||
{
|
||||
if (isValidVTableRoot(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap) && !seen(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap)) {
|
||||
add_to_seen(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap);
|
||||
pde_t *pd = (pde_t *)pptr_of_cap(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap);
|
||||
vm_page_size_t page_size;
|
||||
printf("%p_pd {\n", pd);
|
||||
|
||||
/* PD_INDEX_BITS + ARMSectionBits = 32, can't use left shift here */
|
||||
word_t i = 0;
|
||||
while (i < MAX_UL) {
|
||||
pde_t *pde = lookupPDSlot(pd, i);
|
||||
switch (pde_ptr_get_pdeType(pde)) {
|
||||
case pde_pde_section: {
|
||||
#ifndef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
if (pde_pde_section_ptr_get_size(pde)) {
|
||||
page_size = ARMSuperSection;
|
||||
} else {
|
||||
page_size = ARMSection;
|
||||
}
|
||||
#else
|
||||
if (pde_pde_section_ptr_get_contiguous_hint(pde)) {
|
||||
page_size = ARMSuperSection;
|
||||
} else {
|
||||
page_size = ARMSection;
|
||||
}
|
||||
#endif
|
||||
printf("0x%lx: frame_%p_%04lu ", PD_INDEX(i), pde, PD_INDEX(i));
|
||||
cap_frame_print_attrs_pd(pde);
|
||||
break;
|
||||
}
|
||||
|
||||
case pde_pde_coarse: {
|
||||
printf("0x%lx: pt_%p_%04lu\n", PD_INDEX(i), pde, PD_INDEX(i));
|
||||
page_size = ARMSection;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
page_size = ARMSection;
|
||||
break;
|
||||
}
|
||||
i += (1 << pageBitsForSize(page_size));
|
||||
if (i < (1 << pageBitsForSize(page_size))) {
|
||||
break; /* overflowed */
|
||||
}
|
||||
}
|
||||
printf("}\n"); /* pd */
|
||||
|
||||
i = 0;
|
||||
/* PD_INDEX_BITS + ARMSectionBits = 32, can't use left shift here */
|
||||
while (i < MAX_UL) {
|
||||
pde_t *pde = lookupPDSlot(pd, i);
|
||||
if (pde_ptr_get_pdeType(pde) == pde_pde_coarse) {
|
||||
pte_t *pt = ptrFromPAddr(pde_pde_coarse_ptr_get_address(pde));
|
||||
printf("pt_%p_%04lu {\n", pde, PD_INDEX(i));
|
||||
arm32_cap_pt_print_slots(pt);
|
||||
printf("}\n"); /* pt */
|
||||
}
|
||||
i += (1 << pageBitsForSize(ARMSection));
|
||||
if (i < (1 << pageBitsForSize(ARMSection))) {
|
||||
break; /* overflowed */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* use when only have access to vptr of frames */
|
||||
static void cap_frame_print_attrs_vptr(word_t vptr, pde_t *pd)
|
||||
{
|
||||
pde_t *pde = lookupPDSlot(pd, vptr);
|
||||
|
||||
switch (pde_ptr_get_pdeType(pde)) {
|
||||
case pde_pde_section: {
|
||||
printf("frame_%p_%04lu ", pde, PD_INDEX(vptr));
|
||||
cap_frame_print_attrs_pd(pde);
|
||||
break;
|
||||
}
|
||||
case pde_pde_coarse: {
|
||||
pte_t *pt = ptrFromPAddr(pde_pde_coarse_ptr_get_address(pde));
|
||||
pte_t *pte = lookupPTSlot_nofail(pt, vptr);
|
||||
switch (pte_ptr_get_pteType(pte)) {
|
||||
case pte_pte_small: {
|
||||
printf("frame_%p_%04lu ", pte, PT_INDEX(vptr));
|
||||
cap_frame_print_attrs_pt(pte);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
case pte_pte_large: {
|
||||
printf("frame_%p_%04lu ", pte, PT_INDEX(vptr));
|
||||
cap_frame_print_attrs_pt(pte);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
void print_ipc_buffer_slot(tcb_t *tcb)
|
||||
{
|
||||
word_t vptr = tcb->tcbIPCBuffer;
|
||||
asid_t asid = cap_page_directory_cap_get_capPDMappedASID(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap);
|
||||
findPDForASID_ret_t find_ret = findPDForASID(asid);
|
||||
printf("ipc_buffer_slot: ");
|
||||
cap_frame_print_attrs_vptr(vptr, find_ret.pd);
|
||||
}
|
||||
|
||||
void print_cap_arch(cap_t cap)
|
||||
{
|
||||
switch (cap_get_capType(cap)) {
|
||||
case cap_page_table_cap: {
|
||||
asid_t asid = cap_page_table_cap_get_capPTMappedASID(cap);
|
||||
findPDForASID_ret_t find_ret = findPDForASID(asid);
|
||||
vptr_t vptr = cap_page_table_cap_get_capPTMappedAddress(cap);
|
||||
if (asid) {
|
||||
printf("pt_%p_%04lu (asid: %lu)\n",
|
||||
lookupPDSlot(find_ret.pd, vptr), PD_INDEX(vptr), (long unsigned int)asid);
|
||||
} else {
|
||||
printf("pt_%p_%04lu\n", lookupPDSlot(find_ret.pd, vptr), PD_INDEX(vptr));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case cap_page_directory_cap: {
|
||||
asid_t asid = cap_page_directory_cap_get_capPDMappedASID(cap);
|
||||
findPDForASID_ret_t find_ret = findPDForASID(asid);
|
||||
if (asid) {
|
||||
printf("%p_pd (asid: %lu)\n",
|
||||
find_ret.pd, (long unsigned int)asid);
|
||||
} else {
|
||||
printf("%p_pd\n", find_ret.pd);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case cap_asid_control_cap: {
|
||||
/* only one in the system */
|
||||
printf("asid_control\n");
|
||||
break;
|
||||
}
|
||||
case cap_small_frame_cap: {
|
||||
vptr_t vptr = cap_small_frame_cap_get_capFMappedAddress(cap);
|
||||
findPDForASID_ret_t find_ret = findPDForASID(cap_small_frame_cap_get_capFMappedASID(cap));
|
||||
assert(find_ret.status == EXCEPTION_NONE);
|
||||
cap_frame_print_attrs_vptr(vptr, find_ret.pd);
|
||||
break;
|
||||
}
|
||||
case cap_frame_cap: {
|
||||
vptr_t vptr = cap_frame_cap_get_capFMappedAddress(cap);
|
||||
findPDForASID_ret_t find_ret = findPDForASID(cap_frame_cap_get_capFMappedASID(cap));
|
||||
assert(find_ret.status == EXCEPTION_NONE);
|
||||
cap_frame_print_attrs_vptr(vptr, find_ret.pd);
|
||||
break;
|
||||
}
|
||||
case cap_asid_pool_cap: {
|
||||
printf("%p_asid_pool\n", (void *)cap_asid_pool_cap_get_capASIDPool(cap));
|
||||
break;
|
||||
}
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
case cap_vcpu_cap: {
|
||||
printf("%p_vcpu\n", (void *)cap_vcpu_cap_get_capVCPUPtr(cap));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ARM specific caps */
|
||||
#ifdef CONFIG_ARM_SMMU
|
||||
case cap_io_space_cap: {
|
||||
printf("%p_io_space\n", (void *)cap_io_space_cap_get_capModuleID(cap));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
printf("[unknown cap %u]\n", cap_get_capType(cap));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void print_object_arch(cap_t cap)
|
||||
{
|
||||
|
||||
switch (cap_get_capType(cap)) {
|
||||
case cap_frame_cap:
|
||||
case cap_small_frame_cap:
|
||||
case cap_page_table_cap:
|
||||
case cap_page_directory_cap:
|
||||
/* don't need to deal with these objects since they get handled from vtable */
|
||||
break;
|
||||
|
||||
case cap_asid_pool_cap: {
|
||||
printf("%p_asid_pool = asid_pool ",
|
||||
(void *)cap_asid_pool_cap_get_capASIDPool(cap));
|
||||
obj_asidpool_print_attrs(cap);
|
||||
break;
|
||||
}
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
case cap_vcpu_cap: {
|
||||
printf("%p_vcpu = vcpu\n", (void *)cap_vcpu_cap_get_capVCPUPtr(cap));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
/* ARM specific objects */
|
||||
#ifdef CONFIG_ARM_SMMU
|
||||
case cap_io_space_cap: {
|
||||
printf("%p_io_space = io_space ", (void *)cap_io_space_cap_get_capModuleID(cap));
|
||||
arm_obj_iospace_print_attrs(cap);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
printf("[unknown object %u]\n", cap_get_capType(cap));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void obj_frame_print_attrs(resolve_ret_t ret)
|
||||
{
|
||||
printf("(");
|
||||
|
||||
/* VM size */
|
||||
switch (ret.frameSize) {
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
case ARMSection:
|
||||
printf("2M");
|
||||
break;
|
||||
case ARMSuperSection:
|
||||
printf("32M");
|
||||
break;
|
||||
#else
|
||||
case ARMSection:
|
||||
printf("1M");
|
||||
break;
|
||||
case ARMSuperSection:
|
||||
printf("16M");
|
||||
break;
|
||||
#endif
|
||||
case ARMLargePage:
|
||||
printf("64k");
|
||||
break;
|
||||
case ARMSmallPage:
|
||||
printf("4k");
|
||||
break;
|
||||
}
|
||||
|
||||
printf(", paddr: %p)\n", (void *)ret.frameBase);
|
||||
}
|
||||
|
||||
static void arm32_obj_pt_print_slots(pte_t *pt)
|
||||
{
|
||||
resolve_ret_t ret;
|
||||
word_t i = 0;
|
||||
while (i < BIT(PT_INDEX_BITS + PAGE_BITS)) {
|
||||
pte_t *pte = lookupPTSlot_nofail(pt, i);
|
||||
switch (pte_ptr_get_pteType(pte)) {
|
||||
case pte_pte_small: {
|
||||
ret.frameBase = pte_pte_small_ptr_get_address(pte);
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
if (pte_pte_small_ptr_get_contiguous_hint(pte)) {
|
||||
/* Entries are represented as 16 contiguous small frames. We need to mask
|
||||
to get the large frame base */
|
||||
ret.frameBase &= ~MASK(pageBitsForSize(ARMLargePage));
|
||||
ret.frameSize = ARMLargePage;
|
||||
} else {
|
||||
ret.frameSize = ARMSmallPage;
|
||||
}
|
||||
#else
|
||||
ret.frameSize = ARMSmallPage;
|
||||
#endif
|
||||
printf("frame_%p_%04lu = frame ", pte, PT_INDEX(i));
|
||||
obj_frame_print_attrs(ret);
|
||||
break;
|
||||
}
|
||||
#ifndef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
case pte_pte_large: {
|
||||
ret.frameBase = pte_pte_large_ptr_get_address(pte);
|
||||
ret.frameSize = ARMLargePage;
|
||||
printf("frame_%p_%04lu = frame ", pte, PT_INDEX(i));
|
||||
obj_frame_print_attrs(ret);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
ret.frameSize = ARMSmallPage;
|
||||
}
|
||||
i += (1 << pageBitsForSize(ret.frameSize));
|
||||
}
|
||||
}
|
||||
|
||||
void obj_tcb_print_vtable(tcb_t *tcb)
|
||||
{
|
||||
if (isValidVTableRoot(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap) && !seen(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap)) {
|
||||
add_to_seen(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap);
|
||||
pde_t *pd = (pde_t *)pptr_of_cap(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap);
|
||||
resolve_ret_t ret = {};
|
||||
printf("%p_pd = pd\n", pd);
|
||||
|
||||
/* PD_INDEX_BITS + ARMSectionBits = 32, can't use left shift here */
|
||||
word_t i = 0;
|
||||
while (i < MAX_UL) {
|
||||
pde_t *pde = lookupPDSlot(pd, i);
|
||||
switch (pde_ptr_get_pdeType(pde)) {
|
||||
case pde_pde_section: {
|
||||
ret.frameBase = pde_pde_section_ptr_get_address(pde);
|
||||
#ifndef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
if (pde_pde_section_ptr_get_size(pde)) {
|
||||
ret.frameSize = ARMSuperSection;
|
||||
} else {
|
||||
ret.frameSize = ARMSection;
|
||||
}
|
||||
#else
|
||||
if (pde_pde_section_ptr_get_contiguous_hint(pde)) {
|
||||
/* Entires are represented as 16 contiguous sections. We need to mask
|
||||
to get the super section frame base */
|
||||
ret.frameBase &= ~MASK(pageBitsForSize(ARMSuperSection));
|
||||
ret.frameSize = ARMSuperSection;
|
||||
} else {
|
||||
ret.frameSize = ARMSection;
|
||||
}
|
||||
#endif
|
||||
printf("frame_%p_%04lu = frame ", pde, PD_INDEX(i));
|
||||
obj_frame_print_attrs(ret);
|
||||
break;
|
||||
}
|
||||
|
||||
case pde_pde_coarse: {
|
||||
pte_t *pt = ptrFromPAddr(pde_pde_coarse_ptr_get_address(pde));
|
||||
printf("pt_%p_%04lu = pt\n", pde, PD_INDEX(i));
|
||||
arm32_obj_pt_print_slots(pt);
|
||||
ret.frameSize = ARMSection;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ret.frameSize = ARMSection;
|
||||
break;
|
||||
}
|
||||
i += (1 << pageBitsForSize(ret.frameSize));
|
||||
if (i < (1 << pageBitsForSize(ret.frameSize))) {
|
||||
break; /* overflowed */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void capDL(void)
|
||||
{
|
||||
printf("arch aarch32\n");
|
||||
printf("objects {\n");
|
||||
print_objects();
|
||||
printf("}\n");
|
||||
|
||||
printf("caps {\n");
|
||||
|
||||
/* reset the seen list */
|
||||
reset_seen_list();
|
||||
|
||||
print_caps();
|
||||
printf("}\n");
|
||||
|
||||
obj_irq_print_maps();
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DEBUG_BUILD */
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ add_sources(
|
|||
PREFIX src/arch/arm/64
|
||||
CFILES
|
||||
object/objecttype.c
|
||||
machine/capdl.c
|
||||
machine/registerset.c
|
||||
machine/fpu.c
|
||||
model/statedata.c
|
||||
|
|
@ -21,3 +20,5 @@ add_sources(
|
|||
kernel/vspace.c
|
||||
ASMFILES head.S traps.S
|
||||
)
|
||||
|
||||
add_sources(DEP "KernelSel4ArchAarch64;KernelDebugBuild" CFILES src/arch/arm/64/machine/capdl.c)
|
||||
|
|
|
|||
|
|
@ -5,13 +5,551 @@
|
|||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <machine/capdl.h>
|
||||
#include <arch/machine/capdl.h>
|
||||
#include <string.h>
|
||||
#include <kernel/cspace.h>
|
||||
|
||||
#ifdef CONFIG_DEBUG_BUILD
|
||||
|
||||
void capDL(void)
|
||||
{
|
||||
static void obj_frame_print_attrs(lookupFrame_ret_t ret);
|
||||
static void cap_frame_print_attrs_pud(pude_t *pudSlot);
|
||||
static void cap_frame_print_attrs_pd(pde_t *pdSlot);
|
||||
static void cap_frame_print_attrs_pt(pte_t *ptSlot);
|
||||
static void cap_frame_print_attrs_impl(word_t SH, word_t AP, word_t NXN);
|
||||
static void cap_frame_print_attrs_vptr(word_t vptr, cap_t vspace);
|
||||
|
||||
static void _cap_frame_print_attrs_vptr(word_t vptr, vspace_root_t *vspaceRoot);
|
||||
|
||||
static void arm64_obj_pt_print_slots(pde_t *pdSlot);
|
||||
static void arm64_obj_pd_print_slots(pude_t *pudSlot);
|
||||
static void arm64_obj_pud_print_slots(void *pgdSlot_or_vspace);
|
||||
|
||||
static void arm64_cap_pt_print_slots(pde_t *pdSlot, vptr_t vptr);
|
||||
static void arm64_cap_pd_print_slots(pude_t *pudSlot, vptr_t vptr);
|
||||
static void arm64_cap_pud_print_slots(void *pgdSlot_or_vspace, vptr_t vptr);
|
||||
|
||||
word_t get_tcb_sp(tcb_t *tcb)
|
||||
{
|
||||
return tcb->tcbArch.tcbContext.registers[SP_EL0];
|
||||
}
|
||||
|
||||
/* Stage-1 access permissions:
|
||||
* AP[2:1] higer EL EL0
|
||||
* 00 rw None
|
||||
* 01 rw rw
|
||||
* 10 r None
|
||||
* 11 r r
|
||||
*
|
||||
* Stage-2 access permissions:
|
||||
* S2AP Access from Nonsecure EL1 or Non-secure EL0
|
||||
* 00 None
|
||||
* 01 r
|
||||
* 10 w
|
||||
* 11 rw
|
||||
*
|
||||
* For VMs or native seL4 applications, if hypervisor support
|
||||
* is enabled, we use the S2AP. The kernel itself running in
|
||||
* EL2 still uses the Stage-1 AP format.
|
||||
*/
|
||||
/* use when only have access to pte of frames */
|
||||
static void cap_frame_print_attrs_pud(pude_t *pudSlot)
|
||||
{
|
||||
cap_frame_print_attrs_impl(pude_pude_1g_ptr_get_SH(pudSlot),
|
||||
pude_pude_1g_ptr_get_AP(pudSlot),
|
||||
pude_pude_1g_ptr_get_UXN(pudSlot));
|
||||
}
|
||||
|
||||
static void cap_frame_print_attrs_pd(pde_t *pdSlot)
|
||||
{
|
||||
cap_frame_print_attrs_impl(pde_pde_large_ptr_get_SH(pdSlot),
|
||||
pde_pde_large_ptr_get_AP(pdSlot),
|
||||
pde_pde_large_ptr_get_UXN(pdSlot));
|
||||
}
|
||||
|
||||
static void cap_frame_print_attrs_pt(pte_t *ptSlot)
|
||||
{
|
||||
cap_frame_print_attrs_impl(pte_ptr_get_SH(ptSlot),
|
||||
pte_ptr_get_AP(ptSlot),
|
||||
pte_ptr_get_UXN(ptSlot));
|
||||
}
|
||||
|
||||
static void cap_frame_print_attrs_impl(word_t SH, word_t AP, word_t NXN)
|
||||
{
|
||||
printf("(");
|
||||
|
||||
/* rights */
|
||||
switch (AP) {
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
case 0b00:
|
||||
break;
|
||||
case 0b01:
|
||||
printf("R");
|
||||
break;
|
||||
case 0b10:
|
||||
printf("W");
|
||||
break;
|
||||
case 0b11:
|
||||
printf("RW");
|
||||
break;
|
||||
#else
|
||||
case 0b00:
|
||||
break;
|
||||
case 0b01:
|
||||
printf("RW");
|
||||
case 0b10:
|
||||
break;
|
||||
case 0b11:
|
||||
printf("R");
|
||||
#endif /* CONFIG_ARM_HYPERVISOR_SUPPORT */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!NXN) {
|
||||
printf("X");
|
||||
}
|
||||
|
||||
/* Only has effect if SMP enabled */
|
||||
if (SH != SMP_TERNARY(SMP_SHARE, 0)) {
|
||||
printf(", uncached");
|
||||
}
|
||||
|
||||
printf(")\n");
|
||||
}
|
||||
|
||||
/* use when only have access to vptr of frames */
|
||||
static void _cap_frame_print_attrs_vptr(word_t vptr, vspace_root_t *vspace)
|
||||
{
|
||||
lookupPUDSlot_ret_t pudSlot = lookupPUDSlot(vspace, vptr);
|
||||
if (pudSlot.status != EXCEPTION_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (pude_ptr_get_pude_type(pudSlot.pudSlot)) {
|
||||
case pude_pude_1g:
|
||||
printf("frame_%p_%04lu ", pudSlot.pudSlot, GET_PUD_INDEX(vptr));
|
||||
cap_frame_print_attrs_pud(pudSlot.pudSlot);
|
||||
break;
|
||||
|
||||
case pude_pude_pd: {
|
||||
pde_t *pd = paddr_to_pptr(pude_pude_pd_ptr_get_pd_base_address(pudSlot.pudSlot));
|
||||
pde_t *pdSlot = pd + GET_PD_INDEX(vptr);
|
||||
|
||||
switch (pde_ptr_get_pde_type(pdSlot)) {
|
||||
case pde_pde_large:
|
||||
printf("frame_%p_%04lu ", pdSlot, GET_PD_INDEX(vptr));
|
||||
cap_frame_print_attrs_pd(pdSlot);
|
||||
break;
|
||||
|
||||
case pde_pde_small: {
|
||||
pte_t *pt = paddr_to_pptr(pde_pde_small_ptr_get_pt_base_address(pdSlot));
|
||||
pte_t *ptSlot = pt + GET_PT_INDEX(vptr);
|
||||
|
||||
if (pte_ptr_get_present(ptSlot)) {
|
||||
printf("frame_%p_%04lu ", ptSlot, GET_PT_INDEX(vptr));
|
||||
cap_frame_print_attrs_pt(ptSlot);
|
||||
break;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
void cap_frame_print_attrs_vptr(word_t vptr, cap_t vspace)
|
||||
{
|
||||
_cap_frame_print_attrs_vptr(vptr, VSPACE_PTR(pptr_of_cap(vspace)));
|
||||
}
|
||||
|
||||
/*
|
||||
* print object slots
|
||||
*/
|
||||
static void arm64_cap_pt_print_slots(pde_t *pdSlot, vptr_t vptr)
|
||||
{
|
||||
pte_t *pt = paddr_to_pptr(pde_pde_small_ptr_get_pt_base_address(pdSlot));
|
||||
printf("pt_%p_%04lu {\n", pdSlot, GET_PD_INDEX(vptr));
|
||||
|
||||
for (word_t i = 0; i < BIT(PT_INDEX_OFFSET + PT_INDEX_BITS); i += (1 << PT_INDEX_OFFSET)) {
|
||||
pte_t *ptSlot = pt + GET_PT_INDEX(i);
|
||||
|
||||
if (pte_ptr_get_present(ptSlot)) {
|
||||
// print pte entries
|
||||
printf("0x%lx: frame_%p_%04lu", GET_PT_INDEX(i), ptSlot, GET_PT_INDEX(i));
|
||||
cap_frame_print_attrs_pt(ptSlot);
|
||||
}
|
||||
}
|
||||
printf("}\n"); /* pt */
|
||||
}
|
||||
|
||||
static void arm64_cap_pd_print_slots(pude_t *pudSlot, vptr_t vptr)
|
||||
{
|
||||
printf("pd_%p_%04lu {\n", pudSlot, GET_PUD_INDEX(vptr));
|
||||
pde_t *pd = paddr_to_pptr(pude_pude_pd_ptr_get_pd_base_address(pudSlot));
|
||||
|
||||
for (word_t i = 0; i < BIT(PD_INDEX_OFFSET + PD_INDEX_BITS); i += (1 << PD_INDEX_OFFSET)) {
|
||||
pde_t *pdSlot = pd + GET_PD_INDEX(i);
|
||||
|
||||
switch (pde_ptr_get_pde_type(pdSlot)) {
|
||||
|
||||
case pde_pde_large:
|
||||
printf("0x%lx: frame_%p_%04lu", GET_PD_INDEX(i), pdSlot, GET_PD_INDEX(i));
|
||||
cap_frame_print_attrs_pd(pdSlot);
|
||||
break;
|
||||
|
||||
case pde_pde_small:
|
||||
printf("0x%lx: pt_%p_%04lu\n", GET_PD_INDEX(i), pdSlot, GET_PD_INDEX(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("}\n"); /* pd */
|
||||
|
||||
for (word_t i = 0; i < BIT(PD_INDEX_OFFSET + PD_INDEX_BITS); i += (1 << PD_INDEX_OFFSET)) {
|
||||
pde_t *pdSlot = pd + GET_PD_INDEX(i);
|
||||
if (pde_ptr_get_pde_type(pdSlot) == pde_pde_small) {
|
||||
arm64_cap_pt_print_slots(pdSlot, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void arm64_cap_pud_print_slots(void *pgdSlot_or_vspace, vptr_t vptr)
|
||||
{
|
||||
#ifdef AARCH64_VSPACE_S2_START_L1
|
||||
pude_t *pud = pgdSlot_or_vspace;
|
||||
printf("%p_pd {\n", pgdSlot_or_vspace);
|
||||
#else
|
||||
pude_t *pud = paddr_to_pptr(pgde_pgde_pud_ptr_get_pud_base_address(pgdSlot_or_vspace));
|
||||
printf("pud_%p_%04lu {\n", pgdSlot_or_vspace, GET_PGD_INDEX(vptr));
|
||||
#endif
|
||||
|
||||
for (word_t i = 0; i < BIT(PUD_INDEX_OFFSET + UPUD_INDEX_BITS); i += (1 << PUD_INDEX_OFFSET)) {
|
||||
pude_t *pudSlot = pud + GET_PUD_INDEX(i);
|
||||
if (pude_ptr_get_pude_type(pudSlot) == pude_pude_pd) {
|
||||
printf("0x%lx: pd_%p_%04lu\n", GET_PUD_INDEX(i), pudSlot, GET_PUD_INDEX(i));
|
||||
}
|
||||
}
|
||||
|
||||
printf("}\n"); /* pgd/pud */
|
||||
|
||||
for (word_t i = 0; i < BIT(PUD_INDEX_OFFSET + UPUD_INDEX_BITS); i += (1 << PUD_INDEX_OFFSET)) {
|
||||
pude_t *pudSlot = pud + GET_PUD_INDEX(i);
|
||||
if (pude_ptr_get_pude_type(pudSlot) == pude_pude_pd) {
|
||||
arm64_cap_pd_print_slots(pudSlot, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void obj_vtable_print_slots(tcb_t *tcb)
|
||||
{
|
||||
if (isVTableRoot(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap) && !seen(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap)) {
|
||||
add_to_seen(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap);
|
||||
vspace_root_t *vspace = cap_vtable_root_get_basePtr(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap);
|
||||
|
||||
/*
|
||||
* ARM hyp uses 3 level translation rather than the usual 4 level.
|
||||
* levels: PGD -> UPD -> PD -> PT
|
||||
*/
|
||||
#ifdef AARCH64_VSPACE_S2_START_L1
|
||||
arm64_cap_pud_print_slots(vspace, 0);
|
||||
#else
|
||||
printf("%p_pd {\n", vspace);
|
||||
for (word_t i = 0; i < BIT(PGD_INDEX_OFFSET + PGD_INDEX_BITS); i += (1UL << PGD_INDEX_OFFSET)) {
|
||||
lookupPGDSlot_ret_t pgdSlot = lookupPGDSlot(vspace, i);
|
||||
if (pgde_pgde_pud_ptr_get_present(pgdSlot.pgdSlot)) {
|
||||
printf("0x%lx: pud_%p_%04lu\n", GET_PGD_INDEX(i), pgdSlot.pgdSlot, GET_PGD_INDEX(i));
|
||||
}
|
||||
}
|
||||
printf("}\n"); /* pd */
|
||||
|
||||
for (word_t i = 0; i < BIT(PGD_INDEX_OFFSET + PGD_INDEX_BITS); i += (1UL << PGD_INDEX_OFFSET)) {
|
||||
lookupPGDSlot_ret_t pgdSlot = lookupPGDSlot(vspace, i);
|
||||
if (pgde_pgde_pud_ptr_get_present(pgdSlot.pgdSlot)) {
|
||||
arm64_cap_pud_print_slots(pgdSlot.pgdSlot, i);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void print_ipc_buffer_slot(tcb_t *tcb)
|
||||
{
|
||||
word_t vptr = tcb->tcbIPCBuffer;
|
||||
printf("ipc_buffer_slot: ");
|
||||
cap_frame_print_attrs_vptr(vptr, TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap);
|
||||
}
|
||||
|
||||
void print_cap_arch(cap_t cap)
|
||||
{
|
||||
|
||||
switch (cap_get_capType(cap)) {
|
||||
case cap_page_table_cap: {
|
||||
asid_t asid = cap_page_table_cap_get_capPTMappedASID(cap);
|
||||
findVSpaceForASID_ret_t find_ret = findVSpaceForASID(asid);
|
||||
vptr_t vptr = cap_page_table_cap_get_capPTMappedAddress(cap);
|
||||
if (asid) {
|
||||
printf("pt_%p_%04lu (asid: %lu)\n",
|
||||
lookupPDSlot(find_ret.vspace_root, vptr).pdSlot, GET_PD_INDEX(vptr), (long unsigned int)asid);
|
||||
} else {
|
||||
printf("pt_%p_%04lu\n", lookupPDSlot(find_ret.vspace_root, vptr).pdSlot, GET_PD_INDEX(vptr));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case cap_page_directory_cap: {
|
||||
asid_t asid = cap_page_directory_cap_get_capPDMappedASID(cap);
|
||||
findVSpaceForASID_ret_t find_ret = findVSpaceForASID(asid);
|
||||
vptr_t vptr = cap_page_directory_cap_get_capPDMappedAddress(cap);
|
||||
if (asid) {
|
||||
printf("pd_%p_%04lu (asid: %lu)\n",
|
||||
lookupPUDSlot(find_ret.vspace_root, vptr).pudSlot, GET_PUD_INDEX(vptr), (long unsigned int)asid);
|
||||
} else {
|
||||
printf("pd_%p_%04lu\n",
|
||||
lookupPUDSlot(find_ret.vspace_root, vptr).pudSlot, GET_PUD_INDEX(vptr));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case cap_page_upper_directory_cap: {
|
||||
asid_t asid = cap_page_upper_directory_cap_get_capPUDMappedASID(cap);
|
||||
findVSpaceForASID_ret_t find_ret = findVSpaceForASID(asid);
|
||||
vptr_t vptr = cap_page_upper_directory_cap_get_capPUDMappedAddress(cap);
|
||||
|
||||
#ifdef AARCH64_VSPACE_S2_START_L1
|
||||
if (asid) {
|
||||
printf("pud_%p_%04lu (asid: %lu)\n",
|
||||
find_ret.vspace_root, GET_PGD_INDEX(vptr), (long unsigned int)asid);
|
||||
} else {
|
||||
printf("pud_%p_%04lu\n", find_ret.vspace_root, GET_PGD_INDEX(vptr));
|
||||
}
|
||||
#else
|
||||
if (asid) {
|
||||
printf("pud_%p_%04lu (asid: %lu)\n",
|
||||
lookupPGDSlot(find_ret.vspace_root, vptr).pgdSlot, GET_PGD_INDEX(vptr), (long unsigned int)asid);
|
||||
} else {
|
||||
printf("pud_%p_%04lu\n", lookupPGDSlot(find_ret.vspace_root, vptr).pgdSlot, GET_PGD_INDEX(vptr));
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case cap_page_global_directory_cap: {
|
||||
asid_t asid = cap_page_global_directory_cap_get_capPGDMappedASID(cap);
|
||||
findVSpaceForASID_ret_t find_ret = findVSpaceForASID(asid);
|
||||
if (asid) {
|
||||
printf("%p_pd (asid: %lu)\n",
|
||||
find_ret.vspace_root, (long unsigned int)asid);
|
||||
} else {
|
||||
printf("%p_pd\n", find_ret.vspace_root);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case cap_asid_control_cap: {
|
||||
/* only one in the system */
|
||||
printf("asid_control\n");
|
||||
break;
|
||||
}
|
||||
case cap_frame_cap: {
|
||||
vptr_t vptr = cap_frame_cap_get_capFMappedAddress(cap);
|
||||
findVSpaceForASID_ret_t find_ret = findVSpaceForASID(cap_frame_cap_get_capFMappedASID(cap));
|
||||
assert(find_ret.status == EXCEPTION_NONE);
|
||||
_cap_frame_print_attrs_vptr(vptr, find_ret.vspace_root);
|
||||
break;
|
||||
}
|
||||
case cap_asid_pool_cap: {
|
||||
printf("%p_asid_pool\n", (void *)cap_asid_pool_cap_get_capASIDPool(cap));
|
||||
break;
|
||||
}
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
case cap_vcpu_cap: {
|
||||
printf("%p_vcpu\n", (void *)cap_vcpu_cap_get_capVCPUPtr(cap));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ARM specific caps */
|
||||
#ifdef CONFIG_ARM_SMMU
|
||||
case cap_io_space_cap: {
|
||||
printf("%p_io_space\n", (void *)cap_io_space_cap_get_capModuleID(cap));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
printf("[unknown cap %lu]\n", (long unsigned int)cap_get_capType(cap));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void print_object_arch(cap_t cap)
|
||||
{
|
||||
switch (cap_get_capType(cap)) {
|
||||
case cap_frame_cap:
|
||||
case cap_page_table_cap:
|
||||
case cap_page_directory_cap:
|
||||
case cap_page_upper_directory_cap:
|
||||
case cap_page_global_directory_cap:
|
||||
/* don't need to deal with these objects since they get handled from vtable */
|
||||
break;
|
||||
|
||||
case cap_asid_pool_cap: {
|
||||
printf("%p_asid_pool = asid_pool ",
|
||||
(void *)cap_asid_pool_cap_get_capASIDPool(cap));
|
||||
obj_asidpool_print_attrs(cap);
|
||||
break;
|
||||
}
|
||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||
case cap_vcpu_cap: {
|
||||
printf("%p_vcpu = vcpu\n", (void *)cap_vcpu_cap_get_capVCPUPtr(cap));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
/* ARM specific objects */
|
||||
#ifdef CONFIG_ARM_SMMU
|
||||
case cap_io_space_cap: {
|
||||
printf("%p_io_space = io_space ", (void *)cap_io_space_cap_get_capModuleID(cap));
|
||||
arm_obj_iospace_print_attrs(cap);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
printf("[unknown object %lu]\n", (long unsigned int)cap_get_capType(cap));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void obj_frame_print_attrs(lookupFrame_ret_t ret)
|
||||
{
|
||||
printf("(");
|
||||
|
||||
/* VM size */
|
||||
switch (ret.frameSize) {
|
||||
case ARMHugePage:
|
||||
printf("1G");
|
||||
break;
|
||||
case ARMLargePage:
|
||||
printf("2M");
|
||||
break;
|
||||
case ARMSmallPage:
|
||||
printf("4k");
|
||||
break;
|
||||
}
|
||||
|
||||
printf(", paddr: 0x%p)\n", (void *)ret.frameBase);
|
||||
}
|
||||
|
||||
void arm64_obj_pt_print_slots(pde_t *pdSlot)
|
||||
{
|
||||
lookupFrame_ret_t ret;
|
||||
pte_t *pt = paddr_to_pptr(pde_pde_small_ptr_get_pt_base_address(pdSlot));
|
||||
|
||||
for (word_t i = 0; i < BIT(PT_INDEX_OFFSET + PT_INDEX_BITS); i += (1 << PT_INDEX_OFFSET)) {
|
||||
pte_t *ptSlot = pt + GET_PT_INDEX(i);
|
||||
|
||||
if (pte_ptr_get_present(ptSlot)) {
|
||||
ret.frameBase = pte_ptr_get_page_base_address(ptSlot);
|
||||
ret.frameSize = ARMSmallPage;
|
||||
printf("frame_%p_%04lu = frame ", ptSlot, GET_PT_INDEX(i));
|
||||
obj_frame_print_attrs(ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void arm64_obj_pd_print_slots(pude_t *pudSlot)
|
||||
{
|
||||
lookupFrame_ret_t ret;
|
||||
pde_t *pd = paddr_to_pptr(pude_pude_pd_ptr_get_pd_base_address(pudSlot));
|
||||
|
||||
for (word_t i = 0; i < BIT(PD_INDEX_OFFSET + PD_INDEX_BITS); i += (1 << PD_INDEX_OFFSET)) {
|
||||
pde_t *pdSlot = pd + GET_PD_INDEX(i);
|
||||
|
||||
if (pde_ptr_get_pde_type(pdSlot) == pde_pde_large) {
|
||||
ret.frameBase = pde_pde_large_ptr_get_page_base_address(pdSlot);
|
||||
ret.frameSize = ARMLargePage;
|
||||
|
||||
printf("frame_%p_%04lu = frame ", pdSlot, GET_PD_INDEX(i));
|
||||
obj_frame_print_attrs(ret);
|
||||
}
|
||||
|
||||
if (pde_ptr_get_pde_type(pdSlot) == pde_pde_small) {
|
||||
printf("pt_%p_%04lu = pt\n", pdSlot, GET_PD_INDEX(i));
|
||||
arm64_obj_pt_print_slots(pdSlot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void arm64_obj_pud_print_slots(void *pgdSlot_or_vspace)
|
||||
{
|
||||
lookupFrame_ret_t ret;
|
||||
pude_t *pud = paddr_to_pptr(pgde_pgde_pud_ptr_get_pud_base_address(pgdSlot_or_vspace));
|
||||
|
||||
for (word_t i = 0; i < BIT(PUD_INDEX_OFFSET + UPUD_INDEX_BITS); i += (1 << PUD_INDEX_OFFSET)) {
|
||||
pude_t *pudSlot = pud + GET_PUD_INDEX(i);
|
||||
|
||||
switch (pude_ptr_get_pude_type(pudSlot)) {
|
||||
case pude_pude_1g:
|
||||
ret.frameBase = pude_pude_1g_ptr_get_page_base_address(pudSlot);
|
||||
ret.frameSize = ARMHugePage;
|
||||
|
||||
printf("frame_%p_%04lu = frame ", pudSlot, GET_PUD_INDEX(i));
|
||||
obj_frame_print_attrs(ret);
|
||||
break;
|
||||
|
||||
case pude_pude_pd: {
|
||||
printf("pd_%p_%04lu = pd\n", pudSlot, GET_PUD_INDEX(i));
|
||||
arm64_obj_pd_print_slots(pudSlot);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void obj_tcb_print_vtable(tcb_t *tcb)
|
||||
{
|
||||
if (isVTableRoot(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap) && !seen(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap)) {
|
||||
add_to_seen(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap);
|
||||
vspace_root_t *vspace = cap_vtable_root_get_basePtr(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap);
|
||||
|
||||
/*
|
||||
* ARM hyp uses 3 level translation rather than the usual 4 level.
|
||||
* levels: PGD -> PUD -> PD -> PT
|
||||
*/
|
||||
#ifdef AARCH64_VSPACE_S2_START_L1
|
||||
printf("%p_pd = pud\n", vspace);
|
||||
arm64_obj_pud_print_slots(vspace);
|
||||
#else
|
||||
printf("%p_pd = pgd\n", vspace);
|
||||
for (word_t i = 0; i < BIT(PGD_INDEX_OFFSET + PGD_INDEX_BITS); i += (1UL << PGD_INDEX_OFFSET)) {
|
||||
lookupPGDSlot_ret_t pgdSlot = lookupPGDSlot(vspace, i);
|
||||
if (pgde_pgde_pud_ptr_get_present(pgdSlot.pgdSlot)) {
|
||||
printf("pud_%p_%04lu = pud\n", pgdSlot.pgdSlot, GET_PGD_INDEX(i));
|
||||
arm64_obj_pud_print_slots(pgdSlot.pgdSlot);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void capDL(void)
|
||||
{
|
||||
printf("arch aarch64\n");
|
||||
printf("objects {\n");
|
||||
print_objects();
|
||||
printf("}\n");
|
||||
|
||||
printf("caps {\n");
|
||||
|
||||
/* reset the seen list */
|
||||
reset_seen_list();
|
||||
|
||||
print_caps();
|
||||
printf("}\n");
|
||||
|
||||
obj_irq_print_maps();
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DEBUG_BUILD */
|
||||
|
|
|
|||
Loading…
Reference in a new issue