]> 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 EDBPrint (L"\n");
138
139 if (ShowParameter) {
140 //
141 // Print parameter
142 //
143 if (sizeof(UINTN) == sizeof(UINT64)) {
144 EDBPrint (
145 L" Parameter Address (0x%016lx) (\n",
146 CallStackEntry->ParameterAddr
147 );
148 if (ParameterNumber == 0) {
149 EDBPrint (L" )\n");
150 continue;
151 }
152 //
153 // Print each parameter
154 //
155 for (SubIndex = 0; SubIndex < ParameterNumber - 1; SubIndex++) {
156 if (SubIndex % 2 == 0) {
157 EDBPrint (L" ");
158 }
159 EDBPrint (
160 L"0x%016lx, ",
161 CallStackEntry->Parameter[SubIndex]
162 );
163 if (SubIndex % 2 == 1) {
164 EDBPrint (L"\n");
165 }
166 }
167 if (SubIndex % 2 == 0) {
168 EDBPrint (L" ");
169 }
170 EDBPrint (
171 L"0x%016lx\n",
172 CallStackEntry->Parameter[SubIndex]
173 );
174 EDBPrint (L" )\n");
175 //
176 // break only for parameter
177 //
178 if ((((DebuggerPrivate->CallStackEntryCount - Index) % (16 / ParameterNumber)) == 0) &&
179 (Index != 0)) {
180 if (SetPageBreak ()) {
181 break;
182 }
183 }
184 } else {
185 EDBPrint (
186 L" Parameter Address (0x%08x) (\n",
187 CallStackEntry->ParameterAddr
188 );
189 if (ParameterNumber == 0) {
190 EDBPrint (L" )\n");
191 continue;
192 }
193 //
194 // Print each parameter
195 //
196 for (SubIndex = 0; SubIndex < ParameterNumber - 1; SubIndex++) {
197 if (SubIndex % 4 == 0) {
198 EDBPrint (L" ");
199 }
200 EDBPrint (
201 L"0x%08x, ",
202 CallStackEntry->Parameter[SubIndex]
203 );
204 if (SubIndex % 4 == 3) {
205 EDBPrint (L"\n");
206 }
207 }
208 if (SubIndex % 4 == 0) {
209 EDBPrint (L" ");
210 }
211 EDBPrint (
212 L"0x%08x\n",
213 CallStackEntry->Parameter[SubIndex]
214 );
215 EDBPrint (L" )\n");
216 //
217 // break only for parameter
218 //
219 if ((((DebuggerPrivate->CallStackEntryCount - Index) % (32 / ParameterNumber)) == 0) &&
220 (Index != 0)) {
221 if (SetPageBreak ()) {
222 break;
223 }
224 }
225 }
226 }
227 }
228
229 //
230 // Done
231 //
232 return EFI_DEBUG_CONTINUE;
233 }
234
235 /**
236
237 DebuggerCommand - InstructionBranch.
238
239 @param CommandArg The argument for this command
240 @param DebuggerPrivate EBC Debugger private data structure
241 @param ExceptionType Exception type.
242 @param SystemContext EBC system context.
243
244 @retval EFI_DEBUG_CONTINUE formal return value
245
246 **/
247 EFI_DEBUG_STATUS
248 DebuggerInstructionBranch (
249 IN CHAR16 *CommandArg,
250 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,
251 IN EFI_EXCEPTION_TYPE ExceptionType,
252 IN OUT EFI_SYSTEM_CONTEXT SystemContext
253 )
254 {
255 UINTN Index;
256
257 //
258 // Check argument
259 //
260 if (CommandArg != NULL) {
261 if (StriCmp (CommandArg, L"c") == 0) {
262 //
263 // Clear Trace
264 //
265 DebuggerPrivate->TraceEntryCount = 0;
266 ZeroMem (DebuggerPrivate->TraceEntry, sizeof(DebuggerPrivate->TraceEntry));
267 EDBPrint (L"Instruction Trace is cleared\n");
268 } else {
269 EDBPrint (L"Trace argument Invalid\n");
270 }
271 return EFI_DEBUG_CONTINUE;
272 }
273
274 //
275 // Check Trace Entry Count
276 //
277 if (DebuggerPrivate->TraceEntryCount == 0) {
278 EDBPrint (L"No Instruction Trace\n");
279 return EFI_DEBUG_CONTINUE;
280 } else if (DebuggerPrivate->TraceEntryCount > EFI_DEBUGGER_TRACE_MAX) {
281 EDBPrint (L"Instruction Trace Crash, re-initialize!\n");
282 DebuggerPrivate->TraceEntryCount = 0;
283 return EFI_DEBUG_CONTINUE;
284 }
285
286 //
287 // Go through each Trace entry and print
288 //
289 EDBPrint (L"Instruction Trace (->Latest):\n");
290 EDBPrint (L" Source Addr Destination Addr Type\n");
291 EDBPrint (L" ================== ================== ========\n");
292 //EDBPrint (L" 0x00000000FFFFFFFF 0xFFFFFFFF00000000 (CALLEX)\n");
293 for (Index = 0; Index < DebuggerPrivate->TraceEntryCount; Index++) {
294 EDBPrint (
295 L" 0x%016lx 0x%016lx %s\n",
296 DebuggerPrivate->TraceEntry[Index].SourceAddress,
297 DebuggerPrivate->TraceEntry[Index].DestAddress,
298 EdbBranchTypeToStr (DebuggerPrivate->TraceEntry[Index].Type)
299 );
300 }
301
302 //
303 // Done
304 //
305 return EFI_DEBUG_CONTINUE;
306 }