TianoCore EDK2 master
MicrocodeLib.c
Go to the documentation of this file.
1
9#include <Uefi/UefiBaseType.h>
13#include <Library/BaseLib.h>
14#include <Library/DebugLib.h>
15#include <Ppi/ShadowMicrocode.h>
16
22UINT32
23EFIAPI
25 VOID
26 )
27{
29
33 return BiosSignIdMsr.Bits.MicrocodeUpdateSignature;
34}
35
41VOID
42EFIAPI
44 EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId
45 )
46{
48
49 ASSERT (MicrocodeCpuId != NULL);
50
52 MicrocodeCpuId->PlatformId = (UINT8)PlatformIdMsr.Bits.PlatformId;
53 AsmCpuid (CPUID_VERSION_INFO, &MicrocodeCpuId->ProcessorSignature, NULL, NULL, NULL);
54}
55
71UINT32
72EFIAPI
74 IN CPU_MICROCODE_HEADER *Microcode
75 )
76{
77 UINT32 TotalSize;
78
79 ASSERT (Microcode != NULL);
80
81 TotalSize = 2048;
82 if (Microcode->DataSize != 0) {
83 TotalSize = Microcode->TotalSize;
84 }
85
86 return TotalSize;
87}
88
96VOID
97EFIAPI
99 IN CPU_MICROCODE_HEADER *Microcode
100 )
101{
102 ASSERT (Microcode != NULL);
103
104 AsmWriteMsr64 (MSR_IA32_BIOS_UPDT_TRIG, (UINT64)(UINTN)(Microcode + 1));
105}
106
121BOOLEAN
123 IN UINT32 ProcessorSignature,
124 IN UINT32 ProcessorFlags,
125 IN EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId,
126 IN UINTN MicrocodeCpuIdCount
127 )
128{
129 UINTN Index;
130
131 if (MicrocodeCpuIdCount == 0) {
132 return TRUE;
133 }
134
135 for (Index = 0; Index < MicrocodeCpuIdCount; Index++) {
136 if ((ProcessorSignature == MicrocodeCpuId[Index].ProcessorSignature) &&
137 ((ProcessorFlags & (1 << MicrocodeCpuId[Index].PlatformId)) != 0))
138 {
139 return TRUE;
140 }
141 }
142
143 return FALSE;
144}
145
184BOOLEAN
185EFIAPI
187 IN CPU_MICROCODE_HEADER *Microcode,
188 IN UINTN MicrocodeLength,
189 IN UINT32 MinimumRevision,
190 IN EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuIds,
191 IN UINTN MicrocodeCpuIdCount,
192 IN BOOLEAN VerifyChecksum
193 )
194{
195 UINTN Index;
196 UINT32 DataSize;
197 UINT32 TotalSize;
198 CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable;
199 CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader;
200 UINT32 ExtendedTableLength;
201 UINT32 Sum32;
202 BOOLEAN Match;
203
204 ASSERT (Microcode != NULL);
205
206 //
207 // It's invalid when:
208 // the input microcode buffer is so small that even cannot contain the header.
209 // the input microcode buffer is so large that exceeds MAX_ADDRESS.
210 //
211 if ((MicrocodeLength < sizeof (CPU_MICROCODE_HEADER)) || (MicrocodeLength > (MAX_ADDRESS - (UINTN)Microcode))) {
212 return FALSE;
213 }
214
215 //
216 // Per SDM, HeaderVersion and LoaderRevision should both be 1.
217 //
218 if ((Microcode->HeaderVersion != 1) || (Microcode->LoaderRevision != 1)) {
219 return FALSE;
220 }
221
222 //
223 // The microcode revision should be larger than the minimum revision.
224 //
225 if (Microcode->UpdateRevision <= MinimumRevision) {
226 return FALSE;
227 }
228
229 DataSize = Microcode->DataSize;
230 if (DataSize == 0) {
231 DataSize = 2000;
232 }
233
234 //
235 // Per SDM, DataSize should be multiple of DWORDs.
236 //
237 if ((DataSize % 4) != 0) {
238 return FALSE;
239 }
240
241 TotalSize = GetMicrocodeLength (Microcode);
242
243 //
244 // Check whether the whole microcode is within the buffer.
245 // TotalSize should be multiple of 1024.
246 //
247 if (((TotalSize % SIZE_1KB) != 0) || (TotalSize > MicrocodeLength)) {
248 return FALSE;
249 }
250
251 //
252 // The summation of all DWORDs in microcode should be zero.
253 //
254 if (VerifyChecksum && (CalculateSum32 ((UINT32 *)Microcode, TotalSize) != 0)) {
255 return FALSE;
256 }
257
258 Sum32 = Microcode->ProcessorSignature.Uint32 + Microcode->ProcessorFlags + Microcode->Checksum;
259
260 //
261 // Check the processor signature and platform ID in the primary header.
262 //
264 Microcode->ProcessorSignature.Uint32,
265 Microcode->ProcessorFlags,
266 MicrocodeCpuIds,
267 MicrocodeCpuIdCount
268 );
269 if (Match) {
270 return TRUE;
271 }
272
273 ExtendedTableLength = TotalSize - (DataSize + sizeof (CPU_MICROCODE_HEADER));
274 if ((ExtendedTableLength < sizeof (CPU_MICROCODE_EXTENDED_TABLE_HEADER)) || ((ExtendedTableLength % 4) != 0)) {
275 return FALSE;
276 }
277
278 //
279 // Extended Table exist, check if the CPU in support list
280 //
281 ExtendedTableHeader = (CPU_MICROCODE_EXTENDED_TABLE_HEADER *)((UINTN)(Microcode + 1) + DataSize);
282 if (ExtendedTableHeader->ExtendedSignatureCount > MAX_UINT32 / sizeof (CPU_MICROCODE_EXTENDED_TABLE)) {
283 return FALSE;
284 }
285
286 if (ExtendedTableHeader->ExtendedSignatureCount * sizeof (CPU_MICROCODE_EXTENDED_TABLE)
287 > ExtendedTableLength - sizeof (CPU_MICROCODE_EXTENDED_TABLE_HEADER))
288 {
289 return FALSE;
290 }
291
292 //
293 // Check the extended table checksum
294 //
295 if (VerifyChecksum && (CalculateSum32 ((UINT32 *)ExtendedTableHeader, ExtendedTableLength) != 0)) {
296 return FALSE;
297 }
298
299 ExtendedTable = (CPU_MICROCODE_EXTENDED_TABLE *)(ExtendedTableHeader + 1);
300 for (Index = 0; Index < ExtendedTableHeader->ExtendedSignatureCount; Index++) {
301 if (VerifyChecksum &&
302 (ExtendedTable[Index].ProcessorSignature.Uint32 + ExtendedTable[Index].ProcessorFlag
303 + ExtendedTable[Index].Checksum != Sum32))
304 {
305 //
306 // The extended table entry is valid when the summation of Processor Signature, Processor Flags
307 // and Checksum equal to the coresponding summation from primary header. Because:
308 // CalculateSum32 (Header + Update Binary) == 0
309 // CalculateSum32 (Header + Update Binary)
310 // - (Header.ProcessorSignature + Header.ProcessorFlag + Header.Checksum)
311 // + (Extended.ProcessorSignature + Extended.ProcessorFlag + Extended.Checksum) == 0
312 // So,
313 // (Header.ProcessorSignature + Header.ProcessorFlag + Header.Checksum)
314 // == (Extended.ProcessorSignature + Extended.ProcessorFlag + Extended.Checksum)
315 //
316 continue;
317 }
318
320 ExtendedTable[Index].ProcessorSignature.Uint32,
321 ExtendedTable[Index].ProcessorFlag,
322 MicrocodeCpuIds,
323 MicrocodeCpuIdCount
324 );
325 if (Match) {
326 return TRUE;
327 }
328 }
329
330 return FALSE;
331}
UINT64 UINTN
#define MAX_ADDRESS
BOOLEAN EFIAPI VerifyChecksum(IN BOOLEAN Log, IN UINT8 *Ptr, IN UINT32 Length)
Definition: AcpiParser.c:117
#define NULL
Definition: Base.h:312
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
UINT32 EFIAPI CalculateSum32(IN CONST UINT32 *Buffer, IN UINTN Length)
Definition: CheckSum.c:186
#define ASSERT(Expression)
Definition: DebugLib.h:391
UINT64 EFIAPI AsmReadMsr64(IN UINT32 Index)
Definition: GccInlinePriv.c:60
UINT64 EFIAPI AsmWriteMsr64(IN UINT32 Index, IN UINT64 Value)
#define MSR_IA32_BIOS_UPDT_TRIG
#define MSR_IA32_PLATFORM_ID
#define MSR_IA32_BIOS_SIGN_ID
#define CPUID_VERSION_INFO
Definition: Cpuid.h:81
UINT32 EFIAPI AsmCpuid(IN UINT32 Index, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
Definition: CpuId.c:36
BOOLEAN EFIAPI IsValidMicrocode(IN CPU_MICROCODE_HEADER *Microcode, IN UINTN MicrocodeLength, IN UINT32 MinimumRevision, IN EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuIds, IN UINTN MicrocodeCpuIdCount, IN BOOLEAN VerifyChecksum)
Definition: MicrocodeLib.c:186
BOOLEAN IsProcessorMatchedMicrocode(IN UINT32 ProcessorSignature, IN UINT32 ProcessorFlags, IN EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId, IN UINTN MicrocodeCpuIdCount)
Definition: MicrocodeLib.c:122
VOID EFIAPI GetProcessorMicrocodeCpuId(EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId)
Definition: MicrocodeLib.c:43
VOID EFIAPI LoadMicrocode(IN CPU_MICROCODE_HEADER *Microcode)
Definition: MicrocodeLib.c:98
UINT32 EFIAPI GetMicrocodeLength(IN CPU_MICROCODE_HEADER *Microcode)
Definition: MicrocodeLib.c:73
UINT32 EFIAPI GetProcessorMicrocodeSignature(VOID)
Definition: MicrocodeLib.c:24
STATIC BOOLEAN Match(IN CONST CHAR16 *Translated, IN UINTN TranslatedLength, IN EFI_DEVICE_PATH_PROTOCOL *DevicePath)
struct MSR_IA32_BIOS_SIGN_ID_REGISTER::@541 Bits
struct MSR_IA32_PLATFORM_ID_REGISTER::@538 Bits