2 Implementation of helper routines for DXE environment.
4 Copyright (c) 2013 - 2016 Intel Corporation.
6 SPDX-License-Identifier: BSD-2-Clause-Patent
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>
20 #include <Guid/MemoryConfigData.h>
21 #include <Guid/QuarkVariableLock.h>
23 #include "CommonHeader.h"
25 #define FLASH_BLOCK_SIZE SIZE_4KB
30 EFI_SPI_PROTOCOL
*mPlatHelpSpiProtocolRef
= NULL
;
33 // Routines defined in other source modules of this component.
37 // Routines local to this component.
41 // Routines shared with other souce modules in this component.
46 IN EFI_SMM_SYSTEM_TABLE2
*Smst
49 if (mPlatHelpSpiProtocolRef
== NULL
) {
51 Smst
->SmmLocateProtocol (
52 &gEfiSmmSpiProtocolGuid
,
54 (VOID
**) &mPlatHelpSpiProtocolRef
60 (VOID
**) &mPlatHelpSpiProtocolRef
63 ASSERT (mPlatHelpSpiProtocolRef
!= NULL
);
65 return mPlatHelpSpiProtocolRef
;
69 // Routines exported by this source module.
73 Find pointer to RAW data in Firmware volume file.
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.
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).
88 PlatformFindFvFileRawDataSection (
89 IN CONST EFI_GUID
*FvNameGuid OPTIONAL
,
90 IN CONST EFI_GUID
*FileNameGuid
,
91 OUT VOID
**SectionData
,
92 OUT UINTN
*SectionDataSize
95 if (FileNameGuid
== NULL
|| SectionData
== NULL
|| SectionDataSize
== NULL
) {
96 return EFI_INVALID_PARAMETER
;
98 if (FvNameGuid
!= NULL
) {
99 return EFI_UNSUPPORTED
; // Searching in specific FV unsupported in DXE.
102 return GetSectionFromAnyFv (FileNameGuid
, EFI_SECTION_RAW
, 0, SectionData
, SectionDataSize
);
106 Find free spi protect register and write to it to protect a flash region.
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.
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.
119 PlatformWriteFirstFreeSpiProtect (
120 IN CONST UINT32 DirectValue
,
121 IN CONST UINT32 BaseAddress
,
122 IN CONST UINT32 Length
126 UINT32 PchRootComplexBar
;
129 PchRootComplexBar
= QNC_RCRB_BASE
;
131 Status
= WriteFirstFreeSpiProtect (
139 if (!EFI_ERROR (Status
)) {
140 S3BootScriptSaveMemWrite (
141 S3BootScriptWidthUint32
,
142 (UINTN
) (PchRootComplexBar
+ FreeOffset
),
144 (VOID
*) (UINTN
) (PchRootComplexBar
+ FreeOffset
)
152 Lock legacy SPI static configuration information.
154 Function will assert if unable to lock config.
159 PlatformFlashLockConfig (
164 EFI_SPI_PROTOCOL
*SpiProtocol
;
167 // Enable lock of legacy SPI static configuration information.
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
);
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"));
180 ASSERT_EFI_ERROR (Status
);
186 Platform Variable Lock.
188 @retval EFI_SUCCESS Platform Variable Lock successful.
189 @retval EFI_NOT_FOUND No protocol instances were found that match Protocol and
195 PlatformVariableLock (
199 EDKII_VARIABLE_LOCK_PROTOCOL
*VariableLockProtocol
;
201 Status
= gBS
->LocateProtocol (&gEdkiiVariableLockProtocolGuid
, NULL
, (VOID
**)&VariableLockProtocol
);
202 ASSERT_EFI_ERROR (Status
);
204 Status
= VariableLockProtocol
->RequestToLock (
205 VariableLockProtocol
,
206 QUARK_VARIABLE_LOCK_NAME
,
207 &gQuarkVariableLockGuid
209 ASSERT_EFI_ERROR (Status
);
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
217 ASSERT_EFI_ERROR (Status
);
221 Lock regions and config of SPI flash given the policy for this platform.
223 Function will assert if unable to lock regions or config.
225 @param PreBootPolicy If TRUE do Pre Boot Flash Lock Policy.
230 PlatformFlashLockPolicy (
231 IN CONST BOOLEAN PreBootPolicy
235 UINT64 CpuAddressNvStorage
;
236 UINT64 CpuAddressFlashDevice
;
238 EFI_BOOT_MODE BootMode
;
239 UINTN SpiFlashDeviceSize
;
241 BootMode
= GetBootModeHob ();
243 SpiFlashDeviceSize
= (UINTN
) PcdGet32 (PcdSpiFlashDeviceSize
);
244 CpuAddressFlashDevice
= SIZE_4GB
- SpiFlashDeviceSize
;
247 "Platform:FlashDeviceSize = 0x%08x Bytes\n",
252 // If not in update or recovery mode, lock stuff down
254 if ((BootMode
!= BOOT_IN_RECOVERY_MODE
) && (BootMode
!= BOOT_ON_FLASH_UPDATE
)) {
259 CpuAddressNvStorage
= (UINT64
) PcdGet32 (PcdFlashNvStorageVariableBase
);
262 // Lock from start of flash device up to Smi writable flash storage areas.
265 if (!PlatformIsSpiRangeProtected ((UINT32
) SpiAddress
, (UINT32
) (CpuAddressNvStorage
- CpuAddressFlashDevice
))) {
268 "Platform: Protect Region Base:Len 0x%08x:0x%08x\n",
269 (UINTN
) SpiAddress
, (UINTN
)(CpuAddressNvStorage
- CpuAddressFlashDevice
))
271 Status
= PlatformWriteFirstFreeSpiProtect (
274 (UINT32
) (CpuAddressNvStorage
- CpuAddressFlashDevice
)
277 ASSERT_EFI_ERROR (Status
);
280 // Move Spi Address to after Smi writable flash storage areas.
282 SpiAddress
= CpuAddressNvStorage
- CpuAddressFlashDevice
;
283 SpiAddress
+= ((UINT64
) PcdGet32 (PcdFlashNvStorageVariableSize
));
286 // Lock from end of OEM area to end of flash part.
288 if (!PlatformIsSpiRangeProtected ((UINT32
) SpiAddress
, SpiFlashDeviceSize
- ((UINT32
) SpiAddress
))) {
291 "Platform: Protect Region Base:Len 0x%08x:0x%08x\n",
293 (UINTN
) (SpiFlashDeviceSize
- ((UINT32
) SpiAddress
)))
295 ASSERT (SpiAddress
< ((UINT64
) SpiFlashDeviceSize
));
296 Status
= PlatformWriteFirstFreeSpiProtect (
299 SpiFlashDeviceSize
- ((UINT32
) SpiAddress
)
302 ASSERT_EFI_ERROR (Status
);
307 // Always Lock flash config registers if about to boot a boot option
308 // else lock depending on boot mode.
310 if (PreBootPolicy
|| (BootMode
!= BOOT_ON_FLASH_UPDATE
)) {
311 PlatformFlashLockConfig ();
315 // Enable Quark Variable lock if PreBootPolicy.
318 PlatformVariableLock ();
322 /** Check if System booted with recovery Boot Stage1 image.
324 @retval TRUE If system booted with recovery Boot Stage1 image.
325 @retval FALSE If system booted with normal stage1 image.
330 PlatformIsBootWithRecoveryStage1 (
334 ASSERT_EFI_ERROR (EFI_UNSUPPORTED
);