TianoCore EDK2 master
PiSmmCommunicationSmm.c
Go to the documentation of this file.
1
9#include <PiSmm.h>
14#include <Library/BaseLib.h>
16#include <Library/DebugLib.h>
17#include <Library/SmmMemLib.h>
21
23
24EFI_SMM_COMMUNICATION_CONTEXT mSmmCommunicationContext = {
25 SMM_COMMUNICATION_SIGNATURE
26};
27
31VOID
33 VOID
34 )
35{
36 EFI_STATUS Status;
37
38 Status = gSmst->SmmInstallConfigurationTable (
39 gSmst,
40 &gEfiPeiSmmCommunicationPpiGuid,
41 &mSmmCommunicationContext,
42 sizeof (mSmmCommunicationContext)
43 );
44 ASSERT_EFI_ERROR (Status);
45}
46
61EFIAPI
63 IN EFI_HANDLE DispatchHandle,
64 IN CONST VOID *Context OPTIONAL,
65 IN OUT VOID *CommBuffer OPTIONAL,
66 IN OUT UINTN *CommBufferSize OPTIONAL
67 )
68{
69 UINTN CommSize;
70 EFI_STATUS Status;
71 EFI_SMM_COMMUNICATE_HEADER *CommunicateHeader;
72 EFI_PHYSICAL_ADDRESS *BufferPtrAddress;
73
74 DEBUG ((DEBUG_INFO, "PiSmmCommunicationHandler Enter\n"));
75
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"));
81 Status = EFI_SUCCESS;
82 } else {
83 if (!SmmIsBufferOutsideSmmValid ((UINTN)CommunicateHeader, OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data))) {
84 DEBUG ((DEBUG_INFO, "PiSmmCommunicationHandler CommunicateHeader invalid - 0x%x\n", CommunicateHeader));
85 Status = EFI_SUCCESS;
86 goto Done;
87 }
88
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]));
92 Status = EFI_SUCCESS;
93 goto Done;
94 }
95
96 //
97 // Call dispatch function
98 //
99 DEBUG ((DEBUG_INFO, "PiSmmCommunicationHandler Data - %x\n", &CommunicateHeader->Data[0]));
100 Status = gSmst->SmiManage (
101 &CommunicateHeader->HeaderGuid,
102 NULL,
103 &CommunicateHeader->Data[0],
104 &CommSize
105 );
106 }
107
108Done:
109 DEBUG ((DEBUG_INFO, "PiSmmCommunicationHandler %r\n", Status));
110 DEBUG ((DEBUG_INFO, "PiSmmCommunicationHandler Exit\n"));
111
112 return (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_INTERRUPT_PENDING;
113}
114
125VOID *
127 IN UINTN Size
128 )
129{
130 UINTN Pages;
131 EFI_PHYSICAL_ADDRESS Address;
132 EFI_STATUS Status;
133 VOID *Buffer;
134
135 Pages = EFI_SIZE_TO_PAGES (Size);
136 Address = 0xffffffff;
137
138 Status = gBS->AllocatePages (
141 Pages,
142 &Address
143 );
144 ASSERT_EFI_ERROR (Status);
145
146 Buffer = (VOID *)(UINTN)Address;
147 ZeroMem (Buffer, Size);
148
149 return Buffer;
150}
151
162EFIAPI
164 IN EFI_HANDLE ImageHandle,
165 IN EFI_SYSTEM_TABLE *SystemTable
166 )
167{
168 EFI_STATUS Status;
169 EFI_SMM_SW_DISPATCH2_PROTOCOL *SmmSwDispatch2;
170 EFI_SMM_SW_REGISTER_CONTEXT SmmSwDispatchContext;
171 EFI_HANDLE DispatchHandle;
172 EFI_PHYSICAL_ADDRESS *BufferPtrAddress;
173
174 //
175 // Register software SMI handler
176 //
177 Status = gSmst->SmmLocateProtocol (
178 &gEfiSmmSwDispatch2ProtocolGuid,
179 NULL,
180 (VOID **)&SmmSwDispatch2
181 );
182 ASSERT_EFI_ERROR (Status);
183
184 SmmSwDispatchContext.SwSmiInputValue = (UINTN)-1;
185 Status = SmmSwDispatch2->Register (
186 SmmSwDispatch2,
188 &SmmSwDispatchContext,
189 &DispatchHandle
190 );
191 ASSERT_EFI_ERROR (Status);
192
193 DEBUG ((DEBUG_INFO, "SmmCommunication SwSmi: %x\n", (UINTN)SmmSwDispatchContext.SwSmiInputValue));
194
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));
198
199 //
200 // Save context
201 //
202 mSmmCommunicationContext.SwSmiNumber = (UINT32)SmmSwDispatchContext.SwSmiInputValue;
203 mSmmCommunicationContext.BufferPtrAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)BufferPtrAddress;
205
206 return Status;
207}
UINT64 UINTN
#define NULL
Definition: Base.h:312
#define CONST
Definition: Base.h:259
#define IN
Definition: Base.h:279
#define OFFSET_OF(TYPE, Field)
Definition: Base.h:750
#define OUT
Definition: Base.h:284
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:440
#define DEBUG(Expression)
Definition: DebugLib.h:417
#define ASSERT(Expression)
Definition: DebugLib.h:391
#define EFI_INTERRUPT_PENDING
Definition: PiMultiPhase.h:66
VOID SetCommunicationContext(VOID)
VOID * AllocateAcpiNvsMemoryBelow4G(IN UINTN Size)
EFI_STATUS EFIAPI PiSmmCommunicationSmmEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
EFI_STATUS EFIAPI PiSmmCommunicationHandler(IN EFI_HANDLE DispatchHandle, IN CONST VOID *Context OPTIONAL, IN OUT VOID *CommBuffer OPTIONAL, IN OUT UINTN *CommBufferSize OPTIONAL)
EFI_SMM_SYSTEM_TABLE2 * gSmst
BOOLEAN EFIAPI SmmIsBufferOutsideSmmValid(IN EFI_PHYSICAL_ADDRESS Buffer, IN UINT64 Length)
Definition: SmmMemLib.c:114
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:49
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:28
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:197
VOID * EFI_HANDLE
Definition: UefiBaseType.h:32
#define EFI_SUCCESS
Definition: UefiBaseType.h:111
EFI_BOOT_SERVICES * gBS
@ EfiACPIMemoryNVS
@ AllocateMaxAddress
Definition: UefiSpec.h:37
EFI_SMM_INTERRUPT_MANAGE SmiManage
Definition: PiSmmCis.h:195