]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/EbcDxe/EbcDebugger/Edb.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Universal / EbcDxe / EbcDebugger / Edb.c
CommitLineData
e8a5ac7c 1/** @file\r
748edcd5 2\r
e8a5ac7c 3Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
9d510e61 4SPDX-License-Identifier: BSD-2-Clause-Patent\r
748edcd5 5\r
e8a5ac7c 6**/\r
748edcd5
PB
7\r
8#include <Uefi.h>\r
9#include "Edb.h"\r
10\r
1436aea4 11EFI_DEBUGGER_PRIVATE_DATA mDebuggerPrivate = {\r
748edcd5
PB
12 EFI_DEBUGGER_SIGNATURE, // Signature\r
13 IsaEbc, // Isa\r
14 (EBC_DEBUGGER_MAJOR_VERSION << 16) |\r
1436aea4 15 EBC_DEBUGGER_MINOR_VERSION, // EfiDebuggerRevision\r
748edcd5 16 (VM_MAJOR_VERSION << 16) |\r
1436aea4 17 VM_MINOR_VERSION, // EbcVmRevision\r
2b2efe33
PB
18 {\r
19 EFI_DEBUGGER_CONFIGURATION_VERSION,\r
20 &mDebuggerPrivate,\r
21 }, // DebuggerConfiguration\r
748edcd5
PB
22 NULL, // DebugImageInfoTableHeader\r
23 NULL, // Vol\r
24 NULL, // PciRootBridgeIo\r
25 mDebuggerCommandSet, // DebuggerCommandSet\r
1436aea4 26 { 0 }, // DebuggerSymbolContext\r
748edcd5 27 0, // DebuggerBreakpointCount\r
1436aea4
MK
28 {\r
29 { 0 }\r
30 }, // DebuggerBreakpointContext\r
748edcd5 31 0, // CallStackEntryCount\r
1436aea4
MK
32 {\r
33 { 0 }\r
34 }, // CallStackEntry\r
748edcd5 35 0, // TraceEntryCount\r
1436aea4
MK
36 {\r
37 { 0 }\r
38 }, // TraceEntry\r
39 { 0 }, // StepContext\r
40 { 0 }, // GoTilContext\r
41 0, // InstructionScope\r
42 EFI_DEBUG_DEFAULT_INSTRUCTION_NUMBER, // InstructionNumber\r
748edcd5
PB
43 EFI_DEBUG_FLAG_EBC_BOE | EFI_DEBUG_FLAG_EBC_BOT, // FeatureFlags\r
44 0, // StatusFlags\r
45 FALSE, // EnablePageBreak\r
46 NULL // BreakEvent\r
47};\r
48\r
1436aea4 49CHAR16 *mExceptionStr[] = {\r
748edcd5
PB
50 L"EXCEPT_EBC_UNDEFINED",\r
51 L"EXCEPT_EBC_DIVIDE_ERROR",\r
52 L"EXCEPT_EBC_DEBUG",\r
53 L"EXCEPT_EBC_BREAKPOINT",\r
54 L"EXCEPT_EBC_OVERFLOW",\r
55 L"EXCEPT_EBC_INVALID_OPCODE",\r
56 L"EXCEPT_EBC_STACK_FAULT",\r
57 L"EXCEPT_EBC_ALIGNMENT_CHECK",\r
58 L"EXCEPT_EBC_INSTRUCTION_ENCODING",\r
59 L"EXCEPT_EBC_BAD_BREAK",\r
60 L"EXCEPT_EBC_SINGLE_STEP",\r
61};\r
62\r
e8a5ac7c
DB
63/**\r
64\r
65 Clear all the breakpoint.\r
66\r
67 @param DebuggerPrivate EBC Debugger private data structure\r
68 @param NeedRemove Whether need to remove all the breakpoint\r
69\r
70**/\r
748edcd5
PB
71VOID\r
72EdbClearAllBreakpoint (\r
1436aea4
MK
73 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
74 IN BOOLEAN NeedRemove\r
748edcd5 75 )\r
748edcd5 76{\r
1436aea4 77 UINTN Index;\r
748edcd5
PB
78\r
79 //\r
80 // Patch all the breakpoint\r
81 //\r
82 for (Index = 0; (Index < DebuggerPrivate->DebuggerBreakpointCount) && (Index < EFI_DEBUGGER_BREAKPOINT_MAX); Index++) {\r
83 if (DebuggerPrivate->DebuggerBreakpointContext[Index].State) {\r
84 CopyMem (\r
85 (VOID *)(UINTN)DebuggerPrivate->DebuggerBreakpointContext[Index].BreakpointAddress,\r
86 &DebuggerPrivate->DebuggerBreakpointContext[Index].OldInstruction,\r
1436aea4 87 sizeof (UINT16)\r
748edcd5
PB
88 );\r
89 }\r
90 }\r
91\r
92 //\r
93 // Zero Breakpoint context, if need to remove all breakpoint\r
94 //\r
95 if (NeedRemove) {\r
96 DebuggerPrivate->DebuggerBreakpointCount = 0;\r
1436aea4 97 ZeroMem (DebuggerPrivate->DebuggerBreakpointContext, sizeof (DebuggerPrivate->DebuggerBreakpointContext));\r
748edcd5
PB
98 }\r
99\r
100 //\r
101 // Done\r
102 //\r
1436aea4 103 return;\r
748edcd5
PB
104}\r
105\r
e8a5ac7c
DB
106/**\r
107\r
108 Set all the breakpoint.\r
109\r
110 @param DebuggerPrivate EBC Debugger private data structure\r
111\r
112**/\r
748edcd5
PB
113VOID\r
114EdbSetAllBreakpoint (\r
1436aea4 115 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate\r
748edcd5 116 )\r
748edcd5 117{\r
1436aea4
MK
118 UINTN Index;\r
119 UINT16 Data16;\r
748edcd5
PB
120\r
121 //\r
122 // Set all the breakpoint (BREAK(3) : 0x0300)\r
123 //\r
124 Data16 = 0x0300;\r
125 for (Index = 0; (Index < DebuggerPrivate->DebuggerBreakpointCount) && (Index < EFI_DEBUGGER_BREAKPOINT_MAX); Index++) {\r
126 if (DebuggerPrivate->DebuggerBreakpointContext[Index].State) {\r
127 CopyMem (\r
128 (VOID *)(UINTN)DebuggerPrivate->DebuggerBreakpointContext[Index].BreakpointAddress,\r
129 &Data16,\r
1436aea4 130 sizeof (UINT16)\r
748edcd5
PB
131 );\r
132 }\r
133 }\r
134\r
135 //\r
136 // Check if current break is caused by breakpoint set.\r
137 // If so, we need to patch memory back to let user see the real memory.\r
138 //\r
139 if (DebuggerPrivate->DebuggerBreakpointContext[EFI_DEBUGGER_BREAKPOINT_MAX].BreakpointAddress != 0) {\r
140 CopyMem (\r
141 (VOID *)(UINTN)DebuggerPrivate->DebuggerBreakpointContext[EFI_DEBUGGER_BREAKPOINT_MAX].BreakpointAddress,\r
142 &DebuggerPrivate->DebuggerBreakpointContext[EFI_DEBUGGER_BREAKPOINT_MAX].OldInstruction,\r
1436aea4 143 sizeof (UINT16)\r
748edcd5
PB
144 );\r
145 DebuggerPrivate->StatusFlags &= ~EFI_DEBUG_FLAG_EBC_B_BP;\r
146 }\r
147\r
148 //\r
149 // Done\r
150 //\r
1436aea4 151 return;\r
748edcd5
PB
152}\r
153\r
e8a5ac7c 154/**\r
748edcd5
PB
155\r
156 Check all the breakpoint, if match, then set status flag, and record current breakpoint.\r
157 Then clear all breakpoint to let user see a clean memory\r
158\r
e8a5ac7c
DB
159 @param DebuggerPrivate EBC Debugger private data structure\r
160 @param SystemContext EBC system context.\r
748edcd5 161\r
e8a5ac7c
DB
162**/\r
163VOID\r
164EdbCheckBreakpoint (\r
1436aea4
MK
165 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
166 IN EFI_SYSTEM_CONTEXT SystemContext\r
e8a5ac7c 167 )\r
748edcd5
PB
168{\r
169 UINT64 Address;\r
170 UINTN Index;\r
748edcd5
PB
171 BOOLEAN IsHitBreakpoint;\r
172\r
173 //\r
174 // Roll back IP for breakpoint instruction (BREAK(3) : 0x0300)\r
175 //\r
1436aea4 176 Address = SystemContext.SystemContextEbc->Ip - sizeof (UINT16);\r
748edcd5
PB
177\r
178 //\r
179 // Check if the breakpoint is hit\r
180 //\r
181 IsHitBreakpoint = FALSE;\r
182 for (Index = 0; (Index < DebuggerPrivate->DebuggerBreakpointCount) && (Index < EFI_DEBUGGER_BREAKPOINT_MAX); Index++) {\r
183 if ((DebuggerPrivate->DebuggerBreakpointContext[Index].BreakpointAddress == Address) &&\r
1436aea4
MK
184 (DebuggerPrivate->DebuggerBreakpointContext[Index].State))\r
185 {\r
748edcd5
PB
186 IsHitBreakpoint = TRUE;\r
187 break;\r
188 }\r
189 }\r
190\r
191 if (IsHitBreakpoint) {\r
192 //\r
193 // If hit, record current breakpoint\r
194 //\r
1436aea4 195 DebuggerPrivate->DebuggerBreakpointContext[EFI_DEBUGGER_BREAKPOINT_MAX] = DebuggerPrivate->DebuggerBreakpointContext[Index];\r
748edcd5
PB
196 DebuggerPrivate->DebuggerBreakpointContext[EFI_DEBUGGER_BREAKPOINT_MAX].State = TRUE;\r
197 //\r
198 // Update: IP and Instruction (NOTE: Since we not allow set breakpoint to BREAK 3, this update is safe)\r
199 //\r
200 SystemContext.SystemContextEbc->Ip = Address;\r
201 //\r
202 // Set Flags\r
203 //\r
204 DebuggerPrivate->StatusFlags |= EFI_DEBUG_FLAG_EBC_BP;\r
205 } else {\r
206 //\r
207 // If not hit, check whether current IP is in breakpoint list,\r
208 // because STEP will be triggered before execute the instruction.\r
209 // We should not patch it in de-init.\r
210 //\r
211 Address = SystemContext.SystemContextEbc->Ip;\r
212\r
213 //\r
214 // Check if the breakpoint is hit\r
215 //\r
216 IsHitBreakpoint = FALSE;\r
217 for (Index = 0; (Index < DebuggerPrivate->DebuggerBreakpointCount) && (Index < EFI_DEBUGGER_BREAKPOINT_MAX); Index++) {\r
218 if ((DebuggerPrivate->DebuggerBreakpointContext[Index].BreakpointAddress == Address) &&\r
1436aea4
MK
219 (DebuggerPrivate->DebuggerBreakpointContext[Index].State))\r
220 {\r
748edcd5
PB
221 IsHitBreakpoint = TRUE;\r
222 break;\r
223 }\r
224 }\r
225\r
226 if (IsHitBreakpoint) {\r
227 //\r
228 // If hit, record current breakpoint\r
229 //\r
b04453d3
M
230 CopyMem (\r
231 &DebuggerPrivate->DebuggerBreakpointContext[EFI_DEBUGGER_BREAKPOINT_MAX],\r
232 &DebuggerPrivate->DebuggerBreakpointContext[Index],\r
233 sizeof (DebuggerPrivate->DebuggerBreakpointContext[EFI_DEBUGGER_BREAKPOINT_MAX])\r
234 );\r
748edcd5
PB
235 DebuggerPrivate->DebuggerBreakpointContext[EFI_DEBUGGER_BREAKPOINT_MAX].State = TRUE;\r
236 //\r
237 // Do not set Breakpoint flag. We record the address here just let it not patch breakpoint address when de-init.\r
238 //\r
239 } else {\r
240 //\r
241 // Zero current breakpoint\r
242 //\r
243 ZeroMem (\r
244 &DebuggerPrivate->DebuggerBreakpointContext[EFI_DEBUGGER_BREAKPOINT_MAX],\r
1436aea4 245 sizeof (DebuggerPrivate->DebuggerBreakpointContext[EFI_DEBUGGER_BREAKPOINT_MAX])\r
748edcd5
PB
246 );\r
247 }\r
248 }\r
249\r
250 //\r
251 // Done\r
252 //\r
1436aea4 253 return;\r
748edcd5
PB
254}\r
255\r
e8a5ac7c
DB
256/**\r
257 clear all the symbol.\r
258\r
259 @param DebuggerPrivate EBC Debugger private data structure\r
260\r
261**/\r
748edcd5
PB
262VOID\r
263EdbClearSymbol (\r
1436aea4 264 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate\r
748edcd5 265 )\r
748edcd5 266{\r
1436aea4
MK
267 EFI_DEBUGGER_SYMBOL_CONTEXT *DebuggerSymbolContext;\r
268 EFI_DEBUGGER_SYMBOL_OBJECT *Object;\r
269 UINTN ObjectIndex;\r
270 UINTN Index;\r
748edcd5
PB
271\r
272 //\r
273 // Go throuth each object\r
274 //\r
275 DebuggerSymbolContext = &DebuggerPrivate->DebuggerSymbolContext;\r
276 for (ObjectIndex = 0; ObjectIndex < DebuggerSymbolContext->ObjectCount; ObjectIndex++) {\r
277 Object = &DebuggerSymbolContext->Object[ObjectIndex];\r
278 //\r
279 // Go throuth each entry\r
280 //\r
281 for (Index = 0; Index < Object->EntryCount; Index++) {\r
1436aea4 282 ZeroMem (&Object->Entry[Index], sizeof (Object->Entry[Index]));\r
748edcd5 283 }\r
1436aea4
MK
284\r
285 ZeroMem (Object->Name, sizeof (Object->Name));\r
286 Object->EntryCount = 0;\r
287 Object->BaseAddress = 0;\r
748edcd5 288 Object->StartEntrypointRVA = 0;\r
1436aea4 289 Object->MainEntrypointRVA = 0;\r
748edcd5
PB
290 //\r
291 // Free source buffer\r
292 //\r
293 for (Index = 0; Object->SourceBuffer[Index] != NULL; Index++) {\r
294 gBS->FreePool (Object->SourceBuffer[Index]);\r
295 Object->SourceBuffer[Index] = NULL;\r
296 }\r
297 }\r
1436aea4 298\r
748edcd5
PB
299 DebuggerSymbolContext->ObjectCount = 0;\r
300\r
1436aea4 301 return;\r
748edcd5
PB
302}\r
303\r
e8a5ac7c
DB
304/**\r
305\r
306 Initialize Debugger private data structure\r
307\r
308 @param DebuggerPrivate EBC Debugger private data structure\r
309 @param ExceptionType Exception type.\r
310 @param SystemContext EBC system context.\r
311 @param Initialized Whether the DebuggerPrivate data is initialized.\r
312\r
313**/\r
748edcd5
PB
314EFI_STATUS\r
315InitDebuggerPrivateData (\r
1436aea4
MK
316 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
317 IN EFI_EXCEPTION_TYPE ExceptionType,\r
318 IN EFI_SYSTEM_CONTEXT SystemContext,\r
319 IN BOOLEAN Initialized\r
748edcd5 320 )\r
748edcd5
PB
321{\r
322 //\r
323 // clear STEP flag in any condition.\r
324 //\r
1436aea4
MK
325 if (SystemContext.SystemContextEbc->Flags & ((UINT64)VMFLAGS_STEP)) {\r
326 SystemContext.SystemContextEbc->Flags &= ~((UINT64)VMFLAGS_STEP);\r
748edcd5
PB
327 }\r
328\r
329 if (!Initialized) {\r
330 //\r
331 // Initialize everything\r
332 //\r
333 DebuggerPrivate->InstructionNumber = EFI_DEBUG_DEFAULT_INSTRUCTION_NUMBER;\r
334\r
335 DebuggerPrivate->DebuggerBreakpointCount = 0;\r
1436aea4 336 ZeroMem (DebuggerPrivate->DebuggerBreakpointContext, sizeof (DebuggerPrivate->DebuggerBreakpointContext));\r
748edcd5 337\r
1436aea4 338 // DebuggerPrivate->StatusFlags = 0;\r
748edcd5 339\r
1436aea4 340 DebuggerPrivate->DebuggerSymbolContext.DisplaySymbol = TRUE;\r
748edcd5 341 DebuggerPrivate->DebuggerSymbolContext.DisplayCodeOnly = FALSE;\r
1436aea4 342 DebuggerPrivate->DebuggerSymbolContext.ObjectCount = 0;\r
748edcd5
PB
343 } else {\r
344 //\r
345 // Already initialized, just check Breakpoint here.\r
346 //\r
347 if (ExceptionType == EXCEPT_EBC_BREAKPOINT) {\r
348 EdbCheckBreakpoint (DebuggerPrivate, SystemContext);\r
349 }\r
350\r
351 //\r
352 // Clear all breakpoint\r
353 //\r
354 EdbClearAllBreakpoint (DebuggerPrivate, FALSE);\r
355 }\r
356\r
357 //\r
358 // Set Scope to currentl IP. (Note: Check Breakpoint may change Ip)\r
359 //\r
360 DebuggerPrivate->InstructionScope = SystemContext.SystemContextEbc->Ip;\r
361\r
362 //\r
363 // Done\r
364 //\r
365 return EFI_SUCCESS;\r
366}\r
367\r
e8a5ac7c
DB
368/**\r
369\r
370 De-initialize Debugger private data structure.\r
371\r
372 @param DebuggerPrivate EBC Debugger private data structure\r
373 @param ExceptionType Exception type.\r
374 @param SystemContext EBC system context.\r
375 @param Initialized Whether the DebuggerPrivate data is initialized.\r
376\r
377**/\r
748edcd5
PB
378EFI_STATUS\r
379DeinitDebuggerPrivateData (\r
1436aea4
MK
380 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
381 IN EFI_EXCEPTION_TYPE ExceptionType,\r
382 IN EFI_SYSTEM_CONTEXT SystemContext,\r
383 IN BOOLEAN Initialized\r
748edcd5 384 )\r
748edcd5
PB
385{\r
386 if (!Initialized) {\r
387 //\r
388 // If it does not want initialized state, de-init everything\r
389 //\r
1436aea4 390 DebuggerPrivate->FeatureFlags = EFI_DEBUG_FLAG_EBC_BOE | EFI_DEBUG_FLAG_EBC_BOT;\r
748edcd5 391 DebuggerPrivate->CallStackEntryCount = 0;\r
1436aea4
MK
392 DebuggerPrivate->TraceEntryCount = 0;\r
393 ZeroMem (DebuggerPrivate->CallStackEntry, sizeof (DebuggerPrivate->CallStackEntry));\r
394 ZeroMem (DebuggerPrivate->TraceEntry, sizeof (DebuggerPrivate->TraceEntry));\r
748edcd5
PB
395\r
396 //\r
397 // Clear all breakpoint\r
398 //\r
399 EdbClearAllBreakpoint (DebuggerPrivate, TRUE);\r
400\r
401 //\r
402 // Clear symbol\r
403 //\r
404 EdbClearSymbol (DebuggerPrivate);\r
405 } else {\r
406 //\r
407 // If it wants to keep initialized state, just set breakpoint.\r
408 //\r
409 EdbSetAllBreakpoint (DebuggerPrivate);\r
410 }\r
411\r
412 //\r
413 // Clear Step context\r
414 //\r
1436aea4 415 ZeroMem (&mDebuggerPrivate.StepContext, sizeof (mDebuggerPrivate.StepContext));\r
748edcd5
PB
416 DebuggerPrivate->StatusFlags = 0;\r
417\r
418 //\r
419 // Done\r
420 //\r
421 return EFI_SUCCESS;\r
422}\r
423\r
e8a5ac7c
DB
424/**\r
425\r
426 Print the reason of current break to EbcDebugger.\r
427\r
428 @param DebuggerPrivate EBC Debugger private data structure\r
429 @param ExceptionType Exception type.\r
430 @param SystemContext EBC system context.\r
431 @param Initialized Whether the DebuggerPrivate data is initialized.\r
432\r
433**/\r
748edcd5
PB
434VOID\r
435PrintExceptionReason (\r
1436aea4
MK
436 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
437 IN EFI_EXCEPTION_TYPE ExceptionType,\r
438 IN EFI_SYSTEM_CONTEXT SystemContext,\r
439 IN BOOLEAN Initialized\r
748edcd5 440 )\r
748edcd5
PB
441{\r
442 //\r
443 // Print break status\r
444 //\r
445 if ((DebuggerPrivate->StatusFlags & EFI_DEBUG_FLAG_EBC_GT) == EFI_DEBUG_FLAG_EBC_GT) {\r
446 EDBPrint (L"Break on GoTil\n");\r
447 } else if ((DebuggerPrivate->StatusFlags & EFI_DEBUG_FLAG_EBC_BOC) == EFI_DEBUG_FLAG_EBC_BOC) {\r
448 EDBPrint (L"Break on CALL\n");\r
449 } else if ((DebuggerPrivate->StatusFlags & EFI_DEBUG_FLAG_EBC_BOCX) == EFI_DEBUG_FLAG_EBC_BOCX) {\r
450 EDBPrint (L"Break on CALLEX\n");\r
451 } else if ((DebuggerPrivate->StatusFlags & EFI_DEBUG_FLAG_EBC_BOR) == EFI_DEBUG_FLAG_EBC_BOR) {\r
452 EDBPrint (L"Break on RET\n");\r
453 } else if ((DebuggerPrivate->StatusFlags & EFI_DEBUG_FLAG_EBC_BOE) == EFI_DEBUG_FLAG_EBC_BOE) {\r
454 EDBPrint (L"Break on Entrypoint\n");\r
455 } else if ((DebuggerPrivate->StatusFlags & EFI_DEBUG_FLAG_EBC_BOT) == EFI_DEBUG_FLAG_EBC_BOT) {\r
456 EDBPrint (L"Break on Thunk\n");\r
457 } else if ((DebuggerPrivate->StatusFlags & EFI_DEBUG_FLAG_EBC_STEPOVER) == EFI_DEBUG_FLAG_EBC_STEPOVER) {\r
458 EDBPrint (L"Break on StepOver\n");\r
459 } else if ((DebuggerPrivate->StatusFlags & EFI_DEBUG_FLAG_EBC_STEPOUT) == EFI_DEBUG_FLAG_EBC_STEPOUT) {\r
460 EDBPrint (L"Break on StepOut\n");\r
461 } else if ((DebuggerPrivate->StatusFlags & EFI_DEBUG_FLAG_EBC_BP) == EFI_DEBUG_FLAG_EBC_BP) {\r
462 EDBPrint (L"Break on Breakpoint\n");\r
463 } else if ((DebuggerPrivate->StatusFlags & EFI_DEBUG_FLAG_EBC_BOK) == EFI_DEBUG_FLAG_EBC_BOK) {\r
464 EDBPrint (L"Break on Key\n");\r
465 } else {\r
466 EDBPrint (L"Exception Type - %x", (UINTN)ExceptionType);\r
467 if ((ExceptionType >= EXCEPT_EBC_UNDEFINED) && (ExceptionType <= EXCEPT_EBC_STEP)) {\r
468 EDBPrint (L" (%s)\n", mExceptionStr[ExceptionType]);\r
469 } else {\r
470 EDBPrint (L"\n");\r
471 }\r
472 }\r
473\r
1436aea4 474 return;\r
748edcd5
PB
475}\r
476\r
e8a5ac7c 477/**\r
748edcd5
PB
478\r
479 The default Exception Callback for the VM interpreter.\r
480 In this function, we report status code, and print debug information\r
481 about EBC_CONTEXT, then dead loop.\r
482\r
e8a5ac7c
DB
483 @param ExceptionType Exception type.\r
484 @param SystemContext EBC system context.\r
748edcd5 485\r
e8a5ac7c
DB
486**/\r
487VOID\r
488EFIAPI\r
489EdbExceptionHandler (\r
1436aea4
MK
490 IN EFI_EXCEPTION_TYPE ExceptionType,\r
491 IN OUT EFI_SYSTEM_CONTEXT SystemContext\r
e8a5ac7c 492 )\r
748edcd5 493{\r
1436aea4
MK
494 CHAR16 InputBuffer[EFI_DEBUG_INPUS_BUFFER_SIZE];\r
495 CHAR16 *CommandArg;\r
496 EFI_DEBUGGER_COMMAND DebuggerCommand;\r
497 EFI_DEBUG_STATUS DebugStatus;\r
498 STATIC BOOLEAN mInitialized;\r
8fd543c7
DB
499\r
500 mInitialized = FALSE;\r
748edcd5
PB
501\r
502 DEBUG ((DEBUG_ERROR, "Hello EBC Debugger!\n"));\r
503\r
504 if (!mInitialized) {\r
505 //\r
506 // Print version\r
507 //\r
508 EDBPrint (\r
509 L"EBC Interpreter Version - %d.%d\n",\r
510 (UINTN)VM_MAJOR_VERSION,\r
511 (UINTN)VM_MINOR_VERSION\r
512 );\r
513 EDBPrint (\r
514 L"EBC Debugger Version - %d.%d\n",\r
515 (UINTN)EBC_DEBUGGER_MAJOR_VERSION,\r
516 (UINTN)EBC_DEBUGGER_MINOR_VERSION\r
517 );\r
518 }\r
1436aea4 519\r
748edcd5
PB
520 //\r
521 // Init Private Data\r
522 //\r
523 InitDebuggerPrivateData (&mDebuggerPrivate, ExceptionType, SystemContext, mInitialized);\r
524\r
525 //\r
526 // EDBPrint basic info\r
527 //\r
528 PrintExceptionReason (&mDebuggerPrivate, ExceptionType, SystemContext, mInitialized);\r
529\r
530 EdbShowDisasm (&mDebuggerPrivate, SystemContext);\r
531 // EFI_BREAKPOINT ();\r
532\r
533 if (!mInitialized) {\r
534 //\r
535 // Interactive with user\r
536 //\r
537 EDBPrint (L"\nPlease enter command now, \'h\' for help.\n");\r
538 EDBPrint (L"(Using <Command> -b <...> to enable page break.)\n");\r
539 }\r
1436aea4 540\r
748edcd5
PB
541 mInitialized = TRUE;\r
542\r
543 //\r
544 // Dispatch each command\r
545 //\r
546 while (TRUE) {\r
547 //\r
548 // Get user input\r
549 //\r
550 Input (L"\n\r" EFI_DEBUG_PROMPT_STRING, InputBuffer, EFI_DEBUG_INPUS_BUFFER_SIZE);\r
551 EDBPrint (L"\n");\r
552\r
553 //\r
554 // Get command\r
555 //\r
556 DebuggerCommand = MatchDebuggerCommand (InputBuffer, &CommandArg);\r
557 if (DebuggerCommand == NULL) {\r
558 EDBPrint (L"ERROR: Command not found!\n");\r
559 continue;\r
560 }\r
561\r
562 //\r
563 // Check PageBreak;\r
564 //\r
565 if (CommandArg != NULL) {\r
566 if (StriCmp (CommandArg, L"-b") == 0) {\r
1436aea4 567 CommandArg = StrGetNextTokenLine (L" ");\r
748edcd5
PB
568 mDebuggerPrivate.EnablePageBreak = TRUE;\r
569 }\r
570 }\r
571\r
572 //\r
573 // Dispatch command\r
574 //\r
1436aea4 575 DebugStatus = DebuggerCommand (CommandArg, &mDebuggerPrivate, ExceptionType, SystemContext);\r
748edcd5
PB
576 mDebuggerPrivate.EnablePageBreak = FALSE;\r
577\r
578 //\r
579 // Check command return status\r
580 //\r
581 if (DebugStatus == EFI_DEBUG_RETURN) {\r
582 mInitialized = FALSE;\r
583 break;\r
584 } else if (DebugStatus == EFI_DEBUG_BREAK) {\r
585 break;\r
586 } else if (DebugStatus == EFI_DEBUG_CONTINUE) {\r
587 continue;\r
588 } else {\r
589 ASSERT (FALSE);\r
590 }\r
591 }\r
592\r
593 //\r
594 // Deinit Private Data\r
595 //\r
596 DeinitDebuggerPrivateData (&mDebuggerPrivate, ExceptionType, SystemContext, mInitialized);\r
597\r
598 DEBUG ((DEBUG_ERROR, "Goodbye EBC Debugger!\n"));\r
599\r
600 return;\r
601}\r