]> git.proxmox.com Git - mirror_edk2.git/blob - Vlv2TbltDevicePkg/Feature/Capsule/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.c
Vlv2TbltDevicePkg/PlatformFlashAccessLib: Fix IA32 build issues
[mirror_edk2.git] / Vlv2TbltDevicePkg / Feature / Capsule / Library / PlatformFlashAccessLib / PlatformFlashAccessLib.c
1 /** @file
2 Platform Flash Access library.
3
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
9
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.
12
13 **/
14
15 #include <PiDxe.h>
16
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>
24
25 #define SECTOR_SIZE_64KB 0x10000 // Common 64kBytes sector size
26 #define ALINGED_SIZE SECTOR_SIZE_64KB
27
28 STATIC EFI_PHYSICAL_ADDRESS mInternalFdAddress;
29
30 /**
31 Perform flash write opreation.
32
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.
38
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.
43 **/
44 EFI_STATUS
45 EFIAPI
46 PerformFlashWrite (
47 IN PLATFORM_FIRMWARE_TYPE FirmwareType,
48 IN EFI_PHYSICAL_ADDRESS FlashAddress,
49 IN FLASH_ADDRESS_TYPE FlashAddressType,
50 IN VOID *Buffer,
51 IN UINTN Length
52 )
53 {
54 EFI_STATUS Status;
55
56 DEBUG((DEBUG_INFO, "PerformFlashWrite - 0x%x(%x) - 0x%x\n", (UINTN)FlashAddress, (UINTN)FlashAddressType, Length));
57 if (FlashAddressType == FlashAddressTypeRelativeAddress) {
58 FlashAddress = FlashAddress + mInternalFdAddress;
59 }
60
61 DEBUG((DEBUG_INFO, " - 0x%x(%x) - 0x%x\n", (UINTN)FlashAddress, (UINTN)FlashAddressType, Length));
62 LibFvbFlashDeviceBlockLock((UINTN)FlashAddress, Length, FALSE);
63
64 //
65 // Erase & Write
66 //
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"));
72 return Status;
73 }
74
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"));
80 return Status;
81 }
82
83 LibFvbFlashDeviceBlockLock((UINTN)FlashAddress, Length, TRUE);
84
85 return EFI_SUCCESS;
86 }
87
88 /**
89 Perform microcode write opreation.
90
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.
94
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.
99 **/
100 EFI_STATUS
101 EFIAPI
102 MicrocodeFlashWrite (
103 IN EFI_PHYSICAL_ADDRESS FlashAddress,
104 IN VOID *Buffer,
105 IN UINTN Length
106 )
107 {
108 EFI_PHYSICAL_ADDRESS AlignedFlashAddress;
109 VOID *AlignedBuffer;
110 UINTN AlignedLength;
111 UINTN OffsetHead;
112 UINTN OffsetTail;
113 EFI_STATUS Status;
114
115 DEBUG((DEBUG_INFO, "MicrocodeFlashWrite - 0x%x - 0x%x\n", (UINTN)FlashAddress, Length));
116
117 //
118 // Need make buffer 64K aligned to support ERASE
119 //
120 // [Aligned] FlashAddress [Aligned]
121 // | | |
122 // V V V
123 // +--------------+========+------------+
124 // | OffsetHeader | Length | OffsetTail |
125 // +--------------+========+------------+
126 // ^
127 // |<-----------AlignedLength----------->
128 // |
129 // AlignedFlashAddress
130 //
131 OffsetHead = FlashAddress & (ALINGED_SIZE - 1);
132 OffsetTail = (FlashAddress + Length) & (ALINGED_SIZE - 1);
133 if (OffsetTail != 0) {
134 OffsetTail = ALINGED_SIZE - OffsetTail;
135 }
136
137 if ((OffsetHead != 0) || (OffsetTail != 0)) {
138 AlignedFlashAddress = FlashAddress - OffsetHead;
139 AlignedLength = Length + OffsetHead + OffsetTail;
140
141 AlignedBuffer = AllocatePool(AlignedLength);
142 if (AlignedBuffer == NULL) {
143 return EFI_OUT_OF_RESOURCES;
144 }
145 //
146 // Save original buffer
147 //
148 if (OffsetHead != 0) {
149 CopyMem((UINT8 *)AlignedBuffer, (VOID *)(UINTN)AlignedFlashAddress, OffsetHead);
150 }
151 if (OffsetTail != 0) {
152 CopyMem((UINT8 *)AlignedBuffer + OffsetHead + Length, (VOID *)(UINTN)(AlignedFlashAddress + OffsetHead + Length), OffsetTail);
153 }
154 //
155 // Override new buffer
156 //
157 CopyMem((UINT8 *)AlignedBuffer + OffsetHead, Buffer, Length);
158 } else {
159 AlignedFlashAddress = FlashAddress;
160 AlignedBuffer = Buffer;
161 AlignedLength = Length;
162 }
163
164 Status = PerformFlashWrite(
165 PlatformFirmwareTypeSystemFirmware,
166 AlignedFlashAddress,
167 FlashAddressTypeAbsoluteAddress,
168 AlignedBuffer,
169 AlignedLength
170 );
171 if ((OffsetHead != 0) || (OffsetTail != 0)) {
172 FreePool (AlignedBuffer);
173 }
174 return Status;
175 }
176
177 /**
178 Platform Flash Access Lib Constructor.
179 **/
180 EFI_STATUS
181 EFIAPI
182 PerformFlashAccessLibConstructor (
183 VOID
184 )
185 {
186 mInternalFdAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32(PcdFlashAreaBaseAddress);
187 DEBUG((DEBUG_INFO, "PcdFlashAreaBaseAddress - 0x%x\n", mInternalFdAddress));
188
189 return EFI_SUCCESS;
190 }