]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.c
UefiCpuPkg PiSmmCommunicationSmm: Deprecate SMM Communication ACPI Table
[mirror_edk2.git] / UefiCpuPkg / PiSmmCommunication / PiSmmCommunicationSmm.c
1 /** @file
2 PiSmmCommunication SMM Driver.
3
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
9
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.
12
13 **/
14
15 #include <PiSmm.h>
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>
27
28 #include "PiSmmCommunicationPrivate.h"
29
30 EFI_SMM_COMMUNICATION_CONTEXT mSmmCommunicationContext = {
31 SMM_COMMUNICATION_SIGNATURE
32 };
33
34 /**
35 Set SMM communication context.
36 **/
37 VOID
38 SetCommunicationContext (
39 VOID
40 )
41 {
42 EFI_STATUS Status;
43
44 Status = gSmst->SmmInstallConfigurationTable (
45 gSmst,
46 &gEfiPeiSmmCommunicationPpiGuid,
47 &mSmmCommunicationContext,
48 sizeof(mSmmCommunicationContext)
49 );
50 ASSERT_EFI_ERROR (Status);
51 }
52
53 /**
54 Dispatch function for a Software SMI handler.
55
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.
62
63 @retval EFI_SUCCESS Command is handled successfully.
64
65 **/
66 EFI_STATUS
67 EFIAPI
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
73 )
74 {
75 UINTN CommSize;
76 EFI_STATUS Status;
77 EFI_SMM_COMMUNICATE_HEADER *CommunicateHeader;
78 EFI_PHYSICAL_ADDRESS *BufferPtrAddress;
79
80 DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler Enter\n"));
81
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"));
87 Status = EFI_SUCCESS;
88 } else {
89 if (!SmmIsBufferOutsideSmmValid ((UINTN)CommunicateHeader, OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data))) {
90 DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler CommunicateHeader invalid - 0x%x\n", CommunicateHeader));
91 Status = EFI_SUCCESS;
92 goto Done;
93 }
94
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]));
98 Status = EFI_SUCCESS;
99 goto Done;
100 }
101
102 //
103 // Call dispatch function
104 //
105 DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler Data - %x\n", &CommunicateHeader->Data[0]));
106 Status = gSmst->SmiManage (
107 &CommunicateHeader->HeaderGuid,
108 NULL,
109 &CommunicateHeader->Data[0],
110 &CommSize
111 );
112 }
113
114 Done:
115 DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler %r\n", Status));
116 DEBUG ((EFI_D_INFO, "PiSmmCommunicationHandler Exit\n"));
117
118 return (Status == EFI_SUCCESS) ? EFI_SUCCESS : EFI_INTERRUPT_PENDING;
119 }
120
121 /**
122 Allocate EfiACPIMemoryNVS below 4G memory address.
123
124 This function allocates EfiACPIMemoryNVS below 4G memory address.
125
126 @param Size Size of memory to allocate.
127
128 @return Allocated address for output.
129
130 **/
131 VOID*
132 AllocateAcpiNvsMemoryBelow4G (
133 IN UINTN Size
134 )
135 {
136 UINTN Pages;
137 EFI_PHYSICAL_ADDRESS Address;
138 EFI_STATUS Status;
139 VOID* Buffer;
140
141 Pages = EFI_SIZE_TO_PAGES (Size);
142 Address = 0xffffffff;
143
144 Status = gBS->AllocatePages (
145 AllocateMaxAddress,
146 EfiACPIMemoryNVS,
147 Pages,
148 &Address
149 );
150 ASSERT_EFI_ERROR (Status);
151
152 Buffer = (VOID *) (UINTN) Address;
153 ZeroMem (Buffer, Size);
154
155 return Buffer;
156 }
157
158 /**
159 Entry Point for PI SMM communication SMM driver.
160
161 @param[in] ImageHandle Image handle of this driver.
162 @param[in] SystemTable A Pointer to the EFI System Table.
163
164 @retval EFI_SUCEESS
165 @return Others Some error occurs.
166 **/
167 EFI_STATUS
168 EFIAPI
169 PiSmmCommunicationSmmEntryPoint (
170 IN EFI_HANDLE ImageHandle,
171 IN EFI_SYSTEM_TABLE *SystemTable
172 )
173 {
174 EFI_STATUS Status;
175 EFI_SMM_SW_DISPATCH2_PROTOCOL *SmmSwDispatch2;
176 EFI_SMM_SW_REGISTER_CONTEXT SmmSwDispatchContext;
177 EFI_HANDLE DispatchHandle;
178 EFI_PHYSICAL_ADDRESS *BufferPtrAddress;
179
180 //
181 // Register software SMI handler
182 //
183 Status = gSmst->SmmLocateProtocol (
184 &gEfiSmmSwDispatch2ProtocolGuid,
185 NULL,
186 (VOID **)&SmmSwDispatch2
187 );
188 ASSERT_EFI_ERROR (Status);
189
190 SmmSwDispatchContext.SwSmiInputValue = (UINTN)-1;
191 Status = SmmSwDispatch2->Register (
192 SmmSwDispatch2,
193 PiSmmCommunicationHandler,
194 &SmmSwDispatchContext,
195 &DispatchHandle
196 );
197 ASSERT_EFI_ERROR (Status);
198
199 DEBUG ((EFI_D_INFO, "SmmCommunication SwSmi: %x\n", (UINTN)SmmSwDispatchContext.SwSmiInputValue));
200
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));
204
205 //
206 // Save context
207 //
208 mSmmCommunicationContext.SwSmiNumber = (UINT32)SmmSwDispatchContext.SwSmiInputValue;
209 mSmmCommunicationContext.BufferPtrAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)BufferPtrAddress;
210 SetCommunicationContext ();
211
212 return Status;
213 }