]> git.proxmox.com Git - mirror_edk2.git/blame - SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.c
Fix the issue that might prevent single step in PeCoffExtraActionLib (right after...
[mirror_edk2.git] / SourceLevelDebugPkg / Library / DebugAgent / DebugAgentCommon / DebugAgent.c
CommitLineData
18b144ea 1/** @file\r
2 Commond Debug Agent library implementition. It mainly includes\r
3 the first C function called by exception/interrupt handlers,\r
4 read/write debug packet to communication with HOST based on transfer\r
5 protocol.\r
6\r
7 Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
8 This program and the accompanying materials\r
9 are licensed and made available under the terms and conditions of the BSD License\r
10 which accompanies this distribution. The full text of the license may be found at\r
11 http://opensource.org/licenses/bsd-license.php.\r
12\r
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15\r
16**/\r
17\r
18#include "DebugAgent.h"\r
19#include "Ia32/DebugException.h"\r
20\r
21/**\r
22 Check if HOST is connected based on Mailbox.\r
23\r
24 @retval TRUE HOST is connected.\r
25 @retval FALSE HOST is not connected.\r
26\r
27**/\r
28BOOLEAN\r
29IsHostConnected (\r
30 VOID\r
31 )\r
32{\r
33 DEBUG_AGENT_MAILBOX *Mailbox;\r
34\r
35 Mailbox = GetMailboxPointer ();\r
36\r
37 if (Mailbox->DebugFlag.Bits.HostPresent == 1) {\r
38 return TRUE;\r
39 } else {\r
40 return FALSE;\r
41 }\r
42}\r
43\r
44/**\r
45 Set HOST connect flag in Mailbox.\r
46\r
47**/\r
48VOID\r
49SetHostConnectedFlag (\r
50 VOID\r
51 )\r
52{\r
53 DEBUG_AGENT_MAILBOX *Mailbox;\r
54\r
55 Mailbox = GetMailboxPointer ();\r
56\r
57 Mailbox->DebugFlag.Bits.HostPresent = 1;\r
58}\r
59\r
60/**\r
61 Set debug flag of Debug Agent in Mailbox.\r
62\r
63 @param DebugFlag Debug Flag defined by transfer protocol.\r
64\r
65**/\r
66VOID\r
67SetDebugFlag (\r
68 IN UINT32 DebugFlag\r
69 )\r
70{\r
71 DEBUG_AGENT_MAILBOX *Mailbox;\r
72\r
73 Mailbox = GetMailboxPointer ();\r
74\r
75 if ((DebugFlag & SOFT_DEBUGGER_SETTING_SMM_ENTRY_BREAK) != 0) {\r
76 Mailbox->DebugFlag.Bits.BreakOnNextSmi = 1;\r
77 } else {\r
78 Mailbox->DebugFlag.Bits.BreakOnNextSmi = 0;\r
79 }\r
80}\r
81\r
82/**\r
83 Exectue GO command.\r
84\r
85 @param[in] CpuContext Pointer to saved CPU context.\r
86\r
87**/\r
88VOID\r
89CommandGo (\r
90 IN DEBUG_CPU_CONTEXT *CpuContext\r
91 )\r
92{\r
93 IA32_EFLAGS32 *Eflags;\r
94\r
95 Eflags = (IA32_EFLAGS32 *) &CpuContext->Eflags;\r
96 Eflags->Bits.TF = 0;\r
97 Eflags->Bits.RF = 1;\r
98}\r
99\r
100/**\r
101 Exectue Stepping command.\r
102\r
103 @param[in] CpuContext Pointer to saved CPU context.\r
104\r
105**/\r
106VOID\r
107CommandStepping (\r
108 IN DEBUG_CPU_CONTEXT *CpuContext\r
109 )\r
110{\r
111 IA32_EFLAGS32 *Eflags;\r
112\r
113 Eflags = (IA32_EFLAGS32 *) &CpuContext->Eflags;\r
114 Eflags->Bits.TF = 1;\r
115 Eflags->Bits.RF = 1;\r
116}\r
117\r
118/**\r
119 Set debug register for hardware breakpoint.\r
120\r
121 @param[in] CpuContext Pointer to saved CPU context.\r
122 @param[in] SetHwBreakpoint Hardware breakpoint to be set.\r
123\r
124**/\r
125VOID\r
126SetDebugRegister (\r
127 IN DEBUG_CPU_CONTEXT *CpuContext,\r
128 IN DEBUG_DATA_SET_HW_BREAKPOINT *SetHwBreakpoint\r
129 )\r
130{\r
131 UINT8 RegisterIndex;\r
132 UINTN Dr7Value;\r
133\r
134 RegisterIndex = SetHwBreakpoint->Type.Index;\r
135\r
136 //\r
137 // Set debug address\r
138 //\r
139 * ((UINTN *) &CpuContext->Dr0 + RegisterIndex) = (UINTN) SetHwBreakpoint->Address;\r
140\r
141 Dr7Value = CpuContext->Dr7;\r
142\r
143 //\r
144 // Enable Gx, Lx\r
145 //\r
146 Dr7Value |= 0x3 << (RegisterIndex * 2);\r
147 //\r
148 // Set RWx and Lenx\r
149 //\r
150 Dr7Value &= ~(0xf0000 << (RegisterIndex * 4));\r
151 Dr7Value |= (SetHwBreakpoint->Type.Length | SetHwBreakpoint->Type.Access) << (RegisterIndex * 4);\r
152 //\r
153 // Enable GE, LE\r
154 //\r
155 Dr7Value |= 0x300;\r
156\r
157 CpuContext->Dr7 = Dr7Value;\r
158}\r
159\r
160/**\r
161 Clear debug register for hardware breakpoint.\r
162\r
163 @param[in] CpuContext Pointer to saved CPU context.\r
164 @param[in] ClearHwBreakpoint Hardware breakpoint to be cleared.\r
165\r
166**/\r
167VOID\r
168ClearDebugRegister (\r
169 IN DEBUG_CPU_CONTEXT *CpuContext,\r
170 IN DEBUG_DATA_CLEAR_HW_BREAKPOINT *ClearHwBreakpoint\r
171 )\r
172{\r
173 if ((ClearHwBreakpoint->IndexMask & BIT0) != 0) {\r
174 CpuContext->Dr0 = 0;\r
175 CpuContext->Dr7 &= ~(0x3 << 0);\r
176 }\r
177 if ((ClearHwBreakpoint->IndexMask & BIT1) != 0) {\r
178 CpuContext->Dr1 = 0;\r
179 CpuContext->Dr7 &= ~(0x3 << 2);\r
180 }\r
181 if ((ClearHwBreakpoint->IndexMask & BIT2) != 0) {\r
182 CpuContext->Dr2 = 0;\r
183 CpuContext->Dr7 &= ~(0x3 << 4);\r
184 }\r
185 if ((ClearHwBreakpoint->IndexMask & BIT3) != 0) {\r
186 CpuContext->Dr3 = 0;\r
187 CpuContext->Dr7 &= ~(0x3 << 6);\r
188 }\r
189}\r
190\r
191/**\r
192 Send acknowledge packet to HOST.\r
193\r
194 @param[in] AckCommand Type of Acknowledge packet.\r
195\r
196**/\r
197VOID\r
198SendAckPacket (\r
199 IN UINT8 AckCommand\r
200 )\r
201{\r
202 DEBUG_COMMAND_HEADER DebugCommonHeader;\r
203 DEBUG_PORT_HANDLE Handle;\r
204\r
205 Handle = GetDebugPortHandle();\r
206\r
207 DebugCommonHeader.StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL;\r
208 DebugCommonHeader.Command = AckCommand;\r
209 DebugCommonHeader.DataLength = 0;\r
210\r
211 DebugPortWriteBuffer (Handle, (UINT8 *) &DebugCommonHeader, sizeof (DEBUG_COMMAND_HEADER));\r
212}\r
213\r
214/**\r
215 Receive acknowledge packet from HOST in specified time.\r
216\r
217 @param[out] Ack Returned acknowlege type from HOST.\r
218 @param[in] Timeout Time out value to wait for acknowlege from HOST.\r
219 The unit is microsecond.\r
220 @param[out] BreakReceived If BreakReceived is not NULL,\r
221 TRUE is retured if break-in symbol received.\r
222 FALSE is retured if break-in symbol not received.\r
223\r
224 @retval RETRUEN_SUCCESS Succeed to receive acknowlege packet from HOST,\r
225 the type of acknowlege packet saved in Ack.\r
226 @retval RETURN_TIMEOUT Specified timeout value was up.\r
227\r
228**/\r
229RETURN_STATUS\r
230ReceiveAckPacket (\r
231 OUT UINT8 *Ack,\r
232 IN UINTN Timeout,\r
233 OUT BOOLEAN *BreakReceived OPTIONAL\r
234 )\r
235{\r
236 DEBUG_COMMAND_HEADER DebugCommonHeader;\r
237 DEBUG_PORT_HANDLE Handle;\r
238\r
239 Handle = GetDebugPortHandle();\r
240\r
241 while (TRUE) {\r
242 if (DebugPortReadBuffer (Handle, (UINT8 *) &DebugCommonHeader.StartSymbol, 1, Timeout) == 0) {\r
243 return RETURN_TIMEOUT;\r
244 }\r
245 if (DebugCommonHeader.StartSymbol == DEBUG_STARTING_SYMBOL_BREAK) {\r
246 if (BreakReceived != NULL) {\r
247 SendAckPacket (DEBUG_COMMAND_HALT_DEFERRED);\r
248 *BreakReceived = TRUE;\r
249 }\r
250 }\r
251 if (DebugCommonHeader.StartSymbol == DEBUG_STARTING_SYMBOL_NORMAL) {\r
252 break;\r
253 }\r
254 }\r
255 if (DebugPortReadBuffer (Handle, (UINT8 *)&DebugCommonHeader.Command, sizeof (DEBUG_COMMAND_HEADER) - 1, Timeout) == 0) {\r
256 return RETURN_TIMEOUT;\r
257 }\r
258\r
259 *Ack = DebugCommonHeader.Command;\r
260 return RETURN_SUCCESS;\r
261}\r
262\r
263/**\r
264 Receive acknowledge packet OK from HOST in specified time.\r
265\r
266 @param[in] Timeout Time out value to wait for acknowlege from HOST.\r
267 The unit is microsecond.\r
268 @param[out] BreakReceived If BreakReceived is not NULL,\r
269 TRUE is retured if break-in symbol received.\r
270 FALSE is retured if break-in symbol not received.\r
271\r
272 @retval RETRUEN_SUCCESS Succeed to receive acknowlege packet from HOST,\r
273 the type of acknowlege packet saved in Ack.\r
274 @retval RETURN_TIMEOUT Specified timeout value was up.\r
275\r
276**/\r
277RETURN_STATUS\r
278WaitForAckPacketOK (\r
279 IN UINTN Timeout,\r
280 OUT BOOLEAN *BreakReceived OPTIONAL\r
281 )\r
282{\r
283 RETURN_STATUS Status;\r
284 UINT8 Ack;\r
285\r
286 while (TRUE) {\r
287 Status = ReceiveAckPacket (&Ack, Timeout, BreakReceived);\r
288 if ((Status == RETURN_SUCCESS && Ack == DEBUG_COMMAND_OK) ||\r
289 Status == RETURN_TIMEOUT) {\r
290 break;\r
291 }\r
292 }\r
293\r
294 return Status;\r
295}\r
296\r
297/**\r
298 Receive valid packet from HOST.\r
299\r
300 @param[out] InputPacket Buffer to receive packet.\r
301 @param[out] BreakReceived TRUE means break-in symbol received.\r
302 FALSE means break-in symbol not received.\r
303\r
304 @retval RETURN_SUCCESS A valid package was reveived in InputPacket.\r
305 @retval RETURN_NOT_READY No valid start symbol received.\r
306 @retval RETURN_TIMEOUT Timeout occurs.\r
307\r
308**/\r
309RETURN_STATUS\r
310ReceivePacket (\r
311 OUT UINT8 *InputPacket,\r
312 OUT BOOLEAN *BreakReceived\r
313 )\r
314{\r
315 DEBUG_COMMAND_HEADER *DebugHeader;\r
316 UINTN Received;\r
317 DEBUG_PORT_HANDLE Handle;\r
318\r
319 Handle = GetDebugPortHandle();\r
320 //\r
321 // Find the valid start symbol\r
322 //\r
323 DebugPortReadBuffer (Handle, InputPacket, 1, 0);\r
324\r
325 if (*InputPacket == DEBUG_STARTING_SYMBOL_BREAK) {\r
326 *BreakReceived = TRUE;\r
327 SendAckPacket (DEBUG_COMMAND_HALT_DEFERRED);\r
328 }\r
329\r
330 if (*InputPacket != DEBUG_STARTING_SYMBOL_NORMAL) {\r
331 return RETURN_NOT_READY;\r
332 }\r
333\r
334 //\r
335 // Read Package header\r
336 //\r
337 Received = DebugPortReadBuffer (Handle, InputPacket + 1, sizeof(DEBUG_COMMAND_HEADER_NO_START_SYMBOL), 0);\r
338 if (Received == 0) {\r
339 return RETURN_TIMEOUT;\r
340 }\r
341\r
342 DebugHeader = (DEBUG_COMMAND_HEADER *) InputPacket;\r
343 //\r
344 // Read the payload if has\r
345 //\r
346 if (DebugHeader->DataLength > 0 && DebugHeader->DataLength < (DEBUG_DATA_MAXIMUM_REAL_DATA - sizeof(DEBUG_COMMAND_HEADER))) {\r
347 InputPacket = InputPacket + 1 + Received;\r
348 Received = DebugPortReadBuffer (Handle, InputPacket, DebugHeader->DataLength, 0);\r
349\r
350 if (Received == 0) {\r
351 return RETURN_TIMEOUT;\r
352 }\r
353 }\r
354\r
355 return RETURN_SUCCESS;\r
356}\r
357\r
358/**\r
359 Get current break cause.\r
360\r
361 @param[in] Vector Vector value of exception or interrupt.\r
362 @param[in] CpuContext Pointer to save CPU context.\r
363\r
364 @return The type of break cause defined by XXXX\r
365\r
366**/\r
367UINT8\r
368GetBreakCause (\r
369 IN UINTN Vector,\r
370 IN DEBUG_CPU_CONTEXT *CpuContext\r
371 )\r
372{\r
373 UINT8 Cause;\r
374\r
375 Cause = DEBUG_DATA_BREAK_CAUSE_UNKNOWN;\r
376\r
377 switch (Vector) {\r
378 case DEBUG_INT1_VECTOR:\r
379 case DEBUG_INT3_VECTOR:\r
380\r
381 if (Vector == DEBUG_INT1_VECTOR) {\r
382 //\r
383 // INT 1\r
384 //\r
385 if ((CpuContext->Dr6 & BIT14) != 0) {\r
386 Cause = DEBUG_DATA_BREAK_CAUSE_STEPPING;\r
0a16169b 387 //\r
388 // If it's single step, no need to check DR0, to ensure single step work in PeCoffExtraActionLib\r
389 // (right after triggering a breakpoint to report image load/unload).\r
390 //\r
391 return Cause;\r
18b144ea 392\r
393 } else {\r
394 Cause = DEBUG_DATA_BREAK_CAUSE_HW_BREAKPOINT;\r
395 }\r
396 } else {\r
397 //\r
398 // INT 3\r
399 //\r
400 Cause = DEBUG_DATA_BREAK_CAUSE_SW_BREAKPOINT;\r
401 }\r
402\r
403 switch (CpuContext->Dr0) {\r
404 case IMAGE_LOAD_SIGNATURE:\r
405 case IMAGE_UNLOAD_SIGNATURE:\r
406\r
407 if (CpuContext->Dr3 == IO_PORT_BREAKPOINT_ADDRESS) {\r
408\r
409 Cause = (UINT8) ((CpuContext->Dr0 == IMAGE_LOAD_SIGNATURE) ? \r
410 DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD : DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD);\r
411 }\r
412 break;\r
413\r
414 case SOFT_INTERRUPT_SIGNATURE:\r
415 \r
416 if (CpuContext->Dr1 == MEMORY_READY_SIGNATURE) {\r
417 Cause = DEBUG_DATA_BREAK_CAUSE_MEMORY_READY;\r
418 CpuContext->Dr0 = 0;\r
419 } else if (CpuContext->Dr1 == SYSTEM_RESET_SIGNATURE) {\r
420 Cause = DEBUG_DATA_BREAK_CAUSE_SYSTEM_RESET;\r
421 CpuContext->Dr0 = 0;\r
422 }\r
423 break;\r
424\r
425 default:\r
426 break;\r
427\r
428 }\r
429\r
430 break;\r
431\r
432 case DEBUG_TIMER_VECTOR:\r
433 Cause = DEBUG_DATA_BREAK_CAUSE_USER_HALT;\r
434 break;\r
435\r
436 default:\r
437 if (Vector < 20) {\r
438 Cause = DEBUG_DATA_BREAK_CAUSE_EXCEPTION;\r
439 }\r
440 break;\r
441 }\r
442\r
443 return Cause;\r
444}\r
445\r
446/**\r
447 Send packet with response data to HOST.\r
448\r
449 @param[in] CpuContext Pointer to saved CPU context.\r
450 @param[in] Data Pointer to response data buffer.\r
451 @param[in] DataSize Size of response data in byte.\r
452\r
453 @retval RETURN_SUCCESS Response data was sent successfully.\r
454 @retval RETURN_DEVICE_ERROR Cannot receive DEBUG_COMMAND_OK from HOST.\r
455\r
456**/\r
457RETURN_STATUS\r
458SendDataResponsePacket (\r
459 IN DEBUG_CPU_CONTEXT *CpuContext,\r
460 IN UINT8 *Data,\r
461 IN UINT16 DataSize\r
462 )\r
463{\r
464 UINT8 PacketHeader[DEBUG_DATA_MAXIMUM_LENGTH_FOR_SMALL_COMMANDS];\r
465 BOOLEAN LastPacket;\r
466 UINT8 Ack;\r
467 UINT8 PacketData[DEBUG_DATA_MAXIMUM_REAL_DATA];\r
468 DEBUG_PORT_HANDLE Handle;\r
469\r
470 Handle = GetDebugPortHandle();\r
471\r
472 ((DEBUG_COMMAND_HEADER *)PacketHeader)->StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL;\r
473\r
474 while (TRUE) {\r
475 if (DataSize <= DEBUG_DATA_MAXIMUM_REAL_DATA) {\r
476 LastPacket = TRUE;\r
477 ((DEBUG_COMMAND_HEADER *)PacketHeader)->Command = DEBUG_COMMAND_OK;\r
478 ((DEBUG_COMMAND_HEADER *)PacketHeader)->DataLength = (UINT8) DataSize;\r
479 CopyMem (PacketData, Data, DataSize);\r
480\r
481 } else {\r
482 LastPacket = FALSE;\r
483 ((DEBUG_COMMAND_HEADER *)PacketHeader)->Command = DEBUG_COMMAND_IN_PROGRESS;\r
484 ((DEBUG_COMMAND_HEADER *)PacketHeader)->DataLength = DEBUG_DATA_MAXIMUM_REAL_DATA;\r
485 CopyMem (PacketData, Data, DEBUG_DATA_MAXIMUM_REAL_DATA);\r
486 }\r
487\r
488 DebugPortWriteBuffer (Handle, PacketHeader, sizeof (DEBUG_COMMAND_HEADER));\r
489 DebugPortWriteBuffer (Handle, PacketData, ((DEBUG_COMMAND_HEADER *)PacketHeader)->DataLength);\r
490\r
491 ReceiveAckPacket(&Ack, 0, NULL);\r
492 switch (Ack) {\r
493 case DEBUG_COMMAND_RESEND:\r
494 //\r
495 // Send the packet again\r
496 //\r
497 break;\r
498\r
499 case DEBUG_COMMAND_CONTINUE:\r
500 //\r
501 // Send the rest packet\r
502 //\r
503 Data += DEBUG_DATA_MAXIMUM_REAL_DATA;\r
504 DataSize -= DEBUG_DATA_MAXIMUM_REAL_DATA;\r
505 break;\r
506\r
507 case DEBUG_COMMAND_OK:\r
508 if (LastPacket) {\r
509 //\r
510 // If this is the last packet, return RETURN_SUCCESS.\r
511 //\r
512 return RETURN_SUCCESS;\r
513 } else {\r
514 return RETURN_DEVICE_ERROR;\r
515 }\r
516\r
517 default:\r
518 return RETURN_DEVICE_ERROR;\r
519\r
520 }\r
521 }\r
522}\r
523\r
524/**\r
525 Send break cause packet to HOST.\r
526\r
527 @param[in] Vector Vector value of exception or interrutp.\r
528 @param[in] CpuContext Pointer to save CPU context.\r
529\r
530 @retval RETURN_SUCCESS Response data was sent successfully.\r
531 @retval RETURN_DEVICE_ERROR Cannot receive DEBUG_COMMAND_OK from HOST.\r
532\r
533**/\r
534RETURN_STATUS\r
535SendBreakCausePacket (\r
536 IN UINTN Vector,\r
537 IN DEBUG_CPU_CONTEXT *CpuContext\r
538 )\r
539{\r
540 DEBUG_DATA_RESPONSE_BREAK_CAUSE DebugDataBreakCause;\r
541\r
542 DebugDataBreakCause.StopAddress = CpuContext->Eip;\r
543 DebugDataBreakCause.Cause = GetBreakCause (Vector, CpuContext);\r
544\r
545 return SendDataResponsePacket (CpuContext, (UINT8 *) &DebugDataBreakCause, (UINT16) sizeof (DEBUG_DATA_RESPONSE_BREAK_CAUSE));\r
546}\r
547\r
548\r
549/**\r
550 The main function to process communication with HOST.\r
551\r
552 It received the command packet from HOST, and sent response data packet to HOST.\r
553\r
554 @param[in] Vector Vector value of exception or interrutp.\r
555 @param[in, out] CpuContext Pointer to saved CPU context.\r
556 @param[in] BreakReceived TRUE means break-in symbol received.\r
557 FALSE means break-in symbol not received.\r
558\r
559**/\r
560VOID\r
561CommandCommunication (\r
562 IN UINTN Vector,\r
563 IN OUT DEBUG_CPU_CONTEXT *CpuContext,\r
564 IN BOOLEAN BreakReceived\r
565 )\r
566{\r
567 RETURN_STATUS Status;\r
568 UINT8 InputPacketBuffer[DEBUG_DATA_MAXIMUM_LENGTH_FOR_SMALL_COMMANDS];\r
569 DEBUG_COMMAND_HEADER *DebugHeader;\r
570 UINT8 Data8;\r
571 UINT32 Data32;\r
572 UINT64 Data64;\r
573 UINTN DataN;\r
574 DEBUG_DATA_READ_MEMORY_8 *MemoryRead;\r
575 DEBUG_DATA_WRITE_MEMORY_8 *MemoryWrite;\r
576 DEBUG_DATA_READ_IO *IoRead;\r
577 DEBUG_DATA_WRITE_IO *IoWrite;\r
578 DEBUG_DATA_READ_REGISTER *RegisterRead;\r
579 DEBUG_DATA_WRITE_REGISTER *RegisterWrite;\r
580 UINT8 *RegisterBuffer;\r
581 DEBUG_DATA_READ_MSR *MsrRegisterRead;\r
582 DEBUG_DATA_WRITE_MSR *MsrRegisterWrite;\r
583 DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM RegisterGroupSegLim;\r
584 DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE RegisterGroupSegBase;\r
585 DEBUG_DATA_RESPONSE_GET_REVISION DebugAgentRevision;\r
586 BOOLEAN HaltDeferred;\r
587 DEBUG_DATA_RESPONSE_GET_EXCEPTION Exception;\r
588 UINT32 ProcessorIndex;\r
589 DEBUG_PORT_HANDLE Handle;\r
590\r
591 Handle = GetDebugPortHandle();\r
592\r
593 ProcessorIndex = 0;\r
594 HaltDeferred = BreakReceived;\r
595\r
596 if (MultiProcessorDebugSupport) {\r
597 ProcessorIndex = GetProcessorIndex ();\r
598 SetCpuStopFlagByIndex (ProcessorIndex, TRUE);\r
599 }\r
600\r
601 while (TRUE) {\r
602\r
603 if (MultiProcessorDebugSupport) {\r
604 if (mDebugMpContext.ViewPointIndex != ProcessorIndex) {\r
605 if (mDebugMpContext.RunCommandSet) {\r
606 SetCpuStopFlagByIndex (ProcessorIndex, FALSE);\r
607 CommandGo (CpuContext);\r
608 break;\r
609 } else {\r
610 continue;\r
611 }\r
612 }\r
613 }\r
614\r
615 AcquireDebugPortControl ();\r
616\r
617 Status = ReceivePacket (InputPacketBuffer, &BreakReceived);\r
618\r
619 if (BreakReceived) {\r
620 HaltDeferred = TRUE;\r
621 BreakReceived = FALSE;\r
622 }\r
623\r
624 if (Status != RETURN_SUCCESS) {\r
625 ReleaseDebugPortControl ();\r
626 continue;\r
627 }\r
628\r
629 Data8 = 1;\r
630\r
631 DebugHeader =(DEBUG_COMMAND_HEADER *) InputPacketBuffer;\r
632 switch (DebugHeader->Command) {\r
633\r
634 case DEBUG_COMMAND_RESET:\r
635 SendAckPacket (DEBUG_COMMAND_OK);\r
636 ReleaseDebugPortControl ();\r
637\r
638 ResetCold ();\r
639 //\r
640 // Wait for reset\r
641 //\r
642 CpuDeadLoop ();\r
643 break;\r
644\r
645 case DEBUG_COMMAND_GO:\r
646 CommandGo (CpuContext);\r
647 if (!HaltDeferred) {\r
648 //\r
649 // If no HALT command received when being in-active mode\r
650 //\r
651 if (MultiProcessorDebugSupport) {\r
652 Data32 = FindCpuNotRunning ();\r
653 if (Data32 != -1) {\r
654 //\r
655 // If there are still others processors being in break state, \r
656 // send OK packet to HOST to finish this go command\r
657 //\r
658 SendAckPacket (DEBUG_COMMAND_OK);\r
659 CpuPause ();\r
660 //\r
661 // Set current view to the next breaking processor\r
662 //\r
663 mDebugMpContext.ViewPointIndex = Data32;\r
664 mDebugMpContext.BreakAtCpuIndex = mDebugMpContext.ViewPointIndex;\r
665 SetCpuBreakFlagByIndex (mDebugMpContext.ViewPointIndex, FALSE);\r
666 //\r
667 // Send break packet to HOST and exit to wait for command packet from HOST.\r
668 //\r
669 SendAckPacket (DEBUG_COMMAND_BREAK_POINT);\r
670 WaitForAckPacketOK (0, &BreakReceived);\r
671 ReleaseDebugPortControl (); \r
672 break;\r
673 }\r
674\r
675 //\r
676 // If no else processor break, set stop bitmask,\r
677 // and set Running flag for all processors.\r
678 //\r
679 SetCpuStopFlagByIndex (ProcessorIndex, FALSE);\r
680 SetCpuRunningFlag (TRUE);\r
681 CpuPause ();\r
682 //\r
683 // Wait for all processors are in running state \r
684 //\r
685 while (TRUE) {\r
686 if (IsAllCpuRunning ()) {\r
687 break;\r
688 }\r
689 }\r
690 //\r
691 // Set BSP to be current view point.\r
692 //\r
693 SetDebugViewPoint (mDebugMpContext.BspIndex);\r
694 CpuPause ();\r
695 //\r
696 // Clear breaking processor index and running flag\r
697 //\r
698 mDebugMpContext.BreakAtCpuIndex = (UINT32) (-1);\r
699 SetCpuRunningFlag (FALSE);\r
700 }\r
701\r
702 //\r
703 // Send OK packet to HOST to finish this go command\r
704 //\r
705 SendAckPacket (DEBUG_COMMAND_OK);\r
706\r
707 ReleaseDebugPortControl ();\r
708\r
709 return;\r
710\r
711 } else {\r
712 //\r
713 // If reveived HALT command, need to defer the GO command\r
714 //\r
715 SendAckPacket (DEBUG_COMMAND_HALT_PROCESSED);\r
716 HaltDeferred = FALSE;\r
717 Data8 = GetBreakCause (Vector, CpuContext);\r
718 if (Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD || Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD) {\r
719 CpuContext->Dr0 = 0;\r
720 CpuContext->Dr3 = 0;\r
721 }\r
722\r
723 Vector = DEBUG_TIMER_VECTOR;\r
724 }\r
725 break;\r
726\r
727 case DEBUG_COMMAND_BREAK_CAUSE:\r
728\r
729 if (MultiProcessorDebugSupport && ProcessorIndex != mDebugMpContext.BreakAtCpuIndex) {\r
730 Status = SendBreakCausePacket (DEBUG_TIMER_VECTOR, CpuContext);\r
731\r
732 } else {\r
733 Status = SendBreakCausePacket (Vector, CpuContext);\r
734 }\r
735\r
736 break;\r
737\r
738 case DEBUG_COMMAND_SET_HW_BREAKPOINT:\r
739 SetDebugRegister (CpuContext, (DEBUG_DATA_SET_HW_BREAKPOINT *) (DebugHeader + 1));\r
740 SendAckPacket (DEBUG_COMMAND_OK);\r
741 break;\r
742\r
743 case DEBUG_COMMAND_CLEAR_HW_BREAKPOINT:\r
744 ClearDebugRegister (CpuContext, (DEBUG_DATA_CLEAR_HW_BREAKPOINT *) (DebugHeader + 1));\r
745 SendAckPacket (DEBUG_COMMAND_OK);\r
746 break;\r
747\r
748 case DEBUG_COMMAND_SINGLE_STEPPING:\r
749 CommandStepping (CpuContext);\r
750\r
751 mDebugMpContext.BreakAtCpuIndex = (UINT32) (-1);\r
752\r
753 ReleaseDebugPortControl ();\r
754 //\r
755 // Executing stepping command directly without sending ACK packet.\r
756 //\r
757 return;\r
758\r
759 case DEBUG_COMMAND_SET_SW_BREAKPOINT:\r
760 Data64 = (UINTN) (((DEBUG_DATA_SET_SW_BREAKPOINT *) (DebugHeader + 1))->Address);\r
761 Data8 = *(UINT8 *) (UINTN) Data64;\r
762 *(UINT8 *) (UINTN) Data64 = DEBUG_SW_BREAKPOINT_SYMBOL;\r
763 Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Data8, (UINT16) sizeof (UINT8));\r
764 break;\r
765\r
766 case DEBUG_COMMAND_READ_MEMORY_64:\r
767 Data8 *= 2;\r
768 case DEBUG_COMMAND_READ_MEMORY_32:\r
769 Data8 *= 2;\r
770 case DEBUG_COMMAND_READ_MEMORY_16:\r
771 Data8 *= 2;\r
772 case DEBUG_COMMAND_READ_MEMORY_8:\r
773 MemoryRead = (DEBUG_DATA_READ_MEMORY_8 *) (DebugHeader + 1);\r
774 Status = SendDataResponsePacket (CpuContext, (UINT8 *) (UINTN) MemoryRead->Address, (UINT16) (MemoryRead->Count * Data8));\r
775 break;\r
776\r
777 case DEBUG_COMMAND_WRITE_MEMORY_64:\r
778 Data8 *= 2;\r
779 case DEBUG_COMMAND_WRITE_MEMORY_32:\r
780 Data8 *= 2;\r
781 case DEBUG_COMMAND_WRITE_MEMORY_16:\r
782 Data8 *= 2;\r
783 case DEBUG_COMMAND_WRITE_MEMORY_8:\r
784 MemoryWrite = (DEBUG_DATA_WRITE_MEMORY_8 *) (DebugHeader + 1);\r
785 CopyMem ((VOID *) (UINTN) MemoryWrite->Address, &MemoryWrite->Data, MemoryWrite->Count * Data8);\r
786 SendAckPacket (DEBUG_COMMAND_OK);\r
787 break;\r
788\r
789 case DEBUG_COMMAND_READ_IO:\r
790 IoRead = (DEBUG_DATA_READ_IO *) (DebugHeader + 1);\r
791 switch (IoRead->Width) {\r
792 case 1:\r
793 Data64 = IoRead8 (IoRead->Port);\r
794 break;\r
795 case 2:\r
796 Data64 = IoRead16 (IoRead->Port);\r
797 break;\r
798 case 4:\r
799 Data64 = IoRead32 (IoRead->Port);\r
800 break;\r
801 case 8:\r
802 Data64 = IoRead64 (IoRead->Port);\r
803 break;\r
804 default:\r
805 Data64 = (UINT64) -1;\r
806 }\r
807 Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Data64, IoRead->Width);\r
808 break;\r
809\r
810 case DEBUG_COMMAND_WRITE_IO:\r
811 IoWrite = (DEBUG_DATA_WRITE_IO *) (DebugHeader + 1);\r
812 switch (IoWrite->Width) {\r
813 case 1:\r
814 Data64 = IoWrite8 (IoWrite->Port, *(UINT8 *) &IoWrite->Data);\r
815 break;\r
816 case 2:\r
817 Data64 = IoWrite16 (IoWrite->Port, *(UINT16 *) &IoWrite->Data);\r
818 break;\r
819 case 4:\r
820 Data64 = IoWrite32 (IoWrite->Port, *(UINT32 *) &IoWrite->Data);\r
821 break;\r
822 case 8:\r
823 Data64 = IoWrite64 (IoWrite->Port, *(UINT64 *) &IoWrite->Data);\r
824 break;\r
825 default:\r
826 Data64 = (UINT64) -1;\r
827 }\r
828 SendAckPacket (DEBUG_COMMAND_OK);\r
829 break;\r
830\r
831 case DEBUG_COMMAND_READ_REGISTER:\r
832 RegisterRead = (DEBUG_DATA_READ_REGISTER *) (DebugHeader + 1);\r
833\r
834 if (RegisterRead->Index < SOFT_DEBUGGER_REGISTER_OTHERS_BASE) {\r
835 Data8 = RegisterRead->Length;\r
836 RegisterBuffer = ArchReadRegisterBuffer (CpuContext, RegisterRead->Index, RegisterRead->Offset, &Data8);\r
837 Status = SendDataResponsePacket (CpuContext, RegisterBuffer, Data8);\r
838 break;\r
839 }\r
840\r
841 if (RegisterRead->Index <= SOFT_DEBUGGER_REGISTER_TSS_LIM) {\r
842 ReadRegisterGroupSegLim (CpuContext, &RegisterGroupSegLim);\r
843 DataN = * ((UINTN *) &RegisterGroupSegLim + (RegisterRead->Index - SOFT_DEBUGGER_REGISTER_CS_LIM));\r
844 Status = SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN));\r
845 } else if (RegisterRead->Index <= SOFT_DEBUGGER_REGISTER_TSS_BAS) {\r
846 ReadRegisterGroupSegBase (CpuContext, &RegisterGroupSegBase);\r
847 DataN = * ((UINTN *) &RegisterGroupSegBase + (RegisterRead->Index - SOFT_DEBUGGER_REGISTER_CS_BAS));\r
848 Status = SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN));\r
849 } else if (RegisterRead->Index < SOFT_DEBUGGER_REGISTER_IDT_LIM) {\r
850 Data64 = ReadRegisterSelectorByIndex (CpuContext, RegisterRead->Index);\r
851 Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Data64, (UINT16) sizeof (UINT64));\r
852 } else {\r
853 switch (RegisterRead->Index) {\r
854 case SOFT_DEBUGGER_REGISTER_IDT_LIM:\r
855 DataN = (UINTN) (CpuContext->Idtr[0] & 0xffff);\r
856 SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN));\r
857 break;\r
858 case SOFT_DEBUGGER_REGISTER_GDT_LIM:\r
859 DataN = (UINTN) (CpuContext->Gdtr[0] & 0xffff);\r
860 SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN));\r
861 break;\r
862 case SOFT_DEBUGGER_REGISTER_IDT_BAS:\r
863 DataN = (UINTN) RShiftU64 (CpuContext->Idtr[0], 16);\r
864 DataN |= (UINTN) LShiftU64 (CpuContext->Idtr[1], (UINT16) (sizeof (UINTN) * 8 - 16));\r
865 SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN));\r
866 break;\r
867 case SOFT_DEBUGGER_REGISTER_GDT_BAS:\r
868 DataN = (UINTN) RShiftU64 (CpuContext->Gdtr[0], 16);\r
869 DataN |= (UINTN) LShiftU64 (CpuContext->Gdtr[1], (UINT16) (sizeof (UINTN) * 8 - 16));\r
870 SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN));\r
871 break;\r
872 }\r
873 }\r
874 break;\r
875\r
876 case DEBUG_COMMAND_WRITE_REGISTER:\r
877 RegisterWrite = (DEBUG_DATA_WRITE_REGISTER *) (DebugHeader + 1);\r
878 ArchWriteRegisterBuffer (CpuContext, RegisterWrite->Index, RegisterWrite->Offset, RegisterWrite->Length, (UINT8 *)&RegisterWrite->Value);\r
879 SendAckPacket (DEBUG_COMMAND_OK);\r
880 break;\r
881\r
882 case DEBUG_COMMAND_ARCH_MODE:\r
883 Data8 = DEBUG_ARCH_SYMBOL;\r
884 Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Data8, (UINT16) sizeof (UINT8));\r
885 break;\r
886\r
887 case DEBUG_COMMAND_READ_MSR:\r
888 MsrRegisterRead = (DEBUG_DATA_READ_MSR *) (DebugHeader + 1);\r
889 Data64 = AsmReadMsr64 (MsrRegisterRead->Index);\r
890 Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Data64, (UINT16) sizeof (UINT64));\r
891 break;\r
892\r
893 case DEBUG_COMMAND_WRITE_MSR:\r
894 MsrRegisterWrite = (DEBUG_DATA_WRITE_MSR *) (DebugHeader + 1);\r
895 AsmWriteMsr64 (MsrRegisterWrite->Index, MsrRegisterWrite->Value);\r
896 SendAckPacket (DEBUG_COMMAND_OK);\r
897 break;\r
898\r
899 case DEBUG_COMMAND_READ_REGISTER_GROUP:\r
900 Data8 = *(UINT8 *) (DebugHeader + 1);\r
901 Status = ArchReadRegisterGroup (CpuContext, Data8);\r
902 break;\r
903\r
904 case DEBUG_COMMAND_SET_DEBUG_FLAG:\r
905 Data32 = *(UINT32 *) (DebugHeader + 1);\r
906 SetDebugFlag (Data32);\r
907 SendAckPacket (DEBUG_COMMAND_OK);\r
908 break;\r
909\r
910 case DEBUG_COMMAND_GET_REVISION:\r
911 DebugAgentRevision.Revision = DEBUG_AGENT_REVISION;\r
912 DebugAgentRevision.Capabilities = DEBUG_AGENT_CAPABILITIES;\r
913 Status = SendDataResponsePacket (CpuContext, (UINT8 *) &DebugAgentRevision, (UINT16) sizeof (DEBUG_DATA_RESPONSE_GET_REVISION));\r
914 break;\r
915\r
916 case DEBUG_COMMAND_GET_EXCEPTION:\r
917 Exception.ExceptionNum = (UINT8) Vector;\r
918 Exception.ExceptionData = 0;\r
919 Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Exception, (UINT16) sizeof (DEBUG_DATA_RESPONSE_GET_EXCEPTION));\r
920 break;\r
921\r
922 case DEBUG_COMMAND_SET_VIEWPOINT:\r
923 Data32 = *(UINT32 *) (DebugHeader + 1);\r
924\r
925 if (MultiProcessorDebugSupport) {\r
926 if (IsCpuStopped (Data32)) {\r
927 SetDebugViewPoint (Data32);\r
928 SendAckPacket (DEBUG_COMMAND_OK);\r
929 } else {\r
930 //\r
931 // If CPU is not halted\r
932 //\r
933 SendAckPacket (DEBUG_COMMAND_NOT_SUPPORTED);\r
934 }\r
935 } else if (Data32 == 0) {\r
936 SendAckPacket (DEBUG_COMMAND_OK);\r
937\r
938 } else {\r
939 SendAckPacket (DEBUG_COMMAND_NOT_SUPPORTED);\r
940 }\r
941\r
942 break;\r
943\r
944 case DEBUG_COMMAND_GET_VIEWPOINT:\r
945 Data32 = mDebugMpContext.ViewPointIndex;\r
946 SendDataResponsePacket(CpuContext, (UINT8 *) &Data32, (UINT16) sizeof (UINT32));\r
947 break;\r
948\r
949 default:\r
950 SendAckPacket (DEBUG_COMMAND_NOT_SUPPORTED);\r
951 break;\r
952 }\r
953\r
954 if (Status == RETURN_UNSUPPORTED) {\r
955 SendAckPacket (DEBUG_COMMAND_NOT_SUPPORTED);\r
956 } else if (Status != RETURN_SUCCESS) {\r
957 SendAckPacket (DEBUG_COMMAND_ABORT);\r
958 }\r
959\r
960 ReleaseDebugPortControl ();\r
961 CpuPause ();\r
962 }\r
963}\r
964\r
965/**\r
966 C function called in interrupt handler.\r
967\r
968 @param[in] Vector Vector value of exception or interrutp.\r
969 @param[in] CpuContext Pointer to save CPU context.\r
970\r
971**/\r
972VOID\r
973EFIAPI\r
974InterruptProcess (\r
975 IN UINT32 Vector,\r
976 IN DEBUG_CPU_CONTEXT *CpuContext\r
977 )\r
978{\r
979 UINT8 InputCharacter;\r
980 UINT8 BreakCause;\r
981 UINTN SavedEip;\r
982 BOOLEAN BreakReceived;\r
983 UINT32 ProcessorIndex;\r
984 UINT32 CurrentDebugTimerInitCount;\r
985 DEBUG_PORT_HANDLE Handle;\r
986 UINT8 Data8;\r
987\r
988 Handle = GetDebugPortHandle();\r
989\r
990 ProcessorIndex = 0;\r
991 BreakReceived = FALSE;\r
992\r
993 if (MultiProcessorDebugSupport) {\r
994 ProcessorIndex = GetProcessorIndex ();\r
995 while (mDebugMpContext.RunCommandSet);\r
996 }\r
997\r
998 switch (Vector) {\r
999 case DEBUG_INT1_VECTOR:\r
1000 case DEBUG_INT3_VECTOR:\r
1001\r
1002 BreakCause = GetBreakCause (Vector, CpuContext);\r
1003\r
1004 if (BreakCause == DEBUG_DATA_BREAK_CAUSE_SYSTEM_RESET) {\r
1005\r
1006 //\r
1007 // Init break, if no ack received after 200ms, return\r
1008 //\r
1009 SendAckPacket (DEBUG_COMMAND_INIT_BREAK);\r
1010 if (WaitForAckPacketOK (200 * 1000, &BreakReceived) != RETURN_SUCCESS) {\r
1011 break;\r
1012 }\r
1013\r
1014 SetHostConnectedFlag ();\r
1015 CommandCommunication (Vector, CpuContext, BreakReceived);\r
1016\r
1017 } else if (BreakCause == DEBUG_DATA_BREAK_CAUSE_STEPPING) {\r
1018\r
1019 //\r
1020 // Stepping is finished, send Ack package.\r
1021 //\r
1022 if (MultiProcessorDebugSupport) {\r
1023 mDebugMpContext.BreakAtCpuIndex = ProcessorIndex;\r
1024 }\r
1025 SendAckPacket (DEBUG_COMMAND_OK);\r
1026 CommandCommunication (Vector, CpuContext, BreakReceived);\r
1027\r
1028 } else if (BreakCause == DEBUG_DATA_BREAK_CAUSE_MEMORY_READY) {\r
1029\r
1030 //\r
1031 // Memory is ready\r
1032 //\r
1033 SendAckPacket (DEBUG_COMMAND_MEMORY_READY);\r
1034 WaitForAckPacketOK (0, &BreakReceived);\r
1035 CommandCommunication (Vector, CpuContext, BreakReceived);\r
1036\r
1037 } else {\r
1038\r
1039 if (BreakCause == DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD || BreakCause == DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD) {\r
1040 \r
1041 //\r
1042 // Set AL to DEBUG_AGENT_IMAGE_CONTINUE\r
1043 //\r
1044 Data8 = DEBUG_AGENT_IMAGE_CONTINUE;\r
1045 ArchWriteRegisterBuffer (CpuContext, SOFT_DEBUGGER_REGISTER_AX, 0, 1, &Data8);\r
1046\r
1047 if (!IsHostConnected ()) {\r
1048 //\r
1049 // If HOST is not connected, return\r
1050 //\r
1051 break;\r
1052 }\r
1053 }\r
1054\r
1055 AcquireDebugPortControl ();\r
1056\r
1057 if (MultiProcessorDebugSupport) {\r
1058 if(!IsAllCpuRunning ()) {\r
1059 //\r
1060 // If other processors have been stopped\r
1061 //\r
1062 SetCpuBreakFlagByIndex (ProcessorIndex, TRUE);\r
1063 } else {\r
1064 //\r
1065 // If no any processor was stopped, try to halt other processors\r
1066 //\r
1067 HaltOtherProcessors (ProcessorIndex);\r
1068 SendAckPacket (DEBUG_COMMAND_BREAK_POINT);\r
1069 WaitForAckPacketOK (0, &BreakReceived);\r
1070 }\r
1071 } else {\r
1072 SendAckPacket (DEBUG_COMMAND_BREAK_POINT);\r
1073 WaitForAckPacketOK (0, &BreakReceived);\r
1074 }\r
1075\r
1076 ReleaseDebugPortControl ();\r
1077\r
1078 if (Vector == DEBUG_INT3_VECTOR) {\r
1079 //\r
1080 // go back address located "0xCC"\r
1081 //\r
1082 CpuContext->Eip--;\r
1083 SavedEip = CpuContext->Eip;\r
1084 CommandCommunication (Vector, CpuContext, BreakReceived);\r
1085 if ((SavedEip == CpuContext->Eip) &&\r
1086 (*(UINT8 *) (UINTN) CpuContext->Eip == DEBUG_SW_BREAKPOINT_SYMBOL)) {\r
1087 //\r
1088 // If this is not a software breakpoint set by HOST,\r
1089 // restore EIP\r
1090 //\r
1091 CpuContext->Eip++;\r
1092 }\r
1093 } else {\r
1094 CommandCommunication (Vector, CpuContext, BreakReceived);\r
1095 }\r
1096 }\r
1097\r
1098 break;\r
1099\r
1100 case DEBUG_TIMER_VECTOR:\r
1101\r
1102 if (MultiProcessorDebugSupport) {\r
1103 if (IsBsp (ProcessorIndex)) {\r
1104 //\r
1105 // If current processor is BSP, check Apic timer's init count if changed,\r
1106 // it may be re-written when switching BSP.\r
1107 // If it changed, re-initialize debug timer\r
1108 //\r
1109 CurrentDebugTimerInitCount = GetApicTimerInitCount ();\r
1110 if (mDebugMpContext.DebugTimerInitCount != CurrentDebugTimerInitCount) {\r
1111 InitializeDebugTimer ();\r
1112 }\r
1113 }\r
1114\r
1115 if (!IsBsp (ProcessorIndex) || mDebugMpContext.IpiSentByAp) {\r
1116 //\r
1117 // If current processor is not BSP or this is one IPI sent by AP\r
1118 //\r
1119 if (mDebugMpContext.BreakAtCpuIndex != (UINT32) (-1)) {\r
1120 CommandCommunication (Vector, CpuContext, FALSE);\r
1121 }\r
1122\r
1123 //\r
1124 // Clear EOI before exiting interrupt process routine.\r
1125 //\r
1126 SendApicEoi ();\r
1127 break;\r
1128 }\r
1129 }\r
1130\r
1131 //\r
1132 // Only BSP could run here\r
1133 //\r
1134\r
1135 AcquireDebugPortControl ();\r
1136 \r
1137 while (DebugPortPollBuffer (Handle)) {\r
1138 //\r
1139 // If there is data in debug port, will check whether it is break-in symbol,\r
1140 // If yes, go into communication mode with HOST.\r
1141 // If no, exit interrupt process.\r
1142 //\r
1143 DebugPortReadBuffer (Handle, &InputCharacter, 1, 0);\r
1144 if (InputCharacter == DEBUG_STARTING_SYMBOL_BREAK) {\r
1145 SendAckPacket (DEBUG_COMMAND_OK);\r
1146 if (MultiProcessorDebugSupport) {\r
1147 if(FindCpuNotRunning () != -1) {\r
1148 SetCpuBreakFlagByIndex (ProcessorIndex, TRUE);\r
1149 } else {\r
1150 HaltOtherProcessors (ProcessorIndex);\r
1151 }\r
1152 }\r
1153 ReleaseDebugPortControl ();\r
1154 CommandCommunication (Vector, CpuContext, BreakReceived);\r
1155 AcquireDebugPortControl ();\r
1156 break;\r
1157 }\r
1158 }\r
1159\r
1160 //\r
1161 // Clear EOI before exiting interrupt process routine.\r
1162 //\r
1163 SendApicEoi ();\r
1164\r
1165 ReleaseDebugPortControl ();\r
1166\r
1167 break;\r
1168\r
1169 default:\r
1170\r
1171 if (Vector <= DEBUG_EXCEPT_SIMD) {\r
1172\r
1173 AcquireDebugPortControl ();\r
1174\r
1175 if (MultiProcessorDebugSupport) {\r
1176 if(FindCpuNotRunning () != -1) {\r
1177 SetCpuBreakFlagByIndex (ProcessorIndex, TRUE);\r
1178 } else {\r
1179 HaltOtherProcessors (ProcessorIndex);\r
1180 }\r
1181 }\r
1182 SendAckPacket (DEBUG_COMMAND_BREAK_POINT);\r
1183 WaitForAckPacketOK (0, &BreakReceived);\r
1184 ReleaseDebugPortControl ();\r
1185 CommandCommunication (Vector, CpuContext, BreakReceived);\r
1186 }\r
1187 break;\r
1188 }\r
1189\r
1190 if (MultiProcessorDebugSupport) {\r
1191 //\r
1192 // Clear flag and wait for all processors run here\r
1193 //\r
1194 SetIpiSentByApFlag (FALSE);\r
1195 while (mDebugMpContext.RunCommandSet);\r
1196 }\r
1197\r
1198 return;\r
1199}\r
1200\r