]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbCmdBreakpoint.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Universal / EbcDxe / EbcDebugger / EdbCmdBreakpoint.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
748edcd5 6\r
e8a5ac7c 7**/\r
748edcd5 8\r
e8a5ac7c 9#include "Edb.h"\r
748edcd5 10\r
e8a5ac7c 11/**\r
748edcd5 12\r
e8a5ac7c 13 Check whether current IP is EBC BREAK3 instruction.\r
748edcd5 14\r
e8a5ac7c 15 @param Address EBC IP address.\r
748edcd5 16\r
e8a5ac7c
DB
17 @retval TRUE Current IP is EBC BREAK3 instruction\r
18 @retval FALSE Current IP is not EBC BREAK3 instruction\r
19\r
20**/\r
748edcd5
PB
21BOOLEAN\r
22IsEBCBREAK3 (\r
1436aea4 23 IN UINTN Address\r
748edcd5 24 )\r
748edcd5 25{\r
1436aea4 26 if (GET_OPCODE (Address) != OPCODE_BREAK) {\r
748edcd5
PB
27 return FALSE;\r
28 }\r
29\r
30 if (GET_OPERANDS (Address) != 3) {\r
31 return FALSE;\r
32 } else {\r
33 return TRUE;\r
34 }\r
35}\r
36\r
e8a5ac7c
DB
37/**\r
38\r
39 Check whether the Address is already set in breakpoint.\r
40\r
41 @param DebuggerPrivate EBC Debugger private data structure\r
42 @param Address Breakpoint Address\r
43\r
44 @retval TRUE breakpoint is found\r
45 @retval FALSE breakpoint is not found\r
46\r
47**/\r
748edcd5
PB
48BOOLEAN\r
49DebuggerBreakpointIsDuplicated (\r
1436aea4
MK
50 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
51 IN UINTN Address\r
748edcd5 52 )\r
748edcd5
PB
53{\r
54 UINTN Index;\r
55\r
56 //\r
57 // Go through each breakpoint context\r
58 //\r
59 for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) {\r
60 if (DebuggerPrivate->DebuggerBreakpointContext[Index].BreakpointAddress == Address) {\r
61 //\r
62 // Found it\r
63 //\r
64 return TRUE;\r
65 }\r
66 }\r
67\r
68 //\r
69 // Not found\r
70 //\r
71 return FALSE;\r
72}\r
73\r
e8a5ac7c
DB
74/**\r
75\r
76 Add this breakpoint.\r
77\r
78 @param DebuggerPrivate EBC Debugger private data structure\r
79 @param Address Breakpoint Address\r
80\r
81 @retval EFI_SUCCESS breakpoint added successfully\r
82 @retval EFI_ALREADY_STARTED breakpoint is already added\r
83 @retval EFI_OUT_OF_RESOURCES all the breakpoint entries are used\r
84\r
85**/\r
748edcd5
PB
86EFI_STATUS\r
87DebuggerBreakpointAdd (\r
1436aea4
MK
88 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
89 IN UINTN Address\r
748edcd5 90 )\r
748edcd5
PB
91{\r
92 //\r
93 // Check duplicated breakpoint\r
94 //\r
95 if (DebuggerBreakpointIsDuplicated (DebuggerPrivate, Address)) {\r
96 EDBPrint (L"Breakpoint duplicated!\n");\r
97 return EFI_ALREADY_STARTED;\r
98 }\r
99\r
100 //\r
101 // Check whether the address is a breakpoint 3 instruction\r
102 //\r
103 if (IsEBCBREAK3 (Address)) {\r
104 EDBPrint (L"Breakpoint can not be set on BREAK 3 instruction!\n");\r
105 return EFI_ALREADY_STARTED;\r
106 }\r
107\r
108 if (DebuggerPrivate->DebuggerBreakpointCount >= EFI_DEBUGGER_BREAKPOINT_MAX) {\r
109 EDBPrint (L"Breakpoint out of resource!\n");\r
110 return EFI_OUT_OF_RESOURCES;\r
111 }\r
112\r
113 //\r
114 // Set the breakpoint\r
115 //\r
116 DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].BreakpointAddress = Address;\r
1436aea4
MK
117 DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].State = TRUE;\r
118 DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].OldInstruction = 0;\r
748edcd5
PB
119 CopyMem (\r
120 &DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].OldInstruction,\r
121 (VOID *)Address,\r
1436aea4 122 sizeof (UINT16)\r
748edcd5
PB
123 );\r
124\r
1436aea4 125 DebuggerPrivate->DebuggerBreakpointCount++;\r
748edcd5
PB
126\r
127 //\r
128 // Done\r
129 //\r
130 return EFI_SUCCESS;\r
131}\r
132\r
e8a5ac7c
DB
133/**\r
134\r
135 Delete this breakpoint.\r
136\r
137 @param DebuggerPrivate EBC Debugger private data structure\r
138 @param Index Breakpoint Index\r
139\r
140 @retval EFI_SUCCESS breakpoint deleted successfully\r
141 @retval EFI_NOT_FOUND breakpoint not found\r
142\r
143**/\r
748edcd5
PB
144EFI_STATUS\r
145DebuggerBreakpointDel (\r
1436aea4
MK
146 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
147 IN UINTN Index\r
748edcd5 148 )\r
748edcd5 149{\r
1436aea4 150 UINTN BpIndex;\r
748edcd5
PB
151\r
152 if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) ||\r
1436aea4
MK
153 (Index >= DebuggerPrivate->DebuggerBreakpointCount))\r
154 {\r
748edcd5
PB
155 return EFI_NOT_FOUND;\r
156 }\r
157\r
158 //\r
159 // Delete this breakpoint\r
160 //\r
161 for (BpIndex = Index; BpIndex < DebuggerPrivate->DebuggerBreakpointCount - 1; BpIndex++) {\r
b04453d3
M
162 CopyMem (\r
163 &DebuggerPrivate->DebuggerBreakpointContext[BpIndex],\r
164 &DebuggerPrivate->DebuggerBreakpointContext[BpIndex + 1],\r
165 sizeof (DebuggerPrivate->DebuggerBreakpointContext[BpIndex])\r
166 );\r
748edcd5 167 }\r
1436aea4 168\r
748edcd5
PB
169 ZeroMem (\r
170 &DebuggerPrivate->DebuggerBreakpointContext[BpIndex],\r
1436aea4 171 sizeof (DebuggerPrivate->DebuggerBreakpointContext[BpIndex])\r
748edcd5
PB
172 );\r
173\r
1436aea4 174 DebuggerPrivate->DebuggerBreakpointCount--;\r
748edcd5
PB
175\r
176 //\r
177 // Done\r
178 //\r
179 return EFI_SUCCESS;\r
180}\r
181\r
e8a5ac7c
DB
182/**\r
183\r
184 Disable this breakpoint.\r
185\r
186 @param DebuggerPrivate EBC Debugger private data structure\r
187 @param Index Breakpoint Index\r
188\r
189 @retval EFI_SUCCESS breakpoint disabled successfully\r
190 @retval EFI_NOT_FOUND breakpoint not found\r
191\r
192**/\r
748edcd5
PB
193EFI_STATUS\r
194DebuggerBreakpointDis (\r
1436aea4
MK
195 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
196 IN UINTN Index\r
748edcd5 197 )\r
748edcd5
PB
198{\r
199 if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) ||\r
1436aea4
MK
200 (Index >= DebuggerPrivate->DebuggerBreakpointCount))\r
201 {\r
748edcd5
PB
202 return EFI_NOT_FOUND;\r
203 }\r
204\r
205 //\r
206 // Disable this breakpoint\r
207 //\r
208 DebuggerPrivate->DebuggerBreakpointContext[Index].State = FALSE;\r
209\r
210 return EFI_SUCCESS;\r
211}\r
212\r
e8a5ac7c
DB
213/**\r
214\r
215 Enable this breakpoint.\r
216\r
217 @param DebuggerPrivate - EBC Debugger private data structure\r
218 @param Index - Breakpoint Index\r
219\r
220 @retval EFI_SUCCESS - breakpoint enabled successfully\r
221 @retval EFI_NOT_FOUND - breakpoint not found\r
222\r
223**/\r
748edcd5
PB
224EFI_STATUS\r
225DebuggerBreakpointEn (\r
1436aea4
MK
226 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
227 IN UINTN Index\r
748edcd5 228 )\r
748edcd5
PB
229{\r
230 if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) ||\r
1436aea4
MK
231 (Index >= DebuggerPrivate->DebuggerBreakpointCount))\r
232 {\r
748edcd5
PB
233 return EFI_NOT_FOUND;\r
234 }\r
235\r
236 //\r
237 // Enable this breakpoint\r
238 //\r
239 DebuggerPrivate->DebuggerBreakpointContext[Index].State = TRUE;\r
240\r
241 return EFI_SUCCESS;\r
242}\r
243\r
e8a5ac7c
DB
244/**\r
245\r
246 DebuggerCommand - BreakpointList.\r
247\r
248 @param CommandArg - The argument for this command\r
249 @param DebuggerPrivate - EBC Debugger private data structure\r
250 @param ExceptionType - Exception type.\r
251 @param SystemContext - EBC system context.\r
252\r
253 @retval EFI_DEBUG_CONTINUE - formal return value\r
254\r
255**/\r
748edcd5
PB
256EFI_DEBUG_STATUS\r
257DebuggerBreakpointList (\r
1436aea4
MK
258 IN CHAR16 *CommandArg,\r
259 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
260 IN EFI_EXCEPTION_TYPE ExceptionType,\r
261 IN OUT EFI_SYSTEM_CONTEXT SystemContext\r
748edcd5 262 )\r
748edcd5 263{\r
1436aea4 264 UINTN Index;\r
748edcd5
PB
265\r
266 //\r
267 // Check breakpoint cound\r
268 //\r
269 if (DebuggerPrivate->DebuggerBreakpointCount == 0) {\r
270 EDBPrint (L"No Breakpoint\n");\r
271 return EFI_DEBUG_CONTINUE;\r
272 } else if (DebuggerPrivate->DebuggerBreakpointCount > EFI_DEBUGGER_BREAKPOINT_MAX) {\r
273 EDBPrint (L"Breakpoint too many!\n");\r
274 DebuggerPrivate->DebuggerBreakpointCount = 0;\r
275 return EFI_DEBUG_CONTINUE;\r
276 }\r
277\r
278 //\r
279 // Go through each breakpoint\r
280 //\r
281 EDBPrint (L"Breakpoint :\n");\r
282 EDBPrint (L" Index Address Status\n");\r
283 EDBPrint (L"======= ================== ========\n");\r
1436aea4
MK
284 // EDBPrint (L" 1 0xFFFFFFFF00000000 *\n");\r
285 // EDBPrint (L" 12 0x00000000FFFFFFFF\n");\r
748edcd5
PB
286 for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) {\r
287 //\r
288 // Print the breakpoint\r
289 //\r
290 EDBPrint (L" %2d 0x%016lx", Index, DebuggerPrivate->DebuggerBreakpointContext[Index].BreakpointAddress);\r
291 if (DebuggerPrivate->DebuggerBreakpointContext[Index].State) {\r
292 EDBPrint (L" *\n");\r
293 } else {\r
294 EDBPrint (L"\n");\r
295 }\r
296 }\r
297\r
298 //\r
299 // Done\r
300 //\r
301 return EFI_DEBUG_CONTINUE;\r
302}\r
303\r
e8a5ac7c
DB
304/**\r
305\r
306 DebuggerCommand - BreakpointSet.\r
307\r
308 @param CommandArg The argument for this command\r
309 @param DebuggerPrivate EBC Debugger private data structure\r
310 @param ExceptionType Exception type.\r
311 @param SystemContext EBC system context.\r
312\r
313 @retval EFI_DEBUG_CONTINUE - formal return value\r
314\r
315**/\r
748edcd5
PB
316EFI_DEBUG_STATUS\r
317DebuggerBreakpointSet (\r
1436aea4
MK
318 IN CHAR16 *CommandArg,\r
319 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
320 IN EFI_EXCEPTION_TYPE ExceptionType,\r
321 IN OUT EFI_SYSTEM_CONTEXT SystemContext\r
748edcd5 322 )\r
748edcd5 323{\r
1436aea4
MK
324 UINTN Address;\r
325 EFI_STATUS Status;\r
748edcd5
PB
326\r
327 if (CommandArg == NULL) {\r
328 EDBPrint (L"BreakpointSet Argument error!\n");\r
329 return EFI_DEBUG_CONTINUE;\r
330 }\r
331\r
332 //\r
333 // Get breakpoint address\r
334 //\r
335 Status = Symboltoi (CommandArg, &Address);\r
336 if (EFI_ERROR (Status)) {\r
337 if (Status == EFI_NOT_FOUND) {\r
1436aea4 338 Address = Xtoi (CommandArg);\r
748edcd5
PB
339 } else {\r
340 //\r
341 // Something wrong, let Symboltoi print error info.\r
342 //\r
343 EDBPrint (L"Command Argument error!\n");\r
344 return EFI_DEBUG_CONTINUE;\r
345 }\r
346 }\r
347\r
348 //\r
349 // Add breakpoint\r
350 //\r
351 Status = DebuggerBreakpointAdd (DebuggerPrivate, Address);\r
1436aea4 352 if (EFI_ERROR (Status)) {\r
748edcd5
PB
353 EDBPrint (L"BreakpointSet error!\n");\r
354 }\r
355\r
356 //\r
357 // Done\r
358 //\r
359 return EFI_DEBUG_CONTINUE;\r
360}\r
361\r
e8a5ac7c
DB
362/**\r
363\r
364 DebuggerCommand - BreakpointClear\r
365\r
366 @param CommandArg The argument for this command\r
367 @param DebuggerPrivate EBC Debugger private data structure\r
368 @param ExceptionType Exception type.\r
369 @param SystemContext EBC system context.\r
370\r
371 @retval EFI_DEBUG_CONTINUE formal return value\r
372\r
373**/\r
748edcd5
PB
374EFI_DEBUG_STATUS\r
375DebuggerBreakpointClear (\r
1436aea4
MK
376 IN CHAR16 *CommandArg,\r
377 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
378 IN EFI_EXCEPTION_TYPE ExceptionType,\r
379 IN OUT EFI_SYSTEM_CONTEXT SystemContext\r
748edcd5 380 )\r
748edcd5 381{\r
1436aea4
MK
382 UINTN Index;\r
383 EFI_STATUS Status;\r
748edcd5
PB
384\r
385 if (CommandArg == NULL) {\r
386 EDBPrint (L"BreakpointClear Argument error!\n");\r
387 return EFI_DEBUG_CONTINUE;\r
388 }\r
389\r
390 if (StriCmp (CommandArg, L"*") == 0) {\r
391 //\r
392 // delete all breakpoint\r
393 //\r
394 DebuggerPrivate->DebuggerBreakpointCount = 0;\r
1436aea4 395 ZeroMem (DebuggerPrivate->DebuggerBreakpointContext, sizeof (DebuggerPrivate->DebuggerBreakpointContext));\r
748edcd5
PB
396 EDBPrint (L"All the Breakpoint is cleared\n");\r
397 return EFI_DEBUG_CONTINUE;\r
398 }\r
399\r
400 //\r
401 // Get breakpoint index\r
402 //\r
1436aea4
MK
403 Index = Atoi (CommandArg);\r
404 if (Index == (UINTN)-1) {\r
12f49354
HW
405 EDBPrint (L"BreakpointClear Argument error!\n");\r
406 return EFI_DEBUG_CONTINUE;\r
407 }\r
748edcd5
PB
408\r
409 if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) ||\r
1436aea4
MK
410 (Index >= DebuggerPrivate->DebuggerBreakpointCount))\r
411 {\r
748edcd5
PB
412 EDBPrint (L"BreakpointClear error!\n");\r
413 return EFI_DEBUG_CONTINUE;\r
748edcd5
PB
414 }\r
415\r
416 //\r
417 // Delete breakpoint\r
418 //\r
419 Status = DebuggerBreakpointDel (DebuggerPrivate, Index);\r
1436aea4 420 if (EFI_ERROR (Status)) {\r
748edcd5
PB
421 EDBPrint (L"BreakpointClear error!\n");\r
422 }\r
423\r
424 //\r
425 // Done\r
426 //\r
427 return EFI_DEBUG_CONTINUE;\r
428}\r
429\r
e8a5ac7c
DB
430/**\r
431\r
432 DebuggerCommand - BreakpointDisable\r
433\r
434 @param CommandArg The argument for this command\r
435 @param DebuggerPrivate EBC Debugger private data structure\r
436 @param ExceptionType Exception type.\r
437 @param SystemContext EBC system context.\r
438\r
439 @retval EFI_DEBUG_CONTINUE formal return value\r
440\r
441**/\r
748edcd5
PB
442EFI_DEBUG_STATUS\r
443DebuggerBreakpointDisable (\r
1436aea4
MK
444 IN CHAR16 *CommandArg,\r
445 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
446 IN EFI_EXCEPTION_TYPE ExceptionType,\r
447 IN OUT EFI_SYSTEM_CONTEXT SystemContext\r
748edcd5 448 )\r
748edcd5 449{\r
1436aea4
MK
450 UINTN Index;\r
451 EFI_STATUS Status;\r
748edcd5
PB
452\r
453 if (CommandArg == NULL) {\r
454 EDBPrint (L"BreakpointDisable Argument error!\n");\r
455 return EFI_DEBUG_CONTINUE;\r
456 }\r
457\r
458 if (StriCmp (CommandArg, L"*") == 0) {\r
459 //\r
460 // disable all breakpoint\r
461 //\r
462 for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) {\r
463 Status = DebuggerBreakpointDis (DebuggerPrivate, Index);\r
464 }\r
1436aea4 465\r
748edcd5
PB
466 EDBPrint (L"All the Breakpoint is disabled\n");\r
467 return EFI_DEBUG_CONTINUE;\r
468 }\r
469\r
470 //\r
471 // Get breakpoint index\r
472 //\r
1436aea4
MK
473 Index = Atoi (CommandArg);\r
474 if (Index == (UINTN)-1) {\r
12f49354
HW
475 EDBPrint (L"BreakpointDisable Argument error!\n");\r
476 return EFI_DEBUG_CONTINUE;\r
477 }\r
748edcd5
PB
478\r
479 //\r
480 // Disable breakpoint\r
481 //\r
482 Status = DebuggerBreakpointDis (DebuggerPrivate, Index);\r
1436aea4 483 if (EFI_ERROR (Status)) {\r
748edcd5
PB
484 EDBPrint (L"BreakpointDisable error!\n");\r
485 }\r
486\r
487 //\r
488 // Done\r
489 //\r
490 return EFI_DEBUG_CONTINUE;\r
491}\r
492\r
e8a5ac7c
DB
493/**\r
494 DebuggerCommand - BreakpointEnable.\r
495\r
496 @param CommandArg The argument for this command\r
497 @param DebuggerPrivate EBC Debugger private data structure\r
498 @param ExceptionType Exception type.\r
499 @param SystemContext EBC system context.\r
500\r
501 @retval EFI_DEBUG_CONTINUE formal return value\r
502\r
503**/\r
748edcd5
PB
504EFI_DEBUG_STATUS\r
505DebuggerBreakpointEnable (\r
1436aea4
MK
506 IN CHAR16 *CommandArg,\r
507 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
508 IN EFI_EXCEPTION_TYPE ExceptionType,\r
509 IN OUT EFI_SYSTEM_CONTEXT SystemContext\r
748edcd5 510 )\r
748edcd5 511{\r
1436aea4
MK
512 UINTN Index;\r
513 EFI_STATUS Status;\r
748edcd5
PB
514\r
515 if (CommandArg == NULL) {\r
516 EDBPrint (L"BreakpointEnable Argument error!\n");\r
517 return EFI_DEBUG_CONTINUE;\r
518 }\r
519\r
520 if (StriCmp (CommandArg, L"*") == 0) {\r
521 //\r
522 // enable all breakpoint\r
523 //\r
524 for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) {\r
525 Status = DebuggerBreakpointEn (DebuggerPrivate, Index);\r
526 }\r
1436aea4 527\r
748edcd5
PB
528 EDBPrint (L"All the Breakpoint is enabled\n");\r
529 return EFI_DEBUG_CONTINUE;\r
530 }\r
531\r
532 //\r
533 // Get breakpoint index\r
534 //\r
1436aea4
MK
535 Index = Atoi (CommandArg);\r
536 if (Index == (UINTN)-1) {\r
12f49354
HW
537 EDBPrint (L"BreakpointEnable Argument error!\n");\r
538 return EFI_DEBUG_CONTINUE;\r
539 }\r
748edcd5
PB
540\r
541 //\r
542 // Enable breakpoint\r
543 //\r
544 Status = DebuggerBreakpointEn (DebuggerPrivate, Index);\r
1436aea4 545 if (EFI_ERROR (Status)) {\r
748edcd5
PB
546 EDBPrint (L"BreakpointEnable error!\n");\r
547 }\r
548\r
549 //\r
550 // Done\r
551 //\r
552 return EFI_DEBUG_CONTINUE;\r
553}\r