1/* 2 * Copyright 2014, General Dynamics C4 Systems 3 * 4 * This software may be distributed and modified according to the terms of 5 * the GNU General Public License version 2. Note that NO WARRANTY is provided. 6 * See "LICENSE_GPLv2.txt" for details. 7 * 8 * @TAG(GD_GPL) 9 */ 10 11#include <config.h> 12 13#ifdef CONFIG_DEBUG_BUILD 14#ifndef __API_DEBUG_H 15#define __API_DEBUG_H 16 17#include <benchmark/benchmark_track.h> 18#include <arch/api/syscall.h> 19#include <arch/kernel/vspace.h> 20#include <model/statedata.h> 21#include <kernel/thread.h> 22 23#ifdef CONFIG_PRINTING 24 25static inline void 26debug_printKernelEntryReason(void) 27{ 28 printf("\nKernel entry via "); 29 switch (ksKernelEntry.path) { 30 case Entry_Interrupt: 31 printf("Interrupt, irq %lu\n", (unsigned long) ksKernelEntry.word); 32 break; 33 case Entry_UnknownSyscall: 34 printf("Unknown syscall, word: %lu", (unsigned long) ksKernelEntry.word); 35 break; 36 case Entry_VMFault: 37 printf("VM Fault, fault type: %lu\n", (unsigned long) ksKernelEntry.word); 38 break; 39 case Entry_UserLevelFault: 40 printf("User level fault, number: %lu", (unsigned long) ksKernelEntry.word); 41 break; 42#ifdef CONFIG_HARDWARE_DEBUG_API 43 case Entry_DebugFault: 44 printf("Debug fault. Fault Vaddr: 0x%lx", (unsigned long) ksKernelEntry.word); 45 break; 46#endif 47 case Entry_Syscall: 48 printf("Syscall, number: %ld, %s\n", (long) ksKernelEntry.syscall_no, syscall_names[ksKernelEntry.syscall_no]); 49 if (ksKernelEntry.syscall_no == -SysSend || 50 ksKernelEntry.syscall_no == -SysNBSend || 51 ksKernelEntry.syscall_no == -SysCall) { 52 53 printf("Cap type: %lu, Invocation tag: %lu\n", (unsigned long) ksKernelEntry.cap_type, 54 (unsigned long) ksKernelEntry.invocation_tag); 55 } 56 break; 57#ifdef CONFIG_ARCH_ARM 58 case Entry_VCPUFault: 59 printf("VCPUFault\n"); 60 break; 61#endif 62#ifdef CONFIG_ARCH_x86 63 case Entry_VMExit: 64 printf("VMExit\n"); 65 break; 66#endif 67 default: 68 printf("Unknown\n"); 69 break; 70 71 } 72} 73 74/* Prints the user context and stack trace of the current thread */ 75static inline void 76debug_printUserState(void) 77{ 78 tcb_t *tptr = NODE_STATE(ksCurThread); 79 printf("Current thread: %s\n", tptr->tcbName); 80 printf("Next instruction adress: %lx\n", getRestartPC(tptr)); 81 printf("Stack:\n"); 82 Arch_userStackTrace(tptr); 83} 84 85static inline void 86debug_printTCB(tcb_t *tcb) 87{ 88 printf("%40s\t", tcb->tcbName); 89 char* state; 90 switch (thread_state_get_tsType(tcb->tcbState)) { 91 case ThreadState_Inactive: 92 state = "inactive"; 93 break; 94 case ThreadState_Running: 95 state = "running"; 96 break; 97 case ThreadState_Restart: 98 state = "restart"; 99 break; 100 case ThreadState_BlockedOnReceive: 101 state = "blocked on recv"; 102 break; 103 case ThreadState_BlockedOnSend: 104 state = "blocked on send"; 105 break; 106 case ThreadState_BlockedOnReply: 107 state = "blocked on reply"; 108 break; 109 case ThreadState_BlockedOnNotification: 110 state = "blocked on ntfn"; 111 break; 112#ifdef CONFIG_VTX 113 case ThreadState_RunningVM: 114 state = "running VM"; 115 break; 116#endif 117 case ThreadState_IdleThreadState: 118 state = "idle"; 119 break; 120 default: 121 fail("Unknown thread state"); 122 } 123 124 word_t core = SMP_TERNARY(tcb->tcbAffinity, 0); 125 printf("%15s\t%p\t%20lu\t%lu\n", state, (void *) getRestartPC(tcb), tcb->tcbPriority, core); 126} 127 128static inline void 129debug_dumpScheduler(void) 130{ 131 printf("Dumping all tcbs!\n"); 132 printf("Name \tState \tIP \t Prio \t Core\n"); 133 printf("--------------------------------------------------------------------------------------\n"); 134 for (tcb_t *curr = NODE_STATE(ksDebugTCBs); curr != NULL; curr = curr->tcbDebugNext) { 135 debug_printTCB(curr); 136 } 137} 138#endif /* CONFIG_PRINTING */ 139#endif /* __API_DEBUG_H */ 140#endif /* CONFIG_DEBUG_BUILD */ 141 142