CS350 COS
COS
Loading...
Searching...
No Matches
debug.c File Reference
#include <stdbool.h>
#include <stdint.h>
#include <sys/kassert.h>
#include <sys/kconfig.h>
#include <sys/kdebug.h>
#include <sys/mp.h>
#include <machine/amd64.h>
#include <machine/amd64op.h>
#include <machine/atomic.h>
#include <machine/trap.h>
#include <machine/lapic.h>
#include <machine/mp.h>
Include dependency graph for debug.c:

Go to the source code of this file.

Functions

void Debug_HaltCPUs ()
 
void Debug_ResumeCPUs ()
 
void Debug_HaltIPI (TrapFrame *tf)
 
void Debug_Breakpoint (TrapFrame *tf)
 
static void Debug_Registers (int argc, const char *argv[])
 
 REGISTER_DBGCMD (registers, "Show CPU registers", Debug_Registers)
 
static void Debug_Backtrace (int argc, const char *argv[])
 
 REGISTER_DBGCMD (backtrace, "Print backtrace", Debug_Backtrace)
 
static void Debug_SetBreakpoint (int argc, const char *argv[])
 
 REGISTER_DBGCMD (bkpt, "Set breakpoint", Debug_SetBreakpoint)
 
static void Debug_ClearBreakpoint (int argc, const char *argv[])
 
 REGISTER_DBGCMD (clrbkpt, "Clear breakpoint", Debug_ClearBreakpoint)
 
static void Debug_ListBreakpoints (int argc, const char *argv[])
 
 REGISTER_DBGCMD (bkpts, "List breakpoint", Debug_ListBreakpoints)
 
static void Debug_Reboot (int argc, const char *argv[])
 
 REGISTER_DBGCMD (reboot, "Reboot computer", Debug_Reboot)
 

Variables

TrapFrameframes [MAX_CPUS]
 
static volatile uint64_t debugLock = 0
 
static volatile uint64_t debugCmd = 0
 
static volatile uint64_t debugHalted = 0
 

Function Documentation

◆ Debug_Backtrace()

static void Debug_Backtrace ( int  argc,
const char *  argv[] 
)
static

Definition at line 130 of file debug.c.

131{
132 TrapFrame *tf = frames[CPU()];
133 uint64_t *ptr;
134 uint64_t rip;
135 uint64_t rbp;
136
137 if (argc == 2) {
138 int cpuNo = Debug_StrToInt(argv[1]);
139 if (cpuNo >= MAX_CPUS) {
140 kprintf("Invalid CPU number\n");
141 return;
142 }
143 tf = frames[cpuNo];
144 }
145
146 rip = tf->rip;
147 rbp = tf->rbp;
148
149 kprintf("%-16s %-16s\n", "IP Pointer", "Base Pointer");
150 while (3) {
151 kprintf("%016llx %016llx\n", rip, rbp);
152 ptr = (uint64_t *)rbp;
153 if (rbp == 0ULL || rip == 0ULL) {
154 break;
155 }
156 rbp = ptr[0];
157 rip = ptr[1];
158 }
159}
TrapFrame * frames[MAX_CPUS]
Definition: debug.c:17
#define CPU
Definition: mp.h:7
int kprintf(const char *fmt,...)
Definition: printf.c:210
#define MAX_CPUS
Definition: kconfig.h:8
uint64_t Debug_StrToInt(const char *s)
Definition: debug.c:124
uint64_t rbp
Definition: trap.h:60
uint64_t rip
Definition: trap.h:72
Definition: trap.h:51
unsigned long uint64_t
Definition: types.h:13
Here is the call graph for this function:

◆ Debug_Breakpoint()

void Debug_Breakpoint ( TrapFrame tf)

Definition at line 67 of file debug.c.

