Changeset 58459 in vbox for trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent
- Timestamp:
- Oct 28, 2015 8:17:18 PM (9 years ago)
- Location:
- trunk/src/VBox/Devices/EFI/Firmware
- Files:
-
- 4 deleted
- 24 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/EFI/Firmware
-
Property svn:mergeinfo
set to (toggle deleted branches)
/vendor/edk2/current 103735-103757
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.c
r48674 r58459 5 5 protocol. 6 6 7 Copyright (c) 2010 , Intel Corporation. All rights reserved.<BR>7 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR> 8 8 This program and the accompanying materials 9 9 are licensed and made available under the terms and conditions of the BSD License … … 19 19 #include "Ia32/DebugException.h" 20 20 21 /** 22 Check if HOST is connected based on Mailbox. 23 24 @retval TRUE HOST is connected. 25 @retval FALSE HOST is not connected. 21 GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 mErrorMsgVersionAlert[] = "\rThe SourceLevelDebugPkg you are using requires a newer version of the Intel(R) UDK Debugger Tool.\r\n"; 22 GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 mErrorMsgSendInitPacket[] = "\rSend INIT break packet and try to connect the HOST (Intel(R) UDK Debugger Tool v1.4) ...\r\n"; 23 GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 mErrorMsgConnectOK[] = "HOST connection is successful!\r\n"; 24 GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 mErrorMsgConnectFail[] = "HOST connection is failed!\r\n"; 25 GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 mWarningMsgIngoreBreakpoint[] = "Ignore break point in SMM for SMI issued during DXE debugging!\r\n"; 26 27 // 28 // Vector Handoff Info list used by Debug Agent for persist 29 // 30 GLOBAL_REMOVE_IF_UNREFERENCED EFI_VECTOR_HANDOFF_INFO mVectorHandoffInfoDebugAgent[] = { 31 { 32 DEBUG_EXCEPT_DIVIDE_ERROR, // Vector 0 33 EFI_VECTOR_HANDOFF_HOOK_BEFORE, 34 EFI_DEBUG_AGENT_GUID 35 }, 36 { 37 DEBUG_EXCEPT_DEBUG, // Vector 1 38 EFI_VECTOR_HANDOFF_DO_NOT_HOOK, 39 EFI_DEBUG_AGENT_GUID 40 }, 41 { 42 DEBUG_EXCEPT_NMI, // Vector 2 43 EFI_VECTOR_HANDOFF_HOOK_BEFORE, 44 EFI_DEBUG_AGENT_GUID 45 }, 46 { 47 DEBUG_EXCEPT_BREAKPOINT, // Vector 3 48 EFI_VECTOR_HANDOFF_DO_NOT_HOOK, 49 EFI_DEBUG_AGENT_GUID 50 }, 51 { 52 DEBUG_EXCEPT_OVERFLOW, // Vector 4 53 EFI_VECTOR_HANDOFF_HOOK_BEFORE, 54 EFI_DEBUG_AGENT_GUID 55 }, 56 { 57 DEBUG_EXCEPT_BOUND, // Vector 5 58 EFI_VECTOR_HANDOFF_HOOK_BEFORE, 59 EFI_DEBUG_AGENT_GUID 60 }, 61 { 62 DEBUG_EXCEPT_INVALID_OPCODE, // Vector 6 63 EFI_VECTOR_HANDOFF_HOOK_BEFORE, 64 EFI_DEBUG_AGENT_GUID 65 }, 66 { 67 DEBUG_EXCEPT_DOUBLE_FAULT, // Vector 8 68 EFI_VECTOR_HANDOFF_HOOK_BEFORE, 69 EFI_DEBUG_AGENT_GUID 70 }, 71 { 72 DEBUG_EXCEPT_INVALID_TSS, // Vector 10 73 EFI_VECTOR_HANDOFF_HOOK_BEFORE, 74 EFI_DEBUG_AGENT_GUID 75 }, 76 { 77 DEBUG_EXCEPT_SEG_NOT_PRESENT, // Vector 11 78 EFI_VECTOR_HANDOFF_HOOK_BEFORE, 79 EFI_DEBUG_AGENT_GUID 80 }, 81 { 82 DEBUG_EXCEPT_STACK_FAULT, // Vector 12 83 EFI_VECTOR_HANDOFF_HOOK_BEFORE, 84 EFI_DEBUG_AGENT_GUID 85 }, 86 { 87 DEBUG_EXCEPT_GP_FAULT, // Vector 13 88 EFI_VECTOR_HANDOFF_HOOK_BEFORE, 89 EFI_DEBUG_AGENT_GUID 90 }, 91 { 92 DEBUG_EXCEPT_PAGE_FAULT, // Vector 14 93 EFI_VECTOR_HANDOFF_HOOK_BEFORE, 94 EFI_DEBUG_AGENT_GUID 95 }, 96 { 97 DEBUG_EXCEPT_FP_ERROR, // Vector 16 98 EFI_VECTOR_HANDOFF_HOOK_BEFORE, 99 EFI_DEBUG_AGENT_GUID 100 }, 101 { 102 DEBUG_EXCEPT_ALIGNMENT_CHECK, // Vector 17 103 EFI_VECTOR_HANDOFF_HOOK_BEFORE, 104 EFI_DEBUG_AGENT_GUID 105 }, 106 { 107 DEBUG_EXCEPT_MACHINE_CHECK, // Vector 18 108 EFI_VECTOR_HANDOFF_HOOK_BEFORE, 109 EFI_DEBUG_AGENT_GUID 110 }, 111 { 112 DEBUG_EXCEPT_SIMD, // Vector 19 113 EFI_VECTOR_HANDOFF_HOOK_BEFORE, 114 EFI_DEBUG_AGENT_GUID 115 }, 116 { 117 DEBUG_TIMER_VECTOR, // Vector 32 118 EFI_VECTOR_HANDOFF_DO_NOT_HOOK, 119 EFI_DEBUG_AGENT_GUID 120 }, 121 { 122 DEBUG_MAILBOX_VECTOR, // Vector 33 123 EFI_VECTOR_HANDOFF_DO_NOT_HOOK, 124 EFI_DEBUG_AGENT_GUID 125 }, 126 { 127 0, 128 EFI_VECTOR_HANDOFF_LAST_ENTRY, 129 { 0 } 130 } 131 }; 132 133 GLOBAL_REMOVE_IF_UNREFERENCED UINTN mVectorHandoffInfoCount = sizeof (mVectorHandoffInfoDebugAgent) / sizeof (EFI_VECTOR_HANDOFF_INFO); 134 135 /** 136 Calculate CRC16 for target data. 137 138 @param[in] Data The target data. 139 @param[in] DataSize The target data size. 140 @param[in] Crc Initial CRC. 141 142 @return UINT16 The CRC16 value. 143 144 **/ 145 UINT16 146 CalculateCrc16 ( 147 IN UINT8 *Data, 148 IN UINTN DataSize, 149 IN UINT16 Crc 150 ) 151 { 152 UINTN Index; 153 UINTN BitIndex; 154 155 for (Index = 0; Index < DataSize; Index++) { 156 Crc ^= (UINT16)Data[Index]; 157 for (BitIndex = 0; BitIndex < 8; BitIndex++) { 158 if ((Crc & 0x8000) != 0) { 159 Crc <<= 1; 160 Crc ^= 0x1021; 161 } else { 162 Crc <<= 1; 163 } 164 } 165 } 166 return Crc; 167 } 168 169 170 /** 171 Read IDT entry to check if IDT entries are setup by Debug Agent. 172 173 @retval TRUE IDT entries were setup by Debug Agent. 174 @retval FALSE IDT entries were not setup by Debug Agent. 26 175 27 176 **/ 28 177 BOOLEAN 29 Is HostConnected (178 IsDebugAgentInitialzed ( 30 179 VOID 31 180 ) 32 181 { 33 DEBUG_AGENT_MAILBOX *Mailbox; 34 35 Mailbox = GetMailboxPointer (); 36 37 if (Mailbox->DebugFlag.Bits.HostPresent == 1) { 182 UINTN InterruptHandler; 183 184 InterruptHandler = (UINTN) GetExceptionHandlerInIdtEntry (0); 185 if (InterruptHandler >= 4 && *(UINT32 *)(InterruptHandler - 4) == AGENT_HANDLER_SIGNATURE) { 38 186 return TRUE; 39 187 } else { … … 43 191 44 192 /** 45 Set HOST connect flag in Mailbox. 193 Find and report module image info to HOST. 194 195 @param[in] AlignSize Image aligned size. 46 196 47 197 **/ 48 198 VOID 49 SetHostConnectedFlag ( 50 VOID 51 ) 52 { 53 DEBUG_AGENT_MAILBOX *Mailbox; 54 55 Mailbox = GetMailboxPointer (); 56 57 Mailbox->DebugFlag.Bits.HostPresent = 1; 58 } 59 60 /** 61 Set debug flag of Debug Agent in Mailbox. 62 63 @param DebugFlag Debug Flag defined by transfer protocol. 199 FindAndReportModuleImageInfo ( 200 IN UINTN AlignSize 201 ) 202 { 203 UINTN Pe32Data; 204 EFI_IMAGE_DOS_HEADER *DosHdr; 205 EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr; 206 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; 207 208 // 209 // Find Image Base 210 // 211 Pe32Data = ((UINTN)mErrorMsgVersionAlert) & ~(AlignSize - 1); 212 while (Pe32Data != 0) { 213 DosHdr = (EFI_IMAGE_DOS_HEADER *) Pe32Data; 214 if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) { 215 // 216 // DOS image header is present, so read the PE header after the DOS image header. 217 // 218 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff)); 219 // 220 // Make sure PE header address does not overflow and is less than the initial address. 221 // 222 if (((UINTN)Hdr.Pe32 > Pe32Data) && ((UINTN)Hdr.Pe32 < (UINTN)mErrorMsgVersionAlert)) { 223 if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) { 224 // 225 // It's PE image. 226 // 227 break; 228 } 229 } 230 } else { 231 // 232 // DOS image header is not present, TE header is at the image base. 233 // 234 Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data; 235 if ((Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) && 236 ((Hdr.Te->Machine == IMAGE_FILE_MACHINE_I386) || Hdr.Te->Machine == IMAGE_FILE_MACHINE_X64)) { 237 // 238 // It's TE image, it TE header and Machine type match 239 // 240 break; 241 } 242 } 243 244 // 245 // Not found the image base, check the previous aligned address 246 // 247 Pe32Data -= AlignSize; 248 } 249 250 ImageContext.ImageAddress = Pe32Data; 251 ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress); 252 PeCoffLoaderRelocateImageExtraAction (&ImageContext); 253 } 254 255 /** 256 Trigger one software interrupt to debug agent to handle it. 257 258 @param[in] Signature Software interrupt signature. 259 260 **/ 261 VOID 262 TriggerSoftInterrupt ( 263 IN UINT32 Signature 264 ) 265 { 266 UINTN Dr0; 267 UINTN Dr1; 268 269 // 270 // Save Debug Register State 271 // 272 Dr0 = AsmReadDr0 (); 273 Dr1 = AsmReadDr1 (); 274 275 // 276 // DR0 = Signature 277 // 278 AsmWriteDr0 (SOFT_INTERRUPT_SIGNATURE); 279 AsmWriteDr1 (Signature); 280 281 // 282 // Do INT3 to communicate with HOST side 283 // 284 CpuBreakpoint (); 285 286 // 287 // Restore Debug Register State only when Host didn't change it inside exception handler. 288 // Dr registers can only be changed by setting the HW breakpoint. 289 // 290 AsmWriteDr0 (Dr0); 291 AsmWriteDr1 (Dr1); 292 293 } 294 295 /** 296 Caculate Mailbox checksum and update the checksum field. 297 298 @param[in] Mailbox Debug Agent Mailbox pointer. 299 300 **/ 301 VOID 302 UpdateMailboxChecksum ( 303 IN DEBUG_AGENT_MAILBOX *Mailbox 304 ) 305 { 306 Mailbox->CheckSum = CalculateCheckSum8 ((UINT8 *)Mailbox, sizeof (DEBUG_AGENT_MAILBOX) - 2); 307 } 308 309 /** 310 Verify Mailbox checksum. 311 312 If checksum error, print debug message and run init dead loop. 313 314 @param[in] Mailbox Debug Agent Mailbox pointer. 315 316 **/ 317 VOID 318 VerifyMailboxChecksum ( 319 IN DEBUG_AGENT_MAILBOX *Mailbox 320 ) 321 { 322 UINT8 CheckSum; 323 324 CheckSum = CalculateCheckSum8 ((UINT8 *) Mailbox, sizeof (DEBUG_AGENT_MAILBOX) - 2); 325 // 326 // The checksum updating process may be disturbed by hardware SMI, we need to check CheckSum field 327 // and ToBeCheckSum field to validate the mail box. 328 // 329 if (CheckSum != Mailbox->CheckSum && CheckSum != Mailbox->ToBeCheckSum) { 330 DEBUG ((EFI_D_ERROR, "DebugAgent: Mailbox checksum error, stack or heap crashed!\n")); 331 DEBUG ((EFI_D_ERROR, "DebugAgent: CheckSum = %x, Mailbox->CheckSum = %x, Mailbox->ToBeCheckSum = %x\n", CheckSum, Mailbox->CheckSum, Mailbox->ToBeCheckSum)); 332 CpuDeadLoop (); 333 } 334 } 335 336 /** 337 Update Mailbox content by index. 338 339 @param[in] Mailbox Debug Agent Mailbox pointer. 340 @param[in] Index Mailbox content index. 341 @param[in] Value Value to be set into Mailbox. 342 343 **/ 344 VOID 345 UpdateMailboxContent ( 346 IN DEBUG_AGENT_MAILBOX *Mailbox, 347 IN UINTN Index, 348 IN UINT64 Value 349 ) 350 { 351 AcquireMpSpinLock (&mDebugMpContext.MailboxSpinLock); 352 switch (Index) { 353 case DEBUG_MAILBOX_DEBUG_FLAG_INDEX: 354 Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->DebugFlag.Uint64, sizeof(UINT64)) 355 - CalculateSum8 ((UINT8 *)&Value, sizeof(UINT64)); 356 Mailbox->DebugFlag.Uint64 = Value; 357 break; 358 case DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX: 359 Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->DebugPortHandle, sizeof(UINTN)) 360 - CalculateSum8 ((UINT8 *)&Value, sizeof(UINTN)); 361 Mailbox->DebugPortHandle = (UINTN) Value; 362 break; 363 case DEBUG_MAILBOX_EXCEPTION_BUFFER_POINTER_INDEX: 364 Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->ExceptionBufferPointer, sizeof(UINTN)) 365 - CalculateSum8 ((UINT8 *)&Value, sizeof(UINTN)); 366 Mailbox->ExceptionBufferPointer = (UINTN) Value; 367 break; 368 case DEBUG_MAILBOX_LAST_ACK: 369 Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->LastAck, sizeof(UINT8)) 370 - CalculateSum8 ((UINT8 *)&Value, sizeof(UINT8)); 371 Mailbox->LastAck = (UINT8) Value; 372 break; 373 case DEBUG_MAILBOX_SEQUENCE_NO_INDEX: 374 Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->SequenceNo, sizeof(UINT8)) 375 - CalculateSum8 ((UINT8 *)&Value, sizeof(UINT8)); 376 Mailbox->SequenceNo = (UINT8) Value; 377 break; 378 case DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX: 379 Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->HostSequenceNo, sizeof(UINT8)) 380 - CalculateSum8 ((UINT8 *)&Value, sizeof(UINT8)); 381 Mailbox->HostSequenceNo = (UINT8) Value; 382 break; 383 } 384 UpdateMailboxChecksum (Mailbox); 385 ReleaseMpSpinLock (&mDebugMpContext.MailboxSpinLock); 386 } 387 /** 388 Set debug flag in mailbox. 389 390 @param[in] FlagMask Debug flag mask value. 391 @param[in] FlagValue Debug flag value. 64 392 65 393 **/ 66 394 VOID 67 395 SetDebugFlag ( 68 IN UINT32 DebugFlag 69 ) 70 { 71 DEBUG_AGENT_MAILBOX *Mailbox; 396 IN UINT64 FlagMask, 397 IN UINT32 FlagValue 398 ) 399 { 400 DEBUG_AGENT_MAILBOX *Mailbox; 401 UINT64 Data64; 72 402 73 403 Mailbox = GetMailboxPointer (); 74 75 if ((DebugFlag & SOFT_DEBUGGER_SETTING_SMM_ENTRY_BREAK) != 0) { 76 Mailbox->DebugFlag.Bits.BreakOnNextSmi = 1; 404 Data64 = (Mailbox->DebugFlag.Uint64 & ~FlagMask) | 405 (LShiftU64 ((UINT64)FlagValue, LowBitSet64 (FlagMask)) & FlagMask); 406 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_FLAG_INDEX, Data64); 407 } 408 409 /** 410 Get debug flag in mailbox. 411 412 @param[in] FlagMask Debug flag mask value. 413 414 @return Debug flag value. 415 416 **/ 417 UINT32 418 GetDebugFlag ( 419 IN UINT64 FlagMask 420 ) 421 { 422 DEBUG_AGENT_MAILBOX *Mailbox; 423 UINT32 DebugFlag; 424 425 Mailbox = GetMailboxPointer (); 426 DebugFlag = (UINT32) RShiftU64 (Mailbox->DebugFlag.Uint64 & FlagMask, LowBitSet64 (FlagMask)); 427 428 return DebugFlag; 429 } 430 431 /** 432 Send a debug message packet to the debug port. 433 434 @param[in] Buffer The debug message. 435 @param[in] Length The length of debug message. 436 437 **/ 438 VOID 439 SendDebugMsgPacket ( 440 IN CHAR8 *Buffer, 441 IN UINTN Length 442 ) 443 { 444 DEBUG_PACKET_HEADER DebugHeader; 445 DEBUG_PORT_HANDLE Handle; 446 447 Handle = GetDebugPortHandle(); 448 449 DebugHeader.StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL; 450 DebugHeader.Command = DEBUG_COMMAND_PRINT_MESSAGE; 451 DebugHeader.Length = sizeof (DEBUG_PACKET_HEADER) + (UINT8) Length; 452 DebugHeader.SequenceNo = 0xEE; 453 DebugHeader.Crc = 0; 454 DebugHeader.Crc = CalculateCrc16 ( 455 (UINT8 *)Buffer, Length, 456 CalculateCrc16 ((UINT8 *)&DebugHeader, sizeof (DEBUG_PACKET_HEADER), 0) 457 ); 458 459 DebugPortWriteBuffer (Handle, (UINT8 *)&DebugHeader, sizeof (DEBUG_PACKET_HEADER)); 460 DebugPortWriteBuffer (Handle, (UINT8 *)Buffer, Length); 461 } 462 463 /** 464 Prints a debug message to the debug port if the specified error level is enabled. 465 466 If any bit in ErrorLevel is also set in Mainbox, then print the message specified 467 by Format and the associated variable argument list to the debug port. 468 469 @param[in] ErrorLevel The error level of the debug message. 470 @param[in] Format Format string for the debug message to print. 471 @param[in] ... Variable argument list whose contents are accessed 472 based on the format string specified by Format. 473 474 **/ 475 VOID 476 EFIAPI 477 DebugAgentMsgPrint ( 478 IN UINT8 ErrorLevel, 479 IN CHAR8 *Format, 480 ... 481 ) 482 { 483 CHAR8 Buffer[DEBUG_DATA_MAXIMUM_REAL_DATA]; 484 VA_LIST Marker; 485 486 // 487 // Check driver debug mask value and global mask 488 // 489 if ((ErrorLevel & GetDebugFlag (DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL)) == 0) { 490 return; 491 } 492 493 // 494 // Convert the DEBUG() message to an ASCII String 495 // 496 VA_START (Marker, Format); 497 AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker); 498 VA_END (Marker); 499 500 SendDebugMsgPacket (Buffer, AsciiStrLen (Buffer)); 501 } 502 503 /** 504 Prints a debug message to the debug output device if the specified error level is enabled. 505 506 If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function 507 GetDebugPrintErrorLevel (), then print the message specified by Format and the 508 associated variable argument list to the debug output device. 509 510 If Format is NULL, then ASSERT(). 511 512 @param[in] ErrorLevel The error level of the debug message. 513 @param[in] IsSend Flag of debug message to declare that the data is being sent or being received. 514 @param[in] Data Variable argument list whose contents are accessed 515 @param[in] Length based on the format string specified by Format. 516 517 **/ 518 VOID 519 EFIAPI 520 DebugAgentDataMsgPrint ( 521 IN UINT8 ErrorLevel, 522 IN BOOLEAN IsSend, 523 IN UINT8 *Data, 524 IN UINT8 Length 525 ) 526 { 527 CHAR8 Buffer[DEBUG_DATA_MAXIMUM_REAL_DATA]; 528 CHAR8 *DestBuffer; 529 UINTN Index; 530 531 // 532 // Check driver debug mask value and global mask 533 // 534 if ((ErrorLevel & GetDebugFlag (DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL)) == 0) { 535 return; 536 } 537 538 DestBuffer = Buffer; 539 if (IsSend) { 540 DestBuffer += AsciiSPrint (DestBuffer, DEBUG_DATA_MAXIMUM_REAL_DATA, "Sent data [ "); 77 541 } else { 78 Mailbox->DebugFlag.Bits.BreakOnNextSmi = 0; 79 } 542 DestBuffer += AsciiSPrint (DestBuffer, DEBUG_DATA_MAXIMUM_REAL_DATA, "Received data [ "); 543 } 544 545 Index = 0; 546 while (TRUE) { 547 if (DestBuffer - Buffer > DEBUG_DATA_MAXIMUM_REAL_DATA - 6) { 548 // 549 // If there was no enough space in buffer, send out the debug message, 550 // reserving 6 bytes is for the last data and end characters "]\n". 551 // 552 SendDebugMsgPacket (Buffer, DestBuffer - Buffer); 553 DestBuffer = Buffer; 554 } 555 DestBuffer += AsciiSPrint (DestBuffer, DEBUG_DATA_MAXIMUM_REAL_DATA - (DestBuffer - Buffer), "%02x ", Data[Index]); 556 Index ++; 557 if (Index >= Length) { 558 // 559 // The last character of debug message has been foramtted in buffer 560 // 561 DestBuffer += AsciiSPrint(DestBuffer, DEBUG_DATA_MAXIMUM_REAL_DATA - (DestBuffer - Buffer), "]\n"); 562 SendDebugMsgPacket (Buffer, DestBuffer - Buffer); 563 break; 564 } 565 } 566 } 567 568 /** 569 Read remaing debug packet except for the start symbol 570 571 @param[in] Handle Pointer to Debug Port handle. 572 @param[in, out] DebugHeader Debug header buffer including start symbol. 573 574 @retval EFI_SUCCESS Read the symbol in BreakSymbol. 575 @retval EFI_CRC_ERROR CRC check fail. 576 @retval EFI_TIMEOUT Timeout occurs when reading debug packet. 577 @retval EFI_DEVICE_ERROR Receive the old or responsed packet. 578 579 **/ 580 EFI_STATUS 581 ReadRemainingBreakPacket ( 582 IN DEBUG_PORT_HANDLE Handle, 583 IN OUT DEBUG_PACKET_HEADER *DebugHeader 584 ) 585 { 586 UINT16 Crc; 587 DEBUG_AGENT_MAILBOX *Mailbox; 588 589 // 590 // Has received start symbol, try to read the rest part 591 // 592 if (DebugPortReadBuffer (Handle, (UINT8 *)DebugHeader + OFFSET_OF (DEBUG_PACKET_HEADER, Command), sizeof (DEBUG_PACKET_HEADER) - OFFSET_OF (DEBUG_PACKET_HEADER, Command), READ_PACKET_TIMEOUT) == 0) { 593 // 594 // Timeout occur, exit 595 // 596 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "Timeout in Debug Timer interrupt\n"); 597 return EFI_TIMEOUT; 598 } 599 600 Crc = DebugHeader->Crc; 601 DebugHeader->Crc = 0; 602 if (CalculateCrc16 ((UINT8 *)DebugHeader, DebugHeader->Length, 0) != Crc) { 603 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "Debug Timer CRC (%x) against (%x)\n", Crc, CalculateCrc16 ((UINT8 *) &DebugHeader, DebugHeader->Length, 0)); 604 DebugAgentDataMsgPrint (DEBUG_AGENT_VERBOSE, FALSE, (UINT8 *)DebugHeader, DebugHeader->Length); 605 return EFI_CRC_ERROR; 606 } 607 Mailbox = GetMailboxPointer(); 608 if (((DebugHeader->Command & DEBUG_COMMAND_RESPONSE) == 0) && 609 (DebugHeader->SequenceNo == (UINT8) (Mailbox->HostSequenceNo + 1))) { 610 // 611 // Only updagte HostSequenceNo for new command packet 612 // 613 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX, DebugHeader->SequenceNo); 614 return EFI_SUCCESS; 615 } else { 616 // 617 // If one old command or response packet received, skip it 618 // 619 return EFI_DEVICE_ERROR; 620 } 621 } 622 623 /** 624 Check if HOST is attached based on Mailbox. 625 626 @retval TRUE HOST is attached. 627 @retval FALSE HOST is not attached. 628 629 **/ 630 BOOLEAN 631 IsHostAttached ( 632 VOID 633 ) 634 { 635 return (BOOLEAN) (GetDebugFlag (DEBUG_AGENT_FLAG_HOST_ATTACHED) == 1); 636 } 637 638 /** 639 Set HOST connect flag in Mailbox. 640 641 @param[in] Attached Attach status. 642 643 **/ 644 VOID 645 SetHostAttached ( 646 IN BOOLEAN Attached 647 ) 648 { 649 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Attach status is %d\n", Attached); 650 SetDebugFlag (DEBUG_AGENT_FLAG_HOST_ATTACHED, (UINT32)Attached); 651 } 652 653 /** 654 Set debug setting of Debug Agent in Mailbox. 655 656 @param DebugSetting Pointer to Debug Setting defined by transfer protocol. 657 658 @retval RETURN_SUCCESS The setting is set successfully. 659 @retval RETURN_UNSUPPORTED The Key value is not supported. 660 661 **/ 662 RETURN_STATUS 663 SetDebugSetting ( 664 IN DEBUG_DATA_SET_DEBUG_SETTING *DebugSetting 665 ) 666 { 667 RETURN_STATUS Status; 668 669 Status = RETURN_SUCCESS; 670 switch (DebugSetting->Key) { 671 case DEBUG_AGENT_SETTING_SMM_ENTRY_BREAK: 672 SetDebugFlag (DEBUG_AGENT_FLAG_BREAK_ON_NEXT_SMI, DebugSetting->Value); 673 break; 674 case DEBUG_AGENT_SETTING_PRINT_ERROR_LEVEL: 675 SetDebugFlag (DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL, DebugSetting->Value); 676 break; 677 case DEBUG_AGENT_SETTING_BOOT_SCRIPT_ENTRY_BREAK: 678 SetDebugFlag (DEBUG_AGENT_FLAG_BREAK_BOOT_SCRIPT, DebugSetting->Value); 679 break; 680 default: 681 Status = RETURN_UNSUPPORTED; 682 } 683 return Status; 80 684 } 81 685 … … 144 748 // Enable Gx, Lx 145 749 // 146 Dr7Value |= 0x3 << (RegisterIndex * 2);750 Dr7Value |= (UINTN) (0x3 << (RegisterIndex * 2)); 147 751 // 148 752 // Set RWx and Lenx 149 753 // 150 Dr7Value &= ~(0xf0000 << (RegisterIndex * 4));151 Dr7Value |= ( SetHwBreakpoint->Type.Length | SetHwBreakpoint->Type.Access) << (RegisterIndex * 4);754 Dr7Value &= (UINTN) (~(0xf << (16 + RegisterIndex * 4))); 755 Dr7Value |= (UINTN) ((SetHwBreakpoint->Type.Length << 2) | SetHwBreakpoint->Type.Access) << (16 + RegisterIndex * 4); 152 756 // 153 757 // Enable GE, LE … … 173 777 if ((ClearHwBreakpoint->IndexMask & BIT0) != 0) { 174 778 CpuContext->Dr0 = 0; 175 CpuContext->Dr7 &= ~(0x3 << 0);779 CpuContext->Dr7 &= (UINTN)(~(0x3 << 0)); 176 780 } 177 781 if ((ClearHwBreakpoint->IndexMask & BIT1) != 0) { 178 782 CpuContext->Dr1 = 0; 179 CpuContext->Dr7 &= ~(0x3 << 2);783 CpuContext->Dr7 &= (UINTN)(~(0x3 << 2)); 180 784 } 181 785 if ((ClearHwBreakpoint->IndexMask & BIT2) != 0) { 182 786 CpuContext->Dr2 = 0; 183 CpuContext->Dr7 &= ~(0x3 << 4);787 CpuContext->Dr7 &= (UINTN)(~(0x3 << 4)); 184 788 } 185 789 if ((ClearHwBreakpoint->IndexMask & BIT3) != 0) { 186 790 CpuContext->Dr3 = 0; 187 CpuContext->Dr7 &= ~(0x3 << 6); 188 } 791 CpuContext->Dr7 &= (UINTN)(~(0x3 << 6)); 792 } 793 } 794 795 796 /** 797 Return the offset of FP / MMX / XMM registers in the FPU saved state by register index. 798 799 @param[in] Index Register index. 800 @param[out] Width Register width returned. 801 802 @return Offset in the FPU Save State. 803 804 **/ 805 UINT16 806 ArchReadFxStatOffset ( 807 IN UINT8 Index, 808 OUT UINT8 *Width 809 ) 810 { 811 if (Index < SOFT_DEBUGGER_REGISTER_ST0) { 812 switch (Index) { 813 case SOFT_DEBUGGER_REGISTER_FP_FCW: 814 *Width = (UINT8) sizeof (UINT16); 815 return OFFSET_OF(DEBUG_DATA_FX_SAVE_STATE, Fcw); 816 817 case SOFT_DEBUGGER_REGISTER_FP_FSW: 818 *Width = (UINT8) sizeof (UINT16); 819 return OFFSET_OF(DEBUG_DATA_FX_SAVE_STATE, Fsw); 820 821 case SOFT_DEBUGGER_REGISTER_FP_FTW: 822 *Width = (UINT8) sizeof (UINT16); 823 return OFFSET_OF(DEBUG_DATA_FX_SAVE_STATE, Ftw); 824 825 case SOFT_DEBUGGER_REGISTER_FP_OPCODE: 826 *Width = (UINT8) sizeof (UINT16); 827 return OFFSET_OF(DEBUG_DATA_FX_SAVE_STATE, Opcode); 828 829 case SOFT_DEBUGGER_REGISTER_FP_EIP: 830 *Width = (UINT8) sizeof (UINT32); 831 return OFFSET_OF(DEBUG_DATA_FX_SAVE_STATE, Eip); 832 833 case SOFT_DEBUGGER_REGISTER_FP_CS: 834 *Width = (UINT8) sizeof (UINT16); 835 return OFFSET_OF(DEBUG_DATA_FX_SAVE_STATE, Cs); 836 837 case SOFT_DEBUGGER_REGISTER_FP_DATAOFFSET: 838 *Width = (UINT8) sizeof (UINT32); 839 return OFFSET_OF(DEBUG_DATA_FX_SAVE_STATE, DataOffset); 840 841 case SOFT_DEBUGGER_REGISTER_FP_DS: 842 *Width = (UINT8) sizeof (UINT16); 843 return OFFSET_OF(DEBUG_DATA_FX_SAVE_STATE, Ds); 844 845 case SOFT_DEBUGGER_REGISTER_FP_MXCSR: 846 *Width = (UINT8) sizeof (UINT32); 847 return OFFSET_OF(DEBUG_DATA_FX_SAVE_STATE, Mxcsr); 848 849 case SOFT_DEBUGGER_REGISTER_FP_MXCSR_MASK: 850 *Width = (UINT8) sizeof (UINT32); 851 return OFFSET_OF(DEBUG_DATA_FX_SAVE_STATE, Mxcsr_Mask); 852 } 853 } 854 855 if (Index <= SOFT_DEBUGGER_REGISTER_ST7) { 856 *Width = 10; 857 } else if (Index <= SOFT_DEBUGGER_REGISTER_XMM15) { 858 *Width = 16; 859 } else { 860 // 861 // MMX register 862 // 863 *Width = 8; 864 Index -= SOFT_DEBUGGER_REGISTER_MM0 - SOFT_DEBUGGER_REGISTER_ST0; 865 } 866 867 return OFFSET_OF (DEBUG_DATA_FX_SAVE_STATE, St0Mm0) + (Index - SOFT_DEBUGGER_REGISTER_ST0) * 16; 868 } 869 870 /** 871 Return the pointer of the register value in the CPU saved context. 872 873 @param[in] CpuContext Pointer to saved CPU context. 874 @param[in] Index Register index value. 875 @param[out] Width Data width to read. 876 877 @return The pointer in the CPU saved context. 878 879 **/ 880 UINT8 * 881 ArchReadRegisterBuffer ( 882 IN DEBUG_CPU_CONTEXT *CpuContext, 883 IN UINT8 Index, 884 OUT UINT8 *Width 885 ) 886 { 887 UINT8 *Buffer; 888 889 if (Index < SOFT_DEBUGGER_REGISTER_FP_BASE) { 890 Buffer = (UINT8 *) CpuContext + OFFSET_OF (DEBUG_CPU_CONTEXT, Dr0) + Index * sizeof (UINTN); 891 *Width = (UINT8) sizeof (UINTN); 892 } else { 893 // 894 // FPU/MMX/XMM registers 895 // 896 Buffer = (UINT8 *) CpuContext + OFFSET_OF (DEBUG_CPU_CONTEXT, FxSaveState) + ArchReadFxStatOffset (Index, Width); 897 } 898 899 return Buffer; 900 } 901 902 /** 903 Send the packet without data to HOST. 904 905 @param[in] CommandType Type of Command. 906 @param[in] SequenceNo Sequence number. 907 908 **/ 909 VOID 910 SendPacketWithoutData ( 911 IN UINT8 CommandType, 912 IN UINT8 SequenceNo 913 ) 914 { 915 DEBUG_PACKET_HEADER DebugHeader; 916 DEBUG_PORT_HANDLE Handle; 917 918 Handle = GetDebugPortHandle(); 919 920 DebugHeader.StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL; 921 DebugHeader.Command = CommandType; 922 DebugHeader.Length = sizeof (DEBUG_PACKET_HEADER); 923 DebugHeader.SequenceNo = SequenceNo; 924 DebugHeader.Crc = 0; 925 DebugHeader.Crc = CalculateCrc16 ((UINT8 *)&DebugHeader, sizeof (DEBUG_PACKET_HEADER), 0); 926 927 DebugAgentDataMsgPrint (DEBUG_AGENT_VERBOSE, TRUE, (UINT8 *) &DebugHeader, DebugHeader.Length); 928 DebugPortWriteBuffer (Handle, (UINT8 *) &DebugHeader, DebugHeader.Length); 189 929 } 190 930 … … 200 940 ) 201 941 { 202 DEBUG_COMMAND_HEADER DebugCommonHeader; 203 DEBUG_PORT_HANDLE Handle; 942 UINT8 SequenceNo; 943 DEBUG_AGENT_MAILBOX *Mailbox; 944 945 if (AckCommand != DEBUG_COMMAND_OK) { 946 // 947 // This is not ACK OK packet 948 // 949 DebugAgentMsgPrint (DEBUG_AGENT_ERROR, "Send ACK(%d)\n", AckCommand); 950 } 951 Mailbox = GetMailboxPointer(); 952 SequenceNo = Mailbox->HostSequenceNo; 953 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "SendAckPacket: SequenceNo = %x\n", SequenceNo); 954 SendPacketWithoutData (AckCommand, SequenceNo); 955 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_LAST_ACK, AckCommand); 956 } 957 958 /** 959 Receive valid packet from HOST. 960 961 @param[out] InputPacket Buffer to receive packet. 962 @param[out] BreakReceived TRUE means break-in symbol received. 963 FALSE means break-in symbol not received. 964 @param[out] IncompatibilityFlag If IncompatibilityFlag is not NULL, return 965 TRUE: Compatible packet received. 966 FALSE: Incompatible packet received. 967 @param[in] Timeout Time out value to wait for acknowlege from HOST. 968 The unit is microsecond. 969 @param[in] SkipStartSymbol TRUE: Skip time out when reading start symbol. 970 FALSE: Does not Skip time out when reading start symbol. 971 972 @retval RETURN_SUCCESS A valid package was reveived in InputPacket. 973 @retval RETURN_TIMEOUT Timeout occurs. 974 975 **/ 976 RETURN_STATUS 977 ReceivePacket ( 978 OUT UINT8 *InputPacket, 979 OUT BOOLEAN *BreakReceived, 980 OUT BOOLEAN *IncompatibilityFlag, OPTIONAL 981 IN UINTN Timeout, 982 IN BOOLEAN SkipStartSymbol 983 ) 984 { 985 DEBUG_PACKET_HEADER *DebugHeader; 986 UINTN Received; 987 DEBUG_PORT_HANDLE Handle; 988 UINT16 Crc; 989 UINTN TimeoutForStartSymbol; 204 990 205 991 Handle = GetDebugPortHandle(); 206 207 DebugCommonHeader.StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL; 208 DebugCommonHeader.Command = AckCommand; 209 DebugCommonHeader.DataLength = 0; 210 211 DebugPortWriteBuffer (Handle, (UINT8 *) &DebugCommonHeader, sizeof (DEBUG_COMMAND_HEADER)); 212 } 213 214 /** 215 Receive acknowledge packet from HOST in specified time. 216 217 @param[out] Ack Returned acknowlege type from HOST. 218 @param[in] Timeout Time out value to wait for acknowlege from HOST. 219 The unit is microsecond. 220 @param[out] BreakReceived If BreakReceived is not NULL, 221 TRUE is retured if break-in symbol received. 222 FALSE is retured if break-in symbol not received. 992 if (SkipStartSymbol) { 993 TimeoutForStartSymbol = 0; 994 } else { 995 TimeoutForStartSymbol = Timeout; 996 } 997 998 DebugHeader = (DEBUG_PACKET_HEADER *) InputPacket; 999 while (TRUE) { 1000 // 1001 // Find the valid start symbol 1002 // 1003 Received = DebugPortReadBuffer (Handle, &DebugHeader->StartSymbol, sizeof (DebugHeader->StartSymbol), TimeoutForStartSymbol); 1004 if (Received < sizeof (DebugHeader->StartSymbol)) { 1005 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "DebugPortReadBuffer(StartSymbol) timeout\n"); 1006 return RETURN_TIMEOUT; 1007 } 1008 1009 if (DebugHeader->StartSymbol != DEBUG_STARTING_SYMBOL_NORMAL) { 1010 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "Invalid start symbol received [%02x]\n", DebugHeader->StartSymbol); 1011 continue; 1012 } 1013 1014 // 1015 // Read Package header till field Length 1016 // 1017 Received = DebugPortReadBuffer ( 1018 Handle, 1019 (UINT8 *)DebugHeader + OFFSET_OF (DEBUG_PACKET_HEADER, Command), 1020 OFFSET_OF (DEBUG_PACKET_HEADER, Length) + sizeof (DebugHeader->Length) - sizeof (DebugHeader->StartSymbol), 1021 Timeout 1022 ); 1023 if (Received == 0) { 1024 DebugAgentMsgPrint (DEBUG_AGENT_ERROR, "DebugPortReadBuffer(Command) timeout\n"); 1025 return RETURN_TIMEOUT; 1026 } 1027 if (DebugHeader->Length < sizeof (DEBUG_PACKET_HEADER)) { 1028 if (IncompatibilityFlag != NULL) { 1029 // 1030 // This is one old version debug packet format, set Incompatibility flag 1031 // 1032 *IncompatibilityFlag = TRUE; 1033 } else { 1034 // 1035 // Skip the bad small packet 1036 // 1037 continue; 1038 } 1039 } else { 1040 // 1041 // Read the payload data include the CRC field 1042 // 1043 Received = DebugPortReadBuffer (Handle, &DebugHeader->SequenceNo, (UINT8) (DebugHeader->Length - OFFSET_OF (DEBUG_PACKET_HEADER, SequenceNo)), Timeout); 1044 if (Received == 0) { 1045 DebugAgentMsgPrint (DEBUG_AGENT_ERROR, "DebugPortReadBuffer(SequenceNo) timeout\n"); 1046 return RETURN_TIMEOUT; 1047 } 1048 // 1049 // Calculate the CRC of Debug Packet 1050 // 1051 Crc = DebugHeader->Crc; 1052 DebugHeader->Crc = 0; 1053 if (Crc == CalculateCrc16 ((UINT8 *) DebugHeader, DebugHeader->Length, 0)) { 1054 break; 1055 } 1056 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "CRC Error (received CRC is %x)\n", Crc); 1057 DebugAgentDataMsgPrint (DEBUG_AGENT_VERBOSE, FALSE, (UINT8 *) DebugHeader, DebugHeader->Length); 1058 } 1059 } 1060 1061 DebugAgentDataMsgPrint (DEBUG_AGENT_VERBOSE, FALSE, (UINT8 *) DebugHeader, DebugHeader->Length); 1062 1063 return RETURN_SUCCESS; 1064 } 1065 1066 /** 1067 Receive acknowledge packet OK from HOST in specified time. 1068 1069 @param[in] Command The command type issued by TARGET. 1070 @param[in] Timeout Time out value to wait for acknowlege from HOST. 1071 The unit is microsecond. 1072 @param[out] BreakReceived If BreakReceived is not NULL, 1073 TRUE is retured if break-in symbol received. 1074 FALSE is retured if break-in symbol not received. 1075 @param[out] IncompatibilityFlag If IncompatibilityFlag is not NULL, return 1076 TRUE: Compatible packet received. 1077 FALSE: Incompatible packet received. 223 1078 224 1079 @retval RETRUEN_SUCCESS Succeed to receive acknowlege packet from HOST, … … 228 1083 **/ 229 1084 RETURN_STATUS 230 ReceiveAckPacket ( 231 OUT UINT8 *Ack, 232 IN UINTN Timeout, 233 OUT BOOLEAN *BreakReceived OPTIONAL 234 ) 235 { 236 DEBUG_COMMAND_HEADER DebugCommonHeader; 237 DEBUG_PORT_HANDLE Handle; 238 239 Handle = GetDebugPortHandle(); 240 241 while (TRUE) { 242 if (DebugPortReadBuffer (Handle, (UINT8 *) &DebugCommonHeader.StartSymbol, 1, Timeout) == 0) { 243 return RETURN_TIMEOUT; 244 } 245 if (DebugCommonHeader.StartSymbol == DEBUG_STARTING_SYMBOL_BREAK) { 246 if (BreakReceived != NULL) { 247 SendAckPacket (DEBUG_COMMAND_HALT_DEFERRED); 248 *BreakReceived = TRUE; 249 } 250 } 251 if (DebugCommonHeader.StartSymbol == DEBUG_STARTING_SYMBOL_NORMAL) { 252 break; 253 } 254 } 255 if (DebugPortReadBuffer (Handle, (UINT8 *)&DebugCommonHeader.Command, sizeof (DEBUG_COMMAND_HEADER) - 1, Timeout) == 0) { 256 return RETURN_TIMEOUT; 257 } 258 259 *Ack = DebugCommonHeader.Command; 260 return RETURN_SUCCESS; 261 } 262 263 /** 264 Receive acknowledge packet OK from HOST in specified time. 265 266 @param[in] Timeout Time out value to wait for acknowlege from HOST. 267 The unit is microsecond. 268 @param[out] BreakReceived If BreakReceived is not NULL, 269 TRUE is retured if break-in symbol received. 270 FALSE is retured if break-in symbol not received. 271 272 @retval RETRUEN_SUCCESS Succeed to receive acknowlege packet from HOST, 273 the type of acknowlege packet saved in Ack. 274 @retval RETURN_TIMEOUT Specified timeout value was up. 275 276 **/ 277 RETURN_STATUS 278 WaitForAckPacketOK ( 279 IN UINTN Timeout, 280 OUT BOOLEAN *BreakReceived OPTIONAL 281 ) 282 { 283 RETURN_STATUS Status; 284 UINT8 Ack; 285 286 while (TRUE) { 287 Status = ReceiveAckPacket (&Ack, Timeout, BreakReceived); 288 if ((Status == RETURN_SUCCESS && Ack == DEBUG_COMMAND_OK) || 289 Status == RETURN_TIMEOUT) { 290 break; 291 } 292 } 293 1085 SendCommandAndWaitForAckOK ( 1086 IN UINT8 Command, 1087 IN UINTN Timeout, 1088 OUT BOOLEAN *BreakReceived, OPTIONAL 1089 OUT BOOLEAN *IncompatibilityFlag OPTIONAL 1090 ) 1091 { 1092 RETURN_STATUS Status; 1093 UINT8 InputPacketBuffer[DEBUG_DATA_UPPER_LIMIT]; 1094 DEBUG_PACKET_HEADER *DebugHeader; 1095 UINT8 SequenceNo; 1096 UINT8 HostSequenceNo; 1097 UINT8 RetryCount; 1098 1099 RetryCount = 3; 1100 DebugHeader = (DEBUG_PACKET_HEADER *) InputPacketBuffer; 1101 Status = RETURN_TIMEOUT; 1102 while (RetryCount > 0) { 1103 SequenceNo = GetMailboxPointer()->SequenceNo; 1104 HostSequenceNo = GetMailboxPointer()->HostSequenceNo; 1105 SendPacketWithoutData (Command, SequenceNo); 1106 Status = ReceivePacket ((UINT8 *) DebugHeader, BreakReceived, IncompatibilityFlag, Timeout, FALSE); 1107 if (Status == RETURN_TIMEOUT) { 1108 if (Command == DEBUG_COMMAND_INIT_BREAK) { 1109 RetryCount--; 1110 } else { 1111 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "TARGET: Timeout when waiting for ACK packet.\n"); 1112 } 1113 continue; 1114 } 1115 ASSERT_EFI_ERROR (Status); 1116 // 1117 // Status == RETURN_SUCCESS 1118 // 1119 if (DebugHeader->Command == DEBUG_COMMAND_OK && DebugHeader->SequenceNo == SequenceNo) { 1120 // 1121 // Received Ack OK 1122 // 1123 UpdateMailboxContent (GetMailboxPointer(), DEBUG_MAILBOX_SEQUENCE_NO_INDEX, ++SequenceNo); 1124 return Status; 1125 } 1126 if (DebugHeader->Command == DEBUG_COMMAND_GO && (DebugHeader->SequenceNo == HostSequenceNo || Command == DEBUG_COMMAND_INIT_BREAK)) { 1127 // 1128 // Received Old GO 1129 // 1130 if (Command == DEBUG_COMMAND_INIT_BREAK) { 1131 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "TARGET: Receive GO() in last boot\n"); 1132 } 1133 SendPacketWithoutData (DEBUG_COMMAND_OK, DebugHeader->SequenceNo); 1134 } 1135 } 1136 1137 ASSERT (Command == DEBUG_COMMAND_INIT_BREAK); 294 1138 return Status; 295 }296 297 /**298 Receive valid packet from HOST.299 300 @param[out] InputPacket Buffer to receive packet.301 @param[out] BreakReceived TRUE means break-in symbol received.302 FALSE means break-in symbol not received.303 304 @retval RETURN_SUCCESS A valid package was reveived in InputPacket.305 @retval RETURN_NOT_READY No valid start symbol received.306 @retval RETURN_TIMEOUT Timeout occurs.307 308 **/309 RETURN_STATUS310 ReceivePacket (311 OUT UINT8 *InputPacket,312 OUT BOOLEAN *BreakReceived313 )314 {315 DEBUG_COMMAND_HEADER *DebugHeader;316 UINTN Received;317 DEBUG_PORT_HANDLE Handle;318 319 Handle = GetDebugPortHandle();320 //321 // Find the valid start symbol322 //323 DebugPortReadBuffer (Handle, InputPacket, 1, 0);324 325 if (*InputPacket == DEBUG_STARTING_SYMBOL_BREAK) {326 *BreakReceived = TRUE;327 SendAckPacket (DEBUG_COMMAND_HALT_DEFERRED);328 }329 330 if (*InputPacket != DEBUG_STARTING_SYMBOL_NORMAL) {331 return RETURN_NOT_READY;332 }333 334 //335 // Read Package header336 //337 Received = DebugPortReadBuffer (Handle, InputPacket + 1, sizeof(DEBUG_COMMAND_HEADER_NO_START_SYMBOL), 0);338 if (Received == 0) {339 return RETURN_TIMEOUT;340 }341 342 DebugHeader = (DEBUG_COMMAND_HEADER *) InputPacket;343 //344 // Read the payload if has345 //346 if (DebugHeader->DataLength > 0 && DebugHeader->DataLength < (DEBUG_DATA_MAXIMUM_REAL_DATA - sizeof(DEBUG_COMMAND_HEADER))) {347 InputPacket = InputPacket + 1 + Received;348 Received = DebugPortReadBuffer (Handle, InputPacket, DebugHeader->DataLength, 0);349 350 if (Received == 0) {351 return RETURN_TIMEOUT;352 }353 }354 355 return RETURN_SUCCESS;356 1139 } 357 1140 … … 407 1190 if (CpuContext->Dr3 == IO_PORT_BREAKPOINT_ADDRESS) { 408 1191 409 Cause = (UINT8) ((CpuContext->Dr0 == IMAGE_LOAD_SIGNATURE) ? 1192 Cause = (UINT8) ((CpuContext->Dr0 == IMAGE_LOAD_SIGNATURE) ? 410 1193 DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD : DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD); 411 1194 } … … 413 1196 414 1197 case SOFT_INTERRUPT_SIGNATURE: 415 1198 416 1199 if (CpuContext->Dr1 == MEMORY_READY_SIGNATURE) { 417 1200 Cause = DEBUG_DATA_BREAK_CAUSE_MEMORY_READY; … … 436 1219 default: 437 1220 if (Vector < 20) { 438 Cause = DEBUG_DATA_BREAK_CAUSE_EXCEPTION; 1221 if (GetDebugFlag (DEBUG_AGENT_FLAG_STEPPING) == 1) { 1222 // 1223 // If stepping command is executing 1224 // 1225 Cause = DEBUG_DATA_BREAK_CAUSE_STEPPING; 1226 } else { 1227 Cause = DEBUG_DATA_BREAK_CAUSE_EXCEPTION; 1228 } 439 1229 } 440 1230 break; … … 445 1235 446 1236 /** 1237 Copy memory from source to destination with specified width. 1238 1239 @param[out] Dest A pointer to the destination buffer of the memory copy. 1240 @param[in] Src A pointer to the source buffer of the memory copy. 1241 @param[in] Count The number of data with specified width to copy from source to destination. 1242 @param[in] Width Data width in byte. 1243 1244 **/ 1245 VOID 1246 CopyMemByWidth ( 1247 OUT UINT8 *Dest, 1248 IN UINT8 *Src, 1249 IN UINT16 Count, 1250 IN UINT8 Width 1251 ) 1252 { 1253 UINT8 *Destination; 1254 UINT8 *Source; 1255 INT8 Step; 1256 1257 if (Src > Dest) { 1258 Destination = Dest; 1259 Source = Src; 1260 Step = Width; 1261 } else { 1262 // 1263 // Copy memory from tail to avoid memory overlap 1264 // 1265 Destination = Dest + (Count - 1) * Width; 1266 Source = Src + (Count - 1) * Width; 1267 Step = -Width; 1268 } 1269 1270 while (Count-- != 0) { 1271 switch (Width) { 1272 case 1: 1273 *(UINT8 *) Destination = MmioRead8 ((UINTN) Source); 1274 break; 1275 case 2: 1276 *(UINT16 *) Destination = MmioRead16 ((UINTN) Source); 1277 break; 1278 case 4: 1279 *(UINT32 *) Destination = MmioRead32 ((UINTN) Source); 1280 break; 1281 case 8: 1282 *(UINT64 *) Destination = MmioRead64 ((UINTN) Source); 1283 break; 1284 default: 1285 ASSERT (FALSE); 1286 } 1287 Source += Step; 1288 Destination += Step; 1289 } 1290 } 1291 1292 /** 1293 Read memory with speicifed width and send packet with response data to HOST. 1294 1295 @param[in] Data Pointer to response data buffer. 1296 @param[in] Count The number of data with specified Width. 1297 @param[in] Width Data width in byte. 1298 1299 @retval RETURN_SUCCESS Response data was sent successfully. 1300 1301 **/ 1302 RETURN_STATUS 1303 ReadMemoryAndSendResponsePacket ( 1304 IN UINT8 *Data, 1305 IN UINT16 Count, 1306 IN UINT8 Width 1307 ) 1308 { 1309 RETURN_STATUS Status; 1310 DEBUG_PACKET_HEADER *DebugHeader; 1311 BOOLEAN LastPacket; 1312 DEBUG_PACKET_HEADER *AckDebugHeader; 1313 UINT8 DebugPacket[DEBUG_DATA_UPPER_LIMIT + sizeof (UINT64) - 1]; 1314 UINT8 InputPacketBuffer[DEBUG_DATA_UPPER_LIMIT]; 1315 DEBUG_PORT_HANDLE Handle; 1316 UINT8 SequenceNo; 1317 UINTN RemainingDataSize; 1318 UINTN CurrentDataSize; 1319 1320 Handle = GetDebugPortHandle(); 1321 1322 // 1323 // Data is appended end of Debug Packet header, make sure data address 1324 // in Debug Packet 8-byte alignment always 1325 // 1326 DebugHeader = (DEBUG_PACKET_HEADER *) (ALIGN_VALUE ((UINTN)&DebugPacket + sizeof (DEBUG_PACKET_HEADER), sizeof (UINT64)) 1327 - sizeof (DEBUG_PACKET_HEADER)); 1328 DebugHeader->StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL; 1329 1330 RemainingDataSize = Count * Width; 1331 while (TRUE) { 1332 SequenceNo = GetMailboxPointer()->HostSequenceNo; 1333 if (RemainingDataSize <= DEBUG_DATA_MAXIMUM_REAL_DATA) { 1334 // 1335 // If the remaining data is less one real packet size, this is the last data packet 1336 // 1337 CurrentDataSize = RemainingDataSize; 1338 LastPacket = TRUE; 1339 DebugHeader->Command = DEBUG_COMMAND_OK; 1340 } else { 1341 // 1342 // Data is too larger to be sent in one packet, calculate the actual data size could 1343 // be sent in one Maximum data packet 1344 // 1345 CurrentDataSize = (DEBUG_DATA_MAXIMUM_REAL_DATA / Width) * Width; 1346 LastPacket = FALSE; 1347 DebugHeader->Command = DEBUG_COMMAND_IN_PROGRESS; 1348 } 1349 // 1350 // Construct the rest Debug header 1351 // 1352 DebugHeader->Length = (UINT8)(CurrentDataSize + sizeof (DEBUG_PACKET_HEADER)); 1353 DebugHeader->SequenceNo = SequenceNo; 1354 DebugHeader->Crc = 0; 1355 CopyMemByWidth ((UINT8 *)(DebugHeader + 1), Data, (UINT16) CurrentDataSize / Width, Width); 1356 // 1357 // Calculate and fill the checksum, DebugHeader->Crc should be 0 before invoking CalculateCrc16 () 1358 // 1359 DebugHeader->Crc = CalculateCrc16 ((UINT8 *) DebugHeader, DebugHeader->Length, 0); 1360 1361 DebugAgentDataMsgPrint (DEBUG_AGENT_VERBOSE, TRUE, (UINT8 *) DebugHeader, DebugHeader->Length); 1362 1363 DebugPortWriteBuffer (Handle, (UINT8 *) DebugHeader, DebugHeader->Length); 1364 1365 while (TRUE) { 1366 Status = ReceivePacket (InputPacketBuffer, NULL, NULL, READ_PACKET_TIMEOUT, FALSE); 1367 if (Status == RETURN_TIMEOUT) { 1368 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "TARGET: Timeout in SendDataResponsePacket()\n"); 1369 break; 1370 } 1371 AckDebugHeader = (DEBUG_PACKET_HEADER *) InputPacketBuffer; 1372 SequenceNo = AckDebugHeader->SequenceNo; 1373 if (AckDebugHeader->Command == DEBUG_COMMAND_OK && 1374 SequenceNo == DebugHeader->SequenceNo && 1375 LastPacket) { 1376 // 1377 // If this is the last packet, return RETURN_SUCCESS. 1378 // 1379 return RETURN_SUCCESS; 1380 } 1381 if ((SequenceNo == (UINT8) (DebugHeader->SequenceNo + 1)) && (AckDebugHeader->Command == DEBUG_COMMAND_CONTINUE)) { 1382 // 1383 // Calculate the rest data size 1384 // 1385 Data += CurrentDataSize; 1386 RemainingDataSize -= CurrentDataSize; 1387 UpdateMailboxContent (GetMailboxPointer(), DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX, (UINT8) SequenceNo); 1388 break; 1389 } 1390 if (SequenceNo >= DebugHeader->SequenceNo) { 1391 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "TARGET: Received one old or new command(SequenceNo is %x, last SequenceNo is %x)\n", SequenceNo, DebugHeader->SequenceNo); 1392 break; 1393 } 1394 } 1395 } 1396 } 1397 1398 /** 447 1399 Send packet with response data to HOST. 448 1400 449 @param[in] CpuContext Pointer to saved CPU context.450 1401 @param[in] Data Pointer to response data buffer. 451 1402 @param[in] DataSize Size of response data in byte. 452 1403 453 1404 @retval RETURN_SUCCESS Response data was sent successfully. 454 @retval RETURN_DEVICE_ERROR Cannot receive DEBUG_COMMAND_OK from HOST.455 1405 456 1406 **/ 457 1407 RETURN_STATUS 458 1408 SendDataResponsePacket ( 459 IN DEBUG_CPU_CONTEXT *CpuContext,460 1409 IN UINT8 *Data, 461 1410 IN UINT16 DataSize 462 1411 ) 463 1412 { 464 UINT8 PacketHeader[DEBUG_DATA_MAXIMUM_LENGTH_FOR_SMALL_COMMANDS]; 465 BOOLEAN LastPacket; 466 UINT8 Ack; 467 UINT8 PacketData[DEBUG_DATA_MAXIMUM_REAL_DATA]; 468 DEBUG_PORT_HANDLE Handle; 469 470 Handle = GetDebugPortHandle(); 471 472 ((DEBUG_COMMAND_HEADER *)PacketHeader)->StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL; 473 474 while (TRUE) { 475 if (DataSize <= DEBUG_DATA_MAXIMUM_REAL_DATA) { 476 LastPacket = TRUE; 477 ((DEBUG_COMMAND_HEADER *)PacketHeader)->Command = DEBUG_COMMAND_OK; 478 ((DEBUG_COMMAND_HEADER *)PacketHeader)->DataLength = (UINT8) DataSize; 479 CopyMem (PacketData, Data, DataSize); 480 481 } else { 482 LastPacket = FALSE; 483 ((DEBUG_COMMAND_HEADER *)PacketHeader)->Command = DEBUG_COMMAND_IN_PROGRESS; 484 ((DEBUG_COMMAND_HEADER *)PacketHeader)->DataLength = DEBUG_DATA_MAXIMUM_REAL_DATA; 485 CopyMem (PacketData, Data, DEBUG_DATA_MAXIMUM_REAL_DATA); 486 } 487 488 DebugPortWriteBuffer (Handle, PacketHeader, sizeof (DEBUG_COMMAND_HEADER)); 489 DebugPortWriteBuffer (Handle, PacketData, ((DEBUG_COMMAND_HEADER *)PacketHeader)->DataLength); 490 491 ReceiveAckPacket(&Ack, 0, NULL); 492 switch (Ack) { 493 case DEBUG_COMMAND_RESEND: 494 // 495 // Send the packet again 496 // 497 break; 498 499 case DEBUG_COMMAND_CONTINUE: 500 // 501 // Send the rest packet 502 // 503 Data += DEBUG_DATA_MAXIMUM_REAL_DATA; 504 DataSize -= DEBUG_DATA_MAXIMUM_REAL_DATA; 505 break; 506 507 case DEBUG_COMMAND_OK: 508 if (LastPacket) { 509 // 510 // If this is the last packet, return RETURN_SUCCESS. 511 // 512 return RETURN_SUCCESS; 513 } else { 514 return RETURN_DEVICE_ERROR; 515 } 516 517 default: 518 return RETURN_DEVICE_ERROR; 519 520 } 521 } 1413 return ReadMemoryAndSendResponsePacket (Data, DataSize, 1); 522 1414 } 523 1415 … … 543 1435 DebugDataBreakCause.Cause = GetBreakCause (Vector, CpuContext); 544 1436 545 return SendDataResponsePacket (CpuContext, (UINT8 *) &DebugDataBreakCause, (UINT16) sizeof (DEBUG_DATA_RESPONSE_BREAK_CAUSE)); 546 } 547 1437 return SendDataResponsePacket ((UINT8 *) &DebugDataBreakCause, (UINT16) sizeof (DEBUG_DATA_RESPONSE_BREAK_CAUSE)); 1438 } 1439 1440 /** 1441 Try to attach the HOST. 1442 1443 Send init break packet to HOST: 1444 If no acknowlege received in specified Timeout, return RETURN_TIMEOUT. 1445 If received acknowlege, check the revision of HOST. 1446 Set Attach Flag if attach successfully. 1447 1448 @param[in] BreakCause Break cause of this break event. 1449 @param[in] Timeout Time out value to wait for acknowlege from HOST. 1450 The unit is microsecond. 1451 @param[out] BreakReceived If BreakReceived is not NULL, 1452 TRUE is retured if break-in symbol received. 1453 FALSE is retured if break-in symbol not received. 1454 **/ 1455 RETURN_STATUS 1456 AttachHost ( 1457 IN UINT8 BreakCause, 1458 IN UINTN Timeout, 1459 OUT BOOLEAN *BreakReceived 1460 ) 1461 { 1462 RETURN_STATUS Status; 1463 DEBUG_PORT_HANDLE Handle; 1464 BOOLEAN IncompatibilityFlag; 1465 1466 IncompatibilityFlag = FALSE; 1467 Handle = GetDebugPortHandle(); 1468 1469 // 1470 // Send init break and wait ack in Timeout 1471 // 1472 DebugPortWriteBuffer (Handle, (UINT8 *) mErrorMsgSendInitPacket, AsciiStrLen (mErrorMsgSendInitPacket)); 1473 if (BreakCause == DEBUG_DATA_BREAK_CAUSE_SYSTEM_RESET) { 1474 Status = SendCommandAndWaitForAckOK (DEBUG_COMMAND_INIT_BREAK, Timeout, BreakReceived, &IncompatibilityFlag); 1475 } else { 1476 Status = SendCommandAndWaitForAckOK (DEBUG_COMMAND_ATTACH_BREAK, Timeout, BreakReceived, &IncompatibilityFlag); 1477 } 1478 if (IncompatibilityFlag) { 1479 // 1480 // If the incompatible Debug Packet received, the HOST should be running transfer protocol before DEBUG_AGENT_REVISION. 1481 // It could be UDK Debugger for Windows v1.1/v1.2 or for Linux v0.8/v1.2. 1482 // 1483 DebugPortWriteBuffer (Handle, (UINT8 *) mErrorMsgVersionAlert, AsciiStrLen (mErrorMsgVersionAlert)); 1484 CpuDeadLoop (); 1485 } 1486 1487 if (RETURN_ERROR (Status)) { 1488 DebugPortWriteBuffer (Handle, (UINT8 *) mErrorMsgConnectFail, AsciiStrLen (mErrorMsgConnectFail)); 1489 } else { 1490 DebugPortWriteBuffer (Handle, (UINT8 *) mErrorMsgConnectOK, AsciiStrLen (mErrorMsgConnectOK)); 1491 // 1492 // Set Attach flag 1493 // 1494 SetHostAttached (TRUE); 1495 } 1496 return Status; 1497 } 1498 1499 /** 1500 Send Break point packet to HOST. 1501 1502 Only the first breaking processor could sent BREAK_POINT packet. 1503 1504 @param[in] BreakCause Break cause of this break event. 1505 @param[in] ProcessorIndex Processor index value. 1506 @param[out] BreakReceived If BreakReceived is not NULL, 1507 TRUE is retured if break-in symbol received. 1508 FALSE is retured if break-in symbol not received. 1509 1510 **/ 1511 VOID 1512 SendBreakPacketToHost ( 1513 IN UINT8 BreakCause, 1514 IN UINT32 ProcessorIndex, 1515 OUT BOOLEAN *BreakReceived 1516 ) 1517 { 1518 UINT8 InputCharacter; 1519 DEBUG_PORT_HANDLE Handle; 1520 1521 Handle = GetDebugPortHandle(); 1522 1523 if (IsHostAttached ()) { 1524 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "processor[%x]:Send Break Packet to HOST.\n", ProcessorIndex); 1525 SendCommandAndWaitForAckOK (DEBUG_COMMAND_BREAK_POINT, READ_PACKET_TIMEOUT, BreakReceived, NULL); 1526 } else { 1527 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "processor[%x]:Try to attach HOST.\n", ProcessorIndex); 1528 // 1529 // If HOST is not attached, try to attach it firstly. 1530 // 1531 // 1532 // Poll Attach symbols from HOST and ack OK 1533 // 1534 do { 1535 DebugPortReadBuffer (Handle, &InputCharacter, 1, 0); 1536 } while (InputCharacter != DEBUG_STARTING_SYMBOL_ATTACH); 1537 SendAckPacket (DEBUG_COMMAND_OK); 1538 1539 // 1540 // Try to attach HOST 1541 // 1542 while (AttachHost (BreakCause, 0, NULL) != RETURN_SUCCESS); 1543 1544 } 1545 } 548 1546 549 1547 /** … … 565 1563 ) 566 1564 { 567 RETURN_STATUS Status; 568 UINT8 InputPacketBuffer[DEBUG_DATA_MAXIMUM_LENGTH_FOR_SMALL_COMMANDS]; 569 DEBUG_COMMAND_HEADER *DebugHeader; 570 UINT8 Data8; 571 UINT32 Data32; 572 UINT64 Data64; 573 UINTN DataN; 574 DEBUG_DATA_READ_MEMORY_8 *MemoryRead; 575 DEBUG_DATA_WRITE_MEMORY_8 *MemoryWrite; 576 DEBUG_DATA_READ_IO *IoRead; 577 DEBUG_DATA_WRITE_IO *IoWrite; 578 DEBUG_DATA_READ_REGISTER *RegisterRead; 579 DEBUG_DATA_WRITE_REGISTER *RegisterWrite; 580 UINT8 *RegisterBuffer; 581 DEBUG_DATA_READ_MSR *MsrRegisterRead; 582 DEBUG_DATA_WRITE_MSR *MsrRegisterWrite; 583 DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM RegisterGroupSegLim; 584 DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE RegisterGroupSegBase; 585 DEBUG_DATA_RESPONSE_GET_REVISION DebugAgentRevision; 586 BOOLEAN HaltDeferred; 587 DEBUG_DATA_RESPONSE_GET_EXCEPTION Exception; 588 UINT32 ProcessorIndex; 589 DEBUG_PORT_HANDLE Handle; 590 591 Handle = GetDebugPortHandle(); 1565 RETURN_STATUS Status; 1566 UINT8 InputPacketBuffer[DEBUG_DATA_UPPER_LIMIT + sizeof (UINT64) - 1]; 1567 DEBUG_PACKET_HEADER *DebugHeader; 1568 UINT8 Width; 1569 UINT8 Data8; 1570 UINT32 Data32; 1571 UINT64 Data64; 1572 DEBUG_DATA_READ_MEMORY *MemoryRead; 1573 DEBUG_DATA_WRITE_MEMORY *MemoryWrite; 1574 DEBUG_DATA_READ_IO *IoRead; 1575 DEBUG_DATA_WRITE_IO *IoWrite; 1576 DEBUG_DATA_READ_REGISTER *RegisterRead; 1577 DEBUG_DATA_WRITE_REGISTER *RegisterWrite; 1578 UINT8 *RegisterBuffer; 1579 DEBUG_DATA_READ_MSR *MsrRegisterRead; 1580 DEBUG_DATA_WRITE_MSR *MsrRegisterWrite; 1581 DEBUG_DATA_CPUID *Cpuid; 1582 DEBUG_DATA_RESPONSE_CPUID CpuidResponse; 1583 DEBUG_DATA_SEARCH_SIGNATURE *SearchSignature; 1584 DEBUG_DATA_RESPONSE_GET_EXCEPTION Exception; 1585 DEBUG_DATA_RESPONSE_GET_REVISION DebugAgentRevision; 1586 DEBUG_DATA_SET_VIEWPOINT *SetViewPoint; 1587 BOOLEAN HaltDeferred; 1588 UINT32 ProcessorIndex; 1589 DEBUG_PORT_HANDLE Handle; 1590 DEBUG_AGENT_EXCEPTION_BUFFER AgentExceptionBuffer; 1591 UINT32 IssuedViewPoint; 1592 DEBUG_AGENT_MAILBOX *Mailbox; 1593 UINT8 *AlignedDataPtr; 592 1594 593 1595 ProcessorIndex = 0; 594 HaltDeferred = BreakReceived; 595 596 if (MultiProcessorDebugSupport) { 1596 IssuedViewPoint = 0; 1597 HaltDeferred = BreakReceived; 1598 1599 if (MultiProcessorDebugSupport()) { 597 1600 ProcessorIndex = GetProcessorIndex (); 598 1601 SetCpuStopFlagByIndex (ProcessorIndex, TRUE); 599 } 1602 if (mDebugMpContext.ViewPointIndex == ProcessorIndex) { 1603 // 1604 // Only the current view processor could set AgentInProgress Flag. 1605 // 1606 IssuedViewPoint = ProcessorIndex; 1607 } 1608 } 1609 1610 if (IssuedViewPoint == ProcessorIndex) { 1611 // 1612 // Set AgentInProgress Flag. 1613 // 1614 SetDebugFlag (DEBUG_AGENT_FLAG_AGENT_IN_PROGRESS, 1); 1615 } 1616 1617 Handle = GetDebugPortHandle(); 600 1618 601 1619 while (TRUE) { 602 1620 603 if (MultiProcessorDebugSupport) { 1621 if (MultiProcessorDebugSupport()) { 1622 // 1623 // Check if the current processor is HOST view point 1624 // 604 1625 if (mDebugMpContext.ViewPointIndex != ProcessorIndex) { 605 1626 if (mDebugMpContext.RunCommandSet) { 1627 // 1628 // If HOST view point sets RUN flag, run GO command to leave 1629 // 606 1630 SetCpuStopFlagByIndex (ProcessorIndex, FALSE); 607 1631 CommandGo (CpuContext); 608 1632 break; 609 1633 } else { 1634 // 1635 // Run into loop again 1636 // 1637 CpuPause (); 610 1638 continue; 611 1639 } … … 613 1641 } 614 1642 615 AcquireDebugPortControl (); 616 617 Status = ReceivePacket (InputPacketBuffer, &BreakReceived); 618 619 if (BreakReceived) { 1643 AcquireMpSpinLock (&mDebugMpContext.DebugPortSpinLock); 1644 1645 DebugHeader =(DEBUG_PACKET_HEADER *) InputPacketBuffer; 1646 1647 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "TARGET: Try to get command from HOST...\n"); 1648 Status = ReceivePacket ((UINT8 *)DebugHeader, &BreakReceived, NULL, READ_PACKET_TIMEOUT, TRUE); 1649 if (Status != RETURN_SUCCESS || (DebugHeader->Command & DEBUG_COMMAND_RESPONSE) != 0) { 1650 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "TARGET: Get command[%x] sequenceno[%x] returned status is [%x] \n", DebugHeader->Command, DebugHeader->SequenceNo, Status); 1651 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "TARGET: Get command failed or it's response packet not expected! \n"); 1652 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock); 1653 continue; 1654 } 1655 1656 Mailbox = GetMailboxPointer (); 1657 if (DebugHeader->SequenceNo == Mailbox->HostSequenceNo) { 1658 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "TARGET: Receive one old command[%x] agaist command[%x]\n", DebugHeader->SequenceNo, Mailbox->HostSequenceNo); 1659 SendAckPacket (Mailbox->LastAck); 1660 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock); 1661 continue; 1662 } else if (DebugHeader->SequenceNo == (UINT8) (Mailbox->HostSequenceNo + 1)) { 1663 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX, (UINT8) DebugHeader->SequenceNo); 1664 } else { 1665 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "Receive one invalid comamnd[%x] agaist command[%x]\n", DebugHeader->SequenceNo, Mailbox->HostSequenceNo); 1666 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock); 1667 continue; 1668 } 1669 1670 // 1671 // Save CPU content before executing HOST commond 1672 // 1673 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_EXCEPTION_BUFFER_POINTER_INDEX, (UINT64)(UINTN) &AgentExceptionBuffer.JumpBuffer); 1674 if (SetJump (&AgentExceptionBuffer.JumpBuffer) != 0) { 1675 // 1676 // If HOST command failed, continue to wait for HOST's next command 1677 // If needed, agent could send exception info to HOST. 1678 // 1679 SendAckPacket (DEBUG_COMMAND_ABORT); 1680 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock); 1681 continue; 1682 } 1683 1684 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Processor[%x]:Received one command(%x)\n", mDebugMpContext.ViewPointIndex, DebugHeader->Command); 1685 1686 switch (DebugHeader->Command) { 1687 1688 case DEBUG_COMMAND_HALT: 1689 SendAckPacket (DEBUG_COMMAND_HALT_DEFERRED); 620 1690 HaltDeferred = TRUE; 621 1691 BreakReceived = FALSE; 622 } 623 624 if (Status != RETURN_SUCCESS) { 625 ReleaseDebugPortControl (); 626 continue; 627 } 628 629 Data8 = 1; 630 631 DebugHeader =(DEBUG_COMMAND_HEADER *) InputPacketBuffer; 632 switch (DebugHeader->Command) { 1692 Status = RETURN_SUCCESS; 1693 break; 633 1694 634 1695 case DEBUG_COMMAND_RESET: 635 1696 SendAckPacket (DEBUG_COMMAND_OK); 636 ReleaseDebugPortControl (); 1697 SendAckPacket (DEBUG_COMMAND_OK); 1698 SendAckPacket (DEBUG_COMMAND_OK); 1699 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock); 637 1700 638 1701 ResetCold (); 639 1702 // 640 // Wait for reset 641 // 642 CpuDeadLoop (); 1703 // Assume system resets in 2 seconds, otherwise send TIMEOUT packet. 1704 // PCD can be used if 2 seconds isn't long enough for some platforms. 1705 // 1706 MicroSecondDelay (2000000); 1707 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX, Mailbox->HostSequenceNo + 1); 1708 SendAckPacket (DEBUG_COMMAND_TIMEOUT); 1709 SendAckPacket (DEBUG_COMMAND_TIMEOUT); 1710 SendAckPacket (DEBUG_COMMAND_TIMEOUT); 643 1711 break; 644 1712 645 1713 case DEBUG_COMMAND_GO: 646 1714 CommandGo (CpuContext); 1715 // 1716 // Clear Dr0 to avoid to be recognized as IMAGE_LOAD/_UNLOAD again when hitting a breakpoint after GO 1717 // If HOST changed Dr0 before GO, we will not change Dr0 here 1718 // 1719 Data8 = GetBreakCause (Vector, CpuContext); 1720 if (Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD || Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD) { 1721 CpuContext->Dr0 = 0; 1722 } 1723 // 1724 // Clear Stepping Flag 1725 // 1726 SetDebugFlag (DEBUG_AGENT_FLAG_STEPPING, 0); 1727 647 1728 if (!HaltDeferred) { 648 1729 // 649 1730 // If no HALT command received when being in-active mode 650 1731 // 651 if (MultiProcessorDebugSupport ) {652 Data32 = Find CpuNotRunning();1732 if (MultiProcessorDebugSupport()) { 1733 Data32 = FindNextPendingBreakCpu (); 653 1734 if (Data32 != -1) { 654 1735 // 655 // If there are still others processors being in break state, 1736 // If there are still others processors being in break state, 656 1737 // send OK packet to HOST to finish this go command 657 1738 // … … 665 1746 SetCpuBreakFlagByIndex (mDebugMpContext.ViewPointIndex, FALSE); 666 1747 // 667 // Send break packet to HOST and exit to wait for command packet from HOST.1748 // Send break packet to HOST to let HOST break again 668 1749 // 669 SendAckPacket (DEBUG_COMMAND_BREAK_POINT); 670 WaitForAckPacketOK (0, &BreakReceived); 671 ReleaseDebugPortControl (); 1750 SendBreakPacketToHost (DEBUG_DATA_BREAK_CAUSE_UNKNOWN, mDebugMpContext.BreakAtCpuIndex, &BreakReceived); 1751 // 1752 // Continue to run into loop to read command packet from HOST 1753 // 1754 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock); 672 1755 break; 673 1756 } … … 681 1764 CpuPause (); 682 1765 // 683 // Wait for all processors are in running state 1766 // Wait for all processors are in running state 684 1767 // 685 1768 while (TRUE) { … … 705 1788 SendAckPacket (DEBUG_COMMAND_OK); 706 1789 707 ReleaseDebugPortControl (); 708 1790 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock); 1791 1792 if (!IsHostAttached()) { 1793 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_SEQUENCE_NO_INDEX, 0); 1794 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX, 0); 1795 } 709 1796 return; 710 1797 … … 715 1802 SendAckPacket (DEBUG_COMMAND_HALT_PROCESSED); 716 1803 HaltDeferred = FALSE; 717 Data8 = GetBreakCause (Vector, CpuContext);718 if (Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD || Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD) {719 CpuContext->Dr0 = 0;720 CpuContext->Dr3 = 0;721 }722 1804 723 1805 Vector = DEBUG_TIMER_VECTOR; … … 727 1809 case DEBUG_COMMAND_BREAK_CAUSE: 728 1810 729 if (MultiProcessorDebugSupport && ProcessorIndex != mDebugMpContext.BreakAtCpuIndex) {1811 if (MultiProcessorDebugSupport() && ProcessorIndex != mDebugMpContext.BreakAtCpuIndex) { 730 1812 Status = SendBreakCausePacket (DEBUG_TIMER_VECTOR, CpuContext); 731 1813 … … 748 1830 case DEBUG_COMMAND_SINGLE_STEPPING: 749 1831 CommandStepping (CpuContext); 1832 // 1833 // Clear Dr0 to avoid to be recognized as IMAGE_LOAD/_UNLOAD again when hitting a breakpoint after GO 1834 // If HOST changed Dr0 before GO, we will not change Dr0 here 1835 // 1836 Data8 = GetBreakCause (Vector, CpuContext); 1837 if (Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD || Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD) { 1838 CpuContext->Dr0 = 0; 1839 } 750 1840 751 1841 mDebugMpContext.BreakAtCpuIndex = (UINT32) (-1); 752 753 ReleaseDebugPortControl (); 754 // 755 // Executing stepping command directly without sending ACK packet. 1842 // 1843 // Set Stepping Flag 1844 // 1845 SetDebugFlag (DEBUG_AGENT_FLAG_STEPPING, 1); 1846 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock); 1847 // 1848 // Executing stepping command directly without sending ACK packet, 1849 // ACK packet will be sent after stepping done. 756 1850 // 757 1851 return; … … 761 1855 Data8 = *(UINT8 *) (UINTN) Data64; 762 1856 *(UINT8 *) (UINTN) Data64 = DEBUG_SW_BREAKPOINT_SYMBOL; 763 Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Data8, (UINT16) sizeof (UINT8)); 764 break; 765 766 case DEBUG_COMMAND_READ_MEMORY_64: 767 Data8 *= 2; 768 case DEBUG_COMMAND_READ_MEMORY_32: 769 Data8 *= 2; 770 case DEBUG_COMMAND_READ_MEMORY_16: 771 Data8 *= 2; 772 case DEBUG_COMMAND_READ_MEMORY_8: 773 MemoryRead = (DEBUG_DATA_READ_MEMORY_8 *) (DebugHeader + 1); 774 Status = SendDataResponsePacket (CpuContext, (UINT8 *) (UINTN) MemoryRead->Address, (UINT16) (MemoryRead->Count * Data8)); 775 break; 776 777 case DEBUG_COMMAND_WRITE_MEMORY_64: 778 Data8 *= 2; 779 case DEBUG_COMMAND_WRITE_MEMORY_32: 780 Data8 *= 2; 781 case DEBUG_COMMAND_WRITE_MEMORY_16: 782 Data8 *= 2; 783 case DEBUG_COMMAND_WRITE_MEMORY_8: 784 MemoryWrite = (DEBUG_DATA_WRITE_MEMORY_8 *) (DebugHeader + 1); 785 CopyMem ((VOID *) (UINTN) MemoryWrite->Address, &MemoryWrite->Data, MemoryWrite->Count * Data8); 1857 Status = SendDataResponsePacket ((UINT8 *) &Data8, (UINT16) sizeof (UINT8)); 1858 break; 1859 1860 case DEBUG_COMMAND_READ_MEMORY: 1861 MemoryRead = (DEBUG_DATA_READ_MEMORY *) (DebugHeader + 1); 1862 Status = ReadMemoryAndSendResponsePacket ((UINT8 *) (UINTN) MemoryRead->Address, MemoryRead->Count, MemoryRead->Width); 1863 break; 1864 1865 case DEBUG_COMMAND_WRITE_MEMORY: 1866 MemoryWrite = (DEBUG_DATA_WRITE_MEMORY *) (DebugHeader + 1); 1867 // 1868 // Copy data into one memory with 8-byte alignment address 1869 // 1870 AlignedDataPtr = ALIGN_POINTER ((UINT8 *) &MemoryWrite->Data, sizeof (UINT64)); 1871 if (AlignedDataPtr != (UINT8 *) &MemoryWrite->Data) { 1872 CopyMem (AlignedDataPtr, (UINT8 *) &MemoryWrite->Data, MemoryWrite->Count * MemoryWrite->Width); 1873 } 1874 CopyMemByWidth ((UINT8 *) (UINTN) MemoryWrite->Address, AlignedDataPtr, MemoryWrite->Count, MemoryWrite->Width); 786 1875 SendAckPacket (DEBUG_COMMAND_OK); 787 1876 break; … … 791 1880 switch (IoRead->Width) { 792 1881 case 1: 793 Data64 = IoRead8 ( IoRead->Port);1882 Data64 = IoRead8 ((UINTN) IoRead->Port); 794 1883 break; 795 1884 case 2: 796 Data64 = IoRead16 ( IoRead->Port);1885 Data64 = IoRead16 ((UINTN) IoRead->Port); 797 1886 break; 798 1887 case 4: 799 Data64 = IoRead32 ( IoRead->Port);1888 Data64 = IoRead32 ((UINTN) IoRead->Port); 800 1889 break; 801 1890 case 8: 802 Data64 = IoRead64 ( IoRead->Port);1891 Data64 = IoRead64 ((UINTN) IoRead->Port); 803 1892 break; 804 1893 default: 805 1894 Data64 = (UINT64) -1; 806 1895 } 807 Status = SendDataResponsePacket ( CpuContext,(UINT8 *) &Data64, IoRead->Width);1896 Status = SendDataResponsePacket ((UINT8 *) &Data64, IoRead->Width); 808 1897 break; 809 1898 … … 812 1901 switch (IoWrite->Width) { 813 1902 case 1: 814 Data64 = IoWrite8 ( IoWrite->Port, *(UINT8 *) &IoWrite->Data);1903 Data64 = IoWrite8 ((UINTN) IoWrite->Port, *(UINT8 *) &IoWrite->Data); 815 1904 break; 816 1905 case 2: 817 Data64 = IoWrite16 ( IoWrite->Port, *(UINT16 *) &IoWrite->Data);1906 Data64 = IoWrite16 ((UINTN) IoWrite->Port, *(UINT16 *) &IoWrite->Data); 818 1907 break; 819 1908 case 4: 820 Data64 = IoWrite32 ( IoWrite->Port, *(UINT32 *) &IoWrite->Data);1909 Data64 = IoWrite32 ((UINTN) IoWrite->Port, *(UINT32 *) &IoWrite->Data); 821 1910 break; 822 1911 case 8: 823 Data64 = IoWrite64 ( IoWrite->Port, *(UINT64 *) &IoWrite->Data);1912 Data64 = IoWrite64 ((UINTN) IoWrite->Port, *(UINT64 *) &IoWrite->Data); 824 1913 break; 825 1914 default: … … 829 1918 break; 830 1919 1920 case DEBUG_COMMAND_READ_ALL_REGISTERS: 1921 Status = SendDataResponsePacket ((UINT8 *) CpuContext, sizeof (*CpuContext)); 1922 break; 1923 831 1924 case DEBUG_COMMAND_READ_REGISTER: 832 1925 RegisterRead = (DEBUG_DATA_READ_REGISTER *) (DebugHeader + 1); 833 1926 834 if (RegisterRead->Index < SOFT_DEBUGGER_REGISTER_OTHERS_BASE) { 835 Data8 = RegisterRead->Length; 836 RegisterBuffer = ArchReadRegisterBuffer (CpuContext, RegisterRead->Index, RegisterRead->Offset, &Data8); 837 Status = SendDataResponsePacket (CpuContext, RegisterBuffer, Data8); 838 break; 839 } 840 841 if (RegisterRead->Index <= SOFT_DEBUGGER_REGISTER_TSS_LIM) { 842 ReadRegisterGroupSegLim (CpuContext, &RegisterGroupSegLim); 843 DataN = * ((UINTN *) &RegisterGroupSegLim + (RegisterRead->Index - SOFT_DEBUGGER_REGISTER_CS_LIM)); 844 Status = SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN)); 845 } else if (RegisterRead->Index <= SOFT_DEBUGGER_REGISTER_TSS_BAS) { 846 ReadRegisterGroupSegBase (CpuContext, &RegisterGroupSegBase); 847 DataN = * ((UINTN *) &RegisterGroupSegBase + (RegisterRead->Index - SOFT_DEBUGGER_REGISTER_CS_BAS)); 848 Status = SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN)); 849 } else if (RegisterRead->Index < SOFT_DEBUGGER_REGISTER_IDT_LIM) { 850 Data64 = ReadRegisterSelectorByIndex (CpuContext, RegisterRead->Index); 851 Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Data64, (UINT16) sizeof (UINT64)); 1927 if (RegisterRead->Index <= SOFT_DEBUGGER_REGISTER_MAX) { 1928 RegisterBuffer = ArchReadRegisterBuffer (CpuContext, RegisterRead->Index, &Width); 1929 Status = SendDataResponsePacket (RegisterBuffer, Width); 852 1930 } else { 853 switch (RegisterRead->Index) { 854 case SOFT_DEBUGGER_REGISTER_IDT_LIM: 855 DataN = (UINTN) (CpuContext->Idtr[0] & 0xffff); 856 SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN)); 857 break; 858 case SOFT_DEBUGGER_REGISTER_GDT_LIM: 859 DataN = (UINTN) (CpuContext->Gdtr[0] & 0xffff); 860 SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN)); 861 break; 862 case SOFT_DEBUGGER_REGISTER_IDT_BAS: 863 DataN = (UINTN) RShiftU64 (CpuContext->Idtr[0], 16); 864 DataN |= (UINTN) LShiftU64 (CpuContext->Idtr[1], (UINT16) (sizeof (UINTN) * 8 - 16)); 865 SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN)); 866 break; 867 case SOFT_DEBUGGER_REGISTER_GDT_BAS: 868 DataN = (UINTN) RShiftU64 (CpuContext->Gdtr[0], 16); 869 DataN |= (UINTN) LShiftU64 (CpuContext->Gdtr[1], (UINT16) (sizeof (UINTN) * 8 - 16)); 870 SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN)); 871 break; 872 } 1931 Status = RETURN_UNSUPPORTED; 873 1932 } 874 1933 break; … … 876 1935 case DEBUG_COMMAND_WRITE_REGISTER: 877 1936 RegisterWrite = (DEBUG_DATA_WRITE_REGISTER *) (DebugHeader + 1); 878 ArchWriteRegisterBuffer (CpuContext, RegisterWrite->Index, RegisterWrite->Offset, RegisterWrite->Length, (UINT8 *)&RegisterWrite->Value); 879 SendAckPacket (DEBUG_COMMAND_OK); 1937 if (RegisterWrite->Index <= SOFT_DEBUGGER_REGISTER_MAX) { 1938 RegisterBuffer = ArchReadRegisterBuffer (CpuContext, RegisterWrite->Index, &Width); 1939 ASSERT (Width == RegisterWrite->Length); 1940 CopyMem (RegisterBuffer, RegisterWrite->Data, Width); 1941 SendAckPacket (DEBUG_COMMAND_OK); 1942 } else { 1943 Status = RETURN_UNSUPPORTED; 1944 } 880 1945 break; 881 1946 882 1947 case DEBUG_COMMAND_ARCH_MODE: 883 1948 Data8 = DEBUG_ARCH_SYMBOL; 884 Status = SendDataResponsePacket ( CpuContext,(UINT8 *) &Data8, (UINT16) sizeof (UINT8));1949 Status = SendDataResponsePacket ((UINT8 *) &Data8, (UINT16) sizeof (UINT8)); 885 1950 break; 886 1951 … … 888 1953 MsrRegisterRead = (DEBUG_DATA_READ_MSR *) (DebugHeader + 1); 889 1954 Data64 = AsmReadMsr64 (MsrRegisterRead->Index); 890 Status = SendDataResponsePacket ( CpuContext,(UINT8 *) &Data64, (UINT16) sizeof (UINT64));1955 Status = SendDataResponsePacket ((UINT8 *) &Data64, (UINT16) sizeof (UINT64)); 891 1956 break; 892 1957 … … 897 1962 break; 898 1963 899 case DEBUG_COMMAND_READ_REGISTER_GROUP: 900 Data8 = *(UINT8 *) (DebugHeader + 1); 901 Status = ArchReadRegisterGroup (CpuContext, Data8); 902 break; 903 904 case DEBUG_COMMAND_SET_DEBUG_FLAG: 905 Data32 = *(UINT32 *) (DebugHeader + 1); 906 SetDebugFlag (Data32); 907 SendAckPacket (DEBUG_COMMAND_OK); 1964 case DEBUG_COMMAND_SET_DEBUG_SETTING: 1965 Status = SetDebugSetting ((DEBUG_DATA_SET_DEBUG_SETTING *)(DebugHeader + 1)); 1966 if (Status == RETURN_SUCCESS) { 1967 SendAckPacket (DEBUG_COMMAND_OK); 1968 } 908 1969 break; 909 1970 … … 911 1972 DebugAgentRevision.Revision = DEBUG_AGENT_REVISION; 912 1973 DebugAgentRevision.Capabilities = DEBUG_AGENT_CAPABILITIES; 913 Status = SendDataResponsePacket ( CpuContext,(UINT8 *) &DebugAgentRevision, (UINT16) sizeof (DEBUG_DATA_RESPONSE_GET_REVISION));1974 Status = SendDataResponsePacket ((UINT8 *) &DebugAgentRevision, (UINT16) sizeof (DEBUG_DATA_RESPONSE_GET_REVISION)); 914 1975 break; 915 1976 916 1977 case DEBUG_COMMAND_GET_EXCEPTION: 917 1978 Exception.ExceptionNum = (UINT8) Vector; 918 Exception.ExceptionData = 0;919 Status = SendDataResponsePacket ( CpuContext,(UINT8 *) &Exception, (UINT16) sizeof (DEBUG_DATA_RESPONSE_GET_EXCEPTION));1979 Exception.ExceptionData = (UINT32) CpuContext->ExceptionData; 1980 Status = SendDataResponsePacket ((UINT8 *) &Exception, (UINT16) sizeof (DEBUG_DATA_RESPONSE_GET_EXCEPTION)); 920 1981 break; 921 1982 922 1983 case DEBUG_COMMAND_SET_VIEWPOINT: 923 Data32 = *(UINT32 *) (DebugHeader + 1); 924 925 if (MultiProcessorDebugSupport) { 926 if (IsCpuStopped (Data32)) { 927 SetDebugViewPoint (Data32); 1984 SetViewPoint = (DEBUG_DATA_SET_VIEWPOINT *) (DebugHeader + 1); 1985 if (MultiProcessorDebugSupport()) { 1986 if (IsCpuStopped (SetViewPoint->ViewPoint)) { 1987 SetDebugViewPoint (SetViewPoint->ViewPoint); 928 1988 SendAckPacket (DEBUG_COMMAND_OK); 929 1989 } else { … … 933 1993 SendAckPacket (DEBUG_COMMAND_NOT_SUPPORTED); 934 1994 } 935 } else if ( Data32== 0) {1995 } else if (SetViewPoint->ViewPoint == 0) { 936 1996 SendAckPacket (DEBUG_COMMAND_OK); 937 1997 … … 944 2004 case DEBUG_COMMAND_GET_VIEWPOINT: 945 2005 Data32 = mDebugMpContext.ViewPointIndex; 946 SendDataResponsePacket(CpuContext, (UINT8 *) &Data32, (UINT16) sizeof (UINT32)); 2006 SendDataResponsePacket((UINT8 *) &Data32, (UINT16) sizeof (UINT32)); 2007 break; 2008 2009 case DEBUG_COMMAND_MEMORY_READY: 2010 Data8 = (UINT8) GetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY); 2011 SendDataResponsePacket (&Data8, (UINT16) sizeof (UINT8)); 2012 break; 2013 2014 case DEBUG_COMMAND_DETACH: 2015 SetHostAttached (FALSE); 2016 SendAckPacket (DEBUG_COMMAND_OK); 2017 break; 2018 2019 case DEBUG_COMMAND_CPUID: 2020 Cpuid = (DEBUG_DATA_CPUID *) (DebugHeader + 1); 2021 AsmCpuidEx ( 2022 Cpuid->Eax, Cpuid->Ecx, 2023 &CpuidResponse.Eax, &CpuidResponse.Ebx, 2024 &CpuidResponse.Ecx, &CpuidResponse.Edx 2025 ); 2026 SendDataResponsePacket ((UINT8 *) &CpuidResponse, (UINT16) sizeof (CpuidResponse)); 2027 break; 2028 2029 case DEBUG_COMMAND_SEARCH_SIGNATURE: 2030 SearchSignature = (DEBUG_DATA_SEARCH_SIGNATURE *) (DebugHeader + 1); 2031 if ((SearchSignature->Alignment != 0) && 2032 (SearchSignature->Alignment == GetPowerOfTwo32 (SearchSignature->Alignment)) 2033 ) { 2034 if (SearchSignature->Positive) { 2035 for ( 2036 Data64 = ALIGN_VALUE ((UINTN) SearchSignature->Start, SearchSignature->Alignment); 2037 Data64 <= SearchSignature->Start + SearchSignature->Count - SearchSignature->DataLength; 2038 Data64 += SearchSignature->Alignment 2039 ) { 2040 if (CompareMem ((VOID *) (UINTN) Data64, &SearchSignature->Data, SearchSignature->DataLength) == 0) { 2041 break; 2042 } 2043 } 2044 if (Data64 > SearchSignature->Start + SearchSignature->Count - SearchSignature->DataLength) { 2045 Data64 = (UINT64) -1; 2046 } 2047 } else { 2048 for ( 2049 Data64 = ALIGN_VALUE ((UINTN) SearchSignature->Start - SearchSignature->Alignment, SearchSignature->Alignment); 2050 Data64 >= SearchSignature->Start - SearchSignature->Count; 2051 Data64 -= SearchSignature->Alignment 2052 ) { 2053 if (CompareMem ((VOID *) (UINTN) Data64, &SearchSignature->Data, SearchSignature->DataLength) == 0) { 2054 break; 2055 } 2056 } 2057 if (Data64 < SearchSignature->Start - SearchSignature->Count) { 2058 Data64 = (UINT64) -1; 2059 } 2060 } 2061 SendDataResponsePacket ((UINT8 *) &Data64, (UINT16) sizeof (Data64)); 2062 } else { 2063 Status = RETURN_UNSUPPORTED; 2064 } 947 2065 break; 948 2066 … … 958 2076 } 959 2077 960 Release DebugPortControl ();2078 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock); 961 2079 CpuPause (); 962 2080 } … … 977 2095 ) 978 2096 { 979 UINT8 InputCharacter; 980 UINT8 BreakCause; 981 UINTN SavedEip; 982 BOOLEAN BreakReceived; 983 UINT32 ProcessorIndex; 984 UINT32 CurrentDebugTimerInitCount; 985 DEBUG_PORT_HANDLE Handle; 986 UINT8 Data8; 987 988 Handle = GetDebugPortHandle(); 989 990 ProcessorIndex = 0; 991 BreakReceived = FALSE; 992 993 if (MultiProcessorDebugSupport) { 2097 UINT8 InputCharacter; 2098 UINT8 BreakCause; 2099 UINTN SavedEip; 2100 BOOLEAN BreakReceived; 2101 UINT32 ProcessorIndex; 2102 UINT32 CurrentDebugTimerInitCount; 2103 DEBUG_PORT_HANDLE Handle; 2104 UINT8 Data8; 2105 UINT8 *Al; 2106 UINT32 IssuedViewPoint; 2107 DEBUG_AGENT_EXCEPTION_BUFFER *ExceptionBuffer; 2108 2109 InputCharacter = 0; 2110 ProcessorIndex = 0; 2111 IssuedViewPoint = 0; 2112 BreakReceived = FALSE; 2113 2114 if (mSkipBreakpoint) { 2115 // 2116 // If Skip Breakpoint flag is set, means communication is disturbed by hardware SMI, we need to ignore the break points in SMM 2117 // 2118 if ((Vector == DEBUG_INT1_VECTOR) || (Vector == DEBUG_INT3_VECTOR)) { 2119 DebugPortWriteBuffer (GetDebugPortHandle(), (UINT8 *) mWarningMsgIngoreBreakpoint, AsciiStrLen (mWarningMsgIngoreBreakpoint)); 2120 return; 2121 } 2122 } 2123 2124 if (MultiProcessorDebugSupport()) { 994 2125 ProcessorIndex = GetProcessorIndex (); 995 while (mDebugMpContext.RunCommandSet); 996 } 997 2126 // 2127 // If this processor has alreay halted before, need to check it later 2128 // 2129 if (IsCpuStopped (ProcessorIndex)) { 2130 IssuedViewPoint = ProcessorIndex; 2131 } 2132 } 2133 2134 if (IssuedViewPoint == ProcessorIndex && GetDebugFlag (DEBUG_AGENT_FLAG_STEPPING) != 1) { 2135 // 2136 // Check if this exception is issued by Debug Agent itself 2137 // If yes, fill the debug agent exception buffer and LongJump() back to 2138 // the saved CPU content in CommandCommunication() 2139 // 2140 if (GetDebugFlag (DEBUG_AGENT_FLAG_AGENT_IN_PROGRESS) == 1) { 2141 DebugAgentMsgPrint (DEBUG_AGENT_ERROR, "Debug agent meet one Exception, ExceptionNum is %d, EIP = 0x%x.\n", Vector, (UINTN)CpuContext->Eip); 2142 ExceptionBuffer = (DEBUG_AGENT_EXCEPTION_BUFFER *) (UINTN) GetMailboxPointer()->ExceptionBufferPointer; 2143 ExceptionBuffer->ExceptionContent.ExceptionNum = (UINT8) Vector; 2144 ExceptionBuffer->ExceptionContent.ExceptionData = (UINT32) CpuContext->ExceptionData; 2145 LongJump ((BASE_LIBRARY_JUMP_BUFFER *)(UINTN)(ExceptionBuffer), 1); 2146 } 2147 } 2148 2149 if (MultiProcessorDebugSupport()) { 2150 // 2151 // If RUN commmand is executing, wait for it done. 2152 // 2153 while (mDebugMpContext.RunCommandSet) { 2154 CpuPause (); 2155 } 2156 } 2157 2158 Handle = GetDebugPortHandle(); 2159 BreakCause = GetBreakCause (Vector, CpuContext); 998 2160 switch (Vector) { 999 2161 case DEBUG_INT1_VECTOR: 1000 2162 case DEBUG_INT3_VECTOR: 1001 1002 BreakCause = GetBreakCause (Vector, CpuContext); 1003 1004 if (BreakCause == DEBUG_DATA_BREAK_CAUSE_SYSTEM_RESET) { 1005 1006 // 1007 // Init break, if no ack received after 200ms, return 1008 // 1009 SendAckPacket (DEBUG_COMMAND_INIT_BREAK); 1010 if (WaitForAckPacketOK (200 * 1000, &BreakReceived) != RETURN_SUCCESS) { 2163 switch (BreakCause) { 2164 case DEBUG_DATA_BREAK_CAUSE_SYSTEM_RESET: 2165 if (AttachHost (BreakCause, READ_PACKET_TIMEOUT, &BreakReceived) != RETURN_SUCCESS) { 2166 // 2167 // Try to connect HOST, return if fails 2168 // 1011 2169 break; 1012 2170 } 1013 1014 SetHostConnectedFlag ();1015 2171 CommandCommunication (Vector, CpuContext, BreakReceived); 1016 1017 } else if (BreakCause == DEBUG_DATA_BREAK_CAUSE_STEPPING) { 1018 2172 break; 2173 2174 case DEBUG_DATA_BREAK_CAUSE_STEPPING: 1019 2175 // 1020 2176 // Stepping is finished, send Ack package. 1021 2177 // 1022 if (MultiProcessorDebugSupport ) {2178 if (MultiProcessorDebugSupport()) { 1023 2179 mDebugMpContext.BreakAtCpuIndex = ProcessorIndex; 1024 2180 } 1025 2181 SendAckPacket (DEBUG_COMMAND_OK); 1026 2182 CommandCommunication (Vector, CpuContext, BreakReceived); 1027 1028 } else if (BreakCause == DEBUG_DATA_BREAK_CAUSE_MEMORY_READY) { 1029 2183 break; 2184 2185 case DEBUG_DATA_BREAK_CAUSE_MEMORY_READY: 1030 2186 // 1031 2187 // Memory is ready 1032 2188 // 1033 SendAckPacket (DEBUG_COMMAND_MEMORY_READY); 1034 WaitForAckPacketOK (0, &BreakReceived); 2189 SendCommandAndWaitForAckOK (DEBUG_COMMAND_MEMORY_READY, READ_PACKET_TIMEOUT, &BreakReceived, NULL); 1035 2190 CommandCommunication (Vector, CpuContext, BreakReceived); 1036 1037 } else { 1038 1039 if (BreakCause == DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD || BreakCause == DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD) { 1040 1041 // 1042 // Set AL to DEBUG_AGENT_IMAGE_CONTINUE 1043 // 1044 Data8 = DEBUG_AGENT_IMAGE_CONTINUE; 1045 ArchWriteRegisterBuffer (CpuContext, SOFT_DEBUGGER_REGISTER_AX, 0, 1, &Data8); 1046 1047 if (!IsHostConnected ()) { 1048 // 1049 // If HOST is not connected, return 1050 // 1051 break; 1052 } 1053 } 1054 1055 AcquireDebugPortControl (); 1056 1057 if (MultiProcessorDebugSupport) { 1058 if(!IsAllCpuRunning ()) { 1059 // 1060 // If other processors have been stopped 1061 // 1062 SetCpuBreakFlagByIndex (ProcessorIndex, TRUE); 1063 } else { 1064 // 1065 // If no any processor was stopped, try to halt other processors 1066 // 1067 HaltOtherProcessors (ProcessorIndex); 1068 SendAckPacket (DEBUG_COMMAND_BREAK_POINT); 1069 WaitForAckPacketOK (0, &BreakReceived); 1070 } 1071 } else { 1072 SendAckPacket (DEBUG_COMMAND_BREAK_POINT); 1073 WaitForAckPacketOK (0, &BreakReceived); 1074 } 1075 1076 ReleaseDebugPortControl (); 2191 break; 2192 2193 case DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD: 2194 case DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD: 2195 // 2196 // Set AL to DEBUG_AGENT_IMAGE_CONTINUE 2197 // 2198 Al = ArchReadRegisterBuffer (CpuContext, SOFT_DEBUGGER_REGISTER_AX, &Data8); 2199 *Al = DEBUG_AGENT_IMAGE_CONTINUE; 2200 2201 if (!IsHostAttached ()) { 2202 // 2203 // If HOST is not connected for image load/unload, return 2204 // 2205 break; 2206 } 2207 // 2208 // Continue to run the following common code 2209 // 2210 2211 case DEBUG_DATA_BREAK_CAUSE_HW_BREAKPOINT: 2212 case DEBUG_DATA_BREAK_CAUSE_SW_BREAKPOINT: 2213 default: 2214 // 2215 // Send Break packet to HOST 2216 // 2217 AcquireMpSpinLock (&mDebugMpContext.DebugPortSpinLock); 2218 // 2219 // Only the first breaking processor could send BREAK_POINT to HOST 2220 // 2221 if (IsFirstBreakProcessor (ProcessorIndex)) { 2222 SendBreakPacketToHost (BreakCause, ProcessorIndex, &BreakReceived); 2223 } 2224 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock); 1077 2225 1078 2226 if (Vector == DEBUG_INT3_VECTOR) { … … 1094 2242 CommandCommunication (Vector, CpuContext, BreakReceived); 1095 2243 } 2244 break; 1096 2245 } 1097 2246 … … 1100 2249 case DEBUG_TIMER_VECTOR: 1101 2250 1102 if (MultiProcessorDebugSupport) { 2251 AcquireMpSpinLock (&mDebugMpContext.DebugPortSpinLock); 2252 2253 if (MultiProcessorDebugSupport()) { 1103 2254 if (IsBsp (ProcessorIndex)) { 1104 2255 // … … 1114 2265 1115 2266 if (!IsBsp (ProcessorIndex) || mDebugMpContext.IpiSentByAp) { 2267 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock); 1116 2268 // 1117 2269 // If current processor is not BSP or this is one IPI sent by AP … … 1132 2284 // Only BSP could run here 1133 2285 // 1134 1135 AcquireDebugPortControl (); 1136 1137 while (DebugPortPollBuffer (Handle)) { 1138 // 1139 // If there is data in debug port, will check whether it is break-in symbol, 2286 while (TRUE) { 2287 // 2288 // If there is data in debug port, will check whether it is break(attach/break-in) symbol, 1140 2289 // If yes, go into communication mode with HOST. 1141 2290 // If no, exit interrupt process. 1142 2291 // 1143 DebugPortReadBuffer (Handle, &InputCharacter, 1, 0); 1144 if (InputCharacter == DEBUG_STARTING_SYMBOL_BREAK) { 2292 if (DebugReadBreakSymbol (Handle, &InputCharacter) == EFI_NOT_FOUND) { 2293 break; 2294 } 2295 2296 if ((!IsHostAttached () && (InputCharacter == DEBUG_STARTING_SYMBOL_ATTACH)) || 2297 (IsHostAttached () && (InputCharacter == DEBUG_COMMAND_HALT)) || 2298 (IsHostAttached () && (InputCharacter == DEBUG_COMMAND_GO)) 2299 ) { 2300 DebugAgentMsgPrint (DEBUG_AGENT_VERBOSE, "Received data [%02x]\n", InputCharacter); 2301 // 2302 // Ack OK for break-in symbol 2303 // 1145 2304 SendAckPacket (DEBUG_COMMAND_OK); 1146 if (MultiProcessorDebugSupport) { 1147 if(FindCpuNotRunning () != -1) { 2305 2306 // 2307 // If receive GO command in Debug Timer, means HOST may lost ACK packet before. 2308 // 2309 if (InputCharacter == DEBUG_COMMAND_GO) { 2310 break; 2311 } 2312 2313 if (!IsHostAttached ()) { 2314 // 2315 // Try to attach HOST, if no ack received after 200ms, return 2316 // 2317 if (AttachHost (BreakCause, READ_PACKET_TIMEOUT, &BreakReceived) != RETURN_SUCCESS) { 2318 break; 2319 } 2320 } 2321 2322 if (MultiProcessorDebugSupport()) { 2323 if(FindNextPendingBreakCpu () != -1) { 1148 2324 SetCpuBreakFlagByIndex (ProcessorIndex, TRUE); 1149 2325 } else { … … 1151 2327 } 1152 2328 } 1153 Release DebugPortControl ();2329 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock); 1154 2330 CommandCommunication (Vector, CpuContext, BreakReceived); 1155 Acquire DebugPortControl ();2331 AcquireMpSpinLock (&mDebugMpContext.DebugPortSpinLock); 1156 2332 break; 1157 2333 } … … 1163 2339 SendApicEoi (); 1164 2340 1165 Release DebugPortControl ();2341 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock); 1166 2342 1167 2343 break; 1168 2344 1169 2345 default: 1170 1171 2346 if (Vector <= DEBUG_EXCEPT_SIMD) { 1172 1173 AcquireDebugPortControl (); 1174 1175 if (MultiProcessorDebugSupport) { 1176 if(FindCpuNotRunning () != -1) { 1177 SetCpuBreakFlagByIndex (ProcessorIndex, TRUE); 1178 } else { 1179 HaltOtherProcessors (ProcessorIndex); 2347 if (BreakCause == DEBUG_DATA_BREAK_CAUSE_STEPPING) { 2348 // 2349 // Stepping is finished, send Ack package. 2350 // 2351 if (MultiProcessorDebugSupport()) { 2352 mDebugMpContext.BreakAtCpuIndex = ProcessorIndex; 1180 2353 } 1181 } 1182 SendAckPacket (DEBUG_COMMAND_BREAK_POINT); 1183 WaitForAckPacketOK (0, &BreakReceived); 1184 ReleaseDebugPortControl (); 2354 SendAckPacket (DEBUG_COMMAND_OK); 2355 } else { 2356 // 2357 // Exception occurs, send Break packet to HOST 2358 // 2359 AcquireMpSpinLock (&mDebugMpContext.DebugPortSpinLock); 2360 // 2361 // Only the first breaking processor could send BREAK_POINT to HOST 2362 // 2363 if (IsFirstBreakProcessor (ProcessorIndex)) { 2364 SendBreakPacketToHost (BreakCause, ProcessorIndex, &BreakReceived); 2365 } 2366 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock); 2367 } 2368 1185 2369 CommandCommunication (Vector, CpuContext, BreakReceived); 1186 2370 } … … 1188 2372 } 1189 2373 1190 if (MultiProcessorDebugSupport ) {2374 if (MultiProcessorDebugSupport()) { 1191 2375 // 1192 2376 // Clear flag and wait for all processors run here 1193 2377 // 1194 2378 SetIpiSentByApFlag (FALSE); 1195 while (mDebugMpContext.RunCommandSet); 2379 while (mDebugMpContext.RunCommandSet) { 2380 CpuPause (); 2381 } 2382 2383 // 2384 // Only current (view) processor could clean up AgentInProgress flag. 2385 // 2386 if (mDebugMpContext.ViewPointIndex == ProcessorIndex) { 2387 IssuedViewPoint = mDebugMpContext.ViewPointIndex; 2388 } 2389 } 2390 2391 if (IssuedViewPoint == ProcessorIndex && GetDebugFlag (DEBUG_AGENT_FLAG_STEPPING) != 1) { 2392 // 2393 // If the command is not stepping, clean up AgentInProgress flag 2394 // 2395 SetDebugFlag (DEBUG_AGENT_FLAG_AGENT_IN_PROGRESS, 0); 1196 2396 } 1197 2397 -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.h
r48674 r58459 2 2 Command header of for Debug Agent library instance. 3 3 4 Copyright (c) 2010 - 201 1, Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 17 17 18 18 #include <Register/LocalApic.h> 19 20 19 #include <Guid/DebugAgentGuid.h> 21 20 #include <Guid/VectorHandoffTable.h> 21 #include <Ppi/VectorHandoffInfo.h> 22 22 #include <Library/BaseLib.h> 23 23 #include <Library/BaseMemoryLib.h> … … 31 31 #include <Library/LocalApicLib.h> 32 32 #include <Library/DebugLib.h> 33 #include <Library/TimerLib.h> 34 #include <Library/PrintLib.h> 35 #include <Library/PeCoffGetEntryPointLib.h> 36 #include <Library/PeCoffExtraActionLib.h> 33 37 34 38 #include <TransferProtocol.h> … … 38 42 #include "DebugTimer.h" 39 43 #include "ArchDebugSupport.h" 40 41 #define DEBUG_AGENT_REVISION ((0 << 16) | 01) 42 #define DEBUG_AGENT_CAPABILITIES 0 43 44 #define DEBUG_INT1_VECTOR 1 45 #define DEBUG_INT3_VECTOR 3 44 #include "DebugException.h" 45 46 // 47 // These macros may be already defined in DebugAgentLib.h 48 // 49 #define DEBUG_AGENT_INIT_PEI 9 50 #define DEBUG_AGENT_INIT_DXE_LOAD 10 51 #define DEBUG_AGENT_INIT_DXE_UNLOAD 11 52 #define DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64 12 53 54 #define DEBUG_INT1_VECTOR DEBUG_EXCEPT_DEBUG 55 #define DEBUG_INT3_VECTOR DEBUG_EXCEPT_BREAKPOINT 46 56 #define DEBUG_TIMER_VECTOR 32 47 57 #define DEBUG_MAILBOX_VECTOR 33 58 59 // 60 // Timeout value for reading packet (unit is microsecond) 61 // 62 #define READ_PACKET_TIMEOUT (500 * 1000) 48 63 49 64 #define SOFT_INTERRUPT_SIGNATURE SIGNATURE_32('S','O','F','T') … … 53 68 extern UINTN Exception0Handle; 54 69 extern UINTN TimerInterruptHandle; 55 extern UINT16 ExceptionStubHeaderSize; 56 70 extern UINT32 ExceptionStubHeaderSize; 71 extern BOOLEAN mSkipBreakpoint; 72 extern EFI_VECTOR_HANDOFF_INFO mVectorHandoffInfoDebugAgent[]; 73 extern UINTN mVectorHandoffInfoCount; 74 75 // 76 // CPU exception information issued by debug agent 77 // 78 typedef struct { 79 // 80 // This field is used to save CPU content before executing HOST command 81 // 82 BASE_LIBRARY_JUMP_BUFFER JumpBuffer; 83 // 84 // This field returns the exception information issued by the HOST command 85 // 86 DEBUG_DATA_RESPONSE_GET_EXCEPTION ExceptionContent; 87 } DEBUG_AGENT_EXCEPTION_BUFFER; 88 89 #define DEBUG_AGENT_FLAG_HOST_ATTACHED BIT0 90 #define DEBUG_AGENT_FLAG_AGENT_IN_PROGRESS BIT1 91 #define DEBUG_AGENT_FLAG_MEMORY_READY BIT2 92 #define DEBUG_AGENT_FLAG_STEPPING BIT3 93 #define DEBUG_AGENT_FLAG_CHECK_MAILBOX_IN_HOB BIT4 94 #define DEBUG_AGENT_FLAG_INIT_ARCH BIT5|BIT6 95 #define DEBUG_AGENT_FLAG_BREAK_ON_NEXT_SMI BIT32 96 #define DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL (BIT33|BIT34|BIT35|BIT36) 97 #define DEBUG_AGENT_FLAG_BREAK_BOOT_SCRIPT BIT37 98 99 #define DEBUG_MAILBOX_DEBUG_FLAG_INDEX 1 100 #define DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX 2 101 #define DEBUG_MAILBOX_EXCEPTION_BUFFER_POINTER_INDEX 3 102 #define DEBUG_MAILBOX_LAST_ACK 4 103 #define DEBUG_MAILBOX_SEQUENCE_NO_INDEX 5 104 #define DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX 6 105 106 #pragma pack(1) 57 107 typedef union { 58 108 struct { 59 UINT32 HostPresent : 1; 60 UINT32 BreakOnNextSmi : 1; 61 UINT32 Reserved : 30; 109 // 110 // Lower 32 bits to store the status of DebugAgent 111 // 112 UINT32 HostAttached : 1; // 1: HOST is attached 113 UINT32 AgentInProgress : 1; // 1: Debug Agent is communicating with HOST 114 UINT32 MemoryReady : 1; // 1: Memory is ready 115 UINT32 SteppingFlag : 1; // 1: Agent is running stepping command 116 UINT32 CheckMailboxInHob : 1; // 1: Need to check mailbox saved in HOB 117 UINT32 InitArch : 2; // value of DEBUG_DATA_RESPONSE_ARCH_MODE 118 UINT32 Reserved1 : 25; 119 // 120 // Higher 32bits to control the behavior of DebugAgent 121 // 122 UINT32 BreakOnNextSmi : 1; // 1: Break on next SMI 123 UINT32 PrintErrorLevel : 4; // Bitmask of print error level for debug message 124 UINT32 BreakOnBootScript : 1; // 1: Break before executing boot script 125 UINT32 Reserved2 : 26; 62 126 } Bits; 63 UINT 32 Uint32;127 UINT64 Uint64; 64 128 } DEBUG_AGENT_FLAG; 65 129 66 #pragma pack(1)67 130 typedef struct { 68 131 DEBUG_AGENT_FLAG DebugFlag; 69 132 UINT64 DebugPortHandle; 133 // 134 // Pointer to DEBUG_AGENT_EXCEPTION_BUFFER 135 // 136 UINT64 ExceptionBufferPointer; 137 UINT8 LastAck; // The last ack packet type 138 UINT8 SequenceNo; 139 UINT8 HostSequenceNo; 140 UINT8 CheckSum; // Mailbox checksum 141 UINT8 ToBeCheckSum; // To be Mailbox checksum at the next 70 142 } DEBUG_AGENT_MAILBOX; 71 143 #pragma pack() 144 145 /// 146 /// Byte packed structure for an IA-32 Interrupt Gate Descriptor. 147 /// 148 typedef union { 149 struct { 150 UINT32 OffsetLow:16; ///< Offset bits 15..0. 151 UINT32 Selector:16; ///< Selector. 152 UINT32 Reserved_0:8; ///< Reserved. 153 UINT32 GateType:8; ///< Gate Type. See #defines above. 154 UINT32 OffsetHigh:16; ///< Offset bits 31..16. 155 } Bits; 156 UINT64 Uint64; 157 } IA32_IDT_ENTRY; 158 72 159 73 160 typedef union { … … 91 178 92 179 /** 93 Caller provided function to be invoked at the end of DebugPortInitialize().94 95 Refer to the descrption for DebugPortInitialize() for more details.96 97 @param[in] Context The first input argument of DebugPortInitialize().98 @param[in] DebugPortHandle Debug port handle created by Debug Communication Libary.99 100 **/101 VOID102 EFIAPI103 InitializeDebugAgentPhase2 (104 IN VOID *Context,105 IN DEBUG_PORT_HANDLE DebugPortHandle106 );107 108 /**109 180 Initialize IDT entries to support source level debug. 110 181 … … 116 187 117 188 /** 118 Write specified register into saveCPU context.189 Read register value from saved CPU context. 119 190 120 191 @param[in] CpuContext Pointer to saved CPU context. 121 192 @param[in] Index Register index value. 122 @param[in] Offset Offset in register address range123 @param[in] Width Data width to read.124 @param[in] RegisterBuffer Pointer to input buffer with data.125 126 **/127 VOID128 ArchWriteRegisterBuffer (129 IN DEBUG_CPU_CONTEXT *CpuContext,130 IN UINT8 Index,131 IN UINT8 Offset,132 IN UINT8 Width,133 IN UINT8 *RegisterBuffer134 );135 136 /**137 Read register value from saved CPU context.138 139 @param[in] CpuContext Pointer to saved CPU context.140 @param[in] Index Register index value.141 @param[in] Offset Offset in register address range142 193 @param[in] Width Data width to read. 143 194 … … 149 200 IN DEBUG_CPU_CONTEXT *CpuContext, 150 201 IN UINT8 Index, 151 IN UINT8 Offset,152 202 IN UINT8 *Width 153 203 ); … … 156 206 Send packet with response data to HOST. 157 207 158 @param[in] CpuContext Pointer to saved CPU context.159 208 @param[in] Data Pointer to response data buffer. 160 209 @param[in] DataSize Size of response data in byte. … … 166 215 RETURN_STATUS 167 216 SendDataResponsePacket ( 168 IN DEBUG_CPU_CONTEXT *CpuContext,169 217 IN UINT8 *Data, 170 218 IN UINT16 DataSize … … 172 220 173 221 /** 174 Read segment selector by register index. 175 176 @param[in] CpuContext Pointer to saved CPU context. 177 @param[in] RegisterIndex Register Index. 178 179 @return Value of segment selector. 180 181 **/ 182 UINT64 183 ReadRegisterSelectorByIndex ( 184 IN DEBUG_CPU_CONTEXT *CpuContext, 185 IN UINT8 RegisterIndex 186 ); 187 188 /** 189 Read group register of common registers. 190 191 @param[in] CpuContext Pointer to saved CPU context. 192 @param[in] RegisterGroup Pointer to Group registers. 193 194 **/ 195 VOID 196 ReadRegisterGroup ( 197 IN DEBUG_CPU_CONTEXT *CpuContext, 198 IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP *RegisterGroup 199 ); 200 201 /** 202 Read group register of Segment Base. 203 204 @param[in] CpuContext Pointer to saved CPU context. 205 @param[in] RegisterGroupSegBase Pointer to Group registers. 206 207 **/ 208 VOID 209 ReadRegisterGroupSegBase ( 210 IN DEBUG_CPU_CONTEXT *CpuContext, 211 IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE *RegisterGroupSegBase 212 ); 213 214 /** 215 Read gourp register of Segment Limit. 216 217 @param[in] CpuContext Pointer to saved CPU context. 218 @param[in] RegisterGroupSegLim Pointer to Group registers. 219 220 **/ 221 VOID 222 ReadRegisterGroupSegLim ( 223 IN DEBUG_CPU_CONTEXT *CpuContext, 224 IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM *RegisterGroupSegLim 225 ); 226 227 /** 228 Read group register by group index. 229 230 @param[in] CpuContext Pointer to saved CPU context. 231 @param[in] GroupIndex Group Index. 232 233 @retval RETURN_SUCCESS Read successfully. 234 @retval RETURN_NOT_SUPPORTED Group index cannot be supported. 235 236 **/ 237 RETURN_STATUS 238 ArchReadRegisterGroup ( 239 IN DEBUG_CPU_CONTEXT *CpuContext, 240 IN UINT8 GroupIndex 241 ); 242 243 /** 244 Send acknowledge packet to HOST. 245 246 @param AckCommand Type of Acknowledge packet. 247 248 **/ 249 VOID 250 SendAckPacket ( 251 IN UINT8 AckCommand 252 ); 253 254 /** 255 Receive acknowledge packet OK from HOST in specified time. 256 257 @param[in] Timeout Time out value to wait for acknowlege from HOST. 258 The unit is microsecond. 259 @param[out] BreakReceived If BreakReceived is not NULL, 260 TRUE is retured if break-in symbol received. 261 FALSE is retured if break-in symbol not received. 262 263 @retval RETRUEN_SUCCESS Succeed to receive acknowlege packet from HOST, 264 the type of acknowlege packet saved in Ack. 265 @retval RETURN_TIMEOUT Specified timeout value was up. 266 267 **/ 268 RETURN_STATUS 269 WaitForAckPacketOK ( 270 IN UINTN Timeout, 271 OUT BOOLEAN *BreakReceived OPTIONAL 272 ); 273 274 /** 275 Check if HOST is connected based on Mailbox. 276 277 @retval TRUE HOST is connected. 278 @retval FALSE HOST is not connected. 222 Check if HOST is attached based on Mailbox. 223 224 @retval TRUE HOST is attached. 225 @retval FALSE HOST is not attached. 279 226 280 227 **/ 281 228 BOOLEAN 282 IsHost Connected (229 IsHostAttached ( 283 230 VOID 284 231 ); … … 306 253 ); 307 254 255 /** 256 Read the Attach/Break-in symbols from the debug port. 257 258 @param[in] Handle Pointer to Debug Port handle. 259 @param[out] BreakSymbol Returned break symbol. 260 261 @retval EFI_SUCCESS Read the symbol in BreakSymbol. 262 @retval EFI_NOT_FOUND No read the break symbol. 263 264 **/ 265 EFI_STATUS 266 DebugReadBreakSymbol ( 267 IN DEBUG_PORT_HANDLE Handle, 268 OUT UINT8 *BreakSymbol 269 ); 270 271 /** 272 Prints a debug message to the debug port if the specified error level is enabled. 273 274 If any bit in ErrorLevel is also set in Mainbox, then print the message specified 275 by Format and the associated variable argument list to the debug port. 276 277 @param[in] ErrorLevel The error level of the debug message. 278 @param[in] Format Format string for the debug message to print. 279 @param[in] ... Variable argument list whose contents are accessed 280 based on the format string specified by Format. 281 282 **/ 283 VOID 284 EFIAPI 285 DebugAgentMsgPrint ( 286 IN UINT8 ErrorLevel, 287 IN CHAR8 *Format, 288 ... 289 ); 290 291 /** 292 Trigger one software interrupt to debug agent to handle it. 293 294 @param[in] Signature Software interrupt signature. 295 296 **/ 297 VOID 298 TriggerSoftInterrupt ( 299 IN UINT32 Signature 300 ); 301 302 /** 303 Check if debug agent support multi-processor. 304 305 @retval TRUE Multi-processor is supported. 306 @retval FALSE Multi-processor is not supported. 307 308 **/ 309 BOOLEAN 310 MultiProcessorDebugSupport ( 311 VOID 312 ); 313 314 /** 315 Find and report module image info to HOST. 316 317 @param[in] AlignSize Image aligned size. 318 319 **/ 320 VOID 321 FindAndReportModuleImageInfo ( 322 IN UINTN AlignSize 323 ); 324 325 /** 326 Read IDT entry to check if IDT entries are setup by Debug Agent. 327 328 @retval TRUE IDT entries were setup by Debug Agent. 329 @retval FALSE IDT entries were not setup by Debug Agent. 330 331 **/ 332 BOOLEAN 333 IsDebugAgentInitialzed ( 334 VOID 335 ); 336 337 /** 338 Caculate Mailbox checksum and update the checksum field. 339 340 @param[in] Mailbox Debug Agent Mailbox pointer. 341 342 **/ 343 VOID 344 UpdateMailboxChecksum ( 345 IN DEBUG_AGENT_MAILBOX *Mailbox 346 ); 347 348 /** 349 Verify Mailbox checksum. 350 351 If checksum error, print debug message and run init dead loop. 352 353 @param[in] Mailbox Debug Agent Mailbox pointer. 354 355 **/ 356 VOID 357 VerifyMailboxChecksum ( 358 IN DEBUG_AGENT_MAILBOX *Mailbox 359 ); 360 361 /** 362 Set debug flag in mailbox. 363 364 @param[in] FlagMask Debug flag mask value. 365 @param[in] FlagValue Debug flag value. 366 367 **/ 368 VOID 369 SetDebugFlag ( 370 IN UINT64 FlagMask, 371 IN UINT32 FlagValue 372 ); 373 374 /** 375 Get debug flag in mailbox. 376 377 @param[in] FlagMask Debug flag mask value. 378 379 @return Debug flag value. 380 381 **/ 382 UINT32 383 GetDebugFlag ( 384 IN UINT64 FlagMask 385 ); 386 387 /** 388 Update Mailbox content by index. 389 390 @param[in] Mailbox Debug Agent Mailbox pointer. 391 @param[in] Index Mailbox content index. 392 @param[in] Value Value to be set into mail box. 393 394 **/ 395 VOID 396 UpdateMailboxContent ( 397 IN DEBUG_AGENT_MAILBOX *Mailbox, 398 IN UINTN Index, 399 IN UINT64 Value 400 ); 401 402 /** 403 Retrieve exception handler from IDT table by ExceptionNum. 404 405 @param[in] ExceptionNum Exception number 406 407 @return Exception handler 408 409 **/ 410 VOID * 411 GetExceptionHandlerInIdtEntry ( 412 IN UINTN ExceptionNum 413 ); 414 415 /** 416 Set exception handler in IDT table by ExceptionNum. 417 418 @param[in] ExceptionNum Exception number 419 @param[in] ExceptionHandler Exception Handler to be set 420 421 **/ 422 VOID 423 SetExceptionHandlerInIdtEntry ( 424 IN UINTN ExceptionNum, 425 IN VOID *ExceptionHandler 426 ); 427 428 /** 429 Prints a debug message to the debug output device if the specified error level is enabled. 430 431 If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function 432 GetDebugPrintErrorLevel (), then print the message specified by Format and the 433 associated variable argument list to the debug output device. 434 435 If Format is NULL, then ASSERT(). 436 437 @param[in] ErrorLevel The error level of the debug message. 438 @param[in] IsSend Flag of debug message to declare that the data is being sent or being received. 439 @param[in] Data Variable argument list whose contents are accessed 440 @param[in] Length based on the format string specified by Format. 441 442 **/ 443 VOID 444 EFIAPI 445 DebugAgentDataMsgPrint ( 446 IN UINT8 ErrorLevel, 447 IN BOOLEAN IsSend, 448 IN UINT8 *Data, 449 IN UINT8 Length 450 ); 451 452 /** 453 Read remaing debug packet except for the start symbol 454 455 @param[in] Handle Pointer to Debug Port handle. 456 @param[in, out] DebugHeader Debug header buffer including start symbol. 457 458 @retval EFI_SUCCESS Read the symbol in BreakSymbol. 459 @retval EFI_CRC_ERROR CRC check fail. 460 @retval EFI_TIMEOUT Timeout occurs when reading debug packet. 461 462 **/ 463 EFI_STATUS 464 ReadRemainingBreakPacket ( 465 IN DEBUG_PORT_HANDLE Handle, 466 IN OUT DEBUG_PACKET_HEADER *DebugHeader 467 ); 468 308 469 #endif 309 470 -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugMp.c
r48674 r58459 2 2 Multi-Processor support functions implementation. 3 3 4 Copyright (c) 2010 - 201 1, Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 15 15 #include "DebugAgent.h" 16 16 17 DEBUG_MP_CONTEXT volatile mDebugMpContext = {0,0,0,0,0,0,0,0,FALSE,FALSE};18 19 DEBUG_CPU_DATA volatile mDebugCpuData = {0};20 21 /** 22 Acquire a ccess control on debug port.17 GLOBAL_REMOVE_IF_UNREFERENCED DEBUG_MP_CONTEXT volatile mDebugMpContext = {0,0,0,{0},{0},0,0,0,0,FALSE,FALSE}; 18 19 GLOBAL_REMOVE_IF_UNREFERENCED DEBUG_CPU_DATA volatile mDebugCpuData = {0}; 20 21 /** 22 Acquire a spin lock when Multi-processor supported. 23 23 24 24 It will block in the function if cannot get the access control. 25 26 **/ 27 VOID 28 AcquireDebugPortControl ( 29 VOID 30 ) 31 { 32 if (!MultiProcessorDebugSupport) { 25 If Multi-processor is not supported, return directly. 26 27 @param[in, out] MpSpinLock A pointer to the spin lock. 28 29 **/ 30 VOID 31 AcquireMpSpinLock ( 32 IN OUT SPIN_LOCK *MpSpinLock 33 ) 34 { 35 if (!MultiProcessorDebugSupport()) { 33 36 return; 34 37 } 35 38 36 39 while (TRUE) { 37 if (AcquireSpinLockOrFail ( &mDebugMpContext.DebugPortSpinLock)) {40 if (AcquireSpinLockOrFail (MpSpinLock)) { 38 41 break; 39 42 } … … 44 47 45 48 /** 46 Release access control on debug port. 47 48 **/ 49 VOID 50 ReleaseDebugPortControl ( 51 VOID 52 ) 53 { 54 if (!MultiProcessorDebugSupport) { 49 Release a spin lock when Multi-processor supported. 50 51 @param[in, out] MpSpinLock A pointer to the spin lock. 52 53 **/ 54 VOID 55 ReleaseMpSpinLock ( 56 IN OUT SPIN_LOCK *MpSpinLock 57 ) 58 { 59 if (!MultiProcessorDebugSupport()) { 55 60 return; 56 61 } 57 62 58 ReleaseSpinLock (&mDebugMpContext.DebugPortSpinLock); 59 } 60 61 /** 62 Acquire access control on MP context. 63 64 It will block in the function if cannot get the access control. 65 66 **/ 67 VOID 68 AcquireMpContextControl ( 69 VOID 70 ) 71 { 72 while (TRUE) { 73 if (AcquireSpinLockOrFail (&mDebugMpContext.MpContextSpinLock)) { 74 break; 75 } 76 CpuPause (); 77 continue; 78 } 79 } 80 81 /** 82 Release access control on MP context. 83 84 **/ 85 VOID 86 ReleaseMpContextControl ( 87 VOID 88 ) 89 { 90 ReleaseSpinLock (&mDebugMpContext.MpContextSpinLock); 63 ReleaseSpinLock (MpSpinLock); 91 64 } 92 65 … … 102 75 ) 103 76 { 104 77 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "processor[%x]:Try to halt other processors.\n", CurrentProcessorIndex); 105 78 if (!IsBsp (CurrentProcessorIndex)) { 106 79 SetIpiSentByApFlag (TRUE);; … … 118 91 // 119 92 SendFixedIpiAllExcludingSelf (DEBUG_TIMER_VECTOR); 120 93 121 94 } 122 95 … … 137 110 LocalApicID = (UINT16) GetApicId (); 138 111 139 AcquireMp ContextControl ();112 AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock); 140 113 141 114 for (Index = 0; Index < mDebugCpuData.CpuCount; Index ++) { … … 150 123 } 151 124 152 ReleaseMp ContextControl ();125 ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock); 153 126 154 127 return Index; … … 171 144 if (AsmMsrBitFieldRead64 (MSR_IA32_APIC_BASE_ADDRESS, 8, 8) == 1) { 172 145 if (mDebugMpContext.BspIndex != ProcessorIndex) { 173 AcquireMp ContextControl ();146 AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock); 174 147 mDebugMpContext.BspIndex = ProcessorIndex; 175 ReleaseMp ContextControl ();148 ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock); 176 149 } 177 150 return TRUE; … … 198 171 UINTN Index; 199 172 200 AcquireMp ContextControl ();173 AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock); 201 174 202 175 Value = mDebugMpContext.CpuStopStatusMask[ProcessorIndex / 8]; … … 209 182 mDebugMpContext.CpuStopStatusMask[ProcessorIndex / 8] = Value; 210 183 211 ReleaseMp ContextControl ();184 ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock); 212 185 } 213 186 … … 229 202 UINTN Index; 230 203 231 AcquireMp ContextControl ();204 AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock); 232 205 233 206 Value = mDebugMpContext.CpuBreakMask[ProcessorIndex / 8]; … … 240 213 mDebugMpContext.CpuBreakMask[ProcessorIndex / 8] = Value; 241 214 242 ReleaseMp ContextControl ();215 ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock); 243 216 } 244 217 … … 280 253 ) 281 254 { 282 AcquireMpContextControl (); 283 255 AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock); 284 256 mDebugMpContext.RunCommandSet = RunningFlag; 285 286 ReleaseMpContextControl (); 257 ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock); 287 258 } 288 259 … … 298 269 ) 299 270 { 300 AcquireMpContextControl (); 301 271 AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock); 302 272 mDebugMpContext.ViewPointIndex = ProcessorIndex; 303 304 ReleaseMpContextControl (); 305 } 306 307 /** 308 Initialize debug timer. 273 ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock); 274 } 275 276 /** 277 Set the IPI send by BPS/AP flag. 309 278 310 279 @param[in] IpiSentByApFlag TRUE means this IPI is sent by AP. … … 317 286 ) 318 287 { 319 AcquireMpContextControl (); 320 288 AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock); 321 289 mDebugMpContext.IpiSentByAp = IpiSentByApFlag; 322 323 ReleaseMpContextControl (); 324 } 325 326 /** 327 Check if any processor breaks. 290 ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock); 291 } 292 293 /** 294 Check the next pending breaking CPU. 328 295 329 296 @retval others There is at least one processor broken, the minimum … … 333 300 **/ 334 301 UINT32 335 Find CpuNotRunning(302 FindNextPendingBreakCpu ( 336 303 VOID 337 304 ) 338 305 { 339 306 UINT32 Index; 340 307 341 308 for (Index = 0; Index < DEBUG_CPU_MAX_COUNT / 8; Index ++) { 342 309 if (mDebugMpContext.CpuBreakMask[Index] != 0) { … … 346 313 return (UINT32)-1; 347 314 } 348 315 349 316 /** 350 317 Check if all processors are in running status. … … 360 327 { 361 328 UINTN Index; 362 329 363 330 for (Index = 0; Index < DEBUG_CPU_MAX_COUNT / 8; Index ++) { 364 331 if (mDebugMpContext.CpuStopStatusMask[Index] != 0) { … … 369 336 } 370 337 338 /** 339 Check if the current processor is the first breaking processor. 340 341 If yes, halt other processors. 342 343 @param[in] ProcessorIndex Processor index value. 344 345 @return TRUE This processor is the first breaking processor. 346 @return FALSE This processor is not the first breaking processor. 347 348 **/ 349 BOOLEAN 350 IsFirstBreakProcessor ( 351 IN UINT32 ProcessorIndex 352 ) 353 { 354 if (MultiProcessorDebugSupport()) { 355 if (mDebugMpContext.BreakAtCpuIndex != (UINT32) -1) { 356 // 357 // The current processor is not the first breaking one. 358 // 359 SetCpuBreakFlagByIndex (ProcessorIndex, TRUE); 360 return FALSE; 361 } else { 362 // 363 // If no any processor breaks, try to halt other processors 364 // 365 HaltOtherProcessors (ProcessorIndex); 366 return TRUE; 367 } 368 } 369 return TRUE; 370 } 371 -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugMp.h
r48674 r58459 2 2 Header file for Multi-Processor support. 3 3 4 Copyright (c) 2010 , Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 26 26 SPIN_LOCK MpContextSpinLock; ///< Lock for writting MP context 27 27 SPIN_LOCK DebugPortSpinLock; ///< Lock for access debug port 28 SPIN_LOCK MailboxSpinLock; ///< Lock for accessing mail box 28 29 UINT8 CpuBreakMask[DEBUG_CPU_MAX_COUNT/8]; ///< Bitmask of all breaking CPUs 29 30 UINT8 CpuStopStatusMask[DEBUG_CPU_MAX_COUNT/8]; ///< Bitmask of CPU stop status … … 33 34 UINT32 DebugTimerInitCount; ///< Record BSP's init timer count 34 35 BOOLEAN IpiSentByAp; ///< TRUR: IPI is sent by AP. TALSE: IPI is sent by BSP 35 BOOLEAN RunCommandSet; ///< TRUE: RUN commmand is not executed. FALSE : RUN command isexecuted.36 BOOLEAN RunCommandSet; ///< TRUE: RUN commmand is executing. FALSE : RUN command has been executed. 36 37 } DEBUG_MP_CONTEXT; 37 38 38 extern CONST BOOLEAN MultiProcessorDebugSupport;39 39 extern DEBUG_MP_CONTEXT volatile mDebugMpContext; 40 40 extern DEBUG_CPU_DATA volatile mDebugCpuData; … … 63 63 64 64 /** 65 Acquire a ccess control on MP context.65 Acquire a spin lock when Multi-processor supported. 66 66 67 67 It will block in the function if cannot get the access control. 68 69 **/ 70 VOID 71 AcquireMpContextControl ( 72 VOID 73 ); 74 75 /** 76 Release access control on MP context. 77 78 **/ 79 VOID 80 ReleaseMpContextControl ( 81 VOID 82 ); 83 84 /** 85 Acquire access control on debug port. 86 87 It will block in the function if cannot get the access control. 88 89 **/ 90 VOID 91 AcquireDebugPortControl ( 92 VOID 93 ); 94 95 /** 96 Release access control on debug port. 97 98 **/ 99 VOID 100 ReleaseDebugPortControl ( 101 VOID 68 If Multi-processor is not supported, return directly. 69 70 @param[in, out] MpSpinLock A pointer to the spin lock. 71 72 **/ 73 VOID 74 AcquireMpSpinLock ( 75 IN OUT SPIN_LOCK *MpSpinLock 76 ); 77 78 /** 79 Release a spin lock when Multi-processor supported. 80 81 @param[in, out] MpSpinLock A pointer to the spin lock. 82 83 **/ 84 VOID 85 ReleaseMpSpinLock ( 86 IN OUT SPIN_LOCK *MpSpinLock 102 87 ); 103 88 … … 182 167 183 168 /** 184 Initialize debug timer.169 Set the IPI send by BPS/AP flag. 185 170 186 171 @param[in] IpiSentByApFlag TRUE means this IPI is sent by AP. … … 194 179 195 180 /** 196 Check if any processor breaks.181 Check the next pending breaking CPU. 197 182 198 183 @retval others There is at least one processor broken, the minimum … … 202 187 **/ 203 188 UINT32 204 Find CpuNotRunning(189 FindNextPendingBreakCpu ( 205 190 VOID 206 191 ); … … 218 203 ); 219 204 205 /** 206 Check if the current processor is the first breaking processor. 207 208 If yes, halt other processors. 209 210 @param[in] ProcessorIndex Processor index value. 211 212 @return TRUE This processor is the first breaking processor. 213 @return FALSE This processor is not the first breaking processor. 214 215 **/ 216 BOOLEAN 217 IsFirstBreakProcessor ( 218 IN UINT32 ProcessorIndex 219 ); 220 220 221 #endif 221 222 -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugTimer.c
r48674 r58459 2 2 Code for debug timer to support debug agent library implementation. 3 3 4 Copyright (c) 2010 , Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 18 18 Initialize CPU local APIC timer. 19 19 20 @return 32-bit Local APIC timer init count. 20 21 **/ 21 VOID 22 UINT32 22 23 InitializeDebugTimer ( 23 24 VOID … … 42 43 InitializeApicTimer (ApicTimerDivisor, InitialCount, TRUE, DEBUG_TIMER_VECTOR); 43 44 44 if (MultiProcessorDebugSupport) { 45 mDebugMpContext.DebugTimerInitCount = InitialCount; 46 } 45 return InitialCount; 47 46 } 48 47 … … 66 65 ) 67 66 { 68 BOOLEAN OldInterruptState;69 67 BOOLEAN OldDebugTimerInterruptState; 70 68 71 OldInterruptState = SaveAndDisableInterrupts ();72 69 OldDebugTimerInterruptState = GetApicTimerInterruptState (); 73 74 if (EnableStatus) { 75 EnableApicTimerInterrupt (); 76 } else { 77 DisableApicTimerInterrupt (); 70 71 if (OldDebugTimerInterruptState != EnableStatus) { 72 if (EnableStatus) { 73 EnableApicTimerInterrupt (); 74 } else { 75 DisableApicTimerInterrupt (); 76 } 77 // 78 // Validate the Debug Timer interrupt state 79 // This will make additional delay after Local Apic Timer interrupt state is changed. 80 // Thus, CPU could handle the potential pending interrupt of Local Apic timer. 81 // 82 while (GetApicTimerInterruptState () != EnableStatus) { 83 CpuPause (); 84 } 78 85 } 79 86 80 SetInterruptState (OldInterruptState);81 87 return OldDebugTimerInterruptState; 82 88 } -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugTimer.h
r48674 r58459 2 2 Header file for debug timer to support debug agent library implementation. 3 3 4 Copyright (c) 2010 , Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 17 17 18 18 /** 19 Initialize debugtimer.19 Initialize CPU local APIC timer. 20 20 21 @return 32-bit Local APIC timer init count. 21 22 **/ 22 VOID 23 UINT32 23 24 InitializeDebugTimer ( 24 25 VOID -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.c
r48674 r58459 1 1 /** @file 2 Public include file for Debug Port Library.2 Supporting functions for IA32 architecture. 3 3 4 Copyright (c) 2010 , Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 14 14 15 15 #include "DebugAgent.h" 16 17 /**18 Read the offset of FP / MMX / XMM registers by register index.19 20 @param[in] Index Register index.21 @param[out] Width Register width returned.22 23 @return Offset in register address range.24 25 **/26 UINT1627 ArchReadFxStatOffset (28 IN UINT8 Index,29 OUT UINT8 *Width30 )31 {32 if (Index < SOFT_DEBUGGER_REGISTER_ST0) {33 switch (Index) {34 case SOFT_DEBUGGER_REGISTER_FP_FCW:35 *Width = (UINT8) sizeof (UINT16);36 return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Fcw);37 38 case SOFT_DEBUGGER_REGISTER_FP_FSW:39 *Width = (UINT8) sizeof (UINT16);40 return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Fsw);41 42 case SOFT_DEBUGGER_REGISTER_FP_FTW:43 *Width = (UINT8) sizeof (UINT16);44 return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Ftw);45 46 case SOFT_DEBUGGER_REGISTER_FP_OPCODE:47 *Width = (UINT8) sizeof (UINT16);48 return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Opcode);49 50 case SOFT_DEBUGGER_REGISTER_FP_EIP:51 *Width = (UINT8) sizeof (UINTN);52 return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Eip);53 54 case SOFT_DEBUGGER_REGISTER_FP_CS:55 *Width = (UINT8) sizeof (UINT16);56 return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Cs);57 58 case SOFT_DEBUGGER_REGISTER_FP_DATAOFFSET:59 *Width = (UINT8) sizeof (UINTN);60 return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, DataOffset);61 62 case SOFT_DEBUGGER_REGISTER_FP_DS:63 *Width = (UINT8) sizeof (UINT16);64 return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Ds);65 66 case SOFT_DEBUGGER_REGISTER_FP_MXCSR:67 *Width = (UINT8) sizeof (UINTN);68 return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Mxcsr);69 70 case SOFT_DEBUGGER_REGISTER_FP_MXCSR_MASK:71 *Width = (UINT8) sizeof (UINTN);72 return (UINT16)OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, Mxcsr_Mask);73 }74 }75 76 if (Index < SOFT_DEBUGGER_REGISTER_XMM0) {77 *Width = 10;78 } else if (Index < SOFT_DEBUGGER_REGISTER_MM0 ) {79 *Width = 16;80 } else {81 *Width = 8;82 Index -= SOFT_DEBUGGER_REGISTER_MM0 - SOFT_DEBUGGER_REGISTER_ST0;83 }84 85 return (UINT16)(OFFSET_OF(DEBUG_DATA_IA32_FX_SAVE_STATE, St0Mm0) + (Index - SOFT_DEBUGGER_REGISTER_ST0) * 16);86 }87 88 /**89 Write specified register into save CPU context.90 91 @param[in] CpuContext Pointer to saved CPU context.92 @param[in] Index Register index value.93 @param[in] Offset Offset in register address range.94 @param[in] Width Data width to read.95 @param[in] RegisterBuffer Pointer to input buffer with data.96 97 **/98 VOID99 ArchWriteRegisterBuffer (100 IN DEBUG_CPU_CONTEXT *CpuContext,101 IN UINT8 Index,102 IN UINT8 Offset,103 IN UINT8 Width,104 IN UINT8 *RegisterBuffer105 )106 {107 UINT8 *Buffer;108 if (Index < SOFT_DEBUGGER_REGISTER_FP_BASE) {109 Buffer = (UINT8 *) CpuContext + sizeof (DEBUG_DATA_IA32_FX_SAVE_STATE) + Index * 4;110 } else {111 //112 // If it is MMX register, adjust its index position113 //114 if (Index >= SOFT_DEBUGGER_REGISTER_MM0) {115 Index -= SOFT_DEBUGGER_REGISTER_MM0 - SOFT_DEBUGGER_REGISTER_ST0;116 }117 //118 // FPU/MMX/XMM registers119 //120 Buffer = (UINT8 *) CpuContext + ArchReadFxStatOffset (Index, &Width);121 }122 123 CopyMem (Buffer + Offset, RegisterBuffer, Width);124 }125 126 /**127 Read register value from saved CPU context.128 129 @param[in] CpuContext Pointer to saved CPU context.130 @param[in] Index Register index value.131 @param[in] Offset Offset in register address range132 @param[in] Width Data width to read.133 134 @return The address of register value.135 136 **/137 UINT8 *138 ArchReadRegisterBuffer (139 IN DEBUG_CPU_CONTEXT *CpuContext,140 IN UINT8 Index,141 IN UINT8 Offset,142 IN UINT8 *Width143 )144 {145 UINT8 *Buffer;146 147 if (Index < SOFT_DEBUGGER_REGISTER_FP_BASE) {148 Buffer = (UINT8 *) CpuContext + sizeof (DEBUG_DATA_IA32_FX_SAVE_STATE) + Index * 4;149 if (*Width == 0) {150 *Width = (UINT8) sizeof (UINTN);151 }152 } else {153 //154 // FPU/MMX/XMM registers155 //156 Buffer = (UINT8 *) CpuContext + ArchReadFxStatOffset (Index, Width);157 }158 159 return Buffer;160 }161 162 /**163 Read group register of common registers.164 165 @param[in] CpuContext Pointer to saved CPU context.166 @param[in] RegisterGroup Pointer to Group registers.167 168 **/169 VOID170 ReadRegisterGroup (171 IN DEBUG_CPU_CONTEXT *CpuContext,172 IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP *RegisterGroup173 )174 {175 RegisterGroup->Cs = (UINT16) CpuContext->Cs;176 RegisterGroup->Ds = (UINT16) CpuContext->Ds;177 RegisterGroup->Es = (UINT16) CpuContext->Es;178 RegisterGroup->Fs = (UINT16) CpuContext->Fs;179 RegisterGroup->Gs = (UINT16) CpuContext->Gs;180 RegisterGroup->Ss = (UINT16) CpuContext->Ss;181 RegisterGroup->Eflags = CpuContext->Eflags;182 RegisterGroup->Ebp = CpuContext->Ebp;183 RegisterGroup->Eip = CpuContext->Eip;184 RegisterGroup->Esp = CpuContext->Esp;185 RegisterGroup->Eax = CpuContext->Eax;186 RegisterGroup->Ebx = CpuContext->Ebx;187 RegisterGroup->Ecx = CpuContext->Ecx;188 RegisterGroup->Edx = CpuContext->Edx;189 RegisterGroup->Esi = CpuContext->Esi;190 RegisterGroup->Edi = CpuContext->Edi;191 RegisterGroup->Dr0 = CpuContext->Dr0;192 RegisterGroup->Dr1 = CpuContext->Dr1;193 RegisterGroup->Dr2 = CpuContext->Dr2;194 RegisterGroup->Dr3 = CpuContext->Dr3;195 RegisterGroup->Dr6 = CpuContext->Dr6;196 RegisterGroup->Dr7 = CpuContext->Dr7;197 }198 16 199 17 /** … … 222 40 223 41 for (Index = 0; Index < 20; Index ++) { 224 if (( PcdGet32 (PcdExceptionsIgnoredByDebugger) & (1 << Index)) != 0) {42 if (((PcdGet32 (PcdExceptionsIgnoredByDebugger) & ~(BIT1 | BIT3)) & (1 << Index)) != 0) { 225 43 // 226 // If the exception is masked to be reserved , skip it44 // If the exception is masked to be reserved except for INT1 and INT3, skip it 227 45 // 228 46 continue; … … 231 49 IdtEntry[Index].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler; 232 50 IdtEntry[Index].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16); 233 IdtEntry[Index].Bits.Selector 234 IdtEntry[Index].Bits.GateType 51 IdtEntry[Index].Bits.Selector = CodeSegment; 52 IdtEntry[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; 235 53 } 236 54 … … 238 56 IdtEntry[DEBUG_TIMER_VECTOR].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler; 239 57 IdtEntry[DEBUG_TIMER_VECTOR].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16); 240 IdtEntry[Index].Bits.Selector = CodeSegment; 241 IdtEntry[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; 58 IdtEntry[DEBUG_TIMER_VECTOR].Bits.Selector = CodeSegment; 59 IdtEntry[DEBUG_TIMER_VECTOR].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; 60 61 // 62 // Set DE flag in CR4 to enable IO breakpoint 63 // 64 AsmWriteCr4 (AsmReadCr4 () | BIT3); 242 65 } 66 67 /** 68 Retrieve exception handler from IDT table by ExceptionNum. 69 70 @param[in] ExceptionNum Exception number 71 72 @return Exception handler 73 74 **/ 75 VOID * 76 GetExceptionHandlerInIdtEntry ( 77 IN UINTN ExceptionNum 78 ) 79 { 80 IA32_IDT_GATE_DESCRIPTOR *IdtEntry; 81 IA32_DESCRIPTOR IdtDescriptor; 82 83 AsmReadIdtr (&IdtDescriptor); 84 IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base; 85 86 return (VOID *) (((UINTN)IdtEntry[ExceptionNum].Bits.OffsetLow) | 87 (((UINTN)IdtEntry[ExceptionNum].Bits.OffsetHigh) << 16)); 88 } 89 90 /** 91 Set exception handler in IDT table by ExceptionNum. 92 93 @param[in] ExceptionNum Exception number 94 @param[in] ExceptionHandler Exception Handler to be set 95 96 **/ 97 VOID 98 SetExceptionHandlerInIdtEntry ( 99 IN UINTN ExceptionNum, 100 IN VOID *ExceptionHandler 101 ) 102 { 103 IA32_IDT_GATE_DESCRIPTOR *IdtEntry; 104 IA32_DESCRIPTOR IdtDescriptor; 105 106 AsmReadIdtr (&IdtDescriptor); 107 IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base; 108 109 IdtEntry[ExceptionNum].Bits.OffsetLow = (UINT16)(UINTN)ExceptionHandler; 110 IdtEntry[ExceptionNum].Bits.OffsetHigh = (UINT16)((UINTN)ExceptionHandler >> 16); 111 } -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.h
r48674 r58459 2 2 IA32 specific defintions for debug agent library instance. 3 3 4 Copyright (c) 2010 , Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 16 16 #define _ARCH_DEBUG_SUPPORT_H_ 17 17 18 #include " ArchRegisters.h"18 #include "ProcessorContext.h" 19 19 #include "TransferProtocol.h" 20 20 21 typedef DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_IA32 DEBUG_DATA_REPONSE_READ_REGISTER_GROUP;22 typedef DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM_IA32 DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM;23 typedef DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE_IA32 DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE;24 25 21 #define DEBUG_SW_BREAKPOINT_SYMBOL 0xcc 26 27 22 #define DEBUG_ARCH_SYMBOL DEBUG_DATA_BREAK_CPU_ARCH_IA32 28 23 24 typedef DEBUG_DATA_IA32_FX_SAVE_STATE DEBUG_DATA_FX_SAVE_STATE; 29 25 typedef DEBUG_DATA_IA32_SYSTEM_CONTEXT DEBUG_CPU_CONTEXT; 30 26 -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S
r48674 r58459 1 1 #------------------------------------------------------------------------------ 2 2 # 3 # Copyright (c) 2010 , Intel Corporation. All rights reserved.<BR>3 # Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR> 4 4 # This program and the accompanying materials 5 5 # are licensed and made available under the terms and conditions of the BSD License … … 28 28 ASM_GLOBAL ASM_PFX(CommonEntry) 29 29 30 .macro AGENT_HANDLER_SIGNATURE 31 .byte 0x41, 0x47, 0x54, 0x48 # AGENT_HANDLER_SIGNATURE SIGNATURE_32('A','G','T','H') 32 .endm 33 30 34 .data 31 35 32 ASM_PFX(ExceptionStubHeaderSize): . wordASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle)36 ASM_PFX(ExceptionStubHeaderSize): .long ASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle) 33 37 34 38 .text 35 39 40 AGENT_HANDLER_SIGNATURE 36 41 ASM_PFX(Exception0Handle): 37 42 cli … … 39 44 mov $0, %eax 40 45 jmp ASM_PFX(CommonEntry) 46 AGENT_HANDLER_SIGNATURE 41 47 ASM_PFX(Exception1Handle): 42 48 cli … … 44 50 mov $1, %eax 45 51 jmp ASM_PFX(CommonEntry) 52 AGENT_HANDLER_SIGNATURE 46 53 ASM_PFX(Exception2Handle): 47 54 cli … … 49 56 mov $2, %eax 50 57 jmp ASM_PFX(CommonEntry) 58 AGENT_HANDLER_SIGNATURE 51 59 ASM_PFX(Exception3Handle): 52 60 cli … … 54 62 mov $3, %eax 55 63 jmp ASM_PFX(CommonEntry) 64 AGENT_HANDLER_SIGNATURE 56 65 ASM_PFX(Exception4Handle): 57 66 cli … … 59 68 mov $4, %eax 60 69 jmp ASM_PFX(CommonEntry) 70 AGENT_HANDLER_SIGNATURE 61 71 ASM_PFX(Exception5Handle): 62 72 cli … … 64 74 mov $5, %eax 65 75 jmp ASM_PFX(CommonEntry) 76 AGENT_HANDLER_SIGNATURE 66 77 ASM_PFX(Exception6Handle): 67 78 cli … … 69 80 mov $6, %eax 70 81 jmp ASM_PFX(CommonEntry) 82 AGENT_HANDLER_SIGNATURE 71 83 ASM_PFX(Exception7Handle): 72 84 cli … … 74 86 mov $7, %eax 75 87 jmp ASM_PFX(CommonEntry) 88 AGENT_HANDLER_SIGNATURE 76 89 ASM_PFX(Exception8Handle): 77 90 cli … … 79 92 mov $8, %eax 80 93 jmp ASM_PFX(CommonEntry) 94 AGENT_HANDLER_SIGNATURE 81 95 ASM_PFX(Exception9Handle): 82 96 cli … … 84 98 mov $9, %eax 85 99 jmp ASM_PFX(CommonEntry) 100 AGENT_HANDLER_SIGNATURE 86 101 ASM_PFX(Exception10Handle): 87 102 cli … … 89 104 mov $10, %eax 90 105 jmp ASM_PFX(CommonEntry) 106 AGENT_HANDLER_SIGNATURE 91 107 ASM_PFX(Exception11Handle): 92 108 cli … … 94 110 mov $11, %eax 95 111 jmp ASM_PFX(CommonEntry) 112 AGENT_HANDLER_SIGNATURE 96 113 ASM_PFX(Exception12Handle): 97 114 cli … … 99 116 mov $12, %eax 100 117 jmp ASM_PFX(CommonEntry) 118 AGENT_HANDLER_SIGNATURE 101 119 ASM_PFX(Exception13Handle): 102 120 cli … … 104 122 mov $13, %eax 105 123 jmp ASM_PFX(CommonEntry) 124 AGENT_HANDLER_SIGNATURE 106 125 ASM_PFX(Exception14Handle): 107 126 cli … … 109 128 mov $14, %eax 110 129 jmp ASM_PFX(CommonEntry) 130 AGENT_HANDLER_SIGNATURE 111 131 ASM_PFX(Exception15Handle): 112 132 cli … … 114 134 mov $15, %eax 115 135 jmp ASM_PFX(CommonEntry) 136 AGENT_HANDLER_SIGNATURE 116 137 ASM_PFX(Exception16Handle): 117 138 cli … … 119 140 mov $16, %eax 120 141 jmp ASM_PFX(CommonEntry) 142 AGENT_HANDLER_SIGNATURE 121 143 ASM_PFX(Exception17Handle): 122 144 cli … … 124 146 mov $17, %eax 125 147 jmp ASM_PFX(CommonEntry) 148 AGENT_HANDLER_SIGNATURE 126 149 ASM_PFX(Exception18Handle): 127 150 cli … … 129 152 mov $18, %eax 130 153 jmp ASM_PFX(CommonEntry) 154 AGENT_HANDLER_SIGNATURE 131 155 ASM_PFX(Exception19Handle): 132 156 cli … … 134 158 mov $19, %eax 135 159 jmp ASM_PFX(CommonEntry) 136 160 AGENT_HANDLER_SIGNATURE 137 161 ASM_PFX(TimerInterruptHandle): 138 162 cli … … 260 284 ## clear Dr7 while executing debugger itself 261 285 xorl %eax,%eax 262 #movl %eax, %dr7286 movl %eax, %dr7 263 287 264 288 movl %dr6, %eax … … 281 305 movl %esp,%edi 282 306 .byte 0x0f, 0xae, 0x07 # fxsave [edi] 307 308 ## save the exception data 309 pushl 8(%esp) 283 310 284 311 ## Clear Direction Flag … … 290 317 call ASM_PFX(InterruptProcess) 291 318 addl $8,%esp 319 320 ## skip the exception data 321 addl $4,%esp 292 322 293 323 ## FX_SAVE_STATE_IA32 FxSaveState; -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.asm
r48674 r58459 1 1 ;------------------------------------------------------------------------------ 2 2 ; 3 ; Copyright (c) 2010 , Intel Corporation. All rights reserved.<BR>3 ; Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR> 4 4 ; This program and the accompanying materials 5 5 ; are licensed and made available under the terms and conditions of the BSD License … … 33 33 public Exception0Handle, TimerInterruptHandle, ExceptionStubHeaderSize 34 34 35 AGENT_HANDLER_SIGNATURE MACRO 36 db 41h, 47h, 54h, 48h ; SIGNATURE_32('A','G','T','H') 37 ENDM 38 35 39 .data 36 40 37 ExceptionStubHeaderSize D WException1Handle - Exception0Handle41 ExceptionStubHeaderSize DD Exception1Handle - Exception0Handle 38 42 CommonEntryAddr DD CommonEntry 39 43 40 44 .code 41 45 46 AGENT_HANDLER_SIGNATURE 42 47 Exception0Handle: 43 48 cli … … 45 50 mov eax, 0 46 51 jmp dword ptr [CommonEntryAddr] 52 AGENT_HANDLER_SIGNATURE 47 53 Exception1Handle: 48 54 cli … … 50 56 mov eax, 1 51 57 jmp dword ptr [CommonEntryAddr] 58 AGENT_HANDLER_SIGNATURE 52 59 Exception2Handle: 53 60 cli … … 55 62 mov eax, 2 56 63 jmp dword ptr [CommonEntryAddr] 64 AGENT_HANDLER_SIGNATURE 57 65 Exception3Handle: 58 66 cli … … 60 68 mov eax, 3 61 69 jmp dword ptr [CommonEntryAddr] 70 AGENT_HANDLER_SIGNATURE 62 71 Exception4Handle: 63 72 cli … … 65 74 mov eax, 4 66 75 jmp dword ptr [CommonEntryAddr] 76 AGENT_HANDLER_SIGNATURE 67 77 Exception5Handle: 68 78 cli … … 70 80 mov eax, 5 71 81 jmp dword ptr [CommonEntryAddr] 82 AGENT_HANDLER_SIGNATURE 72 83 Exception6Handle: 73 84 cli … … 75 86 mov eax, 6 76 87 jmp dword ptr [CommonEntryAddr] 88 AGENT_HANDLER_SIGNATURE 77 89 Exception7Handle: 78 90 cli … … 80 92 mov eax, 7 81 93 jmp dword ptr [CommonEntryAddr] 94 AGENT_HANDLER_SIGNATURE 82 95 Exception8Handle: 83 96 cli … … 85 98 mov eax, 8 86 99 jmp dword ptr [CommonEntryAddr] 100 AGENT_HANDLER_SIGNATURE 87 101 Exception9Handle: 88 102 cli … … 90 104 mov eax, 9 91 105 jmp dword ptr [CommonEntryAddr] 106 AGENT_HANDLER_SIGNATURE 92 107 Exception10Handle: 93 108 cli … … 95 110 mov eax, 10 96 111 jmp dword ptr [CommonEntryAddr] 112 AGENT_HANDLER_SIGNATURE 97 113 Exception11Handle: 98 114 cli … … 100 116 mov eax, 11 101 117 jmp dword ptr [CommonEntryAddr] 118 AGENT_HANDLER_SIGNATURE 102 119 Exception12Handle: 103 120 cli … … 105 122 mov eax, 12 106 123 jmp dword ptr [CommonEntryAddr] 124 AGENT_HANDLER_SIGNATURE 107 125 Exception13Handle: 108 126 cli … … 110 128 mov eax, 13 111 129 jmp dword ptr [CommonEntryAddr] 130 AGENT_HANDLER_SIGNATURE 112 131 Exception14Handle: 113 132 cli … … 115 134 mov eax, 14 116 135 jmp dword ptr [CommonEntryAddr] 136 AGENT_HANDLER_SIGNATURE 117 137 Exception15Handle: 118 138 cli … … 120 140 mov eax, 15 121 141 jmp dword ptr [CommonEntryAddr] 142 AGENT_HANDLER_SIGNATURE 122 143 Exception16Handle: 123 144 cli … … 125 146 mov eax, 16 126 147 jmp dword ptr [CommonEntryAddr] 148 AGENT_HANDLER_SIGNATURE 127 149 Exception17Handle: 128 150 cli … … 130 152 mov eax, 17 131 153 jmp dword ptr [CommonEntryAddr] 154 AGENT_HANDLER_SIGNATURE 132 155 Exception18Handle: 133 156 cli … … 135 158 mov eax, 18 136 159 jmp dword ptr [CommonEntryAddr] 160 AGENT_HANDLER_SIGNATURE 137 161 Exception19Handle: 138 162 cli … … 140 164 mov eax, 19 141 165 jmp dword ptr [CommonEntryAddr] 142 166 AGENT_HANDLER_SIGNATURE 143 167 TimerInterruptHandle: 144 168 cli … … 260 284 ;; clear Dr7 while executing debugger itself 261 285 xor eax, eax 262 ;;mov dr7, eax286 mov dr7, eax 263 287 264 288 ;; Dr6 … … 283 307 mov edi, esp 284 308 db 0fh, 0aeh, 00000111y ;fxsave [edi] 309 310 ;; save the exception data 311 push dword ptr [ebp + 8] 285 312 286 313 ;; Clear Direction Flag … … 292 319 call InterruptProcess 293 320 add esp, 8 321 322 ; skip the exception data 323 add esp, 4 294 324 295 325 ;; FX_SAVE_STATE_IA32 FxSaveState; -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchDebugSupport.c
r48674 r58459 1 1 /** @file 2 Supporting functions for x64 architecture.2 Supporting functions for X64 architecture. 3 3 4 Copyright (c) 2010 , Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 14 14 15 15 #include "DebugAgent.h" 16 17 /**18 Read the offset of FP / MMX / XMM registers by register index.19 20 @param[in] Index Register index.21 @param[out] Width Register width returned.22 23 @return Offset in register address range.24 25 **/26 UINT1627 ArchReadFxStatOffset (28 IN UINT8 Index,29 OUT UINT8 *Width30 )31 {32 if (Index < SOFT_DEBUGGER_REGISTER_ST0) {33 switch (Index) {34 case SOFT_DEBUGGER_REGISTER_FP_FCW:35 *Width = (UINT8) sizeof (UINT16);36 return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, Fcw);37 38 case SOFT_DEBUGGER_REGISTER_FP_FSW:39 *Width = (UINT8) sizeof (UINT16);40 return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, Fsw);41 42 case SOFT_DEBUGGER_REGISTER_FP_FTW:43 *Width = (UINT8) sizeof (UINT16);44 return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, Ftw);45 46 case SOFT_DEBUGGER_REGISTER_FP_OPCODE:47 *Width = (UINT8) sizeof (UINT16);48 return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, Opcode);49 50 case SOFT_DEBUGGER_REGISTER_FP_EIP:51 *Width = (UINT8) sizeof (UINTN);52 return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, Rip);53 54 case SOFT_DEBUGGER_REGISTER_FP_DATAOFFSET:55 *Width = (UINT8) sizeof (UINTN);56 return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, DataOffset);57 58 case SOFT_DEBUGGER_REGISTER_FP_MXCSR:59 *Width = (UINT8) sizeof (UINT32);60 return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, Mxcsr);61 62 case SOFT_DEBUGGER_REGISTER_FP_MXCSR_MASK:63 *Width = (UINT8) sizeof (UINT32);64 return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, Mxcsr_Mask);65 66 default:67 return (UINT16) (-1);68 }69 }70 71 if (Index < SOFT_DEBUGGER_REGISTER_XMM0) {72 *Width = 10;73 } else if (Index < SOFT_DEBUGGER_REGISTER_MM0 ) {74 *Width = 16;75 } else {76 *Width = 8;77 Index -= SOFT_DEBUGGER_REGISTER_MM0 - SOFT_DEBUGGER_REGISTER_ST0;78 }79 80 return OFFSET_OF(DEBUG_DATA_X64_FX_SAVE_STATE, St0Mm0) + (Index - SOFT_DEBUGGER_REGISTER_ST0) * 16;81 }82 83 /**84 Write specified register into save CPU context.85 86 @param[in] CpuContext Pointer to saved CPU context.87 @param[in] Index Register index value.88 @param[in] Offset Offset in register address range89 @param[in] Width Data width to read.90 @param[in] RegisterBuffer Pointer to input buffer with data.91 92 **/93 VOID94 ArchWriteRegisterBuffer (95 IN DEBUG_CPU_CONTEXT *CpuContext,96 IN UINT8 Index,97 IN UINT8 Offset,98 IN UINT8 Width,99 IN UINT8 *RegisterBuffer100 )101 {102 UINT8 *Buffer;103 if (Index < SOFT_DEBUGGER_REGISTER_FP_BASE) {104 Buffer = (UINT8 *) CpuContext + sizeof (DEBUG_DATA_X64_FX_SAVE_STATE) + Index * 8;105 } else {106 //107 // If it is MMX register, adjust its index position108 //109 if (Index >= SOFT_DEBUGGER_REGISTER_MM0) {110 Index -= SOFT_DEBUGGER_REGISTER_MM0 - SOFT_DEBUGGER_REGISTER_ST0;111 }112 113 //114 // FPU/MMX/XMM registers115 //116 Buffer = (UINT8 *) CpuContext + ArchReadFxStatOffset (Index, &Width);117 }118 119 CopyMem (Buffer + Offset, RegisterBuffer, Width);120 }121 122 /**123 Read register value from saved CPU context.124 125 @param[in] CpuContext Pointer to saved CPU context.126 @param[in] Index Register index value.127 @param[in] Offset Offset in register address range128 @param[in] Width Data width to read.129 130 @return The address of register value.131 132 **/133 UINT8 *134 ArchReadRegisterBuffer (135 IN DEBUG_CPU_CONTEXT *CpuContext,136 IN UINT8 Index,137 IN UINT8 Offset,138 IN UINT8 *Width139 )140 {141 UINT8 *Buffer;142 143 if (Index < SOFT_DEBUGGER_REGISTER_FP_BASE) {144 Buffer = (UINT8 *) CpuContext + sizeof (DEBUG_DATA_X64_FX_SAVE_STATE) + Index * 8;145 if (*Width == 0) {146 *Width = (UINT8) sizeof (UINTN);147 }148 } else {149 //150 // FPU/MMX/XMM registers151 //152 Buffer = (UINT8 *) CpuContext + ArchReadFxStatOffset (Index, Width);153 }154 155 return Buffer;156 }157 158 /**159 Read group register of common registers.160 161 @param[in] CpuContext Pointer to saved CPU context.162 @param[in] RegisterGroup Pointer to Group registers.163 164 **/165 VOID166 ReadRegisterGroup (167 IN DEBUG_CPU_CONTEXT *CpuContext,168 IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP *RegisterGroup169 )170 {171 RegisterGroup->Cs = (UINT16) CpuContext->Cs;172 RegisterGroup->Ds = (UINT16) CpuContext->Ds;173 RegisterGroup->Es = (UINT16) CpuContext->Es;174 RegisterGroup->Fs = (UINT16) CpuContext->Fs;175 RegisterGroup->Gs = (UINT16) CpuContext->Gs;176 RegisterGroup->Ss = (UINT16) CpuContext->Ss;177 RegisterGroup->Eflags = (UINT32) CpuContext->Eflags;178 RegisterGroup->Rbp = CpuContext->Rbp;179 RegisterGroup->Eip = CpuContext->Eip;180 RegisterGroup->Rsp = CpuContext->Rsp;181 RegisterGroup->Eax = CpuContext->Rax;182 RegisterGroup->Rbx = CpuContext->Rbx;183 RegisterGroup->Rcx = CpuContext->Rcx;184 RegisterGroup->Rdx = CpuContext->Rdx;185 RegisterGroup->Rsi = CpuContext->Rsi;186 RegisterGroup->Rdi = CpuContext->Rdi;187 RegisterGroup->R8 = CpuContext->R8;188 RegisterGroup->R9 = CpuContext->R9;189 RegisterGroup->R10 = CpuContext->R10;190 RegisterGroup->R11 = CpuContext->R11;191 RegisterGroup->R12 = CpuContext->R12;192 RegisterGroup->R13 = CpuContext->R13;193 RegisterGroup->R14 = CpuContext->R14;194 RegisterGroup->R15 = CpuContext->R15;195 RegisterGroup->Dr0 = CpuContext->Dr0;196 RegisterGroup->Dr1 = CpuContext->Dr1;197 RegisterGroup->Dr2 = CpuContext->Dr2;198 RegisterGroup->Dr3 = CpuContext->Dr3;199 RegisterGroup->Dr6 = CpuContext->Dr6;200 RegisterGroup->Dr7 = CpuContext->Dr7;201 RegisterGroup->Cr0 = CpuContext->Cr0;202 RegisterGroup->Cr2 = CpuContext->Cr2;203 RegisterGroup->Cr3 = CpuContext->Cr3;204 RegisterGroup->Cr4 = CpuContext->Cr4;205 RegisterGroup->Cr8 = CpuContext->Cr8;206 207 CopyMem ((UINT8 *) &RegisterGroup->Xmm0[0], (UINT8 *) &CpuContext->FxSaveState.Xmm0[0], 16 * 10);208 }209 16 210 17 /** … … 233 40 234 41 for (Index = 0; Index < 20; Index ++) { 235 if (( PcdGet32 (PcdExceptionsIgnoredByDebugger) & (1 << Index)) != 0) {42 if (((PcdGet32 (PcdExceptionsIgnoredByDebugger) & ~(BIT1 | BIT3)) & (1 << Index)) != 0) { 236 43 // 237 // If the exception is masked to be reserved , skip it44 // If the exception is masked to be reserved except for INT1 and INT3, skip it 238 45 // 239 46 continue; … … 253 60 IdtEntry[DEBUG_TIMER_VECTOR].Bits.Selector = CodeSegment; 254 61 IdtEntry[DEBUG_TIMER_VECTOR].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; 62 63 // 64 // Set DE flag in CR4 to enable IO breakpoint 65 // 66 AsmWriteCr4 (AsmReadCr4 () | BIT3); 255 67 } 68 69 /** 70 Retrieve exception handler from IDT table by ExceptionNum. 71 72 @param[in] ExceptionNum Exception number 73 74 @return Exception handler 75 76 **/ 77 VOID * 78 GetExceptionHandlerInIdtEntry ( 79 IN UINTN ExceptionNum 80 ) 81 { 82 IA32_IDT_GATE_DESCRIPTOR *IdtEntry; 83 IA32_DESCRIPTOR IdtDescriptor; 84 85 AsmReadIdtr (&IdtDescriptor); 86 IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base; 87 88 return (VOID *) (IdtEntry[ExceptionNum].Bits.OffsetLow | 89 (((UINTN)IdtEntry[ExceptionNum].Bits.OffsetHigh) << 16) | 90 (((UINTN)IdtEntry[ExceptionNum].Bits.OffsetUpper) << 32)); 91 } 92 93 /** 94 Set exception handler in IDT table by ExceptionNum. 95 96 @param[in] ExceptionNum Exception number 97 @param[in] ExceptionHandler Exception Handler to be set 98 99 **/ 100 VOID 101 SetExceptionHandlerInIdtEntry ( 102 IN UINTN ExceptionNum, 103 IN VOID *ExceptionHandler 104 ) 105 { 106 IA32_IDT_GATE_DESCRIPTOR *IdtEntry; 107 IA32_DESCRIPTOR IdtDescriptor; 108 109 AsmReadIdtr (&IdtDescriptor); 110 IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base; 111 112 IdtEntry[ExceptionNum].Bits.OffsetLow = (UINT16)(UINTN)ExceptionHandler; 113 IdtEntry[ExceptionNum].Bits.OffsetHigh = (UINT16)((UINTN)ExceptionHandler >> 16); 114 IdtEntry[ExceptionNum].Bits.OffsetUpper = (UINT32)((UINTN)ExceptionHandler >> 32); 115 } -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchDebugSupport.h
r48674 r58459 2 2 X64 specific defintions for debug agent library instance. 3 3 4 Copyright (c) 2010 , Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 16 16 #define _ARCH_DEBUG_SUPPORT_H_ 17 17 18 #include " ArchRegisters.h"18 #include "ProcessorContext.h" 19 19 #include "TransferProtocol.h" 20 20 21 typedef DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_X64 DEBUG_DATA_REPONSE_READ_REGISTER_GROUP;22 typedef DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM_X64 DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM;23 typedef DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE_X64 DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE;24 25 21 #define DEBUG_SW_BREAKPOINT_SYMBOL 0xcc 26 27 22 #define DEBUG_ARCH_SYMBOL DEBUG_DATA_BREAK_CPU_ARCH_X64 28 23 24 typedef DEBUG_DATA_X64_FX_SAVE_STATE DEBUG_DATA_FX_SAVE_STATE; 29 25 typedef DEBUG_DATA_X64_SYSTEM_CONTEXT DEBUG_CPU_CONTEXT; 30 26 -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.S
r48674 r58459 1 1 #------------------------------------------------------------------------------ 2 2 # 3 # Copyright (c) 2006 - 20 08, Intel Corporation. All rights reserved.<BR>3 # Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR> 4 4 # This program and the accompanying materials 5 5 # are licensed and made available under the terms and conditions of the BSD License … … 29 29 ASM_GLOBAL ASM_PFX(CommonEntry) 30 30 31 .macro AGENT_HANDLER_SIGNATURE 32 .byte 0x41, 0x47, 0x54, 0x48 # AGENT_HANDLER_SIGNATURE SIGNATURE_32('A','G','T','H') 33 .endm 34 31 35 .data 32 36 33 ASM_PFX(ExceptionStubHeaderSize): . wordASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle)37 ASM_PFX(ExceptionStubHeaderSize): .long ASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle) 34 38 35 39 36 40 .text 37 41 42 AGENT_HANDLER_SIGNATURE 38 43 ASM_PFX(Exception0Handle): 39 44 cli … … 41 46 mov $0, %rcx 42 47 jmp ASM_PFX(CommonEntry) 48 AGENT_HANDLER_SIGNATURE 43 49 ASM_PFX(Exception1Handle): 44 50 cli … … 46 52 mov $1, %rcx 47 53 jmp ASM_PFX(CommonEntry) 54 AGENT_HANDLER_SIGNATURE 48 55 ASM_PFX(Exception2Handle): 49 56 cli … … 51 58 mov $2, %rcx 52 59 jmp ASM_PFX(CommonEntry) 60 AGENT_HANDLER_SIGNATURE 53 61 ASM_PFX(Exception3Handle): 54 62 cli … … 56 64 mov $3, %rcx 57 65 jmp ASM_PFX(CommonEntry) 66 AGENT_HANDLER_SIGNATURE 58 67 ASM_PFX(Exception4Handle): 59 68 cli … … 61 70 mov $4, %rcx 62 71 jmp ASM_PFX(CommonEntry) 72 AGENT_HANDLER_SIGNATURE 63 73 ASM_PFX(Exception5Handle): 64 74 cli … … 66 76 mov $5, %rcx 67 77 jmp ASM_PFX(CommonEntry) 78 AGENT_HANDLER_SIGNATURE 68 79 ASM_PFX(Exception6Handle): 69 80 cli … … 71 82 mov $6, %rcx 72 83 jmp ASM_PFX(CommonEntry) 84 AGENT_HANDLER_SIGNATURE 73 85 ASM_PFX(Exception7Handle): 74 86 cli … … 76 88 mov $7, %rcx 77 89 jmp ASM_PFX(CommonEntry) 90 AGENT_HANDLER_SIGNATURE 78 91 ASM_PFX(Exception8Handle): 79 92 cli … … 81 94 mov $8, %rcx 82 95 jmp ASM_PFX(CommonEntry) 96 AGENT_HANDLER_SIGNATURE 83 97 ASM_PFX(Exception9Handle): 84 98 cli … … 86 100 mov $9, %rcx 87 101 jmp ASM_PFX(CommonEntry) 102 AGENT_HANDLER_SIGNATURE 88 103 ASM_PFX(Exception10Handle): 89 104 cli … … 91 106 mov $10, %rcx 92 107 jmp ASM_PFX(CommonEntry) 108 AGENT_HANDLER_SIGNATURE 93 109 ASM_PFX(Exception11Handle): 94 110 cli … … 96 112 mov $11, %rcx 97 113 jmp ASM_PFX(CommonEntry) 114 AGENT_HANDLER_SIGNATURE 98 115 ASM_PFX(Exception12Handle): 99 116 cli … … 101 118 mov $12, %rcx 102 119 jmp ASM_PFX(CommonEntry) 120 AGENT_HANDLER_SIGNATURE 103 121 ASM_PFX(Exception13Handle): 104 122 cli … … 106 124 mov $13, %rcx 107 125 jmp ASM_PFX(CommonEntry) 126 AGENT_HANDLER_SIGNATURE 108 127 ASM_PFX(Exception14Handle): 109 128 cli … … 111 130 mov $14, %rcx 112 131 jmp ASM_PFX(CommonEntry) 132 AGENT_HANDLER_SIGNATURE 113 133 ASM_PFX(Exception15Handle): 114 134 cli … … 116 136 mov $15, %rcx 117 137 jmp ASM_PFX(CommonEntry) 138 AGENT_HANDLER_SIGNATURE 118 139 ASM_PFX(Exception16Handle): 119 140 cli … … 121 142 mov $16, %rcx 122 143 jmp ASM_PFX(CommonEntry) 144 AGENT_HANDLER_SIGNATURE 123 145 ASM_PFX(Exception17Handle): 124 146 cli … … 126 148 mov $17, %rcx 127 149 jmp ASM_PFX(CommonEntry) 150 AGENT_HANDLER_SIGNATURE 128 151 ASM_PFX(Exception18Handle): 129 152 cli … … 131 154 mov $18, %rcx 132 155 jmp ASM_PFX(CommonEntry) 156 AGENT_HANDLER_SIGNATURE 133 157 ASM_PFX(Exception19Handle): 134 158 cli … … 136 160 mov $19, %rcx 137 161 jmp ASM_PFX(CommonEntry) 138 162 AGENT_HANDLER_SIGNATURE 139 163 ASM_PFX(TimerInterruptHandle): 140 164 cli … … 248 272 # movq %cs, %rax 249 273 pushq %rax 250 mov q%ds, %rax251 pushq %rax 252 mov q%es, %rax253 pushq %rax 254 mov q%fs, %rax255 pushq %rax 256 mov q%gs, %rax274 mov %ds, %rax 275 pushq %rax 276 mov %es, %rax 277 pushq %rax 278 mov %fs, %rax 279 pushq %rax 280 mov %gs, %rax 257 281 pushq %rax 258 282 … … 281 305 ## clear Dr7 while executing debugger itself 282 306 xorq %rax, %rax 283 #debugmovq %rax, %dr7307 movq %rax, %dr7 284 308 285 309 movq %dr6, %rax … … 302 326 movq %rsp, %rdi 303 327 .byte 0x0f, 0xae, 0b00000111 328 329 ## save the exception data; 330 pushq 16(%rbp) 304 331 305 332 ## Clear Direction Flag … … 314 341 # and make sure RSP is 16-byte aligned 315 342 # 316 subq $( 4 *8), %rsp343 subq $(32 + 8), %rsp 317 344 call ASM_PFX(InterruptProcess) 318 addq $(4 * 8), %rsp 345 addq $(32 + 8), %rsp 346 347 ## skip the exception data; 348 addq $8, %rsp 319 349 320 350 ## FX_SAVE_STATE_X64 FxSaveState; … … 356 386 # (X64 will not use fs and gs, so we do not restore it) 357 387 popq %rax 358 movw%rax, %es359 popq %rax 360 movw%rax, %ds388 mov %rax, %es 389 popq %rax 390 mov %rax, %ds 361 391 popq 32(%rbp) 362 392 popq 56(%rbp) -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.asm
r48674 r58459 1 1 ;------------------------------------------------------------------------------ 2 2 ; 3 ; Copyright (c) 2010 , Intel Corporation. All rights reserved.<BR>3 ; Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR> 4 4 ; This program and the accompanying materials 5 5 ; are licensed and made available under the terms and conditions of the BSD License … … 29 29 public Exception0Handle, TimerInterruptHandle, ExceptionStubHeaderSize 30 30 31 ExceptionStubHeaderSize dw Exception1Handle - Exception0Handle ; 31 AGENT_HANDLER_SIGNATURE MACRO 32 db 41h, 47h, 54h, 48h ; SIGNATURE_32('A','G','T','H') 33 ENDM 34 35 ExceptionStubHeaderSize dd Exception1Handle - Exception0Handle ; 32 36 CommonEntryAddr dq CommonEntry ; 33 37 34 38 .code 35 39 40 AGENT_HANDLER_SIGNATURE 36 41 Exception0Handle: 37 42 cli … … 39 44 mov rcx, 0 40 45 jmp qword ptr [CommonEntryAddr] 46 AGENT_HANDLER_SIGNATURE 41 47 Exception1Handle: 42 48 cli … … 44 50 mov rcx, 1 45 51 jmp qword ptr [CommonEntryAddr] 52 AGENT_HANDLER_SIGNATURE 46 53 Exception2Handle: 47 54 cli … … 49 56 mov rcx, 2 50 57 jmp qword ptr [CommonEntryAddr] 58 AGENT_HANDLER_SIGNATURE 51 59 Exception3Handle: 52 60 cli … … 54 62 mov rcx, 3 55 63 jmp qword ptr [CommonEntryAddr] 64 AGENT_HANDLER_SIGNATURE 56 65 Exception4Handle: 57 66 cli … … 59 68 mov rcx, 4 60 69 jmp qword ptr [CommonEntryAddr] 70 AGENT_HANDLER_SIGNATURE 61 71 Exception5Handle: 62 72 cli … … 64 74 mov rcx, 5 65 75 jmp qword ptr [CommonEntryAddr] 76 AGENT_HANDLER_SIGNATURE 66 77 Exception6Handle: 67 78 cli … … 69 80 mov rcx, 6 70 81 jmp qword ptr [CommonEntryAddr] 82 AGENT_HANDLER_SIGNATURE 71 83 Exception7Handle: 72 84 cli … … 74 86 mov rcx, 7 75 87 jmp qword ptr [CommonEntryAddr] 88 AGENT_HANDLER_SIGNATURE 76 89 Exception8Handle: 77 90 cli … … 79 92 mov rcx, 8 80 93 jmp qword ptr [CommonEntryAddr] 94 AGENT_HANDLER_SIGNATURE 81 95 Exception9Handle: 82 96 cli … … 84 98 mov rcx, 9 85 99 jmp qword ptr [CommonEntryAddr] 100 AGENT_HANDLER_SIGNATURE 86 101 Exception10Handle: 87 102 cli … … 89 104 mov rcx, 10 90 105 jmp qword ptr [CommonEntryAddr] 106 AGENT_HANDLER_SIGNATURE 91 107 Exception11Handle: 92 108 cli … … 94 110 mov rcx, 11 95 111 jmp qword ptr [CommonEntryAddr] 112 AGENT_HANDLER_SIGNATURE 96 113 Exception12Handle: 97 114 cli … … 99 116 mov rcx, 12 100 117 jmp qword ptr [CommonEntryAddr] 118 AGENT_HANDLER_SIGNATURE 101 119 Exception13Handle: 102 120 cli … … 104 122 mov rcx, 13 105 123 jmp qword ptr [CommonEntryAddr] 124 AGENT_HANDLER_SIGNATURE 106 125 Exception14Handle: 107 126 cli … … 109 128 mov rcx, 14 110 129 jmp qword ptr [CommonEntryAddr] 130 AGENT_HANDLER_SIGNATURE 111 131 Exception15Handle: 112 132 cli … … 114 134 mov rcx, 15 115 135 jmp qword ptr [CommonEntryAddr] 136 AGENT_HANDLER_SIGNATURE 116 137 Exception16Handle: 117 138 cli … … 119 140 mov rcx, 16 120 141 jmp qword ptr [CommonEntryAddr] 142 AGENT_HANDLER_SIGNATURE 121 143 Exception17Handle: 122 144 cli … … 124 146 mov rcx, 17 125 147 jmp qword ptr [CommonEntryAddr] 148 AGENT_HANDLER_SIGNATURE 126 149 Exception18Handle: 127 150 cli … … 129 152 mov rcx, 18 130 153 jmp qword ptr [CommonEntryAddr] 154 AGENT_HANDLER_SIGNATURE 131 155 Exception19Handle: 132 156 cli … … 134 158 mov rcx, 19 135 159 jmp qword ptr [CommonEntryAddr] 136 160 AGENT_HANDLER_SIGNATURE 137 161 TimerInterruptHandle: 138 162 cli … … 199 223 mov rax, cr2 200 224 push rax 201 push 0 ; cr0 will not saved???225 push 0 202 226 mov rax, cr0 203 227 push rax … … 264 288 265 289 sub rsp, 512 266 mov rdi, rsp290 mov rdi, rsp 267 291 db 0fh, 0aeh, 00000111y ;fxsave [rdi] 292 293 ;; save the exception data 294 push qword ptr [rbp + 16] 268 295 269 296 ;; Clear Direction Flag … … 274 301 mov r15, rcx ; save vector in r15 275 302 276 sub rsp, 32 303 ; 304 ; Per X64 calling convention, allocate maximum parameter stack space 305 ; and make sure RSP is 16-byte aligned 306 ; 307 sub rsp, 32 + 8 277 308 call InterruptProcess 278 add rsp, 32 309 add rsp, 32 + 8 310 311 ;; skip the exception data 312 add rsp, 8 279 313 280 314 mov rsi, rsp -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c
r48674 r58459 2 2 Debug Agent library implementition for Dxe Core and Dxr modules. 3 3 4 Copyright (c) 2010 , Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 16 16 17 17 DEBUG_AGENT_MAILBOX mMailbox; 18 19 DEBUG_AGENT_MAILBOX *mMailboxPointer; 20 18 DEBUG_AGENT_MAILBOX *mMailboxPointer = NULL; 21 19 IA32_IDT_GATE_DESCRIPTOR mIdtEntryTable[33]; 22 23 BOOLEAN mConfigurationTableNeeded = FALSE; 24 25 CONST BOOLEAN MultiProcessorDebugSupport = TRUE; 26 27 /** 28 Constructor allocates the NVS memory to store Mailbox and install configuration table 20 BOOLEAN mDxeCoreFlag = FALSE; 21 BOOLEAN mMultiProcessorDebugSupport = FALSE; 22 VOID *mSavedIdtTable = NULL; 23 UINTN mSaveIdtTableSize = 0; 24 BOOLEAN mDebugAgentInitialized = FALSE; 25 BOOLEAN mSkipBreakpoint = FALSE; 26 27 /** 28 Check if debug agent support multi-processor. 29 30 @retval TRUE Multi-processor is supported. 31 @retval FALSE Multi-processor is not supported. 32 33 **/ 34 BOOLEAN 35 MultiProcessorDebugSupport ( 36 VOID 37 ) 38 { 39 return mMultiProcessorDebugSupport; 40 } 41 42 /** 43 Internal constructor worker function. 44 45 It will register one callback function on EFI PCD Protocol. 46 It will allocate the NVS memory to store Mailbox and install configuration table 29 47 in system table to store its pointer. 48 49 **/ 50 VOID 51 InternalConstructorWorker ( 52 VOID 53 ) 54 { 55 EFI_STATUS Status; 56 EFI_PHYSICAL_ADDRESS Address; 57 BOOLEAN DebugTimerInterruptState; 58 DEBUG_AGENT_MAILBOX *Mailbox; 59 DEBUG_AGENT_MAILBOX *NewMailbox; 60 EFI_HOB_GUID_TYPE *GuidHob; 61 EFI_VECTOR_HANDOFF_INFO *VectorHandoffInfo; 62 63 // 64 // Check persisted vector handoff info 65 // 66 Status = EFI_SUCCESS; 67 GuidHob = GetFirstGuidHob (&gEfiVectorHandoffInfoPpiGuid); 68 if (GuidHob != NULL && !mDxeCoreFlag) { 69 // 70 // Check if configuration table is installed or not if GUIDed HOB existed, 71 // only when Debug Agent is not linked by DXE Core 72 // 73 Status = EfiGetSystemConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID **) &VectorHandoffInfo); 74 } 75 if (GuidHob == NULL || Status != EFI_SUCCESS) { 76 // 77 // Install configuration table for persisted vector handoff info if GUIDed HOB cannot be found or 78 // configuration table does not exist 79 // 80 Status = gBS->InstallConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID *) &mVectorHandoffInfoDebugAgent[0]); 81 if (EFI_ERROR (Status)) { 82 DEBUG ((EFI_D_ERROR, "DebugAgent: Cannot install configuration table for persisted vector handoff info!\n")); 83 CpuDeadLoop (); 84 } 85 } 86 87 // 88 // Install EFI Serial IO protocol on debug port 89 // 90 InstallSerialIo (); 91 92 Address = 0; 93 Status = gBS->AllocatePages ( 94 AllocateAnyPages, 95 EfiACPIMemoryNVS, 96 EFI_SIZE_TO_PAGES (sizeof(DEBUG_AGENT_MAILBOX) + PcdGet16(PcdDebugPortHandleBufferSize)), 97 &Address 98 ); 99 if (EFI_ERROR (Status)) { 100 DEBUG ((EFI_D_ERROR, "DebugAgent: Cannot install configuration table for mailbox!\n")); 101 CpuDeadLoop (); 102 } 103 104 DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (FALSE); 105 106 NewMailbox = (DEBUG_AGENT_MAILBOX *) (UINTN) Address; 107 // 108 // Copy Mailbox and Debug Port Handle buffer to new location in ACPI NVS memory, because original Mailbox 109 // and Debug Port Handle buffer may be free at runtime, SMM debug agent needs to access them 110 // 111 Mailbox = GetMailboxPointer (); 112 CopyMem (NewMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX)); 113 CopyMem (NewMailbox + 1, (VOID *)(UINTN)Mailbox->DebugPortHandle, PcdGet16(PcdDebugPortHandleBufferSize)); 114 // 115 // Update Debug Port Handle in new Mailbox 116 // 117 UpdateMailboxContent (NewMailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, (UINT64)(UINTN)(NewMailbox + 1)); 118 mMailboxPointer = NewMailbox; 119 120 DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (DebugTimerInterruptState); 121 122 Status = gBS->InstallConfigurationTable (&gEfiDebugAgentGuid, (VOID *) mMailboxPointer); 123 if (EFI_ERROR (Status)) { 124 DEBUG ((EFI_D_ERROR, "DebugAgent: Failed to install configuration for mailbox!\n")); 125 CpuDeadLoop (); 126 } 127 } 128 129 /** 130 Debug Agent constructor function. 30 131 31 132 @param[in] ImageHandle The firmware allocated handle for the EFI image. 32 133 @param[in] SystemTable A pointer to the EFI System Table. 33 134 34 @retval RETURN_SUCCESS Allocate the global memory space to store guid and function tables. 35 @retval RETURN_OUT_OF_RESOURCES No enough memory to allocated. 135 @retval RETURN_SUCCESS When this function completed. 36 136 37 137 **/ … … 43 143 ) 44 144 { 45 EFI_STATUS Status; 46 EFI_PHYSICAL_ADDRESS Address; 47 48 if (!mConfigurationTableNeeded) { 49 return RETURN_SUCCESS; 50 } 51 52 Address = 0; 53 Status = gBS->AllocatePages ( 54 AllocateAnyPages, 55 EfiACPIMemoryNVS, 56 EFI_SIZE_TO_PAGES (sizeof (DEBUG_AGENT_MAILBOX)), 57 &Address 58 ); 59 if (EFI_ERROR (Status)) { 60 return Status; 61 } 62 63 CopyMem ( 64 (UINT8 *) (UINTN) Address, 65 (UINT8 *) (UINTN) mMailboxPointer, 66 sizeof (DEBUG_AGENT_MAILBOX) 67 ); 68 69 mMailboxPointer = (DEBUG_AGENT_MAILBOX *) (UINTN) Address; 70 71 return gBS->InstallConfigurationTable (&gEfiDebugAgentGuid, (VOID *) mMailboxPointer); 145 if (mDxeCoreFlag) { 146 // 147 // Invoke internal constructor function only when DXE core links this library instance 148 // 149 InternalConstructorWorker (); 150 } 151 152 return RETURN_SUCCESS; 153 } 154 155 /** 156 Get the pointer to Mailbox from the configuration table. 157 158 @return Pointer to Mailbox. 159 160 **/ 161 DEBUG_AGENT_MAILBOX * 162 GetMailboxFromConfigurationTable ( 163 VOID 164 ) 165 { 166 EFI_STATUS Status; 167 DEBUG_AGENT_MAILBOX *Mailbox; 168 169 Status = EfiGetSystemConfigurationTable (&gEfiDebugAgentGuid, (VOID **) &Mailbox); 170 if (Status == EFI_SUCCESS && Mailbox != NULL) { 171 VerifyMailboxChecksum (Mailbox); 172 return Mailbox; 173 } else { 174 return NULL; 175 } 72 176 } 73 177 … … 86 190 { 87 191 EFI_HOB_GUID_TYPE *GuidHob; 192 UINT64 *MailboxLocation; 193 DEBUG_AGENT_MAILBOX *Mailbox; 88 194 89 195 GuidHob = GetNextGuidHob (&gEfiDebugAgentGuid, HobStart); … … 91 197 return NULL; 92 198 } 93 94 return (DEBUG_AGENT_MAILBOX *) (GET_GUID_HOB_DATA(GuidHob)); 199 MailboxLocation = (UINT64 *) (GET_GUID_HOB_DATA(GuidHob)); 200 Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocation); 201 VerifyMailboxChecksum (Mailbox); 202 203 return Mailbox; 95 204 } 96 205 … … 106 215 ) 107 216 { 217 AcquireMpSpinLock (&mDebugMpContext.MailboxSpinLock); 218 VerifyMailboxChecksum (mMailboxPointer); 219 ReleaseMpSpinLock (&mDebugMpContext.MailboxSpinLock); 108 220 return mMailboxPointer; 109 221 } … … 120 232 ) 121 233 { 122 return (DEBUG_PORT_HANDLE) (UINTN)(mMailboxPointer->DebugPortHandle); 123 } 124 125 234 return (DEBUG_PORT_HANDLE) (UINTN)(GetMailboxPointer ()->DebugPortHandle); 235 } 236 237 /** 238 Worker function to setup IDT table and initialize the IDT entries. 239 240 @param[in] Mailbox Pointer to Mailbox. 241 242 **/ 243 VOID 244 SetupDebugAgentEnviroment ( 245 IN DEBUG_AGENT_MAILBOX *Mailbox 246 ) 247 { 248 IA32_DESCRIPTOR Idtr; 249 UINT16 IdtEntryCount; 250 UINT64 DebugPortHandle; 251 252 if (mMultiProcessorDebugSupport) { 253 InitializeSpinLock (&mDebugMpContext.MpContextSpinLock); 254 InitializeSpinLock (&mDebugMpContext.DebugPortSpinLock); 255 InitializeSpinLock (&mDebugMpContext.MailboxSpinLock); 256 // 257 // Clear Break CPU index value 258 // 259 mDebugMpContext.BreakAtCpuIndex = (UINT32) -1; 260 } 261 262 // 263 // Get original IDT address and size. 264 // 265 AsmReadIdtr ((IA32_DESCRIPTOR *) &Idtr); 266 IdtEntryCount = (UINT16) ((Idtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR)); 267 if (IdtEntryCount < 33) { 268 ZeroMem (&mIdtEntryTable, sizeof (IA32_IDT_GATE_DESCRIPTOR) * 33); 269 // 270 // Copy original IDT table into new one 271 // 272 CopyMem (&mIdtEntryTable, (VOID *) Idtr.Base, Idtr.Limit + 1); 273 // 274 // Load new IDT table 275 // 276 Idtr.Limit = (UINT16) (sizeof (IA32_IDT_GATE_DESCRIPTOR) * 33 - 1); 277 Idtr.Base = (UINTN) &mIdtEntryTable; 278 AsmWriteIdtr ((IA32_DESCRIPTOR *) &Idtr); 279 } 280 281 // 282 // Initialize the IDT table entries to support source level debug. 283 // 284 InitializeDebugIdt (); 285 286 // 287 // If mMailboxPointer is not set before, set it 288 // 289 if (mMailboxPointer == NULL) { 290 if (Mailbox != NULL) { 291 // 292 // If Mailbox exists, copy it into one global variable 293 // 294 CopyMem (&mMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX)); 295 } else { 296 ZeroMem (&mMailbox, sizeof (DEBUG_AGENT_MAILBOX)); 297 } 298 mMailboxPointer = &mMailbox; 299 } 300 301 // 302 // Initialize debug communication port 303 // 304 DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize ((VOID *)(UINTN)mMailboxPointer->DebugPortHandle, NULL); 305 UpdateMailboxContent (mMailboxPointer, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle); 306 307 if (Mailbox == NULL) { 308 // 309 // Trigger one software interrupt to inform HOST 310 // 311 TriggerSoftInterrupt (SYSTEM_RESET_SIGNATURE); 312 SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1); 313 // 314 // Memory has been ready 315 // 316 if (IsHostAttached ()) { 317 // 318 // Trigger one software interrupt to inform HOST 319 // 320 TriggerSoftInterrupt (MEMORY_READY_SIGNATURE); 321 } 322 } 323 } 324 325 126 326 /** 127 327 Initialize debug agent. … … 149 349 ) 150 350 { 351 UINT64 *MailboxLocation; 151 352 DEBUG_AGENT_MAILBOX *Mailbox; 152 IA32_DESCRIPTOR Idtr;153 UINT16 IdtEntryCount;154 353 BOOLEAN InterruptStatus; 155 156 if (InitFlag != DEBUG_AGENT_INIT_DXE_CORE && 157 InitFlag != DEBUG_AGENT_INIT_S3 && 158 InitFlag != DEBUG_AGENT_INIT_DXE_AP) { 159 return; 160 } 161 354 VOID *HobList; 355 IA32_DESCRIPTOR IdtDescriptor; 356 IA32_DESCRIPTOR *Ia32Idtr; 357 IA32_IDT_ENTRY *Ia32IdtEntry; 358 359 if (InitFlag == DEBUG_AGENT_INIT_DXE_AP) { 360 // 361 // Invoked by AP, enable interrupt to let AP could receive IPI from other processors 362 // 363 EnableInterrupts (); 364 return ; 365 } 366 367 // 368 // Disable Debug Timer interrupt 369 // 370 SaveAndSetDebugTimerInterrupt (FALSE); 162 371 // 163 372 // Save and disable original interrupt status … … 165 374 InterruptStatus = SaveAndDisableInterrupts (); 166 375 167 if (InitFlag == DEBUG_AGENT_INIT_DXE_CORE) { 168 // 169 // Try to get Mailbox from GUIDed HOB. 170 // 171 mConfigurationTableNeeded = TRUE; 172 Mailbox = GetMailboxFromHob (Context); 173 174 } else if (InitFlag == DEBUG_AGENT_INIT_DXE_AP) { 175 376 // 377 // Try to get mailbox firstly 378 // 379 HobList = NULL; 380 Mailbox = NULL; 381 MailboxLocation = NULL; 382 383 switch (InitFlag) { 384 385 case DEBUG_AGENT_INIT_DXE_LOAD: 386 // 387 // Check if Debug Agent has been initialized before 388 // 389 if (IsDebugAgentInitialzed ()) { 390 DEBUG ((EFI_D_INFO, "Debug Agent: The former agent will be overwritten by the new one!\n")); 391 } 392 393 mMultiProcessorDebugSupport = TRUE; 394 // 395 // Save original IDT table 396 // 397 AsmReadIdtr (&IdtDescriptor); 398 mSaveIdtTableSize = IdtDescriptor.Limit + 1; 399 mSavedIdtTable = AllocateCopyPool (mSaveIdtTableSize, (VOID *) IdtDescriptor.Base); 400 // 401 // Initialize Debug Timer hardware and save its initial count 402 // 403 mDebugMpContext.DebugTimerInitCount = InitializeDebugTimer (); 404 // 405 // Check if Debug Agent initialized in DXE phase 406 // 407 Mailbox = GetMailboxFromConfigurationTable (); 408 if (Mailbox == NULL) { 409 // 410 // Try to get mailbox from GUIDed HOB build in PEI 411 // 412 HobList = GetHobList (); 413 Mailbox = GetMailboxFromHob (HobList); 414 } 415 // 416 // Set up IDT table and prepare for IDT entries 417 // 418 SetupDebugAgentEnviroment (Mailbox); 419 // 420 // For DEBUG_AGENT_INIT_S3, needn't to install configuration table and EFI Serial IO protocol 421 // For DEBUG_AGENT_INIT_DXE_CORE, InternalConstructorWorker() will invoked in Constructor() 422 // 423 InternalConstructorWorker (); 424 // 425 // Enable interrupt to receive Debug Timer interrupt 426 // 176 427 EnableInterrupts (); 177 428 178 return; 179 180 } else { 181 // 182 // If it is in S3 path, needn't to install configuration table. 183 // 184 Mailbox = NULL; 185 } 186 187 if (Mailbox != NULL) { 188 // 189 // If Mailbox exists, copy it into one global variable. 190 // 191 CopyMem (&mMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX)); 192 mMailbox.DebugPortHandle = 0; 193 } else { 194 // 195 // If Mailbox not exists, used the local Mailbox. 196 // 197 ZeroMem (&mMailbox, sizeof (DEBUG_AGENT_MAILBOX)); 198 } 199 200 mMailboxPointer = &mMailbox; 201 202 // 203 // Get original IDT address and size. 204 // 205 AsmReadIdtr ((IA32_DESCRIPTOR *) &Idtr); 206 IdtEntryCount = (UINT16) ((Idtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR)); 207 if (IdtEntryCount < 33) { 208 Idtr.Limit = (UINT16) (sizeof (IA32_IDT_GATE_DESCRIPTOR) * 33 - 1); 209 Idtr.Base = (UINTN) &mIdtEntryTable; 210 AsmWriteIdtr ((IA32_DESCRIPTOR *) &Idtr); 211 } 212 213 // 214 // Initialize the IDT table entries to support source level debug. 215 // 216 InitializeDebugIdt (); 217 218 // 219 // Initialize debug communication port 220 // 221 mMailboxPointer->DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize (NULL, NULL); 222 223 InitializeSpinLock (&mDebugMpContext.MpContextSpinLock); 224 InitializeSpinLock (&mDebugMpContext.DebugPortSpinLock); 225 226 if (InitFlag == DEBUG_AGENT_INIT_DXE_CORE) { 227 // 228 // Initialize Debug Timer hardware and enable interrupt. 229 // 230 InitializeDebugTimer (); 429 mDebugAgentInitialized = TRUE; 430 FindAndReportModuleImageInfo (SIZE_4KB); 431 432 *(EFI_STATUS *)Context = EFI_SUCCESS; 433 434 if (gST->ConOut != NULL) { 435 Print (L"Debug Agent: Initialized successfully!\r\n"); 436 Print (L"If the Debug Port is serial port, please make sure this serial port isn't connected by ISA Serial driver\r\n"); 437 Print (L"You could do the following steps to disconnect the serial port:\r\n"); 438 Print (L"1: Shell> drivers\r\n"); 439 Print (L" ...\r\n"); 440 Print (L" V VERSION E G G #D #C DRIVER NAME IMAGE NAME\r\n"); 441 Print (L" == ======== = = = == == =================================== ===================\r\n"); 442 Print (L" 8F 0000000A B - - 1 14 PCI Bus Driver PciBusDxe\r\n"); 443 Print (L" 91 00000010 ? - - - - ATA Bus Driver AtaBusDxe\r\n"); 444 Print (L" ...\r\n"); 445 Print (L" A7 0000000A B - - 1 1 ISA Serial Driver IsaSerialDxe\r\n"); 446 Print (L" ...\r\n"); 447 Print (L"2: Shell> dh -d A7\r\n"); 448 Print (L" A7: Image(IsaSerialDxe) ImageDevPath (..9FB3-11D4-9A3A-0090273FC14D))DriverBinding ComponentName ComponentName2\r\n"); 449 Print (L" Driver Name : ISA Serial Driver\r\n"); 450 Print (L" Image Name : FvFile(93B80003-9FB3-11D4-9A3A-0090273FC14D)\r\n"); 451 Print (L" Driver Version : 0000000A\r\n"); 452 Print (L" Driver Type : BUS\r\n"); 453 Print (L" Configuration : NO\r\n"); 454 Print (L" Diagnostics : NO\r\n"); 455 Print (L" Managing :\r\n"); 456 Print (L" Ctrl[EA] : PciRoot(0x0)/Pci(0x1F,0x0)/Serial(0x0)\r\n"); 457 Print (L" Child[EB] : PciRoot(0x0)/Pci(0x1F,0x0)/Serial(0x0)/Uart(115200,8,N,1)\r\n"); 458 Print (L"3: Shell> disconnect EA\r\n"); 459 Print (L"4: Shell> load -nc DebugAgentDxe.efi\r\n\r\n"); 460 } 461 break; 462 463 case DEBUG_AGENT_INIT_DXE_UNLOAD: 464 if (mDebugAgentInitialized) { 465 if (IsHostAttached ()) { 466 Print (L"Debug Agent: Host is still connected, please de-attach TARGET firstly!\r\n"); 467 *(EFI_STATUS *)Context = EFI_ACCESS_DENIED; 468 // 469 // Enable Debug Timer interrupt again 470 // 471 SaveAndSetDebugTimerInterrupt (TRUE); 472 } else { 473 // 474 // Restore original IDT table 475 // 476 AsmReadIdtr (&IdtDescriptor); 477 IdtDescriptor.Limit = (UINT16) (mSaveIdtTableSize - 1); 478 CopyMem ((VOID *) IdtDescriptor.Base, mSavedIdtTable, mSaveIdtTableSize); 479 AsmWriteIdtr (&IdtDescriptor); 480 FreePool (mSavedIdtTable); 481 mDebugAgentInitialized = FALSE; 482 *(EFI_STATUS *)Context = EFI_SUCCESS; 483 } 484 } else { 485 Print (L"Debug Agent: It hasn't been initialized, cannot unload it!\r\n"); 486 *(EFI_STATUS *)Context = EFI_NOT_STARTED; 487 } 488 489 // 490 // Restore interrupt state. 491 // 492 SetInterruptState (InterruptStatus); 493 break; 494 495 case DEBUG_AGENT_INIT_DXE_CORE: 496 mDxeCoreFlag = TRUE; 497 mMultiProcessorDebugSupport = TRUE; 498 // 499 // Initialize Debug Timer hardware and its initial count 500 // 501 mDebugMpContext.DebugTimerInitCount = InitializeDebugTimer (); 502 // 503 // Try to get mailbox from GUIDed HOB build in PEI 504 // 505 HobList = Context; 506 Mailbox = GetMailboxFromHob (HobList); 507 // 508 // Set up IDT table and prepare for IDT entries 509 // 510 SetupDebugAgentEnviroment (Mailbox); 511 // 512 // Enable interrupt to receive Debug Timer interrupt 513 // 231 514 EnableInterrupts (); 232 515 233 return; 234 } else { 235 // 236 // Disable Debug Timer interrupt in S3 path. 237 // 238 SaveAndSetDebugTimerInterrupt (FALSE); 239 240 // 241 // Restore interrupt state. 242 // 243 SetInterruptState (InterruptStatus); 244 } 245 246 } 247 516 break; 517 518 case DEBUG_AGENT_INIT_S3: 519 520 if (Context != NULL) { 521 Ia32Idtr = (IA32_DESCRIPTOR *) Context; 522 Ia32IdtEntry = (IA32_IDT_ENTRY *)(Ia32Idtr->Base); 523 MailboxLocation = (UINT64 *) (UINTN) (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow + 524 (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh << 16)); 525 Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocation); 526 VerifyMailboxChecksum (Mailbox); 527 } 528 // 529 // Save Mailbox pointer in global variable 530 // 531 mMailboxPointer = Mailbox; 532 // 533 // Set up IDT table and prepare for IDT entries 534 // 535 SetupDebugAgentEnviroment (Mailbox); 536 // 537 // Disable interrupt 538 // 539 DisableInterrupts (); 540 FindAndReportModuleImageInfo (SIZE_4KB); 541 if (GetDebugFlag (DEBUG_AGENT_FLAG_BREAK_BOOT_SCRIPT) == 1) { 542 // 543 // If Boot Script entry break is set, code will be break at here. 544 // 545 CpuBreakpoint (); 546 } 547 break; 548 549 default: 550 // 551 // Only DEBUG_AGENT_INIT_PREMEM_SEC and DEBUG_AGENT_INIT_POSTMEM_SEC are allowed for this 552 // Debug Agent library instance. 553 // 554 DEBUG ((EFI_D_ERROR, "Debug Agent: The InitFlag value is not allowed!\n")); 555 CpuDeadLoop (); 556 break; 557 } 558 } -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.h
r48674 r58459 2 2 Header file for Dxe Core Debug Agent Library instance. 3 3 4 Copyright (c) 2010 , Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 18 18 #include <PiDxe.h> 19 19 20 #include <Protocol/SerialIo.h> 21 #include <Protocol/DevicePath.h> 22 #include <Protocol/PiPcd.h> 23 20 24 #include <Library/UefiBootServicesTableLib.h> 21 25 #include <Library/UefiLib.h> 26 #include <Library/DevicePathLib.h> 27 #include <Library/MemoryAllocationLib.h> 22 28 23 29 #include "DebugAgent.h" 24 30 31 /** 32 Install EFI Serial IO protocol based on Debug Communication Library. 33 34 **/ 35 VOID 36 InstallSerialIo ( 37 VOID 38 ); 39 25 40 #endif -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
r48674 r58459 2 2 # Debug Agent library instance for Dxe Core and Dxe modules. 3 3 # 4 # Copyright (c) 2010 , Intel Corporation. All rights reserved.<BR>4 # Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR> 5 5 # 6 6 # This program and the accompanying materials … … 17 17 INF_VERSION = 0x00010005 18 18 BASE_NAME = DxeDebugAgentLib 19 MODULE_UNI_FILE = DxeDebugAgentLib.uni 19 20 FILE_GUID = BA6BAD25-B814-4747-B0B0-0FBB61D40B90 20 21 MODULE_TYPE = DXE_DRIVER … … 33 34 DxeDebugAgent/DxeDebugAgentLib.c 34 35 DxeDebugAgent/DxeDebugAgentLib.h 36 DxeDebugAgent/SerialIo.c 35 37 DebugAgentCommon/DebugAgent.c 36 38 DebugAgentCommon/DebugAgent.h … … 42 44 [Sources.Ia32] 43 45 DebugAgentCommon/Ia32/AsmFuncs.S | GCC 44 DebugAgentCommon/Ia32/AsmFuncs.asm | MSFT46 DebugAgentCommon/Ia32/AsmFuncs.asm 45 47 DebugAgentCommon/Ia32/ArchDebugSupport.h 46 48 DebugAgentCommon/Ia32/ArchDebugSupport.c 47 DebugAgentCommon/Ia32/ArchReadGroupRegister.c48 DebugAgentCommon/Ia32/ArchRegisters.h49 49 DebugAgentCommon/Ia32/DebugException.h 50 50 51 51 [Sources.X64] 52 52 DebugAgentCommon/X64/AsmFuncs.S | GCC 53 DebugAgentCommon/X64/AsmFuncs.asm | MSFT53 DebugAgentCommon/X64/AsmFuncs.asm 54 54 DebugAgentCommon/X64/ArchDebugSupport.h 55 55 DebugAgentCommon/X64/ArchDebugSupport.c 56 DebugAgentCommon/X64/ArchReadGroupRegister.c57 DebugAgentCommon/X64/ArchRegisters.h58 56 DebugAgentCommon/X64/DebugException.h 59 57 … … 77 75 MemoryAllocationLib 78 76 LocalApicLib 77 TimerLib 78 PrintLib 79 PeCoffGetEntryPointLib 80 PeCoffExtraActionLib 81 MemoryAllocationLib 79 82 80 83 [Guids] 81 gEfiDebugAgentGuid ## PRODUCES ## Configuration Table 82 gEfiDebugAgentGuid ## CONSUMES ## HOB 84 ## SOMETIMES_PRODUCES ## SystemTable 85 ## CONSUMES ## HOB 86 gEfiDebugAgentGuid 87 ## SOMETIMES_CONSUMES ## SystemTable 88 ## SOMETIMES_PRODUCES ## SystemTable 89 gEfiVectorHandoffTableGuid 90 91 [Ppis] 92 gEfiVectorHandoffInfoPpiGuid ## UNDEFINED 93 94 [Protocols] 95 gEfiSerialIoProtocolGuid ## SOMETIMES_PRODUCES 96 gEfiDevicePathProtocolGuid ## SOMETIMES_PRODUCES 83 97 84 98 [Pcd] 85 gEfiMdePkgTokenSpaceGuid.PcdFSBClock ## CONSUMES 86 gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdExceptionsIgnoredByDebugger ## CONSUMES 99 gEfiMdePkgTokenSpaceGuid.PcdFSBClock ## SOMETIMES_CONSUMES 100 gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdExceptionsIgnoredByDebugger ## SOMETIMES_CONSUMES 101 gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugPortHandleBufferSize ## CONSUMES 87 102 -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.c
r48674 r58459 2 2 SEC Core Debug Agent Library instance implementition. 3 3 4 Copyright (c) 2010 - 201 1, Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 15 15 #include "SecPeiDebugAgentLib.h" 16 16 17 CONST BOOLEAN MultiProcessorDebugSupport = FALSE; 18 19 /** 20 Get pointer to Mailbox from IDT entry before memory is ready. 17 GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN mSkipBreakpoint = FALSE; 18 19 20 GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_VECTOR_HANDOFF_INFO_PPI mVectorHandoffInfoPpi = { 21 &mVectorHandoffInfoDebugAgent[0] 22 }; 23 24 // 25 // Ppis to be installed 26 // 27 GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_PPI_DESCRIPTOR mVectorHandoffInfoPpiList[] = { 28 { 29 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), 30 &gEfiVectorHandoffInfoPpiGuid, 31 &mVectorHandoffInfoPpi 32 } 33 }; 34 35 GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList[1] = { 36 { 37 (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), 38 &gEfiPeiMemoryDiscoveredPpiGuid, 39 DebugAgentCallbackMemoryDiscoveredPpi 40 } 41 }; 42 43 /** 44 Check if debug agent support multi-processor. 45 46 @retval TRUE Multi-processor is supported. 47 @retval FALSE Multi-processor is not supported. 48 49 **/ 50 BOOLEAN 51 MultiProcessorDebugSupport ( 52 VOID 53 ) 54 { 55 return FALSE; 56 } 57 58 /** 59 Read the Attach/Break-in symbols from the debug port. 60 61 @param[in] Handle Pointer to Debug Port handle. 62 @param[out] BreakSymbol Returned break symbol. 63 64 @retval EFI_SUCCESS Read the symbol in BreakSymbol. 65 @retval EFI_NOT_FOUND No read the break symbol. 66 67 **/ 68 EFI_STATUS 69 DebugReadBreakSymbol ( 70 IN DEBUG_PORT_HANDLE Handle, 71 OUT UINT8 *BreakSymbol 72 ) 73 { 74 EFI_STATUS Status; 75 DEBUG_PACKET_HEADER DebugHeader; 76 UINT8 *Data8; 77 78 *BreakSymbol = 0; 79 // 80 // If Debug Port buffer has data, read it till it was break symbol or Debug Port buffer empty. 81 // 82 Data8 = (UINT8 *) &DebugHeader; 83 while (TRUE) { 84 // 85 // If start symbol is not received 86 // 87 if (!DebugPortPollBuffer (Handle)) { 88 // 89 // If no data in Debug Port, exit 90 // 91 break; 92 } 93 // 94 // Try to read the start symbol 95 // 96 DebugPortReadBuffer (Handle, Data8, 1, 0); 97 if (*Data8 == DEBUG_STARTING_SYMBOL_ATTACH) { 98 *BreakSymbol = *Data8; 99 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Debug Timer attach symbol received %x", *BreakSymbol); 100 return EFI_SUCCESS; 101 } 102 if (*Data8 == DEBUG_STARTING_SYMBOL_NORMAL) { 103 Status = ReadRemainingBreakPacket (Handle, &DebugHeader); 104 if (Status == EFI_SUCCESS) { 105 *BreakSymbol = DebugHeader.Command; 106 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Debug Timer break symbol received %x", *BreakSymbol); 107 return EFI_SUCCESS; 108 } 109 if (Status == EFI_TIMEOUT) { 110 break; 111 } 112 } 113 } 114 115 return EFI_NOT_FOUND; 116 } 117 118 /** 119 Get the pointer to location saved Mailbox pointer from IDT entry. 21 120 22 121 **/ 23 122 VOID * 24 Get MailboxPointerInIdtEntry (123 GetLocationSavedMailboxPointerInIdtEntry ( 25 124 VOID 26 125 ) 27 126 { 28 IA32_IDT_GATE_DESCRIPTOR *IdtEntry; 29 IA32_DESCRIPTOR IdtDescriptor; 30 UINTN Mailbox; 31 32 AsmReadIdtr (&IdtDescriptor); 33 IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base; 34 35 Mailbox = IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow + (IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh << 16); 36 return (VOID *) Mailbox; 127 UINTN *MailboxLocation; 128 129 MailboxLocation = (UINTN *) GetExceptionHandlerInIdtEntry (DEBUG_MAILBOX_VECTOR); 130 // 131 // *MailboxLocation is the pointer to Mailbox 132 // 133 VerifyMailboxChecksum ((DEBUG_AGENT_MAILBOX *) (*MailboxLocation)); 134 return MailboxLocation; 37 135 } 38 136 … … 40 138 Set the pointer of Mailbox into IDT entry before memory is ready. 41 139 42 @param[in] Mailbox The pointer of Mailbox.140 @param[in] MailboxLocation Pointer to location saved Mailbox pointer. 43 141 44 142 **/ 45 143 VOID 46 SetMailboxPointerInIdtEntry ( 47 IN VOID *Mailbox 48 ) 49 { 50 IA32_IDT_GATE_DESCRIPTOR *IdtEntry; 51 IA32_DESCRIPTOR IdtDescriptor; 52 53 AsmReadIdtr (&IdtDescriptor); 54 IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base; 55 56 IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow = (UINT16)(UINTN)Mailbox; 57 IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh = (UINT16)((UINTN)Mailbox >> 16); 58 } 59 60 /** 61 Get the pointer to Mailbox from IDT entry and build the Mailbox into GUIDed Hob 62 after memory is ready. 63 64 @return Pointer to Mailbox. 65 66 **/ 67 DEBUG_AGENT_MAILBOX * 68 BuildMailboxHob ( 144 SetLocationSavedMailboxPointerInIdtEntry ( 145 IN VOID *MailboxLocation 146 ) 147 { 148 SetExceptionHandlerInIdtEntry (DEBUG_MAILBOX_VECTOR, MailboxLocation); 149 } 150 151 /** 152 Get the location of Mailbox pointer from the GUIDed HOB. 153 154 @return Pointer to the location saved Mailbox pointer. 155 156 **/ 157 UINT64 * 158 GetMailboxLocationFromHob ( 69 159 VOID 70 160 ) 71 161 { 72 DEBUG_AGENT_MAILBOX *Mailbox; 73 74 Mailbox = (DEBUG_AGENT_MAILBOX *) GetMailboxPointerInIdtEntry (); 75 76 return BuildGuidDataHob ( 77 &gEfiDebugAgentGuid, 78 Mailbox, 79 sizeof (DEBUG_AGENT_MAILBOX) 80 ); 162 EFI_HOB_GUID_TYPE *GuidHob; 163 164 GuidHob = GetFirstGuidHob (&gEfiDebugAgentGuid); 165 if (GuidHob == NULL) { 166 return NULL; 167 } 168 return (UINT64 *) (GET_GUID_HOB_DATA(GuidHob)); 81 169 } 82 170 … … 92 180 ) 93 181 { 94 return (DEBUG_AGENT_MAILBOX *) GetMailboxPointerInIdtEntry (); 182 UINT64 DebugPortHandle; 183 UINT64 *MailboxLocationInIdt; 184 UINT64 *MailboxLocationInHob; 185 DEBUG_AGENT_MAILBOX *Mailbox; 186 187 // 188 // Get mailbox from IDT entry firstly 189 // 190 MailboxLocationInIdt = GetLocationSavedMailboxPointerInIdtEntry (); 191 Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocationInIdt); 192 // 193 // Cannot used GetDebugFlag() to get Debug Flag to avoid GetMailboxPointer() nested 194 // 195 if (Mailbox->DebugFlag.Bits.CheckMailboxInHob != 1 || 196 Mailbox->DebugFlag.Bits.InitArch != DEBUG_ARCH_SYMBOL) { 197 // 198 // If mailbox was setup in SEC or the current CPU arch is different from the init arch 199 // Debug Agent initialized, return the mailbox from IDT entry directly. 200 // Otherwise, we need to check the mailbox location saved in GUIDed HOB further. 201 // 202 return Mailbox; 203 } 204 205 MailboxLocationInHob = GetMailboxLocationFromHob (); 206 // 207 // Compare mailbox in IDT enry with mailbox in HOB, 208 // need to fix mailbox location if HOB moved by PEI CORE 209 // 210 if (MailboxLocationInHob != MailboxLocationInIdt && MailboxLocationInHob != NULL) { 211 Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocationInHob); 212 // 213 // Fix up Debug Port handler and save new mailbox in IDT entry 214 // 215 Mailbox = (DEBUG_AGENT_MAILBOX *)((UINTN)Mailbox + ((UINTN)(MailboxLocationInHob) - (UINTN)MailboxLocationInIdt)); 216 DebugPortHandle = (UINT64)((UINTN)Mailbox->DebugPortHandle + ((UINTN)(MailboxLocationInHob) - (UINTN)MailboxLocationInIdt)); 217 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle); 218 *MailboxLocationInHob = (UINT64)(UINTN)Mailbox; 219 SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationInHob); 220 // 221 // Clean CheckMailboxInHob flag 222 // 223 Mailbox->DebugFlag.Bits.CheckMailboxInHob = 0; 224 UpdateMailboxChecksum (Mailbox); 225 } 226 227 return Mailbox; 95 228 } 96 229 … … 107 240 { 108 241 DEBUG_AGENT_MAILBOX *DebugAgentMailbox; 109 110 DebugAgentMailbox = (DEBUG_AGENT_MAILBOX *)GetMailboxPointerInIdtEntry();242 243 DebugAgentMailbox = GetMailboxPointer (); 111 244 112 245 return (DEBUG_PORT_HANDLE) (UINTN)(DebugAgentMailbox->DebugPortHandle); … … 114 247 115 248 /** 116 Trigger one software interrupt to debug agent to handle it. 117 118 @param Signature Software interrupt signature. 119 120 **/ 121 VOID 122 TriggerSoftInterrupt ( 123 UINT32 Signature 124 ) 125 { 126 UINTN Dr0; 127 UINTN Dr1; 128 129 // 130 // Save Debug Register State 131 // 132 Dr0 = AsmReadDr0 (); 133 Dr1 = AsmReadDr1 (); 134 135 // 136 // DR0 = Signature 137 // 138 AsmWriteDr0 (SOFT_INTERRUPT_SIGNATURE); 139 AsmWriteDr1 (Signature); 140 141 // 142 // Do INT3 to communicate with HOST side 143 // 144 CpuBreakpoint (); 145 146 // 147 // Restore Debug Register State only when Host didn't change it inside exception handler. 148 // Dr registers can only be changed by setting the HW breakpoint. 149 // 150 AsmWriteDr0 (Dr0); 151 AsmWriteDr1 (Dr1); 152 249 Debug Agent provided notify callback function on Memory Discovered PPI. 250 251 @param[in] PeiServices Indirect reference to the PEI Services Table. 252 @param[in] NotifyDescriptor Address of the notification descriptor data structure. 253 @param[in] Ppi Address of the PPI that was installed. 254 255 @retval EFI_SUCCESS If the function completed successfully. 256 257 **/ 258 EFI_STATUS 259 EFIAPI 260 DebugAgentCallbackMemoryDiscoveredPpi ( 261 IN EFI_PEI_SERVICES **PeiServices, 262 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, 263 IN VOID *Ppi 264 ) 265 { 266 EFI_STATUS Status; 267 DEBUG_AGENT_MAILBOX *Mailbox; 268 BOOLEAN InterruptStatus; 269 EFI_PHYSICAL_ADDRESS Address; 270 DEBUG_AGENT_MAILBOX *NewMailbox; 271 UINT64 *MailboxLocationInHob; 272 273 // 274 // Save and disable original interrupt status 275 // 276 InterruptStatus = SaveAndDisableInterrupts (); 277 278 // 279 // Allocate ACPI NVS memory for new Mailbox and Debug Port Handle buffer 280 // 281 Status = PeiServicesAllocatePages ( 282 EfiACPIMemoryNVS, 283 EFI_SIZE_TO_PAGES (sizeof(DEBUG_AGENT_MAILBOX) + PcdGet16(PcdDebugPortHandleBufferSize)), 284 &Address 285 ); 286 ASSERT_EFI_ERROR (Status); 287 NewMailbox = (DEBUG_AGENT_MAILBOX *) (UINTN) Address; 288 // 289 // Copy Mailbox and Debug Port Handle buffer to new location in ACPI NVS memory, because original Mailbox 290 // and Debug Port Handle buffer in the allocated pool that may be marked as free by DXE Core after DXE Core 291 // reallocates the HOB. 292 // 293 Mailbox = GetMailboxPointer (); 294 CopyMem (NewMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX)); 295 CopyMem (NewMailbox + 1, (VOID *)(UINTN)Mailbox->DebugPortHandle, PcdGet16(PcdDebugPortHandleBufferSize)); 296 // 297 // Update Mailbox Location pointer in GUIDed HOB and IDT entry with new one 298 // 299 MailboxLocationInHob = GetMailboxLocationFromHob (); 300 ASSERT (MailboxLocationInHob != NULL); 301 *MailboxLocationInHob = (UINT64)(UINTN)NewMailbox; 302 SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationInHob); 303 // 304 // Update Debug Port Handle in new Mailbox 305 // 306 UpdateMailboxContent (NewMailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, (UINT64)(UINTN)(NewMailbox + 1)); 307 // 308 // Set physical memory ready flag 309 // 310 SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1); 311 312 if (IsHostAttached ()) { 313 // 314 // Trigger one software interrupt to inform HOST 315 // 316 TriggerSoftInterrupt (MEMORY_READY_SIGNATURE); 317 } 318 319 // 320 // Restore interrupt state. 321 // 322 SetInterruptState (InterruptStatus); 323 324 return EFI_SUCCESS; 153 325 } 154 326 … … 193 365 { 194 366 DEBUG_AGENT_MAILBOX *Mailbox; 367 DEBUG_AGENT_MAILBOX *NewMailbox; 195 368 DEBUG_AGENT_MAILBOX MailboxInStack; 196 369 DEBUG_AGENT_PHASE2_CONTEXT Phase2Context; 197 370 DEBUG_AGENT_CONTEXT_POSTMEM_SEC *DebugAgentContext; 371 EFI_STATUS Status; 372 IA32_DESCRIPTOR *Ia32Idtr; 373 IA32_IDT_ENTRY *Ia32IdtEntry; 374 UINT64 DebugPortHandle; 375 UINT64 MailboxLocation; 376 UINT64 *MailboxLocationPointer; 377 EFI_PHYSICAL_ADDRESS Address; 198 378 199 379 DisableInterrupts (); … … 205 385 InitializeDebugIdt (); 206 386 387 MailboxLocation = (UINT64)(UINTN)&MailboxInStack; 207 388 Mailbox = &MailboxInStack; 208 389 ZeroMem ((VOID *) Mailbox, sizeof (DEBUG_AGENT_MAILBOX)); 209 210 390 // 211 391 // Get and save debug port handle and set the length of memory block. 212 392 // 213 SetMailboxPointerInIdtEntry ((VOID *) Mailbox); 393 SetLocationSavedMailboxPointerInIdtEntry (&MailboxLocation); 394 // 395 // Force error message could be printed during the first shakehand between Target/HOST. 396 // 397 SetDebugFlag (DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL, DEBUG_AGENT_ERROR); 398 // 399 // Save init arch type when debug agent initialized 400 // 401 SetDebugFlag (DEBUG_AGENT_FLAG_INIT_ARCH, DEBUG_ARCH_SYMBOL); 214 402 215 403 InitializeDebugTimer (); 216 404 405 Phase2Context.InitFlag = InitFlag; 217 406 Phase2Context.Context = Context; 218 407 Phase2Context.Function = Function; 219 408 DebugPortInitialize ((VOID *) &Phase2Context, InitializeDebugAgentPhase2); 220 221 409 // 222 410 // If reaches here, it means Debug Port initialization failed. … … 227 415 228 416 case DEBUG_AGENT_INIT_POSTMEM_SEC: 229 417 Mailbox = GetMailboxPointer (); 230 418 // 231 419 // Memory has been ready 232 420 // 233 if (IsHostConnected()) { 421 SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1); 422 if (IsHostAttached ()) { 234 423 // 235 424 // Trigger one software interrupt to inform HOST … … 237 426 TriggerSoftInterrupt (MEMORY_READY_SIGNATURE); 238 427 } 239 428 // 429 // Install Vector Handoff Info PPI to persist vectors used by Debug Agent 430 // 431 Status = PeiServicesInstallPpi (&mVectorHandoffInfoPpiList[0]); 432 if (EFI_ERROR (Status)) { 433 DEBUG ((EFI_D_ERROR, "DebugAgent: Failed to install Vector Handoff Info PPI!\n")); 434 CpuDeadLoop (); 435 } 436 // 437 // Fix up Debug Port handle address and mailbox address 438 // 240 439 DebugAgentContext = (DEBUG_AGENT_CONTEXT_POSTMEM_SEC *) Context; 241 242 Mailbox = (DEBUG_AGENT_MAILBOX *) GetMailboxPointerInIdtEntry (); 243 Mailbox->DebugPortHandle = Mailbox->DebugPortHandle + DebugAgentContext->StackMigrateOffset; 244 245 Mailbox = BuildMailboxHob (); 246 Mailbox = (DEBUG_AGENT_MAILBOX *) ((UINTN) Mailbox + DebugAgentContext->HeapMigrateOffset); 247 248 SetMailboxPointerInIdtEntry ((VOID *) Mailbox); 249 250 EnableInterrupts (); 251 440 if (DebugAgentContext != NULL) { 441 DebugPortHandle = (UINT64)(UINT32)(Mailbox->DebugPortHandle + DebugAgentContext->StackMigrateOffset); 442 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle); 443 Mailbox = (DEBUG_AGENT_MAILBOX *) ((UINTN) Mailbox + DebugAgentContext->StackMigrateOffset); 444 MailboxLocation = (UINT64)(UINTN)Mailbox; 445 // 446 // Build mailbox location in HOB and fix-up its address 447 // 448 MailboxLocationPointer = BuildGuidDataHob ( 449 &gEfiDebugAgentGuid, 450 &MailboxLocation, 451 sizeof (UINT64) 452 ); 453 MailboxLocationPointer = (UINT64 *) ((UINTN) MailboxLocationPointer + DebugAgentContext->HeapMigrateOffset); 454 } else { 455 // 456 // DebugAgentContext is NULL. Then, Mailbox can directly be copied into memory. 457 // Allocate ACPI NVS memory for new Mailbox and Debug Port Handle buffer 458 // 459 Status = PeiServicesAllocatePages ( 460 EfiACPIMemoryNVS, 461 EFI_SIZE_TO_PAGES (sizeof(DEBUG_AGENT_MAILBOX) + PcdGet16(PcdDebugPortHandleBufferSize)), 462 &Address 463 ); 464 if (EFI_ERROR (Status)) { 465 DEBUG ((EFI_D_ERROR, "DebugAgent: Failed to allocate pages!\n")); 466 CpuDeadLoop (); 467 } 468 NewMailbox = (DEBUG_AGENT_MAILBOX *) (UINTN) Address; 469 // 470 // Copy Mailbox and Debug Port Handle buffer to new location in ACPI NVS memory, because original Mailbox 471 // and Debug Port Handle buffer in the allocated pool that may be marked as free by DXE Core after DXE Core 472 // reallocates the HOB. 473 // 474 CopyMem (NewMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX)); 475 CopyMem (NewMailbox + 1, (VOID *)(UINTN)Mailbox->DebugPortHandle, PcdGet16(PcdDebugPortHandleBufferSize)); 476 UpdateMailboxContent (NewMailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, (UINT64)(UINTN)(NewMailbox + 1)); 477 MailboxLocation = (UINT64)(UINTN)NewMailbox; 478 // 479 // Build mailbox location in HOB 480 // 481 MailboxLocationPointer = BuildGuidDataHob ( 482 &gEfiDebugAgentGuid, 483 &MailboxLocation, 484 sizeof (UINT64) 485 ); 486 } 487 // 488 // Update IDT entry to save the location saved mailbox pointer 489 // 490 SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer); 252 491 break; 253 492 493 case DEBUG_AGENT_INIT_PEI: 494 if (Context == NULL) { 495 DEBUG ((EFI_D_ERROR, "DebugAgent: Input parameter Context cannot be NULL!\n")); 496 CpuDeadLoop (); 497 } 498 // 499 // Check if Debug Agent has initialized before 500 // 501 if (IsDebugAgentInitialzed()) { 502 DEBUG ((EFI_D_WARN, "Debug Agent: It has already initialized in SEC Core!\n")); 503 break; 504 } 505 // 506 // Install Vector Handoff Info PPI to persist vectors used by Debug Agent 507 // 508 Status = PeiServicesInstallPpi (&mVectorHandoffInfoPpiList[0]); 509 if (EFI_ERROR (Status)) { 510 DEBUG ((EFI_D_ERROR, "DebugAgent: Failed to install Vector Handoff Info PPI!\n")); 511 CpuDeadLoop (); 512 } 513 // 514 // Set up IDT entries 515 // 516 InitializeDebugIdt (); 517 // 518 // Build mailbox in HOB and setup Mailbox Set In Pei flag 519 // 520 Mailbox = AllocateZeroPool (sizeof (DEBUG_AGENT_MAILBOX)); 521 MailboxLocation = (UINT64)(UINTN)Mailbox; 522 MailboxLocationPointer = BuildGuidDataHob ( 523 &gEfiDebugAgentGuid, 524 &MailboxLocation, 525 sizeof (UINT64) 526 ); 527 528 InitializeDebugTimer (); 529 // 530 // Update IDT entry to save the location pointer saved mailbox pointer 531 // 532 SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer); 533 // 534 // Save init arch type when debug agent initialized 535 // 536 SetDebugFlag (DEBUG_AGENT_FLAG_INIT_ARCH, DEBUG_ARCH_SYMBOL); 537 // 538 // Register for a callback once memory has been initialized. 539 // If memery has been ready, the callback funtion will be invoked immediately 540 // 541 Status = PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList[0]); 542 if (EFI_ERROR (Status)) { 543 DEBUG ((EFI_D_ERROR, "DebugAgent: Failed to register memory discovered callback function!\n")); 544 CpuDeadLoop (); 545 } 546 // 547 // Set HOB check flag if memory has not been ready yet 548 // 549 if (GetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY) == 0) { 550 SetDebugFlag (DEBUG_AGENT_FLAG_CHECK_MAILBOX_IN_HOB, 1); 551 } 552 553 Phase2Context.InitFlag = InitFlag; 554 Phase2Context.Context = Context; 555 Phase2Context.Function = Function; 556 DebugPortInitialize ((VOID *) &Phase2Context, InitializeDebugAgentPhase2); 557 558 FindAndReportModuleImageInfo (4); 559 560 break; 561 562 case DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64: 563 if (Context == NULL) { 564 DEBUG ((EFI_D_ERROR, "DebugAgent: Input parameter Context cannot be NULL!\n")); 565 CpuDeadLoop (); 566 } else { 567 Ia32Idtr = (IA32_DESCRIPTOR *) Context; 568 Ia32IdtEntry = (IA32_IDT_ENTRY *)(Ia32Idtr->Base); 569 MailboxLocationPointer = (UINT64 *) (UINTN) (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow + 570 (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh << 16)); 571 Mailbox = (DEBUG_AGENT_MAILBOX *) (UINTN)(*MailboxLocationPointer); 572 // 573 // Mailbox should valid and setup before executing thunk code 574 // 575 VerifyMailboxChecksum (Mailbox); 576 577 DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize ((VOID *)(UINTN)Mailbox->DebugPortHandle, NULL); 578 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle); 579 // 580 // Set up IDT entries 581 // 582 InitializeDebugIdt (); 583 // 584 // Update IDT entry to save location pointer saved the mailbox pointer 585 // 586 SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer); 587 588 FindAndReportModuleImageInfo (4); 589 } 590 break; 591 254 592 default: 255 256 // 257 // Only DEBUG_AGENT_INIT_PREMEM_SEC and DEBUG_AGENT_INIT_POSTMEM_SEC are allowed for this 593 // 594 // Only DEBUG_AGENT_INIT_PREMEM_SEC and DEBUG_AGENT_INIT_POSTMEM_SEC are allowed for this 258 595 // Debug Agent library instance. 259 596 // … … 261 598 CpuDeadLoop (); 262 599 break; 263 264 } 600 } 601 602 // 603 // Enable CPU interrupts so debug timer interrupts can be delivered 604 // 605 EnableInterrupts (); 265 606 266 607 // … … 269 610 if (Function != NULL) { 270 611 Function (Context); 612 } 613 // 614 // Set return status for DEBUG_AGENT_INIT_PEI 615 // 616 if (InitFlag == DEBUG_AGENT_INIT_PEI && Context != NULL) { 617 *(EFI_STATUS *)Context = EFI_SUCCESS; 271 618 } 272 619 } … … 289 636 { 290 637 DEBUG_AGENT_PHASE2_CONTEXT *Phase2Context; 638 UINT64 *MailboxLocation; 291 639 DEBUG_AGENT_MAILBOX *Mailbox; 292 640 EFI_SEC_PEI_HAND_OFF *SecCoreData; 293 294 Mailbox = GetMailboxPointerInIdtEntry (); 295 Mailbox->DebugPortHandle = (UINT64) (UINTN)DebugPortHandle; 641 UINT16 BufferSize; 642 UINT64 NewDebugPortHandle; 643 644 Phase2Context = (DEBUG_AGENT_PHASE2_CONTEXT *) Context; 645 MailboxLocation = GetLocationSavedMailboxPointerInIdtEntry (); 646 Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocation); 647 BufferSize = PcdGet16(PcdDebugPortHandleBufferSize); 648 if (Phase2Context->InitFlag == DEBUG_AGENT_INIT_PEI) { 649 NewDebugPortHandle = (UINT64)(UINTN)AllocateCopyPool (BufferSize, DebugPortHandle); 650 } else { 651 NewDebugPortHandle = (UINT64)(UINTN)DebugPortHandle; 652 } 653 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, NewDebugPortHandle); 296 654 297 655 // … … 300 658 TriggerSoftInterrupt (SYSTEM_RESET_SIGNATURE); 301 659 302 // 303 // If Temporary RAM region is below 128 MB, then send message to 304 // host to disable low memory filtering. 305 // 306 Phase2Context = (DEBUG_AGENT_PHASE2_CONTEXT *) Context; 307 SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Phase2Context->Context; 308 if ((UINTN)SecCoreData->TemporaryRamBase < BASE_128MB && IsHostConnected ()) { 309 TriggerSoftInterrupt (MEMORY_READY_SIGNATURE); 310 } 311 312 // 313 // Enable CPU interrupts so debug timer interrupts can be delivered 314 // 315 EnableInterrupts (); 316 317 // 318 // Call continuation function if it is not NULL. 319 // 320 if (Phase2Context->Function != NULL) { 660 if (Phase2Context->InitFlag == DEBUG_AGENT_INIT_PREMEM_SEC) { 661 // 662 // If Temporary RAM region is below 128 MB, then send message to 663 // host to disable low memory filtering. 664 // 665 SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Phase2Context->Context; 666 if ((UINTN)SecCoreData->TemporaryRamBase < BASE_128MB && IsHostAttached ()) { 667 SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1); 668 TriggerSoftInterrupt (MEMORY_READY_SIGNATURE); 669 } 670 // 671 // Enable CPU interrupts so debug timer interrupts can be delivered 672 // 673 EnableInterrupts (); 674 // 675 // Call continuation function if it is not NULL. 676 // 321 677 Phase2Context->Function (Phase2Context->Context); 322 678 } -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.h
r48674 r58459 2 2 Header file for Sec Core Debug Agent Library instance. 3 3 4 Copyright (c) 2010 , Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 17 17 18 18 #include <PiPei.h> 19 19 #include <Ppi/MemoryDiscovered.h> 20 #include <Library/PeiServicesLib.h> 21 #include <Library/MemoryAllocationLib.h> 20 22 #include "DebugAgent.h" 21 23 22 24 typedef struct { 25 UINT32 InitFlag; 23 26 VOID *Context; 24 27 DEBUG_AGENT_CONTINUE Function; 25 28 } DEBUG_AGENT_PHASE2_CONTEXT; 26 29 30 /** 31 Caller provided function to be invoked at the end of DebugPortInitialize(). 32 33 Refer to the descrption for DebugPortInitialize() for more details. 34 35 @param[in] Context The first input argument of DebugPortInitialize(). 36 @param[in] DebugPortHandle Debug port handle created by Debug Communication Libary. 37 38 **/ 39 VOID 40 EFIAPI 41 InitializeDebugAgentPhase2 ( 42 IN VOID *Context, 43 IN DEBUG_PORT_HANDLE DebugPortHandle 44 ); 45 46 /** 47 Debug Agent provided notify callback function on Memory Discovered PPI. 48 49 @param[in] PeiServices Indirect reference to the PEI Services Table. 50 @param[in] NotifyDescriptor Address of the notification descriptor data structure. 51 @param[in] Ppi Address of the PPI that was installed. 52 53 @retval EFI_SUCCESS If the function completed successfully. 54 55 **/ 56 EFI_STATUS 57 EFIAPI 58 DebugAgentCallbackMemoryDiscoveredPpi ( 59 IN EFI_PEI_SERVICES **PeiServices, 60 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, 61 IN VOID *Ppi 62 ); 63 27 64 #endif 28 65 -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
r48674 r58459 2 2 # Debug Agent library instance for SEC Core and PEI modules. 3 3 # 4 # Copyright (c) 2010 - 201 1, Intel Corporation. All rights reserved.<BR>4 # Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR> 5 5 # 6 6 # This program and the accompanying materials … … 17 17 INF_VERSION = 0x00010005 18 18 BASE_NAME = SecPeiDebugAgentLib 19 MODULE_UNI_FILE = SecPeiDebugAgentLib.uni 19 20 FILE_GUID = 508B7D59-CD4E-4a6b-A45B-6D3B2D90111E 20 21 MODULE_TYPE = PEIM … … 40 41 [Sources.Ia32] 41 42 DebugAgentCommon/Ia32/AsmFuncs.S | GCC 42 DebugAgentCommon/Ia32/AsmFuncs.asm | MSFT43 DebugAgentCommon/Ia32/AsmFuncs.asm 43 44 DebugAgentCommon/Ia32/ArchDebugSupport.h 44 45 DebugAgentCommon/Ia32/ArchDebugSupport.c 45 DebugAgentCommon/Ia32/ArchReadGroupRegister.c46 DebugAgentCommon/Ia32/ArchRegisters.h47 46 DebugAgentCommon/Ia32/DebugException.h 48 47 49 48 [Sources.X64] 50 49 DebugAgentCommon/X64/AsmFuncs.S | GCC 51 DebugAgentCommon/X64/AsmFuncs.asm | MSFT50 DebugAgentCommon/X64/AsmFuncs.asm 52 51 DebugAgentCommon/X64/ArchDebugSupport.h 53 52 DebugAgentCommon/X64/ArchDebugSupport.c 54 DebugAgentCommon/X64/ArchReadGroupRegister.c55 DebugAgentCommon/X64/ArchRegisters.h56 53 DebugAgentCommon/X64/DebugException.h 57 54 … … 73 70 LocalApicLib 74 71 DebugLib 72 TimerLib 73 PrintLib 74 PeiServicesLib 75 MemoryAllocationLib 76 PeCoffGetEntryPointLib 77 PeCoffExtraActionLib 78 79 [Ppis] 80 gEfiPeiMemoryDiscoveredPpiGuid ## NOTIFY 81 gEfiVectorHandoffInfoPpiGuid ## PRODUCES 75 82 76 83 [Guids] 77 gEfiDebugAgentGuid ## PRODUCES ## HOB 84 ## PRODUCES ## HOB 85 ## CONSUMES ## HOB 86 gEfiDebugAgentGuid 78 87 79 88 [Pcd] 80 gEfiMdePkgTokenSpaceGuid.PcdFSBClock ## CONSUMES 81 gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdExceptionsIgnoredByDebugger ## CONSUMES 89 gEfiMdePkgTokenSpaceGuid.PcdFSBClock ## SOMETIMES_CONSUMES 90 gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdExceptionsIgnoredByDebugger ## SOMETIMES_CONSUMES 91 gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugPortHandleBufferSize ## SOMETIMES_CONSUMES 82 92 -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c
r48674 r58459 2 2 Debug Agent library implementition. 3 3 4 Copyright (c) 2010 , Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 18 18 DEBUG_AGENT_MAILBOX mLocalMailbox; 19 19 UINTN mSavedDebugRegisters[6]; 20 CONST BOOLEAN MultiProcessorDebugSupport = FALSE; 21 20 IA32_IDT_GATE_DESCRIPTOR mIdtEntryTable[33]; 21 BOOLEAN mSkipBreakpoint = FALSE; 22 23 CHAR8 mWarningMsgIgnoreSmmEntryBreak[] = "Ignore smmentrybreak setting for SMI issued during DXE debugging!\r\n"; 24 25 /** 26 Check if debug agent support multi-processor. 27 28 @retval TRUE Multi-processor is supported. 29 @retval FALSE Multi-processor is not supported. 30 31 **/ 32 BOOLEAN 33 MultiProcessorDebugSupport ( 34 VOID 35 ) 36 { 37 return FALSE; 38 } 39 40 /** 41 Read the Attach/Break-in symbols from the debug port. 42 43 @param[in] Handle Pointer to Debug Port handle. 44 @param[out] BreakSymbol Returned break symbol. 45 46 @retval EFI_SUCCESS Read the symbol in BreakSymbol. 47 @retval EFI_NOT_FOUND No read the break symbol. 48 49 **/ 50 EFI_STATUS 51 DebugReadBreakSymbol ( 52 IN DEBUG_PORT_HANDLE Handle, 53 OUT UINT8 *BreakSymbol 54 ) 55 { 56 // 57 // Smm instance has no debug timer to poll break symbol. 58 // 59 return EFI_NOT_FOUND; 60 } 61 62 /** 63 Get the pointer to Mailbox from the GUIDed HOB. 64 65 @return Pointer to Mailbox. 66 67 **/ 68 DEBUG_AGENT_MAILBOX * 69 GetMailboxFromHob ( 70 VOID 71 ) 72 { 73 EFI_HOB_GUID_TYPE *GuidHob; 74 UINT64 *MailboxLocation; 75 DEBUG_AGENT_MAILBOX *Mailbox; 76 77 GuidHob = GetFirstGuidHob (&gEfiDebugAgentGuid); 78 if (GuidHob == NULL) { 79 return NULL; 80 } 81 MailboxLocation = (UINT64 *) (GET_GUID_HOB_DATA(GuidHob)); 82 Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocation); 83 VerifyMailboxChecksum (Mailbox); 84 85 return Mailbox; 86 } 22 87 23 88 /** … … 32 97 ) 33 98 { 99 VerifyMailboxChecksum (mMailboxPointer); 34 100 return mMailboxPointer; 35 101 } … … 46 112 ) 47 113 { 48 return (DEBUG_PORT_HANDLE) (UINTN)( mMailboxPointer->DebugPortHandle);114 return (DEBUG_PORT_HANDLE) (UINTN)(GetMailboxPointer()->DebugPortHandle); 49 115 } 50 116 … … 114 180 ) 115 181 { 116 EFI_STATUS Status; 117 UINT64 DebugPortHandle; 182 EFI_STATUS Status; 183 UINT64 DebugPortHandle; 184 IA32_IDT_GATE_DESCRIPTOR IdtEntry[33]; 185 IA32_DESCRIPTOR IdtDescriptor; 186 IA32_DESCRIPTOR *Ia32Idtr; 187 IA32_IDT_ENTRY *Ia32IdtEntry; 188 IA32_DESCRIPTOR Idtr; 189 UINT16 IdtEntryCount; 190 DEBUG_AGENT_MAILBOX *Mailbox; 191 UINT64 *MailboxLocation; 118 192 119 193 switch (InitFlag) { 120 194 case DEBUG_AGENT_INIT_SMM: 121 Status = EfiGetSystemConfigurationTable (&gEfiDebugAgentGuid, (VOID **) &mMailboxPointer); 122 if (EFI_ERROR (Status) || mMailboxPointer == NULL) { 123 ZeroMem (&mLocalMailbox, sizeof (DEBUG_AGENT_MAILBOX)); 124 mMailboxPointer = &mLocalMailbox; 125 } 195 // 196 // Install configuration table for persisted vector handoff info 197 // 198 Status = gSmst->SmmInstallConfigurationTable ( 199 gSmst, 200 &gEfiVectorHandoffTableGuid, 201 (VOID *) &mVectorHandoffInfoDebugAgent[0], 202 sizeof (EFI_VECTOR_HANDOFF_INFO) * mVectorHandoffInfoCount 203 ); 204 if (EFI_ERROR (Status)) { 205 DEBUG ((EFI_D_ERROR, "DebugAgent: Cannot install configuration table for persisted vector handoff info!\n")); 206 CpuDeadLoop (); 207 } 208 // 209 // Check if Debug Agent initialized in DXE phase 210 // 211 Status = EfiGetSystemConfigurationTable (&gEfiDebugAgentGuid, (VOID **) &Mailbox); 212 if (Status == EFI_SUCCESS && Mailbox != NULL) { 213 VerifyMailboxChecksum (Mailbox); 214 mMailboxPointer = Mailbox; 215 break; 216 } 217 // 218 // Check if Debug Agent initialized in SEC/PEI phase 219 // 220 Mailbox = GetMailboxFromHob (); 221 if (Mailbox != NULL) { 222 mMailboxPointer = Mailbox; 223 break; 224 } 225 // 226 // Debug Agent was not initialized before, use the local mailbox. 227 // 228 ZeroMem (&mLocalMailbox, sizeof (DEBUG_AGENT_MAILBOX)); 229 Mailbox = &mLocalMailbox; 230 // 231 // Save original IDT entries 232 // 233 AsmReadIdtr (&IdtDescriptor); 234 CopyMem (&IdtEntry, (VOID *)IdtDescriptor.Base, 33 * sizeof(IA32_IDT_GATE_DESCRIPTOR)); 235 // 236 // Initialized Debug Agent 237 // 238 InitializeDebugIdt (); 239 DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize ((DEBUG_PORT_HANDLE) (UINTN)Mailbox->DebugPortHandle, NULL); 240 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle); 241 mMailboxPointer = Mailbox; 242 // 243 // Trigger one software interrupt to inform HOST 244 // 245 TriggerSoftInterrupt (SYSTEM_RESET_SIGNATURE); 246 247 SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1); 248 // 249 // Memory has been ready 250 // 251 if (IsHostAttached ()) { 252 // 253 // Trigger one software interrupt to inform HOST 254 // 255 TriggerSoftInterrupt (MEMORY_READY_SIGNATURE); 256 } 257 // 258 // Find and report PE/COFF image info to HOST 259 // 260 FindAndReportModuleImageInfo (SIZE_4KB); 261 // 262 // Restore saved IDT entries 263 // 264 CopyMem ((VOID *)IdtDescriptor.Base, &IdtEntry, 33 * sizeof(IA32_IDT_GATE_DESCRIPTOR)); 126 265 127 266 break; … … 131 270 InitializeDebugIdt (); 132 271 133 if (mMailboxPointer != NULL) { 134 // 135 // Initialize debug communication port 136 // 137 DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize ((DEBUG_PORT_HANDLE) (UINTN)mMailboxPointer->DebugPortHandle, NULL); 138 mMailboxPointer->DebugPortHandle = DebugPortHandle; 139 140 if (mMailboxPointer->DebugFlag.Bits.BreakOnNextSmi == 1) { 272 Mailbox = GetMailboxPointer (); 273 if (GetDebugFlag (DEBUG_AGENT_FLAG_AGENT_IN_PROGRESS) == 1) { 274 // 275 // If Debug Agent has been communicaton state with HOST, we need skip 276 // any break points set in SMM, set Skip Breakpoint flag 277 // 278 mSkipBreakpoint = TRUE; 279 } 280 if (GetDebugFlag (DEBUG_AGENT_FLAG_BREAK_ON_NEXT_SMI) == 1) { 281 if (mSkipBreakpoint) { 282 // 283 // Print warning message if ignore smm entry break 284 // 285 DebugPortWriteBuffer ((DEBUG_PORT_HANDLE) (UINTN)Mailbox->DebugPortHandle, 286 (UINT8 *)mWarningMsgIgnoreSmmEntryBreak, 287 AsciiStrLen (mWarningMsgIgnoreSmmEntryBreak) 288 ); 289 } else { 141 290 // 142 291 // If SMM entry break is set, SMM code will be break at here. … … 148 297 149 298 case DEBUG_AGENT_INIT_EXIT_SMI: 299 Mailbox = GetMailboxPointer (); 300 // 301 // Clear Skip Breakpoint flag 302 // 303 mSkipBreakpoint = FALSE; 150 304 RestoreDebugRegister (); 151 305 break; 306 307 case DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64: 308 if (Context == NULL) { 309 DEBUG ((EFI_D_ERROR, "DebugAgent: Input parameter Context cannot be NULL!\n")); 310 CpuDeadLoop (); 311 } else { 312 Ia32Idtr = (IA32_DESCRIPTOR *) Context; 313 Ia32IdtEntry = (IA32_IDT_ENTRY *)(Ia32Idtr->Base); 314 MailboxLocation = (UINT64 *) (UINTN) (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow + 315 (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh << 16)); 316 mMailboxPointer = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocation); 317 VerifyMailboxChecksum (mMailboxPointer); 318 // 319 // Get original IDT address and size. 320 // 321 AsmReadIdtr ((IA32_DESCRIPTOR *) &Idtr); 322 IdtEntryCount = (UINT16) ((Idtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR)); 323 if (IdtEntryCount < 33) { 324 Idtr.Limit = (UINT16) (sizeof (IA32_IDT_GATE_DESCRIPTOR) * 33 - 1); 325 Idtr.Base = (UINTN) &mIdtEntryTable; 326 ZeroMem (&mIdtEntryTable, Idtr.Limit + 1); 327 AsmWriteIdtr ((IA32_DESCRIPTOR *) &Idtr); 328 } 329 330 InitializeDebugIdt (); 331 // 332 // Initialize Debug Timer hardware and enable interrupt. 333 // 334 InitializeDebugTimer (); 335 EnableInterrupts (); 336 337 FindAndReportModuleImageInfo (SIZE_4KB); 338 } 339 break; 340 341 default: 342 // 343 // Only DEBUG_AGENT_INIT_PREMEM_SEC and DEBUG_AGENT_INIT_POSTMEM_SEC are allowed for this 344 // Debug Agent library instance. 345 // 346 DEBUG ((EFI_D_ERROR, "Debug Agent: The InitFlag value is not allowed!\n")); 347 CpuDeadLoop (); 348 break; 152 349 } 153 350 } -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.h
r48674 r58459 2 2 Header file for Smm Debug Agent Library instance. 3 3 4 Copyright (c) 2010 , Intel Corporation. All rights reserved.<BR>4 Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR> 5 5 This program and the accompanying materials 6 6 are licensed and made available under the terms and conditions of the BSD License … … 19 19 20 20 #include <Library/UefiLib.h> 21 #include <Library/SmmServicesTableLib.h> 21 22 22 23 #include "DebugAgent.h" -
trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf
r48674 r58459 2 2 # Debug Agent library instance for SMM modules. 3 3 # 4 # Copyright (c) 2010 , Intel Corporation. All rights reserved.<BR>4 # Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR> 5 5 # 6 6 # This program and the accompanying materials … … 16 16 [Defines] 17 17 INF_VERSION = 0x00010005 18 BASE_NAME = SecDebugAgentLib 18 BASE_NAME = SmmDebugAgentLib 19 MODULE_UNI_FILE = SmmDebugAgentLib.uni 19 20 FILE_GUID = CB07D74C-598F-4268-A5D1-644FB4A481E8 20 21 MODULE_TYPE = DXE_SMM_DRIVER … … 40 41 [Sources.Ia32] 41 42 DebugAgentCommon/Ia32/AsmFuncs.S | GCC 42 DebugAgentCommon/Ia32/AsmFuncs.asm | MSFT43 DebugAgentCommon/Ia32/AsmFuncs.asm 43 44 DebugAgentCommon/Ia32/ArchDebugSupport.h 44 45 DebugAgentCommon/Ia32/ArchDebugSupport.c 45 DebugAgentCommon/Ia32/ArchReadGroupRegister.c46 DebugAgentCommon/Ia32/ArchRegisters.h47 46 DebugAgentCommon/Ia32/DebugException.h 48 47 49 48 [Sources.X64] 50 49 DebugAgentCommon/X64/AsmFuncs.S | GCC 51 DebugAgentCommon/X64/AsmFuncs.asm | MSFT50 DebugAgentCommon/X64/AsmFuncs.asm 52 51 DebugAgentCommon/X64/ArchDebugSupport.h 53 52 DebugAgentCommon/X64/ArchDebugSupport.c 54 DebugAgentCommon/X64/ArchReadGroupRegister.c55 DebugAgentCommon/X64/ArchRegisters.h56 53 DebugAgentCommon/X64/DebugException.h 57 54 … … 72 69 SynchronizationLib 73 70 LocalApicLib 71 TimerLib 72 PrintLib 73 PeCoffExtraActionLib 74 PeCoffGetEntryPointLib 75 SmmServicesTableLib 74 76 75 77 [Guids] 76 gEfiDebugAgentGuid ## CONSUMES ## Configuration Table 78 ## CONSUMES ## SystemTable 79 ## CONSUMES ## HOB 80 gEfiDebugAgentGuid 81 gEfiVectorHandoffTableGuid ## PRODUCES ## GUID # SMM Configuration Table 77 82 78 83 [Pcd] 79 gEfiMdePkgTokenSpaceGuid.PcdFSBClock ## CONSUMES 80 gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdExceptionsIgnoredByDebugger ## CONSUMES 84 gEfiMdePkgTokenSpaceGuid.PcdFSBClock ## SOMETIMES_CONSUMES 85 # Skip Page Fault exception (14) by default in SMM 86 gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdExceptionsIgnoredByDebugger|0x00004000 ## SOMETIMES_CONSUMES 81 87
Note:
See TracChangeset
for help on using the changeset viewer.