]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbCmdBranch.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Universal / EbcDxe / EbcDebugger / EdbCmdBranch.c
1 /** @file
2
3 Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
4 SPDX-License-Identifier: BSD-2-Clause-Patent
5
6
7 **/
8
9 #include "Edb.h"
10
11 CHAR16 *mBranchTypeStr[] = {
12 L"(CALL)",
13 L"(CALLEX)",
14 L"(RET)",
15 L"(JMP)",
16 L"(JMP8)",
17 };
18
19 /**
20
21 Comvert Branch Type to string.
22
23 @param Type Branch Type
24
25 @retval String string of Branch Type.
26
27 **/
28 CHAR16 *
29 EdbBranchTypeToStr (
30 IN EFI_DEBUGGER_BRANCH_TYPE Type
31 )
32 {
33 if ((Type < 0) || (Type >= EfiDebuggerBranchTypeEbcMax)) {
34 return L"(Unknown Type)";
35 }
36
37 return mBranchTypeStr[Type];
38 }
39
40 /**
41
42 DebuggerCommand - CallStack.
43
44 @param CommandArg The argument for this command
45 @param DebuggerPrivate EBC Debugger private data structure
46 @param ExceptionType Exception type.
47 @param SystemContext EBC system context.
48
49 @retval EFI_DEBUG_CONTINUE formal return value
50
51 **/
52 EFI_DEBUG_STATUS
53 DebuggerCallStack (
54 IN CHAR16 *CommandArg,
55 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
56 IN EFI_EXCEPTION_TYPE ExceptionType,
57 IN OUT EFI_SYSTEM_CONTEXT SystemContext
58 )
59 {
60 INTN Index;
61 UINTN SubIndex;
62 CHAR8 *FuncName;
63 EFI_DEBUGGER_CALLSTACK_CONTEXT *CallStackEntry;
64 BOOLEAN ShowParameter;
65 UINTN ParameterNumber;
66
67 ShowParameter = FALSE;
68 ParameterNumber = EFI_DEBUGGER_CALL_DEFAULT_PARAMETER;
69
70 //
71 // Check argument
72 //
73 if (CommandArg != NULL) {
74 if (StriCmp (CommandArg, L"c") == 0) {
75 //
76 // Clear Call-Stack
77 //
78 DebuggerPrivate->CallStackEntryCount = 0;
79 ZeroMem (DebuggerPrivate->CallStackEntry, sizeof (DebuggerPrivate->CallStackEntry));
80 EDBPrint (L"Call-Stack is cleared\n");
81 return EFI_DEBUG_CONTINUE;
82 } else if (StriCmp (CommandArg, L"p") == 0) {
83 //
84 // Print Call-Stack with parameter
85 //
86 ShowParameter = TRUE;
87 CommandArg = StrGetNextTokenLine (L" ");
88 if (CommandArg != NULL) {
89 //
90 // Try to get the parameter number
91 //
92 ParameterNumber = Atoi (CommandArg);
93 if (ParameterNumber > 16) {
94 EDBPrint (L"Call-Stack argument Invalid\n");
95 return EFI_DEBUG_CONTINUE;
96 }
97 }
98 } else {
99 EDBPrint (L"Call-Stack argument Invalid\n");
100 return EFI_DEBUG_CONTINUE;
101 }
102 }
103
104 //
105 // Check CallStack Entry Count
106 //
107 if (DebuggerPrivate->CallStackEntryCount == 0) {
108 EDBPrint (L"No Call-Stack\n");
109 return EFI_DEBUG_CONTINUE;
110 } else if (DebuggerPrivate->CallStackEntryCount > EFI_DEBUGGER_CALLSTACK_MAX) {
111 EDBPrint (L"Call-Stack Crash, re-initialize!\n");
112 DebuggerPrivate->CallStackEntryCount = 0;
113 return EFI_DEBUG_CONTINUE;
114 }
115
116 //
117 // Go through each CallStack entry and print
118 //
119 EDBPrint (L"Call-Stack (TOP):\n");
120 EDBPrint (L" Caller Callee Name\n");
121 EDBPrint (L" ================== ================== ========\n");
122 // EDBPrint (L" 0x00000000FFFFFFFF 0xFFFFFFFF00000000 EfiMain\n");
123 for (Index = (INTN)(DebuggerPrivate->CallStackEntryCount - 1); Index >= 0; Index--) {
124 //
125 // Get CallStack and print
126 //
127 CallStackEntry = &DebuggerPrivate->CallStackEntry[Index];
128 EDBPrint (
129 L" 0x%016lx 0x%016lx",
130 CallStackEntry->SourceAddress,
131 CallStackEntry->DestAddress
132 );
133 FuncName = FindSymbolStr ((UINTN)CallStackEntry->DestAddress);
134 if (FuncName != NULL) {
135 EDBPrint (L" %a()", FuncName);
136 }
137
138 EDBPrint (L"\n");
139
140 if (ShowParameter) {
141 //
142 // Print parameter
143 //
144 if (sizeof (UINTN) == sizeof (UINT64)) {
145 EDBPrint (
146 L" Parameter Address (0x%016lx) (\n",
147 CallStackEntry->ParameterAddr
148 );
149 if (ParameterNumber == 0) {
150 EDBPrint (L" )\n");
151 continue;
152 }
153
154 //
155 // Print each parameter
156 //
157 for (SubIndex = 0; SubIndex < ParameterNumber - 1; SubIndex++) {
158 if (SubIndex % 2 == 0) {
159 EDBPrint (L" ");
160 }
161
162 EDBPrint (
163 L"0x%016lx, ",
164 CallStackEntry->Parameter[SubIndex]
165 );
166 if (SubIndex % 2 == 1) {
167 EDBPrint (L"\n");
168 }
169 }
170
171 if (SubIndex % 2 == 0) {
172 EDBPrint (L" ");
173 }
174
175 EDBPrint (
176 L"0x%016lx\n",
177 CallStackEntry->Parameter[SubIndex]
178 );
179 EDBPrint (L" )\n");
180 //
181 // break only for parameter
182 //
183 if ((((DebuggerPrivate->CallStackEntryCount - Index) % (16 / ParameterNumber)) == 0) &&
184 (Index != 0))
185 {
186 if (SetPageBreak ()) {
187 break;
188 }
189 }
190 } else {
191 EDBPrint (
192 L" Parameter Address (0x%08x) (\n",
193 CallStackEntry->ParameterAddr
194 );
195 if (ParameterNumber == 0) {
196 EDBPrint (L" )\n");
197 continue;
198 }
199
200 //
201 // Print each parameter
202 //
203 for (SubIndex = 0; SubIndex < ParameterNumber - 1; SubIndex++) {
204 if (SubIndex % 4 == 0) {
205 EDBPrint (L" ");
206 }
207
208 EDBPrint (
209 L"0x%08x, ",
210 CallStackEntry->Parameter[SubIndex]
211 );
212 if (SubIndex % 4 == 3) {
213 EDBPrint (L"\n");
214 }
215 }
216
217 if (SubIndex % 4 == 0) {
218 EDBPrint (L" ");
219 }
220
221 EDBPrint (
222 L"0x%08x\n",
223 CallStackEntry->Parameter[SubIndex]
224 );
225 EDBPrint (L" )\n");
226 //
227 // break only for parameter
228 //
229 if ((((DebuggerPrivate->CallStackEntryCount - Index) % (32 / ParameterNumber)) == 0) &&
230 (Index != 0))
231 {
232 if (SetPageBreak ()) {
233 break;
234 }
235 }
236 }
237 }
238 }
239
240 //
241 // Done
242 //
243 return EFI_DEBUG_CONTINUE;
244 }
245
246 /**
247
248 DebuggerCommand - InstructionBranch.
249
250 @param CommandArg The argument for this command
251 @param DebuggerPrivate EBC Debugger private data structure
252 @param ExceptionType Exception type.
253 @param SystemContext EBC system context.
254
255 @retval EFI_DEBUG_CONTINUE formal return value
256
257 **/
258 EFI_DEBUG_STATUS
259 DebuggerInstructionBranch (
260 IN CHAR16 *CommandArg,
261 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
262 IN EFI_EXCEPTION_TYPE ExceptionType,
263 IN OUT EFI_SYSTEM_CONTEXT SystemContext
264 )
265 {
266 UINTN Index;
267
268 //
269 // Check argument
270 //
271 if (CommandArg != NULL) {
272 if (StriCmp (CommandArg, L"c") == 0) {
273 //
274 // Clear Trace
275 //
276 DebuggerPrivate->TraceEntryCount = 0;
277 ZeroMem (DebuggerPrivate->TraceEntry, sizeof (DebuggerPrivate->TraceEntry));
278 EDBPrint (L"Instruction Trace is cleared\n");
279 } else {
280 EDBPrint (L"Trace argument Invalid\n");
281 }
282
283 return EFI_DEBUG_CONTINUE;
284 }
285
286 //
287 // Check Trace Entry Count
288 //
289 if (DebuggerPrivate->TraceEntryCount == 0) {
290 EDBPrint (L"No Instruction Trace\n");
291 return EFI_DEBUG_CONTINUE;
292 } else if (DebuggerPrivate->TraceEntryCount > EFI_DEBUGGER_TRACE_MAX) {
293 EDBPrint (L"Instruction Trace Crash, re-initialize!\n");
294 DebuggerPrivate->TraceEntryCount = 0;
295 return EFI_DEBUG_CONTINUE;
296 }
297
298 //
299 // Go through each Trace entry and print
300 //
301 EDBPrint (L"Instruction Trace (->Latest):\n");
302 EDBPrint (L" Source Addr Destination Addr Type\n");
303 EDBPrint (L" ================== ================== ========\n");
304 // EDBPrint (L" 0x00000000FFFFFFFF 0xFFFFFFFF00000000 (CALLEX)\n");
305 for (Index = 0; Index < DebuggerPrivate->TraceEntryCount; Index++) {
306 EDBPrint (
307 L" 0x%016lx 0x%016lx %s\n",
308 DebuggerPrivate->TraceEntry[Index].SourceAddress,
309 DebuggerPrivate->TraceEntry[Index].DestAddress,
310 EdbBranchTypeToStr (DebuggerPrivate->TraceEntry[Index].Type)
311 );
312 }
313
314 //
315 // Done
316 //
317 return EFI_DEBUG_CONTINUE;
318 }