2 PiSmmCommunication SMM Driver.
4 Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <Library/UefiDriverEntryPoint.h>
11 #include <Library/UefiBootServicesTableLib.h>
12 #include <Library/UefiRuntimeServicesTableLib.h>
13 #include <Library/SmmServicesTableLib.h>
14 #include <Library/BaseLib.h>
15 #include <Library/BaseMemoryLib.h>
16 #include <Library/DebugLib.h>
17 #include <Library/SmmMemLib.h>
18 #include <Protocol/SmmSwDispatch2.h>
19 #include <Protocol/SmmCommunication.h>
20 #include <Ppi/SmmCommunication.h>
22 #include "PiSmmCommunicationPrivate.h"
24 EFI_SMM_COMMUNICATION_CONTEXT mSmmCommunicationContext
= {
25 SMM_COMMUNICATION_SIGNATURE
29 Set SMM communication context.
32 SetCommunicationContext (
38 Status
= gSmst
->SmmInstallConfigurationTable (
40 &gEfiPeiSmmCommunicationPpiGuid
,
41 &mSmmCommunicationContext
,
42 sizeof (mSmmCommunicationContext
)
44 ASSERT_EFI_ERROR (Status
);
48 Dispatch function for a Software SMI handler.
50 @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
51 @param Context Points to an optional handler context which was specified when the
52 handler was registered.
53 @param CommBuffer A pointer to a collection of data in memory that will
54 be conveyed from a non-SMM environment into an SMM environment.
55 @param CommBufferSize The size of the CommBuffer.
57 @retval EFI_SUCCESS Command is handled successfully.
62 PiSmmCommunicationHandler (
63 IN EFI_HANDLE DispatchHandle
,
64 IN CONST VOID
*Context OPTIONAL
,
65 IN OUT VOID
*CommBuffer OPTIONAL
,
66 IN OUT UINTN
*CommBufferSize OPTIONAL
71 EFI_SMM_COMMUNICATE_HEADER
*CommunicateHeader
;
72 EFI_PHYSICAL_ADDRESS
*BufferPtrAddress
;
74 DEBUG ((DEBUG_INFO
, "PiSmmCommunicationHandler Enter\n"));
76 BufferPtrAddress
= (EFI_PHYSICAL_ADDRESS
*)(UINTN
)mSmmCommunicationContext
.BufferPtrAddress
;
77 CommunicateHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)(UINTN
)*BufferPtrAddress
;
78 DEBUG ((DEBUG_INFO
, "PiSmmCommunicationHandler CommunicateHeader - %x\n", CommunicateHeader
));
79 if (CommunicateHeader
== NULL
) {
80 DEBUG ((DEBUG_INFO
, "PiSmmCommunicationHandler is NULL, needn't to call dispatch function\n"));
83 if (!SmmIsBufferOutsideSmmValid ((UINTN
)CommunicateHeader
, OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
))) {
84 DEBUG ((DEBUG_INFO
, "PiSmmCommunicationHandler CommunicateHeader invalid - 0x%x\n", CommunicateHeader
));
89 CommSize
= (UINTN
)CommunicateHeader
->MessageLength
;
90 if (!SmmIsBufferOutsideSmmValid ((UINTN
)&CommunicateHeader
->Data
[0], CommSize
)) {
91 DEBUG ((DEBUG_INFO
, "PiSmmCommunicationHandler CommunicateData invalid - 0x%x\n", &CommunicateHeader
->Data
[0]));
97 // Call dispatch function
99 DEBUG ((DEBUG_INFO
, "PiSmmCommunicationHandler Data - %x\n", &CommunicateHeader
->Data
[0]));
100 Status
= gSmst
->SmiManage (
101 &CommunicateHeader
->HeaderGuid
,
103 &CommunicateHeader
->Data
[0],
109 DEBUG ((DEBUG_INFO
, "PiSmmCommunicationHandler %r\n", Status
));
110 DEBUG ((DEBUG_INFO
, "PiSmmCommunicationHandler Exit\n"));
112 return (Status
== EFI_SUCCESS
) ? EFI_SUCCESS
: EFI_INTERRUPT_PENDING
;
116 Allocate EfiACPIMemoryNVS below 4G memory address.
118 This function allocates EfiACPIMemoryNVS below 4G memory address.
120 @param Size Size of memory to allocate.
122 @return Allocated address for output.
126 AllocateAcpiNvsMemoryBelow4G (
131 EFI_PHYSICAL_ADDRESS Address
;
135 Pages
= EFI_SIZE_TO_PAGES (Size
);
136 Address
= 0xffffffff;
138 Status
= gBS
->AllocatePages (
144 ASSERT_EFI_ERROR (Status
);
146 Buffer
= (VOID
*)(UINTN
)Address
;
147 ZeroMem (Buffer
, Size
);
153 Entry Point for PI SMM communication SMM driver.
155 @param[in] ImageHandle Image handle of this driver.
156 @param[in] SystemTable A Pointer to the EFI System Table.
159 @return Others Some error occurs.
163 PiSmmCommunicationSmmEntryPoint (
164 IN EFI_HANDLE ImageHandle
,
165 IN EFI_SYSTEM_TABLE
*SystemTable
169 EFI_SMM_SW_DISPATCH2_PROTOCOL
*SmmSwDispatch2
;
170 EFI_SMM_SW_REGISTER_CONTEXT SmmSwDispatchContext
;
171 EFI_HANDLE DispatchHandle
;
172 EFI_PHYSICAL_ADDRESS
*BufferPtrAddress
;
175 // Register software SMI handler
177 Status
= gSmst
->SmmLocateProtocol (
178 &gEfiSmmSwDispatch2ProtocolGuid
,
180 (VOID
**)&SmmSwDispatch2
182 ASSERT_EFI_ERROR (Status
);
184 SmmSwDispatchContext
.SwSmiInputValue
= (UINTN
)-1;
185 Status
= SmmSwDispatch2
->Register (
187 PiSmmCommunicationHandler
,
188 &SmmSwDispatchContext
,
191 ASSERT_EFI_ERROR (Status
);
193 DEBUG ((DEBUG_INFO
, "SmmCommunication SwSmi: %x\n", (UINTN
)SmmSwDispatchContext
.SwSmiInputValue
));
195 BufferPtrAddress
= AllocateAcpiNvsMemoryBelow4G (sizeof (EFI_PHYSICAL_ADDRESS
));
196 ASSERT (BufferPtrAddress
!= NULL
);
197 DEBUG ((DEBUG_INFO
, "SmmCommunication BufferPtrAddress: 0x%016lx, BufferPtr: 0x%016lx\n", (EFI_PHYSICAL_ADDRESS
)(UINTN
)BufferPtrAddress
, *BufferPtrAddress
));
202 mSmmCommunicationContext
.SwSmiNumber
= (UINT32
)SmmSwDispatchContext
.SwSmiInputValue
;
203 mSmmCommunicationContext
.BufferPtrAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)BufferPtrAddress
;
204 SetCommunicationContext ();