]> git.proxmox.com Git - mirror_edk2.git/blob - QuarkPlatformPkg/Library/PlatformHelperLib/PlatformHelperDxe.c
a0acf88c2bc2f20e9bf0b9b659c625c64f8b79b5
[mirror_edk2.git] / QuarkPlatformPkg / Library / PlatformHelperLib / PlatformHelperDxe.c
1 /** @file
2 Implementation of helper routines for DXE environment.
3
4 Copyright (c) 2013 - 2016 Intel Corporation.
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include <PiDxe.h>
11
12 #include <Library/UefiBootServicesTableLib.h>
13 #include <Library/S3BootScriptLib.h>
14 #include <Library/DxeServicesLib.h>
15 #include <Library/UefiRuntimeServicesTableLib.h>
16 #include <Protocol/SmmBase2.h>
17 #include <Protocol/Spi.h>
18 #include <Protocol/VariableLock.h>
19
20 #include <Guid/MemoryConfigData.h>
21 #include <Guid/QuarkVariableLock.h>
22
23 #include "CommonHeader.h"
24
25 #define FLASH_BLOCK_SIZE SIZE_4KB
26
27 //
28 // Global variables.
29 //
30 EFI_SPI_PROTOCOL *mPlatHelpSpiProtocolRef = NULL;
31
32 //
33 // Routines defined in other source modules of this component.
34 //
35
36 //
37 // Routines local to this component.
38 //
39
40 //
41 // Routines shared with other souce modules in this component.
42 //
43
44 EFI_SPI_PROTOCOL *
45 LocateSpiProtocol (
46 IN EFI_SMM_SYSTEM_TABLE2 *Smst
47 )
48 {
49 if (mPlatHelpSpiProtocolRef == NULL) {
50 if (Smst != NULL) {
51 Smst->SmmLocateProtocol (
52 &gEfiSmmSpiProtocolGuid,
53 NULL,
54 (VOID **) &mPlatHelpSpiProtocolRef
55 );
56 } else {
57 gBS->LocateProtocol (
58 &gEfiSpiProtocolGuid,
59 NULL,
60 (VOID **) &mPlatHelpSpiProtocolRef
61 );
62 }
63 ASSERT (mPlatHelpSpiProtocolRef != NULL);
64 }
65 return mPlatHelpSpiProtocolRef;
66 }
67
68 //
69 // Routines exported by this source module.
70 //
71
72 /**
73 Find pointer to RAW data in Firmware volume file.
74
75 @param FvNameGuid Firmware volume to search. If == NULL search all.
76 @param FileNameGuid Firmware volume file to search for.
77 @param SectionData Pointer to RAW data section of found file.
78 @param SectionDataSize Pointer to UNITN to get size of RAW data.
79
80 @retval EFI_SUCCESS Raw Data found.
81 @retval EFI_INVALID_PARAMETER FileNameGuid == NULL.
82 @retval EFI_NOT_FOUND Firmware volume file not found.
83 @retval EFI_UNSUPPORTED Unsupported in current enviroment (PEI or DXE).
84
85 **/
86 EFI_STATUS
87 EFIAPI
88 PlatformFindFvFileRawDataSection (
89 IN CONST EFI_GUID *FvNameGuid OPTIONAL,
90 IN CONST EFI_GUID *FileNameGuid,
91 OUT VOID **SectionData,
92 OUT UINTN *SectionDataSize
93 )
94 {
95 if (FileNameGuid == NULL || SectionData == NULL || SectionDataSize == NULL) {
96 return EFI_INVALID_PARAMETER;
97 }
98 if (FvNameGuid != NULL) {
99 return EFI_UNSUPPORTED; // Searching in specific FV unsupported in DXE.
100 }
101
102 return GetSectionFromAnyFv (FileNameGuid, EFI_SECTION_RAW, 0, SectionData, SectionDataSize);
103 }
104
105 /**
106 Find free spi protect register and write to it to protect a flash region.
107
108 @param DirectValue Value to directly write to register.
109 if DirectValue == 0 the use Base & Length below.
110 @param BaseAddress Base address of region in Flash Memory Map.
111 @param Length Length of region to protect.
112
113 @retval EFI_SUCCESS Free spi protect register found & written.
114 @retval EFI_NOT_FOUND Free Spi protect register not found.
115 @retval EFI_DEVICE_ERROR Unable to write to spi protect register.
116 **/
117 EFI_STATUS
118 EFIAPI
119 PlatformWriteFirstFreeSpiProtect (
120 IN CONST UINT32 DirectValue,
121 IN CONST UINT32 BaseAddress,
122 IN CONST UINT32 Length
123 )
124 {
125 UINT32 FreeOffset;
126 UINT32 PchRootComplexBar;
127 EFI_STATUS Status;
128
129 PchRootComplexBar = QNC_RCRB_BASE;
130
131 Status = WriteFirstFreeSpiProtect (
132 PchRootComplexBar,
133 DirectValue,
134 BaseAddress,
135 Length,
136 &FreeOffset
137 );
138
139 if (!EFI_ERROR (Status)) {
140 S3BootScriptSaveMemWrite (
141 S3BootScriptWidthUint32,
142 (UINTN) (PchRootComplexBar + FreeOffset),
143 1,
144 (VOID *) (UINTN) (PchRootComplexBar + FreeOffset)
145 );
146 }
147
148 return Status;
149 }
150
151 /**
152 Lock legacy SPI static configuration information.
153
154 Function will assert if unable to lock config.
155
156 **/
157 VOID
158 EFIAPI
159 PlatformFlashLockConfig (
160 VOID
161 )
162 {
163 EFI_STATUS Status;
164 EFI_SPI_PROTOCOL *SpiProtocol;
165
166 //
167 // Enable lock of legacy SPI static configuration information.
168 //
169
170 SpiProtocol = LocateSpiProtocol (NULL); // This routine will not be called in SMM.
171 ASSERT (SpiProtocol != NULL);
172 if (SpiProtocol != NULL) {
173 Status = SpiProtocol->Lock (SpiProtocol);
174
175 if (!EFI_ERROR (Status)) {
176 DEBUG ((EFI_D_INFO, "Platform: Spi Config Locked Down\n"));
177 } else if (Status == EFI_ACCESS_DENIED) {
178 DEBUG ((EFI_D_INFO, "Platform: Spi Config already locked down\n"));
179 } else {
180 ASSERT_EFI_ERROR (Status);
181 }
182 }
183 }
184
185 /**
186 Platform Variable Lock.
187
188 @retval EFI_SUCCESS Platform Variable Lock successful.
189 @retval EFI_NOT_FOUND No protocol instances were found that match Protocol and
190 Registration.
191
192 **/
193 VOID
194 EFIAPI
195 PlatformVariableLock (
196 )
197 {
198 EFI_STATUS Status;
199 EDKII_VARIABLE_LOCK_PROTOCOL *VariableLockProtocol;
200
201 Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLockProtocol);
202 ASSERT_EFI_ERROR (Status);
203
204 Status = VariableLockProtocol->RequestToLock (
205 VariableLockProtocol,
206 QUARK_VARIABLE_LOCK_NAME,
207 &gQuarkVariableLockGuid
208 );
209 ASSERT_EFI_ERROR (Status);
210
211 // Memory Config Data shouldn't be writable when Quark Variable Lock is enabled.
212 Status = VariableLockProtocol->RequestToLock (
213 VariableLockProtocol,
214 EFI_MEMORY_CONFIG_DATA_NAME,
215 &gEfiMemoryConfigDataGuid
216 );
217 ASSERT_EFI_ERROR (Status);
218 }
219
220 /**
221 Lock regions and config of SPI flash given the policy for this platform.
222
223 Function will assert if unable to lock regions or config.
224
225 @param PreBootPolicy If TRUE do Pre Boot Flash Lock Policy.
226
227 **/
228 VOID
229 EFIAPI
230 PlatformFlashLockPolicy (
231 IN CONST BOOLEAN PreBootPolicy
232 )
233 {
234 EFI_STATUS Status;
235 UINT64 CpuAddressNvStorage;
236 UINT64 CpuAddressFlashDevice;
237 UINT64 SpiAddress;
238 EFI_BOOT_MODE BootMode;
239 UINTN SpiFlashDeviceSize;
240
241 BootMode = GetBootModeHob ();
242
243 SpiFlashDeviceSize = (UINTN) PcdGet32 (PcdSpiFlashDeviceSize);
244 CpuAddressFlashDevice = SIZE_4GB - SpiFlashDeviceSize;
245 DEBUG (
246 (EFI_D_INFO,
247 "Platform:FlashDeviceSize = 0x%08x Bytes\n",
248 SpiFlashDeviceSize)
249 );
250
251 //
252 // If not in update or recovery mode, lock stuff down
253 //
254 if ((BootMode != BOOT_IN_RECOVERY_MODE) && (BootMode != BOOT_ON_FLASH_UPDATE)) {
255
256 //
257 // Lock regions
258 //
259 CpuAddressNvStorage = (UINT64) PcdGet32 (PcdFlashNvStorageVariableBase);
260
261 //
262 // Lock from start of flash device up to Smi writable flash storage areas.
263 //
264 SpiAddress = 0;
265 if (!PlatformIsSpiRangeProtected ((UINT32) SpiAddress, (UINT32) (CpuAddressNvStorage - CpuAddressFlashDevice))) {
266 DEBUG (
267 (EFI_D_INFO,
268 "Platform: Protect Region Base:Len 0x%08x:0x%08x\n",
269 (UINTN) SpiAddress, (UINTN)(CpuAddressNvStorage - CpuAddressFlashDevice))
270 );
271 Status = PlatformWriteFirstFreeSpiProtect (
272 0,
273 (UINT32) SpiAddress,
274 (UINT32) (CpuAddressNvStorage - CpuAddressFlashDevice)
275 );
276
277 ASSERT_EFI_ERROR (Status);
278 }
279 //
280 // Move Spi Address to after Smi writable flash storage areas.
281 //
282 SpiAddress = CpuAddressNvStorage - CpuAddressFlashDevice;
283 SpiAddress += ((UINT64) PcdGet32 (PcdFlashNvStorageVariableSize));
284
285 //
286 // Lock from end of OEM area to end of flash part.
287 //
288 if (!PlatformIsSpiRangeProtected ((UINT32) SpiAddress, SpiFlashDeviceSize - ((UINT32) SpiAddress))) {
289 DEBUG (
290 (EFI_D_INFO,
291 "Platform: Protect Region Base:Len 0x%08x:0x%08x\n",
292 (UINTN) SpiAddress,
293 (UINTN) (SpiFlashDeviceSize - ((UINT32) SpiAddress)))
294 );
295 ASSERT (SpiAddress < ((UINT64) SpiFlashDeviceSize));
296 Status = PlatformWriteFirstFreeSpiProtect (
297 0,
298 (UINT32) SpiAddress,
299 SpiFlashDeviceSize - ((UINT32) SpiAddress)
300 );
301
302 ASSERT_EFI_ERROR (Status);
303 }
304 }
305
306 //
307 // Always Lock flash config registers if about to boot a boot option
308 // else lock depending on boot mode.
309 //
310 if (PreBootPolicy || (BootMode != BOOT_ON_FLASH_UPDATE)) {
311 PlatformFlashLockConfig ();
312 }
313
314 //
315 // Enable Quark Variable lock if PreBootPolicy.
316 //
317 if (PreBootPolicy) {
318 PlatformVariableLock ();
319 }
320 }
321
322 /** Check if System booted with recovery Boot Stage1 image.
323
324 @retval TRUE If system booted with recovery Boot Stage1 image.
325 @retval FALSE If system booted with normal stage1 image.
326
327 **/
328 BOOLEAN
329 EFIAPI
330 PlatformIsBootWithRecoveryStage1 (
331 VOID
332 )
333 {
334 ASSERT_EFI_ERROR (EFI_UNSUPPORTED);
335 return FALSE;
336 }
337