mirror of https://github.com/acidanthera/audk.git
This revision can only work with Intel(c) UDK Debugger Tool version 1.3 or greater. Detailed change log is as below:
1. Add DebugAgentPei driver to initialize Debug Agent in PEI phase. Add DebugAgentDxe driver to initialize Debug Agent in DXE phase. DebugAgentDxe driver could be loaded and unloaded in shell. 2. Update the SourceLevelDebugPkg so that the debug agent can be initialized in any phase: SEC, PEI or DXE. 3. Add an enhanced retry algorithm that provides a robust connection when data loss happens in the debug channel. 4. Clear DR7 register in exception handler. 5. Set the default serial port parameter to 0 instead of PCDs. 6. Build pointer of Mailbox in HOB instead of Mailbox itself, since HOB may be moved at DXE entry point function. 7. Raise TPL to prevent recursion from EFI timer interrupts in SerialIo.c. 8. Add one spin lock for accessing Mailbox when MP debugging supported. 9. Use more non-NULL library instances in SourceLevelDebugPkg DSC file, thus DebugAgentDxe.efi built from SourceLevelDebugPkg could work in shell. 10.Separate all operations about IDT table entry from SecDebugAgentLib.c into DebugAgent\DebugAgentCommon's arch sub-directory. 11.Enhance Debug Agent to avoid breaking by hardware SMI during DXE debugging phase. 12.Add supporting on mode switch code debugging. 13.Remove reset Host Controller operation in DebugCommunicationLibUsb.c to avoid impacting EDKII usb stack. 14.Fix debug timer interrupt missing issue after back from legacy code. Signed-off-by: Jeff Fan <jeff.fan@intel.com> Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com> Signed-off-by: Feng Tian <feng.tian@intel.com> Reviewed-by: Jeff Fan <jeff.fan@intel.com> Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com> Reviewed-by: Feng Tian <feng.tian@intel.com> git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14083 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
b7d269eae1
commit
b422b62c01
|
@ -0,0 +1,101 @@
|
|||
/** @file
|
||||
Initialize Debug Agent in DXE by invoking Debug Agent Library.
|
||||
|
||||
Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <PiDxe.h>
|
||||
#include <Guid/EventGroup.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/DebugAgentLib.h>
|
||||
|
||||
EFI_EVENT mExitBootServiceEvent;
|
||||
|
||||
/**
|
||||
One notified function to disable Debug Timer interrupt when gBS->ExitBootServices() called.
|
||||
|
||||
@param[in] Event Pointer to this event
|
||||
@param[in] Context Event hanlder private data
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
DisableDebugTimerExitBootService (
|
||||
EFI_EVENT Event,
|
||||
VOID *Context
|
||||
)
|
||||
|
||||
{
|
||||
SaveAndSetDebugTimerInterrupt (FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
The Entry Point for Debug Agent Dxe driver.
|
||||
|
||||
It will invoke Debug Agent Library to enable source debugging feature in DXE phase.
|
||||
|
||||
@param[in] ImageHandle The firmware allocated handle for the EFI image.
|
||||
@param[in] SystemTable A pointer to the EFI System Table.
|
||||
|
||||
@retval EFI_SUCCESS The entry point is executed successfully.
|
||||
@retval other Some error occurs when initialzed Debug Agent.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DebugAgentDxeInitialize(
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
InitializeDebugAgent (DEBUG_AGENT_INIT_DXE_LOAD, &Status, NULL);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// Create event to disable Debug Timer interrupt when exit boot service.
|
||||
//
|
||||
Status = gBS->CreateEventEx (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_NOTIFY,
|
||||
DisableDebugTimerExitBootService,
|
||||
NULL,
|
||||
&gEfiEventExitBootServicesGuid,
|
||||
&mExitBootServiceEvent
|
||||
);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
This is the unload handle for Debug Agent Dxe driver.
|
||||
|
||||
It will invoke Debug Agent Library to disable source debugging feature.
|
||||
|
||||
@param[in] ImageHandle The drivers' driver image.
|
||||
|
||||
@retval EFI_SUCCESS The image is unloaded.
|
||||
@retval Others Failed to unload the image.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DebugAgentDxeUnload (
|
||||
IN EFI_HANDLE ImageHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
InitializeDebugAgent (DEBUG_AGENT_INIT_DXE_UNLOAD, &Status, NULL);
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
## @file
|
||||
# Initialized Debug Agent in one separated DXE driver.
|
||||
#
|
||||
# This DXE driver will invoke Debug Agent Library to initialize the debug agent.
|
||||
#
|
||||
# Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = DebugAgentDxe
|
||||
FILE_GUID = 9727502C-034E-472b-8E1B-67BB28C6CFDB
|
||||
MODULE_TYPE = DXE_DRIVER
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = DebugAgentDxeInitialize
|
||||
UNLOAD_IMAGE = DebugAgentDxeUnload
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
DebugAgentDxe.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
UefiDriverEntryPoint
|
||||
UefiBootServicesTableLib
|
||||
DebugAgentLib
|
||||
|
||||
[Guids]
|
||||
gEfiEventExitBootServicesGuid ## SOMETIMES_CONSUMES ## Event
|
||||
|
||||
[Depex]
|
||||
TRUE
|
|
@ -0,0 +1,45 @@
|
|||
/** @file
|
||||
Initialize Debug Agent in PEI by invoking Debug Agent Library.
|
||||
|
||||
Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <PiPei.h>
|
||||
|
||||
#include <Library/DebugAgentLib.h>
|
||||
|
||||
/**
|
||||
The Entry Point for Debug Agent PEI driver.
|
||||
|
||||
It will invoke Debug Agent Library to enable source debugging feature in PEI phase.
|
||||
|
||||
This function is the Entry point of the CPU I/O PEIM which installs CpuIoPpi.
|
||||
|
||||
@param[in] FileHandle Pointer to image file handle.
|
||||
@param[in] PeiServices Pointer to PEI Services Table
|
||||
|
||||
@retval EFI_SUCCESS Debug Agent successfully initialized.
|
||||
@retval other Some error occurs when initialzed Debug Agent.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DebugAgentPeiInitialize (
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
InitializeDebugAgent (DEBUG_AGENT_INIT_PEI, &Status, NULL);
|
||||
|
||||
return Status;
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
## @file
|
||||
# Initialized Debug Agent in PEI phase.
|
||||
#
|
||||
# This PEIM will invoke Debug Agent Library to initialize the debug agent in
|
||||
# whole PEI phase.
|
||||
#
|
||||
# Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = DebugAgentPei
|
||||
FILE_GUID = D9D114EF-F40B-4d48-AAA0-A3DC99C9F5BD
|
||||
MODULE_TYPE = PEIM
|
||||
VERSION_STRING = 1.0
|
||||
ENTRY_POINT = DebugAgentPeiInitialize
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
DebugAgentPei.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
PeimEntryPoint
|
||||
DebugAgentLib
|
||||
|
||||
[Depex]
|
||||
TRUE
|
|
@ -2,7 +2,7 @@
|
|||
Public include file for Debug Agent Library instance and PE/COFF Extra
|
||||
Action Library instance.
|
||||
|
||||
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -19,6 +19,7 @@
|
|||
#define IO_PORT_BREAKPOINT_ADDRESS 0x84
|
||||
#define IMAGE_LOAD_SIGNATURE SIGNATURE_32('L','O','A','D')
|
||||
#define IMAGE_UNLOAD_SIGNATURE SIGNATURE_32('U','N','L','O')
|
||||
#define AGENT_HANDLER_SIGNATURE SIGNATURE_32('A','G','T','H')
|
||||
|
||||
#define DEBUG_AGENT_IMAGE_WAIT 0x00
|
||||
#define DEBUG_AGENT_IMAGE_CONTINUE 0x01
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
Transfer protocol defintions used by debug agent and host. It is only
|
||||
intended to be used by Debug related module implementation.
|
||||
|
||||
Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -21,25 +21,19 @@
|
|||
//
|
||||
// Current revision of transfer protocol
|
||||
//
|
||||
#define DEBUG_AGENT_REVISION ((0 << 16) | 02)
|
||||
#define DEBUG_AGENT_REVISION ((0 << 16) | 03)
|
||||
#define DEBUG_AGENT_CAPABILITIES 0
|
||||
|
||||
//
|
||||
// Definitions for break command.
|
||||
//
|
||||
#define DEBUG_STARTING_SYMBOL_BREAK (0xFC)
|
||||
|
||||
//
|
||||
// Definitions for attach command
|
||||
//
|
||||
#define DEBUG_STARTING_SYMBOL_ATTACH (0xFA)
|
||||
#define DEBUG_STARTING_SYMBOL_ATTACH (0xFA)
|
||||
|
||||
//
|
||||
// Definition for starting symbol of a normal debug packet. Choose a non-ASCII to avoid conflict with other serial output.
|
||||
//
|
||||
#define DEBUG_STARTING_SYMBOL_NORMAL (0xFE)
|
||||
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
//
|
||||
|
@ -49,7 +43,8 @@ typedef struct {
|
|||
UINT8 StartSymbol;
|
||||
UINT8 Command;
|
||||
UINT8 Length; // Length of Debug Packet including header and payload in byte
|
||||
UINT8 CheckSum;
|
||||
UINT8 SequenceNo;
|
||||
UINT16 Crc;
|
||||
} DEBUG_PACKET_HEADER;
|
||||
|
||||
//
|
||||
|
@ -86,6 +81,7 @@ typedef struct {
|
|||
#define DEBUG_COMMAND_DETACH (DEBUG_COMMAND_REQUEST | 0x16)
|
||||
#define DEBUG_COMMAND_CPUID (DEBUG_COMMAND_REQUEST | 0x17)
|
||||
#define DEBUG_COMMAND_SEARCH_SIGNATURE (DEBUG_COMMAND_REQUEST | 0x18)
|
||||
#define DEBUG_COMMAND_HALT (DEBUG_COMMAND_REQUEST | 0x19)
|
||||
|
||||
//
|
||||
// TARGET initiated commands
|
||||
|
@ -94,6 +90,7 @@ typedef struct {
|
|||
#define DEBUG_COMMAND_BREAK_POINT (DEBUG_COMMAND_REQUEST | 0x3E)
|
||||
#define DEBUG_COMMAND_MEMORY_READY (DEBUG_COMMAND_REQUEST | 0x3D)
|
||||
#define DEBUG_COMMAND_PRINT_MESSAGE (DEBUG_COMMAND_REQUEST | 0x3C)
|
||||
#define DEBUG_COMMAND_ATTACH_BREAK (DEBUG_COMMAND_REQUEST | 0x3B)
|
||||
|
||||
//
|
||||
// Response commands
|
||||
|
@ -308,8 +305,9 @@ typedef struct {
|
|||
//
|
||||
// Supported keys
|
||||
//
|
||||
#define DEBUG_AGENT_SETTING_SMM_ENTRY_BREAK 1
|
||||
#define DEBUG_AGENT_SETTING_PRINT_ERROR_LEVEL 2
|
||||
#define DEBUG_AGENT_SETTING_SMM_ENTRY_BREAK 1
|
||||
#define DEBUG_AGENT_SETTING_PRINT_ERROR_LEVEL 2
|
||||
#define DEBUG_AGENT_SETTING_BOOT_SCRIPT_ENTRY_BREAK 3
|
||||
//
|
||||
// Bitmask of print error level for debug message
|
||||
//
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Command header of for Debug Agent library instance.
|
||||
|
||||
Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -32,6 +32,8 @@
|
|||
#include <Library/DebugLib.h>
|
||||
#include <Library/TimerLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
#include <Library/PeCoffGetEntryPointLib.h>
|
||||
#include <Library/PeCoffExtraActionLib.h>
|
||||
|
||||
#include <TransferProtocol.h>
|
||||
#include <ImageDebugSupport.h>
|
||||
|
@ -40,11 +42,24 @@
|
|||
#include "DebugTimer.h"
|
||||
#include "ArchDebugSupport.h"
|
||||
|
||||
//
|
||||
// These macros may be already defined in DebugAgentLib.h
|
||||
//
|
||||
#define DEBUG_AGENT_INIT_PEI 9
|
||||
#define DEBUG_AGENT_INIT_DXE_LOAD 10
|
||||
#define DEBUG_AGENT_INIT_DXE_UNLOAD 11
|
||||
#define DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64 12
|
||||
|
||||
#define DEBUG_INT1_VECTOR 1
|
||||
#define DEBUG_INT3_VECTOR 3
|
||||
#define DEBUG_TIMER_VECTOR 32
|
||||
#define DEBUG_MAILBOX_VECTOR 33
|
||||
|
||||
//
|
||||
// Timeout value for reading packet (unit is microsecond)
|
||||
//
|
||||
#define READ_PACKET_TIMEOUT (500 * 1000)
|
||||
|
||||
#define SOFT_INTERRUPT_SIGNATURE SIGNATURE_32('S','O','F','T')
|
||||
#define SYSTEM_RESET_SIGNATURE SIGNATURE_32('S','Y','S','R')
|
||||
#define MEMORY_READY_SIGNATURE SIGNATURE_32('M','E','M','R')
|
||||
|
@ -53,6 +68,8 @@ extern UINTN Exception0Handle;
|
|||
extern UINTN TimerInterruptHandle;
|
||||
extern UINT16 ExceptionStubHeaderSize;
|
||||
|
||||
extern BOOLEAN mSkipBreakpoint;
|
||||
|
||||
//
|
||||
// CPU exception information issued by debug agent
|
||||
//
|
||||
|
@ -67,23 +84,44 @@ typedef struct {
|
|||
DEBUG_DATA_RESPONSE_GET_EXCEPTION ExceptionContent;
|
||||
} DEBUG_AGENT_EXCEPTION_BUFFER;
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
//
|
||||
// Lower 32 bits to store the status of DebugAgent
|
||||
//
|
||||
UINT32 HostAttached : 1; // 1: HOST is attached
|
||||
UINT32 AgentInProgress : 1; // 1: Debug Agent is communicating with HOST
|
||||
UINT32 MemoryReady : 1; // 1: Memory is ready
|
||||
UINT32 SteppingFlag : 1; // 1: Agent is running stepping command
|
||||
UINT32 Reserved1 : 28;
|
||||
#define DEBUG_AGENT_FLAG_HOST_ATTACHED BIT0
|
||||
#define DEBUG_AGENT_FLAG_AGENT_IN_PROGRESS BIT1
|
||||
#define DEBUG_AGENT_FLAG_MEMORY_READY BIT2
|
||||
#define DEBUG_AGENT_FLAG_STEPPING BIT3
|
||||
#define DEBUG_AGENT_FLAG_CHECK_MAILBOX_IN_HOB BIT4
|
||||
#define DEBUG_AGENT_FLAG_BREAK_ON_NEXT_SMI BIT32
|
||||
#define DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL (BIT33|BIT34|BIT35|BIT36)
|
||||
#define DEBUG_AGENT_FLAG_BREAK_BOOT_SCRIPT BIT37
|
||||
|
||||
//
|
||||
// Higher 32bits to control the behavior of DebugAgent
|
||||
//
|
||||
UINT32 BreakOnNextSmi : 1; // 1: Break on next SMI
|
||||
UINT32 PrintErrorLevel : 8; // Bitmask of print error level for debug message
|
||||
UINT32 Reserved2 : 23;
|
||||
#define DEBUG_MAILBOX_DEBUG_FLAG_INDEX 1
|
||||
#define DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX 2
|
||||
#define DEBUG_MAILBOX_EXCEPTION_BUFFER_POINTER_INDEX 3
|
||||
#define DEBUG_MAILBOX_LAST_ACK 4
|
||||
#define DEBUG_MAILBOX_SEQUENCE_NO_INDEX 5
|
||||
#define DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX 6
|
||||
|
||||
#pragma pack(1)
|
||||
typedef union {
|
||||
struct {
|
||||
//
|
||||
// Lower 32 bits to store the status of DebugAgent
|
||||
//
|
||||
UINT32 HostAttached : 1; // 1: HOST is attached
|
||||
UINT32 AgentInProgress : 1; // 1: Debug Agent is communicating with HOST
|
||||
UINT32 MemoryReady : 1; // 1: Memory is ready
|
||||
UINT32 SteppingFlag : 1; // 1: Agent is running stepping command
|
||||
UINT32 CheckMailboxInHob : 1; // 1: Need to check mailbox saved in HOB
|
||||
UINT32 SendingPacket : 1; // 1: TARGET is sending debug packet to HOST
|
||||
UINT32 Reserved1 : 26;
|
||||
//
|
||||
// Higher 32bits to control the behavior of DebugAgent
|
||||
//
|
||||
UINT32 BreakOnNextSmi : 1; // 1: Break on next SMI
|
||||
UINT32 PrintErrorLevel : 4; // Bitmask of print error level for debug message
|
||||
UINT32 BreakOnBootScript : 1; // 1: Break before executing boot script
|
||||
UINT32 Reserved2 : 26;
|
||||
} Bits;
|
||||
UINT64 Uint64;
|
||||
} DEBUG_AGENT_FLAG;
|
||||
|
||||
typedef struct {
|
||||
|
@ -93,9 +131,29 @@ typedef struct {
|
|||
// Pointer to DEBUG_AGENT_EXCEPTION_BUFFER
|
||||
//
|
||||
UINT64 ExceptionBufferPointer;
|
||||
UINT8 LastAck; // The last ack packet type
|
||||
UINT8 SequenceNo;
|
||||
UINT8 HostSequenceNo;
|
||||
UINT8 CheckSum; // Mailbox checksum
|
||||
UINT8 ToBeCheckSum; // To be Mailbox checksum at the next
|
||||
} DEBUG_AGENT_MAILBOX;
|
||||
#pragma pack()
|
||||
|
||||
///
|
||||
/// Byte packed structure for an IA-32 Interrupt Gate Descriptor.
|
||||
///
|
||||
typedef union {
|
||||
struct {
|
||||
UINT32 OffsetLow:16; ///< Offset bits 15..0.
|
||||
UINT32 Selector:16; ///< Selector.
|
||||
UINT32 Reserved_0:8; ///< Reserved.
|
||||
UINT32 GateType:8; ///< Gate Type. See #defines above.
|
||||
UINT32 OffsetHigh:16; ///< Offset bits 31..16.
|
||||
} Bits;
|
||||
UINT64 Uint64;
|
||||
} IA32_IDT_ENTRY;
|
||||
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
UINT32 LimitLow : 16;
|
||||
|
@ -115,22 +173,6 @@ typedef union {
|
|||
UINT64 Uint64;
|
||||
} IA32_GDT;
|
||||
|
||||
/**
|
||||
Caller provided function to be invoked at the end of DebugPortInitialize().
|
||||
|
||||
Refer to the descrption for DebugPortInitialize() for more details.
|
||||
|
||||
@param[in] Context The first input argument of DebugPortInitialize().
|
||||
@param[in] DebugPortHandle Debug port handle created by Debug Communication Libary.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
InitializeDebugAgentPhase2 (
|
||||
IN VOID *Context,
|
||||
IN DEBUG_PORT_HANDLE DebugPortHandle
|
||||
);
|
||||
|
||||
/**
|
||||
Initialize IDT entries to support source level debug.
|
||||
|
||||
|
@ -242,5 +284,184 @@ DebugAgentMsgPrint (
|
|||
IN CHAR8 *Format,
|
||||
...
|
||||
);
|
||||
|
||||
/**
|
||||
Trigger one software interrupt to debug agent to handle it.
|
||||
|
||||
@param[in] Signature Software interrupt signature.
|
||||
|
||||
**/
|
||||
VOID
|
||||
TriggerSoftInterrupt (
|
||||
IN UINT32 Signature
|
||||
);
|
||||
|
||||
/**
|
||||
Check if debug agent support multi-processor.
|
||||
|
||||
@retval TRUE Multi-processor is supported.
|
||||
@retval FALSE Multi-processor is not supported.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
MultiProcessorDebugSupport (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Find and report module image info to HOST.
|
||||
|
||||
@param[in] AlignSize Image aligned size.
|
||||
|
||||
**/
|
||||
VOID
|
||||
FindAndReportModuleImageInfo (
|
||||
IN UINTN AlignSize
|
||||
);
|
||||
|
||||
/**
|
||||
Read IDT entry to check if IDT entries are setup by Debug Agent.
|
||||
|
||||
@retval TRUE IDT entries were setup by Debug Agent.
|
||||
@retval FALSE IDT entries were not setup by Debug Agent.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
IsDebugAgentInitialzed (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Caculate Mailbox checksum and update the checksum field.
|
||||
|
||||
@param[in] Mailbox Debug Agent Mailbox pointer.
|
||||
|
||||
**/
|
||||
VOID
|
||||
UpdateMailboxChecksum (
|
||||
IN DEBUG_AGENT_MAILBOX *Mailbox
|
||||
);
|
||||
|
||||
/**
|
||||
Verify Mailbox checksum.
|
||||
|
||||
If checksum error, print debug message and run init dead loop.
|
||||
|
||||
@param[in] Mailbox Debug Agent Mailbox pointer.
|
||||
|
||||
**/
|
||||
VOID
|
||||
VerifyMailboxChecksum (
|
||||
IN DEBUG_AGENT_MAILBOX *Mailbox
|
||||
);
|
||||
|
||||
/**
|
||||
Set debug flag in mailbox.
|
||||
|
||||
@param[in] FlagMask Debug flag mask value.
|
||||
@param[in] FlagValue Debug flag value.
|
||||
|
||||
**/
|
||||
VOID
|
||||
SetDebugFlag (
|
||||
IN UINT64 FlagMask,
|
||||
IN UINT32 FlagValue
|
||||
);
|
||||
|
||||
/**
|
||||
Get debug flag in mailbox.
|
||||
|
||||
@param[in] FlagMask Debug flag mask value.
|
||||
|
||||
@return Debug flag value.
|
||||
|
||||
**/
|
||||
UINT32
|
||||
GetDebugFlag (
|
||||
IN UINT64 FlagMask
|
||||
);
|
||||
|
||||
/**
|
||||
Update Mailbox content by index.
|
||||
|
||||
@param[in] Mailbox Debug Agent Mailbox pointer.
|
||||
@param[in] Index Mailbox content index.
|
||||
@param[in] Value Value to be set into mail box.
|
||||
|
||||
**/
|
||||
VOID
|
||||
UpdateMailboxContent (
|
||||
IN DEBUG_AGENT_MAILBOX *Mailbox,
|
||||
IN UINTN Index,
|
||||
IN UINT64 Value
|
||||
);
|
||||
|
||||
/**
|
||||
Retrieve exception handler from IDT table by ExceptionNum.
|
||||
|
||||
@param[in] ExceptionNum Exception number
|
||||
|
||||
@return Exception handler
|
||||
|
||||
**/
|
||||
VOID *
|
||||
GetExceptionHandlerInIdtEntry (
|
||||
IN UINTN ExceptionNum
|
||||
);
|
||||
|
||||
/**
|
||||
Set exception handler in IDT table by ExceptionNum.
|
||||
|
||||
@param[in] ExceptionNum Exception number
|
||||
@param[in] ExceptionHandler Exception Handler to be set
|
||||
|
||||
**/
|
||||
VOID
|
||||
SetExceptionHandlerInIdtEntry (
|
||||
IN UINTN ExceptionNum,
|
||||
IN VOID *ExceptionHandler
|
||||
);
|
||||
|
||||
/**
|
||||
Prints a debug message to the debug output device if the specified error level is enabled.
|
||||
|
||||
If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function
|
||||
GetDebugPrintErrorLevel (), then print the message specified by Format and the
|
||||
associated variable argument list to the debug output device.
|
||||
|
||||
If Format is NULL, then ASSERT().
|
||||
|
||||
@param[in] ErrorLevel The error level of the debug message.
|
||||
@param[in] IsSend Flag of debug message to declare that the data is being sent or being received.
|
||||
@param[in] Data Variable argument list whose contents are accessed
|
||||
@param[in] Length based on the format string specified by Format.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
DebugAgentDataMsgPrint (
|
||||
IN UINT8 ErrorLevel,
|
||||
IN BOOLEAN IsSend,
|
||||
IN UINT8 *Data,
|
||||
IN UINT8 Length
|
||||
);
|
||||
|
||||
/**
|
||||
Read remaing debug packet except for the start symbol
|
||||
|
||||
@param[in] Handle Pointer to Debug Port handle.
|
||||
@param[in, out] DebugHeader Debug header buffer including start symbol.
|
||||
|
||||
@retval EFI_SUCCESS Read the symbol in BreakSymbol.
|
||||
@retval EFI_CRC_ERROR CRC check fail.
|
||||
@retval EFI_TIMEOUT Timeout occurs when reading debug packet.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
ReadRemainingBreakPacket (
|
||||
IN DEBUG_PORT_HANDLE Handle,
|
||||
IN OUT DEBUG_PACKET_HEADER *DebugHeader
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Multi-Processor support functions implementation.
|
||||
|
||||
Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -14,27 +14,30 @@
|
|||
|
||||
#include "DebugAgent.h"
|
||||
|
||||
DEBUG_MP_CONTEXT volatile mDebugMpContext = {0,0,{0},{0},0,0,0,0,FALSE,FALSE};
|
||||
DEBUG_MP_CONTEXT volatile mDebugMpContext = {0,0,0,{0},{0},0,0,0,0,FALSE,FALSE};
|
||||
|
||||
DEBUG_CPU_DATA volatile mDebugCpuData = {0};
|
||||
|
||||
/**
|
||||
Acquire access control on debug port.
|
||||
Acquire a spin lock when Multi-processor supported.
|
||||
|
||||
It will block in the function if cannot get the access control.
|
||||
If Multi-processor is not supported, return directly.
|
||||
|
||||
@param[in, out] MpSpinLock A pointer to the spin lock.
|
||||
|
||||
**/
|
||||
VOID
|
||||
AcquireDebugPortControl (
|
||||
VOID
|
||||
AcquireMpSpinLock (
|
||||
IN OUT SPIN_LOCK *MpSpinLock
|
||||
)
|
||||
{
|
||||
if (!MultiProcessorDebugSupport) {
|
||||
if (!MultiProcessorDebugSupport()) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (TRUE) {
|
||||
if (AcquireSpinLockOrFail (&mDebugMpContext.DebugPortSpinLock)) {
|
||||
if (AcquireSpinLockOrFail (MpSpinLock)) {
|
||||
break;
|
||||
}
|
||||
CpuPause ();
|
||||
|
@ -43,51 +46,21 @@ AcquireDebugPortControl (
|
|||
}
|
||||
|
||||
/**
|
||||
Release access control on debug port.
|
||||
Release a spin lock when Multi-processor supported.
|
||||
|
||||
@param[in, out] MpSpinLock A pointer to the spin lock.
|
||||
|
||||
**/
|
||||
VOID
|
||||
ReleaseDebugPortControl (
|
||||
VOID
|
||||
ReleaseMpSpinLock (
|
||||
IN OUT SPIN_LOCK *MpSpinLock
|
||||
)
|
||||
{
|
||||
if (!MultiProcessorDebugSupport) {
|
||||
if (!MultiProcessorDebugSupport()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ReleaseSpinLock (&mDebugMpContext.DebugPortSpinLock);
|
||||
}
|
||||
|
||||
/**
|
||||
Acquire access control on MP context.
|
||||
|
||||
It will block in the function if cannot get the access control.
|
||||
|
||||
**/
|
||||
VOID
|
||||
AcquireMpContextControl (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
while (TRUE) {
|
||||
if (AcquireSpinLockOrFail (&mDebugMpContext.MpContextSpinLock)) {
|
||||
break;
|
||||
}
|
||||
CpuPause ();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Release access control on MP context.
|
||||
|
||||
**/
|
||||
VOID
|
||||
ReleaseMpContextControl (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
ReleaseSpinLock (&mDebugMpContext.MpContextSpinLock);
|
||||
ReleaseSpinLock (MpSpinLock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -136,7 +109,7 @@ GetProcessorIndex (
|
|||
|
||||
LocalApicID = (UINT16) GetApicId ();
|
||||
|
||||
AcquireMpContextControl ();
|
||||
AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);
|
||||
|
||||
for (Index = 0; Index < mDebugCpuData.CpuCount; Index ++) {
|
||||
if (mDebugCpuData.ApicID[Index] == LocalApicID) {
|
||||
|
@ -149,7 +122,7 @@ GetProcessorIndex (
|
|||
mDebugCpuData.CpuCount ++ ;
|
||||
}
|
||||
|
||||
ReleaseMpContextControl ();
|
||||
ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock);
|
||||
|
||||
return Index;
|
||||
}
|
||||
|
@ -170,9 +143,9 @@ IsBsp (
|
|||
{
|
||||
if (AsmMsrBitFieldRead64 (MSR_IA32_APIC_BASE_ADDRESS, 8, 8) == 1) {
|
||||
if (mDebugMpContext.BspIndex != ProcessorIndex) {
|
||||
AcquireMpContextControl ();
|
||||
AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);
|
||||
mDebugMpContext.BspIndex = ProcessorIndex;
|
||||
ReleaseMpContextControl ();
|
||||
ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock);
|
||||
}
|
||||
return TRUE;
|
||||
} else {
|
||||
|
@ -197,7 +170,7 @@ SetCpuStopFlagByIndex (
|
|||
UINT8 Value;
|
||||
UINTN Index;
|
||||
|
||||
AcquireMpContextControl ();
|
||||
AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);
|
||||
|
||||
Value = mDebugMpContext.CpuStopStatusMask[ProcessorIndex / 8];
|
||||
Index = ProcessorIndex % 8;
|
||||
|
@ -208,7 +181,7 @@ SetCpuStopFlagByIndex (
|
|||
}
|
||||
mDebugMpContext.CpuStopStatusMask[ProcessorIndex / 8] = Value;
|
||||
|
||||
ReleaseMpContextControl ();
|
||||
ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -228,7 +201,7 @@ SetCpuBreakFlagByIndex (
|
|||
UINT8 Value;
|
||||
UINTN Index;
|
||||
|
||||
AcquireMpContextControl ();
|
||||
AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);
|
||||
|
||||
Value = mDebugMpContext.CpuBreakMask[ProcessorIndex / 8];
|
||||
Index = ProcessorIndex % 8;
|
||||
|
@ -239,7 +212,7 @@ SetCpuBreakFlagByIndex (
|
|||
}
|
||||
mDebugMpContext.CpuBreakMask[ProcessorIndex / 8] = Value;
|
||||
|
||||
ReleaseMpContextControl ();
|
||||
ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -279,11 +252,9 @@ SetCpuRunningFlag (
|
|||
IN BOOLEAN RunningFlag
|
||||
)
|
||||
{
|
||||
AcquireMpContextControl ();
|
||||
|
||||
AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);
|
||||
mDebugMpContext.RunCommandSet = RunningFlag;
|
||||
|
||||
ReleaseMpContextControl ();
|
||||
ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -297,11 +268,9 @@ SetDebugViewPoint (
|
|||
IN UINT32 ProcessorIndex
|
||||
)
|
||||
{
|
||||
AcquireMpContextControl ();
|
||||
|
||||
AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);
|
||||
mDebugMpContext.ViewPointIndex = ProcessorIndex;
|
||||
|
||||
ReleaseMpContextControl ();
|
||||
ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -316,11 +285,9 @@ SetIpiSentByApFlag (
|
|||
IN BOOLEAN IpiSentByApFlag
|
||||
)
|
||||
{
|
||||
AcquireMpContextControl ();
|
||||
|
||||
AcquireMpSpinLock (&mDebugMpContext.MpContextSpinLock);
|
||||
mDebugMpContext.IpiSentByAp = IpiSentByApFlag;
|
||||
|
||||
ReleaseMpContextControl ();
|
||||
ReleaseMpSpinLock (&mDebugMpContext.MpContextSpinLock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -384,7 +351,7 @@ IsFirstBreakProcessor (
|
|||
IN UINT32 ProcessorIndex
|
||||
)
|
||||
{
|
||||
if (MultiProcessorDebugSupport) {
|
||||
if (MultiProcessorDebugSupport()) {
|
||||
if (mDebugMpContext.BreakAtCpuIndex != (UINT32) -1) {
|
||||
//
|
||||
// The current processor is not the first breaking one.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Header file for Multi-Processor support.
|
||||
|
||||
Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -25,6 +25,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
SPIN_LOCK MpContextSpinLock; ///< Lock for writting MP context
|
||||
SPIN_LOCK DebugPortSpinLock; ///< Lock for access debug port
|
||||
SPIN_LOCK MailboxSpinLock; ///< Lock for accessing mail box
|
||||
UINT8 CpuBreakMask[DEBUG_CPU_MAX_COUNT/8]; ///< Bitmask of all breaking CPUs
|
||||
UINT8 CpuStopStatusMask[DEBUG_CPU_MAX_COUNT/8]; ///< Bitmask of CPU stop status
|
||||
UINT32 ViewPointIndex; ///< Current view point to be debugged
|
||||
|
@ -35,7 +36,6 @@ typedef struct {
|
|||
BOOLEAN RunCommandSet; ///< TRUE: RUN commmand is executing. FALSE : RUN command has been executed.
|
||||
} DEBUG_MP_CONTEXT;
|
||||
|
||||
extern CONST BOOLEAN MultiProcessorDebugSupport;
|
||||
extern DEBUG_MP_CONTEXT volatile mDebugMpContext;
|
||||
extern DEBUG_CPU_DATA volatile mDebugCpuData;
|
||||
|
||||
|
@ -62,43 +62,28 @@ GetProcessorIndex (
|
|||
);
|
||||
|
||||
/**
|
||||
Acquire access control on MP context.
|
||||
Acquire a spin lock when Multi-processor supported.
|
||||
|
||||
It will block in the function if cannot get the access control.
|
||||
If Multi-processor is not supported, return directly.
|
||||
|
||||
@param[in, out] MpSpinLock A pointer to the spin lock.
|
||||
|
||||
**/
|
||||
VOID
|
||||
AcquireMpContextControl (
|
||||
VOID
|
||||
AcquireMpSpinLock (
|
||||
IN OUT SPIN_LOCK *MpSpinLock
|
||||
);
|
||||
|
||||
/**
|
||||
Release access control on MP context.
|
||||
Release a spin lock when Multi-processor supported.
|
||||
|
||||
@param[in, out] MpSpinLock A pointer to the spin lock.
|
||||
|
||||
**/
|
||||
VOID
|
||||
ReleaseMpContextControl (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Acquire access control on debug port.
|
||||
|
||||
It will block in the function if cannot get the access control.
|
||||
|
||||
**/
|
||||
VOID
|
||||
AcquireDebugPortControl (
|
||||
VOID
|
||||
);
|
||||
|
||||
/**
|
||||
Release access control on debug port.
|
||||
|
||||
**/
|
||||
VOID
|
||||
ReleaseDebugPortControl (
|
||||
VOID
|
||||
ReleaseMpSpinLock (
|
||||
IN OUT SPIN_LOCK *MpSpinLock
|
||||
);
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Code for debug timer to support debug agent library implementation.
|
||||
|
||||
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -41,7 +41,7 @@ InitializeDebugTimer (
|
|||
|
||||
InitializeApicTimer (ApicTimerDivisor, InitialCount, TRUE, DEBUG_TIMER_VECTOR);
|
||||
|
||||
if (MultiProcessorDebugSupport) {
|
||||
if (MultiProcessorDebugSupport()) {
|
||||
mDebugMpContext.DebugTimerInitCount = InitialCount;
|
||||
}
|
||||
}
|
||||
|
@ -65,19 +65,26 @@ SaveAndSetDebugTimerInterrupt (
|
|||
IN BOOLEAN EnableStatus
|
||||
)
|
||||
{
|
||||
BOOLEAN OldInterruptState;
|
||||
BOOLEAN OldDebugTimerInterruptState;
|
||||
|
||||
OldInterruptState = SaveAndDisableInterrupts ();
|
||||
OldDebugTimerInterruptState = GetApicTimerInterruptState ();
|
||||
|
||||
if (EnableStatus) {
|
||||
EnableApicTimerInterrupt ();
|
||||
} else {
|
||||
DisableApicTimerInterrupt ();
|
||||
if (OldDebugTimerInterruptState != EnableStatus) {
|
||||
if (EnableStatus) {
|
||||
EnableApicTimerInterrupt ();
|
||||
} else {
|
||||
DisableApicTimerInterrupt ();
|
||||
}
|
||||
//
|
||||
// Validate the Debug Timer interrupt state
|
||||
// This will make additional delay after Local Apic Timer interrupt state is changed.
|
||||
// Thus, CPU could handle the potential pending interrupt of Local Apic timer.
|
||||
//
|
||||
while (GetApicTimerInterruptState () != EnableStatus) {
|
||||
CpuPause ();
|
||||
}
|
||||
}
|
||||
|
||||
SetInterruptState (OldInterruptState);
|
||||
|
||||
return OldDebugTimerInterruptState;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Supporting functions for IA32 architecture.
|
||||
|
||||
Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -39,17 +39,17 @@ InitializeDebugIdt (
|
|||
IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;
|
||||
|
||||
for (Index = 0; Index < 20; Index ++) {
|
||||
if ((PcdGet32 (PcdExceptionsIgnoredByDebugger) & (1 << Index)) != 0) {
|
||||
if (((PcdGet32 (PcdExceptionsIgnoredByDebugger) & ~(BIT1 | BIT3)) & (1 << Index)) != 0) {
|
||||
//
|
||||
// If the exception is masked to be reserved, skip it
|
||||
// If the exception is masked to be reserved except for INT1 and INT3, skip it
|
||||
//
|
||||
continue;
|
||||
}
|
||||
InterruptHandler = (UINTN)&Exception0Handle + Index * ExceptionStubHeaderSize;
|
||||
IdtEntry[Index].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;
|
||||
IdtEntry[Index].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);
|
||||
IdtEntry[Index].Bits.Selector = CodeSegment;
|
||||
IdtEntry[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
|
||||
IdtEntry[Index].Bits.Selector = CodeSegment;
|
||||
IdtEntry[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
|
||||
}
|
||||
|
||||
InterruptHandler = (UINTN) &TimerInterruptHandle;
|
||||
|
@ -63,3 +63,49 @@ InitializeDebugIdt (
|
|||
//
|
||||
AsmWriteCr4 (AsmReadCr4 () | BIT3);
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieve exception handler from IDT table by ExceptionNum.
|
||||
|
||||
@param[in] ExceptionNum Exception number
|
||||
|
||||
@return Exception handler
|
||||
|
||||
**/
|
||||
VOID *
|
||||
GetExceptionHandlerInIdtEntry (
|
||||
IN UINTN ExceptionNum
|
||||
)
|
||||
{
|
||||
IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
|
||||
IA32_DESCRIPTOR IdtDescriptor;
|
||||
|
||||
AsmReadIdtr (&IdtDescriptor);
|
||||
IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;
|
||||
|
||||
return (VOID *) (((UINTN)IdtEntry[ExceptionNum].Bits.OffsetLow) |
|
||||
(((UINTN)IdtEntry[ExceptionNum].Bits.OffsetHigh) << 16));
|
||||
}
|
||||
|
||||
/**
|
||||
Set exception handler in IDT table by ExceptionNum.
|
||||
|
||||
@param[in] ExceptionNum Exception number
|
||||
@param[in] ExceptionHandler Exception Handler to be set
|
||||
|
||||
**/
|
||||
VOID
|
||||
SetExceptionHandlerInIdtEntry (
|
||||
IN UINTN ExceptionNum,
|
||||
IN VOID *ExceptionHandler
|
||||
)
|
||||
{
|
||||
IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
|
||||
IA32_DESCRIPTOR IdtDescriptor;
|
||||
|
||||
AsmReadIdtr (&IdtDescriptor);
|
||||
IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;
|
||||
|
||||
IdtEntry[ExceptionNum].Bits.OffsetLow = (UINT16)(UINTN)ExceptionHandler;
|
||||
IdtEntry[ExceptionNum].Bits.OffsetHigh = (UINT16)((UINTN)ExceptionHandler >> 16);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -33,6 +33,7 @@ ASM_PFX(ExceptionStubHeaderSize): .word ASM_PFX(Exception1Handle) - ASM_PFX
|
|||
|
||||
.text
|
||||
|
||||
.byte 0x41, 0x47, 0x54, 0x48 # AGENT_HANDLER_SIGNATURE SIGNATURE_32('A','G','T','H')
|
||||
ASM_PFX(Exception0Handle):
|
||||
cli
|
||||
pushl %eax
|
||||
|
@ -259,7 +260,7 @@ NoExtrPush:
|
|||
pushl %eax
|
||||
## clear Dr7 while executing debugger itself
|
||||
xorl %eax,%eax
|
||||
# movl %eax, %dr7
|
||||
movl %eax, %dr7
|
||||
|
||||
movl %dr6, %eax
|
||||
pushl %eax
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;------------------------------------------------------------------------------
|
||||
;
|
||||
; Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
; Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
; This program and the accompanying materials
|
||||
; are licensed and made available under the terms and conditions of the BSD License
|
||||
; which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -39,6 +39,7 @@ CommonEntryAddr DD CommonEntry
|
|||
|
||||
.code
|
||||
|
||||
db 41h, 47h, 54h, 48h ; AGENT_HANDLER_SIGNATURE SIGNATURE_32('A','G','T','H')
|
||||
Exception0Handle:
|
||||
cli
|
||||
push eax
|
||||
|
@ -259,7 +260,7 @@ NoExtrPush:
|
|||
|
||||
;; clear Dr7 while executing debugger itself
|
||||
xor eax, eax
|
||||
;; mov dr7, eax
|
||||
mov dr7, eax
|
||||
|
||||
;; Dr6
|
||||
mov eax, dr6
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Supporting functions for X64 architecture.
|
||||
|
||||
Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -39,9 +39,9 @@ InitializeDebugIdt (
|
|||
IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;
|
||||
|
||||
for (Index = 0; Index < 20; Index ++) {
|
||||
if ((PcdGet32 (PcdExceptionsIgnoredByDebugger) & (1 << Index)) != 0) {
|
||||
if (((PcdGet32 (PcdExceptionsIgnoredByDebugger) & ~(BIT1 | BIT3)) & (1 << Index)) != 0) {
|
||||
//
|
||||
// If the exception is masked to be reserved, skip it
|
||||
// If the exception is masked to be reserved except for INT1 and INT3, skip it
|
||||
//
|
||||
continue;
|
||||
}
|
||||
|
@ -65,3 +65,51 @@ InitializeDebugIdt (
|
|||
//
|
||||
AsmWriteCr4 (AsmReadCr4 () | BIT3);
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieve exception handler from IDT table by ExceptionNum.
|
||||
|
||||
@param[in] ExceptionNum Exception number
|
||||
|
||||
@return Exception handler
|
||||
|
||||
**/
|
||||
VOID *
|
||||
GetExceptionHandlerInIdtEntry (
|
||||
IN UINTN ExceptionNum
|
||||
)
|
||||
{
|
||||
IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
|
||||
IA32_DESCRIPTOR IdtDescriptor;
|
||||
|
||||
AsmReadIdtr (&IdtDescriptor);
|
||||
IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;
|
||||
|
||||
return (VOID *) (IdtEntry[ExceptionNum].Bits.OffsetLow |
|
||||
(((UINTN)IdtEntry[ExceptionNum].Bits.OffsetHigh) << 16) |
|
||||
(((UINTN)IdtEntry[ExceptionNum].Bits.OffsetUpper) << 32));
|
||||
}
|
||||
|
||||
/**
|
||||
Set exception handler in IDT table by ExceptionNum.
|
||||
|
||||
@param[in] ExceptionNum Exception number
|
||||
@param[in] ExceptionHandler Exception Handler to be set
|
||||
|
||||
**/
|
||||
VOID
|
||||
SetExceptionHandlerInIdtEntry (
|
||||
IN UINTN ExceptionNum,
|
||||
IN VOID *ExceptionHandler
|
||||
)
|
||||
{
|
||||
IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
|
||||
IA32_DESCRIPTOR IdtDescriptor;
|
||||
|
||||
AsmReadIdtr (&IdtDescriptor);
|
||||
IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;
|
||||
|
||||
IdtEntry[ExceptionNum].Bits.OffsetLow = (UINT16)(UINTN)ExceptionHandler;
|
||||
IdtEntry[ExceptionNum].Bits.OffsetHigh = (UINT16)((UINTN)ExceptionHandler >> 16);
|
||||
IdtEntry[ExceptionNum].Bits.OffsetUpper = (UINT32)((UINTN)ExceptionHandler >> 32);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -35,6 +35,7 @@ ASM_PFX(ExceptionStubHeaderSize): .word ASM_PFX(Exception1Handle) - ASM_PFX
|
|||
|
||||
.text
|
||||
|
||||
.byte 0x41, 0x47, 0x54, 0x48 # AGENT_HANDLER_SIGNATURE SIGNATURE_32('A','G','T','H')
|
||||
ASM_PFX(Exception0Handle):
|
||||
cli
|
||||
pushq %rcx
|
||||
|
@ -280,7 +281,7 @@ NoExtrPush:
|
|||
pushq %rax
|
||||
## clear Dr7 while executing debugger itself
|
||||
xorq %rax, %rax
|
||||
#debug movq %rax, %dr7
|
||||
movq %rax, %dr7
|
||||
|
||||
movq %dr6, %rax
|
||||
pushq %rax
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;------------------------------------------------------------------------------
|
||||
;
|
||||
; Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
; Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
; This program and the accompanying materials
|
||||
; are licensed and made available under the terms and conditions of the BSD License
|
||||
; which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -33,6 +33,7 @@ CommonEntryAddr dq CommonEntry ;
|
|||
|
||||
.code
|
||||
|
||||
db 41h, 47h, 54h, 48h ; AGENT_HANDLER_SIGNATURE SIGNATURE_32('A','G','T','H')
|
||||
Exception0Handle:
|
||||
cli
|
||||
push rcx
|
||||
|
@ -198,7 +199,7 @@ NoExtrPush:
|
|||
push rax
|
||||
mov rax, cr2
|
||||
push rax
|
||||
push 0 ; cr0 will not saved???
|
||||
push 0
|
||||
mov rax, cr0
|
||||
push rax
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Debug Agent library implementition for Dxe Core and Dxr modules.
|
||||
|
||||
Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -15,57 +15,51 @@
|
|||
#include "DxeDebugAgentLib.h"
|
||||
|
||||
DEBUG_AGENT_MAILBOX mMailbox;
|
||||
DEBUG_AGENT_MAILBOX *mMailboxPointer;
|
||||
DEBUG_AGENT_MAILBOX *mMailboxPointer = NULL;
|
||||
IA32_IDT_GATE_DESCRIPTOR mIdtEntryTable[33];
|
||||
BOOLEAN mDxeCoreFlag = FALSE;
|
||||
CONST BOOLEAN MultiProcessorDebugSupport = TRUE;
|
||||
BOOLEAN mDxeCoreFlag = FALSE;
|
||||
BOOLEAN mMultiProcessorDebugSupport = FALSE;
|
||||
VOID *mSavedIdtTable = NULL;
|
||||
UINTN mSaveIdtTableSize = 0;
|
||||
BOOLEAN mDebugAgentInitialized = FALSE;
|
||||
BOOLEAN mSkipBreakpoint = FALSE;
|
||||
|
||||
/**
|
||||
Constructor allocates the NVS memory to store Mailbox and install configuration table
|
||||
in system table to store its pointer.
|
||||
Check if debug agent support multi-processor.
|
||||
|
||||
@param[in] ImageHandle The firmware allocated handle for the EFI image.
|
||||
@param[in] SystemTable A pointer to the EFI System Table.
|
||||
|
||||
@retval RETURN_SUCCESS Allocate the global memory space to store guid and function tables.
|
||||
@retval TRUE Multi-processor is supported.
|
||||
@retval FALSE Multi-processor is not supported.
|
||||
|
||||
**/
|
||||
RETURN_STATUS
|
||||
EFIAPI
|
||||
DxeDebugAgentLibConstructor (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
BOOLEAN
|
||||
MultiProcessorDebugSupport (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return mMultiProcessorDebugSupport;
|
||||
}
|
||||
|
||||
/**
|
||||
Internal constructor worker function.
|
||||
|
||||
It will register one callback function on EFI PCD Protocol.
|
||||
It will allocate the NVS memory to store Mailbox and install configuration table
|
||||
in system table to store its pointer.
|
||||
|
||||
**/
|
||||
VOID
|
||||
InternalConstructorWorker (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PHYSICAL_ADDRESS Address;
|
||||
EFI_EVENT Event;
|
||||
VOID *EventRegistration;
|
||||
|
||||
if (!mDxeCoreFlag) {
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
Status = gBS->CreateEvent (
|
||||
EVT_NOTIFY_SIGNAL,
|
||||
TPL_CALLBACK,
|
||||
InstallSerialIoNotification,
|
||||
NULL,
|
||||
&Event
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
BOOLEAN DebugTimerInterruptState;
|
||||
|
||||
//
|
||||
// Register for protocol notifications on this event
|
||||
// Install EFI Serial IO protocol on debug port
|
||||
//
|
||||
|
||||
Status = gBS->RegisterProtocolNotify (
|
||||
&gEfiPcdProtocolGuid,
|
||||
Event,
|
||||
&EventRegistration
|
||||
);
|
||||
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
InstallSerialIo ();
|
||||
|
||||
Address = 0;
|
||||
Status = gBS->AllocatePages (
|
||||
|
@ -76,18 +70,67 @@ DxeDebugAgentLibConstructor (
|
|||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (FALSE);
|
||||
CopyMem (
|
||||
(UINT8 *) (UINTN) Address,
|
||||
(UINT8 *) (UINTN) mMailboxPointer,
|
||||
(UINT8 *) (UINTN) GetMailboxPointer (),
|
||||
sizeof (DEBUG_AGENT_MAILBOX)
|
||||
);
|
||||
DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (DebugTimerInterruptState);
|
||||
|
||||
mMailboxPointer = (DEBUG_AGENT_MAILBOX *) (UINTN) Address;
|
||||
|
||||
Status = gBS->InstallConfigurationTable (&gEfiDebugAgentGuid, (VOID *) mMailboxPointer);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
|
||||
/**
|
||||
Debug Agent constructor function.
|
||||
|
||||
@param[in] ImageHandle The firmware allocated handle for the EFI image.
|
||||
@param[in] SystemTable A pointer to the EFI System Table.
|
||||
|
||||
@retval RETURN_SUCCESS When this function completed.
|
||||
|
||||
**/
|
||||
RETURN_STATUS
|
||||
EFIAPI
|
||||
DxeDebugAgentLibConstructor (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
{
|
||||
if (mDxeCoreFlag) {
|
||||
//
|
||||
// Invoke internal constructor function only when DXE core links this library instance
|
||||
//
|
||||
InternalConstructorWorker ();
|
||||
}
|
||||
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the pointer to Mailbox from the configuration table.
|
||||
|
||||
@return Pointer to Mailbox.
|
||||
|
||||
**/
|
||||
DEBUG_AGENT_MAILBOX *
|
||||
GetMailboxFromConfigurationTable (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
DEBUG_AGENT_MAILBOX *Mailbox;
|
||||
|
||||
return Status;
|
||||
Status = EfiGetSystemConfigurationTable (&gEfiDebugAgentGuid, (VOID **) &Mailbox);
|
||||
if (Status == EFI_SUCCESS && Mailbox != NULL) {
|
||||
VerifyMailboxChecksum (Mailbox);
|
||||
return Mailbox;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,13 +147,18 @@ GetMailboxFromHob (
|
|||
)
|
||||
{
|
||||
EFI_HOB_GUID_TYPE *GuidHob;
|
||||
UINT64 *MailboxLocation;
|
||||
DEBUG_AGENT_MAILBOX *Mailbox;
|
||||
|
||||
GuidHob = GetNextGuidHob (&gEfiDebugAgentGuid, HobStart);
|
||||
if (GuidHob == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
MailboxLocation = (UINT64 *) (GET_GUID_HOB_DATA(GuidHob));
|
||||
Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocation);
|
||||
VerifyMailboxChecksum (Mailbox);
|
||||
|
||||
return (DEBUG_AGENT_MAILBOX *) (GET_GUID_HOB_DATA(GuidHob));
|
||||
return Mailbox;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -124,6 +172,9 @@ GetMailboxPointer (
|
|||
VOID
|
||||
)
|
||||
{
|
||||
AcquireMpSpinLock (&mDebugMpContext.MailboxSpinLock);
|
||||
VerifyMailboxChecksum (mMailboxPointer);
|
||||
ReleaseMpSpinLock (&mDebugMpContext.MailboxSpinLock);
|
||||
return mMailboxPointer;
|
||||
}
|
||||
|
||||
|
@ -138,10 +189,86 @@ GetDebugPortHandle (
|
|||
VOID
|
||||
)
|
||||
{
|
||||
return (DEBUG_PORT_HANDLE) (UINTN)(mMailboxPointer->DebugPortHandle);
|
||||
return (DEBUG_PORT_HANDLE) (UINTN)(GetMailboxPointer ()->DebugPortHandle);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Worker function to setup IDT table and initialize the IDT entries.
|
||||
|
||||
@param[in] Mailbox Pointer to Mailbox.
|
||||
|
||||
**/
|
||||
VOID
|
||||
SetupDebugAgentEnviroment (
|
||||
IN DEBUG_AGENT_MAILBOX *Mailbox
|
||||
)
|
||||
{
|
||||
IA32_DESCRIPTOR Idtr;
|
||||
UINT16 IdtEntryCount;
|
||||
UINT64 DebugPortHandle;
|
||||
|
||||
if (mMultiProcessorDebugSupport) {
|
||||
InitializeSpinLock (&mDebugMpContext.MpContextSpinLock);
|
||||
InitializeSpinLock (&mDebugMpContext.DebugPortSpinLock);
|
||||
InitializeSpinLock (&mDebugMpContext.MailboxSpinLock);
|
||||
//
|
||||
// Clear Break CPU index value
|
||||
//
|
||||
mDebugMpContext.BreakAtCpuIndex = (UINT32) -1;
|
||||
}
|
||||
|
||||
//
|
||||
// Get original IDT address and size.
|
||||
//
|
||||
AsmReadIdtr ((IA32_DESCRIPTOR *) &Idtr);
|
||||
IdtEntryCount = (UINT16) ((Idtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR));
|
||||
if (IdtEntryCount < 33) {
|
||||
Idtr.Limit = (UINT16) (sizeof (IA32_IDT_GATE_DESCRIPTOR) * 33 - 1);
|
||||
Idtr.Base = (UINTN) &mIdtEntryTable;
|
||||
ZeroMem (&mIdtEntryTable, Idtr.Limit + 1);
|
||||
AsmWriteIdtr ((IA32_DESCRIPTOR *) &Idtr);
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the IDT table entries to support source level debug.
|
||||
//
|
||||
InitializeDebugIdt ();
|
||||
|
||||
if (Mailbox != NULL) {
|
||||
//
|
||||
// If Mailbox exists, copy it into one global variable,
|
||||
//
|
||||
CopyMem (&mMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX));
|
||||
} else {
|
||||
ZeroMem (&mMailbox, sizeof (DEBUG_AGENT_MAILBOX));
|
||||
}
|
||||
|
||||
mMailboxPointer = &mMailbox;
|
||||
//
|
||||
// Initialize debug communication port
|
||||
//
|
||||
DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize ((VOID *)(UINTN)mMailboxPointer->DebugPortHandle, NULL);
|
||||
UpdateMailboxContent (mMailboxPointer, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);
|
||||
|
||||
if (Mailbox == NULL) {
|
||||
//
|
||||
// Trigger one software interrupt to inform HOST
|
||||
//
|
||||
TriggerSoftInterrupt (SYSTEM_RESET_SIGNATURE);
|
||||
SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1);
|
||||
//
|
||||
// Memory has been ready
|
||||
//
|
||||
if (IsHostAttached ()) {
|
||||
//
|
||||
// Trigger one software interrupt to inform HOST
|
||||
//
|
||||
TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Initialize debug agent.
|
||||
|
||||
|
@ -167,105 +294,207 @@ InitializeDebugAgent (
|
|||
IN DEBUG_AGENT_CONTINUE Function OPTIONAL
|
||||
)
|
||||
{
|
||||
UINT64 *MailboxLocation;
|
||||
DEBUG_AGENT_MAILBOX *Mailbox;
|
||||
IA32_DESCRIPTOR Idtr;
|
||||
UINT16 IdtEntryCount;
|
||||
BOOLEAN InterruptStatus;
|
||||
VOID *HobList;
|
||||
IA32_DESCRIPTOR IdtDescriptor;
|
||||
IA32_DESCRIPTOR *Ia32Idtr;
|
||||
IA32_IDT_ENTRY *Ia32IdtEntry;
|
||||
|
||||
if (InitFlag != DEBUG_AGENT_INIT_DXE_CORE &&
|
||||
InitFlag != DEBUG_AGENT_INIT_S3 &&
|
||||
InitFlag != DEBUG_AGENT_INIT_DXE_AP) {
|
||||
return;
|
||||
if (InitFlag == DEBUG_AGENT_INIT_DXE_AP) {
|
||||
//
|
||||
// Invoked by AP, enable interrupt to let AP could receive IPI from other processors
|
||||
//
|
||||
EnableInterrupts ();
|
||||
return ;
|
||||
}
|
||||
|
||||
//
|
||||
// Disable Debug Timer interrupt
|
||||
//
|
||||
SaveAndSetDebugTimerInterrupt (FALSE);
|
||||
//
|
||||
// Save and disable original interrupt status
|
||||
//
|
||||
InterruptStatus = SaveAndDisableInterrupts ();
|
||||
|
||||
if (InitFlag == DEBUG_AGENT_INIT_DXE_CORE) {
|
||||
//
|
||||
// Try to get Mailbox from GUIDed HOB.
|
||||
//
|
||||
mDxeCoreFlag = TRUE;
|
||||
Mailbox = GetMailboxFromHob (Context);
|
||||
|
||||
//
|
||||
// Clear Break CPU index value
|
||||
//
|
||||
mDebugMpContext.BreakAtCpuIndex = (UINT32) -1;
|
||||
|
||||
} else if (InitFlag == DEBUG_AGENT_INIT_DXE_AP) {
|
||||
|
||||
EnableInterrupts ();
|
||||
|
||||
return;
|
||||
|
||||
} else {
|
||||
//
|
||||
// If it is in S3 path, needn't to install configuration table.
|
||||
//
|
||||
Mailbox = NULL;
|
||||
}
|
||||
|
||||
if (Mailbox != NULL) {
|
||||
//
|
||||
// If Mailbox exists, copy it into one global variable.
|
||||
//
|
||||
CopyMem (&mMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX));
|
||||
} else {
|
||||
//
|
||||
// If Mailbox not exists, used the local Mailbox.
|
||||
//
|
||||
ZeroMem (&mMailbox, sizeof (DEBUG_AGENT_MAILBOX));
|
||||
}
|
||||
|
||||
mMailboxPointer = &mMailbox;
|
||||
|
||||
//
|
||||
// Get original IDT address and size.
|
||||
// Try to get mailbox firstly
|
||||
//
|
||||
AsmReadIdtr ((IA32_DESCRIPTOR *) &Idtr);
|
||||
IdtEntryCount = (UINT16) ((Idtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR));
|
||||
if (IdtEntryCount < 33) {
|
||||
Idtr.Limit = (UINT16) (sizeof (IA32_IDT_GATE_DESCRIPTOR) * 33 - 1);
|
||||
Idtr.Base = (UINTN) &mIdtEntryTable;
|
||||
ZeroMem (&mIdtEntryTable, Idtr.Limit + 1);
|
||||
AsmWriteIdtr ((IA32_DESCRIPTOR *) &Idtr);
|
||||
}
|
||||
HobList = NULL;
|
||||
Mailbox = NULL;
|
||||
MailboxLocation = NULL;
|
||||
|
||||
//
|
||||
// Initialize the IDT table entries to support source level debug.
|
||||
//
|
||||
InitializeDebugIdt ();
|
||||
switch (InitFlag) {
|
||||
|
||||
//
|
||||
// Initialize debug communication port
|
||||
//
|
||||
mMailboxPointer->DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize ((VOID *)(UINTN)mMailbox.DebugPortHandle, NULL);
|
||||
|
||||
InitializeSpinLock (&mDebugMpContext.MpContextSpinLock);
|
||||
InitializeSpinLock (&mDebugMpContext.DebugPortSpinLock);
|
||||
|
||||
if (InitFlag == DEBUG_AGENT_INIT_DXE_CORE) {
|
||||
case DEBUG_AGENT_INIT_DXE_LOAD:
|
||||
//
|
||||
// Initialize Debug Timer hardware and enable interrupt.
|
||||
// Check if Debug Agent has been initialized before
|
||||
//
|
||||
if (IsDebugAgentInitialzed ()) {
|
||||
DEBUG ((EFI_D_INFO, "Debug Agent: The former agent will be overwritten by the new one!\n"));
|
||||
}
|
||||
|
||||
mMultiProcessorDebugSupport = TRUE;
|
||||
//
|
||||
// Save original IDT table
|
||||
//
|
||||
AsmReadIdtr (&IdtDescriptor);
|
||||
mSaveIdtTableSize = IdtDescriptor.Limit + 1;
|
||||
mSavedIdtTable = AllocateCopyPool (mSaveIdtTableSize, (VOID *) IdtDescriptor.Base);
|
||||
//
|
||||
// Initialize Debug Timer hardware
|
||||
//
|
||||
InitializeDebugTimer ();
|
||||
//
|
||||
// Check if Debug Agent initialized in DXE phase
|
||||
//
|
||||
Mailbox = GetMailboxFromConfigurationTable ();
|
||||
if (Mailbox == NULL) {
|
||||
//
|
||||
// Try to get mailbox from GUIDed HOB build in PEI
|
||||
//
|
||||
HobList = GetHobList ();
|
||||
Mailbox = GetMailboxFromHob (HobList);
|
||||
}
|
||||
//
|
||||
// Set up IDT table and prepare for IDT entries
|
||||
//
|
||||
SetupDebugAgentEnviroment (Mailbox);
|
||||
//
|
||||
// For DEBUG_AGENT_INIT_S3, needn't to install configuration table and EFI Serial IO protocol
|
||||
// For DEBUG_AGENT_INIT_DXE_CORE, InternalConstructorWorker() will invoked in Constructor()
|
||||
//
|
||||
InternalConstructorWorker ();
|
||||
//
|
||||
// Enable interrupt to receive Debug Timer interrupt
|
||||
//
|
||||
EnableInterrupts ();
|
||||
|
||||
return;
|
||||
} else {
|
||||
//
|
||||
// Disable Debug Timer interrupt in S3 path.
|
||||
//
|
||||
SaveAndSetDebugTimerInterrupt (FALSE);
|
||||
mDebugAgentInitialized = TRUE;
|
||||
FindAndReportModuleImageInfo (SIZE_4KB);
|
||||
|
||||
*(EFI_STATUS *)Context = EFI_SUCCESS;
|
||||
|
||||
if (gST->ConOut != NULL) {
|
||||
Print (L"Debug Agent: Initialized successfully!\r\n");
|
||||
Print (L"If the Debug Port is serial port, please make sure this serial port isn't connected by ISA Serial driver\r\n");
|
||||
Print (L"You could do the following steps to disconnect the serial port:\r\n");
|
||||
Print (L"1: Shell> drivers\r\n");
|
||||
Print (L" ...\r\n");
|
||||
Print (L" V VERSION E G G #D #C DRIVER NAME IMAGE NAME\r\n");
|
||||
Print (L" == ======== = = = == == =================================== ===================\r\n");
|
||||
Print (L" 8F 0000000A B - - 1 14 PCI Bus Driver PciBusDxe\r\n");
|
||||
Print (L" 91 00000010 ? - - - - ATA Bus Driver AtaBusDxe\r\n");
|
||||
Print (L" ...\r\n");
|
||||
Print (L" A7 0000000A B - - 1 1 ISA Serial Driver IsaSerialDxe\r\n");
|
||||
Print (L" ...\r\n");
|
||||
Print (L"2: Shell> dh -d A7\r\n");
|
||||
Print (L" A7: Image(IsaSerialDxe) ImageDevPath (..9FB3-11D4-9A3A-0090273FC14D))DriverBinding ComponentName ComponentName2\r\n");
|
||||
Print (L" Driver Name : ISA Serial Driver\r\n");
|
||||
Print (L" Image Name : FvFile(93B80003-9FB3-11D4-9A3A-0090273FC14D)\r\n");
|
||||
Print (L" Driver Version : 0000000A\r\n");
|
||||
Print (L" Driver Type : BUS\r\n");
|
||||
Print (L" Configuration : NO\r\n");
|
||||
Print (L" Diagnostics : NO\r\n");
|
||||
Print (L" Managing :\r\n");
|
||||
Print (L" Ctrl[EA] : PciRoot(0x0)/Pci(0x1F,0x0)/Serial(0x0)\r\n");
|
||||
Print (L" Child[EB] : PciRoot(0x0)/Pci(0x1F,0x0)/Serial(0x0)/Uart(115200,8,N,1)\r\n");
|
||||
Print (L"3: Shell> disconnect EA\r\n");
|
||||
Print (L"4: Shell> load -nc DebugAgentDxe.efi\r\n\r\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case DEBUG_AGENT_INIT_DXE_UNLOAD:
|
||||
if (mDebugAgentInitialized) {
|
||||
if (IsHostAttached ()) {
|
||||
Print (L"Debug Agent: Host is still connected, please de-attach TARGET firstly!\r\n");
|
||||
*(EFI_STATUS *)Context = EFI_ACCESS_DENIED;
|
||||
//
|
||||
// Enable Debug Timer interrupt again
|
||||
//
|
||||
SaveAndSetDebugTimerInterrupt (TRUE);
|
||||
} else {
|
||||
//
|
||||
// Restore original IDT table
|
||||
//
|
||||
AsmReadIdtr (&IdtDescriptor);
|
||||
IdtDescriptor.Limit = (UINT16) (mSaveIdtTableSize - 1);
|
||||
CopyMem ((VOID *) IdtDescriptor.Base, mSavedIdtTable, mSaveIdtTableSize);
|
||||
AsmWriteIdtr (&IdtDescriptor);
|
||||
FreePool (mSavedIdtTable);
|
||||
mDebugAgentInitialized = FALSE;
|
||||
*(EFI_STATUS *)Context = EFI_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
Print (L"Debug Agent: It hasn't been initialized, cannot unload it!\r\n");
|
||||
*(EFI_STATUS *)Context = EFI_NOT_STARTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Restore interrupt state.
|
||||
//
|
||||
SetInterruptState (InterruptStatus);
|
||||
break;
|
||||
|
||||
case DEBUG_AGENT_INIT_DXE_CORE:
|
||||
mDxeCoreFlag = TRUE;
|
||||
mMultiProcessorDebugSupport = TRUE;
|
||||
//
|
||||
// Initialize Debug Timer hardware
|
||||
//
|
||||
InitializeDebugTimer ();
|
||||
//
|
||||
// Try to get mailbox from GUIDed HOB build in PEI
|
||||
//
|
||||
HobList = Context;
|
||||
Mailbox = GetMailboxFromHob (HobList);
|
||||
//
|
||||
// Set up IDT table and prepare for IDT entries
|
||||
//
|
||||
SetupDebugAgentEnviroment (Mailbox);
|
||||
//
|
||||
// Enable interrupt to receive Debug Timer interrupt
|
||||
//
|
||||
EnableInterrupts ();
|
||||
|
||||
break;
|
||||
|
||||
case DEBUG_AGENT_INIT_S3:
|
||||
|
||||
if (Context != NULL) {
|
||||
Ia32Idtr = (IA32_DESCRIPTOR *) Context;
|
||||
Ia32IdtEntry = (IA32_IDT_ENTRY *)(Ia32Idtr->Base);
|
||||
MailboxLocation = (UINT64 *) (UINTN) (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow +
|
||||
(Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh << 16));
|
||||
Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocation);
|
||||
VerifyMailboxChecksum (Mailbox);
|
||||
}
|
||||
//
|
||||
// Set up IDT table and prepare for IDT entries
|
||||
//
|
||||
SetupDebugAgentEnviroment (Mailbox);
|
||||
//
|
||||
// Disable interrupt
|
||||
//
|
||||
DisableInterrupts ();
|
||||
FindAndReportModuleImageInfo (SIZE_4KB);
|
||||
if (GetDebugFlag (DEBUG_AGENT_FLAG_BREAK_BOOT_SCRIPT) == 1) {
|
||||
//
|
||||
// If Boot Script entry break is set, code will be break at here.
|
||||
//
|
||||
CpuBreakpoint ();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
//
|
||||
// Only DEBUG_AGENT_INIT_PREMEM_SEC and DEBUG_AGENT_INIT_POSTMEM_SEC are allowed for this
|
||||
// Debug Agent library instance.
|
||||
//
|
||||
DEBUG ((EFI_D_ERROR, "Debug Agent: The InitFlag value is not allowed!\n"));
|
||||
CpuDeadLoop ();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Header file for Dxe Core Debug Agent Library instance.
|
||||
|
||||
Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -24,22 +24,17 @@
|
|||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/UefiLib.h>
|
||||
#include <Library/DevicePathLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
|
||||
#include "DebugAgent.h"
|
||||
|
||||
/**
|
||||
Notification function on EFI PCD protocol to install EFI Serial IO protocol based
|
||||
on Debug Communication Library.
|
||||
|
||||
@param[in] Event The event of notify protocol.
|
||||
@param[in] Context Notify event context.
|
||||
Install EFI Serial IO protocol based on Debug Communication Library.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
InstallSerialIoNotification (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
InstallSerialIo (
|
||||
VOID
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Install Serial IO Protocol that layers on top of a Debug Communication Library instance.
|
||||
|
||||
Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -149,11 +149,11 @@ SerialRead (
|
|||
EFI_SERIAL_IO_MODE mSerialIoMode = {
|
||||
SERIAL_PORT_DEFAULT_CONTROL_MASK,
|
||||
SERIAL_PORT_DEFAULT_TIMEOUT,
|
||||
0, // BaudRate
|
||||
0, // default BaudRate
|
||||
SERIAL_PORT_DEFAULT_RECEIVE_FIFO_DEPTH,
|
||||
0, // DataBits
|
||||
0, // Parity
|
||||
0 // StopBits
|
||||
0, // default DataBits
|
||||
0, // default Parity
|
||||
0 // default StopBits
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -204,10 +204,10 @@ SERIAL_IO_DEVICE_PATH mSerialIoDevicePath = {
|
|||
}
|
||||
},
|
||||
0,
|
||||
0, // BaudRate
|
||||
0, // DataBits
|
||||
0, // Parity
|
||||
0, // StopBits
|
||||
0, // default BaudRate
|
||||
0, // default DataBits
|
||||
0, // default Parity
|
||||
0, // default StopBits
|
||||
},
|
||||
{
|
||||
END_DEVICE_PATH_TYPE,
|
||||
|
@ -357,34 +357,15 @@ DebugTerminalFifoRemove (
|
|||
}
|
||||
|
||||
/**
|
||||
Notification function on EFI PCD protocol to install EFI Serial IO protocol based
|
||||
on Debug Communication Library.
|
||||
|
||||
@param[in] Event The event of notify protocol.
|
||||
@param[in] Context Notify event context.
|
||||
Install EFI Serial IO protocol based on Debug Communication Library.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
InstallSerialIoNotification (
|
||||
IN EFI_EVENT Event,
|
||||
IN VOID *Context
|
||||
InstallSerialIo (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
//
|
||||
// Get Debug Port parameters from PCDs
|
||||
//
|
||||
mSerialIoDevicePath.UartDevicePath.BaudRate = PcdGet64 (PcdUartDefaultBaudRate);
|
||||
mSerialIoDevicePath.UartDevicePath.DataBits = PcdGet8 (PcdUartDefaultDataBits);
|
||||
mSerialIoDevicePath.UartDevicePath.Parity = PcdGet8 (PcdUartDefaultParity);
|
||||
mSerialIoDevicePath.UartDevicePath.StopBits = PcdGet8 (PcdUartDefaultStopBits);
|
||||
|
||||
mSerialIoMode.BaudRate = mSerialIoDevicePath.UartDevicePath.BaudRate;
|
||||
mSerialIoMode.DataBits = mSerialIoDevicePath.UartDevicePath.DataBits;
|
||||
mSerialIoMode.Parity = mSerialIoDevicePath.UartDevicePath.Parity;
|
||||
mSerialIoMode.StopBits = mSerialIoDevicePath.UartDevicePath.StopBits;
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||
&mSerialIoHandle,
|
||||
|
@ -448,22 +429,10 @@ SerialSetAttributes (
|
|||
)
|
||||
{
|
||||
//
|
||||
// The Debug Communication Library does not support changing communications parameters, so unless
|
||||
// the request is to use the default value or the value the Debug Communication Library is already
|
||||
// using, then return EFI_INVALID_PARAMETER.
|
||||
// The Debug Communication Library CAN NOT change communications parameters (if it has)
|
||||
// actually. Because it also has no any idea on what parameters are based on, we cannot
|
||||
// check the input parameters (like BaudRate, Parity, DataBits and StopBits).
|
||||
//
|
||||
if (BaudRate != 0 && BaudRate != PcdGet64 (PcdUartDefaultBaudRate)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
if (Parity != DefaultParity && Parity != PcdGet8 (PcdUartDefaultParity)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
if (DataBits != 0 && DataBits != PcdGet8 (PcdUartDefaultDataBits)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
if (StopBits != DefaultStopBits && StopBits != PcdGet8 (PcdUartDefaultStopBits)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Update the Timeout value in the mode structure based on the request.
|
||||
|
@ -536,7 +505,18 @@ SerialGetControl (
|
|||
)
|
||||
{
|
||||
DEBUG_PORT_HANDLE Handle;
|
||||
BOOLEAN DebugTimerInterruptState;
|
||||
EFI_TPL Tpl;
|
||||
|
||||
//
|
||||
// Raise TPL to prevent recursion from EFI timer interrupts
|
||||
//
|
||||
Tpl = gBS->RaiseTPL (TPL_NOTIFY);
|
||||
|
||||
//
|
||||
// Save and disable Debug Timer interrupt to avoid it to access Debug Port
|
||||
//
|
||||
DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (FALSE);
|
||||
Handle = GetDebugPortHandle ();
|
||||
|
||||
//
|
||||
|
@ -552,6 +532,17 @@ SerialGetControl (
|
|||
if (!IsDebugTermianlFifoEmpty (&mSerialFifoForTerminal) || DebugPortPollBuffer (Handle)) {
|
||||
*Control &= ~EFI_SERIAL_INPUT_BUFFER_EMPTY;
|
||||
}
|
||||
|
||||
//
|
||||
// Restore Debug Timer interrupt
|
||||
//
|
||||
SaveAndSetDebugTimerInterrupt (DebugTimerInterruptState);
|
||||
|
||||
//
|
||||
// Restore to original TPL
|
||||
//
|
||||
gBS->RestoreTPL (Tpl);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -577,7 +568,18 @@ SerialWrite (
|
|||
)
|
||||
{
|
||||
DEBUG_PORT_HANDLE Handle;
|
||||
BOOLEAN DebugTimerInterruptState;
|
||||
EFI_TPL Tpl;
|
||||
|
||||
//
|
||||
// Raise TPL to prevent recursion from EFI timer interrupts
|
||||
//
|
||||
Tpl = gBS->RaiseTPL (TPL_NOTIFY);
|
||||
|
||||
//
|
||||
// Save and disable Debug Timer interrupt to avoid it to access Debug Port
|
||||
//
|
||||
DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (FALSE);
|
||||
Handle = GetDebugPortHandle ();
|
||||
|
||||
if ((mSerialIoMode.ControlMask & EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE) != 0) {
|
||||
|
@ -593,6 +595,17 @@ SerialWrite (
|
|||
} else {
|
||||
*BufferSize = DebugPortWriteBuffer (Handle, Buffer, *BufferSize);
|
||||
}
|
||||
|
||||
//
|
||||
// Restore Debug Timer interrupt
|
||||
//
|
||||
SaveAndSetDebugTimerInterrupt (DebugTimerInterruptState);
|
||||
|
||||
//
|
||||
// Restore to original TPL
|
||||
//
|
||||
gBS->RestoreTPL (Tpl);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -620,17 +633,24 @@ SerialRead (
|
|||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
UINT8 *Uint8Buffer;
|
||||
BOOLEAN OldInterruptState;
|
||||
BOOLEAN DebugTimerInterruptState;
|
||||
EFI_TPL Tpl;
|
||||
DEBUG_PORT_HANDLE Handle;
|
||||
UINT8 Data;
|
||||
|
||||
Handle = GetDebugPortHandle ();
|
||||
DEBUG_PACKET_HEADER DebugHeader;
|
||||
UINT8 *Data8;
|
||||
|
||||
//
|
||||
// Raise TPL to prevent recursion from EFI timer interrupts
|
||||
//
|
||||
Tpl = gBS->RaiseTPL (TPL_NOTIFY);
|
||||
|
||||
//
|
||||
// Save and disable Debug Timer interrupt to avoid it to access Debug Port
|
||||
//
|
||||
OldInterruptState = SaveAndSetDebugTimerInterrupt (FALSE);
|
||||
|
||||
DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (FALSE);
|
||||
Handle = GetDebugPortHandle ();
|
||||
|
||||
Data8 = (UINT8 *) &DebugHeader;
|
||||
Uint8Buffer = (UINT8 *)Buffer;
|
||||
if ((mSerialIoMode.ControlMask & EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE) != 0) {
|
||||
if ((mLoopbackBuffer & SERIAL_PORT_LOOPBACK_BUFFER_FULL) == 0) {
|
||||
|
@ -644,9 +664,9 @@ SerialRead (
|
|||
//
|
||||
// Read input character from terminal FIFO firstly
|
||||
//
|
||||
Status = DebugTerminalFifoRemove (&mSerialFifoForTerminal, &Data);
|
||||
Status = DebugTerminalFifoRemove (&mSerialFifoForTerminal, Data8);
|
||||
if (Status == EFI_SUCCESS) {
|
||||
*Uint8Buffer = Data;
|
||||
*Uint8Buffer = *Data8;
|
||||
Uint8Buffer ++;
|
||||
continue;
|
||||
}
|
||||
|
@ -656,16 +676,25 @@ SerialRead (
|
|||
if (!DebugPortPollBuffer (Handle)) {
|
||||
break;
|
||||
}
|
||||
DebugPortReadBuffer (Handle, &Data, 1, 0);
|
||||
DebugPortReadBuffer (Handle, Data8, 1, 0);
|
||||
|
||||
if (Data== DEBUG_STARTING_SYMBOL_ATTACH ||
|
||||
Data == DEBUG_STARTING_SYMBOL_BREAK) {
|
||||
if (*Data8 == DEBUG_STARTING_SYMBOL_ATTACH) {
|
||||
//
|
||||
// Add the debug symbol into Debug FIFO
|
||||
//
|
||||
DebugTerminalFifoAdd (&mSerialFifoForDebug, Data);
|
||||
DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Terminal Timer attach symbol received %x", *Data8);
|
||||
DebugTerminalFifoAdd (&mSerialFifoForDebug, *Data8);
|
||||
} else if (*Data8 == DEBUG_STARTING_SYMBOL_NORMAL) {
|
||||
Status = ReadRemainingBreakPacket (Handle, &DebugHeader);
|
||||
if (Status == EFI_SUCCESS) {
|
||||
DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Terminal Timer break symbol received %x", DebugHeader.Command);
|
||||
DebugTerminalFifoAdd (&mSerialFifoForDebug, DebugHeader.Command);
|
||||
}
|
||||
if (Status == EFI_TIMEOUT) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
*Uint8Buffer = Data;
|
||||
*Uint8Buffer = *Data8;
|
||||
Uint8Buffer ++;
|
||||
}
|
||||
}
|
||||
|
@ -675,7 +704,12 @@ SerialRead (
|
|||
//
|
||||
// Restore Debug Timer interrupt
|
||||
//
|
||||
SaveAndSetDebugTimerInterrupt (OldInterruptState);
|
||||
SaveAndSetDebugTimerInterrupt (DebugTimerInterruptState);
|
||||
|
||||
//
|
||||
// Restore to original TPL
|
||||
//
|
||||
gBS->RestoreTPL (Tpl);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
@ -689,6 +723,71 @@ SerialRead (
|
|||
@retval EFI_SUCCESS Read the symbol in BreakSymbol.
|
||||
@retval EFI_NOT_FOUND No read the break symbol.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DebugReadBreakFromDebugPort (
|
||||
IN DEBUG_PORT_HANDLE Handle,
|
||||
OUT UINT8 *BreakSymbol
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
DEBUG_PACKET_HEADER DebugHeader;
|
||||
UINT8 *Data8;
|
||||
|
||||
*BreakSymbol = 0;
|
||||
//
|
||||
// If Debug Port buffer has data, read it till it was break symbol or Debug Port buffer empty.
|
||||
//
|
||||
Data8 = (UINT8 *) &DebugHeader;
|
||||
while (TRUE) {
|
||||
//
|
||||
// If start symbol is not received
|
||||
//
|
||||
if (!DebugPortPollBuffer (Handle)) {
|
||||
//
|
||||
// If no data in Debug Port, exit
|
||||
//
|
||||
break;
|
||||
}
|
||||
//
|
||||
// Try to read the start symbol
|
||||
//
|
||||
DebugPortReadBuffer (Handle, Data8, 1, 0);
|
||||
if (*Data8 == DEBUG_STARTING_SYMBOL_ATTACH) {
|
||||
DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Debug Timer attach symbol received %x", *Data8);
|
||||
*BreakSymbol = *Data8;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
if (*Data8 == DEBUG_STARTING_SYMBOL_NORMAL) {
|
||||
Status = ReadRemainingBreakPacket (Handle, &DebugHeader);
|
||||
if (Status == EFI_SUCCESS) {
|
||||
DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Debug Timer break symbol received %x", DebugHeader.Command);
|
||||
*BreakSymbol = DebugHeader.Command;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
if (Status == EFI_TIMEOUT) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// Add to Terminal FIFO
|
||||
//
|
||||
DebugTerminalFifoAdd (&mSerialFifoForTerminal, *Data8);
|
||||
}
|
||||
}
|
||||
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
Read the Attach/Break-in symbols.
|
||||
|
||||
@param[in] Handle Pointer to Debug Port handle.
|
||||
@param[out] BreakSymbol Returned break symbol.
|
||||
|
||||
@retval EFI_SUCCESS Read the symbol in BreakSymbol.
|
||||
@retval EFI_NOT_FOUND No read the break symbol.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
DebugReadBreakSymbol (
|
||||
|
@ -697,30 +796,19 @@ DebugReadBreakSymbol (
|
|||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT8 Data;
|
||||
UINT8 Data8;
|
||||
|
||||
Status = DebugTerminalFifoRemove (&mSerialFifoForDebug, &Data);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
if (!DebugPortPollBuffer (Handle)) {
|
||||
//
|
||||
// No data in Debug Port buffer.
|
||||
//
|
||||
return EFI_NOT_FOUND;
|
||||
} else {
|
||||
//
|
||||
// Read one character from Debug Port.
|
||||
//
|
||||
DebugPortReadBuffer (Handle, &Data, 1, 0);
|
||||
if ((Data != DEBUG_STARTING_SYMBOL_ATTACH) && (Data != DEBUG_STARTING_SYMBOL_BREAK)) {
|
||||
//
|
||||
// If the data is not Break symbol, add it into Terminal FIFO
|
||||
//
|
||||
DebugTerminalFifoAdd (&mSerialFifoForTerminal, Data);
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Read break symbol from debug FIFO firstly
|
||||
//
|
||||
Status = DebugTerminalFifoRemove (&mSerialFifoForDebug, &Data8);
|
||||
if (Status == EFI_SUCCESS) {
|
||||
*BreakSymbol = Data8;
|
||||
return EFI_SUCCESS;
|
||||
} else {
|
||||
//
|
||||
// Read Break symbol from debug port
|
||||
//
|
||||
return DebugReadBreakFromDebugPort (Handle, BreakSymbol);
|
||||
}
|
||||
|
||||
*BreakSymbol = Data;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## @file
|
||||
# Debug Agent library instance for Dxe Core and Dxe modules.
|
||||
#
|
||||
# Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
|
@ -75,6 +75,9 @@
|
|||
LocalApicLib
|
||||
TimerLib
|
||||
PrintLib
|
||||
PeCoffGetEntryPointLib
|
||||
PeCoffExtraActionLib
|
||||
MemoryAllocationLib
|
||||
|
||||
[Guids]
|
||||
gEfiDebugAgentGuid ## PRODUCES ## Configuration Table
|
||||
|
@ -83,13 +86,8 @@
|
|||
[Protocols]
|
||||
gEfiSerialIoProtocolGuid ## PRODUCES
|
||||
gEfiDevicePathProtocolGuid ## PRODUCES
|
||||
gEfiPcdProtocolGuid ## NOTIFY
|
||||
|
||||
[Pcd]
|
||||
gEfiMdePkgTokenSpaceGuid.PcdFSBClock ## CONSUMES
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate ## CONSUMES
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits ## CONSUMES
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity ## CONSUMES
|
||||
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits ## CONSUMES
|
||||
gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdExceptionsIgnoredByDebugger ## CONSUMES
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
SEC Core Debug Agent Library instance implementition.
|
||||
|
||||
Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -14,7 +14,30 @@
|
|||
|
||||
#include "SecPeiDebugAgentLib.h"
|
||||
|
||||
CONST BOOLEAN MultiProcessorDebugSupport = FALSE;
|
||||
BOOLEAN mSkipBreakpoint = FALSE;
|
||||
|
||||
EFI_PEI_NOTIFY_DESCRIPTOR mMemoryDiscoveredNotifyList[1] = {
|
||||
{
|
||||
(EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
||||
&gEfiPeiMemoryDiscoveredPpiGuid,
|
||||
DebugAgentCallbackMemoryDiscoveredPpi
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
Check if debug agent support multi-processor.
|
||||
|
||||
@retval TRUE Multi-processor is supported.
|
||||
@retval FALSE Multi-processor is not supported.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
MultiProcessorDebugSupport (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
Read the Attach/Break-in symbols from the debug port.
|
||||
|
@ -32,14 +55,44 @@ DebugReadBreakSymbol (
|
|||
OUT UINT8 *BreakSymbol
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
DEBUG_PACKET_HEADER DebugHeader;
|
||||
UINT8 *Data8;
|
||||
|
||||
*BreakSymbol = 0;
|
||||
//
|
||||
// If Debug Port buffer has data, read it till it was break symbol or Debug Port buffer emty.
|
||||
// If Debug Port buffer has data, read it till it was break symbol or Debug Port buffer empty.
|
||||
//
|
||||
while (DebugPortPollBuffer (Handle)) {
|
||||
DebugPortReadBuffer (Handle, BreakSymbol, 1, 0);
|
||||
if (*BreakSymbol == DEBUG_STARTING_SYMBOL_ATTACH || *BreakSymbol == DEBUG_STARTING_SYMBOL_BREAK) {
|
||||
Data8 = (UINT8 *) &DebugHeader;
|
||||
while (TRUE) {
|
||||
//
|
||||
// If start symbol is not received
|
||||
//
|
||||
if (!DebugPortPollBuffer (Handle)) {
|
||||
//
|
||||
// If no data in Debug Port, exit
|
||||
//
|
||||
break;
|
||||
}
|
||||
//
|
||||
// Try to read the start symbol
|
||||
//
|
||||
DebugPortReadBuffer (Handle, Data8, 1, 0);
|
||||
if (*Data8 == DEBUG_STARTING_SYMBOL_ATTACH) {
|
||||
*BreakSymbol = *Data8;
|
||||
DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Debug Timer attach symbol received %x", *BreakSymbol);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
if (*Data8 == DEBUG_STARTING_SYMBOL_NORMAL) {
|
||||
Status = ReadRemainingBreakPacket (Handle, &DebugHeader);
|
||||
if (Status == EFI_SUCCESS) {
|
||||
*BreakSymbol = DebugHeader.Command;
|
||||
DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Debug Timer break symbol received %x", *BreakSymbol);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
if (Status == EFI_TIMEOUT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,67 +100,56 @@ DebugReadBreakSymbol (
|
|||
}
|
||||
|
||||
/**
|
||||
Get pointer to Mailbox from IDT entry before memory is ready.
|
||||
Get the pointer to location saved Mailbox pointer from IDT entry.
|
||||
|
||||
**/
|
||||
VOID *
|
||||
GetMailboxPointerInIdtEntry (
|
||||
GetLocationSavedMailboxPointerInIdtEntry (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
|
||||
IA32_DESCRIPTOR IdtDescriptor;
|
||||
UINTN Mailbox;
|
||||
UINTN *MailboxLocation;
|
||||
|
||||
AsmReadIdtr (&IdtDescriptor);
|
||||
IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;
|
||||
|
||||
Mailbox = IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow + (IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh << 16);
|
||||
return (VOID *) Mailbox;
|
||||
MailboxLocation = (UINTN *) GetExceptionHandlerInIdtEntry (DEBUG_MAILBOX_VECTOR);
|
||||
//
|
||||
// *MailboxLocation is the pointer to Mailbox
|
||||
//
|
||||
VerifyMailboxChecksum ((DEBUG_AGENT_MAILBOX *) (*MailboxLocation));
|
||||
return MailboxLocation;
|
||||
}
|
||||
|
||||
/**
|
||||
Set the pointer of Mailbox into IDT entry before memory is ready.
|
||||
|
||||
@param[in] Mailbox The pointer of Mailbox.
|
||||
@param[in] MailboxLocation Pointer to location saved Mailbox pointer.
|
||||
|
||||
**/
|
||||
VOID
|
||||
SetMailboxPointerInIdtEntry (
|
||||
IN VOID *Mailbox
|
||||
SetLocationSavedMailboxPointerInIdtEntry (
|
||||
IN VOID *MailboxLocation
|
||||
)
|
||||
{
|
||||
IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
|
||||
IA32_DESCRIPTOR IdtDescriptor;
|
||||
|
||||
AsmReadIdtr (&IdtDescriptor);
|
||||
IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;
|
||||
|
||||
IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow = (UINT16)(UINTN)Mailbox;
|
||||
IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh = (UINT16)((UINTN)Mailbox >> 16);
|
||||
SetExceptionHandlerInIdtEntry (DEBUG_MAILBOX_VECTOR, MailboxLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
Get the pointer to Mailbox from IDT entry and build the Mailbox into GUIDed Hob
|
||||
after memory is ready.
|
||||
Get the location of Mailbox pointer from the GUIDed HOB.
|
||||
|
||||
@return Pointer to Mailbox.
|
||||
@return Pointer to the location saved Mailbox pointer.
|
||||
|
||||
**/
|
||||
DEBUG_AGENT_MAILBOX *
|
||||
BuildMailboxHob (
|
||||
UINT64 *
|
||||
GetMailboxLocationFromHob (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
DEBUG_AGENT_MAILBOX *Mailbox;
|
||||
EFI_HOB_GUID_TYPE *GuidHob;
|
||||
|
||||
Mailbox = (DEBUG_AGENT_MAILBOX *) GetMailboxPointerInIdtEntry ();
|
||||
|
||||
return BuildGuidDataHob (
|
||||
&gEfiDebugAgentGuid,
|
||||
Mailbox,
|
||||
sizeof (DEBUG_AGENT_MAILBOX)
|
||||
);
|
||||
GuidHob = GetFirstGuidHob (&gEfiDebugAgentGuid);
|
||||
if (GuidHob == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return (UINT64 *) (GET_GUID_HOB_DATA(GuidHob));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -121,7 +163,49 @@ GetMailboxPointer (
|
|||
VOID
|
||||
)
|
||||
{
|
||||
return (DEBUG_AGENT_MAILBOX *) GetMailboxPointerInIdtEntry ();
|
||||
UINT64 DebugPortHandle;
|
||||
UINT64 *MailboxLocationInIdt;
|
||||
UINT64 *MailboxLocationInHob;
|
||||
DEBUG_AGENT_MAILBOX *Mailbox;
|
||||
|
||||
//
|
||||
// Get mailbox from IDT entry firstly
|
||||
//
|
||||
MailboxLocationInIdt = GetLocationSavedMailboxPointerInIdtEntry ();
|
||||
Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocationInIdt);
|
||||
//
|
||||
// Check if mailbox was setup in PEI firstly, cannot used GetDebugFlag() to
|
||||
// get CheckMailboxInHob flag to avoid GetMailboxPointer() nesting.
|
||||
//
|
||||
if (Mailbox->DebugFlag.Bits.CheckMailboxInHob != 1) {
|
||||
//
|
||||
// If mailbox in IDT entry has already been the final one
|
||||
//
|
||||
return Mailbox;
|
||||
}
|
||||
|
||||
MailboxLocationInHob = GetMailboxLocationFromHob ();
|
||||
//
|
||||
// Compare mailbox in IDT enry with mailbox in HOB
|
||||
//
|
||||
if (MailboxLocationInHob != MailboxLocationInIdt && MailboxLocationInHob != NULL) {
|
||||
Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocationInHob);
|
||||
//
|
||||
// Fix up Debug Port handler and save new mailbox in IDT entry
|
||||
//
|
||||
Mailbox = (DEBUG_AGENT_MAILBOX *)((UINTN)Mailbox + ((UINTN)(MailboxLocationInHob) - (UINTN)MailboxLocationInIdt));
|
||||
DebugPortHandle = (UINT64)((UINTN)Mailbox->DebugPortHandle + ((UINTN)(MailboxLocationInHob) - (UINTN)MailboxLocationInIdt));
|
||||
UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);
|
||||
*MailboxLocationInHob = (UINT64)(UINTN)Mailbox;
|
||||
SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationInHob);
|
||||
//
|
||||
// Clean CheckMailboxInHob flag
|
||||
//
|
||||
Mailbox->DebugFlag.Bits.CheckMailboxInHob = 0;
|
||||
UpdateMailboxChecksum (Mailbox);
|
||||
}
|
||||
|
||||
return Mailbox;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -137,49 +221,59 @@ GetDebugPortHandle (
|
|||
{
|
||||
DEBUG_AGENT_MAILBOX *DebugAgentMailbox;
|
||||
|
||||
DebugAgentMailbox = (DEBUG_AGENT_MAILBOX *)GetMailboxPointerInIdtEntry ();
|
||||
DebugAgentMailbox = GetMailboxPointer ();
|
||||
|
||||
return (DEBUG_PORT_HANDLE) (UINTN)(DebugAgentMailbox->DebugPortHandle);
|
||||
}
|
||||
|
||||
/**
|
||||
Trigger one software interrupt to debug agent to handle it.
|
||||
Debug Agent provided notify callback function on Memory Discovered PPI.
|
||||
|
||||
@param Signature Software interrupt signature.
|
||||
@param[in] PeiServices Indirect reference to the PEI Services Table.
|
||||
@param[in] NotifyDescriptor Address of the notification descriptor data structure.
|
||||
@param[in] Ppi Address of the PPI that was installed.
|
||||
|
||||
@retval EFI_SUCCESS If the function completed successfully.
|
||||
|
||||
**/
|
||||
VOID
|
||||
TriggerSoftInterrupt (
|
||||
UINT32 Signature
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DebugAgentCallbackMemoryDiscoveredPpi (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
|
||||
IN VOID *Ppi
|
||||
)
|
||||
{
|
||||
UINTN Dr0;
|
||||
UINTN Dr1;
|
||||
DEBUG_AGENT_MAILBOX *Mailbox;
|
||||
BOOLEAN InterruptStatus;
|
||||
|
||||
//
|
||||
// Save and disable original interrupt status
|
||||
//
|
||||
InterruptStatus = SaveAndDisableInterrupts ();
|
||||
|
||||
//
|
||||
// Set physical memory ready flag
|
||||
//
|
||||
Mailbox = GetMailboxPointer ();
|
||||
SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1);
|
||||
|
||||
//
|
||||
// Save Debug Register State
|
||||
// Memory has been ready
|
||||
//
|
||||
Dr0 = AsmReadDr0 ();
|
||||
Dr1 = AsmReadDr1 ();
|
||||
if (IsHostAttached ()) {
|
||||
//
|
||||
// Trigger one software interrupt to inform HOST
|
||||
//
|
||||
TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);
|
||||
}
|
||||
|
||||
//
|
||||
// DR0 = Signature
|
||||
// Restore interrupt state.
|
||||
//
|
||||
AsmWriteDr0 (SOFT_INTERRUPT_SIGNATURE);
|
||||
AsmWriteDr1 (Signature);
|
||||
|
||||
//
|
||||
// Do INT3 to communicate with HOST side
|
||||
//
|
||||
CpuBreakpoint ();
|
||||
|
||||
//
|
||||
// Restore Debug Register State only when Host didn't change it inside exception handler.
|
||||
// Dr registers can only be changed by setting the HW breakpoint.
|
||||
//
|
||||
AsmWriteDr0 (Dr0);
|
||||
AsmWriteDr1 (Dr1);
|
||||
|
||||
SetInterruptState (InterruptStatus);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -225,7 +319,13 @@ InitializeDebugAgent (
|
|||
DEBUG_AGENT_MAILBOX MailboxInStack;
|
||||
DEBUG_AGENT_PHASE2_CONTEXT Phase2Context;
|
||||
DEBUG_AGENT_CONTEXT_POSTMEM_SEC *DebugAgentContext;
|
||||
|
||||
EFI_STATUS Status;
|
||||
IA32_DESCRIPTOR *Ia32Idtr;
|
||||
IA32_IDT_ENTRY *Ia32IdtEntry;
|
||||
UINT64 DebugPortHandle;
|
||||
UINT64 MailboxLocation;
|
||||
UINT64 *MailboxLocationPointer;
|
||||
|
||||
DisableInterrupts ();
|
||||
|
||||
switch (InitFlag) {
|
||||
|
@ -234,20 +334,20 @@ InitializeDebugAgent (
|
|||
|
||||
InitializeDebugIdt ();
|
||||
|
||||
MailboxLocation = (UINT64)(UINTN)&MailboxInStack;
|
||||
Mailbox = &MailboxInStack;
|
||||
ZeroMem ((VOID *) Mailbox, sizeof (DEBUG_AGENT_MAILBOX));
|
||||
|
||||
//
|
||||
// Get and save debug port handle and set the length of memory block.
|
||||
//
|
||||
SetMailboxPointerInIdtEntry ((VOID *) Mailbox);
|
||||
SetLocationSavedMailboxPointerInIdtEntry (&MailboxLocation);
|
||||
SetDebugFlag (DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL, DEBUG_AGENT_ERROR);
|
||||
|
||||
InitializeDebugTimer ();
|
||||
|
||||
Phase2Context.Context = Context;
|
||||
Phase2Context.Function = Function;
|
||||
DebugPortInitialize ((VOID *) &Phase2Context, InitializeDebugAgentPhase2);
|
||||
|
||||
//
|
||||
// If reaches here, it means Debug Port initialization failed.
|
||||
//
|
||||
|
@ -256,34 +356,123 @@ InitializeDebugAgent (
|
|||
break;
|
||||
|
||||
case DEBUG_AGENT_INIT_POSTMEM_SEC:
|
||||
|
||||
Mailbox = GetMailboxPointer ();
|
||||
//
|
||||
// Memory has been ready
|
||||
//
|
||||
if (IsHostAttached()) {
|
||||
SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1);
|
||||
if (IsHostAttached ()) {
|
||||
//
|
||||
// Trigger one software interrupt to inform HOST
|
||||
//
|
||||
TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);
|
||||
}
|
||||
|
||||
//
|
||||
// Fix up Debug Port handle address and mailbox address
|
||||
//
|
||||
DebugAgentContext = (DEBUG_AGENT_CONTEXT_POSTMEM_SEC *) Context;
|
||||
|
||||
Mailbox = (DEBUG_AGENT_MAILBOX *) GetMailboxPointerInIdtEntry ();
|
||||
Mailbox->DebugPortHandle = (UINT64)(UINT32)(Mailbox->DebugPortHandle + DebugAgentContext->StackMigrateOffset);
|
||||
Mailbox->DebugFlag.MemoryReady = 1;
|
||||
|
||||
Mailbox = BuildMailboxHob ();
|
||||
Mailbox = (DEBUG_AGENT_MAILBOX *) ((UINTN) Mailbox + DebugAgentContext->HeapMigrateOffset);
|
||||
|
||||
SetMailboxPointerInIdtEntry ((VOID *) Mailbox);
|
||||
|
||||
DebugPortHandle = (UINT64)(UINT32)(Mailbox->DebugPortHandle + DebugAgentContext->StackMigrateOffset);
|
||||
UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);
|
||||
Mailbox = (DEBUG_AGENT_MAILBOX *) ((UINTN) Mailbox + DebugAgentContext->StackMigrateOffset);
|
||||
MailboxLocation = (UINT64)(UINTN)Mailbox;
|
||||
//
|
||||
// Build mailbox location in HOB and fix-up its address
|
||||
//
|
||||
MailboxLocationPointer = BuildGuidDataHob (
|
||||
&gEfiDebugAgentGuid,
|
||||
&MailboxLocation,
|
||||
sizeof (UINT64)
|
||||
);
|
||||
MailboxLocationPointer = (UINT64 *) ((UINTN) MailboxLocationPointer + DebugAgentContext->HeapMigrateOffset);
|
||||
//
|
||||
// Update IDT entry to save the location saved mailbox pointer
|
||||
//
|
||||
SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer);
|
||||
//
|
||||
// Enable CPU interrupts so debug timer interrupts can be delivered
|
||||
//
|
||||
EnableInterrupts ();
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
case DEBUG_AGENT_INIT_PEI:
|
||||
//
|
||||
// Check if Debug Agent has initialized before
|
||||
//
|
||||
if (IsDebugAgentInitialzed()) {
|
||||
DEBUG ((EFI_D_WARN, "Debug Agent: It has already initialized in SEC Core!\n"));
|
||||
break;
|
||||
}
|
||||
//
|
||||
// Set up IDT entries
|
||||
//
|
||||
InitializeDebugIdt ();
|
||||
//
|
||||
// Build mailbox in HOB and setup Mailbox Set In Pei flag
|
||||
//
|
||||
Mailbox = AllocateZeroPool (sizeof (DEBUG_AGENT_MAILBOX));
|
||||
MailboxLocation = (UINT64)(UINTN)Mailbox;
|
||||
MailboxLocationPointer = BuildGuidDataHob (
|
||||
&gEfiDebugAgentGuid,
|
||||
&MailboxLocation,
|
||||
sizeof (UINT64)
|
||||
);
|
||||
|
||||
InitializeDebugTimer ();
|
||||
//
|
||||
// Update IDT entry to save the location pointer saved mailbox pointer
|
||||
//
|
||||
SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer);
|
||||
//
|
||||
// Register for a callback once memory has been initialized.
|
||||
// If memery has been ready, the callback funtion will be invoked immediately
|
||||
//
|
||||
Status = PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList[0]);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
//
|
||||
// Set HOB check flag if memory has not been ready yet
|
||||
//
|
||||
if (GetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY) == 0) {
|
||||
SetDebugFlag (DEBUG_AGENT_FLAG_CHECK_MAILBOX_IN_HOB, 1);
|
||||
}
|
||||
|
||||
Phase2Context.Context = Context;
|
||||
Phase2Context.Function = Function;
|
||||
DebugPortInitialize ((VOID *) &Phase2Context, InitializeDebugAgentPhase2);
|
||||
|
||||
FindAndReportModuleImageInfo (4);
|
||||
|
||||
break;
|
||||
|
||||
case DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64:
|
||||
if (Context == NULL) {
|
||||
DEBUG ((EFI_D_ERROR, "DebugAgent: Input parameter Context cannot be NULL!\n"));
|
||||
CpuDeadLoop ();
|
||||
} else {
|
||||
Ia32Idtr = (IA32_DESCRIPTOR *) Context;
|
||||
Ia32IdtEntry = (IA32_IDT_ENTRY *)(Ia32Idtr->Base);
|
||||
MailboxLocationPointer = (UINT64 *) (UINTN) (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow +
|
||||
(Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh << 16));
|
||||
Mailbox = (DEBUG_AGENT_MAILBOX *) (UINTN)(*MailboxLocationPointer);
|
||||
VerifyMailboxChecksum (Mailbox);
|
||||
|
||||
DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize ((VOID *)(UINTN)Mailbox->DebugPortHandle, NULL);
|
||||
UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);
|
||||
//
|
||||
// Set up IDT entries
|
||||
//
|
||||
InitializeDebugIdt ();
|
||||
//
|
||||
// Update IDT entry to save location pointer saved the mailbox pointer
|
||||
//
|
||||
SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer);
|
||||
|
||||
FindAndReportModuleImageInfo (4);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
//
|
||||
// Only DEBUG_AGENT_INIT_PREMEM_SEC and DEBUG_AGENT_INIT_POSTMEM_SEC are allowed for this
|
||||
// Debug Agent library instance.
|
||||
|
@ -294,6 +483,8 @@ InitializeDebugAgent (
|
|||
|
||||
}
|
||||
|
||||
EnableInterrupts ();
|
||||
|
||||
//
|
||||
// If Function is not NULL, invoke it always whatever debug agent was initialized sucesssfully or not.
|
||||
//
|
||||
|
@ -319,11 +510,22 @@ InitializeDebugAgentPhase2 (
|
|||
)
|
||||
{
|
||||
DEBUG_AGENT_PHASE2_CONTEXT *Phase2Context;
|
||||
UINT64 *MailboxLocation;
|
||||
DEBUG_AGENT_MAILBOX *Mailbox;
|
||||
EFI_SEC_PEI_HAND_OFF *SecCoreData;
|
||||
UINT16 BufferSize;
|
||||
UINT64 NewDebugPortHandle;
|
||||
|
||||
Mailbox = GetMailboxPointerInIdtEntry ();
|
||||
Mailbox->DebugPortHandle = (UINT64) (UINTN)DebugPortHandle;
|
||||
Phase2Context = (DEBUG_AGENT_PHASE2_CONTEXT *) Context;
|
||||
MailboxLocation = GetLocationSavedMailboxPointerInIdtEntry ();
|
||||
Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocation);
|
||||
BufferSize = PcdGet16(PcdDebugPortHandleBufferSize);
|
||||
if (Phase2Context->Function == NULL && DebugPortHandle != NULL && BufferSize != 0) {
|
||||
NewDebugPortHandle = (UINT64)(UINTN)AllocateCopyPool (BufferSize, DebugPortHandle);
|
||||
} else {
|
||||
NewDebugPortHandle = (UINT64)(UINTN)DebugPortHandle;
|
||||
}
|
||||
UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, NewDebugPortHandle);
|
||||
|
||||
//
|
||||
// Trigger one software interrupt to inform HOST
|
||||
|
@ -334,9 +536,9 @@ InitializeDebugAgentPhase2 (
|
|||
// If Temporary RAM region is below 128 MB, then send message to
|
||||
// host to disable low memory filtering.
|
||||
//
|
||||
Phase2Context = (DEBUG_AGENT_PHASE2_CONTEXT *) Context;
|
||||
SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Phase2Context->Context;
|
||||
if ((UINTN)SecCoreData->TemporaryRamBase < BASE_128MB && IsHostAttached ()) {
|
||||
SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1);
|
||||
TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Header file for Sec Core Debug Agent Library instance.
|
||||
|
||||
Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -16,7 +16,9 @@
|
|||
#define _SEC_CORE_DEBUG_AGENT_LIB_H_
|
||||
|
||||
#include <PiPei.h>
|
||||
|
||||
#include <Ppi/MemoryDiscovered.h>
|
||||
#include <Library/PeiServicesLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include "DebugAgent.h"
|
||||
|
||||
typedef struct {
|
||||
|
@ -24,5 +26,39 @@ typedef struct {
|
|||
DEBUG_AGENT_CONTINUE Function;
|
||||
} DEBUG_AGENT_PHASE2_CONTEXT;
|
||||
|
||||
/**
|
||||
Caller provided function to be invoked at the end of DebugPortInitialize().
|
||||
|
||||
Refer to the descrption for DebugPortInitialize() for more details.
|
||||
|
||||
@param[in] Context The first input argument of DebugPortInitialize().
|
||||
@param[in] DebugPortHandle Debug port handle created by Debug Communication Libary.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
InitializeDebugAgentPhase2 (
|
||||
IN VOID *Context,
|
||||
IN DEBUG_PORT_HANDLE DebugPortHandle
|
||||
);
|
||||
|
||||
/**
|
||||
Debug Agent provided notify callback function on Memory Discovered PPI.
|
||||
|
||||
@param[in] PeiServices Indirect reference to the PEI Services Table.
|
||||
@param[in] NotifyDescriptor Address of the notification descriptor data structure.
|
||||
@param[in] Ppi Address of the PPI that was installed.
|
||||
|
||||
@retval EFI_SUCCESS If the function completed successfully.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
DebugAgentCallbackMemoryDiscoveredPpi (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
|
||||
IN VOID *Ppi
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## @file
|
||||
# Debug Agent library instance for SEC Core and PEI modules.
|
||||
#
|
||||
# Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
|
@ -70,6 +70,13 @@
|
|||
DebugLib
|
||||
TimerLib
|
||||
PrintLib
|
||||
PeiServicesLib
|
||||
MemoryAllocationLib
|
||||
PeCoffGetEntryPointLib
|
||||
PeCoffExtraActionLib
|
||||
|
||||
[Ppis]
|
||||
gEfiPeiMemoryDiscoveredPpiGuid
|
||||
|
||||
[Guids]
|
||||
gEfiDebugAgentGuid ## PRODUCES ## HOB
|
||||
|
@ -77,4 +84,5 @@
|
|||
[Pcd]
|
||||
gEfiMdePkgTokenSpaceGuid.PcdFSBClock ## CONSUMES
|
||||
gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdExceptionsIgnoredByDebugger ## CONSUMES
|
||||
gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugPortHandleBufferSize ## CONSUMES
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Debug Agent library implementition.
|
||||
|
||||
Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -17,7 +17,25 @@
|
|||
DEBUG_AGENT_MAILBOX *mMailboxPointer = NULL;
|
||||
DEBUG_AGENT_MAILBOX mLocalMailbox;
|
||||
UINTN mSavedDebugRegisters[6];
|
||||
CONST BOOLEAN MultiProcessorDebugSupport = FALSE;
|
||||
IA32_IDT_GATE_DESCRIPTOR mIdtEntryTable[33];
|
||||
BOOLEAN mSkipBreakpoint = FALSE;
|
||||
|
||||
CHAR8 mWarningMsgIgnoreSmmEntryBreak[] = "Ignore smmentrybreak setting for SMI issued during DXE debugging!\r\n";
|
||||
|
||||
/**
|
||||
Check if debug agent support multi-processor.
|
||||
|
||||
@retval TRUE Multi-processor is supported.
|
||||
@retval FALSE Multi-processor is not supported.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
MultiProcessorDebugSupport (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
Read the Attach/Break-in symbols from the debug port.
|
||||
|
@ -41,6 +59,32 @@ DebugReadBreakSymbol (
|
|||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the pointer to Mailbox from the GUIDed HOB.
|
||||
|
||||
@return Pointer to Mailbox.
|
||||
|
||||
**/
|
||||
DEBUG_AGENT_MAILBOX *
|
||||
GetMailboxFromHob (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_HOB_GUID_TYPE *GuidHob;
|
||||
UINT64 *MailboxLocation;
|
||||
DEBUG_AGENT_MAILBOX *Mailbox;
|
||||
|
||||
GuidHob = GetFirstGuidHob (&gEfiDebugAgentGuid);
|
||||
if (GuidHob == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
MailboxLocation = (UINT64 *) (GET_GUID_HOB_DATA(GuidHob));
|
||||
Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocation);
|
||||
VerifyMailboxChecksum (Mailbox);
|
||||
|
||||
return Mailbox;
|
||||
}
|
||||
|
||||
/**
|
||||
Get Debug Agent Mailbox pointer.
|
||||
|
||||
|
@ -52,6 +96,7 @@ GetMailboxPointer (
|
|||
VOID
|
||||
)
|
||||
{
|
||||
VerifyMailboxChecksum (mMailboxPointer);
|
||||
return mMailboxPointer;
|
||||
}
|
||||
|
||||
|
@ -66,7 +111,7 @@ GetDebugPortHandle (
|
|||
VOID
|
||||
)
|
||||
{
|
||||
return (DEBUG_PORT_HANDLE) (UINTN)(mMailboxPointer->DebugPortHandle);
|
||||
return (DEBUG_PORT_HANDLE) (UINTN)(GetMailboxPointer()->DebugPortHandle);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -134,16 +179,76 @@ InitializeDebugAgent (
|
|||
IN DEBUG_AGENT_CONTINUE Function OPTIONAL
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT64 DebugPortHandle;
|
||||
EFI_STATUS Status;
|
||||
UINT64 DebugPortHandle;
|
||||
IA32_IDT_GATE_DESCRIPTOR IdtEntry[33];
|
||||
IA32_DESCRIPTOR IdtDescriptor;
|
||||
IA32_DESCRIPTOR *Ia32Idtr;
|
||||
IA32_IDT_ENTRY *Ia32IdtEntry;
|
||||
IA32_DESCRIPTOR Idtr;
|
||||
UINT16 IdtEntryCount;
|
||||
DEBUG_AGENT_MAILBOX *Mailbox;
|
||||
UINT64 *MailboxLocation;
|
||||
|
||||
switch (InitFlag) {
|
||||
case DEBUG_AGENT_INIT_SMM:
|
||||
Status = EfiGetSystemConfigurationTable (&gEfiDebugAgentGuid, (VOID **) &mMailboxPointer);
|
||||
if (EFI_ERROR (Status) || mMailboxPointer == NULL) {
|
||||
ZeroMem (&mLocalMailbox, sizeof (DEBUG_AGENT_MAILBOX));
|
||||
mMailboxPointer = &mLocalMailbox;
|
||||
//
|
||||
// Check if Debug Agent initialized in DXE phase
|
||||
//
|
||||
Status = EfiGetSystemConfigurationTable (&gEfiDebugAgentGuid, (VOID **) &Mailbox);
|
||||
if (Status == EFI_SUCCESS && Mailbox != NULL) {
|
||||
VerifyMailboxChecksum (Mailbox);
|
||||
mMailboxPointer = Mailbox;
|
||||
break;
|
||||
}
|
||||
//
|
||||
// Check if Debug Agent initialized in SEC/PEI phase
|
||||
//
|
||||
Mailbox = GetMailboxFromHob ();
|
||||
if (Mailbox != NULL) {
|
||||
mMailboxPointer = Mailbox;
|
||||
break;
|
||||
}
|
||||
//
|
||||
// Debug Agent was not initialized before, uset the local mailbox.
|
||||
//
|
||||
ZeroMem (&mLocalMailbox, sizeof (DEBUG_AGENT_MAILBOX));
|
||||
Mailbox = &mLocalMailbox;
|
||||
//
|
||||
// Save original IDT entries
|
||||
//
|
||||
AsmReadIdtr (&IdtDescriptor);
|
||||
CopyMem (&IdtEntry, (VOID *)IdtDescriptor.Base, 33 * sizeof(IA32_IDT_GATE_DESCRIPTOR));
|
||||
//
|
||||
// Initialized Debug Agent
|
||||
//
|
||||
InitializeDebugIdt ();
|
||||
DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize ((DEBUG_PORT_HANDLE) (UINTN)Mailbox->DebugPortHandle, NULL);
|
||||
UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);
|
||||
mMailboxPointer = Mailbox;
|
||||
//
|
||||
// Trigger one software interrupt to inform HOST
|
||||
//
|
||||
TriggerSoftInterrupt (SYSTEM_RESET_SIGNATURE);
|
||||
|
||||
SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1);
|
||||
//
|
||||
// Memory has been ready
|
||||
//
|
||||
if (IsHostAttached ()) {
|
||||
//
|
||||
// Trigger one software interrupt to inform HOST
|
||||
//
|
||||
TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);
|
||||
}
|
||||
//
|
||||
// Find and report PE/COFF image info to HOST
|
||||
//
|
||||
FindAndReportModuleImageInfo (SIZE_4KB);
|
||||
//
|
||||
// Restore saved IDT entries
|
||||
//
|
||||
CopyMem ((VOID *)IdtDescriptor.Base, &IdtEntry, 33 * sizeof(IA32_IDT_GATE_DESCRIPTOR));
|
||||
|
||||
break;
|
||||
|
||||
|
@ -151,14 +256,24 @@ InitializeDebugAgent (
|
|||
SaveDebugRegister ();
|
||||
InitializeDebugIdt ();
|
||||
|
||||
if (mMailboxPointer != NULL) {
|
||||
Mailbox = GetMailboxPointer ();
|
||||
if (GetDebugFlag (DEBUG_AGENT_FLAG_AGENT_IN_PROGRESS) == 1) {
|
||||
//
|
||||
// Initialize debug communication port
|
||||
// If Debug Agent has been communicaton state with HOST, we need skip
|
||||
// any break points set in SMM, set Skip Breakpoint flag
|
||||
//
|
||||
DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize ((DEBUG_PORT_HANDLE) (UINTN)mMailboxPointer->DebugPortHandle, NULL);
|
||||
mMailboxPointer->DebugPortHandle = DebugPortHandle;
|
||||
|
||||
if (mMailboxPointer->DebugFlag.BreakOnNextSmi == 1) {
|
||||
mSkipBreakpoint = TRUE;
|
||||
}
|
||||
if (GetDebugFlag (DEBUG_AGENT_FLAG_BREAK_ON_NEXT_SMI) == 1) {
|
||||
if (mSkipBreakpoint) {
|
||||
//
|
||||
// Print warning message if ignore smm entry break
|
||||
//
|
||||
DebugPortWriteBuffer ((DEBUG_PORT_HANDLE) (UINTN)Mailbox->DebugPortHandle,
|
||||
(UINT8 *)mWarningMsgIgnoreSmmEntryBreak,
|
||||
AsciiStrLen (mWarningMsgIgnoreSmmEntryBreak)
|
||||
);
|
||||
} else {
|
||||
//
|
||||
// If SMM entry break is set, SMM code will be break at here.
|
||||
//
|
||||
|
@ -168,8 +283,56 @@ InitializeDebugAgent (
|
|||
break;
|
||||
|
||||
case DEBUG_AGENT_INIT_EXIT_SMI:
|
||||
Mailbox = GetMailboxPointer ();
|
||||
//
|
||||
// Clear Skip Breakpoint flag
|
||||
//
|
||||
mSkipBreakpoint = FALSE;
|
||||
RestoreDebugRegister ();
|
||||
break;
|
||||
|
||||
case DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64:
|
||||
if (Context == NULL) {
|
||||
DEBUG ((EFI_D_ERROR, "DebugAgent: Input parameter Context cannot be NULL!\n"));
|
||||
CpuDeadLoop ();
|
||||
} else {
|
||||
Ia32Idtr = (IA32_DESCRIPTOR *) Context;
|
||||
Ia32IdtEntry = (IA32_IDT_ENTRY *)(Ia32Idtr->Base);
|
||||
MailboxLocation = (UINT64 *) (UINTN) (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow +
|
||||
(Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh << 16));
|
||||
mMailboxPointer = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocation);
|
||||
VerifyMailboxChecksum (mMailboxPointer);
|
||||
//
|
||||
// Get original IDT address and size.
|
||||
//
|
||||
AsmReadIdtr ((IA32_DESCRIPTOR *) &Idtr);
|
||||
IdtEntryCount = (UINT16) ((Idtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR));
|
||||
if (IdtEntryCount < 33) {
|
||||
Idtr.Limit = (UINT16) (sizeof (IA32_IDT_GATE_DESCRIPTOR) * 33 - 1);
|
||||
Idtr.Base = (UINTN) &mIdtEntryTable;
|
||||
ZeroMem (&mIdtEntryTable, Idtr.Limit + 1);
|
||||
AsmWriteIdtr ((IA32_DESCRIPTOR *) &Idtr);
|
||||
}
|
||||
|
||||
InitializeDebugIdt ();
|
||||
//
|
||||
// Initialize Debug Timer hardware and enable interrupt.
|
||||
//
|
||||
InitializeDebugTimer ();
|
||||
EnableInterrupts ();
|
||||
|
||||
FindAndReportModuleImageInfo (SIZE_4KB);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
//
|
||||
// Only DEBUG_AGENT_INIT_PREMEM_SEC and DEBUG_AGENT_INIT_POSTMEM_SEC are allowed for this
|
||||
// Debug Agent library instance.
|
||||
//
|
||||
DEBUG ((EFI_D_ERROR, "Debug Agent: The InitFlag value is not allowed!\n"));
|
||||
CpuDeadLoop ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## @file
|
||||
# Debug Agent library instance for SMM modules.
|
||||
#
|
||||
# Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
|
@ -15,7 +15,7 @@
|
|||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = SecDebugAgentLib
|
||||
BASE_NAME = SmmDebugAgentLib
|
||||
FILE_GUID = CB07D74C-598F-4268-A5D1-644FB4A481E8
|
||||
MODULE_TYPE = DXE_SMM_DRIVER
|
||||
VERSION_STRING = 0.7
|
||||
|
@ -69,11 +69,14 @@
|
|||
LocalApicLib
|
||||
TimerLib
|
||||
PrintLib
|
||||
PeCoffExtraActionLib
|
||||
PeCoffGetEntryPointLib
|
||||
|
||||
[Guids]
|
||||
gEfiDebugAgentGuid ## CONSUMES ## Configuration Table
|
||||
|
||||
[Pcd]
|
||||
gEfiMdePkgTokenSpaceGuid.PcdFSBClock ## CONSUMES
|
||||
gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdExceptionsIgnoredByDebugger ## CONSUMES
|
||||
gEfiMdePkgTokenSpaceGuid.PcdFSBClock ## CONSUMES
|
||||
## Skip Page Fault exception (14) by default in SMM
|
||||
gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdExceptionsIgnoredByDebugger|0x00004000 ## CONSUMES
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Debug Port Library implementation based on serial port.
|
||||
|
||||
Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -18,6 +18,80 @@
|
|||
#include <Library/SerialPortLib.h>
|
||||
#include <Library/TimerLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
|
||||
#pragma pack(1)
|
||||
//
|
||||
// The internal data structure of DEBUG_PORT_HANDLE, which stores some
|
||||
// important datum which are used across various phases.
|
||||
//
|
||||
typedef struct _SERIAL_DEBUG_PORT_HANDLE{
|
||||
//
|
||||
// Timter settings
|
||||
//
|
||||
UINT64 TimerFrequency;
|
||||
UINT64 TimerCycle;
|
||||
BOOLEAN TimerCountDown;
|
||||
} SERIAL_DEBUG_PORT_HANDLE;
|
||||
#pragma pack()
|
||||
|
||||
//
|
||||
// The global variable which can be used after memory is ready.
|
||||
//
|
||||
SERIAL_DEBUG_PORT_HANDLE mSerialDebugPortHandle;
|
||||
|
||||
/**
|
||||
Check if the timer is timeout.
|
||||
|
||||
@param[in] SerialDebugPortHandle Pointer to Serial Debug port handle
|
||||
@param[in] Timer The start timer from the begin.
|
||||
@param[in] TimeoutTicker Ticker number need time out.
|
||||
|
||||
@return TRUE Timer time out occurs.
|
||||
@retval FALSE Timer does not time out.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
IsTimerTimeout (
|
||||
IN SERIAL_DEBUG_PORT_HANDLE *SerialDebugPortHandle,
|
||||
IN UINT64 Timer,
|
||||
IN UINT64 TimeoutTicker
|
||||
)
|
||||
{
|
||||
UINT64 CurrentTimer;
|
||||
UINT64 Delta;
|
||||
|
||||
CurrentTimer = GetPerformanceCounter ();
|
||||
|
||||
if (SerialDebugPortHandle->TimerCountDown) {
|
||||
//
|
||||
// The timer counter counts down. Check for roll over condition.
|
||||
//
|
||||
if (CurrentTimer < Timer) {
|
||||
Delta = Timer - CurrentTimer;
|
||||
} else {
|
||||
//
|
||||
// Handle one roll-over.
|
||||
//
|
||||
Delta = SerialDebugPortHandle->TimerCycle - (CurrentTimer - Timer);
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// The timer counter counts up. Check for roll over condition.
|
||||
//
|
||||
if (CurrentTimer > Timer) {
|
||||
Delta = CurrentTimer - Timer;
|
||||
} else {
|
||||
//
|
||||
// Handle one roll-over.
|
||||
//
|
||||
Delta = SerialDebugPortHandle->TimerCycle - (Timer - CurrentTimer);
|
||||
}
|
||||
}
|
||||
|
||||
return (BOOLEAN) (Delta >= TimeoutTicker);
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize the debug port.
|
||||
|
@ -62,7 +136,42 @@ DebugPortInitialize (
|
|||
IN DEBUG_PORT_CONTINUE Function
|
||||
)
|
||||
{
|
||||
RETURN_STATUS Status;
|
||||
RETURN_STATUS Status;
|
||||
SERIAL_DEBUG_PORT_HANDLE Handle;
|
||||
SERIAL_DEBUG_PORT_HANDLE *SerialDebugPortHandle;
|
||||
UINT64 TimerStartValue;
|
||||
UINT64 TimerEndValue;
|
||||
|
||||
//
|
||||
// Validate the PCD PcdDebugPortHandleBufferSize value
|
||||
//
|
||||
ASSERT (PcdGet16 (PcdDebugPortHandleBufferSize) == sizeof (SERIAL_DEBUG_PORT_HANDLE));
|
||||
|
||||
if (Context != NULL && Function == NULL) {
|
||||
SerialDebugPortHandle = (SERIAL_DEBUG_PORT_HANDLE *)Context;
|
||||
} else {
|
||||
ZeroMem (&Handle, sizeof (SERIAL_DEBUG_PORT_HANDLE));
|
||||
SerialDebugPortHandle = &Handle;
|
||||
}
|
||||
SerialDebugPortHandle->TimerFrequency = GetPerformanceCounterProperties (
|
||||
&TimerStartValue,
|
||||
&TimerEndValue
|
||||
);
|
||||
DEBUG ((EFI_D_INFO, "Serial Debug Port: TimerFrequency = 0x%lx\n", SerialDebugPortHandle->TimerFrequency));
|
||||
DEBUG ((EFI_D_INFO, "Serial Debug Port: TimerStartValue = 0x%lx\n", TimerStartValue));
|
||||
DEBUG ((EFI_D_INFO, "Serial Debug Port: TimerEndValue = 0x%lx\n", TimerEndValue));
|
||||
|
||||
if (TimerEndValue < TimerStartValue) {
|
||||
SerialDebugPortHandle->TimerCountDown = TRUE;
|
||||
SerialDebugPortHandle->TimerCycle = TimerStartValue - TimerEndValue;
|
||||
} else {
|
||||
SerialDebugPortHandle->TimerCountDown = FALSE;
|
||||
SerialDebugPortHandle->TimerCycle = TimerEndValue - TimerStartValue;
|
||||
}
|
||||
|
||||
if (Function == NULL && Context != NULL) {
|
||||
return (DEBUG_PORT_HANDLE *) Context;
|
||||
}
|
||||
|
||||
Status = SerialPortInitialize ();
|
||||
if (RETURN_ERROR(Status)) {
|
||||
|
@ -70,10 +179,12 @@ DebugPortInitialize (
|
|||
}
|
||||
|
||||
if (Function != NULL) {
|
||||
Function (Context, NULL);
|
||||
Function (Context, SerialDebugPortHandle);
|
||||
} else {
|
||||
CopyMem(&mSerialDebugPortHandle, SerialDebugPortHandle, sizeof (SERIAL_DEBUG_PORT_HANDLE));
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return (DEBUG_PORT_HANDLE)(UINTN)&mSerialDebugPortHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -102,25 +213,62 @@ DebugPortReadBuffer (
|
|||
IN UINTN Timeout
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
INTN Elapsed;
|
||||
SERIAL_DEBUG_PORT_HANDLE *SerialDebugPortHandle;
|
||||
UINTN Index;
|
||||
UINT64 Begin;
|
||||
UINT64 TimeoutTicker;
|
||||
UINT64 TimerRound;
|
||||
|
||||
//
|
||||
// If Handle is NULL, it means memory is ready for use.
|
||||
// Use global variable to store handle value.
|
||||
//
|
||||
if (Handle == NULL) {
|
||||
SerialDebugPortHandle = &mSerialDebugPortHandle;
|
||||
} else {
|
||||
SerialDebugPortHandle = (SERIAL_DEBUG_PORT_HANDLE *)Handle;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < NumberOfBytes; Index ++) {
|
||||
Elapsed = (INTN) Timeout;
|
||||
while (TRUE) {
|
||||
if (SerialPortPoll () || Timeout == 0) {
|
||||
SerialPortRead (Buffer + Index, 1);
|
||||
break;
|
||||
}
|
||||
MicroSecondDelay (1000);
|
||||
Elapsed -= 1000;
|
||||
if (Elapsed < 0) {
|
||||
Begin = 0;
|
||||
TimeoutTicker = 0;
|
||||
TimerRound = 0;
|
||||
if (Timeout != 0) {
|
||||
Begin = GetPerformanceCounter ();
|
||||
TimeoutTicker = DivU64x32 (
|
||||
MultU64x64 (
|
||||
SerialDebugPortHandle->TimerFrequency,
|
||||
Timeout
|
||||
),
|
||||
1000000u
|
||||
);
|
||||
TimerRound = DivU64x64Remainder (
|
||||
TimeoutTicker,
|
||||
DivU64x32 (SerialDebugPortHandle->TimerCycle, 2),
|
||||
&TimeoutTicker
|
||||
);
|
||||
}
|
||||
Index = 0;
|
||||
while (Index < NumberOfBytes) {
|
||||
if (SerialPortPoll () || Timeout == 0) {
|
||||
SerialPortRead (Buffer + Index, 1);
|
||||
Index ++;
|
||||
continue;
|
||||
}
|
||||
if (TimerRound == 0) {
|
||||
if (IsTimerTimeout (SerialDebugPortHandle, Begin, TimeoutTicker)) {
|
||||
//
|
||||
// If time out occurs.
|
||||
//
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (IsTimerTimeout (SerialDebugPortHandle, Begin, DivU64x32 (SerialDebugPortHandle->TimerCycle, 2))) {
|
||||
TimerRound --;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NumberOfBytes;
|
||||
return Index;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## @file
|
||||
# Debug Communication Library instance based on serila port.
|
||||
#
|
||||
# Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
|
@ -36,4 +36,10 @@
|
|||
SerialPortLib
|
||||
TimerLib
|
||||
DebugLib
|
||||
|
||||
BaseMemoryLib
|
||||
BaseLib
|
||||
|
||||
[PCD]
|
||||
## The value of data buffer size used for Serial debug port handle.
|
||||
## It should be equal to sizeof (SERIAL_DEBUG_PORT_HANDLE).
|
||||
gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugPortHandleBufferSize|17
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
Debug Port Library implementation based on usb debug port.
|
||||
|
||||
Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -147,6 +147,12 @@ typedef struct _USB_DEBUG_PORT_HANDLE{
|
|||
// The data buffer. Maximum length is 8 bytes.
|
||||
//
|
||||
UINT8 Data[8];
|
||||
//
|
||||
// Timter settings
|
||||
//
|
||||
UINT64 TimerFrequency;
|
||||
UINT64 TimerCycle;
|
||||
BOOLEAN TimerCountDown;
|
||||
} USB_DEBUG_PORT_HANDLE;
|
||||
#pragma pack()
|
||||
|
||||
|
@ -155,6 +161,58 @@ typedef struct _USB_DEBUG_PORT_HANDLE{
|
|||
//
|
||||
USB_DEBUG_PORT_HANDLE mUsbDebugPortHandle;
|
||||
|
||||
/**
|
||||
Check if the timer is timeout.
|
||||
|
||||
@param[in] UsbDebugPortHandle Pointer to USB Debug port handle
|
||||
@param[in] Timer The start timer from the begin.
|
||||
@param[in] TimeoutTicker Ticker number need time out.
|
||||
|
||||
@return TRUE Timer time out occurs.
|
||||
@retval FALSE Timer does not time out.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
IsTimerTimeout (
|
||||
IN USB_DEBUG_PORT_HANDLE *UsbDebugPortHandle,
|
||||
IN UINT64 Timer,
|
||||
IN UINT64 TimeoutTicker
|
||||
)
|
||||
{
|
||||
UINT64 CurrentTimer;
|
||||
UINT64 Delta;
|
||||
|
||||
CurrentTimer = GetPerformanceCounter ();
|
||||
|
||||
if (UsbDebugPortHandle->TimerCountDown) {
|
||||
//
|
||||
// The timer counter counts down. Check for roll over condition.
|
||||
//
|
||||
if (CurrentTimer < Timer) {
|
||||
Delta = Timer - CurrentTimer;
|
||||
} else {
|
||||
//
|
||||
// Handle one roll-over.
|
||||
//
|
||||
Delta = UsbDebugPortHandle->TimerCycle - (CurrentTimer - Timer);
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// The timer counter counts up. Check for roll over condition.
|
||||
//
|
||||
if (CurrentTimer > Timer) {
|
||||
Delta = CurrentTimer - Timer;
|
||||
} else {
|
||||
//
|
||||
// Handle one roll-over.
|
||||
//
|
||||
Delta = UsbDebugPortHandle->TimerCycle - (Timer - CurrentTimer);
|
||||
}
|
||||
}
|
||||
|
||||
return (BOOLEAN) (Delta >= TimeoutTicker);
|
||||
}
|
||||
|
||||
/**
|
||||
Calculate the usb debug port bar address.
|
||||
|
||||
|
@ -617,28 +675,21 @@ InitializeUsbDebugHardware (
|
|||
if (((MmioRead32((UINTN)&UsbDebugPortRegister->ControlStatus) & (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE))
|
||||
!= (USB_DEBUG_PORT_OWNER | USB_DEBUG_PORT_IN_USE)) || (Handle->Initialized == USBDBG_RESET)) {
|
||||
//
|
||||
// If the host controller is not halted, then halt it.
|
||||
// If the host controller is halted, then reset and restart it.
|
||||
//
|
||||
if ((MmioRead32((UINTN)UsbStatus) & BIT12) == 0) {
|
||||
MmioAnd32((UINTN)UsbCmd, (UINT32)~BIT0);
|
||||
while ((MmioRead32((UINTN)UsbStatus) & BIT12) == 0);
|
||||
}
|
||||
//
|
||||
// reset the host controller.
|
||||
//
|
||||
MmioOr32((UINTN)UsbCmd, BIT1);
|
||||
//
|
||||
// ensure that the host controller is reset.
|
||||
//
|
||||
while (MmioRead32((UINTN)UsbCmd) & BIT1);
|
||||
if ((MmioRead32((UINTN)UsbStatus) & BIT12) != 0) {
|
||||
//
|
||||
// reset the host controller.
|
||||
//
|
||||
MmioOr32((UINTN)UsbCmd, BIT1);
|
||||
//
|
||||
// ensure that the host controller is reset.
|
||||
//
|
||||
while ((MmioRead32((UINTN)UsbCmd) & BIT1) != 0);
|
||||
|
||||
//
|
||||
// Start the host controller if it's not running
|
||||
//
|
||||
if (MmioRead32((UINTN)UsbStatus) & BIT12) {
|
||||
MmioOr32((UINTN)UsbCmd, BIT0);
|
||||
// ensure that the host controller is started (HALTED bit must be cleared)
|
||||
while (MmioRead32((UINTN)UsbStatus) & BIT12);
|
||||
while ((MmioRead32((UINTN)UsbStatus) & BIT12) != 0);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -780,6 +831,9 @@ DebugPortReadBuffer (
|
|||
UINTN Remaining;
|
||||
UINT8 Index;
|
||||
UINT8 Length;
|
||||
UINT64 Begin;
|
||||
UINT64 TimeoutTicker;
|
||||
UINT64 TimerRound;
|
||||
|
||||
if (NumberOfBytes == 0 || Buffer == NULL) {
|
||||
return 0;
|
||||
|
@ -834,14 +888,43 @@ DebugPortReadBuffer (
|
|||
//
|
||||
// If Timeout is equal to 0, then it means it should always wait until all datum required are received.
|
||||
//
|
||||
if (Timeout == 0) {
|
||||
Timeout = 0xFFFFFFFF;
|
||||
Begin = 0;
|
||||
TimeoutTicker = 0;
|
||||
TimerRound = 0;
|
||||
if (Timeout != 0) {
|
||||
Begin = GetPerformanceCounter ();
|
||||
TimeoutTicker = DivU64x32 (
|
||||
MultU64x64 (
|
||||
UsbDebugPortHandle->TimerFrequency,
|
||||
Timeout
|
||||
),
|
||||
1000000u
|
||||
);
|
||||
TimerRound = DivU64x64Remainder (
|
||||
TimeoutTicker,
|
||||
DivU64x32 (UsbDebugPortHandle->TimerCycle, 2),
|
||||
&TimeoutTicker
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Read remaining data by executing one or more usb debug transfer transactions at usb debug port hw.
|
||||
//
|
||||
while ((Total < NumberOfBytes) && (Timeout != 0)) {
|
||||
while (Total < NumberOfBytes) {
|
||||
if (Timeout != 0) {
|
||||
if (TimerRound == 0) {
|
||||
if (IsTimerTimeout (UsbDebugPortHandle, Begin, TimeoutTicker)) {
|
||||
//
|
||||
// If time out occurs.
|
||||
//
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (IsTimerTimeout (UsbDebugPortHandle, Begin, DivU64x32 (UsbDebugPortHandle->TimerCycle, 2))) {
|
||||
TimerRound --;
|
||||
}
|
||||
}
|
||||
}
|
||||
Remaining = NumberOfBytes - Total;
|
||||
if (Remaining >= USB_DEBUG_PORT_MAX_PACKET_SIZE) {
|
||||
Status = UsbDebugPortIn(UsbDebugPortRegister, Buffer + Total, &Received, INPUT_PID, 0x7f, 0x82, UsbDebugPortHandle->BulkInToggle);
|
||||
|
@ -850,46 +933,44 @@ DebugPortReadBuffer (
|
|||
return Total;
|
||||
}
|
||||
} else {
|
||||
Status = UsbDebugPortIn(UsbDebugPortRegister, &UsbDebugPortHandle->Data[0], &Received, INPUT_PID, 0x7f, 0x82, UsbDebugPortHandle->BulkInToggle);
|
||||
Status = UsbDebugPortIn(UsbDebugPortRegister, &UsbDebugPortHandle->Data[0], &Received, INPUT_PID, 0x7f, 0x82, UsbDebugPortHandle->BulkInToggle);
|
||||
|
||||
if (RETURN_ERROR(Status)) {
|
||||
return Total;
|
||||
}
|
||||
|
||||
UsbDebugPortHandle->DataCount = Received;
|
||||
|
||||
if (Remaining <= Received) {
|
||||
Length = (UINT8)Remaining;
|
||||
} else {
|
||||
Length = (UINT8)Received;
|
||||
}
|
||||
|
||||
//
|
||||
// Copy required data from the data buffer to user buffer.
|
||||
//
|
||||
for (Index = 0; Index < Length; Index++) {
|
||||
(Buffer + Total)[Index] = UsbDebugPortHandle->Data[Index];
|
||||
UsbDebugPortHandle->DataCount--;
|
||||
}
|
||||
|
||||
//
|
||||
// reorder the data buffer to make available data arranged from the beginning of the data buffer.
|
||||
//
|
||||
for (Index = 0; Index < Received - Length; Index++) {
|
||||
if (Length + Index >= 8) {
|
||||
return 0;
|
||||
}
|
||||
UsbDebugPortHandle->Data[Index] = UsbDebugPortHandle->Data[Length + Index];
|
||||
}
|
||||
//
|
||||
// fixup the real received length in Buffer.
|
||||
//
|
||||
Received = Length;
|
||||
if (RETURN_ERROR(Status)) {
|
||||
return Total;
|
||||
}
|
||||
UsbDebugPortHandle->BulkInToggle ^= 1;
|
||||
|
||||
Total += Received;
|
||||
Timeout -= 100;
|
||||
UsbDebugPortHandle->DataCount = Received;
|
||||
|
||||
if (Remaining <= Received) {
|
||||
Length = (UINT8)Remaining;
|
||||
} else {
|
||||
Length = (UINT8)Received;
|
||||
}
|
||||
|
||||
//
|
||||
// Copy required data from the data buffer to user buffer.
|
||||
//
|
||||
for (Index = 0; Index < Length; Index++) {
|
||||
(Buffer + Total)[Index] = UsbDebugPortHandle->Data[Index];
|
||||
UsbDebugPortHandle->DataCount--;
|
||||
}
|
||||
|
||||
//
|
||||
// reorder the data buffer to make available data arranged from the beginning of the data buffer.
|
||||
//
|
||||
for (Index = 0; Index < Received - Length; Index++) {
|
||||
if (Length + Index >= 8) {
|
||||
return 0;
|
||||
}
|
||||
UsbDebugPortHandle->Data[Index] = UsbDebugPortHandle->Data[Length + Index];
|
||||
}
|
||||
//
|
||||
// fixup the real received length in Buffer.
|
||||
//
|
||||
Received = Length;
|
||||
}
|
||||
UsbDebugPortHandle->BulkInToggle ^= 1;
|
||||
Total += Received;
|
||||
}
|
||||
|
||||
return Total;
|
||||
|
@ -1118,11 +1199,40 @@ DebugPortInitialize (
|
|||
{
|
||||
RETURN_STATUS Status;
|
||||
USB_DEBUG_PORT_HANDLE Handle;
|
||||
if (Function == NULL && Context != NULL) {
|
||||
return (DEBUG_PORT_HANDLE *) Context;
|
||||
USB_DEBUG_PORT_HANDLE *UsbDebugPortHandle;
|
||||
UINT64 TimerStartValue;
|
||||
UINT64 TimerEndValue;
|
||||
//
|
||||
// Validate the PCD PcdDebugPortHandleBufferSize value
|
||||
//
|
||||
ASSERT (PcdGet16 (PcdDebugPortHandleBufferSize) == sizeof (USB_DEBUG_PORT_HANDLE));
|
||||
|
||||
if (Function == NULL && Context != NULL) {
|
||||
UsbDebugPortHandle = (USB_DEBUG_PORT_HANDLE *)Context;
|
||||
} else {
|
||||
ZeroMem(&Handle, sizeof (USB_DEBUG_PORT_HANDLE));
|
||||
UsbDebugPortHandle = &Handle;
|
||||
}
|
||||
|
||||
ZeroMem(&Handle, sizeof (USB_DEBUG_PORT_HANDLE));
|
||||
UsbDebugPortHandle->TimerFrequency = GetPerformanceCounterProperties (
|
||||
&TimerStartValue,
|
||||
&TimerEndValue
|
||||
);
|
||||
DEBUG ((EFI_D_INFO, "USB Debug Port: TimerFrequency = 0x%lx\n", UsbDebugPortHandle->TimerFrequency));
|
||||
DEBUG ((EFI_D_INFO, "USB Debug Port: TimerStartValue = 0x%lx\n", TimerStartValue));
|
||||
DEBUG ((EFI_D_INFO, "USB Debug Port: TimerEndValue = 0x%lx\n", TimerEndValue));
|
||||
|
||||
if (TimerEndValue < TimerStartValue) {
|
||||
UsbDebugPortHandle->TimerCountDown = TRUE;
|
||||
UsbDebugPortHandle->TimerCycle = TimerStartValue - TimerEndValue;
|
||||
} else {
|
||||
UsbDebugPortHandle->TimerCountDown = FALSE;
|
||||
UsbDebugPortHandle->TimerCycle = TimerEndValue - TimerStartValue;
|
||||
}
|
||||
|
||||
if (Function == NULL && Context != NULL) {
|
||||
return (DEBUG_PORT_HANDLE *) Context;
|
||||
}
|
||||
|
||||
Status = CalculateUsbDebugPortBar(&Handle.DebugPortOffset, &Handle.DebugPortBarNumber);
|
||||
if (RETURN_ERROR (Status)) {
|
||||
|
@ -1156,7 +1266,7 @@ DebugPortInitialize (
|
|||
DEBUG ((EFI_D_ERROR, "UsbDbg: Start EHCI debug port initialization!\n"));
|
||||
Status = InitializeUsbDebugHardware (&Handle);
|
||||
if (RETURN_ERROR(Status)) {
|
||||
DEBUG ((EFI_D_ERROR, "UsbDbg: Initialization failed, please check if USB debug cable is plugged into EHCI debug port correctly!\n"));
|
||||
DEBUG ((EFI_D_ERROR, "UsbDbg: Failed, please check if USB debug cable is plugged into EHCI debug port correctly!\n"));
|
||||
goto Exit;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## @file
|
||||
# Debug Communication Library instance based on usb debug port.
|
||||
#
|
||||
# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
|
@ -44,6 +44,9 @@
|
|||
## The pci address of ehci host controller, in which usb debug feature is enabled.
|
||||
## The format of pci address please refer to SourceLevelDebugPkg.dec
|
||||
gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdUsbEhciPciAddress
|
||||
## The value of data buffer size used for USB debug port handle.
|
||||
## It should be equal to sizeof (USB_DEBUG_PORT_HANDLE).
|
||||
gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugPortHandleBufferSize|40
|
||||
|
||||
[LibraryClasses]
|
||||
TimerLib
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php.
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
# Module Name:
|
||||
#
|
||||
# IntHandler.S
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
# Assembly interrupt handler function.
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
ASM_GLOBAL ASM_PFX(AsmInterruptHandle)
|
||||
|
||||
.text
|
||||
ASM_PFX(AsmInterruptHandle):
|
||||
cli
|
||||
movb $1, %al
|
||||
iretl
|
|
@ -0,0 +1,33 @@
|
|||
;------------------------------------------------------------------------------
|
||||
;
|
||||
; Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
|
||||
; This program and the accompanying materials
|
||||
; are licensed and made available under the terms and conditions of the BSD License
|
||||
; which accompanies this distribution. The full text of the license may be found at
|
||||
; http://opensource.org/licenses/bsd-license.php.
|
||||
;
|
||||
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
;
|
||||
; Module Name:
|
||||
;
|
||||
; IntHandler.asm
|
||||
;
|
||||
; Abstract:
|
||||
;
|
||||
; Assembly interrupt handler function.
|
||||
;
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
|
||||
.686p
|
||||
.model flat,c
|
||||
|
||||
public AsmInterruptHandle
|
||||
|
||||
.code
|
||||
AsmInterruptHandle:
|
||||
cli
|
||||
mov al, 1
|
||||
iretd
|
||||
END
|
|
@ -0,0 +1,96 @@
|
|||
/** @file
|
||||
Ia32 arch functions to access IDT vector.
|
||||
|
||||
Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <PeCoffExtraActionLib.h>
|
||||
|
||||
/**
|
||||
Read IDT entry to check if IDT entries are setup by Debug Agent.
|
||||
|
||||
@param[in] IdtDescriptor Pointer to IDT Descriptor.
|
||||
|
||||
@retval TRUE IDT entries were setup by Debug Agent.
|
||||
@retval FALSE IDT entries were not setuo by Debug Agent.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
CheckDebugAgentHandler (
|
||||
IN IA32_DESCRIPTOR *IdtDescriptor
|
||||
)
|
||||
{
|
||||
IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
|
||||
UINTN InterruptHandler;
|
||||
|
||||
IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor->Base;
|
||||
if (IdtEntry == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
InterruptHandler = IdtEntry[0].Bits.OffsetLow + (IdtEntry[0].Bits.OffsetHigh << 16);
|
||||
if (InterruptHandler >= 4 && *(UINT32 *)(InterruptHandler - 4) == AGENT_HANDLER_SIGNATURE) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Save IDT entry for INT1 and update it.
|
||||
|
||||
@param[in] IdtDescriptor Pointer to IDT Descriptor.
|
||||
@param[out] SavedIdtEntry Original IDT entry returned.
|
||||
|
||||
**/
|
||||
VOID
|
||||
SaveAndUpdateIdtEntry1 (
|
||||
IN IA32_DESCRIPTOR *IdtDescriptor,
|
||||
OUT IA32_IDT_GATE_DESCRIPTOR *SavedIdtEntry
|
||||
)
|
||||
{
|
||||
IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
|
||||
UINT16 CodeSegment;
|
||||
UINTN InterruptHandler;
|
||||
|
||||
IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor->Base;
|
||||
CopyMem (SavedIdtEntry, &IdtEntry[1], sizeof (IA32_IDT_GATE_DESCRIPTOR));
|
||||
|
||||
//
|
||||
// Use current CS as the segment selector of interrupt gate in IDT
|
||||
//
|
||||
CodeSegment = AsmReadCs ();
|
||||
|
||||
InterruptHandler = (UINTN) &AsmInterruptHandle;
|
||||
IdtEntry[1].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;
|
||||
IdtEntry[1].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);
|
||||
IdtEntry[1].Bits.Selector = CodeSegment;
|
||||
IdtEntry[1].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
|
||||
}
|
||||
|
||||
/**
|
||||
Restore IDT entry for INT1.
|
||||
|
||||
@param[in] IdtDescriptor Pointer to IDT Descriptor.
|
||||
@param[in] RestoredIdtEntry IDT entry to be restored.
|
||||
|
||||
**/
|
||||
VOID
|
||||
RestoreIdtEntry1 (
|
||||
IN IA32_DESCRIPTOR *IdtDescriptor,
|
||||
IN IA32_IDT_GATE_DESCRIPTOR *RestoredIdtEntry
|
||||
)
|
||||
{
|
||||
IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
|
||||
|
||||
IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor->Base;
|
||||
CopyMem (&IdtEntry[1], RestoredIdtEntry, sizeof (IA32_IDT_GATE_DESCRIPTOR));
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
/** @file
|
||||
PE/Coff Extra Action library instances.
|
||||
|
||||
Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
|
@ -12,17 +12,7 @@
|
|||
|
||||
**/
|
||||
|
||||
#include <Base.h>
|
||||
#include <Library/PeCoffExtraActionLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
|
||||
#include <ImageDebugSupport.h>
|
||||
|
||||
#define DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT 1
|
||||
#define DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3 2
|
||||
#include <PeCoffExtraActionLib.h>
|
||||
|
||||
/**
|
||||
Check if the hardware breakpoint in Drx is enabled by checking the Lx and Gx bit in Dr7.
|
||||
|
@ -62,16 +52,19 @@ PeCoffLoaderExtraActionCommon (
|
|||
IN UINTN Signature
|
||||
)
|
||||
{
|
||||
BOOLEAN InterruptState;
|
||||
UINTN Dr0;
|
||||
UINTN Dr1;
|
||||
UINTN Dr2;
|
||||
UINTN Dr3;
|
||||
UINTN Dr7;
|
||||
UINTN Cr4;
|
||||
UINTN NewDr7;
|
||||
UINT8 LoadImageMethod;
|
||||
UINT8 DebugAgentStatus;
|
||||
BOOLEAN InterruptState;
|
||||
UINTN Dr0;
|
||||
UINTN Dr1;
|
||||
UINTN Dr2;
|
||||
UINTN Dr3;
|
||||
UINTN Dr7;
|
||||
UINTN Cr4;
|
||||
UINTN NewDr7;
|
||||
UINT8 LoadImageMethod;
|
||||
UINT8 DebugAgentStatus;
|
||||
IA32_DESCRIPTOR IdtDescriptor;
|
||||
IA32_IDT_GATE_DESCRIPTOR OriginalIdtEntry;
|
||||
BOOLEAN IdtEntryHooked;
|
||||
|
||||
ASSERT (ImageContext != NULL);
|
||||
|
||||
|
@ -84,6 +77,23 @@ PeCoffLoaderExtraActionCommon (
|
|||
//
|
||||
InterruptState = SaveAndDisableInterrupts ();
|
||||
|
||||
IdtEntryHooked = FALSE;
|
||||
LoadImageMethod = PcdGet8 (PcdDebugLoadImageMethod);
|
||||
AsmReadIdtr (&IdtDescriptor);
|
||||
if (!CheckDebugAgentHandler (&IdtDescriptor)) {
|
||||
if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) {
|
||||
//
|
||||
// Do not trigger INT3 if Debug Agent did not setup IDT entries.
|
||||
//
|
||||
return;
|
||||
}
|
||||
//
|
||||
// Save and update IDT entry for INT1
|
||||
//
|
||||
SaveAndUpdateIdtEntry1 (&IdtDescriptor, &OriginalIdtEntry);
|
||||
IdtEntryHooked = TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// Save Debug Register State
|
||||
//
|
||||
|
@ -108,7 +118,6 @@ PeCoffLoaderExtraActionCommon (
|
|||
AsmWriteDr2 ((UINTN) ImageContext);
|
||||
AsmWriteDr3 (IO_PORT_BREAKPOINT_ADDRESS);
|
||||
|
||||
LoadImageMethod = PcdGet8 (PcdDebugLoadImageMethod);
|
||||
if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) {
|
||||
AsmWriteDr7 (0x20000480);
|
||||
AsmWriteCr4 (Cr4 | BIT3);
|
||||
|
@ -156,6 +165,12 @@ PeCoffLoaderExtraActionCommon (
|
|||
AsmWriteDr7 (Dr7);
|
||||
}
|
||||
//
|
||||
// Restore original IDT entry for INT1 if it was hooked.
|
||||
//
|
||||
if (IdtEntryHooked) {
|
||||
RestoreIdtEntry1 (&IdtDescriptor, &OriginalIdtEntry);
|
||||
}
|
||||
//
|
||||
// Restore the interrupt state
|
||||
//
|
||||
SetInterruptState (InterruptState);
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/** @file
|
||||
PE/Coff Extra Action library instances, it will report image debug info.
|
||||
|
||||
Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef _PE_COFF_EXTRA_ACTION_LIB_H_
|
||||
#define _PE_COFF_EXTRA_ACTION_LIB_H_
|
||||
|
||||
#include <Base.h>
|
||||
#include <Library/PeCoffExtraActionLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
|
||||
#include <ImageDebugSupport.h>
|
||||
|
||||
#define DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT 1
|
||||
#define DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3 2
|
||||
|
||||
extern UINTN AsmInterruptHandle;
|
||||
|
||||
/**
|
||||
Read IDT entry to check if IDT entries are setup by Debug Agent.
|
||||
|
||||
@param[in] IdtDescriptor Pointer to IDT Descriptor.
|
||||
|
||||
@retval TRUE IDT entries were setup by Debug Agent.
|
||||
@retval FALSE IDT entries were not setuo by Debug Agent.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
CheckDebugAgentHandler (
|
||||
IN IA32_DESCRIPTOR *IdtDescriptor
|
||||
);
|
||||
|
||||
/**
|
||||
Save IDT entry for INT1 and update it.
|
||||
|
||||
@param[in] IdtDescriptor Pointer to IDT Descriptor.
|
||||
@param[out] SavedIdtEntry Original IDT entry returned.
|
||||
|
||||
**/
|
||||
VOID
|
||||
SaveAndUpdateIdtEntry1 (
|
||||
IN IA32_DESCRIPTOR *IdtDescriptor,
|
||||
OUT IA32_IDT_GATE_DESCRIPTOR *SavedIdtEntry
|
||||
);
|
||||
|
||||
/**
|
||||
Restore IDT entry for INT1.
|
||||
|
||||
@param[in] IdtDescriptor Pointer to IDT Descriptor.
|
||||
@param[in] RestoredIdtEntry IDT entry to be restored.
|
||||
|
||||
**/
|
||||
VOID
|
||||
RestoreIdtEntry1 (
|
||||
IN IA32_DESCRIPTOR *IdtDescriptor,
|
||||
IN IA32_IDT_GATE_DESCRIPTOR *RestoredIdtEntry
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
## @file
|
||||
# PeCoffExtraAction Library to support source level debug.
|
||||
#
|
||||
# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
|
@ -28,8 +28,19 @@
|
|||
#
|
||||
|
||||
[Sources.common]
|
||||
PeCoffExtraActionLib.h
|
||||
PeCoffExtraActionLib.c
|
||||
|
||||
[Sources.IA32]
|
||||
Ia32/IntHandlerFuncs.c
|
||||
Ia32/IntHandler.asm | MSFT
|
||||
Ia32/IntHandler.S | GCC
|
||||
|
||||
[Sources.X64]
|
||||
X64/IntHandlerFuncs.c
|
||||
X64/IntHandler.asm | MSFT
|
||||
X64/IntHandler.S | GCC
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
SourceLevelDebugPkg/SourceLevelDebugPkg.dec
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
# which accompanies this distribution. The full text of the license may be found at
|
||||
# http://opensource.org/licenses/bsd-license.php.
|
||||
#
|
||||
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#
|
||||
# Module Name:
|
||||
#
|
||||
# IntHandler.S
|
||||
#
|
||||
# Abstract:
|
||||
#
|
||||
# Assembly interrupt handler function.
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
ASM_GLOBAL ASM_PFX(AsmInterruptHandle)
|
||||
|
||||
.text
|
||||
ASM_PFX(AsmInterruptHandle):
|
||||
cli
|
||||
movb $1, %al
|
||||
iretq
|
|
@ -0,0 +1,29 @@
|
|||
;------------------------------------------------------------------------------
|
||||
;
|
||||
; Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
|
||||
; This program and the accompanying materials
|
||||
; are licensed and made available under the terms and conditions of the BSD License
|
||||
; which accompanies this distribution. The full text of the license may be found at
|
||||
; http://opensource.org/licenses/bsd-license.php.
|
||||
;
|
||||
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
;
|
||||
; Module Name:
|
||||
;
|
||||
; IntHandler.asm
|
||||
;
|
||||
; Abstract:
|
||||
;
|
||||
; Assembly interrupt handler function.
|
||||
;
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
public AsmInterruptHandle
|
||||
|
||||
.code
|
||||
AsmInterruptHandle:
|
||||
cli
|
||||
mov al, 1
|
||||
iretq
|
||||
END
|
|
@ -0,0 +1,98 @@
|
|||
/** @file
|
||||
X64 arch function to access IDT vector.
|
||||
|
||||
Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php.
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
**/
|
||||
|
||||
#include <PeCoffExtraActionLib.h>
|
||||
|
||||
/**
|
||||
Read IDT entry to check if IDT entries are setup by Debug Agent.
|
||||
|
||||
@param[in] IdtDescriptor Pointer to IDT Descriptor.
|
||||
|
||||
@retval TRUE IDT entries were setup by Debug Agent.
|
||||
@retval FALSE IDT entries were not setuo by Debug Agent.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
CheckDebugAgentHandler (
|
||||
IN IA32_DESCRIPTOR *IdtDescriptor
|
||||
)
|
||||
{
|
||||
IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
|
||||
UINTN InterruptHandler;
|
||||
|
||||
IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor->Base;
|
||||
if (IdtEntry == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
InterruptHandler = IdtEntry[0].Bits.OffsetLow + (((UINTN)IdtEntry[0].Bits.OffsetHigh) << 16) +
|
||||
(((UINTN)IdtEntry[0].Bits.OffsetUpper) << 32);
|
||||
if (InterruptHandler >= 4 && *(UINT32 *)(InterruptHandler - 4) == AGENT_HANDLER_SIGNATURE) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Save IDT entry for INT1 and update it.
|
||||
|
||||
@param[in] IdtDescriptor Pointer to IDT Descriptor.
|
||||
@param[out] SavedIdtEntry Original IDT entry returned.
|
||||
|
||||
**/
|
||||
VOID
|
||||
SaveAndUpdateIdtEntry1 (
|
||||
IN IA32_DESCRIPTOR *IdtDescriptor,
|
||||
OUT IA32_IDT_GATE_DESCRIPTOR *SavedIdtEntry
|
||||
)
|
||||
{
|
||||
IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
|
||||
UINT16 CodeSegment;
|
||||
UINTN InterruptHandler;
|
||||
|
||||
IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor->Base;
|
||||
CopyMem (SavedIdtEntry, &IdtEntry[1], sizeof (IA32_IDT_GATE_DESCRIPTOR));
|
||||
|
||||
//
|
||||
// Use current CS as the segment selector of interrupt gate in IDT
|
||||
//
|
||||
CodeSegment = AsmReadCs ();
|
||||
|
||||
InterruptHandler = (UINTN) &AsmInterruptHandle;
|
||||
IdtEntry[1].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;
|
||||
IdtEntry[1].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);
|
||||
IdtEntry[1].Bits.OffsetUpper = (UINT32)((UINTN)InterruptHandler >> 32);
|
||||
IdtEntry[1].Bits.Selector = CodeSegment;
|
||||
IdtEntry[1].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
|
||||
}
|
||||
|
||||
/**
|
||||
Restore IDT entry for INT1.
|
||||
|
||||
@param[in] IdtDescriptor Pointer to IDT Descriptor.
|
||||
@param[in] RestoredIdtEntry IDT entry to be restored.
|
||||
|
||||
**/
|
||||
VOID
|
||||
RestoreIdtEntry1 (
|
||||
IN IA32_DESCRIPTOR *IdtDescriptor,
|
||||
IN IA32_IDT_GATE_DESCRIPTOR *RestoredIdtEntry
|
||||
)
|
||||
{
|
||||
IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
|
||||
|
||||
IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor->Base;
|
||||
CopyMem (&IdtEntry[1], RestoredIdtEntry, sizeof (IA32_IDT_GATE_DESCRIPTOR));
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
# and host, PeCoffExtraActionLib instance to report symbol path information,
|
||||
# etc.
|
||||
#
|
||||
# Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
# This program and the accompanying materials are licensed and made available under
|
||||
# the terms and conditions of the BSD License that accompanies this distribution.
|
||||
# The full text of the license may be found at
|
||||
|
@ -22,7 +22,7 @@
|
|||
DEC_SPECIFICATION = 0x00010005
|
||||
PACKAGE_NAME = SourceLevelDebugPkg
|
||||
PACKAGE_GUID = DBF00C27-D8D7-443d-918B-4E85CDA1373B
|
||||
PACKAGE_VERSION = 0.80
|
||||
PACKAGE_VERSION = 0.85
|
||||
|
||||
[Includes]
|
||||
Include
|
||||
|
@ -72,3 +72,7 @@
|
|||
## 1: Use I/O Port 84 to issue hardware break point
|
||||
## 2: Use INT3 to issue software break point
|
||||
gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|0x1|UINT8|0x00000005
|
||||
|
||||
## The data buffer size used by debug port in debug communication library.
|
||||
gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugPortHandleBufferSize|0x0|UINT16|0x00000006
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
# Source Level Debug Package.
|
||||
#
|
||||
# Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# This program and the accompanying materials
|
||||
# are licensed and made available under the terms and conditions of the BSD License
|
||||
|
@ -22,7 +22,7 @@
|
|||
[Defines]
|
||||
PLATFORM_NAME = SourceLevelDebugPkg
|
||||
PLATFORM_GUID = 38C85805-883F-4ee8-A854-95B966ED73AA
|
||||
PLATFORM_VERSION = 0.80
|
||||
PLATFORM_VERSION = 0.85
|
||||
DSC_SPECIFICATION = 0x00010005
|
||||
OUTPUT_DIRECTORY = Build/SourceLevelDebugPkg
|
||||
SUPPORTED_ARCHITECTURES = IA32|X64
|
||||
|
@ -30,13 +30,43 @@
|
|||
SKUID_IDENTIFIER = DEFAULT
|
||||
|
||||
[LibraryClasses.common]
|
||||
DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf
|
||||
DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
|
||||
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
|
||||
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
|
||||
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
|
||||
TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
|
||||
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
|
||||
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
|
||||
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
|
||||
SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
|
||||
LocalApicLib|UefiCpuPkg/Library/BaseXApicLib/BaseXApicLib.inf
|
||||
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
|
||||
SerialPortLib|MdeModulePkg/Library/BaseSerialPortLib16550/BaseSerialPortLib16550.inf
|
||||
PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
|
||||
TimerLib|UefiCpuPkg/Library/SecPeiDxeTimerLibUefiCpu/SecPeiDxeTimerLibUefiCpu.inf
|
||||
ResetSystemLib|PcAtChipsetPkg/Library/ResetSystemLib/ResetSystemLib.inf
|
||||
|
||||
PlatformHookLib|MdeModulePkg/Library/BasePlatformHookLibNull/BasePlatformHookLibNull.inf
|
||||
|
||||
DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf
|
||||
#DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibUsb/DebugCommunicationLibUsb.inf
|
||||
|
||||
[LibraryClasses.common.PEIM]
|
||||
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
|
||||
PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
|
||||
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
|
||||
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
|
||||
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
|
||||
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
|
||||
|
||||
[LibraryClasses.common.DXE_DRIVER]
|
||||
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
|
||||
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
|
||||
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
|
||||
UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
|
||||
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
|
||||
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
|
||||
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
|
||||
DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
|
||||
|
||||
###################################################################################################
|
||||
#
|
||||
|
@ -64,4 +94,5 @@
|
|||
SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf
|
||||
SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf
|
||||
SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgentLib.inf
|
||||
|
||||
SourceLevelDebugPkg/DebugAgentPei/DebugAgentPei.inf
|
||||
SourceLevelDebugPkg/DebugAgentDxe/DebugAgentDxe.inf
|
||||
|
|
Loading…
Reference in New Issue