capDL: Add kernel debugging tool for capDL
Add general debugging features of capDL Kernel Printing Signed-off-by: Jingyao Zhou <Jingyao.Zhou@data61.csiro.au>
This commit is contained in:
parent
658e110622
commit
a403d0d66c
3 changed files with 562 additions and 0 deletions
|
|
@ -6,3 +6,45 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#ifdef CONFIG_DEBUG_BUILD
|
||||
|
||||
/* helpers */
|
||||
void add_to_seen(cap_t c);
|
||||
void reset_seen_list(void);
|
||||
bool_t seen(cap_t c);
|
||||
bool_t same_cap(cap_t a, cap_t b);
|
||||
bool_t root_or_idle_tcb(tcb_t *tcb);
|
||||
|
||||
/* common */
|
||||
void obj_tcb_print_cnodes(cap_t cnode, tcb_t *tcb);
|
||||
void print_caps(void);
|
||||
void print_objects(void);
|
||||
void print_cap(cap_t cap);
|
||||
void print_object(cap_t cap);
|
||||
|
||||
void obj_tcb_print_attrs(tcb_t *tcb);
|
||||
void obj_sc_print_attrs(cap_t sc);
|
||||
void obj_cnode_print_attrs(cap_t cnode);
|
||||
void obj_ut_print_attrs(cte_t *slot, tcb_t *tcb);
|
||||
|
||||
void obj_tcb_print_slots(tcb_t *tcb);
|
||||
void obj_cnode_print_slots(tcb_t *tcb);
|
||||
void obj_irq_print_slots(cap_t irq_cap);
|
||||
void obj_irq_print_maps(void);
|
||||
|
||||
void cap_ep_print_attrs(cap_t ep);
|
||||
void cap_ntfn_print_attrs(cap_t ntfn);
|
||||
void cap_cnode_print_attrs(cap_t cnode);
|
||||
|
||||
/* arch specific functions */
|
||||
void print_ipc_buffer_slot(tcb_t *tcb);
|
||||
/* TBD: currently the capDL extractor declaring an object for every entry in the vspace.
|
||||
* However, frames can be mapped into multiple locations but sould only be declared once.
|
||||
*/
|
||||
void obj_vtable_print_slots(tcb_t *tcb);
|
||||
word_t get_tcb_sp(tcb_t *tcb);
|
||||
void print_cap_arch(cap_t cap);
|
||||
void print_object_arch(cap_t cap);
|
||||
void obj_tcb_print_vtable(tcb_t *tcb);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -46,3 +46,8 @@ add_sources(
|
|||
src/object/schedcontrol.c
|
||||
src/kernel/sporadic.c
|
||||
)
|
||||
|
||||
add_sources(
|
||||
DEP "KernelDebugBuild;KernelArchARM OR KernelSel4ArchX86_64 OR KernelSel4ArchRiscV32"
|
||||
CFILES src/machine/capdl.c
|
||||
)
|
||||
|
|
|
|||
515
src/machine/capdl.c
Normal file
515
src/machine/capdl.c
Normal file
|
|
@ -0,0 +1,515 @@
|
|||
/*
|
||||
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-only
|
||||
*/
|
||||
|
||||
#include <machine/capdl.h>
|
||||
#include <machine/registerset.h>
|
||||
#include <machine/timer.h>
|
||||
#include <config.h>
|
||||
#include <string.h>
|
||||
#include <kernel/cspace.h>
|
||||
#ifdef CONFIG_KERNEL_MCS
|
||||
#include <kernel/sporadic.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUG_BUILD
|
||||
|
||||
#define SEEN_SZ 256
|
||||
|
||||
/* seen list - check this array before we print cnode and vspace */
|
||||
/* TBD: This is to avoid traversing the same cnode. It should be applied to object
|
||||
* as well since the extractor might comes across multiple caps to the same object.
|
||||
*/
|
||||
cap_t seen_list[SEEN_SZ];
|
||||
int watermark = 0;
|
||||
|
||||
void add_to_seen(cap_t c)
|
||||
{
|
||||
/* Won't work well if there're more than SEEN_SZ cnode */
|
||||
if (watermark <= SEEN_SZ) {
|
||||
seen_list[watermark] = c;
|
||||
watermark++;
|
||||
}
|
||||
}
|
||||
|
||||
void reset_seen_list(void)
|
||||
{
|
||||
memset(seen_list, 0, SEEN_SZ * sizeof(seen_list[0]));
|
||||
watermark = 0;
|
||||
}
|
||||
|
||||
bool_t seen(cap_t c)
|
||||
{
|
||||
for (int i = 0; i < watermark; i++) {
|
||||
if (same_cap(seen_list[i], c)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool_t same_cap(cap_t a, cap_t b)
|
||||
{
|
||||
return (a.words[0] == b.words[0] && a.words[1] == b.words[1]);
|
||||
}
|
||||
|
||||
/* Return true if strings are the same */
|
||||
static inline bool_t strings_equal(const char *str1, const char *str2)
|
||||
{
|
||||
while (*str1 && *str2 && (*str1 == *str2)) {
|
||||
str1++;
|
||||
str2++;
|
||||
}
|
||||
return !(*(const unsigned char *)str1 - * (const unsigned char *)str2);
|
||||
}
|
||||
|
||||
/* Return true if the tcb is for rootserver or idle thread */
|
||||
bool_t root_or_idle_tcb(tcb_t *tcb)
|
||||
{
|
||||
return (strings_equal(TCB_PTR_DEBUG_PTR(tcb)->tcbName, "rootserver")
|
||||
|| strings_equal(TCB_PTR_DEBUG_PTR(tcb)->tcbName, "idle_thread"));
|
||||
}
|
||||
|
||||
/*
|
||||
* Print objects
|
||||
*/
|
||||
|
||||
void obj_tcb_print_attrs(tcb_t *tcb)
|
||||
{
|
||||
printf("(addr: 0x%lx, ip: 0x%lx, sp: 0x%lx, prio: %lu, max_prio: %lu",
|
||||
(long unsigned int)tcb->tcbIPCBuffer,
|
||||
(long unsigned int)getRestartPC(tcb),
|
||||
(long unsigned int)get_tcb_sp(tcb),
|
||||
(long unsigned int)tcb->tcbPriority,
|
||||
(long unsigned int)tcb->tcbMCP);
|
||||
|
||||
#ifdef ENABLE_SMP_SUPPORT
|
||||
printf(", affinity: %lu", (long unsigned int)tcb->tcbAffinity);
|
||||
#endif /* ENABLE_SMP_SUPPORT */
|
||||
|
||||
/* init */
|
||||
|
||||
#ifdef CONFIG_KERNEL_MCS
|
||||
cap_t ep_cap = TCB_PTR_CTE_PTR(tcb, tcbFaultHandler)->cap;
|
||||
if (cap_get_capType(ep_cap) != cap_null_cap) {
|
||||
printf(", fault_ep: %p", EP_PTR(cap_endpoint_cap_get_capEPPtr(ep_cap)));
|
||||
}
|
||||
#endif
|
||||
|
||||
printf(", dom: %ld)\n", tcb->tcbDomain);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KERNEL_MCS
|
||||
|
||||
/* to make compilers happy */
|
||||
#define REFILL_INDEX(sc, index) (((refill_t *) (SC_REF(sc) + sizeof(sched_context_t)))[index])
|
||||
#define REFILL_HEAD(sc) REFILL_INDEX((sc), (sc)->scRefillHead)
|
||||
|
||||
static inline ticks_t sc_get_budget(sched_context_t *sc)
|
||||
{
|
||||
ticks_t sum = REFILL_HEAD(sc).rAmount;
|
||||
word_t current = sc->scRefillHead;
|
||||
|
||||
while (current != sc->scRefillTail) {
|
||||
current = ((current == sc->scRefillMax - 1u) ? (0) : current + 1u);
|
||||
sum += REFILL_INDEX(sc, current).rAmount;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
void obj_sc_print_attrs(cap_t sc_cap)
|
||||
{
|
||||
sched_context_t *sc = SC_PTR(cap_sched_context_cap_get_capSCPtr(sc_cap));
|
||||
printf("(period: %lu, budget: %lu, %lu bits)\n",
|
||||
(long unsigned int)ticksToUs(sc->scPeriod),
|
||||
(long unsigned int)ticksToUs(sc_get_budget(sc)),
|
||||
(word_t)cap_sched_context_cap_get_capSCSizeBits(sc_cap)
|
||||
);
|
||||
}
|
||||
#endif /* CONFIG_KERNEL_MCS */
|
||||
|
||||
void obj_ut_print_attrs(cte_t *slot, tcb_t *tcb)
|
||||
{
|
||||
/* might have two untypeds with the same address but different size */
|
||||
printf("%p_%lu_untyped = ut (%lu bits, paddr: %p) {",
|
||||
(void *)cap_untyped_cap_get_capPtr(slot->cap),
|
||||
(long unsigned int)cap_untyped_cap_get_capBlockSize(slot->cap),
|
||||
(long unsigned int)cap_untyped_cap_get_capBlockSize(slot->cap),
|
||||
WORD_PTR(cap_untyped_cap_get_capPtr(slot->cap)));
|
||||
|
||||
/* there is no need to check for a NullCap as NullCaps are
|
||||
always accompanied by null mdb pointers */
|
||||
for (cte_t *nextPtr = CTE_PTR(mdb_node_get_mdbNext(slot->cteMDBNode));
|
||||
nextPtr && isMDBParentOf(slot, nextPtr);
|
||||
nextPtr = CTE_PTR(mdb_node_get_mdbNext(slot->cteMDBNode))) {
|
||||
if (!sameRegionAs(slot->cap, nextPtr->cap)) {
|
||||
/* TBD:
|
||||
* - this will print out the attributes of the cap, which it shouldn't
|
||||
*
|
||||
* - might be a pathological case where an untyped has a child cap that
|
||||
* isn't reachable from any of the non root threads. This would result
|
||||
* in an object being mentioned but never properly defined
|
||||
*/
|
||||
print_cap(nextPtr->cap);
|
||||
}
|
||||
}
|
||||
printf("}\n");
|
||||
}
|
||||
|
||||
void obj_cnode_print_attrs(cap_t cnode)
|
||||
{
|
||||
printf("(%lu bits)\n", (long unsigned int)cap_cnode_cap_get_capCNodeRadix(cnode));
|
||||
}
|
||||
|
||||
void obj_tcb_print_cnodes(cap_t cnode, tcb_t *tcb)
|
||||
{
|
||||
if (seen(cnode)) {
|
||||
return;
|
||||
}
|
||||
add_to_seen(cnode);
|
||||
printf("%p_cnode = cnode ", (void *)cap_cnode_cap_get_capCNodePtr(cnode));
|
||||
obj_cnode_print_attrs(cnode);
|
||||
word_t radix = cap_cnode_cap_get_capCNodeRadix(cnode);
|
||||
|
||||
for (uint32_t i = 0; i < (1 << radix); i++) {
|
||||
lookupCapAndSlot_ret_t c = lookupCapAndSlot(tcb, i);
|
||||
if (cap_get_capType(c.cap) == cap_untyped_cap) {
|
||||
/* we need `cte_t *` to print out the slots of an untyped object */
|
||||
obj_ut_print_attrs(c.slot, tcb);
|
||||
|
||||
} else if (cap_get_capType(c.cap) == cap_cnode_cap) {
|
||||
/* TBD: deal with nested cnodes */
|
||||
|
||||
} else if (cap_get_capType(c.cap) != cap_null_cap) {
|
||||
print_object(c.cap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Caps
|
||||
*/
|
||||
|
||||
void cap_cnode_print_attrs(cap_t cnode)
|
||||
{
|
||||
printf("(guard: %lu, guard_size: %lu)\n",
|
||||
(long unsigned int)cap_cnode_cap_get_capCNodeGuard(cnode),
|
||||
(long unsigned int)cap_cnode_cap_get_capCNodeGuardSize(cnode));
|
||||
}
|
||||
|
||||
void cap_ep_print_attrs(cap_t ep)
|
||||
{
|
||||
printf("(");
|
||||
cap_endpoint_cap_get_capCanReceive(ep) ? putchar('R') : 0;
|
||||
cap_endpoint_cap_get_capCanSend(ep) ? putchar('W') : 0;
|
||||
cap_endpoint_cap_get_capCanGrant(ep) ? putchar('G') : 0;
|
||||
cap_endpoint_cap_get_capCanGrantReply(ep) ? putchar('P') : 0;
|
||||
long unsigned int badge = cap_endpoint_cap_get_capEPBadge(ep);
|
||||
badge ? printf(", badge: %lu)\n", badge) : printf(")\n");
|
||||
}
|
||||
|
||||
void cap_ntfn_print_attrs(cap_t ntfn)
|
||||
{
|
||||
printf("(");
|
||||
cap_notification_cap_get_capNtfnCanReceive(ntfn) ? putchar('R') : 0;
|
||||
cap_notification_cap_get_capNtfnCanSend(ntfn) ? putchar('W') : 0;
|
||||
long unsigned int badge = cap_notification_cap_get_capNtfnBadge(ntfn);
|
||||
badge ? printf(", badge: %lu)\n", badge) : printf(")\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* print object slots
|
||||
*/
|
||||
|
||||
void obj_tcb_print_slots(tcb_t *tcb)
|
||||
{
|
||||
printf("%p_tcb {\n", tcb);
|
||||
|
||||
/* CSpace root */
|
||||
if (cap_get_capType(TCB_PTR_CTE_PTR(tcb, tcbCTable)->cap) != cap_null_cap) {
|
||||
printf("cspace: %p_cnode ",
|
||||
(void *)cap_cnode_cap_get_capCNodePtr(TCB_PTR_CTE_PTR(tcb, tcbCTable)->cap));
|
||||
cap_cnode_print_attrs(TCB_PTR_CTE_PTR(tcb, tcbCTable)->cap);
|
||||
}
|
||||
|
||||
/* VSpace root */
|
||||
if (cap_get_capType(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap) != cap_null_cap) {
|
||||
printf("vspace: %p_pd\n",
|
||||
cap_vtable_cap_get_vspace_root_fp(TCB_PTR_CTE_PTR(tcb, tcbVTable)->cap));
|
||||
|
||||
}
|
||||
|
||||
/* IPC buffer cap slot */
|
||||
if (cap_get_capType(TCB_PTR_CTE_PTR(tcb, tcbBuffer)->cap) != cap_null_cap) {
|
||||
/* TBD: print out the bound vcpu */
|
||||
print_ipc_buffer_slot(tcb);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KERNEL_MCS
|
||||
|
||||
/* Fault endpoint slot */
|
||||
if (cap_get_capType(TCB_PTR_CTE_PTR(tcb, tcbFaultHandler)->cap) != cap_null_cap) {
|
||||
printf("fault_ep_slot: %p_ep ",
|
||||
(void *)cap_endpoint_cap_get_capEPPtr(TCB_PTR_CTE_PTR(tcb, tcbFaultHandler)->cap));
|
||||
cap_ep_print_attrs(TCB_PTR_CTE_PTR(tcb, tcbFaultHandler)->cap);
|
||||
}
|
||||
|
||||
/* sc */
|
||||
if (tcb->tcbSchedContext) {
|
||||
printf("sc_slot: %p_sc\n", tcb->tcbSchedContext);
|
||||
}
|
||||
|
||||
/* Timeout endpoint slot */
|
||||
if (cap_get_capType(TCB_PTR_CTE_PTR(tcb, tcbTimeoutHandler)->cap) != cap_null_cap) {
|
||||
printf("temp_fault_ep_slot: %p_ep ",
|
||||
(void *)cap_endpoint_cap_get_capEPPtr(TCB_PTR_CTE_PTR(tcb, tcbTimeoutHandler)->cap));
|
||||
cap_ep_print_attrs(TCB_PTR_CTE_PTR(tcb, tcbTimeoutHandler)->cap);
|
||||
}
|
||||
|
||||
# else
|
||||
/* Reply cap slot */
|
||||
if (cap_get_capType(TCB_PTR_CTE_PTR(tcb, tcbReply)->cap) != cap_null_cap) {
|
||||
printf("reply_slot: %p_reply\n",
|
||||
(void *)cap_reply_cap_get_capTCBPtr(TCB_PTR_CTE_PTR(tcb, tcbReply)->cap));
|
||||
}
|
||||
|
||||
/* TCB of most recent IPC sender */
|
||||
if (cap_get_capType(TCB_PTR_CTE_PTR(tcb, tcbCaller)->cap) != cap_null_cap) {
|
||||
tcb_t *caller = TCB_PTR(cap_thread_cap_get_capTCBPtr(TCB_PTR_CTE_PTR(tcb, tcbCaller)->cap));
|
||||
printf("caller_slot: %p_tcb\n", caller);
|
||||
}
|
||||
#endif /* CONFIG_KERNEL_MCS */
|
||||
printf("}\n");
|
||||
}
|
||||
|
||||
/* TBD: deal with nested cnodes */
|
||||
void obj_cnode_print_slots(tcb_t *tcb)
|
||||
{
|
||||
cap_t root = TCB_PTR_CTE_PTR(tcb, tcbCTable)->cap;
|
||||
if (cap_get_capType(root) != cap_cnode_cap) {
|
||||
return;
|
||||
}
|
||||
|
||||
word_t radix = cap_cnode_cap_get_capCNodeRadix(root);
|
||||
if (seen(root)) {
|
||||
return;
|
||||
}
|
||||
add_to_seen(root);
|
||||
|
||||
printf("%p_cnode {\n", (void *)cap_cnode_cap_get_capCNodePtr(root));
|
||||
|
||||
for (uint32_t i = 0; i < (1 << radix); i++) {
|
||||
lookupCapAndSlot_ret_t c = lookupCapAndSlot(tcb, i);
|
||||
if (cap_get_capType(c.cap) != cap_null_cap) {
|
||||
printf("0x%x: ", i);
|
||||
print_cap(c.cap);
|
||||
}
|
||||
}
|
||||
printf("}\n");
|
||||
|
||||
for (uint32_t i = 0; i < (1 << radix); i++) {
|
||||
lookupCapAndSlot_ret_t c = lookupCapAndSlot(tcb, i);
|
||||
if (cap_get_capType(c.cap) == cap_irq_handler_cap) {
|
||||
/* TBD: should instead print it from IRQNode */
|
||||
obj_irq_print_slots(c.cap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void obj_irq_print_maps(void)
|
||||
{
|
||||
printf("irq maps {\n");
|
||||
|
||||
for (seL4_Word target = 0; target < CONFIG_MAX_NUM_NODES; target++) {
|
||||
for (unsigned i = 0; i <= maxIRQ; i++) {
|
||||
irq_t irq = CORE_IRQ_TO_IRQT(target, i);
|
||||
if (isIRQActive(irq)) {
|
||||
cap_t cap = intStateIRQNode[IRQT_TO_IDX(irq)].cap;
|
||||
if (cap_get_capType(cap) != cap_null_cap) {
|
||||
printf("%d: 0x%lx_%lu_irq\n",
|
||||
i,
|
||||
#if defined(ENABLE_SMP_SUPPORT) && defined(CONFIG_ARCH_ARM)
|
||||
(long unsigned int)irq.irq,
|
||||
#else
|
||||
(long unsigned int)irq,
|
||||
#endif
|
||||
(long unsigned int)target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("}\n");
|
||||
}
|
||||
|
||||
void obj_irq_print_slots(cap_t irq_cap)
|
||||
{
|
||||
irq_t irq = IDX_TO_IRQT(cap_irq_handler_cap_get_capIRQ(irq_cap));
|
||||
if (isIRQActive(irq)) {
|
||||
printf("0x%lx_%lu_irq {\n",
|
||||
#if defined(ENABLE_SMP_SUPPORT) && defined(CONFIG_ARCH_ARM)
|
||||
(long unsigned int)irq.irq,
|
||||
#else
|
||||
(long unsigned int)irq,
|
||||
#endif
|
||||
(long unsigned int)IRQT_TO_CORE(irq));
|
||||
cap_t ntfn_cap = intStateIRQNode[IRQT_TO_IDX(irq)].cap;
|
||||
if (cap_get_capType(ntfn_cap) != cap_null_cap) {
|
||||
printf("0x0: ");
|
||||
print_cap(ntfn_cap);
|
||||
}
|
||||
printf("}\n");
|
||||
}
|
||||
}
|
||||
|
||||
void print_objects(void)
|
||||
{
|
||||
for (tcb_t *curr = NODE_STATE(ksDebugTCBs); curr != NULL; curr = TCB_PTR_DEBUG_PTR(curr)->tcbDebugNext) {
|
||||
if (root_or_idle_tcb(curr)) {
|
||||
continue;
|
||||
}
|
||||
/* print the contains of the tcb's vtable as objects */
|
||||
obj_tcb_print_vtable(curr);
|
||||
}
|
||||
|
||||
for (tcb_t *curr = NODE_STATE(ksDebugTCBs); curr != NULL; curr = TCB_PTR_DEBUG_PTR(curr)->tcbDebugNext) {
|
||||
if (root_or_idle_tcb(curr)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* print the tcb as objects */
|
||||
printf("%p_tcb = tcb ", curr);
|
||||
obj_tcb_print_attrs(curr);
|
||||
|
||||
/* print the contains of the tcb's ctable as objects */
|
||||
if (cap_get_capType(TCB_PTR_CTE_PTR(curr, tcbCTable)->cap) == cap_cnode_cap) {
|
||||
obj_tcb_print_cnodes(TCB_PTR_CTE_PTR(curr, tcbCTable)->cap, curr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void print_caps(void)
|
||||
{
|
||||
for (tcb_t *curr = NODE_STATE(ksDebugTCBs); curr != NULL; curr = TCB_PTR_DEBUG_PTR(curr)->tcbDebugNext) {
|
||||
if (root_or_idle_tcb(curr)) {
|
||||
continue;
|
||||
}
|
||||
obj_cnode_print_slots(curr);
|
||||
obj_vtable_print_slots(curr);
|
||||
obj_tcb_print_slots(curr);
|
||||
}
|
||||
}
|
||||
|
||||
void print_cap(cap_t cap)
|
||||
{
|
||||
switch (cap_get_capType(cap)) {
|
||||
case cap_endpoint_cap: {
|
||||
printf("%p_ep ",
|
||||
(void *)cap_endpoint_cap_get_capEPPtr(cap));
|
||||
cap_ep_print_attrs(cap);
|
||||
break;
|
||||
}
|
||||
case cap_notification_cap: {
|
||||
printf("%p_notification ",
|
||||
(void *)cap_notification_cap_get_capNtfnPtr(cap));
|
||||
cap_ntfn_print_attrs(cap);
|
||||
break;
|
||||
}
|
||||
case cap_untyped_cap: {
|
||||
printf("%p_untyped\n",
|
||||
(void *)cap_untyped_cap_get_capPtr(cap));
|
||||
break;
|
||||
}
|
||||
case cap_thread_cap: {
|
||||
printf("%p_tcb\n",
|
||||
(void *)cap_thread_cap_get_capTCBPtr(cap));
|
||||
break;
|
||||
}
|
||||
case cap_cnode_cap: {
|
||||
printf("%p_cnode ",
|
||||
(void *)cap_cnode_cap_get_capCNodePtr(cap));
|
||||
cap_cnode_print_attrs(cap);
|
||||
break;
|
||||
}
|
||||
#ifdef CONFIG_KERNEL_MCS
|
||||
case cap_reply_cap: {
|
||||
printf("%p_reply\n",
|
||||
(void *)cap_reply_cap_get_capReplyPtr(cap));
|
||||
break;
|
||||
}
|
||||
case cap_sched_context_cap: {
|
||||
printf("%p_sc\n",
|
||||
(void *)cap_sched_context_cap_get_capSCPtr(cap));
|
||||
break;
|
||||
}
|
||||
case cap_sched_control_cap: {
|
||||
printf("%lu_sched_control\n",
|
||||
(long unsigned int)cap_sched_control_cap_get_core(cap));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case cap_irq_control_cap: {
|
||||
printf("irq_control\n"); /* only one in the system */
|
||||
break;
|
||||
}
|
||||
case cap_irq_handler_cap: {
|
||||
printf("%p_%lu_irq\n",
|
||||
(void *)cap_irq_handler_cap_get_capIRQ(cap),
|
||||
(long unsigned int)IRQT_TO_CORE(IDX_TO_IRQT(cap_irq_handler_cap_get_capIRQ(cap))));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
print_cap_arch(cap);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void print_object(cap_t cap)
|
||||
{
|
||||
switch (cap_get_capType(cap)) {
|
||||
case cap_endpoint_cap: {
|
||||
printf("%p_ep = ep\n",
|
||||
(void *)cap_endpoint_cap_get_capEPPtr(cap));
|
||||
break;
|
||||
}
|
||||
case cap_notification_cap: {
|
||||
printf("%p_notification = notification\n",
|
||||
(void *)cap_notification_cap_get_capNtfnPtr(cap));
|
||||
break;
|
||||
}
|
||||
case cap_thread_cap: {
|
||||
/* this object has already got handle by `print_objects` */
|
||||
break;
|
||||
}
|
||||
case cap_cnode_cap: {
|
||||
assert(!"should not happend");
|
||||
}
|
||||
#ifdef CONFIG_KERNEL_MCS
|
||||
case cap_reply_cap: {
|
||||
printf("%p_reply = rtreply\n",
|
||||
(void *)cap_reply_cap_get_capReplyPtr(cap));
|
||||
break;
|
||||
}
|
||||
case cap_sched_context_cap: {
|
||||
printf("%p_sc = sc ",
|
||||
(void *)cap_sched_context_cap_get_capSCPtr(cap));
|
||||
obj_sc_print_attrs(cap);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case cap_irq_handler_cap: {
|
||||
printf("%p_%lu_irq = irq\n",
|
||||
(void *)cap_irq_handler_cap_get_capIRQ(cap),
|
||||
(long unsigned int)IRQT_TO_CORE(IDX_TO_IRQT(cap_irq_handler_cap_get_capIRQ(cap))));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
print_object_arch(cap);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Loading…
Reference in a new issue