68{
69 frames[CPU()] = tf;
70
71 // Should probably force all cores into the debugger
72 while(atomic_swap_uint64(&debugLock, 1) == 1) {
73 // Wait to acquire debugger lock
74 }
75
76 // Stop all processors
78
79 // Enter prompt
81
82 // Resume all processors
85}
void Debug_HaltCPUs()
Definition: debug.c:24
static volatile uint64_t debugLock
Definition: debug.c:19
void Debug_ResumeCPUs()
Definition: debug.c:40
static INLINE uint64_t atomic_swap_uint64(volatile uint64_t *dst, uint64_t newval)
Definition: atomic.h:15
static void atomic_set_uint64(volatile uint64_t *dst, uint64_t newval)
Definition: atomic.h:24
void Debug_Prompt()
Definition: debug.c:248
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Debug_ClearBreakpoint()

static void Debug_ClearBreakpoint ( int  argc,
const char *  argv[] 
)
static

Definition at line 195 of file debug.c.

196{
197 if (argc != 2) {
198 kprintf("clrbkpt [0-3]");
199 return;
200 }
201
202 uint32_t flags = read_dr7();
203 switch (argv[1][0]) {
204 case '0':
205 flags &= ~DR7_DR0G;
206 break;
207 case '1':
208 flags &= ~DR7_DR1G;
209 break;
210 case '2':
211 flags &= ~DR7_DR2G;
212 break;
213 case '3':
214 flags &= ~DR7_DR3G;
215 break;
216 default:
217 kprintf("Specify a breakpoint between 0-3\n");
218 }
219
220 write_dr7(flags);
221}
static INLINE void write_dr7(uint64_t val)
Definition: amd64op.h:289
static INLINE uint64_t read_dr7()
Definition: amd64op.h:279
unsigned int uint32_t
Definition: types.h:12
Here is the call graph for this function:

◆ Debug_HaltCPUs()

void Debug_HaltCPUs ( )

Definition at line 24 of file debug.c.

25{
26 debugCmd = 0;
27
28 if (MP_GetCPUs() == 1)
29 return;
30
32
33 // Wait for processors to enter
34 while (debugHalted < (MP_GetCPUs() - 1)) {
35 pause();
36 }
37}
static volatile uint64_t debugCmd
Definition: debug.c:20
static volatile uint64_t debugHalted
Definition: debug.c:21
int MP_GetCPUs()
Definition: mp.c:134
static INLINE void pause()
Definition: amd64op.h:24
int LAPIC_BroadcastNMI(int vector)
Definition: lapic.c:161
#define T_DEBUGIPI
Definition: trap.h:44
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Debug_HaltIPI()

void Debug_HaltIPI ( TrapFrame tf)

Definition at line 51 of file debug.c.

52{
54 __sync_fetch_and_add(&debugHalted, 1);
55
56 frames[CPU()] = tf;
57
58 while (debugCmd == 0) {
59 pause();
60 }
61
62 __sync_fetch_and_sub(&debugHalted, 1);
64}
void MP_SetState(int state)
Definition: mp.c:127
#define CPUSTATE_HALTED
Definition: mp.h:7
#define CPUSTATE_BOOTED
Definition: mp.h:6
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Debug_ListBreakpoints()

static void Debug_ListBreakpoints ( int  argc,
const char *  argv[] 
)
static

Definition at line 226 of file debug.c.

227{
228 uint32_t flags = read_dr7();
229
230 if (flags & DR7_DR0G) {
231 kprintf("DR0: 0x%lx\n", read_dr0());
232 }
233 if (flags & DR7_DR1G) {
234 kprintf("DR1: 0x%lx\n", read_dr1());
235 }
236 if (flags & DR7_DR2G) {
237 kprintf("DR2: 0x%lx\n", read_dr2());
238 }
239 if (flags & DR7_DR3G) {
240 kprintf("DR3: 0x%lx\n", read_dr3());
241 }
242}
#define DR7_DR2G
Definition: amd64.h:201
#define DR7_DR0G
Definition: amd64.h:197
#define DR7_DR3G
Definition: amd64.h:203
#define DR7_DR1G
Definition: amd64.h:199
static INLINE uint64_t read_dr1()
Definition: amd64op.h:211
static INLINE uint64_t read_dr3()
Definition: amd64op.h:245
static INLINE uint64_t read_dr0()
Definition: amd64op.h:194
static INLINE uint64_t read_dr2()
Definition: amd64op.h:228
Here is the call graph for this function:

