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/FlashDeviceLib.h>
23 #include <Library/MemoryAllocationLib.h>
25 #define SECTOR_SIZE_64KB 0x10000 // Common 64kBytes sector size
26 #define ALINGED_SIZE SECTOR_SIZE_64KB
28 STATIC EFI_PHYSICAL_ADDRESS mInternalFdAddress
;
31 Perform flash write opreation.
33 @param[in] FirmwareType The type of firmware.
34 @param[in] FlashAddress The address of flash device to be accessed.
35 @param[in] FlashAddressType The type of flash device address.
36 @param[in] Buffer The pointer to the data buffer.
37 @param[in] Length The length of data buffer in bytes.
39 @retval EFI_SUCCESS The operation returns successfully.
40 @retval EFI_WRITE_PROTECTED The flash device is read only.
41 @retval EFI_UNSUPPORTED The flash device access is unsupported.
42 @retval EFI_INVALID_PARAMETER The input parameter is not valid.
47 IN PLATFORM_FIRMWARE_TYPE FirmwareType
,
48 IN EFI_PHYSICAL_ADDRESS FlashAddress
,
49 IN FLASH_ADDRESS_TYPE FlashAddressType
,
56 DEBUG((DEBUG_INFO
, "PerformFlashWrite - 0x%x(%x) - 0x%x\n", (UINTN
)FlashAddress
, (UINTN
)FlashAddressType
, Length
));
57 if (FlashAddressType
== FlashAddressTypeRelativeAddress
) {
58 FlashAddress
= FlashAddress
+ mInternalFdAddress
;
61 DEBUG((DEBUG_INFO
, " - 0x%x(%x) - 0x%x\n", (UINTN
)FlashAddress
, (UINTN
)FlashAddressType
, Length
));
62 LibFvbFlashDeviceBlockLock((UINTN
)FlashAddress
, Length
, FALSE
);
67 Status
= LibFvbFlashDeviceBlockErase((UINTN
)FlashAddress
, Length
);
68 ASSERT_EFI_ERROR(Status
);
69 if (EFI_ERROR(Status
)) {
70 LibFvbFlashDeviceBlockLock((UINTN
)FlashAddress
, Length
, TRUE
);
71 DEBUG((DEBUG_ERROR
, "Flash Erase error\n"));
75 Status
= LibFvbFlashDeviceWrite((UINTN
)FlashAddress
, &Length
, Buffer
);
76 ASSERT_EFI_ERROR(Status
);
77 if (EFI_ERROR(Status
)) {
78 LibFvbFlashDeviceBlockLock((UINTN
)FlashAddress
, Length
, TRUE
);
79 DEBUG((DEBUG_ERROR
, "Flash write error\n"));
83 LibFvbFlashDeviceBlockLock((UINTN
)FlashAddress
, Length
, TRUE
);
89 Perform microcode write opreation.
91 @param[in] FlashAddress The address of flash device to be accessed.
92 @param[in] Buffer The pointer to the data buffer.
93 @param[in] Length The length of data buffer in bytes.
95 @retval EFI_SUCCESS The operation returns successfully.
96 @retval EFI_WRITE_PROTECTED The flash device is read only.
97 @retval EFI_UNSUPPORTED The flash device access is unsupported.
98 @retval EFI_INVALID_PARAMETER The input parameter is not valid.
102 MicrocodeFlashWrite (
103 IN EFI_PHYSICAL_ADDRESS FlashAddress
,
108 EFI_PHYSICAL_ADDRESS AlignedFlashAddress
;
115 DEBUG((DEBUG_INFO
, "MicrocodeFlashWrite - 0x%x - 0x%x\n", (UINTN
)FlashAddress
, Length
));
118 // Need make buffer 64K aligned to support ERASE
120 // [Aligned] FlashAddress [Aligned]
123 // +--------------+========+------------+
124 // | OffsetHeader | Length | OffsetTail |
125 // +--------------+========+------------+
127 // |<-----------AlignedLength----------->
129 // AlignedFlashAddress
131 OffsetHead
= FlashAddress
& (ALINGED_SIZE
- 1);
132 OffsetTail
= (FlashAddress
+ Length
) & (ALINGED_SIZE
- 1);
133 if (OffsetTail
!= 0) {
134 OffsetTail
= ALINGED_SIZE
- OffsetTail
;
137 if ((OffsetHead
!= 0) || (OffsetTail
!= 0)) {
138 AlignedFlashAddress
= FlashAddress
- OffsetHead
;
139 AlignedLength
= Length
+ OffsetHead
+ OffsetTail
;
141 AlignedBuffer
= AllocatePool(AlignedLength
);
142 if (AlignedBuffer
== NULL
) {
143 return EFI_OUT_OF_RESOURCES
;
146 // Save original buffer
148 if (OffsetHead
!= 0) {
149 CopyMem((UINT8
*)AlignedBuffer
, (VOID
*)(UINTN
)AlignedFlashAddress
, OffsetHead
);
151 if (OffsetTail
!= 0) {
152 CopyMem((UINT8
*)AlignedBuffer
+ OffsetHead
+ Length
, (VOID
*)(UINTN
)(AlignedFlashAddress
+ OffsetHead
+ Length
), OffsetTail
);
155 // Override new buffer
157 CopyMem((UINT8
*)AlignedBuffer
+ OffsetHead
, Buffer
, Length
);
159 AlignedFlashAddress
= FlashAddress
;
160 AlignedBuffer
= Buffer
;
161 AlignedLength
= Length
;
164 Status
= PerformFlashWrite(
165 PlatformFirmwareTypeSystemFirmware
,
167 FlashAddressTypeAbsoluteAddress
,
171 if ((OffsetHead
!= 0) || (OffsetTail
!= 0)) {
172 FreePool (AlignedBuffer
);
178 Platform Flash Access Lib Constructor.
182 PerformFlashAccessLibConstructor (
186 mInternalFdAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)PcdGet32(PcdFlashAreaBaseAddress
);
187 DEBUG((DEBUG_INFO
, "PcdFlashAreaBaseAddress - 0x%x\n", mInternalFdAddress
));