2 Platform Flash Access library.
4 Copyright (c) 2016 - 2018, 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
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.
17 #include <Library/BaseLib.h>
18 #include <Library/BaseMemoryLib.h>
19 #include <Library/DebugLib.h>
20 #include <Library/PcdLib.h>
21 #include <Library/PlatformFlashAccessLib.h>
22 #include <Library/UefiBootServicesTableLib.h>
23 #include <Protocol/Spi.h>
26 // SPI default opcode slots
28 #define SPI_OPCODE_JEDEC_ID_INDEX 0
29 #define SPI_OPCODE_READ_ID_INDEX 1
30 #define SPI_OPCODE_WRITE_S_INDEX 2
31 #define SPI_OPCODE_WRITE_INDEX 3
32 #define SPI_OPCODE_READ_INDEX 4
33 #define SPI_OPCODE_ERASE_INDEX 5
34 #define SPI_OPCODE_READ_S_INDEX 6
35 #define SPI_OPCODE_CHIP_ERASE_INDEX 7
37 #define SPI_ERASE_SECTOR_SIZE SIZE_4KB //This is the chipset requirement
39 STATIC EFI_PHYSICAL_ADDRESS mInternalFdAddress
;
40 EFI_SPI_PROTOCOL
*mSpiProtocol
;
43 Writes specified number of bytes from the input buffer to the address
45 @param[in] WriteAddress The flash address to be written.
46 @param[in, out] NumBytes The number of bytes.
47 @param[in] Buffer The data buffer to be written.
49 @return The status of flash write.
53 IN UINTN WriteAddress
,
54 IN OUT UINTN
*NumBytes
,
62 Status
= mSpiProtocol
->Execute (
64 SPI_OPCODE_WRITE_INDEX
, // OpcodeIndex
65 0, // PrefixOpcodeIndex
69 WriteAddress
, // Address
70 (UINT32
) (*NumBytes
), // Data Number
74 DEBUG((DEBUG_INFO
, "FlashFdWrite - 0x%x - %r\n", (UINTN
)WriteAddress
, Status
));
82 Erase a certain block from address LbaWriteAddress
84 @param[in] WriteAddress The flash address to be erased.
86 @return The status of flash erase.
95 Status
= mSpiProtocol
->Execute (
97 SPI_OPCODE_ERASE_INDEX
, // OpcodeIndex
98 0, // PrefixOpcodeIndex
102 WriteAddress
, // Address
105 EnumSpiRegionBios
// SPI_REGION_TYPE
107 DEBUG((DEBUG_INFO
, "FlashFdErase - 0x%x - %r\n", (UINTN
)WriteAddress
, Status
));
115 Perform flash write operation with progress indicator. The start and end
116 completion percentage values are passed into this function. If the requested
117 flash write operation is broken up, then completion percentage between the
118 start and end values may be passed to the provided Progress function. The
119 caller of this function is required to call the Progress function for the
120 start and end completion percentage values. This allows the Progress,
121 StartPercentage, and EndPercentage parameters to be ignored if the requested
122 flash write operation can not be broken up
124 @param[in] FirmwareType The type of firmware.
125 @param[in] FlashAddress The address of flash device to be accessed.
126 @param[in] FlashAddressType The type of flash device address.
127 @param[in] Buffer The pointer to the data buffer.
128 @param[in] Length The length of data buffer in bytes.
129 @param[in] Progress A function used report the progress of the
130 firmware update. This is an optional parameter
132 @param[in] StartPercentage The start completion percentage value that may
133 be used to report progress during the flash
135 @param[in] EndPercentage The end completion percentage value that may
136 be used to report progress during the flash
139 @retval EFI_SUCCESS The operation returns successfully.
140 @retval EFI_WRITE_PROTECTED The flash device is read only.
141 @retval EFI_UNSUPPORTED The flash device access is unsupported.
142 @retval EFI_INVALID_PARAMETER The input parameter is not valid.
146 PerformFlashWriteWithProgress (
147 IN PLATFORM_FIRMWARE_TYPE FirmwareType
,
148 IN EFI_PHYSICAL_ADDRESS FlashAddress
,
149 IN FLASH_ADDRESS_TYPE FlashAddressType
,
152 IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress
, OPTIONAL
153 IN UINTN StartPercentage
,
154 IN UINTN EndPercentage
162 DEBUG((DEBUG_INFO
, "PerformFlashWrite - 0x%x(%x) - 0x%x\n", (UINTN
)FlashAddress
, (UINTN
)FlashAddressType
, Length
));
163 if (FlashAddressType
== FlashAddressTypeAbsoluteAddress
) {
164 FlashAddress
= FlashAddress
- mInternalFdAddress
;
170 SectorNum
= Length
/ SPI_ERASE_SECTOR_SIZE
;
171 for (Index
= 0; Index
< SectorNum
; Index
++){
172 if (Progress
!= NULL
) {
173 Progress (StartPercentage
+ ((Index
* (EndPercentage
- StartPercentage
)) / SectorNum
));
177 (UINT8
*)(UINTN
)(FlashAddress
+ mInternalFdAddress
) + Index
* SPI_ERASE_SECTOR_SIZE
,
178 (UINT8
*)Buffer
+ Index
* SPI_ERASE_SECTOR_SIZE
,
179 SPI_ERASE_SECTOR_SIZE
) == 0) {
180 DEBUG((DEBUG_INFO
, "Sector - 0x%x - skip\n", Index
));
183 DEBUG((DEBUG_INFO
, "Sector - 0x%x - update...\n", Index
));
185 Status
= FlashFdErase (
186 (UINTN
)FlashAddress
+ Index
* SPI_ERASE_SECTOR_SIZE
188 if (Status
!= EFI_SUCCESS
){
191 NumBytes
= SPI_ERASE_SECTOR_SIZE
;
192 Status
= FlashFdWrite (
193 (UINTN
)FlashAddress
+ Index
* SPI_ERASE_SECTOR_SIZE
,
195 (UINT8
*)Buffer
+ Index
* SPI_ERASE_SECTOR_SIZE
197 if (Status
!= EFI_SUCCESS
){
201 if (Progress
!= NULL
) {
202 Progress (EndPercentage
);
209 Perform flash write operation.
211 @param[in] FirmwareType The type of firmware.
212 @param[in] FlashAddress The address of flash device to be accessed.
213 @param[in] FlashAddressType The type of flash device address.
214 @param[in] Buffer The pointer to the data buffer.
215 @param[in] Length The length of data buffer in bytes.
217 @retval EFI_SUCCESS The operation returns successfully.
218 @retval EFI_WRITE_PROTECTED The flash device is read only.
219 @retval EFI_UNSUPPORTED The flash device access is unsupported.
220 @retval EFI_INVALID_PARAMETER The input parameter is not valid.
225 IN PLATFORM_FIRMWARE_TYPE FirmwareType
,
226 IN EFI_PHYSICAL_ADDRESS FlashAddress
,
227 IN FLASH_ADDRESS_TYPE FlashAddressType
,
232 return PerformFlashWriteWithProgress (
245 Platform Flash Access Lib Constructor.
247 @param[in] ImageHandle The firmware allocated handle for the EFI image.
248 @param[in] SystemTable A pointer to the EFI System Table.
250 @retval EFI_SUCCESS Constructor returns successfully.
254 PerformFlashAccessLibConstructor (
255 IN EFI_HANDLE ImageHandle
,
256 IN EFI_SYSTEM_TABLE
*SystemTable
261 mInternalFdAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)PcdGet32(PcdFlashAreaBaseAddress
);
262 DEBUG((DEBUG_INFO
, "PcdFlashAreaBaseAddress - 0x%x\n", mInternalFdAddress
));
264 Status
= gBS
->LocateProtocol(&gEfiSpiProtocolGuid
, NULL
, (VOID
**)&mSpiProtocol
);
265 ASSERT_EFI_ERROR(Status
);