]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.c
UefiCpuPkg/CpuDxe: Enable protection for newly added page table
[mirror_edk2.git] / UefiCpuPkg / PiSmmCommunication / PiSmmCommunicationSmm.c
CommitLineData
b3dc26ed
MK
1/** @file\r
2PiSmmCommunication SMM Driver.\r
3\r
8b1d1493 4Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>\r
b3dc26ed
MK
5This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <PiSmm.h>\r
16#include <Library/UefiDriverEntryPoint.h>\r
17#include <Library/UefiBootServicesTableLib.h>\r
18#include <Library/UefiRuntimeServicesTableLib.h>\r
19#include <Library/SmmServicesTableLib.h>\r
20#include <Library/BaseLib.h>\r
21#include <Library/BaseMemoryLib.h>\r
b3dc26ed
MK
22#include <Library/DebugLib.h>\r
23#include <Library/SmmMemLib.h>\r
b3dc26ed 24#include <Protocol/SmmSwDispatch2.h>\r
b3dc26ed 25#include <Protocol/SmmCommunication.h>\r
b3dc26ed 26#include <Ppi/SmmCommunication.h>\r
b3dc26ed
MK
27\r
28#include "PiSmmCommunicationPrivate.h"\r
29\r
30EFI_SMM_COMMUNICATION_CONTEXT mSmmCommunicationContext = {\r
31 SMM_COMMUNICATION_SIGNATURE\r
32};\r
33\r
b3dc26ed
MK
34/**\r
35 Set SMM communication context.\r
36**/\r
37VOID\r
38SetCommunicationContext (\r
39 VOID\r
40 )\r
41{\r
42 EFI_STATUS Status;\r
43\r
44 Status = gSmst->SmmInstallConfigurationTable (\r
45 gSmst,\r
46 &gEfiPeiSmmCommunicationPpiGuid,\r
47 &mSmmCommunicationContext,\r
48 sizeof(mSmmCommunicationContext)\r
49 );\r
50 ASSERT_EFI_ERROR (Status);\r
51}\r
52\r
53/**\r
54 Dispatch function for a Software SMI handler.\r
55\r
56 @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().\r
57 @param Context Points to an optional handler context which was specified when the\r
58 handler was registered.\r
59 @param CommBuffer A pointer to a collection of data in memory that will\r
60 be conveyed from a non-SMM environment into an SMM environment.\r
61 @param CommBufferSize The size of the CommBuffer.\r
62\r
63 @retval EFI_SUCCESS Command is handled successfully.\r
64\r
65**/\r
66EFI_STATUS\r
67EFIAPI\r
68PiSmmCommunicationHandler (\r
69 IN EFI_HANDLE DispatchHandle,\r
70 IN CONST VOID *Context OPTIONAL,\r
71 IN OUT VOID *CommBuffer OPTIONAL,\r
72 IN OUT UINTN *CommBufferSize OPTIONAL\r
73 )\r
74{\r
75 UINTN CommSize;\r
76 EFI_STATUS Status;\r
77 EFI_SMM_COMMUNICATE_HEADER *CommunicateHeader;\r
78 EFI_PHYSICAL_ADDRESS *BufferPtrAddress;\r
79\r
80 DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler Enter\n"));\r
81\r
82 BufferPtrAddress = (EFI_PHYSICAL_ADDRESS *)(UINTN)mSmmCommunicationContext.BufferPtrAddress;\r
83 CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)(UINTN)*BufferPtrAddress;\r
84 DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler CommunicateHeader - %x\n", CommunicateHeader));\r
85 if (CommunicateHeader == NULL) {\r
86 DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler is NULL, needn't to call dispatch function\n"));\r
87 Status = EFI_SUCCESS;\r
88 } else {\r
89 if (!SmmIsBufferOutsideSmmValid ((UINTN)CommunicateHeader, OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data))) {\r
90 DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler CommunicateHeader invalid - 0x%x\n", CommunicateHeader));\r
91 Status = EFI_SUCCESS;\r
92 goto Done;\r
93 }\r
94\r
95 CommSize = (UINTN)CommunicateHeader->MessageLength;\r
96 if (!SmmIsBufferOutsideSmmValid ((UINTN)&CommunicateHeader->Data[0], CommSize)) {\r
97 DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler CommunicateData invalid - 0x%x\n", &CommunicateHeader->Data[0]));\r
98 Status = EFI_SUCCESS;\r
99 goto Done;\r
100 }\r
101\r
102 //\r
103 // Call dispatch function\r
104 //\r
105 DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler Data - %x\n", &CommunicateHeader->Data[0]));\r
106 Status = gSmst->SmiManage (\r
107 &CommunicateHeader->HeaderGuid,\r
108 NULL,\r
109 &CommunicateHeader->Data[0],\r
110 &CommSize\r
111 );\r
112 }\r
113\r
114Done:\r
115 DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler %r\n", Status));\r
116 DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler Exit\n"));\r
117\r
118 return (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_INTERRUPT_PENDING;\r
119}\r
120\r
121/**\r
122 Allocate EfiACPIMemoryNVS below 4G memory address.\r
123\r
124 This function allocates EfiACPIMemoryNVS below 4G memory address.\r
125\r
126 @param Size Size of memory to allocate.\r
127\r
128 @return Allocated address for output.\r
129\r
130**/\r
131VOID*\r
132AllocateAcpiNvsMemoryBelow4G (\r
133 IN UINTN Size\r
134 )\r
135{\r
136 UINTN Pages;\r
137 EFI_PHYSICAL_ADDRESS Address;\r
138 EFI_STATUS Status;\r
139 VOID* Buffer;\r
140\r
141 Pages = EFI_SIZE_TO_PAGES (Size);\r
142 Address = 0xffffffff;\r
143\r
144 Status = gBS->AllocatePages (\r
145 AllocateMaxAddress,\r
146 EfiACPIMemoryNVS,\r
147 Pages,\r
148 &Address\r
149 );\r
150 ASSERT_EFI_ERROR (Status);\r
151\r
152 Buffer = (VOID *) (UINTN) Address;\r
153 ZeroMem (Buffer, Size);\r
154\r
155 return Buffer;\r
156}\r
157\r
158/**\r
159 Entry Point for PI SMM communication SMM driver.\r
160\r
161 @param[in] ImageHandle Image handle of this driver.\r
162 @param[in] SystemTable A Pointer to the EFI System Table.\r
163\r
164 @retval EFI_SUCEESS\r
165 @return Others Some error occurs.\r
166**/\r
167EFI_STATUS\r
168EFIAPI\r
169PiSmmCommunicationSmmEntryPoint (\r
170 IN EFI_HANDLE ImageHandle,\r
171 IN EFI_SYSTEM_TABLE *SystemTable\r
172 )\r
173{\r
174 EFI_STATUS Status;\r
175 EFI_SMM_SW_DISPATCH2_PROTOCOL *SmmSwDispatch2;\r
176 EFI_SMM_SW_REGISTER_CONTEXT SmmSwDispatchContext;\r
177 EFI_HANDLE DispatchHandle;\r
b3dc26ed
MK
178 EFI_PHYSICAL_ADDRESS *BufferPtrAddress;\r
179\r
b3dc26ed
MK
180 //\r
181 // Register software SMI handler\r
182 //\r
183 Status = gSmst->SmmLocateProtocol (\r
184 &gEfiSmmSwDispatch2ProtocolGuid,\r
185 NULL,\r
186 (VOID **)&SmmSwDispatch2\r
187 );\r
188 ASSERT_EFI_ERROR (Status);\r
189\r
190 SmmSwDispatchContext.SwSmiInputValue = (UINTN)-1;\r
191 Status = SmmSwDispatch2->Register (\r
192 SmmSwDispatch2,\r
193 PiSmmCommunicationHandler,\r
194 &SmmSwDispatchContext,\r
195 &DispatchHandle\r
196 );\r
197 ASSERT_EFI_ERROR (Status);\r
198\r
199 DEBUG ((EFI_D_INFO, "SmmCommunication SwSmi: %x\n", (UINTN)SmmSwDispatchContext.SwSmiInputValue));\r
200\r
b3dc26ed
MK
201 BufferPtrAddress = AllocateAcpiNvsMemoryBelow4G (sizeof(EFI_PHYSICAL_ADDRESS));\r
202 ASSERT (BufferPtrAddress != NULL);\r
203 DEBUG ((EFI_D_INFO, "SmmCommunication BufferPtrAddress: 0x%016lx, BufferPtr: 0x%016lx\n", (EFI_PHYSICAL_ADDRESS)(UINTN)BufferPtrAddress, *BufferPtrAddress));\r
b3dc26ed
MK
204\r
205 //\r
206 // Save context\r
207 //\r
208 mSmmCommunicationContext.SwSmiNumber = (UINT32)SmmSwDispatchContext.SwSmiInputValue;\r
8b1d1493 209 mSmmCommunicationContext.BufferPtrAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)BufferPtrAddress;\r
b3dc26ed
MK
210 SetCommunicationContext ();\r
211\r
212 return Status;\r
213}\r