◆ Debug_Reboot()

static void Debug_Reboot ( int  argc,
const char *  argv[] 
)
static

Definition at line 247 of file debug.c.

248{
249 /*
250 * Triple fault the core by loading a non-canonical address into CR3. We
251 * should use ACPI, or even the keyboard controller if it exists.
252 */
253 write_cr3(0x8000000000000000ULL);
254}
static INLINE void write_cr3(uint64_t val)
Definition: amd64op.h:166
Here is the call graph for this function:

◆ Debug_Registers()

static void Debug_Registers ( int  argc,
const char *  argv[] 
)
static

Definition at line 88 of file debug.c.

89{
90 TrapFrame *tf = frames[CPU()];
91
92 if (argc == 2) {
93 int cpuNo = Debug_StrToInt(argv[1]);
94 if (cpuNo >= MAX_CPUS) {
95 kprintf("Invalid CPU number\n");
96 return;
97 }
98 tf = frames[cpuNo];
99 }
100
101 kprintf("Interrupt %d Error Code: %016llx\n",
102 tf->vector, tf->errcode);
103 kprintf("cr0: %016llx cr2: %016llx\n",
104 read_cr0(), read_cr2());
105 kprintf("cr3: %016llx cr4: %016llx\n",
106 read_cr3(), read_cr4());
107 kprintf("dr0: %016llx dr1: %016llx dr2: %016llx\n",
108 read_dr0(), read_dr1(), read_dr2());
109 kprintf("dr3: %016llx dr6: %016llx dr7: %016llx\n",
110 read_dr3(), read_dr6(), read_dr7());
111 kprintf("rip: %04x:%016llx rsp: %04x:%016llx\n",
112 tf->cs, tf->rip, tf->ss, tf->rsp);
113 kprintf("rflags: %016llx ds: %04x es: %04x fs: %04x gs: %04x\n",
114 tf->rflags, read_ds(), read_es(), read_fs(), read_gs());
115 kprintf("rax: %016llx rbx: %016llx rcx: %016llx\n",
116 tf->rax, tf->rbx, tf->rcx);
117 kprintf("rdx: %016llx rsi: %016llx rdi: %016llx\n",
118 tf->rdx, tf->rsi, tf->rdi);
119 kprintf("rbp: %016llx r8: %016llx r9: %016llx\n",
120 tf->rbp, tf->r8, tf->r9);
121 kprintf("r10: %016llx r11: %016llx r12: %016llx\n",
122 tf->r10, tf->r11, tf->r12);
123 kprintf("r13: %016llx r14: %016llx r15: %016llx\n",
124 tf->r13, tf->r14, tf->r15);
125}
static INLINE uint16_t read_es()
Definition: amd64op.h:317
static INLINE uint16_t read_ds()
Definition: amd64op.h:300
static INLINE uint64_t read_cr2()
Definition: amd64op.h:146
static INLINE uint16_t read_fs()
Definition: amd64op.h:334
static INLINE uint64_t read_cr3()
Definition: amd64op.h:156
static INLINE uint64_t read_dr6()
Definition: amd64op.h:262
static INLINE uint16_t read_gs()
Definition: amd64op.h:351
static INLINE uint64_t read_cr4()
Definition: amd64op.h:173
static INLINE uint64_t read_cr0()
Definition: amd64op.h:129
uint16_t cs
Definition: trap.h:73
uint64_t r8
Definition: trap.h:59
uint64_t r15
Definition: trap.h:52
uint64_t rsi
Definition: trap.h:62
uint16_t ss
Definition: trap.h:79
uint64_t rsp
Definition: trap.h:78
uint64_t r12
Definition: trap.h:55
uint64_t rbx
Definition: trap.h:65
uint64_t rdi
Definition: trap.h:61
uint64_t rax
Definition: trap.h:67
uint64_t r14
Definition: trap.h:53
uint64_t vector
Definition: trap.h:69
uint64_t rcx
Definition: trap.h:64
uint32_t errcode
Definition: trap.h:70
uint64_t r10
Definition: trap.h:57
uint64_t r13
Definition: trap.h:54
uint64_t r9
Definition: trap.h:58
uint64_t rflags
Definition: trap.h:77
uint64_t rdx
Definition: trap.h:63
uint64_t r11
Definition: trap.h:56
Here is the call graph for this function:

