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