REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the UefiPayloadPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Ray Ni <ray.ni@intel.com>
		
			
				
	
	
		
			259 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			259 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   This module produces the SMM Control2 Protocol
 | |
| 
 | |
|   Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include <PiDxe.h>
 | |
| #include <Protocol/SmmControl2.h>
 | |
| #include <Library/DebugLib.h>
 | |
| #include <Library/UefiBootServicesTableLib.h>
 | |
| #include <Library/IoLib.h>
 | |
| #include <Library/HobLib.h>
 | |
| #include <Library/UefiRuntimeLib.h>
 | |
| #include <Library/BaseMemoryLib.h>
 | |
| #include <Guid/SmmRegisterInfoGuid.h>
 | |
| 
 | |
| #define SMM_DATA_PORT     0xB3
 | |
| #define SMM_CONTROL_PORT  0xB2
 | |
| 
 | |
| typedef struct {
 | |
|   UINT8     GblBitOffset;
 | |
|   UINT8     ApmBitOffset;
 | |
|   UINT32    Address;
 | |
| } SMM_CONTROL2_REG;
 | |
| 
 | |
| SMM_CONTROL2_REG  mSmiCtrlReg;
 | |
| 
 | |
| /**
 | |
|   Invokes SMI activation from either the preboot or runtime environment.
 | |
| 
 | |
|   This function generates an SMI.
 | |
| 
 | |
|   @param[in]     This                The EFI_SMM_CONTROL2_PROTOCOL instance.
 | |
|   @param[in,out] CommandPort         The value written to the command port.
 | |
|   @param[in,out] DataPort            The value written to the data port.
 | |
|   @param[in]     Periodic            Optional mechanism to engender a periodic stream.
 | |
|   @param[in]     ActivationInterval  Optional parameter to repeat at this period one
 | |
|                                      time or, if the Periodic Boolean is set, periodically.
 | |
| 
 | |
|   @retval EFI_SUCCESS            The SMI has been engendered.
 | |
|   @retval EFI_DEVICE_ERROR       The timing is unsupported.
 | |
|   @retval EFI_INVALID_PARAMETER  The activation period is unsupported.
 | |
|   @retval EFI_INVALID_PARAMETER  The last periodic activation has not been cleared.
 | |
|   @retval EFI_NOT_STARTED        The MM base service has not been initialized.
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| Activate (
 | |
|   IN CONST EFI_SMM_CONTROL2_PROTOCOL  *This,
 | |
|   IN OUT  UINT8                       *CommandPort       OPTIONAL,
 | |
|   IN OUT  UINT8                       *DataPort          OPTIONAL,
 | |
|   IN      BOOLEAN                     Periodic           OPTIONAL,
 | |
|   IN      EFI_SMM_PERIOD              ActivationInterval OPTIONAL
 | |
|   )
 | |
| {
 | |
|   UINT32  SmiEn;
 | |
|   UINT32  SmiEnableBits;
 | |
| 
 | |
|   if (Periodic) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   SmiEn         = IoRead32 (mSmiCtrlReg.Address);
 | |
|   SmiEnableBits = (1 << mSmiCtrlReg.GblBitOffset) | (1 << mSmiCtrlReg.ApmBitOffset);
 | |
|   if ((SmiEn & SmiEnableBits) != SmiEnableBits) {
 | |
|     //
 | |
|     // Set the "global SMI enable" bit and APM bit
 | |
|     //
 | |
|     IoWrite32 (mSmiCtrlReg.Address, SmiEn | SmiEnableBits);
 | |
|   }
 | |
| 
 | |
|   IoWrite8 (SMM_DATA_PORT, DataPort    == NULL ? 0 : *DataPort);
 | |
|   IoWrite8 (SMM_CONTROL_PORT, CommandPort == NULL ? 0 : *CommandPort);
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Clears an SMI.
 | |
| 
 | |
|   @param  This      Pointer to an instance of EFI_SMM_CONTROL2_PROTOCOL
 | |
|   @param  Periodic  TRUE to indicate a periodical SMI
 | |
| 
 | |
|   @return Return value from SmmClear ()
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| Deactivate (
 | |
|   IN CONST EFI_SMM_CONTROL2_PROTOCOL  *This,
 | |
|   IN       BOOLEAN                    Periodic
 | |
|   )
 | |
| {
 | |
|   if (Periodic) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Temporarily do nothing here
 | |
|   //
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| ///
 | |
| /// SMM COntrol2 Protocol instance
 | |
| ///
 | |
| EFI_SMM_CONTROL2_PROTOCOL  mSmmControl2 = {
 | |
|   Activate,
 | |
|   Deactivate,
 | |
|   0
 | |
| };
 | |
| 
 | |
| /**
 | |
|   Get specified SMI register based on given register ID
 | |
| 
 | |
|   @param[in]  SmmRegister  SMI related register array from bootloader
 | |
|   @param[in]  Id           The register ID to get.
 | |
| 
 | |
|   @retval NULL             The register is not found or the format is not expected.
 | |
|   @return smi register
 | |
| 
 | |
| **/
 | |
