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