VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.c@ 77678

最後變更 在這個檔案從77678是 77662,由 vboxsync 提交於 6 年 前

EFI: First step in UDK2018 merge. Does not build yet.

  • 屬性 svn:eol-style 設為 native
檔案大小: 6.6 KB
 
1/** @file
2PiSmmCommunication SMM Driver.
3
4Copyright (c) 2010 - 2017, Intel Corporation. All rights reserved.<BR>
5This program and the accompanying materials
6are licensed and made available under the terms and conditions of the BSD License
7which accompanies this distribution. The full text of the license may be found at
8http://opensource.org/licenses/bsd-license.php
9
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11WITHOUT 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
30EFI_SMM_COMMUNICATION_CONTEXT mSmmCommunicationContext = {
31 SMM_COMMUNICATION_SIGNATURE
32};
33
34/**
35 Set SMM communication context.
36**/
37VOID
38SetCommunicationContext (
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**/
66EFI_STATUS
67EFIAPI
68PiSmmCommunicationHandler (
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
114Done:
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**/
131VOID*
132AllocateAcpiNvsMemoryBelow4G (
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**/
167EFI_STATUS
168EFIAPI
169PiSmmCommunicationSmmEntryPoint (
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}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette