VirtualBox

Ignore:
Timestamp:
Oct 28, 2015 8:17:18 PM (9 years ago)
Author:
vboxsync
Message:

EFI/Firmware: 'svn merge /vendor/edk2/UDK2010.SR1 /vendor/edk2/current .', reverting and removing files+dirs listed in ReadMe.vbox, resolving conflicts with help from ../UDK2014.SP1/. This is a raw untested merge.

Location:
trunk/src/VBox/Devices/EFI/Firmware
Files:
4 deleted
24 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/EFI/Firmware

  • trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.c

    r48674 r58459  
    55  protocol.
    66
    7   Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
     7  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
    88  This program and the accompanying materials
    99  are licensed and made available under the terms and conditions of the BSD License
     
    1919#include "Ia32/DebugException.h"
    2020
    21 /**
    22   Check if HOST is connected based on Mailbox.
    23 
    24   @retval TRUE        HOST is connected.
    25   @retval FALSE       HOST is not connected.
     21GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 mErrorMsgVersionAlert[]       = "\rThe SourceLevelDebugPkg you are using requires a newer version of the Intel(R) UDK Debugger Tool.\r\n";
     22GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 mErrorMsgSendInitPacket[]     = "\rSend INIT break packet and try to connect the HOST (Intel(R) UDK Debugger Tool v1.4) ...\r\n";
     23GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 mErrorMsgConnectOK[]          = "HOST connection is successful!\r\n";
     24GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 mErrorMsgConnectFail[]        = "HOST connection is failed!\r\n";
     25GLOBAL_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//
     30GLOBAL_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
     133GLOBAL_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**/
     145UINT16
     146CalculateCrc16 (
     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.
    26175
    27176**/
    28177BOOLEAN
    29 IsHostConnected (
     178IsDebugAgentInitialzed (
    30179  VOID
    31180  )
    32181{
    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) {
    38186    return TRUE;
    39187  } else {
     
    43191
    44192/**
    45   Set HOST connect flag in Mailbox.
     193  Find and report module image info to HOST.
     194
     195  @param[in] AlignSize      Image aligned size.
    46196
    47197**/
    48198VOID
    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.
     199FindAndReportModuleImageInfo (
     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**/
     261VOID
     262TriggerSoftInterrupt (
     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**/
     301VOID
     302UpdateMailboxChecksum (
     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**/
     317VOID
     318VerifyMailboxChecksum (
     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**/
     344VOID
     345UpdateMailboxContent (
     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.
    64392
    65393**/
    66394VOID
    67395SetDebugFlag (
    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;
    72402
    73403  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**/
     417UINT32
     418GetDebugFlag (
     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**/
     438VOID
     439SendDebugMsgPacket (
     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**/
     475VOID
     476EFIAPI
     477DebugAgentMsgPrint (
     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**/
     518VOID
     519EFIAPI
     520DebugAgentDataMsgPrint (
     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 [ ");
    77541  } 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**/
     580EFI_STATUS
     581ReadRemainingBreakPacket (
     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**/
     630BOOLEAN
     631IsHostAttached (
     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**/
     644VOID
     645SetHostAttached (
     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**/
     662RETURN_STATUS
     663SetDebugSetting (
     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;
    80684}
    81685
     
    144748  // Enable Gx, Lx
    145749  //
    146   Dr7Value |= 0x3 << (RegisterIndex * 2);
     750  Dr7Value |= (UINTN) (0x3 << (RegisterIndex * 2));
    147751  //
    148752  // Set RWx and Lenx
    149753  //
    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);
    152756  //
    153757  // Enable GE, LE
     
    173777  if ((ClearHwBreakpoint->IndexMask & BIT0) != 0) {
    174778    CpuContext->Dr0 = 0;
    175     CpuContext->Dr7 &= ~(0x3 << 0);
     779    CpuContext->Dr7 &= (UINTN)(~(0x3 << 0));
    176780  }
    177781  if ((ClearHwBreakpoint->IndexMask & BIT1) != 0) {
    178782    CpuContext->Dr1 = 0;
    179     CpuContext->Dr7 &= ~(0x3 << 2);
     783    CpuContext->Dr7 &= (UINTN)(~(0x3 << 2));
    180784  }
    181785  if ((ClearHwBreakpoint->IndexMask & BIT2) != 0) {
    182786    CpuContext->Dr2 = 0;
    183     CpuContext->Dr7 &= ~(0x3 << 4);
     787    CpuContext->Dr7 &= (UINTN)(~(0x3 << 4));
    184788  }
    185789  if ((ClearHwBreakpoint->IndexMask & BIT3) != 0) {
    186790    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**/
     805UINT16
     806ArchReadFxStatOffset (
     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**/
     880UINT8 *
     881ArchReadRegisterBuffer (
     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**/
     909VOID
     910SendPacketWithoutData (
     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);
    189929}
    190930
     
    200940  )
    201941{
    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**/
     976RETURN_STATUS
     977ReceivePacket (
     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;
    204990
    205991  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.
    2231078
    2241079  @retval  RETRUEN_SUCCESS  Succeed to receive acknowlege packet from HOST,
     
    2281083**/
    2291084RETURN_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 
     1085SendCommandAndWaitForAckOK (
     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);
    2941138  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_STATUS
    310 ReceivePacket (
    311   OUT UINT8             *InputPacket,
    312   OUT BOOLEAN           *BreakReceived
    313   )
    314 {
    315   DEBUG_COMMAND_HEADER  *DebugHeader;
    316   UINTN                 Received;
    317   DEBUG_PORT_HANDLE     Handle;
    318 
    319   Handle = GetDebugPortHandle();
    320   //
    321   // Find the valid start symbol
    322   //
    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 header
    336   //
    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 has
    345   //
    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;
    3561139}
    3571140
     
    4071190      if (CpuContext->Dr3 == IO_PORT_BREAKPOINT_ADDRESS) {
    4081191
    409         Cause = (UINT8) ((CpuContext->Dr0 == IMAGE_LOAD_SIGNATURE) ? 
     1192        Cause = (UINT8) ((CpuContext->Dr0 == IMAGE_LOAD_SIGNATURE) ?
    4101193          DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD : DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD);
    4111194      }
     
    4131196
    4141197    case SOFT_INTERRUPT_SIGNATURE:
    415    
     1198
    4161199      if (CpuContext->Dr1 == MEMORY_READY_SIGNATURE) {
    4171200        Cause = DEBUG_DATA_BREAK_CAUSE_MEMORY_READY;
     
    4361219  default:
    4371220    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      }
    4391229    }
    4401230    break;
     
    4451235
    4461236/**
     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**/
     1245VOID
     1246CopyMemByWidth (
     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**/
     1302RETURN_STATUS
     1303ReadMemoryAndSendResponsePacket (
     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/**
    4471399  Send packet with response data to HOST.
    4481400
    449   @param[in] CpuContext  Pointer to saved CPU context.
    4501401  @param[in] Data        Pointer to response data buffer.
    4511402  @param[in] DataSize    Size of response data in byte.
    4521403
    4531404  @retval RETURN_SUCCESS      Response data was sent successfully.
    454   @retval RETURN_DEVICE_ERROR Cannot receive DEBUG_COMMAND_OK from HOST.
    4551405
    4561406**/
    4571407RETURN_STATUS
    4581408SendDataResponsePacket (
    459   IN DEBUG_CPU_CONTEXT    *CpuContext,
    4601409  IN UINT8                *Data,
    4611410  IN UINT16               DataSize
    4621411  )
    4631412{
    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);
    5221414}
    5231415
     
    5431435  DebugDataBreakCause.Cause       = GetBreakCause (Vector, CpuContext);
    5441436
    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**/
     1455RETURN_STATUS
     1456AttachHost (
     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**/
     1511VOID
     1512SendBreakPacketToHost (
     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}
    5481546
    5491547/**
     
    5651563  )
    5661564{
    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;
    5921594
    5931595  ProcessorIndex  = 0;
    594   HaltDeferred = BreakReceived;
    595 
    596   if (MultiProcessorDebugSupport) {
     1596  IssuedViewPoint = 0;
     1597  HaltDeferred    = BreakReceived;
     1598
     1599  if (MultiProcessorDebugSupport()) {
    5971600    ProcessorIndex = GetProcessorIndex ();
    5981601    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();
    6001618
    6011619  while (TRUE) {
    6021620
    603     if (MultiProcessorDebugSupport) {
     1621    if (MultiProcessorDebugSupport()) {
     1622      //
     1623      // Check if the current processor is HOST view point
     1624      //
    6041625      if (mDebugMpContext.ViewPointIndex != ProcessorIndex) {
    6051626        if (mDebugMpContext.RunCommandSet) {
     1627          //
     1628          // If HOST view point sets RUN flag, run GO command to leave
     1629          //
    6061630          SetCpuStopFlagByIndex (ProcessorIndex, FALSE);
    6071631          CommandGo (CpuContext);
    6081632          break;
    6091633        } else {
     1634          //
     1635          // Run into loop again
     1636          //
     1637          CpuPause ();
    6101638          continue;
    6111639        }
     
    6131641    }
    6141642
    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);
    6201690      HaltDeferred = TRUE;
    6211691      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;
    6331694
    6341695    case DEBUG_COMMAND_RESET:
    6351696      SendAckPacket (DEBUG_COMMAND_OK);
    636       ReleaseDebugPortControl ();
     1697      SendAckPacket (DEBUG_COMMAND_OK);
     1698      SendAckPacket (DEBUG_COMMAND_OK);
     1699      ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
    6371700
    6381701      ResetCold ();
    6391702      //
    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);
    6431711      break;
    6441712
    6451713    case DEBUG_COMMAND_GO:
    6461714      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
    6471728      if (!HaltDeferred) {
    6481729        //
    6491730        // If no HALT command received when being in-active mode
    6501731        //
    651         if (MultiProcessorDebugSupport) {
    652           Data32 = FindCpuNotRunning ();
     1732        if (MultiProcessorDebugSupport()) {
     1733          Data32 = FindNextPendingBreakCpu ();
    6531734          if (Data32 != -1) {
    6541735            //
    655             // If there are still others processors being in break state,         
     1736            // If there are still others processors being in break state,
    6561737            // send OK packet to HOST to finish this go command
    6571738            //
     
    6651746            SetCpuBreakFlagByIndex (mDebugMpContext.ViewPointIndex, FALSE);
    6661747            //
    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
    6681749            //
    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);
    6721755            break;
    6731756          }
     
    6811764          CpuPause ();
    6821765          //
    683           // Wait for all processors are in running state 
     1766          // Wait for all processors are in running state
    6841767          //
    6851768          while (TRUE) {
     
    7051788        SendAckPacket (DEBUG_COMMAND_OK);
    7061789
    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        }
    7091796        return;
    7101797
     
    7151802        SendAckPacket (DEBUG_COMMAND_HALT_PROCESSED);
    7161803        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         }
    7221804
    7231805        Vector = DEBUG_TIMER_VECTOR;
     
    7271809    case DEBUG_COMMAND_BREAK_CAUSE:
    7281810
    729       if (MultiProcessorDebugSupport && ProcessorIndex != mDebugMpContext.BreakAtCpuIndex) {
     1811      if (MultiProcessorDebugSupport() && ProcessorIndex != mDebugMpContext.BreakAtCpuIndex) {
    7301812        Status = SendBreakCausePacket (DEBUG_TIMER_VECTOR, CpuContext);
    7311813
     
    7481830    case DEBUG_COMMAND_SINGLE_STEPPING:
    7491831      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      }
    7501840
    7511841      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.
    7561850      //
    7571851      return;
     
    7611855      Data8 = *(UINT8 *) (UINTN) Data64;
    7621856      *(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);
    7861875      SendAckPacket (DEBUG_COMMAND_OK);
    7871876      break;
     
    7911880      switch (IoRead->Width) {
    7921881      case 1:
    793         Data64  = IoRead8 (IoRead->Port);
     1882        Data64  = IoRead8 ((UINTN) IoRead->Port);
    7941883        break;
    7951884      case 2:
    796         Data64  = IoRead16 (IoRead->Port);
     1885        Data64  = IoRead16 ((UINTN) IoRead->Port);
    7971886        break;
    7981887      case 4:
    799         Data64  = IoRead32 (IoRead->Port);
     1888        Data64  = IoRead32 ((UINTN) IoRead->Port);
    8001889        break;
    8011890      case 8:
    802         Data64  = IoRead64 (IoRead->Port);
     1891        Data64  = IoRead64 ((UINTN) IoRead->Port);
    8031892        break;
    8041893      default:
    8051894        Data64  = (UINT64) -1;
    8061895      }
    807       Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Data64, IoRead->Width);
     1896      Status = SendDataResponsePacket ((UINT8 *) &Data64, IoRead->Width);
    8081897      break;
    8091898
     
    8121901      switch (IoWrite->Width) {
    8131902      case 1:
    814         Data64  = IoWrite8 (IoWrite->Port, *(UINT8 *) &IoWrite->Data);
     1903        Data64  = IoWrite8 ((UINTN) IoWrite->Port, *(UINT8 *) &IoWrite->Data);
    8151904        break;
    8161905      case 2:
    817         Data64  = IoWrite16 (IoWrite->Port, *(UINT16 *) &IoWrite->Data);
     1906        Data64  = IoWrite16 ((UINTN) IoWrite->Port, *(UINT16 *) &IoWrite->Data);
    8181907        break;
    8191908      case 4:
    820         Data64  = IoWrite32 (IoWrite->Port, *(UINT32 *) &IoWrite->Data);
     1909        Data64  = IoWrite32 ((UINTN) IoWrite->Port, *(UINT32 *) &IoWrite->Data);
    8211910        break;
    8221911      case 8:
    823         Data64  = IoWrite64 (IoWrite->Port, *(UINT64 *) &IoWrite->Data);
     1912        Data64  = IoWrite64 ((UINTN) IoWrite->Port, *(UINT64 *) &IoWrite->Data);
    8241913        break;
    8251914      default:
     
    8291918      break;
    8301919
     1920    case DEBUG_COMMAND_READ_ALL_REGISTERS:
     1921      Status = SendDataResponsePacket ((UINT8 *) CpuContext, sizeof (*CpuContext));
     1922      break;
     1923
    8311924    case DEBUG_COMMAND_READ_REGISTER:
    8321925      RegisterRead = (DEBUG_DATA_READ_REGISTER *) (DebugHeader + 1);
    8331926
    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);
    8521930      } 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;
    8731932      }
    8741933      break;
     
    8761935    case DEBUG_COMMAND_WRITE_REGISTER:
    8771936      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      }
    8801945      break;
    8811946
    8821947    case DEBUG_COMMAND_ARCH_MODE:
    8831948      Data8 = DEBUG_ARCH_SYMBOL;
    884       Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Data8, (UINT16) sizeof (UINT8));
     1949      Status = SendDataResponsePacket ((UINT8 *) &Data8, (UINT16) sizeof (UINT8));
    8851950      break;
    8861951
     
    8881953      MsrRegisterRead = (DEBUG_DATA_READ_MSR *) (DebugHeader + 1);
    8891954      Data64 = AsmReadMsr64 (MsrRegisterRead->Index);
    890       Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Data64, (UINT16) sizeof (UINT64));
     1955      Status = SendDataResponsePacket ((UINT8 *) &Data64, (UINT16) sizeof (UINT64));
    8911956      break;
    8921957
     
    8971962      break;
    8981963
    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      }
    9081969      break;
    9091970
     
    9111972      DebugAgentRevision.Revision = DEBUG_AGENT_REVISION;
    9121973      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));
    9141975      break;
    9151976
    9161977    case DEBUG_COMMAND_GET_EXCEPTION:
    9171978      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));
    9201981      break;
    9211982
    9221983    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);
    9281988          SendAckPacket (DEBUG_COMMAND_OK);
    9291989        } else {
     
    9331993          SendAckPacket (DEBUG_COMMAND_NOT_SUPPORTED);
    9341994        }
    935       } else if (Data32 == 0) {
     1995      } else if (SetViewPoint->ViewPoint == 0) {
    9361996        SendAckPacket (DEBUG_COMMAND_OK);
    9371997
     
    9442004    case DEBUG_COMMAND_GET_VIEWPOINT:
    9452005      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      }
    9472065      break;
    9482066
     
    9582076    }
    9592077
    960     ReleaseDebugPortControl ();
     2078    ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
    9612079    CpuPause ();
    9622080  }
     
    9772095  )
    9782096{
    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()) {
    9942125    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);
    9982160  switch (Vector) {
    9992161  case DEBUG_INT1_VECTOR:
    10002162  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        //
    10112169        break;
    10122170      }
    1013 
    1014       SetHostConnectedFlag ();
    10152171      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:
    10192175      //
    10202176      // Stepping is finished, send Ack package.
    10212177      //
    1022       if (MultiProcessorDebugSupport) {
     2178      if (MultiProcessorDebugSupport()) {
    10232179        mDebugMpContext.BreakAtCpuIndex = ProcessorIndex;
    10242180      }
    10252181      SendAckPacket (DEBUG_COMMAND_OK);
    10262182      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:
    10302186      //
    10312187      // Memory is ready
    10322188      //
    1033       SendAckPacket (DEBUG_COMMAND_MEMORY_READY);
    1034       WaitForAckPacketOK (0, &BreakReceived);
     2189      SendCommandAndWaitForAckOK (DEBUG_COMMAND_MEMORY_READY, READ_PACKET_TIMEOUT, &BreakReceived, NULL);
    10352190      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);
    10772225
    10782226      if (Vector == DEBUG_INT3_VECTOR) {
     
    10942242        CommandCommunication (Vector, CpuContext, BreakReceived);
    10952243      }
     2244      break;
    10962245    }
    10972246
     
    11002249  case DEBUG_TIMER_VECTOR:
    11012250
    1102     if (MultiProcessorDebugSupport) {
     2251    AcquireMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
     2252
     2253    if (MultiProcessorDebugSupport()) {
    11032254      if (IsBsp (ProcessorIndex)) {
    11042255        //
     
    11142265
    11152266      if (!IsBsp (ProcessorIndex) || mDebugMpContext.IpiSentByAp) {
     2267        ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
    11162268        //
    11172269        // If current processor is not BSP or this is one IPI sent by AP
     
    11322284    // Only BSP could run here
    11332285    //
    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,
    11402289      // If yes, go into communication mode with HOST.
    11412290      // If no, exit interrupt process.
    11422291      //
    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        //
    11452304        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) {
    11482324            SetCpuBreakFlagByIndex (ProcessorIndex, TRUE);
    11492325          } else {
     
    11512327          }
    11522328        }
    1153         ReleaseDebugPortControl ();
     2329        ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
    11542330        CommandCommunication (Vector, CpuContext, BreakReceived);
    1155         AcquireDebugPortControl ();
     2331        AcquireMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
    11562332        break;
    11572333      }
     
    11632339    SendApicEoi ();
    11642340
    1165     ReleaseDebugPortControl ();
     2341    ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
    11662342
    11672343    break;
    11682344
    11692345  default:
    1170 
    11712346    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;
    11802353        }
    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
    11852369      CommandCommunication (Vector, CpuContext, BreakReceived);
    11862370    }
     
    11882372  }
    11892373
    1190   if (MultiProcessorDebugSupport) {
     2374  if (MultiProcessorDebugSupport()) {
    11912375    //
    11922376    // Clear flag and wait for all processors run here
    11932377    //
    11942378    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);
    11962396  }
    11972397
  • trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.h

    r48674 r58459  
    22  Command header of for Debug Agent library instance.
    33
    4   Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
    55  This program and the accompanying materials
    66  are licensed and made available under the terms and conditions of the BSD License
     
    1717
    1818#include <Register/LocalApic.h>
    19 
    2019#include <Guid/DebugAgentGuid.h>
    21 
     20#include <Guid/VectorHandoffTable.h>
     21#include <Ppi/VectorHandoffInfo.h>
    2222#include <Library/BaseLib.h>
    2323#include <Library/BaseMemoryLib.h>
     
    3131#include <Library/LocalApicLib.h>
    3232#include <Library/DebugLib.h>
     33#include <Library/TimerLib.h>
     34#include <Library/PrintLib.h>
     35#include <Library/PeCoffGetEntryPointLib.h>
     36#include <Library/PeCoffExtraActionLib.h>
    3337
    3438#include <TransferProtocol.h>
     
    3842#include "DebugTimer.h"
    3943#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
    4656#define DEBUG_TIMER_VECTOR              32
    4757#define DEBUG_MAILBOX_VECTOR            33
     58
     59//
     60//  Timeout value for reading packet (unit is microsecond)
     61//
     62#define READ_PACKET_TIMEOUT     (500 * 1000)
    4863
    4964#define SOFT_INTERRUPT_SIGNATURE    SIGNATURE_32('S','O','F','T')
     
    5368extern UINTN  Exception0Handle;
    5469extern UINTN  TimerInterruptHandle;
    55 extern UINT16 ExceptionStubHeaderSize;
    56 
     70extern UINT32 ExceptionStubHeaderSize;
     71extern BOOLEAN mSkipBreakpoint;
     72extern EFI_VECTOR_HANDOFF_INFO mVectorHandoffInfoDebugAgent[];
     73extern UINTN                   mVectorHandoffInfoCount;
     74
     75//
     76// CPU exception information issued by debug agent
     77//
     78typedef 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)
    57107typedef union {
    58108  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;
    62126  } Bits;
    63   UINT32  Uint32;
     127  UINT64  Uint64;
    64128} DEBUG_AGENT_FLAG;
    65129
    66 #pragma pack(1)
    67130typedef struct {
    68131  DEBUG_AGENT_FLAG           DebugFlag;
    69132  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
    70142} DEBUG_AGENT_MAILBOX;
    71143#pragma pack()
     144
     145///
     146/// Byte packed structure for an IA-32 Interrupt Gate Descriptor.
     147///
     148typedef 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
    72159
    73160typedef union {
     
    91178
    92179/**
    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 VOID
    102 EFIAPI
    103 InitializeDebugAgentPhase2 (
    104   IN VOID                  *Context,
    105   IN DEBUG_PORT_HANDLE     DebugPortHandle
    106   );
    107 
    108 /**
    109180  Initialize IDT entries to support source level debug.
    110181
     
    116187
    117188/**
    118   Write specified register into save CPU context.
     189  Read register value from saved CPU context.
    119190
    120191  @param[in] CpuContext         Pointer to saved CPU context.
    121192  @param[in] Index              Register index value.
    122   @param[in] Offset             Offset in register address range
    123   @param[in] Width              Data width to read.
    124   @param[in] RegisterBuffer     Pointer to input buffer with data.
    125 
    126 **/
    127 VOID
    128 ArchWriteRegisterBuffer (
    129   IN DEBUG_CPU_CONTEXT               *CpuContext,
    130   IN UINT8                           Index,
    131   IN UINT8                           Offset,
    132   IN UINT8                           Width,
    133   IN UINT8                           *RegisterBuffer
    134   );
    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 range
    142193  @param[in] Width              Data width to read.
    143194
     
    149200  IN DEBUG_CPU_CONTEXT               *CpuContext,
    150201  IN UINT8                           Index,
    151   IN UINT8                           Offset,
    152202  IN UINT8                           *Width
    153203  );
     
    156206  Send packet with response data to HOST.
    157207
    158   @param[in] CpuContext  Pointer to saved CPU context.
    159208  @param[in] Data        Pointer to response data buffer.
    160209  @param[in] DataSize    Size of response data in byte.
     
    166215RETURN_STATUS
    167216SendDataResponsePacket (
    168   IN DEBUG_CPU_CONTEXT    *CpuContext,
    169217  IN UINT8                *Data,
    170218  IN UINT16               DataSize
     
    172220
    173221/**
    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.
    279226
    280227**/
    281228BOOLEAN
    282 IsHostConnected (
     229IsHostAttached (
    283230  VOID
    284231  );
     
    306253  );
    307254
     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**/
     265EFI_STATUS
     266DebugReadBreakSymbol (
     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**/
     283VOID
     284EFIAPI
     285DebugAgentMsgPrint (
     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**/
     297VOID
     298TriggerSoftInterrupt (
     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**/
     309BOOLEAN
     310MultiProcessorDebugSupport (
     311  VOID
     312  );
     313
     314/**
     315  Find and report module image info to HOST.
     316 
     317  @param[in] AlignSize      Image aligned size.
     318 
     319**/
     320VOID
     321FindAndReportModuleImageInfo (
     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**/
     332BOOLEAN
     333IsDebugAgentInitialzed (
     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**/
     343VOID
     344UpdateMailboxChecksum (
     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**/
     356VOID
     357VerifyMailboxChecksum (
     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**/
     368VOID
     369SetDebugFlag (
     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**/
     382UINT32
     383GetDebugFlag (
     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**/
     395VOID
     396UpdateMailboxContent (
     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**/
     410VOID *
     411GetExceptionHandlerInIdtEntry (
     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**/
     422VOID
     423SetExceptionHandlerInIdtEntry (
     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**/
     443VOID
     444EFIAPI
     445DebugAgentDataMsgPrint (
     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**/
     463EFI_STATUS
     464ReadRemainingBreakPacket (
     465  IN     DEBUG_PORT_HANDLE      Handle,
     466  IN OUT DEBUG_PACKET_HEADER    *DebugHeader
     467  );
     468
    308469#endif
    309470
  • trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugMp.c

    r48674 r58459  
    22  Multi-Processor support functions implementation.
    33
    4   Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
    55  This program and the accompanying materials
    66  are licensed and made available under the terms and conditions of the BSD License
     
    1515#include "DebugAgent.h"
    1616
    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 access control on debug port.
     17GLOBAL_REMOVE_IF_UNREFERENCED DEBUG_MP_CONTEXT volatile  mDebugMpContext = {0,0,0,{0},{0},0,0,0,0,FALSE,FALSE};
     18
     19GLOBAL_REMOVE_IF_UNREFERENCED DEBUG_CPU_DATA volatile  mDebugCpuData = {0};
     20
     21/**
     22  Acquire a spin lock when Multi-processor supported.
    2323
    2424  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**/
     30VOID
     31AcquireMpSpinLock (
     32  IN OUT SPIN_LOCK           *MpSpinLock
     33  )
     34{
     35  if (!MultiProcessorDebugSupport()) {
    3336    return;
    3437  }
    3538
    3639  while (TRUE) {
    37     if (AcquireSpinLockOrFail (&mDebugMpContext.DebugPortSpinLock)) {
     40    if (AcquireSpinLockOrFail (MpSpinLock)) {
    3841      break;
    3942    }
     
    4447
    4548/**
    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**/
     54VOID
     55ReleaseMpSpinLock (
     56  IN OUT SPIN_LOCK           *MpSpinLock
     57  )
     58{
     59  if (!MultiProcessorDebugSupport()) {
    5560    return;
    5661  }
    5762
    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);
    9164}
    9265
     
    10275  )
    10376{
    104 
     77  DebugAgentMsgPrint (DEBUG_AGENT_INFO, "processor[%x]:Try to halt other processors.\n", CurrentProcessorIndex);
    10578  if (!IsBsp (CurrentProcessorIndex)) {
    10679    SetIpiSentByApFlag (TRUE);;
     
    11891  //
    11992  SendFixedIpiAllExcludingSelf (DEBUG_TIMER_VECTOR);
    120  
     93
    12194}
    12295
     
    137110  LocalApicID = (UINT16) GetApicId ();
    138111
    139   AcquireMpContextControl ();
     112  AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);
    140113
    141114  for (Index = 0; Index < mDebugCpuData.CpuCount; Index ++) {
     
    150123  }
    151124
    152   ReleaseMpContextControl ();
     125  ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock);
    153126
    154127  return Index;
     
    171144  if (AsmMsrBitFieldRead64 (MSR_IA32_APIC_BASE_ADDRESS, 8, 8) == 1) {
    172145    if (mDebugMpContext.BspIndex != ProcessorIndex) {
    173       AcquireMpContextControl ();
     146      AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);
    174147      mDebugMpContext.BspIndex = ProcessorIndex;
    175       ReleaseMpContextControl ();
     148      ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock);
    176149    }
    177150    return TRUE;
     
    198171  UINTN                 Index;
    199172
    200   AcquireMpContextControl ();
     173  AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);
    201174
    202175  Value = mDebugMpContext.CpuStopStatusMask[ProcessorIndex / 8];
     
    209182  mDebugMpContext.CpuStopStatusMask[ProcessorIndex / 8] = Value;
    210183
    211   ReleaseMpContextControl ();
     184  ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock);
    212185}
    213186
     
    229202  UINTN                 Index;
    230203
    231   AcquireMpContextControl ();
     204  AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);
    232205
    233206  Value = mDebugMpContext.CpuBreakMask[ProcessorIndex / 8];
     
    240213  mDebugMpContext.CpuBreakMask[ProcessorIndex / 8] = Value;
    241214
    242   ReleaseMpContextControl ();
     215  ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock);
    243216}
    244217
     
    280253  )
    281254{
    282   AcquireMpContextControl ();
    283 
     255  AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);
    284256  mDebugMpContext.RunCommandSet = RunningFlag;
    285 
    286   ReleaseMpContextControl ();
     257  ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock);
    287258}
    288259
     
    298269  )
    299270{
    300   AcquireMpContextControl ();
    301 
     271  AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);
    302272  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.
    309278
    310279  @param[in] IpiSentByApFlag   TRUE means this IPI is sent by AP.
     
    317286  )
    318287{
    319   AcquireMpContextControl ();
    320 
     288  AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);
    321289  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.
    328295
    329296  @retval others      There is at least one processor broken, the minimum
     
    333300**/
    334301UINT32
    335 FindCpuNotRunning (
     302FindNextPendingBreakCpu (
    336303  VOID
    337304  )
    338305{
    339306  UINT32               Index;
    340  
     307
    341308  for (Index = 0; Index < DEBUG_CPU_MAX_COUNT / 8; Index ++) {
    342309    if (mDebugMpContext.CpuBreakMask[Index] != 0) {
     
    346313  return (UINT32)-1;
    347314}
    348  
     315
    349316/**
    350317  Check if all processors are in running status.
     
    360327{
    361328  UINTN              Index;
    362  
     329
    363330  for (Index = 0; Index < DEBUG_CPU_MAX_COUNT / 8; Index ++) {
    364331    if (mDebugMpContext.CpuStopStatusMask[Index] != 0) {
     
    369336}
    370337
     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**/
     349BOOLEAN
     350IsFirstBreakProcessor (
     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  
    22  Header file for Multi-Processor support.
    33
    4   Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
    55  This program and the accompanying materials
    66  are licensed and made available under the terms and conditions of the BSD License
     
    2626  SPIN_LOCK                 MpContextSpinLock;   ///< Lock for writting MP context
    2727  SPIN_LOCK                 DebugPortSpinLock;   ///< Lock for access debug port
     28  SPIN_LOCK                 MailboxSpinLock;     ///< Lock for accessing mail box
    2829  UINT8                     CpuBreakMask[DEBUG_CPU_MAX_COUNT/8];        ///< Bitmask of all breaking CPUs
    2930  UINT8                     CpuStopStatusMask[DEBUG_CPU_MAX_COUNT/8];   ///< Bitmask of CPU stop status
     
    3334  UINT32                    DebugTimerInitCount; ///< Record BSP's init timer count
    3435  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 is executed.
     36  BOOLEAN                   RunCommandSet;       ///< TRUE: RUN commmand is executing. FALSE : RUN command has been executed.
    3637} DEBUG_MP_CONTEXT;
    3738
    38 extern CONST BOOLEAN               MultiProcessorDebugSupport;
    3939extern DEBUG_MP_CONTEXT volatile   mDebugMpContext;
    4040extern DEBUG_CPU_DATA   volatile   mDebugCpuData;
     
    6363
    6464/**
    65   Acquire access control on MP context.
     65  Acquire a spin lock when Multi-processor supported.
    6666
    6767  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**/
     73VOID
     74AcquireMpSpinLock (
     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**/
     84VOID
     85ReleaseMpSpinLock (
     86  IN OUT SPIN_LOCK           *MpSpinLock
    10287  );
    10388
     
    182167
    183168/**
    184   Initialize debug timer.
     169  Set the IPI send by BPS/AP flag.
    185170
    186171  @param[in] IpiSentByApFlag   TRUE means this IPI is sent by AP.
     
    194179
    195180/**
    196   Check if any processor breaks.
     181  Check the next pending breaking CPU.
    197182
    198183  @retval others      There is at least one processor broken, the minimum
     
    202187**/
    203188UINT32
    204 FindCpuNotRunning (
     189FindNextPendingBreakCpu (
    205190  VOID
    206191  );
     
    218203  );
    219204
     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**/
     216BOOLEAN
     217IsFirstBreakProcessor (
     218  IN UINT32              ProcessorIndex
     219  );
     220 
    220221#endif
    221222
  • trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugTimer.c

    r48674 r58459  
    22  Code for debug timer to support debug agent library implementation.
    33
    4   Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
    55  This program and the accompanying materials
    66  are licensed and made available under the terms and conditions of the BSD License
     
    1818  Initialize CPU local APIC timer.
    1919
     20  @return   32-bit Local APIC timer init count.
    2021**/
    21 VOID
     22UINT32
    2223InitializeDebugTimer (
    2324  VOID
     
    4243  InitializeApicTimer (ApicTimerDivisor, InitialCount, TRUE, DEBUG_TIMER_VECTOR);
    4344
    44   if (MultiProcessorDebugSupport) {
    45     mDebugMpContext.DebugTimerInitCount = InitialCount;
    46   }
     45  return InitialCount;
    4746}
    4847
     
    6665  )
    6766{
    68   BOOLEAN     OldInterruptState;
    6967  BOOLEAN     OldDebugTimerInterruptState;
    7068
    71   OldInterruptState = SaveAndDisableInterrupts ();
    7269  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    }
    7885  }
    7986
    80   SetInterruptState (OldInterruptState);
    8187  return OldDebugTimerInterruptState;
    8288}
  • trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugTimer.h

    r48674 r58459  
    22  Header file for debug timer to support debug agent library implementation.
    33
    4   Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
    55  This program and the accompanying materials
    66  are licensed and made available under the terms and conditions of the BSD License
     
    1717
    1818/**
    19   Initialize debug timer.
     19  Initialize CPU local APIC timer.
    2020
     21  @return   32-bit Local APIC timer init count.
    2122**/
    22 VOID
     23UINT32
    2324InitializeDebugTimer (
    2425  VOID
  • trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/ArchDebugSupport.c

    r48674 r58459  
    11/** @file
    2   Public include file for Debug Port Library.
     2  Supporting functions for IA32 architecture.
    33
    4   Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
    55  This program and the accompanying materials
    66  are licensed and made available under the terms and conditions of the BSD License
     
    1414
    1515#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 UINT16
    27 ArchReadFxStatOffset (
    28   IN  UINT8                     Index,
    29   OUT UINT8                     *Width
    30   )
    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 VOID
    99 ArchWriteRegisterBuffer (
    100   IN DEBUG_CPU_CONTEXT               *CpuContext,
    101   IN UINT8                           Index,
    102   IN UINT8                           Offset,
    103   IN UINT8                           Width,
    104   IN UINT8                           *RegisterBuffer
    105   )
    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 position
    113     //
    114     if (Index >= SOFT_DEBUGGER_REGISTER_MM0) {
    115       Index -= SOFT_DEBUGGER_REGISTER_MM0 - SOFT_DEBUGGER_REGISTER_ST0;
    116     }
    117     //
    118     // FPU/MMX/XMM registers
    119     //
    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 range
    132   @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                           *Width
    143   )
    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 registers
    155     //
    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 VOID
    170 ReadRegisterGroup (
    171   IN DEBUG_CPU_CONTEXT                       *CpuContext,
    172   IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP  *RegisterGroup
    173   )
    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 }
    19816
    19917/**
     
    22240
    22341  for (Index = 0; Index < 20; Index ++) {
    224     if ((PcdGet32 (PcdExceptionsIgnoredByDebugger) & (1 << Index)) != 0) {
     42    if (((PcdGet32 (PcdExceptionsIgnoredByDebugger) & ~(BIT1 | BIT3)) & (1 << Index)) != 0) {
    22543      //
    226       // If the exception is masked to be reserved, skip it
     44      // If the exception is masked to be reserved except for INT1 and INT3, skip it
    22745      //
    22846      continue;
     
    23149    IdtEntry[Index].Bits.OffsetLow  = (UINT16)(UINTN)InterruptHandler;
    23250    IdtEntry[Index].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);
    233     IdtEntry[Index].Bits.Selector        = CodeSegment;
    234     IdtEntry[Index].Bits.GateType        = IA32_IDT_GATE_TYPE_INTERRUPT_32;
     51    IdtEntry[Index].Bits.Selector   = CodeSegment;
     52    IdtEntry[Index].Bits.GateType   = IA32_IDT_GATE_TYPE_INTERRUPT_32;
    23553  }
    23654
     
    23856  IdtEntry[DEBUG_TIMER_VECTOR].Bits.OffsetLow  = (UINT16)(UINTN)InterruptHandler;
    23957  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);
    24265}
     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**/
     75VOID *
     76GetExceptionHandlerInIdtEntry (
     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**/
     97VOID
     98SetExceptionHandlerInIdtEntry (
     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  
    22  IA32 specific defintions for debug agent library instance.
    33
    4   Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
    55  This program and the accompanying materials
    66  are licensed and made available under the terms and conditions of the BSD License
     
    1616#define _ARCH_DEBUG_SUPPORT_H_
    1717
    18 #include "ArchRegisters.h"
     18#include "ProcessorContext.h"
    1919#include "TransferProtocol.h"
    2020
    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 
    2521#define DEBUG_SW_BREAKPOINT_SYMBOL       0xcc
    26 
    2722#define DEBUG_ARCH_SYMBOL                DEBUG_DATA_BREAK_CPU_ARCH_IA32
    2823
     24typedef DEBUG_DATA_IA32_FX_SAVE_STATE    DEBUG_DATA_FX_SAVE_STATE;
    2925typedef DEBUG_DATA_IA32_SYSTEM_CONTEXT   DEBUG_CPU_CONTEXT;
    3026
  • trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S

    r48674 r58459  
    11#------------------------------------------------------------------------------
    22#
    3 # Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
     3# Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
    44# This program and the accompanying materials
    55# are licensed and made available under the terms and conditions of the BSD License
     
    2828ASM_GLOBAL ASM_PFX(CommonEntry)
    2929
     30.macro  AGENT_HANDLER_SIGNATURE
     31  .byte 0x41, 0x47, 0x54, 0x48   # AGENT_HANDLER_SIGNATURE     SIGNATURE_32('A','G','T','H')
     32.endm
     33
    3034.data
    3135
    32 ASM_PFX(ExceptionStubHeaderSize):  .word     ASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle)
     36ASM_PFX(ExceptionStubHeaderSize):  .long     ASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle)
    3337
    3438.text
    3539
     40AGENT_HANDLER_SIGNATURE
    3641ASM_PFX(Exception0Handle):
    3742   cli
     
    3944   mov   $0, %eax
    4045   jmp   ASM_PFX(CommonEntry)
     46AGENT_HANDLER_SIGNATURE
    4147ASM_PFX(Exception1Handle):
    4248   cli
     
    4450   mov   $1, %eax
    4551   jmp   ASM_PFX(CommonEntry)
     52AGENT_HANDLER_SIGNATURE
    4653ASM_PFX(Exception2Handle):
    4754   cli
     
    4956   mov   $2, %eax
    5057   jmp   ASM_PFX(CommonEntry)
     58AGENT_HANDLER_SIGNATURE
    5159ASM_PFX(Exception3Handle):
    5260   cli
     
    5462   mov   $3, %eax
    5563   jmp   ASM_PFX(CommonEntry)
     64AGENT_HANDLER_SIGNATURE
    5665ASM_PFX(Exception4Handle):
    5766   cli
     
    5968   mov   $4, %eax
    6069   jmp   ASM_PFX(CommonEntry)
     70AGENT_HANDLER_SIGNATURE
    6171ASM_PFX(Exception5Handle):
    6272   cli
     
    6474   mov   $5, %eax
    6575   jmp   ASM_PFX(CommonEntry)
     76AGENT_HANDLER_SIGNATURE
    6677ASM_PFX(Exception6Handle):
    6778   cli
     
    6980   mov   $6, %eax
    7081   jmp   ASM_PFX(CommonEntry)
     82AGENT_HANDLER_SIGNATURE
    7183ASM_PFX(Exception7Handle):
    7284   cli
     
    7486   mov   $7, %eax
    7587   jmp   ASM_PFX(CommonEntry)
     88AGENT_HANDLER_SIGNATURE
    7689ASM_PFX(Exception8Handle):
    7790   cli
     
    7992   mov   $8, %eax
    8093   jmp   ASM_PFX(CommonEntry)
     94AGENT_HANDLER_SIGNATURE
    8195ASM_PFX(Exception9Handle):
    8296   cli
     
    8498   mov   $9, %eax
    8599   jmp   ASM_PFX(CommonEntry)
     100AGENT_HANDLER_SIGNATURE
    86101ASM_PFX(Exception10Handle):
    87102   cli
     
    89104   mov   $10, %eax
    90105   jmp   ASM_PFX(CommonEntry)
     106AGENT_HANDLER_SIGNATURE
    91107ASM_PFX(Exception11Handle):
    92108   cli
     
    94110   mov   $11, %eax
    95111   jmp   ASM_PFX(CommonEntry)
     112AGENT_HANDLER_SIGNATURE
    96113ASM_PFX(Exception12Handle):
    97114   cli
     
    99116   mov   $12, %eax
    100117   jmp   ASM_PFX(CommonEntry)
     118AGENT_HANDLER_SIGNATURE
    101119ASM_PFX(Exception13Handle):
    102120   cli
     
    104122   mov   $13, %eax
    105123   jmp   ASM_PFX(CommonEntry)
     124AGENT_HANDLER_SIGNATURE
    106125ASM_PFX(Exception14Handle):
    107126   cli
     
    109128   mov   $14, %eax
    110129   jmp   ASM_PFX(CommonEntry)
     130AGENT_HANDLER_SIGNATURE
    111131ASM_PFX(Exception15Handle):
    112132   cli
     
    114134   mov   $15, %eax
    115135   jmp   ASM_PFX(CommonEntry)
     136AGENT_HANDLER_SIGNATURE
    116137ASM_PFX(Exception16Handle):
    117138   cli
     
    119140   mov   $16, %eax
    120141   jmp   ASM_PFX(CommonEntry)
     142AGENT_HANDLER_SIGNATURE
    121143ASM_PFX(Exception17Handle):
    122144   cli
     
    124146   mov   $17, %eax
    125147   jmp   ASM_PFX(CommonEntry)
     148AGENT_HANDLER_SIGNATURE
    126149ASM_PFX(Exception18Handle):
    127150   cli
     
    129152   mov   $18, %eax
    130153   jmp   ASM_PFX(CommonEntry)
     154AGENT_HANDLER_SIGNATURE
    131155ASM_PFX(Exception19Handle):
    132156   cli
     
    134158   mov   $19, %eax
    135159   jmp   ASM_PFX(CommonEntry)
    136 
     160AGENT_HANDLER_SIGNATURE
    137161ASM_PFX(TimerInterruptHandle):
    138162   cli
     
    260284## clear Dr7 while executing debugger itself
    261285  xorl    %eax,%eax
    262 #  movl    %eax, %dr7
     286  movl    %eax, %dr7
    263287
    264288  movl    %dr6, %eax
     
    281305  movl    %esp,%edi
    282306  .byte 0x0f, 0xae, 0x07   # fxsave [edi]
     307
     308## save the exception data
     309  pushl   8(%esp)
    283310
    284311## Clear Direction Flag
     
    290317  call    ASM_PFX(InterruptProcess)
    291318  addl    $8,%esp
     319
     320## skip the exception data
     321  addl    $4,%esp
    292322
    293323## FX_SAVE_STATE_IA32 FxSaveState;
  • trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.asm

    r48674 r58459  
    11;------------------------------------------------------------------------------
    22;
    3 ; Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
     3; Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
    44; This program and the accompanying materials
    55; are licensed and made available under the terms and conditions of the BSD License
     
    3333public    Exception0Handle, TimerInterruptHandle, ExceptionStubHeaderSize
    3434
     35AGENT_HANDLER_SIGNATURE  MACRO
     36  db   41h, 47h, 54h, 48h       ; SIGNATURE_32('A','G','T','H')
     37ENDM
     38
    3539.data
    3640
    37 ExceptionStubHeaderSize   DW    Exception1Handle - Exception0Handle
     41ExceptionStubHeaderSize   DD    Exception1Handle - Exception0Handle
    3842CommonEntryAddr           DD    CommonEntry
    3943
    4044.code
    4145
     46AGENT_HANDLER_SIGNATURE
    4247Exception0Handle:
    4348    cli
     
    4550    mov     eax, 0
    4651    jmp     dword ptr [CommonEntryAddr]
     52AGENT_HANDLER_SIGNATURE
    4753Exception1Handle:
    4854    cli
     
    5056    mov     eax, 1
    5157    jmp     dword ptr [CommonEntryAddr]
     58AGENT_HANDLER_SIGNATURE
    5259Exception2Handle:
    5360    cli
     
    5562    mov     eax, 2
    5663    jmp     dword ptr [CommonEntryAddr]
     64AGENT_HANDLER_SIGNATURE
    5765Exception3Handle:
    5866    cli
     
    6068    mov     eax, 3
    6169    jmp     dword ptr [CommonEntryAddr]
     70AGENT_HANDLER_SIGNATURE
    6271Exception4Handle:
    6372    cli
     
    6574    mov     eax, 4
    6675    jmp     dword ptr [CommonEntryAddr]
     76AGENT_HANDLER_SIGNATURE
    6777Exception5Handle:
    6878    cli
     
    7080    mov     eax, 5
    7181    jmp     dword ptr [CommonEntryAddr]
     82AGENT_HANDLER_SIGNATURE
    7283Exception6Handle:
    7384    cli
     
    7586    mov     eax, 6
    7687    jmp     dword ptr [CommonEntryAddr]
     88AGENT_HANDLER_SIGNATURE
    7789Exception7Handle:
    7890    cli
     
    8092    mov     eax, 7
    8193    jmp     dword ptr [CommonEntryAddr]
     94AGENT_HANDLER_SIGNATURE
    8295Exception8Handle:
    8396    cli
     
    8598    mov     eax, 8
    8699    jmp     dword ptr [CommonEntryAddr]
     100AGENT_HANDLER_SIGNATURE
    87101Exception9Handle:
    88102    cli
     
    90104    mov     eax, 9
    91105    jmp     dword ptr [CommonEntryAddr]
     106AGENT_HANDLER_SIGNATURE
    92107Exception10Handle:
    93108    cli
     
    95110    mov     eax, 10
    96111    jmp     dword ptr [CommonEntryAddr]
     112AGENT_HANDLER_SIGNATURE
    97113Exception11Handle:
    98114    cli
     
    100116    mov     eax, 11
    101117    jmp     dword ptr [CommonEntryAddr]
     118AGENT_HANDLER_SIGNATURE
    102119Exception12Handle:
    103120    cli
     
    105122    mov     eax, 12
    106123    jmp     dword ptr [CommonEntryAddr]
     124AGENT_HANDLER_SIGNATURE
    107125Exception13Handle:
    108126    cli
     
    110128    mov     eax, 13
    111129    jmp     dword ptr [CommonEntryAddr]
     130AGENT_HANDLER_SIGNATURE
    112131Exception14Handle:
    113132    cli
     
    115134    mov     eax, 14
    116135    jmp     dword ptr [CommonEntryAddr]
     136AGENT_HANDLER_SIGNATURE
    117137Exception15Handle:
    118138    cli
     
    120140    mov     eax, 15
    121141    jmp     dword ptr [CommonEntryAddr]
     142AGENT_HANDLER_SIGNATURE
    122143Exception16Handle:
    123144    cli
     
    125146    mov     eax, 16
    126147    jmp     dword ptr [CommonEntryAddr]
     148AGENT_HANDLER_SIGNATURE
    127149Exception17Handle:
    128150    cli
     
    130152    mov     eax, 17
    131153    jmp     dword ptr [CommonEntryAddr]
     154AGENT_HANDLER_SIGNATURE
    132155Exception18Handle:
    133156    cli
     
    135158    mov     eax, 18
    136159    jmp     dword ptr [CommonEntryAddr]
     160AGENT_HANDLER_SIGNATURE
    137161Exception19Handle:
    138162    cli
     
    140164    mov     eax, 19
    141165    jmp     dword ptr [CommonEntryAddr]
    142 
     166AGENT_HANDLER_SIGNATURE
    143167TimerInterruptHandle:
    144168    cli
     
    260284    ;; clear Dr7 while executing debugger itself
    261285    xor     eax, eax
    262  ;; mov     dr7, eax
     286   mov     dr7, eax
    263287
    264288    ;; Dr6
     
    283307    mov edi, esp
    284308    db 0fh, 0aeh, 00000111y ;fxsave [edi]
     309
     310    ;; save the exception data   
     311    push    dword ptr [ebp + 8]
    285312
    286313    ;; Clear Direction Flag
     
    292319    call    InterruptProcess
    293320    add     esp, 8
     321
     322    ; skip the exception data
     323    add     esp, 4
    294324
    295325    ;; FX_SAVE_STATE_IA32 FxSaveState;
  • trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchDebugSupport.c

    r48674 r58459  
    11/** @file
    2   Supporting functions for x64 architecture.
     2  Supporting functions for X64 architecture.
    33
    4   Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
    55  This program and the accompanying materials
    66  are licensed and made available under the terms and conditions of the BSD License
     
    1414
    1515#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 UINT16
    27 ArchReadFxStatOffset (
    28   IN  UINT8                     Index,
    29   OUT UINT8                     *Width
    30   )
    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 range
    89   @param[in] Width              Data width to read.
    90   @param[in] RegisterBuffer     Pointer to input buffer with data.
    91 
    92 **/
    93 VOID
    94 ArchWriteRegisterBuffer (
    95   IN DEBUG_CPU_CONTEXT               *CpuContext,
    96   IN UINT8                           Index,
    97   IN UINT8                           Offset,
    98   IN UINT8                           Width,
    99   IN UINT8                           *RegisterBuffer
    100   )
    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 position
    108     //
    109     if (Index >= SOFT_DEBUGGER_REGISTER_MM0) {
    110       Index -= SOFT_DEBUGGER_REGISTER_MM0 - SOFT_DEBUGGER_REGISTER_ST0;
    111     }
    112 
    113     //
    114     // FPU/MMX/XMM registers
    115     //
    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 range
    128   @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                           *Width
    139   )
    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 registers
    151     //
    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 VOID
    166 ReadRegisterGroup (
    167   IN DEBUG_CPU_CONTEXT                       *CpuContext,
    168   IN DEBUG_DATA_REPONSE_READ_REGISTER_GROUP  *RegisterGroup
    169   )
    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 }
    20916
    21017/**
     
    23340
    23441  for (Index = 0; Index < 20; Index ++) {
    235     if ((PcdGet32 (PcdExceptionsIgnoredByDebugger) & (1 << Index)) != 0) {
     42    if (((PcdGet32 (PcdExceptionsIgnoredByDebugger) & ~(BIT1 | BIT3)) & (1 << Index)) != 0) {
    23643      //
    237       // If the exception is masked to be reserved, skip it
     44      // If the exception is masked to be reserved except for INT1 and INT3, skip it
    23845      //
    23946      continue;
     
    25360  IdtEntry[DEBUG_TIMER_VECTOR].Bits.Selector        = CodeSegment;
    25461  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);
    25567}
     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**/
     77VOID *
     78GetExceptionHandlerInIdtEntry (
     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**/
     100VOID
     101SetExceptionHandlerInIdtEntry (
     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  
    22  X64 specific defintions for debug agent library instance.
    33
    4   Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
    55  This program and the accompanying materials
    66  are licensed and made available under the terms and conditions of the BSD License
     
    1616#define _ARCH_DEBUG_SUPPORT_H_
    1717
    18 #include "ArchRegisters.h"
     18#include "ProcessorContext.h"
    1919#include "TransferProtocol.h"
    2020
    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 
    2521#define DEBUG_SW_BREAKPOINT_SYMBOL       0xcc
    26 
    2722#define DEBUG_ARCH_SYMBOL                DEBUG_DATA_BREAK_CPU_ARCH_X64
    2823
     24typedef DEBUG_DATA_X64_FX_SAVE_STATE     DEBUG_DATA_FX_SAVE_STATE;
    2925typedef DEBUG_DATA_X64_SYSTEM_CONTEXT    DEBUG_CPU_CONTEXT;
    3026
  • trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.S

    r48674 r58459  
    11#------------------------------------------------------------------------------
    22#
    3 # Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
     3# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
    44# This program and the accompanying materials
    55# are licensed and made available under the terms and conditions of the BSD License
     
    2929ASM_GLOBAL ASM_PFX(CommonEntry)
    3030
     31.macro  AGENT_HANDLER_SIGNATURE
     32  .byte 0x41, 0x47, 0x54, 0x48   # AGENT_HANDLER_SIGNATURE     SIGNATURE_32('A','G','T','H')
     33.endm
     34
    3135.data
    3236
    33 ASM_PFX(ExceptionStubHeaderSize):  .word     ASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle)
     37ASM_PFX(ExceptionStubHeaderSize):  .long     ASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle)
    3438
    3539
    3640.text
    3741
     42AGENT_HANDLER_SIGNATURE
    3843ASM_PFX(Exception0Handle):
    3944   cli
     
    4146   mov   $0, %rcx
    4247   jmp   ASM_PFX(CommonEntry)
     48AGENT_HANDLER_SIGNATURE
    4349ASM_PFX(Exception1Handle):
    4450   cli
     
    4652   mov   $1, %rcx
    4753   jmp   ASM_PFX(CommonEntry)
     54AGENT_HANDLER_SIGNATURE
    4855ASM_PFX(Exception2Handle):
    4956   cli
     
    5158   mov   $2, %rcx
    5259   jmp   ASM_PFX(CommonEntry)
     60AGENT_HANDLER_SIGNATURE
    5361ASM_PFX(Exception3Handle):
    5462   cli
     
    5664   mov   $3, %rcx
    5765   jmp   ASM_PFX(CommonEntry)
     66AGENT_HANDLER_SIGNATURE
    5867ASM_PFX(Exception4Handle):
    5968   cli
     
    6170   mov   $4, %rcx
    6271   jmp   ASM_PFX(CommonEntry)
     72AGENT_HANDLER_SIGNATURE
    6373ASM_PFX(Exception5Handle):
    6474   cli
     
    6676   mov   $5, %rcx
    6777   jmp   ASM_PFX(CommonEntry)
     78AGENT_HANDLER_SIGNATURE
    6879ASM_PFX(Exception6Handle):
    6980   cli
     
    7182   mov   $6, %rcx
    7283   jmp   ASM_PFX(CommonEntry)
     84AGENT_HANDLER_SIGNATURE
    7385ASM_PFX(Exception7Handle):
    7486   cli
     
    7688   mov   $7, %rcx
    7789   jmp   ASM_PFX(CommonEntry)
     90AGENT_HANDLER_SIGNATURE
    7891ASM_PFX(Exception8Handle):
    7992   cli
     
    8194   mov   $8, %rcx
    8295   jmp   ASM_PFX(CommonEntry)
     96AGENT_HANDLER_SIGNATURE
    8397ASM_PFX(Exception9Handle):
    8498   cli
     
    86100   mov   $9, %rcx
    87101   jmp   ASM_PFX(CommonEntry)
     102AGENT_HANDLER_SIGNATURE
    88103ASM_PFX(Exception10Handle):
    89104   cli
     
    91106   mov   $10, %rcx
    92107   jmp   ASM_PFX(CommonEntry)
     108AGENT_HANDLER_SIGNATURE
    93109ASM_PFX(Exception11Handle):
    94110   cli
     
    96112   mov   $11, %rcx
    97113   jmp   ASM_PFX(CommonEntry)
     114AGENT_HANDLER_SIGNATURE
    98115ASM_PFX(Exception12Handle):
    99116   cli
     
    101118   mov   $12, %rcx
    102119   jmp   ASM_PFX(CommonEntry)
     120AGENT_HANDLER_SIGNATURE
    103121ASM_PFX(Exception13Handle):
    104122   cli
     
    106124   mov   $13, %rcx
    107125   jmp   ASM_PFX(CommonEntry)
     126AGENT_HANDLER_SIGNATURE
    108127ASM_PFX(Exception14Handle):
    109128   cli
     
    111130   mov   $14, %rcx
    112131   jmp   ASM_PFX(CommonEntry)
     132AGENT_HANDLER_SIGNATURE
    113133ASM_PFX(Exception15Handle):
    114134   cli
     
    116136   mov   $15, %rcx
    117137   jmp   ASM_PFX(CommonEntry)
     138AGENT_HANDLER_SIGNATURE
    118139ASM_PFX(Exception16Handle):
    119140   cli
     
    121142   mov   $16, %rcx
    122143   jmp   ASM_PFX(CommonEntry)
     144AGENT_HANDLER_SIGNATURE
    123145ASM_PFX(Exception17Handle):
    124146   cli
     
    126148   mov   $17, %rcx
    127149   jmp   ASM_PFX(CommonEntry)
     150AGENT_HANDLER_SIGNATURE
    128151ASM_PFX(Exception18Handle):
    129152   cli
     
    131154   mov   $18, %rcx
    132155   jmp   ASM_PFX(CommonEntry)
     156AGENT_HANDLER_SIGNATURE
    133157ASM_PFX(Exception19Handle):
    134158   cli
     
    136160   mov   $19, %rcx
    137161   jmp   ASM_PFX(CommonEntry)
    138 
     162AGENT_HANDLER_SIGNATURE
    139163ASM_PFX(TimerInterruptHandle):
    140164   cli
     
    248272#  movq     %cs, %rax
    249273  pushq    %rax
    250   movq     %ds, %rax
    251   pushq    %rax
    252   movq     %es, %rax
    253   pushq    %rax
    254   movq     %fs, %rax
    255   pushq    %rax
    256   movq     %gs, %rax
     274  mov      %ds, %rax
     275  pushq    %rax
     276  mov      %es, %rax
     277  pushq    %rax
     278  mov      %fs, %rax
     279  pushq    %rax
     280  mov      %gs, %rax
    257281  pushq    %rax
    258282
     
    281305## clear Dr7 while executing debugger itself
    282306   xorq    %rax, %rax
    283 #debug   movq    %rax, %dr7
     307   movq    %rax, %dr7
    284308
    285309   movq    %dr6, %rax
     
    302326   movq    %rsp, %rdi
    303327   .byte   0x0f, 0xae, 0b00000111
     328
     329## save the exception data;
     330   pushq   16(%rbp)
    304331
    305332## Clear Direction Flag
     
    314341  # and make sure RSP is 16-byte aligned
    315342  #
    316    subq    $(4 * 8), %rsp
     343   subq    $(32 + 8), %rsp
    317344   call    ASM_PFX(InterruptProcess)
    318    addq    $(4 * 8), %rsp
     345   addq    $(32 + 8), %rsp
     346
     347## skip the exception data;
     348   addq    $8, %rsp
    319349
    320350## FX_SAVE_STATE_X64 FxSaveState;
     
    356386  # (X64 will not use fs and gs, so we do not restore it)
    357387   popq     %rax
    358   movw    %rax, %es
    359    popq     %rax
    360   movw    %rax, %ds
     388   mov      %rax, %es
     389   popq     %rax
     390   mov      %rax, %ds
    361391   popq     32(%rbp)
    362392   popq     56(%rbp)
  • trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/AsmFuncs.asm

    r48674 r58459  
    11;------------------------------------------------------------------------------
    22;
    3 ; Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
     3; Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
    44; This program and the accompanying materials
    55; are licensed and made available under the terms and conditions of the BSD License
     
    2929public          Exception0Handle, TimerInterruptHandle, ExceptionStubHeaderSize
    3030
    31 ExceptionStubHeaderSize        dw      Exception1Handle - Exception0Handle ;
     31AGENT_HANDLER_SIGNATURE  MACRO
     32  db   41h, 47h, 54h, 48h       ; SIGNATURE_32('A','G','T','H')
     33ENDM
     34
     35ExceptionStubHeaderSize        dd      Exception1Handle - Exception0Handle ;
    3236CommonEntryAddr                dq      CommonEntry ;
    3337
    3438.code
    3539
     40AGENT_HANDLER_SIGNATURE
    3641Exception0Handle:
    3742    cli
     
    3944    mov     rcx, 0
    4045    jmp     qword ptr [CommonEntryAddr]
     46AGENT_HANDLER_SIGNATURE
    4147Exception1Handle:
    4248    cli
     
    4450    mov     rcx, 1
    4551    jmp     qword ptr [CommonEntryAddr]
     52AGENT_HANDLER_SIGNATURE
    4653Exception2Handle:
    4754    cli
     
    4956    mov     rcx, 2
    5057    jmp     qword ptr [CommonEntryAddr]
     58AGENT_HANDLER_SIGNATURE
    5159Exception3Handle:
    5260    cli
     
    5462    mov     rcx, 3
    5563    jmp     qword ptr [CommonEntryAddr]
     64AGENT_HANDLER_SIGNATURE
    5665Exception4Handle:
    5766    cli
     
    5968    mov     rcx, 4
    6069    jmp     qword ptr [CommonEntryAddr]
     70AGENT_HANDLER_SIGNATURE
    6171Exception5Handle:
    6272    cli
     
    6474    mov     rcx, 5
    6575    jmp     qword ptr [CommonEntryAddr]
     76AGENT_HANDLER_SIGNATURE
    6677Exception6Handle:
    6778    cli
     
    6980    mov     rcx, 6
    7081    jmp     qword ptr [CommonEntryAddr]
     82AGENT_HANDLER_SIGNATURE
    7183Exception7Handle:
    7284    cli
     
    7486    mov     rcx, 7
    7587    jmp     qword ptr [CommonEntryAddr]
     88AGENT_HANDLER_SIGNATURE
    7689Exception8Handle:
    7790    cli
     
    7992    mov     rcx, 8
    8093    jmp     qword ptr [CommonEntryAddr]
     94AGENT_HANDLER_SIGNATURE
    8195Exception9Handle:
    8296    cli
     
    8498    mov     rcx, 9
    8599    jmp     qword ptr [CommonEntryAddr]
     100AGENT_HANDLER_SIGNATURE
    86101Exception10Handle:
    87102    cli
     
    89104    mov     rcx, 10
    90105    jmp     qword ptr [CommonEntryAddr]
     106AGENT_HANDLER_SIGNATURE
    91107Exception11Handle:
    92108    cli
     
    94110    mov     rcx, 11
    95111    jmp     qword ptr [CommonEntryAddr]
     112AGENT_HANDLER_SIGNATURE
    96113Exception12Handle:
    97114    cli
     
    99116    mov     rcx, 12
    100117    jmp     qword ptr [CommonEntryAddr]
     118AGENT_HANDLER_SIGNATURE
    101119Exception13Handle:
    102120    cli
     
    104122    mov     rcx, 13
    105123    jmp     qword ptr [CommonEntryAddr]
     124AGENT_HANDLER_SIGNATURE
    106125Exception14Handle:
    107126    cli
     
    109128    mov     rcx, 14
    110129    jmp     qword ptr [CommonEntryAddr]
     130AGENT_HANDLER_SIGNATURE
    111131Exception15Handle:
    112132    cli
     
    114134    mov     rcx, 15
    115135    jmp     qword ptr [CommonEntryAddr]
     136AGENT_HANDLER_SIGNATURE
    116137Exception16Handle:
    117138    cli
     
    119140    mov     rcx, 16
    120141    jmp     qword ptr [CommonEntryAddr]
     142AGENT_HANDLER_SIGNATURE
    121143Exception17Handle:
    122144    cli
     
    124146    mov     rcx, 17
    125147    jmp     qword ptr [CommonEntryAddr]
     148AGENT_HANDLER_SIGNATURE
    126149Exception18Handle:
    127150    cli
     
    129152    mov     rcx, 18
    130153    jmp     qword ptr [CommonEntryAddr]
     154AGENT_HANDLER_SIGNATURE
    131155Exception19Handle:
    132156    cli
     
    134158    mov     rcx, 19
    135159    jmp     qword ptr [CommonEntryAddr]
    136 
     160AGENT_HANDLER_SIGNATURE
    137161TimerInterruptHandle:
    138162    cli
     
    199223    mov     rax, cr2
    200224    push    rax
    201     push    0         ; cr0 will not saved???
     225    push    0
    202226    mov     rax, cr0
    203227    push    rax
     
    264288
    265289    sub     rsp, 512
    266     mov rdi, rsp
     290    mov     rdi, rsp
    267291    db 0fh, 0aeh, 00000111y ;fxsave [rdi]
     292
     293    ;; save the exception data
     294    push    qword ptr [rbp + 16]
    268295
    269296    ;; Clear Direction Flag
     
    274301    mov     r15, rcx      ; save vector in r15
    275302   
    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
    277308    call    InterruptProcess
    278     add     rsp, 32
     309    add     rsp, 32 + 8
     310
     311    ;; skip the exception data
     312    add     rsp, 8
    279313   
    280314    mov     rsi, rsp
  • trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c

    r48674 r58459  
    22  Debug Agent library implementition for Dxe Core and Dxr modules.
    33
    4   Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
    55  This program and the accompanying materials
    66  are licensed and made available under the terms and conditions of the BSD License
     
    1616
    1717DEBUG_AGENT_MAILBOX          mMailbox;
    18 
    19 DEBUG_AGENT_MAILBOX          *mMailboxPointer;
    20 
     18DEBUG_AGENT_MAILBOX          *mMailboxPointer = NULL;
    2119IA32_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
     20BOOLEAN                      mDxeCoreFlag                = FALSE;
     21BOOLEAN                      mMultiProcessorDebugSupport = FALSE;
     22VOID                         *mSavedIdtTable             = NULL;
     23UINTN                        mSaveIdtTableSize           = 0;
     24BOOLEAN                      mDebugAgentInitialized      = FALSE;
     25BOOLEAN                      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**/
     34BOOLEAN
     35MultiProcessorDebugSupport (
     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
    2947  in system table to store its pointer.
     48
     49**/
     50VOID
     51InternalConstructorWorker (
     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.
    30131
    31132  @param[in]  ImageHandle   The firmware allocated handle for the EFI image.
    32133  @param[in]  SystemTable   A pointer to the EFI System Table.
    33134
    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.
    36136
    37137**/
     
    43143  )
    44144{
    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**/
     161DEBUG_AGENT_MAILBOX *
     162GetMailboxFromConfigurationTable (
     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  }
    72176}
    73177
     
    86190{
    87191  EFI_HOB_GUID_TYPE        *GuidHob;
     192  UINT64                   *MailboxLocation;
     193  DEBUG_AGENT_MAILBOX      *Mailbox;
    88194
    89195  GuidHob = GetNextGuidHob (&gEfiDebugAgentGuid, HobStart);
     
    91197    return NULL;
    92198  }
    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;
    95204}
    96205
     
    106215  )
    107216{
     217  AcquireMpSpinLock (&mDebugMpContext.MailboxSpinLock);
     218  VerifyMailboxChecksum (mMailboxPointer);
     219  ReleaseMpSpinLock (&mDebugMpContext.MailboxSpinLock);
    108220  return mMailboxPointer;
    109221}
     
    120232  )
    121233{
    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**/
     243VOID
     244SetupDebugAgentEnviroment (
     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
    126326/**
    127327  Initialize debug agent.
     
    149349  )
    150350{
     351  UINT64                       *MailboxLocation;
    151352  DEBUG_AGENT_MAILBOX          *Mailbox;
    152   IA32_DESCRIPTOR              Idtr;
    153   UINT16                       IdtEntryCount;
    154353  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);
    162371  //
    163372  // Save and disable original interrupt status
     
    165374  InterruptStatus = SaveAndDisableInterrupts ();
    166375
    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    //
    176427    EnableInterrupts ();
    177428
    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    //
    231514    EnableInterrupts ();
    232515
    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  
    22  Header file for Dxe Core Debug Agent Library instance.
    33
    4   Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
    55  This program and the accompanying materials
    66  are licensed and made available under the terms and conditions of the BSD License
     
    1818#include <PiDxe.h>
    1919
     20#include <Protocol/SerialIo.h>
     21#include <Protocol/DevicePath.h>
     22#include <Protocol/PiPcd.h>
     23
    2024#include <Library/UefiBootServicesTableLib.h>
    2125#include <Library/UefiLib.h>
     26#include <Library/DevicePathLib.h>
     27#include <Library/MemoryAllocationLib.h>
    2228
    2329#include "DebugAgent.h"
    2430
     31/**
     32  Install EFI Serial IO protocol based on Debug Communication Library.
     33
     34**/
     35VOID
     36InstallSerialIo (
     37  VOID
     38  );
     39 
    2540#endif
  • trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf

    r48674 r58459  
    22#  Debug Agent library instance for Dxe Core and Dxe modules.
    33#
    4 #  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
     4#  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
    55#
    66#  This program and the accompanying materials
     
    1717  INF_VERSION                    = 0x00010005
    1818  BASE_NAME                      = DxeDebugAgentLib
     19  MODULE_UNI_FILE                = DxeDebugAgentLib.uni
    1920  FILE_GUID                      = BA6BAD25-B814-4747-B0B0-0FBB61D40B90
    2021  MODULE_TYPE                    = DXE_DRIVER
     
    3334  DxeDebugAgent/DxeDebugAgentLib.c
    3435  DxeDebugAgent/DxeDebugAgentLib.h
     36  DxeDebugAgent/SerialIo.c
    3537  DebugAgentCommon/DebugAgent.c
    3638  DebugAgentCommon/DebugAgent.h
     
    4244[Sources.Ia32]
    4345  DebugAgentCommon/Ia32/AsmFuncs.S     | GCC
    44   DebugAgentCommon/Ia32/AsmFuncs.asm   | MSFT
     46  DebugAgentCommon/Ia32/AsmFuncs.asm
    4547  DebugAgentCommon/Ia32/ArchDebugSupport.h
    4648  DebugAgentCommon/Ia32/ArchDebugSupport.c
    47   DebugAgentCommon/Ia32/ArchReadGroupRegister.c
    48   DebugAgentCommon/Ia32/ArchRegisters.h
    4949  DebugAgentCommon/Ia32/DebugException.h
    5050
    5151[Sources.X64]
    5252  DebugAgentCommon/X64/AsmFuncs.S      | GCC
    53   DebugAgentCommon/X64/AsmFuncs.asm    | MSFT
     53  DebugAgentCommon/X64/AsmFuncs.asm
    5454  DebugAgentCommon/X64/ArchDebugSupport.h
    5555  DebugAgentCommon/X64/ArchDebugSupport.c
    56   DebugAgentCommon/X64/ArchReadGroupRegister.c
    57   DebugAgentCommon/X64/ArchRegisters.h
    5856  DebugAgentCommon/X64/DebugException.h
    5957
     
    7775  MemoryAllocationLib
    7876  LocalApicLib
     77  TimerLib
     78  PrintLib
     79  PeCoffGetEntryPointLib
     80  PeCoffExtraActionLib
     81  MemoryAllocationLib
    7982
    8083[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
    8397
    8498[Pcd]
    85   gEfiMdePkgTokenSpaceGuid.PcdFSBClock                                  ## CONSUMES
    86   gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdExceptionsIgnoredByDebugger  ## CONSUMES
     99  gEfiMdePkgTokenSpaceGuid.PcdFSBClock                                  ## SOMETIMES_CONSUMES
     100  gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdExceptionsIgnoredByDebugger  ## SOMETIMES_CONSUMES
     101  gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugPortHandleBufferSize    ## CONSUMES
    87102
  • trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.c

    r48674 r58459  
    22  SEC Core Debug Agent Library instance implementition.
    33
    4   Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
    55  This program and the accompanying materials
    66  are licensed and made available under the terms and conditions of the BSD License
     
    1515#include "SecPeiDebugAgentLib.h"
    1616
    17 CONST BOOLEAN                MultiProcessorDebugSupport = FALSE;
    18 
    19 /**
    20   Get pointer to Mailbox from IDT entry before memory is ready.
     17GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN  mSkipBreakpoint = FALSE;
     18
     19
     20GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_VECTOR_HANDOFF_INFO_PPI mVectorHandoffInfoPpi = {
     21  &mVectorHandoffInfoDebugAgent[0]
     22};
     23
     24//
     25// Ppis to be installed
     26//
     27GLOBAL_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
     35GLOBAL_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**/
     50BOOLEAN
     51MultiProcessorDebugSupport (
     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**/
     68EFI_STATUS
     69DebugReadBreakSymbol (
     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.
    21120
    22121**/
    23122VOID *
    24 GetMailboxPointerInIdtEntry (
     123GetLocationSavedMailboxPointerInIdtEntry (
    25124  VOID
    26125  )
    27126{
    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;
    37135}
    38136
     
    40138  Set the pointer of Mailbox into IDT entry before memory is ready.
    41139
    42   @param[in]  Mailbox       The pointer of Mailbox.
     140  @param[in]  MailboxLocation    Pointer to location saved Mailbox pointer.
    43141
    44142**/
    45143VOID
    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 (
     144SetLocationSavedMailboxPointerInIdtEntry (
     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**/
     157UINT64 *
     158GetMailboxLocationFromHob (
    69159  VOID
    70160  )
    71161{
    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));
    81169}
    82170
     
    92180  )
    93181{
    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;
    95228}
    96229
     
    107240{
    108241  DEBUG_AGENT_MAILBOX    *DebugAgentMailbox;
    109  
    110   DebugAgentMailbox = (DEBUG_AGENT_MAILBOX *)GetMailboxPointerInIdtEntry ();
     242
     243  DebugAgentMailbox = GetMailboxPointer ();
    111244
    112245  return (DEBUG_PORT_HANDLE) (UINTN)(DebugAgentMailbox->DebugPortHandle);
     
    114247
    115248/**
    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**/
     258EFI_STATUS
     259EFIAPI
     260DebugAgentCallbackMemoryDiscoveredPpi (
     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;
    153325}
    154326
     
    193365{
    194366  DEBUG_AGENT_MAILBOX              *Mailbox;
     367  DEBUG_AGENT_MAILBOX              *NewMailbox;
    195368  DEBUG_AGENT_MAILBOX              MailboxInStack;
    196369  DEBUG_AGENT_PHASE2_CONTEXT       Phase2Context;
    197370  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;
    198378
    199379  DisableInterrupts ();
     
    205385    InitializeDebugIdt ();
    206386
     387    MailboxLocation = (UINT64)(UINTN)&MailboxInStack;
    207388    Mailbox = &MailboxInStack;
    208389    ZeroMem ((VOID *) Mailbox, sizeof (DEBUG_AGENT_MAILBOX));
    209 
    210390    //
    211391    // Get and save debug port handle and set the length of memory block.
    212392    //
    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);
    214402
    215403    InitializeDebugTimer ();
    216404
     405    Phase2Context.InitFlag = InitFlag;
    217406    Phase2Context.Context  = Context;
    218407    Phase2Context.Function = Function;
    219408    DebugPortInitialize ((VOID *) &Phase2Context, InitializeDebugAgentPhase2);
    220 
    221409    //
    222410    // If reaches here, it means Debug Port initialization failed.
     
    227415
    228416  case DEBUG_AGENT_INIT_POSTMEM_SEC:
    229 
     417    Mailbox = GetMailboxPointer ();
    230418    //
    231419    // Memory has been ready
    232420    //
    233     if (IsHostConnected()) {
     421    SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1);
     422    if (IsHostAttached ()) {
    234423      //
    235424      // Trigger one software interrupt to inform HOST
     
    237426      TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);
    238427    }
    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    //
    240439    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);
    252491    break;
    253492
     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
    254592  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
    258595    // Debug Agent library instance.
    259596    //
     
    261598    CpuDeadLoop ();
    262599    break;
    263 
    264   }
     600  }
     601
     602  //
     603  // Enable CPU interrupts so debug timer interrupts can be delivered
     604  //
     605  EnableInterrupts ();
    265606
    266607  //
     
    269610  if (Function != NULL) {
    270611    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;
    271618  }
    272619}
     
    289636{
    290637  DEBUG_AGENT_PHASE2_CONTEXT *Phase2Context;
     638  UINT64                     *MailboxLocation;
    291639  DEBUG_AGENT_MAILBOX        *Mailbox;
    292640  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);
    296654
    297655  //
     
    300658  TriggerSoftInterrupt (SYSTEM_RESET_SIGNATURE);
    301659
    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    //
    321677    Phase2Context->Function (Phase2Context->Context);
    322678  }
  • trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.h

    r48674 r58459  
    22  Header file for Sec Core Debug Agent Library instance.
    33
    4   Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
    55  This program and the accompanying materials
    66  are licensed and made available under the terms and conditions of the BSD License
     
    1717
    1818#include <PiPei.h>
    19 
     19#include <Ppi/MemoryDiscovered.h>
     20#include <Library/PeiServicesLib.h>
     21#include <Library/MemoryAllocationLib.h>
    2022#include "DebugAgent.h"
    2123
    2224typedef struct {
     25  UINT32                  InitFlag;
    2326  VOID                    *Context;
    2427  DEBUG_AGENT_CONTINUE    Function;
    2528} DEBUG_AGENT_PHASE2_CONTEXT;
    2629
     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**/
     39VOID
     40EFIAPI
     41InitializeDebugAgentPhase2 (
     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**/
     56EFI_STATUS
     57EFIAPI
     58DebugAgentCallbackMemoryDiscoveredPpi (
     59  IN EFI_PEI_SERVICES                     **PeiServices,
     60  IN EFI_PEI_NOTIFY_DESCRIPTOR            *NotifyDescriptor,
     61  IN VOID                                 *Ppi
     62  );
     63
    2764#endif
    2865
  • trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf

    r48674 r58459  
    22#  Debug Agent library instance for SEC Core and PEI modules.
    33#
    4 #  Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
     4#  Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
    55#
    66#  This program and the accompanying materials
     
    1717  INF_VERSION                    = 0x00010005
    1818  BASE_NAME                      = SecPeiDebugAgentLib
     19  MODULE_UNI_FILE                = SecPeiDebugAgentLib.uni
    1920  FILE_GUID                      = 508B7D59-CD4E-4a6b-A45B-6D3B2D90111E
    2021  MODULE_TYPE                    = PEIM
     
    4041[Sources.Ia32]
    4142  DebugAgentCommon/Ia32/AsmFuncs.S     | GCC
    42   DebugAgentCommon/Ia32/AsmFuncs.asm   | MSFT
     43  DebugAgentCommon/Ia32/AsmFuncs.asm
    4344  DebugAgentCommon/Ia32/ArchDebugSupport.h
    4445  DebugAgentCommon/Ia32/ArchDebugSupport.c
    45   DebugAgentCommon/Ia32/ArchReadGroupRegister.c
    46   DebugAgentCommon/Ia32/ArchRegisters.h
    4746  DebugAgentCommon/Ia32/DebugException.h
    4847
    4948[Sources.X64]
    5049  DebugAgentCommon/X64/AsmFuncs.S      | GCC
    51   DebugAgentCommon/X64/AsmFuncs.asm    | MSFT
     50  DebugAgentCommon/X64/AsmFuncs.asm
    5251  DebugAgentCommon/X64/ArchDebugSupport.h
    5352  DebugAgentCommon/X64/ArchDebugSupport.c
    54   DebugAgentCommon/X64/ArchReadGroupRegister.c
    55   DebugAgentCommon/X64/ArchRegisters.h
    5653  DebugAgentCommon/X64/DebugException.h
    5754
     
    7370  LocalApicLib
    7471  DebugLib
     72  TimerLib
     73  PrintLib
     74  PeiServicesLib
     75  MemoryAllocationLib
     76  PeCoffGetEntryPointLib
     77  PeCoffExtraActionLib
     78
     79[Ppis]
     80  gEfiPeiMemoryDiscoveredPpiGuid                ## NOTIFY
     81  gEfiVectorHandoffInfoPpiGuid                  ## PRODUCES
    7582
    7683[Guids]
    77   gEfiDebugAgentGuid                            ## PRODUCES ## HOB
     84  ## PRODUCES ## HOB
     85  ## CONSUMES ## HOB
     86  gEfiDebugAgentGuid
    7887
    7988[Pcd]
    80   gEfiMdePkgTokenSpaceGuid.PcdFSBClock                                  ## CONSUMES
    81   gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdExceptionsIgnoredByDebugger  ## CONSUMES
     89  gEfiMdePkgTokenSpaceGuid.PcdFSBClock                                  ## SOMETIMES_CONSUMES
     90  gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdExceptionsIgnoredByDebugger  ## SOMETIMES_CONSUMES
     91  gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugPortHandleBufferSize    ## SOMETIMES_CONSUMES
    8292
  • trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c

    r48674 r58459  
    22  Debug Agent library implementition.
    33
    4   Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
    55  This program and the accompanying materials
    66  are licensed and made available under the terms and conditions of the BSD License
     
    1818DEBUG_AGENT_MAILBOX         mLocalMailbox;
    1919UINTN                       mSavedDebugRegisters[6];
    20 CONST BOOLEAN               MultiProcessorDebugSupport = FALSE;
    21 
     20IA32_IDT_GATE_DESCRIPTOR    mIdtEntryTable[33];
     21BOOLEAN                     mSkipBreakpoint = FALSE;
     22
     23CHAR8 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**/
     32BOOLEAN
     33MultiProcessorDebugSupport (
     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**/
     50EFI_STATUS
     51DebugReadBreakSymbol (
     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**/
     68DEBUG_AGENT_MAILBOX *
     69GetMailboxFromHob (
     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}
    2287
    2388/**
     
    3297  )
    3398{
     99  VerifyMailboxChecksum (mMailboxPointer);
    34100  return mMailboxPointer;
    35101}
     
    46112  )
    47113{
    48   return (DEBUG_PORT_HANDLE) (UINTN)(mMailboxPointer->DebugPortHandle);
     114  return (DEBUG_PORT_HANDLE) (UINTN)(GetMailboxPointer()->DebugPortHandle);
    49115}
    50116
     
    114180  )
    115181{
    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;
    118192
    119193  switch (InitFlag) {
    120194  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));
    126265
    127266    break;
     
    131270    InitializeDebugIdt ();
    132271
    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 {
    141290        //
    142291        // If SMM entry break is set, SMM code will be break at here.
     
    148297
    149298  case DEBUG_AGENT_INIT_EXIT_SMI:
     299    Mailbox = GetMailboxPointer ();
     300    //
     301    // Clear Skip Breakpoint flag
     302    //
     303    mSkipBreakpoint = FALSE;
    150304    RestoreDebugRegister ();
    151305    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;   
    152349  }
    153350}
  • trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.h

    r48674 r58459  
    22  Header file for Smm Debug Agent Library instance.
    33
    4   Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
     4  Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
    55  This program and the accompanying materials
    66  are licensed and made available under the terms and conditions of the BSD License
     
    1919
    2020#include <Library/UefiLib.h>
     21#include <Library/SmmServicesTableLib.h>
    2122
    2223#include "DebugAgent.h"
  • trunk/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf

    r48674 r58459  
    22#  Debug Agent library instance for SMM modules.
    33#
    4 #  Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
     4#  Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
    55#
    66#  This program and the accompanying materials
     
    1616[Defines]
    1717  INF_VERSION                    = 0x00010005
    18   BASE_NAME                      = SecDebugAgentLib
     18  BASE_NAME                      = SmmDebugAgentLib
     19  MODULE_UNI_FILE                = SmmDebugAgentLib.uni
    1920  FILE_GUID                      = CB07D74C-598F-4268-A5D1-644FB4A481E8
    2021  MODULE_TYPE                    = DXE_SMM_DRIVER
     
    4041[Sources.Ia32]
    4142  DebugAgentCommon/Ia32/AsmFuncs.S     | GCC
    42   DebugAgentCommon/Ia32/AsmFuncs.asm   | MSFT
     43  DebugAgentCommon/Ia32/AsmFuncs.asm
    4344  DebugAgentCommon/Ia32/ArchDebugSupport.h
    4445  DebugAgentCommon/Ia32/ArchDebugSupport.c
    45   DebugAgentCommon/Ia32/ArchReadGroupRegister.c
    46   DebugAgentCommon/Ia32/ArchRegisters.h
    4746  DebugAgentCommon/Ia32/DebugException.h
    4847
    4948[Sources.X64]
    5049  DebugAgentCommon/X64/AsmFuncs.S      | GCC
    51   DebugAgentCommon/X64/AsmFuncs.asm    | MSFT
     50  DebugAgentCommon/X64/AsmFuncs.asm
    5251  DebugAgentCommon/X64/ArchDebugSupport.h
    5352  DebugAgentCommon/X64/ArchDebugSupport.c
    54   DebugAgentCommon/X64/ArchReadGroupRegister.c
    55   DebugAgentCommon/X64/ArchRegisters.h
    5653  DebugAgentCommon/X64/DebugException.h
    5754
     
    7269  SynchronizationLib
    7370  LocalApicLib
     71  TimerLib
     72  PrintLib
     73  PeCoffExtraActionLib
     74  PeCoffGetEntryPointLib
     75  SmmServicesTableLib
    7476
    7577[Guids]
    76   gEfiDebugAgentGuid                            ## CONSUMES ## Configuration Table
     78  ## CONSUMES ## SystemTable
     79  ## CONSUMES ## HOB
     80  gEfiDebugAgentGuid
     81  gEfiVectorHandoffTableGuid            ## PRODUCES ## GUID # SMM Configuration Table
    7782
    7883[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
    8187
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette