mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-10-31 17:09:09 +00:00 
			
		
		
		
	 18b144ea42
			
		
	
	
		18b144ea42
		
	
	
	
	
		
			
			git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10867 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			248 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			248 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Debug Agent library implementition for Dxe Core and Dxr modules.
 | |
| 
 | |
|   Copyright (c) 2010, 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 "DxeDebugAgentLib.h"
 | |
| 
 | |
| DEBUG_AGENT_MAILBOX          mMailbox;
 | |
| 
 | |
| DEBUG_AGENT_MAILBOX          *mMailboxPointer;
 | |
| 
 | |
| IA32_IDT_GATE_DESCRIPTOR     mIdtEntryTable[33];
 | |
| 
 | |
| BOOLEAN                      mConfigurationTableNeeded = FALSE;
 | |
| 
 | |
| CONST BOOLEAN                MultiProcessorDebugSupport = TRUE;
 | |
| 
 | |
| /**
 | |
|   Constructor allocates the NVS memory to store Mailbox and install configuration table
 | |
|   in system table to store its pointer.
 | |
| 
 | |
|   @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  RETURN_OUT_OF_RESOURCES   No enough memory to allocated.
 | |
| 
 | |
| **/
 | |
| RETURN_STATUS
 | |
| EFIAPI
 | |
| DxeDebugAgentLibConstructor (
 | |
|   IN EFI_HANDLE        ImageHandle,
 | |
|   IN EFI_SYSTEM_TABLE  *SystemTable
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                  Status;
 | |
|   EFI_PHYSICAL_ADDRESS        Address;
 | |
| 
 | |
|   if (!mConfigurationTableNeeded) {
 | |
|     return RETURN_SUCCESS;
 | |
|   }
 | |
| 
 | |
|   Address = 0;
 | |
|   Status = gBS->AllocatePages (
 | |
|                   AllocateAnyPages,
 | |
|                   EfiACPIMemoryNVS,
 | |
|                   EFI_SIZE_TO_PAGES (sizeof (DEBUG_AGENT_MAILBOX)),
 | |
|                   &Address
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   CopyMem (
 | |
|     (UINT8 *) (UINTN) Address,
 | |
|     (UINT8 *) (UINTN) mMailboxPointer,
 | |
|     sizeof (DEBUG_AGENT_MAILBOX)
 | |
|     );
 | |
| 
 | |
|   mMailboxPointer = (DEBUG_AGENT_MAILBOX *) (UINTN) Address;
 | |
| 
 | |
|   return gBS->InstallConfigurationTable (&gEfiDebugAgentGuid, (VOID *) mMailboxPointer);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Get the pointer to Mailbox from the GUIDed HOB.
 | |
| 
 | |
|   @param[in]  HobStart      The starting HOB pointer to search from.
 | |
| 
 | |
|   @return Pointer to Mailbox.
 | |
| 
 | |
| **/
 | |
| DEBUG_AGENT_MAILBOX *
 | |
| GetMailboxFromHob (
 | |
|   IN VOID                  *HobStart
 | |
|   )
 | |
| {
 | |
|   EFI_HOB_GUID_TYPE        *GuidHob;
 | |
| 
 | |
|   GuidHob = GetNextGuidHob (&gEfiDebugAgentGuid, HobStart);
 | |
|   if (GuidHob == NULL) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   return (DEBUG_AGENT_MAILBOX *) (GET_GUID_HOB_DATA(GuidHob));
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Get Debug Agent Mailbox pointer.
 | |
| 
 | |
|   @return Mailbox pointer.
 | |
| 
 | |
| **/
 | |
| DEBUG_AGENT_MAILBOX *
 | |
| GetMailboxPointer (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   return mMailboxPointer;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Get debug port handle.
 | |
| 
 | |
|   @return Debug port handle.
 | |
| 
 | |
| **/
 | |
| DEBUG_PORT_HANDLE
 | |
| GetDebugPortHandle (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   return (DEBUG_PORT_HANDLE) (UINTN)(mMailboxPointer->DebugPortHandle);
 | |
| }
 | |
| 
 | |
|  
 | |
| /**
 | |
|   Initialize debug agent.
 | |
| 
 | |
|   This function is used to set up debug enviroment for DXE phase.
 | |
| 
 | |
|   If this function is called by DXE Core, Context must be the pointer
 | |
|   to HOB list which will be used to get GUIDed HOB. It will enable
 | |
|   interrupt to support break-in feature.
 | |
|   If this function is called by DXE module, Context must be NULL. It
 | |
|   will enable interrupt to support break-in feature.
 | |
| 
 | |
|   @param[in] InitFlag     Init flag is used to decide initialize process.
 | |
|   @param[in] Context      Context needed according to InitFlag.
 | |
|   @param[in] Function     Continue function called by debug agent library; it was
 | |
|                           optional.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| InitializeDebugAgent (
 | |
|   IN UINT32                InitFlag,
 | |
|   IN VOID                  *Context, OPTIONAL
 | |
|   IN DEBUG_AGENT_CONTINUE  Function  OPTIONAL
 | |
|   )
 | |
| {
 | |
|   DEBUG_AGENT_MAILBOX          *Mailbox;
 | |
|   IA32_DESCRIPTOR              Idtr;
 | |
|   UINT16                       IdtEntryCount;
 | |
|   BOOLEAN                      InterruptStatus;
 | |
| 
 | |
|   if (InitFlag != DEBUG_AGENT_INIT_DXE_CORE &&
 | |
|       InitFlag != DEBUG_AGENT_INIT_S3 &&
 | |
|       InitFlag != DEBUG_AGENT_INIT_DXE_AP) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Save and disable original interrupt status
 | |
|   //
 | |
|   InterruptStatus = SaveAndDisableInterrupts ();
 | |
| 
 | |
|   if (InitFlag == DEBUG_AGENT_INIT_DXE_CORE) {
 | |
|     //
 | |
|     // Try to get Mailbox from GUIDed HOB.
 | |
|     //
 | |
|     mConfigurationTableNeeded = TRUE;
 | |
|     Mailbox = GetMailboxFromHob (Context);
 | |
| 
 | |
|   } 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));
 | |
|     mMailbox.DebugPortHandle = 0;
 | |
|   } else {
 | |
|     //
 | |
|     // If Mailbox not exists, used the local Mailbox.
 | |
|     //
 | |
|     ZeroMem (&mMailbox, sizeof (DEBUG_AGENT_MAILBOX));
 | |
|   }
 | |
| 
 | |
|   mMailboxPointer = &mMailbox;
 | |
| 
 | |
|   //
 | |
|   // 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;
 | |
|     AsmWriteIdtr ((IA32_DESCRIPTOR *) &Idtr);
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Initialize the IDT table entries to support source level debug.
 | |
|   //
 | |
|   InitializeDebugIdt ();
 | |
| 
 | |
|   //
 | |
|   // Initialize debug communication port
 | |
|   //
 | |
|   mMailboxPointer->DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize (NULL, NULL);
 | |
| 
 | |
|   InitializeSpinLock (&mDebugMpContext.MpContextSpinLock);
 | |
|   InitializeSpinLock (&mDebugMpContext.DebugPortSpinLock);
 | |
|  
 | |
|   if (InitFlag == DEBUG_AGENT_INIT_DXE_CORE) {
 | |
|     //
 | |
|     // Initialize Debug Timer hardware and enable interrupt.
 | |
|     //
 | |
|     InitializeDebugTimer ();
 | |
|     EnableInterrupts ();
 | |
| 
 | |
|     return;
 | |
|   } else {
 | |
|     //
 | |
|     // Disable Debug Timer interrupt in S3 path.
 | |
|     //
 | |
|     SaveAndSetDebugTimerInterrupt (FALSE);
 | |
| 
 | |
|     //
 | |
|     // Restore interrupt state.
 | |
|     //
 | |
|     SetInterruptState (InterruptStatus);
 | |
|   }
 | |
| 
 | |
| }
 | |
| 
 |