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