2 Platform Flash Access library.
4 Copyright (c) 2016, 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 opreation.
117 @param[in] FirmwareType The type of firmware.
118 @param[in] FlashAddress The address of flash device to be accessed.
119 @param[in] FlashAddressType The type of flash device address.
120 @param[in] Buffer The pointer to the data buffer.
121 @param[in] Length The length of data buffer in bytes.
123 @retval EFI_SUCCESS The operation returns successfully.
124 @retval EFI_WRITE_PROTECTED The flash device is read only.
125 @retval EFI_UNSUPPORTED The flash device access is unsupported.
126 @retval EFI_INVALID_PARAMETER The input parameter is not valid.
131 IN PLATFORM_FIRMWARE_TYPE FirmwareType
,
132 IN EFI_PHYSICAL_ADDRESS FlashAddress
,
133 IN FLASH_ADDRESS_TYPE FlashAddressType
,
143 DEBUG((DEBUG_INFO
, "PerformFlashWrite - 0x%x(%x) - 0x%x\n", (UINTN
)FlashAddress
, (UINTN
)FlashAddressType
, Length
));
144 if (FlashAddressType
== FlashAddressTypeAbsoluteAddress
) {
145 FlashAddress
= FlashAddress
- mInternalFdAddress
;
151 SectorNum
= Length
/ SPI_ERASE_SECTOR_SIZE
;
152 for (Index
= 0; Index
< SectorNum
; Index
++){
154 (UINT8
*)(UINTN
)(FlashAddress
+ mInternalFdAddress
) + Index
* SPI_ERASE_SECTOR_SIZE
,
155 (UINT8
*)Buffer
+ Index
* SPI_ERASE_SECTOR_SIZE
,
156 SPI_ERASE_SECTOR_SIZE
) == 0) {
157 DEBUG((DEBUG_INFO
, "Sector - 0x%x - skip\n", Index
));
160 DEBUG((DEBUG_INFO
, "Sector - 0x%x - update...\n", Index
));
162 Status
= FlashFdErase (
163 (UINTN
)FlashAddress
+ Index
* SPI_ERASE_SECTOR_SIZE
165 if (Status
!= EFI_SUCCESS
){
168 NumBytes
= SPI_ERASE_SECTOR_SIZE
;
169 Status
= FlashFdWrite (
170 (UINTN
)FlashAddress
+ Index
* SPI_ERASE_SECTOR_SIZE
,
172 (UINT8
*)Buffer
+ Index
* SPI_ERASE_SECTOR_SIZE
174 if (Status
!= EFI_SUCCESS
){
183 Platform Flash Access Lib Constructor.
185 @param[in] ImageHandle The firmware allocated handle for the EFI image.
186 @param[in] SystemTable A pointer to the EFI System Table.
188 @retval EFI_SUCCESS Constructor returns successfully.
192 PerformFlashAccessLibConstructor (
193 IN EFI_HANDLE ImageHandle
,
194 IN EFI_SYSTEM_TABLE
*SystemTable
199 mInternalFdAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)PcdGet32(PcdFlashAreaBaseAddress
);
200 DEBUG((DEBUG_INFO
, "PcdFlashAreaBaseAddress - 0x%x\n", mInternalFdAddress
));
202 Status
= gBS
->LocateProtocol(&gEfiSpiProtocolGuid
, NULL
, (VOID
**)&mSpiProtocol
);
203 ASSERT_EFI_ERROR(Status
);