]> git.proxmox.com Git - mirror_edk2.git/blame - Tools/Source/TianoTools/FlashMap/Microcode.c
GenDepex does not always run correctly on OS X. Turning on debug so that is can be...
[mirror_edk2.git] / Tools / Source / TianoTools / FlashMap / Microcode.c
CommitLineData
d25c4bf0 1/*++\r
2\r
3Copyright (c) 2004 Intel Corporation. All rights reserved\r
4This software and associated documentation (if any) is furnished\r
5under a license and may only be used or copied in accordance\r
6with the terms of the license. Except as permitted by such\r
7license, no part of this software or documentation may be\r
8reproduced, stored in a retrieval system, or transmitted in any\r
9form or by any means without the express written consent of\r
10Intel Corporation.\r
11\r
12Module Name:\r
13\r
14 Microcode.c\r
15\r
16Abstract:\r
17\r
18 Utility for working with microcode patch files in the Intel \r
19 Platform Innovation Framework for EFI build environment.\r
20\r
21--*/\r
22\r
23#include <stdio.h>\r
24#include <string.h> // for memset()\r
25#include <ctype.h>\r
26#include <stdlib.h> // for malloc()\r
27#define INT8 char\r
28#define UINT32 unsigned int\r
29\r
30#include "EfiUtilityMsgs.h"\r
31#include "Microcode.h"\r
32\r
33#define MAX_LINE_LEN 256\r
34\r
35//\r
36// Structure definition for a microcode header\r
37//\r
38typedef struct {\r
39 unsigned int HeaderVersion;\r
40 unsigned int PatchId;\r
41 unsigned int Date;\r
42 unsigned int CpuId;\r
43 unsigned int Checksum;\r
44 unsigned int LoaderVersion;\r
45 unsigned int PlatformId;\r
46 unsigned int DataSize; // if 0, then TotalSize = 2048, and TotalSize field is invalid\r
47 unsigned int TotalSize; // number of bytes\r
48 unsigned int Reserved[3];\r
49} MICROCODE_IMAGE_HEADER;\r
50\r
51static\r
52STATUS\r
53MicrocodeReadData (\r
54 FILE *InFptr,\r
55 unsigned int *Data\r
56 );\r
57\r
58void\r
59MicrocodeConstructor (\r
60 void\r
61 )\r
62/*++\r
63\r
64Routine Description:\r
65\r
66 Constructor of module Microcode\r
67\r
68Arguments:\r
69\r
70 None\r
71\r
72Returns:\r
73\r
74 None\r
75\r
76--*/\r
77{\r
78}\r
79\r
80void\r
81MicrocodeDestructor (\r
82 void\r
83 )\r
84/*++\r
85\r
86Routine Description:\r
87\r
88 Destructor of module Microcode\r
89\r
90Arguments:\r
91\r
92 None\r
93\r
94Returns:\r
95\r
96 None\r
97\r
98--*/\r
99{\r
100}\r
101\r
102static\r
103STATUS\r
104MicrocodeReadData (\r
105 FILE *InFptr,\r
106 unsigned int *Data\r
107 )\r
108/*++\r
109\r
110Routine Description:\r
111 Read a 32-bit microcode data value from a text file and convert to raw binary form.\r
112\r
113Arguments:\r
114 InFptr - file pointer to input text file\r
115 Data - pointer to where to return the data parsed\r
116\r
117Returns:\r
118 STATUS_SUCCESS - no errors or warnings, Data contains valid information\r
119 STATUS_ERROR - errors were encountered\r
120\r
121--*/\r
122{\r
123 char Line[MAX_LINE_LEN];\r
124 char *cptr;\r
125\r
126 Line[MAX_LINE_LEN - 1] = 0;\r
127 *Data = 0;\r
128 if (fgets (Line, MAX_LINE_LEN, InFptr) == NULL) {\r
129 return STATUS_ERROR;\r
130 }\r
131 //\r
132 // If it was a binary file, then it may have overwritten our null terminator\r
133 //\r
134 if (Line[MAX_LINE_LEN - 1] != 0) {\r
135 return STATUS_ERROR;\r
136 }\r
137 //\r
138 // Look for\r
139 // dd 000000001h ; comment\r
140 // dd XXXXXXXX\r
141 // DD XXXXXXXXX\r
142 // DD XXXXXXXXX\r
143 //\r
144 for (cptr = Line; *cptr && isspace(*cptr); cptr++) {\r
145 }\r
146 if ((tolower(cptr[0]) == 'd') && (tolower(cptr[1]) == 'd') && isspace (cptr[2])) {\r
147 //\r
148 // Skip blanks and look for a hex digit\r
149 //\r
150 cptr += 3;\r
151 for (; *cptr && isspace(*cptr); cptr++) {\r
152 }\r
153 if (isxdigit (*cptr)) {\r
154 if (sscanf (cptr, "%X", Data) != 1) {\r
155 return STATUS_ERROR;\r
156 }\r
157 }\r
158 return STATUS_SUCCESS;\r
159 }\r
160 return STATUS_ERROR;\r
161}\r
162\r
163STATUS\r
164MicrocodeParseFile (\r
165 char *InFileName,\r
166 char *OutFileName\r
167 )\r
168/*++\r
169\r
170Routine Description:\r
171 Parse a microcode text file, and write the binary results to an output file.\r
172\r
173Arguments:\r
174 InFileName - input text file to parse\r
175 OutFileName - output file to write raw binary data from parsed input file\r
176\r
177Returns:\r
178 STATUS_SUCCESS - no errors or warnings\r
179 STATUS_ERROR - errors were encountered\r
180\r
181--*/\r
182{\r
183 FILE *InFptr;\r
184 FILE *OutFptr;\r
185 STATUS Status;\r
186 MICROCODE_IMAGE_HEADER *Header;\r
187 unsigned int Size;\r
188 unsigned int Size2;\r
189 unsigned int Data;\r
190 unsigned int Checksum;\r
191 char *Buffer;\r
192 char *Ptr;\r
193 unsigned int TotalSize;\r
194\r
195 Status = STATUS_ERROR;\r
196 InFptr = NULL;\r
197 OutFptr = NULL;\r
198 Buffer = NULL;\r
199 //\r
200 // Open the input text file\r
201 //\r
202 if ((InFptr = fopen (InFileName, "r")) == NULL) {\r
203 Error (NULL, 0, 0, InFileName, "failed to open input microcode file for reading");\r
204 return STATUS_ERROR;\r
205 }\r
206 //\r
207 // Make two passes on the input file. The first pass is to determine how\r
208 // much data is in the file so we can allocate a working buffer. Then\r
209 // we'll allocate a buffer and re-read the file into the buffer for processing.\r
210 //\r
211 Size = 0;\r
212 do {\r
213 Status = MicrocodeReadData (InFptr, &Data);\r
214 if (Status == STATUS_SUCCESS) {\r
215 Size += sizeof (Data);\r
216 }\r
217 } while (Status == STATUS_SUCCESS);\r
218 //\r
219 // Error if no data.\r
220 //\r
221 if (Size == 0) {\r
222 Error (NULL, 0, 0, InFileName, "no parse-able data found in file");\r
223 goto Done;\r
224 }\r
225 if (Size < sizeof (MICROCODE_IMAGE_HEADER)) {\r
226 Error (NULL, 0, 0, InFileName, "amount of parse-able data is insufficient to contain a microcode header");\r
227 goto Done;\r
228 }\r
229 //\r
230 // Allocate a buffer for the data\r
231 //\r
232 Buffer = (char *) _malloc (Size);\r
233 if (Buffer == NULL) {\r
234 Error (NULL, 0, 0, "memory allocation failure", NULL);\r
235 goto Done;\r
236 }\r
237 //\r
238 // Re-read the file, storing the data into our buffer\r
239 //\r
240 fseek (InFptr, 0, SEEK_SET);\r
241 Ptr = Buffer;\r
242 do {\r
243 Status = MicrocodeReadData (InFptr, &Data);\r
244 if (Status == STATUS_SUCCESS) {\r
245 *(unsigned int *) Ptr = Data;\r
246 Ptr += sizeof (Data);\r
247 }\r
248 } while (Status == STATUS_SUCCESS);\r
249 //\r
250 // Can't do much checking on the header because, per the spec, the\r
251 // DataSize field may be 0, which means DataSize = 2000 and TotalSize = 2K,\r
252 // and the TotalSize field is invalid (actually missing). Thus we can't\r
253 // even verify the Reserved fields are 0.\r
254 //\r
255 Header = (MICROCODE_IMAGE_HEADER *) Buffer;\r
256 if (Header->DataSize == 0) {\r
257 TotalSize = 2048;\r
258 } else {\r
259 TotalSize = Header->TotalSize;\r
260 }\r
261 if (TotalSize != Size) {\r
262 Error (NULL, 0, 0, InFileName, "file contents do not contain expected TotalSize 0x%04X", TotalSize);\r
263 goto Done;\r
264 }\r
265 //\r
266 // Checksum the contents\r
267 //\r
268 Ptr = Buffer;\r
269 Checksum = 0;\r
270 Size2 = 0;\r
271 while (Size2 < Size) {\r
272 Checksum += *(unsigned int *) Ptr;\r
273 Ptr += 4;\r
274 Size2 += 4;\r
275 }\r
276 if (Checksum != 0) {\r
277 Error (NULL, 0, 0, InFileName, "checksum failed on file contents");\r
278 goto Done;\r
279 }\r
280 //\r
281 // Open the output file and write the buffer contents\r
282 //\r
283 if ((OutFptr = fopen (OutFileName, "wb")) == NULL) {\r
284 Error (NULL, 0, 0, OutFileName, "failed to open output microcode file for writing");\r
285 goto Done;\r
286 }\r
287 if (fwrite (Buffer, Size, 1, OutFptr) != 1) {\r
288 Error (NULL, 0, 0, OutFileName, "failed to write microcode data to output file");\r
289 goto Done;\r
290 }\r
291 Status = STATUS_SUCCESS;\r
292Done:\r
293 if (Buffer != NULL) {\r
294 free (Buffer);\r
295 }\r
296 if (InFptr != NULL) {\r
297 fclose (InFptr);\r
298 }\r
299 if (OutFptr != NULL) {\r
300 fclose (OutFptr);\r
301 if (Status == STATUS_ERROR) {\r
302 remove (OutFileName);\r
303 }\r
304 }\r
305 return Status;\r
306}\r