]> git.proxmox.com Git - mirror_edk2.git/blame - Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.c
Vlv2TbltDevicePkg/PlatformFlashAccessLib: Add instance for update.
[mirror_edk2.git] / Vlv2TbltDevicePkg / Feature / Capsule / Library / PlatformFlashAccessLib / PlatformFlashAccessLib.c
CommitLineData
75ce133c
JY
1/** @file\r
2 Platform Flash Access library.\r
3\r
4 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <PiDxe.h>\r
16\r
17#include <Library/BaseLib.h>\r
18#include <Library/BaseMemoryLib.h>\r
19#include <Library/DebugLib.h>\r
20#include <Library/PcdLib.h>\r
21#include <Library/PlatformFlashAccessLib.h>\r
22#include <Library/FlashDeviceLib.h>\r
23#include <Library/MemoryAllocationLib.h>\r
24\r
25#define SECTOR_SIZE_64KB 0x10000 // Common 64kBytes sector size\r
26#define ALINGED_SIZE SECTOR_SIZE_64KB\r
27\r
28STATIC EFI_PHYSICAL_ADDRESS mInternalFdAddress;\r
29\r
30/**\r
31 Perform flash write opreation.\r
32\r
33 @param[in] FirmwareType The type of firmware.\r
34 @param[in] FlashAddress The address of flash device to be accessed.\r
35 @param[in] FlashAddressType The type of flash device address.\r
36 @param[in] Buffer The pointer to the data buffer.\r
37 @param[in] Length The length of data buffer in bytes.\r
38\r
39 @retval EFI_SUCCESS The operation returns successfully.\r
40 @retval EFI_WRITE_PROTECTED The flash device is read only.\r
41 @retval EFI_UNSUPPORTED The flash device access is unsupported.\r
42 @retval EFI_INVALID_PARAMETER The input parameter is not valid.\r
43**/\r
44EFI_STATUS\r
45EFIAPI\r
46PerformFlashWrite (\r
47 IN PLATFORM_FIRMWARE_TYPE FirmwareType,\r
48 IN EFI_PHYSICAL_ADDRESS FlashAddress,\r
49 IN FLASH_ADDRESS_TYPE FlashAddressType,\r
50 IN VOID *Buffer,\r
51 IN UINTN Length\r
52 )\r
53{\r
54 EFI_STATUS Status;\r
55\r
56 DEBUG((DEBUG_INFO, "PerformFlashWrite - 0x%x(%x) - 0x%x\n", (UINTN)FlashAddress, (UINTN)FlashAddressType, Length));\r
57 if (FlashAddressType == FlashAddressTypeRelativeAddress) {\r
58 FlashAddress = FlashAddress + mInternalFdAddress;\r
59 }\r
60\r
61 DEBUG((DEBUG_INFO, " - 0x%x(%x) - 0x%x\n", (UINTN)FlashAddress, (UINTN)FlashAddressType, Length));\r
62 LibFvbFlashDeviceBlockLock(FlashAddress, Length, FALSE);\r
63\r
64 //\r
65 // Erase & Write\r
66 //\r
67 Status = LibFvbFlashDeviceBlockErase((UINTN)FlashAddress, Length);\r
68 ASSERT_EFI_ERROR(Status);\r
69 if (EFI_ERROR(Status)) {\r
70 LibFvbFlashDeviceBlockLock(FlashAddress, Length, TRUE);\r
71 DEBUG((DEBUG_ERROR, "Flash Erase error\n"));\r
72 return Status;\r
73 }\r
74\r
75 Status = LibFvbFlashDeviceWrite((UINTN)FlashAddress, &Length, Buffer);\r
76 ASSERT_EFI_ERROR(Status);\r
77 if (EFI_ERROR(Status)) {\r
78 LibFvbFlashDeviceBlockLock(FlashAddress, Length, TRUE);\r
79 DEBUG((DEBUG_ERROR, "Flash write error\n"));\r
80 return Status;\r
81 }\r
82\r
83 LibFvbFlashDeviceBlockLock(FlashAddress, Length, TRUE);\r
84\r
85 return EFI_SUCCESS;\r
86}\r
87\r
88/**\r
89 Perform microcode write opreation.\r
90\r
91 @param[in] FlashAddress The address of flash device to be accessed.\r
92 @param[in] Buffer The pointer to the data buffer.\r
93 @param[in] Length The length of data buffer in bytes.\r
94\r
95 @retval EFI_SUCCESS The operation returns successfully.\r
96 @retval EFI_WRITE_PROTECTED The flash device is read only.\r
97 @retval EFI_UNSUPPORTED The flash device access is unsupported.\r
98 @retval EFI_INVALID_PARAMETER The input parameter is not valid.\r
99**/\r
100EFI_STATUS\r
101EFIAPI\r
102MicrocodeFlashWrite (\r
103 IN EFI_PHYSICAL_ADDRESS FlashAddress,\r
104 IN VOID *Buffer,\r
105 IN UINTN Length\r
106 )\r
107{\r
108 EFI_PHYSICAL_ADDRESS AlignedFlashAddress;\r
109 VOID *AlignedBuffer;\r
110 UINTN AlignedLength;\r
111 UINTN OffsetHead;\r
112 UINTN OffsetTail;\r
113 EFI_STATUS Status;\r
114\r
115 DEBUG((DEBUG_INFO, "MicrocodeFlashWrite - 0x%x - 0x%x\n", (UINTN)FlashAddress, Length));\r
116\r
117 //\r
118 // Need make buffer 64K aligned to support ERASE\r
119 //\r
120 // [Aligned] FlashAddress [Aligned]\r
121 // | | |\r
122 // V V V\r
123 // +--------------+========+------------+\r
124 // | OffsetHeader | Length | OffsetTail |\r
125 // +--------------+========+------------+\r
126 // ^\r
127 // |<-----------AlignedLength----------->\r
128 // |\r
129 // AlignedFlashAddress\r
130 //\r
131 OffsetHead = FlashAddress & (ALINGED_SIZE - 1);\r
132 OffsetTail = (FlashAddress + Length) & (ALINGED_SIZE - 1);\r
133 if (OffsetTail != 0) {\r
134 OffsetTail = ALINGED_SIZE - OffsetTail;\r
135 }\r
136\r
137 if ((OffsetHead != 0) || (OffsetTail != 0)) {\r
138 AlignedFlashAddress = FlashAddress - OffsetHead;\r
139 AlignedLength = Length + OffsetHead + OffsetTail;\r
140\r
141 AlignedBuffer = AllocatePool(AlignedLength);\r
142 if (AlignedBuffer == NULL) {\r
143 return EFI_OUT_OF_RESOURCES;\r
144 }\r
145 //\r
146 // Save original buffer\r
147 //\r
148 if (OffsetHead != 0) {\r
149 CopyMem((UINT8 *)AlignedBuffer, (VOID *)AlignedFlashAddress, OffsetHead);\r
150 }\r
151 if (OffsetTail != 0) {\r
152 CopyMem((UINT8 *)AlignedBuffer + OffsetHead + Length, (VOID *)(AlignedFlashAddress + OffsetHead + Length), OffsetTail);\r
153 }\r
154 //\r
155 // Override new buffer\r
156 //\r
157 CopyMem((UINT8 *)AlignedBuffer + OffsetHead, Buffer, Length);\r
158 } else {\r
159 AlignedFlashAddress = FlashAddress;\r
160 AlignedBuffer = Buffer;\r
161 AlignedLength = Length;\r
162 }\r
163\r
164 Status = PerformFlashWrite(\r
165 PlatformFirmwareTypeSystemFirmware,\r
166 AlignedFlashAddress,\r
167 FlashAddressTypeAbsoluteAddress,\r
168 AlignedBuffer,\r
169 AlignedLength\r
170 );\r
171 if ((OffsetHead != 0) || (OffsetTail != 0)) {\r
172 FreePool (AlignedBuffer);\r
173 }\r
174 return Status;\r
175}\r
176\r
177/**\r
178 Platform Flash Access Lib Constructor.\r
179**/\r
180EFI_STATUS\r
181EFIAPI\r
182PerformFlashAccessLibConstructor (\r
183 VOID\r
184 )\r
185{\r
186 mInternalFdAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32(PcdFlashAreaBaseAddress);\r
187 DEBUG((DEBUG_INFO, "PcdFlashAreaBaseAddress - 0x%x\n", mInternalFdAddress));\r
188\r
189 return EFI_SUCCESS;\r
190}\r