]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Universal/EbcDxe/EbcDebugger/EdbCmdBreakpoint.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / EbcDxe / EbcDebugger / EdbCmdBreakpoint.c
... / ...
CommitLineData
1/** @file\r
2\r
3Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
4SPDX-License-Identifier: BSD-2-Clause-Patent\r
5\r
6\r
7**/\r
8\r
9#include "Edb.h"\r
10\r
11/**\r
12\r
13 Check whether current IP is EBC BREAK3 instruction.\r
14\r
15 @param Address EBC IP address.\r
16\r
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
21BOOLEAN\r
22IsEBCBREAK3 (\r
23 IN UINTN Address\r
24 )\r
25{\r
26 if (GET_OPCODE(Address) != OPCODE_BREAK) {\r
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
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
48BOOLEAN\r
49DebuggerBreakpointIsDuplicated (\r
50 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
51 IN UINTN Address\r
52 )\r
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
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
86EFI_STATUS\r
87DebuggerBreakpointAdd (\r
88 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
89 IN UINTN Address\r
90 )\r
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
117 DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].State = TRUE;\r
118 DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].OldInstruction = 0;\r
119 CopyMem (\r
120 &DebuggerPrivate->DebuggerBreakpointContext[DebuggerPrivate->DebuggerBreakpointCount].OldInstruction,\r
121 (VOID *)Address,\r
122 sizeof(UINT16)\r
123 );\r
124\r
125 DebuggerPrivate->DebuggerBreakpointCount ++;\r
126\r
127 //\r
128 // Done\r
129 //\r
130 return EFI_SUCCESS;\r
131}\r
132\r
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
144EFI_STATUS\r
145DebuggerBreakpointDel (\r
146 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
147 IN UINTN Index\r
148 )\r
149{\r
150 UINTN BpIndex;\r
151\r
152 if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) ||\r
153 (Index >= DebuggerPrivate->DebuggerBreakpointCount)) {\r
154 return EFI_NOT_FOUND;\r
155 }\r
156\r
157 //\r
158 // Delete this breakpoint\r
159 //\r
160 for (BpIndex = Index; BpIndex < DebuggerPrivate->DebuggerBreakpointCount - 1; BpIndex++) {\r
161 DebuggerPrivate->DebuggerBreakpointContext[BpIndex] = DebuggerPrivate->DebuggerBreakpointContext[BpIndex + 1];\r
162 }\r
163 ZeroMem (\r
164 &DebuggerPrivate->DebuggerBreakpointContext[BpIndex],\r
165 sizeof(DebuggerPrivate->DebuggerBreakpointContext[BpIndex])\r
166 );\r
167\r
168 DebuggerPrivate->DebuggerBreakpointCount --;\r
169\r
170 //\r
171 // Done\r
172 //\r
173 return EFI_SUCCESS;\r
174}\r
175\r
176/**\r
177\r
178 Disable this breakpoint.\r
179\r
180 @param DebuggerPrivate EBC Debugger private data structure\r
181 @param Index Breakpoint Index\r
182\r
183 @retval EFI_SUCCESS breakpoint disabled successfully\r
184 @retval EFI_NOT_FOUND breakpoint not found\r
185\r
186**/\r
187EFI_STATUS\r
188DebuggerBreakpointDis (\r
189 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
190 IN UINTN Index\r
191 )\r
192{\r
193 if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) ||\r
194 (Index >= DebuggerPrivate->DebuggerBreakpointCount)) {\r
195 return EFI_NOT_FOUND;\r
196 }\r
197\r
198 //\r
199 // Disable this breakpoint\r
200 //\r
201 DebuggerPrivate->DebuggerBreakpointContext[Index].State = FALSE;\r
202\r
203 return EFI_SUCCESS;\r
204}\r
205\r
206/**\r
207\r
208 Enable this breakpoint.\r
209\r
210 @param DebuggerPrivate - EBC Debugger private data structure\r
211 @param Index - Breakpoint Index\r
212\r
213 @retval EFI_SUCCESS - breakpoint enabled successfully\r
214 @retval EFI_NOT_FOUND - breakpoint not found\r
215\r
216**/\r
217EFI_STATUS\r
218DebuggerBreakpointEn (\r
219 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
220 IN UINTN Index\r
221 )\r
222{\r
223 if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) ||\r
224 (Index >= DebuggerPrivate->DebuggerBreakpointCount)) {\r
225 return EFI_NOT_FOUND;\r
226 }\r
227\r
228 //\r
229 // Enable this breakpoint\r
230 //\r
231 DebuggerPrivate->DebuggerBreakpointContext[Index].State = TRUE;\r
232\r
233 return EFI_SUCCESS;\r
234}\r
235\r
236/**\r
237\r
238 DebuggerCommand - BreakpointList.\r
239\r
240 @param CommandArg - The argument for this command\r
241 @param DebuggerPrivate - EBC Debugger private data structure\r
242 @param ExceptionType - Exception type.\r
243 @param SystemContext - EBC system context.\r
244\r
245 @retval EFI_DEBUG_CONTINUE - formal return value\r
246\r
247**/\r
248EFI_DEBUG_STATUS\r
249DebuggerBreakpointList (\r
250 IN CHAR16 *CommandArg,\r
251 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
252 IN EFI_EXCEPTION_TYPE ExceptionType,\r
253 IN OUT EFI_SYSTEM_CONTEXT SystemContext\r
254 )\r
255{\r
256 UINTN Index;\r
257\r
258 //\r
259 // Check breakpoint cound\r
260 //\r
261 if (DebuggerPrivate->DebuggerBreakpointCount == 0) {\r
262 EDBPrint (L"No Breakpoint\n");\r
263 return EFI_DEBUG_CONTINUE;\r
264 } else if (DebuggerPrivate->DebuggerBreakpointCount > EFI_DEBUGGER_BREAKPOINT_MAX) {\r
265 EDBPrint (L"Breakpoint too many!\n");\r
266 DebuggerPrivate->DebuggerBreakpointCount = 0;\r
267 return EFI_DEBUG_CONTINUE;\r
268 }\r
269\r
270 //\r
271 // Go through each breakpoint\r
272 //\r
273 EDBPrint (L"Breakpoint :\n");\r
274 EDBPrint (L" Index Address Status\n");\r
275 EDBPrint (L"======= ================== ========\n");\r
276//EDBPrint (L" 1 0xFFFFFFFF00000000 *\n");\r
277//EDBPrint (L" 12 0x00000000FFFFFFFF\n");\r
278 for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) {\r
279 //\r
280 // Print the breakpoint\r
281 //\r
282 EDBPrint (L" %2d 0x%016lx", Index, DebuggerPrivate->DebuggerBreakpointContext[Index].BreakpointAddress);\r
283 if (DebuggerPrivate->DebuggerBreakpointContext[Index].State) {\r
284 EDBPrint (L" *\n");\r
285 } else {\r
286 EDBPrint (L"\n");\r
287 }\r
288 }\r
289\r
290 //\r
291 // Done\r
292 //\r
293 return EFI_DEBUG_CONTINUE;\r
294}\r
295\r
296/**\r
297\r
298 DebuggerCommand - BreakpointSet.\r
299\r
300 @param CommandArg The argument for this command\r
301 @param DebuggerPrivate EBC Debugger private data structure\r
302 @param ExceptionType Exception type.\r
303 @param SystemContext EBC system context.\r
304\r
305 @retval EFI_DEBUG_CONTINUE - formal return value\r
306\r
307**/\r
308EFI_DEBUG_STATUS\r
309DebuggerBreakpointSet (\r
310 IN CHAR16 *CommandArg,\r
311 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
312 IN EFI_EXCEPTION_TYPE ExceptionType,\r
313 IN OUT EFI_SYSTEM_CONTEXT SystemContext\r
314 )\r
315{\r
316 UINTN Address;\r
317 EFI_STATUS Status;\r
318\r
319 if (CommandArg == NULL) {\r
320 EDBPrint (L"BreakpointSet Argument error!\n");\r
321 return EFI_DEBUG_CONTINUE;\r
322 }\r
323\r
324 //\r
325 // Get breakpoint address\r
326 //\r
327 Status = Symboltoi (CommandArg, &Address);\r
328 if (EFI_ERROR (Status)) {\r
329 if (Status == EFI_NOT_FOUND) {\r
330 Address = Xtoi(CommandArg);\r
331 } else {\r
332 //\r
333 // Something wrong, let Symboltoi print error info.\r
334 //\r
335 EDBPrint (L"Command Argument error!\n");\r
336 return EFI_DEBUG_CONTINUE;\r
337 }\r
338 }\r
339\r
340 //\r
341 // Add breakpoint\r
342 //\r
343 Status = DebuggerBreakpointAdd (DebuggerPrivate, Address);\r
344 if (EFI_ERROR(Status)) {\r
345 EDBPrint (L"BreakpointSet error!\n");\r
346 }\r
347\r
348 //\r
349 // Done\r
350 //\r
351 return EFI_DEBUG_CONTINUE;\r
352}\r
353\r
354/**\r
355\r
356 DebuggerCommand - BreakpointClear\r
357\r
358 @param CommandArg The argument for this command\r
359 @param DebuggerPrivate EBC Debugger private data structure\r
360 @param ExceptionType Exception type.\r
361 @param SystemContext EBC system context.\r
362\r
363 @retval EFI_DEBUG_CONTINUE formal return value\r
364\r
365**/\r
366EFI_DEBUG_STATUS\r
367DebuggerBreakpointClear (\r
368 IN CHAR16 *CommandArg,\r
369 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
370 IN EFI_EXCEPTION_TYPE ExceptionType,\r
371 IN OUT EFI_SYSTEM_CONTEXT SystemContext\r
372 )\r
373{\r
374 UINTN Index;\r
375 EFI_STATUS Status;\r
376\r
377 if (CommandArg == NULL) {\r
378 EDBPrint (L"BreakpointClear Argument error!\n");\r
379 return EFI_DEBUG_CONTINUE;\r
380 }\r
381\r
382 if (StriCmp (CommandArg, L"*") == 0) {\r
383 //\r
384 // delete all breakpoint\r
385 //\r
386 DebuggerPrivate->DebuggerBreakpointCount = 0;\r
387 ZeroMem (DebuggerPrivate->DebuggerBreakpointContext, sizeof(DebuggerPrivate->DebuggerBreakpointContext));\r
388 EDBPrint (L"All the Breakpoint is cleared\n");\r
389 return EFI_DEBUG_CONTINUE;\r
390 }\r
391\r
392 //\r
393 // Get breakpoint index\r
394 //\r
395 Index = Atoi(CommandArg);\r
396 if (Index == (UINTN) -1) {\r
397 EDBPrint (L"BreakpointClear Argument error!\n");\r
398 return EFI_DEBUG_CONTINUE;\r
399 }\r
400\r
401 if ((Index >= EFI_DEBUGGER_BREAKPOINT_MAX) ||\r
402 (Index >= DebuggerPrivate->DebuggerBreakpointCount)) {\r
403 EDBPrint (L"BreakpointClear error!\n");\r
404 return EFI_DEBUG_CONTINUE;\r
405 }\r
406\r
407 //\r
408 // Delete breakpoint\r
409 //\r
410 Status = DebuggerBreakpointDel (DebuggerPrivate, Index);\r
411 if (EFI_ERROR(Status)) {\r
412 EDBPrint (L"BreakpointClear error!\n");\r
413 }\r
414\r
415 //\r
416 // Done\r
417 //\r
418 return EFI_DEBUG_CONTINUE;\r
419}\r
420\r
421/**\r
422\r
423 DebuggerCommand - BreakpointDisable\r
424\r
425 @param CommandArg The argument for this command\r
426 @param DebuggerPrivate EBC Debugger private data structure\r
427 @param ExceptionType Exception type.\r
428 @param SystemContext EBC system context.\r
429\r
430 @retval EFI_DEBUG_CONTINUE formal return value\r
431\r
432**/\r
433EFI_DEBUG_STATUS\r
434DebuggerBreakpointDisable (\r
435 IN CHAR16 *CommandArg,\r
436 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
437 IN EFI_EXCEPTION_TYPE ExceptionType,\r
438 IN OUT EFI_SYSTEM_CONTEXT SystemContext\r
439 )\r
440{\r
441 UINTN Index;\r
442 EFI_STATUS Status;\r
443\r
444 if (CommandArg == NULL) {\r
445 EDBPrint (L"BreakpointDisable Argument error!\n");\r
446 return EFI_DEBUG_CONTINUE;\r
447 }\r
448\r
449 if (StriCmp (CommandArg, L"*") == 0) {\r
450 //\r
451 // disable all breakpoint\r
452 //\r
453 for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) {\r
454 Status = DebuggerBreakpointDis (DebuggerPrivate, Index);\r
455 }\r
456 EDBPrint (L"All the Breakpoint is disabled\n");\r
457 return EFI_DEBUG_CONTINUE;\r
458 }\r
459\r
460 //\r
461 // Get breakpoint index\r
462 //\r
463 Index = Atoi(CommandArg);\r
464 if (Index == (UINTN) -1) {\r
465 EDBPrint (L"BreakpointDisable Argument error!\n");\r
466 return EFI_DEBUG_CONTINUE;\r
467 }\r
468\r
469 //\r
470 // Disable breakpoint\r
471 //\r
472 Status = DebuggerBreakpointDis (DebuggerPrivate, Index);\r
473 if (EFI_ERROR(Status)) {\r
474 EDBPrint (L"BreakpointDisable error!\n");\r
475 }\r
476\r
477 //\r
478 // Done\r
479 //\r
480 return EFI_DEBUG_CONTINUE;\r
481}\r
482\r
483/**\r
484 DebuggerCommand - BreakpointEnable.\r
485\r
486 @param CommandArg The argument for this command\r
487 @param DebuggerPrivate EBC Debugger private data structure\r
488 @param ExceptionType Exception type.\r
489 @param SystemContext EBC system context.\r
490\r
491 @retval EFI_DEBUG_CONTINUE formal return value\r
492\r
493**/\r
494EFI_DEBUG_STATUS\r
495DebuggerBreakpointEnable (\r
496 IN CHAR16 *CommandArg,\r
497 IN EFI_DEBUGGER_PRIVATE_DATA *DebuggerPrivate,\r
498 IN EFI_EXCEPTION_TYPE ExceptionType,\r
499 IN OUT EFI_SYSTEM_CONTEXT SystemContext\r
500 )\r
501{\r
502 UINTN Index;\r
503 EFI_STATUS Status;\r
504\r
505 if (CommandArg == NULL) {\r
506 EDBPrint (L"BreakpointEnable Argument error!\n");\r
507 return EFI_DEBUG_CONTINUE;\r
508 }\r
509\r
510 if (StriCmp (CommandArg, L"*") == 0) {\r
511 //\r
512 // enable all breakpoint\r
513 //\r
514 for (Index = 0; Index < DebuggerPrivate->DebuggerBreakpointCount; Index++) {\r
515 Status = DebuggerBreakpointEn (DebuggerPrivate, Index);\r
516 }\r
517 EDBPrint (L"All the Breakpoint is enabled\n");\r
518 return EFI_DEBUG_CONTINUE;\r
519 }\r
520\r
521 //\r
522 // Get breakpoint index\r
523 //\r
524 Index = Atoi(CommandArg);\r
525 if (Index == (UINTN) -1) {\r
526 EDBPrint (L"BreakpointEnable Argument error!\n");\r
527 return EFI_DEBUG_CONTINUE;\r
528 }\r
529\r
530 //\r
531 // Enable breakpoint\r
532 //\r
533 Status = DebuggerBreakpointEn (DebuggerPrivate, Index);\r
534 if (EFI_ERROR(Status)) {\r
535 EDBPrint (L"BreakpointEnable error!\n");\r
536 }\r
537\r
538 //\r
539 // Done\r
540 //\r
541 return EFI_DEBUG_CONTINUE;\r
542}\r