123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- /** @file
- PiSmmCommunication SMM Driver.
- Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <PiSmm.h>
- #include <Library/UefiDriverEntryPoint.h>
- #include <Library/UefiBootServicesTableLib.h>
- #include <Library/UefiRuntimeServicesTableLib.h>
- #include <Library/SmmServicesTableLib.h>
- #include <Library/BaseLib.h>
- #include <Library/BaseMemoryLib.h>
- #include <Library/DebugLib.h>
- #include <Library/SmmMemLib.h>
- #include <Protocol/SmmSwDispatch2.h>
- #include <Protocol/SmmCommunication.h>
- #include <Ppi/SmmCommunication.h>
- #include "PiSmmCommunicationPrivate.h"
- EFI_SMM_COMMUNICATION_CONTEXT mSmmCommunicationContext = {
- SMM_COMMUNICATION_SIGNATURE
- };
- /**
- Set SMM communication context.
- **/
- VOID
- SetCommunicationContext (
- VOID
- )
- {
- EFI_STATUS Status;
- Status = gSmst->SmmInstallConfigurationTable (
- gSmst,
- &gEfiPeiSmmCommunicationPpiGuid,
- &mSmmCommunicationContext,
- sizeof (mSmmCommunicationContext)
- );
- ASSERT_EFI_ERROR (Status);
- }
- /**
- Dispatch function for a Software SMI handler.
- @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
- @param Context Points to an optional handler context which was specified when the
- handler was registered.
- @param CommBuffer A pointer to a collection of data in memory that will
- be conveyed from a non-SMM environment into an SMM environment.
- @param CommBufferSize The size of the CommBuffer.
- @retval EFI_SUCCESS Command is handled successfully.
- **/
- EFI_STATUS
- EFIAPI
- PiSmmCommunicationHandler (
- IN EFI_HANDLE DispatchHandle,
- IN CONST VOID *Context OPTIONAL,
- IN OUT VOID *CommBuffer OPTIONAL,
- IN OUT UINTN *CommBufferSize OPTIONAL
- )
- {
- UINTN CommSize;
- EFI_STATUS Status;
- EFI_SMM_COMMUNICATE_HEADER *CommunicateHeader;
- EFI_PHYSICAL_ADDRESS *BufferPtrAddress;
- DEBUG ((DEBUG_INFO, "PiSmmCommunicationHandler Enter\n"));
- BufferPtrAddress = (EFI_PHYSICAL_ADDRESS *)(UINTN)mSmmCommunicationContext.BufferPtrAddress;
- CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)(UINTN)*BufferPtrAddress;
- DEBUG ((DEBUG_INFO, "PiSmmCommunicationHandler CommunicateHeader - %x\n", CommunicateHeader));
- if (CommunicateHeader == NULL) {
- DEBUG ((DEBUG_INFO, "PiSmmCommunicationHandler is NULL, needn't to call dispatch function\n"));
- Status = EFI_SUCCESS;
- } else {
- if (!SmmIsBufferOutsideSmmValid ((UINTN)CommunicateHeader, OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data))) {
- DEBUG ((DEBUG_INFO, "PiSmmCommunicationHandler CommunicateHeader invalid - 0x%x\n", CommunicateHeader));
- Status = EFI_SUCCESS;
- goto Done;
- }
- CommSize = (UINTN)CommunicateHeader->MessageLength;
- if (!SmmIsBufferOutsideSmmValid ((UINTN)&CommunicateHeader->Data[0], CommSize)) {
- DEBUG ((DEBUG_INFO, "PiSmmCommunicationHandler CommunicateData invalid - 0x%x\n", &CommunicateHeader->Data[0]));
- Status = EFI_SUCCESS;
- goto Done;
- }
- //
- // Call dispatch function
- //
- DEBUG ((DEBUG_INFO, "PiSmmCommunicationHandler Data - %x\n", &CommunicateHeader->Data[0]));
- Status = gSmst->SmiManage (
- &CommunicateHeader->HeaderGuid,
- NULL,
- &CommunicateHeader->Data[0],
- &CommSize
- );
- }
- Done:
- DEBUG ((DEBUG_INFO, "PiSmmCommunicationHandler %r\n", Status));
- DEBUG ((DEBUG_INFO, "PiSmmCommunicationHandler Exit\n"));
- return (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_INTERRUPT_PENDING;
- }
- /**
- Allocate EfiACPIMemoryNVS below 4G memory address.
- This function allocates EfiACPIMemoryNVS below 4G memory address.
- @param Size Size of memory to allocate.
- @return Allocated address for output.
- **/
- VOID *
- AllocateAcpiNvsMemoryBelow4G (
- IN UINTN Size
- )
- {
- UINTN Pages;
- EFI_PHYSICAL_ADDRESS Address;
- EFI_STATUS Status;
- VOID *Buffer;
- Pages = EFI_SIZE_TO_PAGES (Size);
- Address = 0xffffffff;
- Status = gBS->AllocatePages (
- AllocateMaxAddress,
- EfiACPIMemoryNVS,
- Pages,
- &Address
- );
- ASSERT_EFI_ERROR (Status);
- Buffer = (VOID *)(UINTN)Address;
- ZeroMem (Buffer, Size);
- return Buffer;
- }
- /**
- Entry Point for PI SMM communication SMM driver.
- @param[in] ImageHandle Image handle of this driver.
- @param[in] SystemTable A Pointer to the EFI System Table.
- @retval EFI_SUCCESS
- @return Others Some error occurs.
- **/
- EFI_STATUS
- EFIAPI
- PiSmmCommunicationSmmEntryPoint (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
- {
- EFI_STATUS Status;
- EFI_SMM_SW_DISPATCH2_PROTOCOL *SmmSwDispatch2;
- EFI_SMM_SW_REGISTER_CONTEXT SmmSwDispatchContext;
- EFI_HANDLE DispatchHandle;
- EFI_PHYSICAL_ADDRESS *BufferPtrAddress;
- //
- // Register software SMI handler
- //
- Status = gSmst->SmmLocateProtocol (
- &gEfiSmmSwDispatch2ProtocolGuid,
- NULL,
- (VOID **)&SmmSwDispatch2
- );
- ASSERT_EFI_ERROR (Status);
- SmmSwDispatchContext.SwSmiInputValue = (UINTN)-1;
- Status = SmmSwDispatch2->Register (
- SmmSwDispatch2,
- PiSmmCommunicationHandler,
- &SmmSwDispatchContext,
- &DispatchHandle
- );
- ASSERT_EFI_ERROR (Status);
- DEBUG ((DEBUG_INFO, "SmmCommunication SwSmi: %x\n", (UINTN)SmmSwDispatchContext.SwSmiInputValue));
- BufferPtrAddress = AllocateAcpiNvsMemoryBelow4G (sizeof (EFI_PHYSICAL_ADDRESS));
- ASSERT (BufferPtrAddress != NULL);
- DEBUG ((DEBUG_INFO, "SmmCommunication BufferPtrAddress: 0x%016lx, BufferPtr: 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)BufferPtrAddress, *BufferPtrAddress));
- //
- // Save context
- //
- mSmmCommunicationContext.SwSmiNumber = (UINT32)SmmSwDispatchContext.SwSmiInputValue;
- mSmmCommunicationContext.BufferPtrAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)BufferPtrAddress;
- SetCommunicationContext ();
- return Status;
- }
|