]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Core/Dxe/FwVol/Ffs.c
Add core FFS3 support, DxeCore.
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / FwVol / Ffs.c
1 /** @file
2 FFS file access utilities.
3
4 Copyright (c) 2006 - 2011, 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
16 #include "DxeMain.h"
17 #include "FwVolDriver.h"
18
19
20 /**
21 Get the FFS file state by checking the highest bit set in the header's state field.
22
23 @param ErasePolarity Erase polarity attribute of the firmware volume
24 @param FfsHeader Points to the FFS file header
25
26 @return FFS File state
27
28 **/
29 EFI_FFS_FILE_STATE
30 GetFileState (
31 IN UINT8 ErasePolarity,
32 IN EFI_FFS_FILE_HEADER *FfsHeader
33 )
34 {
35 EFI_FFS_FILE_STATE FileState;
36 UINT8 HighestBit;
37
38 FileState = FfsHeader->State;
39
40 if (ErasePolarity != 0) {
41 FileState = (EFI_FFS_FILE_STATE)~FileState;
42 }
43
44 HighestBit = 0x80;
45 while (HighestBit != 0 && ((HighestBit & FileState) == 0)) {
46 HighestBit >>= 1;
47 }
48
49 return (EFI_FFS_FILE_STATE) HighestBit;
50 }
51
52
53
54 /**
55 Check if a block of buffer is erased.
56
57 @param ErasePolarity Erase polarity attribute of the firmware volume
58 @param InBuffer The buffer to be checked
59 @param BufferSize Size of the buffer in bytes
60
61 @retval TRUE The block of buffer is erased
62 @retval FALSE The block of buffer is not erased
63
64 **/
65 BOOLEAN
66 IsBufferErased (
67 IN UINT8 ErasePolarity,
68 IN VOID *InBuffer,
69 IN UINTN BufferSize
70 )
71 {
72 UINTN Count;
73 UINT8 EraseByte;
74 UINT8 *Buffer;
75
76 if(ErasePolarity == 1) {
77 EraseByte = 0xFF;
78 } else {
79 EraseByte = 0;
80 }
81
82 Buffer = InBuffer;
83 for (Count = 0; Count < BufferSize; Count++) {
84 if (Buffer[Count] != EraseByte) {
85 return FALSE;
86 }
87 }
88
89 return TRUE;
90 }
91
92
93
94 /**
95 Verify checksum of the firmware volume header.
96
97 @param FvHeader Points to the firmware volume header to be checked
98
99 @retval TRUE Checksum verification passed
100 @retval FALSE Checksum verification failed
101
102 **/
103 BOOLEAN
104 VerifyFvHeaderChecksum (
105 IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader
106 )
107 {
108 UINT16 Checksum;
109
110 Checksum = CalculateSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength);
111
112 if (Checksum == 0) {
113 return TRUE;
114 } else {
115 return FALSE;
116 }
117 }
118
119
120 /**
121 Verify checksum of the FFS file header.
122
123 @param FfsHeader Points to the FFS file header to be checked
124
125 @retval TRUE Checksum verification passed
126 @retval FALSE Checksum verification failed
127
128 **/
129 BOOLEAN
130 VerifyHeaderChecksum (
131 IN EFI_FFS_FILE_HEADER *FfsHeader
132 )
133 {
134 UINT8 HeaderChecksum;
135
136 if (IS_FFS_FILE2 (FfsHeader)) {
137 HeaderChecksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER2));
138 } else {
139 HeaderChecksum = CalculateSum8 ((UINT8 *) FfsHeader, sizeof (EFI_FFS_FILE_HEADER));
140 }
141 HeaderChecksum = (UINT8) (HeaderChecksum - FfsHeader->State - FfsHeader->IntegrityCheck.Checksum.File);
142
143 if (HeaderChecksum == 0) {
144 return TRUE;
145 } else {
146 return FALSE;
147 }
148 }
149
150
151
152 /**
153 Check if it's a valid FFS file header.
154
155 @param ErasePolarity Erase polarity attribute of the firmware volume
156 @param FfsHeader Points to the FFS file header to be checked
157 @param FileState FFS file state to be returned
158
159 @retval TRUE Valid FFS file header
160 @retval FALSE Invalid FFS file header
161
162 **/
163 BOOLEAN
164 IsValidFfsHeader (
165 IN UINT8 ErasePolarity,
166 IN EFI_FFS_FILE_HEADER *FfsHeader,
167 OUT EFI_FFS_FILE_STATE *FileState
168 )
169 {
170 *FileState = GetFileState (ErasePolarity, FfsHeader);
171
172 switch (*FileState) {
173 case EFI_FILE_HEADER_VALID:
174 case EFI_FILE_DATA_VALID:
175 case EFI_FILE_MARKED_FOR_UPDATE:
176 case EFI_FILE_DELETED:
177 //
178 // Here we need to verify header checksum
179 //
180 return VerifyHeaderChecksum (FfsHeader);
181
182 case EFI_FILE_HEADER_CONSTRUCTION:
183 case EFI_FILE_HEADER_INVALID:
184 default:
185 return FALSE;
186 }
187 }
188
189
190 /**
191 Check if it's a valid FFS file.
192 Here we are sure that it has a valid FFS file header since we must call IsValidFfsHeader() first.
193
194 @param ErasePolarity Erase polarity attribute of the firmware volume
195 @param FfsHeader Points to the FFS file to be checked
196
197 @retval TRUE Valid FFS file
198 @retval FALSE Invalid FFS file
199
200 **/
201 BOOLEAN
202 IsValidFfsFile (
203 IN UINT8 ErasePolarity,
204 IN EFI_FFS_FILE_HEADER *FfsHeader
205 )
206 {
207 EFI_FFS_FILE_STATE FileState;
208 UINT8 DataCheckSum;
209
210 FileState = GetFileState (ErasePolarity, FfsHeader);
211 switch (FileState) {
212
213 case EFI_FILE_DELETED:
214 case EFI_FILE_DATA_VALID:
215 case EFI_FILE_MARKED_FOR_UPDATE:
216 DataCheckSum = FFS_FIXED_CHECKSUM;
217 if ((FfsHeader->Attributes & FFS_ATTRIB_CHECKSUM) == FFS_ATTRIB_CHECKSUM) {
218 if (IS_FFS_FILE2 (FfsHeader)) {
219 DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER2), FFS_FILE2_SIZE (FfsHeader) - sizeof(EFI_FFS_FILE_HEADER2));
220 } else {
221 DataCheckSum = CalculateCheckSum8 ((CONST UINT8 *) FfsHeader + sizeof (EFI_FFS_FILE_HEADER), FFS_FILE_SIZE (FfsHeader) - sizeof(EFI_FFS_FILE_HEADER));
222 }
223 }
224 if (FfsHeader->IntegrityCheck.Checksum.File == DataCheckSum) {
225 return TRUE;
226 }
227
228 default:
229 return FALSE;
230 }
231 }
232
233