]>
git.proxmox.com Git - mirror_edk2.git/blob - Tools/CCode/Source/FlashMap/Microcode.c
3 Copyright (c) 2004-2006 Intel Corporation. All rights reserved
4 This program and the accompanying materials are licensed and made available
5 under the terms and conditions of the BSD License which accompanies this
6 distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 Utility for working with microcode patch files in the Intel
19 Platform Innovation Framework for EFI build environment.
24 #include <string.h> // for memset()
26 #include <stdlib.h> // for malloc()
28 #include "EfiUtilityMsgs.h"
29 #include "Microcode.h"
31 #define MAX_LINE_LEN 256
33 #define STATUS_IGNORE 0xA
36 // Structure definition for a microcode header
39 unsigned int HeaderVersion
;
43 unsigned int Checksum
;
44 unsigned int LoaderVersion
;
45 unsigned int PlatformId
;
46 unsigned int DataSize
; // if 0, then TotalSize = 2048, and TotalSize field is invalid
47 unsigned int TotalSize
; // number of bytes
48 unsigned int Reserved
[3];
49 } MICROCODE_IMAGE_HEADER
;
59 MicrocodeConstructor (
66 Constructor of module Microcode
88 Destructor of module Microcode
111 Read a 32-bit microcode data value from a text file and convert to raw binary form.
114 InFptr - file pointer to input text file
115 Data - pointer to where to return the data parsed
118 STATUS_SUCCESS - no errors or warnings, Data contains valid information
119 STATUS_ERROR - errors were encountered
123 char Line
[MAX_LINE_LEN
];
127 Line
[MAX_LINE_LEN
- 1] = 0;
129 if (fgets (Line
, MAX_LINE_LEN
, InFptr
) == NULL
) {
133 // If it was a binary file, then it may have overwritten our null terminator
135 if (Line
[MAX_LINE_LEN
- 1] != 0) {
139 // Strip leading white-space characters (except carriage returns) from Line
141 if (isspace(Line
[0]) && Line
[0] != '\n') {
142 while (isspace(Line
[0])) {
143 for (ctr
= 0; ctr
< strlen(Line
); ctr
++)
144 if (Line
[ctr
] != '\n')
145 Line
[ctr
] = Line
[ctr
+ 1];
151 // dd 000000001h ; comment
156 for (cptr
= Line
; *cptr
&& isspace(*cptr
); cptr
++) {
158 if ((tolower(cptr
[0]) == 'd') && (tolower(cptr
[1]) == 'd') && isspace (cptr
[2])) {
160 // Skip blanks and look for a hex digit
163 for (; *cptr
&& isspace(*cptr
); cptr
++) {
165 if (isxdigit (*cptr
)) {
166 if (sscanf (cptr
, "%X", Data
) != 1) {
170 return STATUS_SUCCESS
;
172 if (strlen(Line
) == 1) {
173 return STATUS_IGNORE
;
175 if (tolower(cptr
[0]) == ';') {
176 return STATUS_IGNORE
;
189 Parse a microcode text file, and write the binary results to an output file.
192 InFileName - input text file to parse
193 OutFileName - output file to write raw binary data from parsed input file
196 STATUS_SUCCESS - no errors or warnings
197 STATUS_ERROR - errors were encountered
204 MICROCODE_IMAGE_HEADER
*Header
;
208 unsigned int Checksum
;
212 unsigned int TotalSize
;
214 Status
= STATUS_ERROR
;
219 // Open the input text file
221 if ((InFptr
= fopen (InFileName
, "r")) == NULL
) {
222 Error (NULL
, 0, 0, InFileName
, "failed to open input microcode file for reading");
226 // Make two passes on the input file. The first pass is to determine how
227 // much data is in the file so we can allocate a working buffer. Then
228 // we'll allocate a buffer and re-read the file into the buffer for processing.
232 Status
= MicrocodeReadData (InFptr
, &Data
);
233 if (Status
== STATUS_SUCCESS
) {
234 Size
+= sizeof (Data
);
236 if (Status
== STATUS_IGNORE
) {
237 Status
= STATUS_SUCCESS
;
239 } while (Status
== STATUS_SUCCESS
);
244 Error (NULL
, 0, 0, InFileName
, "no parse-able data found in file");
247 if (Size
< sizeof (MICROCODE_IMAGE_HEADER
)) {
248 Error (NULL
, 0, 0, InFileName
, "amount of parse-able data is insufficient to contain a microcode header");
252 // Allocate a buffer for the data
254 Buffer
= (char *) _malloc (Size
);
255 if (Buffer
== NULL
) {
256 Error (NULL
, 0, 0, "memory allocation failure", NULL
);
260 // Re-read the file, storing the data into our buffer
262 fseek (InFptr
, 0, SEEK_SET
);
267 Status
= MicrocodeReadData (InFptr
, &Data
);
268 if (Status
== STATUS_SUCCESS
) {
269 *(unsigned int *) Ptr
= Data
;
270 Ptr
+= sizeof (Data
);
272 if (Status
== STATUS_IGNORE
) {
274 Status
= STATUS_SUCCESS
;
276 } while (Status
== STATUS_SUCCESS
);
278 // Can't do much checking on the header because, per the spec, the
279 // DataSize field may be 0, which means DataSize = 2000 and TotalSize = 2K,
280 // and the TotalSize field is invalid (actually missing). Thus we can't
281 // even verify the Reserved fields are 0.
283 Header
= (MICROCODE_IMAGE_HEADER
*) Buffer
;
284 if (Header
->DataSize
== 0) {
287 TotalSize
= Header
->TotalSize
;
289 if (TotalSize
!= Size
) {
290 Error (NULL
, 0, 0, InFileName
, "file contents do not contain expected TotalSize 0x%04X", TotalSize
);
294 // Checksum the contents
299 while (Size2
< Size
) {
300 Checksum
+= *(unsigned int *) Ptr
;
305 Error (NULL
, 0, 0, InFileName
, "checksum failed on file contents");
309 // Open the output file and write the buffer contents
311 if ((OutFptr
= fopen (OutFileName
, "wb")) == NULL
) {
312 Error (NULL
, 0, 0, OutFileName
, "failed to open output microcode file for writing");
315 if (fwrite (Buffer
, Size
, 1, OutFptr
) != 1) {
316 Error (NULL
, 0, 0, OutFileName
, "failed to write microcode data to output file");
319 Status
= STATUS_SUCCESS
;
321 if (Buffer
!= NULL
) {
324 if (InFptr
!= NULL
) {
327 if (OutFptr
!= NULL
) {
329 if (Status
== STATUS_ERROR
) {
330 remove (OutFileName
);