| PLD_GENERIC_REGISTER *
 | |
| GetSmmCtrlRegById (
 | |
|   IN PLD_SMM_REGISTERS  *SmmRegister,
 | |
|   IN UINT32             Id
 | |
|   )
 | |
| {
 | |
|   UINT32                Index;
 | |
|   PLD_GENERIC_REGISTER  *PldReg;
 | |
| 
 | |
|   PldReg = NULL;
 | |
|   for (Index = 0; Index < SmmRegister->Count; Index++) {
 | |
|     if (SmmRegister->Registers[Index].Id == Id) {
 | |
|       PldReg = &SmmRegister->Registers[Index];
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (PldReg == NULL) {
 | |
|     DEBUG ((DEBUG_INFO, "Register %d not found.\n", Id));
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // Checking the register if it is expected.
 | |
|   //
 | |
|   if ((PldReg->Address.AccessSize       != EFI_ACPI_3_0_DWORD) ||
 | |
|       (PldReg->Address.Address          == 0) ||
 | |
|       (PldReg->Address.RegisterBitWidth != 1) ||
 | |
|       (PldReg->Address.AddressSpaceId   != EFI_ACPI_3_0_SYSTEM_IO) ||
 | |
|       (PldReg->Value != 1))
 | |
|   {
 | |
|     DEBUG ((DEBUG_INFO, "Unexpected SMM register.\n"));
 | |
|     DEBUG ((DEBUG_INFO, "AddressSpaceId= 0x%x\n", PldReg->Address.AddressSpaceId));
 | |
|     DEBUG ((DEBUG_INFO, "RegBitWidth   = 0x%x\n", PldReg->Address.RegisterBitWidth));
 | |
|     DEBUG ((DEBUG_INFO, "RegBitOffset  = 0x%x\n", PldReg->Address.RegisterBitOffset));
 | |
|     DEBUG ((DEBUG_INFO, "AccessSize    = 0x%x\n", PldReg->Address.AccessSize));
 | |
|     DEBUG ((DEBUG_INFO, "Address       = 0x%lx\n", PldReg->Address.Address));
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   return PldReg;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Fixup data pointers so that the services can be called in virtual mode.
 | |
| 
 | |
|   @param[in] Event                The event registered.
 | |
|   @param[in] Context              Event context.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| SmmControlVirtualAddressChangeEvent (
 | |
|   IN EFI_EVENT  Event,
 | |
|   IN VOID       *Context
 | |
|   )
 | |
| {
 | |
|   EfiConvertPointer (0x0, (VOID **)&(mSmmControl2.Trigger));
 | |
|   EfiConvertPointer (0x0, (VOID **)&(mSmmControl2.Clear));
 | |
| }
 | |
| 
 | |
| /**
 | |
|   This function installs EFI_SMM_CONTROL2_PROTOCOL.
 | |
| 
 | |
|   @param  ImageHandle Handle for the image of this driver
 | |
|   @param  SystemTable Pointer to the EFI System Table
 | |
| 
 | |
|   @retval EFI_UNSUPPORTED There's no Intel ICH on this platform
 | |
|   @return The status returned from InstallProtocolInterface().
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| SmmControlEntryPoint (
 | |
|   IN EFI_HANDLE        ImageHandle,
 | |
|   IN EFI_SYSTEM_TABLE  *SystemTable
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS            Status;
 | |
|   EFI_HOB_GUID_TYPE     *GuidHob;
 | |
|   PLD_SMM_REGISTERS     *SmmRegister;
 | |
|   PLD_GENERIC_REGISTER  *SmiGblEnReg;
 | |
|   PLD_GENERIC_REGISTER  *SmiApmEnReg;
 | |
|   EFI_EVENT             Event;
 | |
| 
 | |
|   GuidHob = GetFirstGuidHob (&gSmmRegisterInfoGuid);
 | |
|   if (GuidHob == NULL) {
 | |
|     return EFI_UNSUPPORTED;
 | |
|   }
 | |
| 
 | |
|   SmmRegister = (PLD_SMM_REGISTERS *)(GET_GUID_HOB_DATA (GuidHob));
 | |
|   SmiGblEnReg = GetSmmCtrlRegById (SmmRegister, REGISTER_ID_SMI_GBL_EN);
 | |
|   if (SmiGblEnReg == NULL) {
 | |
|     DEBUG ((DEBUG_ERROR, "SMI global enable reg not found.\n"));
 | |
|     return EFI_NOT_FOUND;
 | |
|   }
 | |
| 
 | |
|   mSmiCtrlReg.Address      = (UINT32)SmiGblEnReg->Address.Address;
 | |
|   mSmiCtrlReg.GblBitOffset = SmiGblEnReg->Address.RegisterBitOffset;
 | |
| 
 | |
|   SmiApmEnReg = GetSmmCtrlRegById (SmmRegister, REGISTER_ID_SMI_APM_EN);
 | |
|   if (SmiApmEnReg == NULL) {
 | |
|     DEBUG ((DEBUG_ERROR, "SMI APM enable reg not found.\n"));
 | |
|     return EFI_NOT_FOUND;
 | |
|   }
 | |
| 
 | |
|   if (SmiApmEnReg->Address.Address != mSmiCtrlReg.Address) {
 | |
|     DEBUG ((DEBUG_ERROR, "SMI APM EN and SMI GBL EN are expected to have same register base\n"));
 | |
|     DEBUG ((DEBUG_ERROR, "APM:0x%x, GBL:0x%x\n", SmiApmEnReg->Address.Address, mSmiCtrlReg.Address));
 | |
|     return EFI_UNSUPPORTED;
 | |
|   }
 | |
| 
 | |
|   mSmiCtrlReg.ApmBitOffset = SmiApmEnReg->Address.RegisterBitOffset;
 | |
| 
 | |
|   //
 | |
|   // Install our protocol interfaces on the device's handle
 | |
|   //
 | |
|   Status = gBS->InstallMultipleProtocolInterfaces (
 | |
|                   &ImageHandle,
 | |
|                   &gEfiSmmControl2ProtocolGuid,
 | |
|                   &mSmmControl2,
 | |
|                   NULL
 | |
|                   );
 | |
|   ASSERT_EFI_ERROR (Status);
 | |
| 
 | |
|   Status = gBS->CreateEventEx (
 | |
|                   EVT_NOTIFY_SIGNAL,
 | |
|                   TPL_NOTIFY,
 | |
|                   SmmControlVirtualAddressChangeEvent,
 | |
|                   NULL,
 | |
|                   &gEfiEventVirtualAddressChangeGuid,
 | |
|                   &Event
 | |
|                   );
 | |
|   return Status;
 | |
| }
 |