◆ Debug_ResumeCPUs()

void Debug_ResumeCPUs ( )

Definition at line 40 of file debug.c.

41{
42 debugCmd = 1;
43
44 // Wait for processors to resume
45 while (debugHalted > 0) {
46 pause();
47 }
48}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Debug_SetBreakpoint()

static void Debug_SetBreakpoint ( int  argc,
const char *  argv[] 
)
static

Definition at line 164 of file debug.c.

165{
166 if (argc != 2) {
167 kprintf("bkpt [ADDR]");
168 return;
169 }
170
171 uint64_t addr = Debug_StrToInt(argv[1]);
172
173 uint32_t flags = read_dr7();
174
175 if (!(flags & DR7_DR0G)) {
177 write_dr7(flags | DR7_DR0G);
178 } else if (!(flags & DR7_DR1G)) {
180 write_dr7(flags | DR7_DR1G);
181 } else if (!(flags & DR7_DR2G)) {
183 write_dr7(flags | DR7_DR2G);
184 } else if (!(flags & DR7_DR3G)) {
186 write_dr7(flags | DR7_DR3G);
187 } else {
188 kprintf("No more breakpoints left!\n");
189 }
190}
static INLINE void write_dr0(uint64_t val)
Definition: amd64op.h:204
static INLINE void write_dr1(uint64_t val)
Definition: amd64op.h:221
static INLINE void write_dr2(uint64_t val)
Definition: amd64op.h:238
static INLINE void write_dr3(uint64_t val)
Definition: amd64op.h:255
uint64_t addr
Definition: multiboot.h:1
Here is the call graph for this function:

◆ REGISTER_DBGCMD() [1/6]

REGISTER_DBGCMD ( backtrace  ,
"Print backtrace"  ,
Debug_Backtrace   
)

◆ REGISTER_DBGCMD() [2/6]

REGISTER_DBGCMD ( bkpt  ,
"Set breakpoint"  ,
Debug_SetBreakpoint   
)

◆ REGISTER_DBGCMD() [3/6]

REGISTER_DBGCMD ( bkpts  ,
"List breakpoint"  ,
Debug_ListBreakpoints   
)

◆ REGISTER_DBGCMD() [4/6]

REGISTER_DBGCMD ( clrbkpt  ,
"Clear breakpoint"  ,
Debug_ClearBreakpoint   
)

◆ REGISTER_DBGCMD() [5/6]

REGISTER_DBGCMD ( reboot  ,
"Reboot computer"  ,
Debug_Reboot   
)

◆ REGISTER_DBGCMD() [6/6]

REGISTER_DBGCMD ( registers  ,
"Show CPU registers"  ,
Debug_Registers   
)

Variable Documentation

◆ debugCmd

volatile uint64_t debugCmd = 0
static

Definition at line 20 of file debug.c.

◆ debugHalted

volatile uint64_t debugHalted = 0
static

Definition at line 21 of file debug.c.

◆ debugLock

volatile uint64_t debugLock = 0
static

Definition at line 19 of file debug.c.

◆ frames

TrapFrame* frames[MAX_CPUS]

Definition at line 17 of file debug.c.