2 PiSmmCommunication SMM Driver.
4 Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <Library/UefiDriverEntryPoint.h>
17 #include <Library/UefiBootServicesTableLib.h>
18 #include <Library/UefiRuntimeServicesTableLib.h>
19 #include <Library/SmmServicesTableLib.h>
20 #include <Library/BaseLib.h>
21 #include <Library/BaseMemoryLib.h>
22 #include <Library/DebugLib.h>
23 #include <Library/SmmMemLib.h>
24 #include <Protocol/SmmSwDispatch2.h>
25 #include <Protocol/SmmCommunication.h>
26 #include <Ppi/SmmCommunication.h>
28 #include "PiSmmCommunicationPrivate.h"
30 EFI_SMM_COMMUNICATION_CONTEXT mSmmCommunicationContext
= {
31 SMM_COMMUNICATION_SIGNATURE
35 Set SMM communication context.
38 SetCommunicationContext (
44 Status
= gSmst
->SmmInstallConfigurationTable (
46 &gEfiPeiSmmCommunicationPpiGuid
,
47 &mSmmCommunicationContext
,
48 sizeof(mSmmCommunicationContext
)
50 ASSERT_EFI_ERROR (Status
);
54 Dispatch function for a Software SMI handler.
56 @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
57 @param Context Points to an optional handler context which was specified when the
58 handler was registered.
59 @param CommBuffer A pointer to a collection of data in memory that will
60 be conveyed from a non-SMM environment into an SMM environment.
61 @param CommBufferSize The size of the CommBuffer.
63 @retval EFI_SUCCESS Command is handled successfully.
68 PiSmmCommunicationHandler (
69 IN EFI_HANDLE DispatchHandle
,
70 IN CONST VOID
*Context OPTIONAL
,
71 IN OUT VOID
*CommBuffer OPTIONAL
,
72 IN OUT UINTN
*CommBufferSize OPTIONAL
77 EFI_SMM_COMMUNICATE_HEADER
*CommunicateHeader
;
78 EFI_PHYSICAL_ADDRESS
*BufferPtrAddress
;
80 DEBUG ((EFI_D_INFO
, "PiSmmCommunicationHandler Enter\n"));
82 BufferPtrAddress
= (EFI_PHYSICAL_ADDRESS
*)(UINTN
)mSmmCommunicationContext
.BufferPtrAddress
;
83 CommunicateHeader
= (EFI_SMM_COMMUNICATE_HEADER
*)(UINTN
)*BufferPtrAddress
;
84 DEBUG ((EFI_D_INFO
, "PiSmmCommunicationHandler CommunicateHeader - %x\n", CommunicateHeader
));
85 if (CommunicateHeader
== NULL
) {
86 DEBUG ((EFI_D_INFO
, "PiSmmCommunicationHandler is NULL, needn't to call dispatch function\n"));
89 if (!SmmIsBufferOutsideSmmValid ((UINTN
)CommunicateHeader
, OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER
, Data
))) {
90 DEBUG ((EFI_D_INFO
, "PiSmmCommunicationHandler CommunicateHeader invalid - 0x%x\n", CommunicateHeader
));
95 CommSize
= (UINTN
)CommunicateHeader
->MessageLength
;
96 if (!SmmIsBufferOutsideSmmValid ((UINTN
)&CommunicateHeader
->Data
[0], CommSize
)) {
97 DEBUG ((EFI_D_INFO
, "PiSmmCommunicationHandler CommunicateData invalid - 0x%x\n", &CommunicateHeader
->Data
[0]));
103 // Call dispatch function
105 DEBUG ((EFI_D_INFO
, "PiSmmCommunicationHandler Data - %x\n", &CommunicateHeader
->Data
[0]));
106 Status
= gSmst
->SmiManage (
107 &CommunicateHeader
->HeaderGuid
,
109 &CommunicateHeader
->Data
[0],
115 DEBUG ((EFI_D_INFO
, "PiSmmCommunicationHandler %r\n", Status
));
116 DEBUG ((EFI_D_INFO
, "PiSmmCommunicationHandler Exit\n"));
118 return (Status
== EFI_SUCCESS
) ? EFI_SUCCESS
: EFI_INTERRUPT_PENDING
;
122 Allocate EfiACPIMemoryNVS below 4G memory address.
124 This function allocates EfiACPIMemoryNVS below 4G memory address.
126 @param Size Size of memory to allocate.
128 @return Allocated address for output.
132 AllocateAcpiNvsMemoryBelow4G (
137 EFI_PHYSICAL_ADDRESS Address
;
141 Pages
= EFI_SIZE_TO_PAGES (Size
);
142 Address
= 0xffffffff;
144 Status
= gBS
->AllocatePages (
150 ASSERT_EFI_ERROR (Status
);
152 Buffer
= (VOID
*) (UINTN
) Address
;
153 ZeroMem (Buffer
, Size
);
159 Entry Point for PI SMM communication SMM driver.
161 @param[in] ImageHandle Image handle of this driver.
162 @param[in] SystemTable A Pointer to the EFI System Table.
165 @return Others Some error occurs.
169 PiSmmCommunicationSmmEntryPoint (
170 IN EFI_HANDLE ImageHandle
,
171 IN EFI_SYSTEM_TABLE
*SystemTable
175 EFI_SMM_SW_DISPATCH2_PROTOCOL
*SmmSwDispatch2
;
176 EFI_SMM_SW_REGISTER_CONTEXT SmmSwDispatchContext
;
177 EFI_HANDLE DispatchHandle
;
178 EFI_PHYSICAL_ADDRESS
*BufferPtrAddress
;
181 // Register software SMI handler
183 Status
= gSmst
->SmmLocateProtocol (
184 &gEfiSmmSwDispatch2ProtocolGuid
,
186 (VOID
**)&SmmSwDispatch2
188 ASSERT_EFI_ERROR (Status
);
190 SmmSwDispatchContext
.SwSmiInputValue
= (UINTN
)-1;
191 Status
= SmmSwDispatch2
->Register (
193 PiSmmCommunicationHandler
,
194 &SmmSwDispatchContext
,
197 ASSERT_EFI_ERROR (Status
);
199 DEBUG ((EFI_D_INFO
, "SmmCommunication SwSmi: %x\n", (UINTN
)SmmSwDispatchContext
.SwSmiInputValue
));
201 BufferPtrAddress
= AllocateAcpiNvsMemoryBelow4G (sizeof(EFI_PHYSICAL_ADDRESS
));
202 ASSERT (BufferPtrAddress
!= NULL
);
203 DEBUG ((EFI_D_INFO
, "SmmCommunication BufferPtrAddress: 0x%016lx, BufferPtr: 0x%016lx\n", (EFI_PHYSICAL_ADDRESS
)(UINTN
)BufferPtrAddress
, *BufferPtrAddress
));
208 mSmmCommunicationContext
.SwSmiNumber
= (UINT32
)SmmSwDispatchContext
.SwSmiInputValue
;
209 mSmmCommunicationContext
.BufferPtrAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)BufferPtrAddress
;
210 SetCommunicationContext ();