1 /** @file
2 Implementation of Fsp SA Policy Initialization.
3
4 Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include <PeiFspPolicyInitLib.h>
10
11 #include <Ppi/SiPolicy.h>
12 #include <ConfigBlock/MemoryConfig.h>
13 #include <Library/IoLib.h>
14 #include <Library/BaseMemoryLib.h>
15 #include <Library/SmbusLib.h>
16 #include <Library/MmPciLib.h>
17 #include <Library/ConfigBlockLib.h>
18 #include <Library/PcdLib.h>
19
20 #include <IndustryStandard/Pci.h>
21 #include <MrcSpdData.h>
22 #include <PchAccess.h>
23 #include <Ppi/FirmwareVolume.h>
24 #include <Pi/PiFirmwareFile.h>
25 #include <Pi/PiPeiCis.h>
26
27 #define MAX_SPD_PAGE_COUNT (2)
28 #define MAX_SPD_PAGE_SIZE (256)
29 #define MAX_SPD_SIZE (MAX_SPD_PAGE_SIZE * MAX_SPD_PAGE_COUNT)
30 #define SPD_PAGE_ADDRESS_0 (0x6C)
31 #define SPD_PAGE_ADDRESS_1 (0x6E)
32 #define SPD_DDR3_SDRAM_TYPE_OFFSET (0x02)
33 #define SPD_DDR3_SDRAM_TYPE_NUMBER (0x0B)
34 #define SPD_DDR4_SDRAM_TYPE_NUMBER (0x0C)
35 #define SPD_LPDDR3_SDRAM_TYPE_NUMBER (0xF1)
36 #define SPD_JEDEC_LPDDR3_SDRAM_TYPE_NUMBER (0x0F)
37 #define XMP_ID_STRING (0x4A0C)
38 #define SPD3_MANUF_START (117)
39 #define SPD3_MANUF_END (127)
40 #define SPD4_MANUF_START (320)
41 #define SPD4_MANUF_END (328)
42 #define SPDLP_MANUF_START (320)
43 #define SPDLP_MANUF_END (328)
44
45 GLOBAL_REMOVE_IF_UNREFERENCED const SPD_OFFSET_TABLE mSpdDdr3Table[] = {
46 { 0, 1, (1 << SpdCold),},
47 { 2, 2, (1 << SpdCold) | (1 << SpdFast),},
48 { 3, 41, (1 << SpdCold),},
49 { 60, 63, (1 << SpdCold),},
50 { SPD3_MANUF_START, SPD3_MANUF_END, (1 << SpdCold) | (1 << SpdFast),},
51 { 128, 145, (1 << SpdCold),},
52 #ifdef SUPPORT_SPD_CRC
53 { 39, 59, (1 << SpdCold),},
54 { 64, 125, (1 << SpdCold),},
55 #endif
56 { 176, 179, (1 << SpdCold),},
57 { 180, 184, (1 << SpdCold),},
58 { 185, 215, (1 << SpdCold),},
59 { 220, 250, (1 << SpdCold),},
60 };
61
62 GLOBAL_REMOVE_IF_UNREFERENCED const SPD_OFFSET_TABLE mSpdDdr4Table[] = {
63 { 0, 1, (1 << SpdCold),},
64 { 2, 2, (1 << SpdCold) | (1 << SpdFast),},
65 { 3, 40, (1 << SpdCold),},
66 { 117, 131, (1 << SpdCold),},
67 { SPD4_MANUF_START, SPD4_MANUF_END, (1 << SpdCold) | (1 << SpdFast),},
68 { 329, 348, (1 << SpdCold),},
69 #ifdef SUPPORT_SPD_CRC
70 { 32, 119, (1 << SpdCold),},
71 { 126, 255, (1 << SpdCold),},
72 { 349, 383, (1 << SpdCold),},
73 #endif
74 { 384, 387, (1 << SpdCold),},
75 { 388, 389, (1 << SpdCold),},
76 { 393, 431, (1 << SpdCold),},
77 { 440, 478, (1 << SpdCold),},
78 };
79
80 GLOBAL_REMOVE_IF_UNREFERENCED const SPD_OFFSET_TABLE mSpdLpddrTable[] = {
81 { 0, 1, (1 << SpdCold),},
82 { 2, 2, (1 << SpdCold) | (1 << SpdFast),},
83 { 3, 32, (1 << SpdCold),},
84 { 120, 130, (1 << SpdCold),},
85 { SPDLP_MANUF_START, SPDLP_MANUF_END, (1 << SpdCold) | (1 << SpdFast),},
86 { 329, 348, (1 << SpdCold),},
87 #ifdef SUPPORT_SPD_CRC
88 { 31, 121, (1 << SpdCold),},
89 { 126, 255, (1 << SpdCold),},
90 { 349, 383, (1 << SpdCold),},
91 #endif
92 { 384, 387, (1 << SpdCold),},
93 { 388, 389, (1 << SpdCold),},
94 { 393, 431, (1 << SpdCold),},
95 { 440, 478, (1 << SpdCold),},
96 };
97
98
99 /**
100 Read the SPD data over the SMBus, at the specified SPD address, starting at
101 the specified starting offset and read the given amount of data.
102
103 @param[in] SpdAddress - SPD SMBUS address
104 @param[in, out] Buffer - Buffer to store the data.
105 @param[in] Start - Starting SPD offset
106 @param[in] Size - The number of bytes of data to read and also the size of the buffer.
107 @param[in, out] Page - The final page that is being pointed to.
108
109 @retval EFI_SUCCESS if the read is successful, otherwise error status.
110 **/
111 static
112 EFI_STATUS
InternalDoSpdRead(IN const UINT8 SpdAddress,IN OUT UINT8 * const Buffer,IN const UINT16 Start,IN UINT16 Size,IN OUT UINT8 * const Page)113 InternalDoSpdRead (
114 IN const UINT8 SpdAddress,
115 IN OUT UINT8 *const Buffer,
116 IN const UINT16 Start,
117 IN UINT16 Size,
118 IN OUT UINT8 *const Page
119 )
120 {
121 EFI_STATUS EfiStatus;
122 BOOLEAN PageUpdate;
123 UINT16 Count;
124 UINT16 Index;
125
126 EfiStatus = EFI_DEVICE_ERROR;
127 if ((Buffer != NULL) && (Start < MAX_SPD_SIZE) && ((Start + Size) < MAX_SPD_SIZE)) {
128 Count = 0;
129 PageUpdate = FALSE;
130 while (Size--) {
131 Index = Start + Count;
132 if ((Index / MAX_SPD_PAGE_SIZE) != *Page) {
133 *Page = (UINT8) (Index / MAX_SPD_PAGE_SIZE);
134 PageUpdate = TRUE;
135 }
136 Index %= MAX_SPD_PAGE_SIZE;
137 if (PageUpdate == TRUE) {
138 PageUpdate = FALSE;
139 SmBusWriteDataByte ((*Page == 0) ? SPD_PAGE_ADDRESS_0 : SPD_PAGE_ADDRESS_1, 0, &EfiStatus);
140 }
141 Buffer[Count] = SmBusReadDataByte (SpdAddress | ((UINT32) Index << 8), &EfiStatus);
142 if (EFI_SUCCESS != EfiStatus) {
143 Buffer[Count] = 0;
144 break;
145 }
146 Count++;
147 }
148 EfiStatus = EFI_SUCCESS;
149 }
150 return (EfiStatus);
151 }
152
153 /**
154 See if there is valid XMP SPD data.
155
156 @param[in] Debug - Mrc debug structure.
157 @param[in, out] Spd - Mrc SPD structure.
158 @param[in] XmpStart - The current offset in the SPD.
159
160 @retval TRUE if valid, FALSE in not.
161 **/
162 static
163 BOOLEAN
InternalVerifyXmp(IN OUT MrcSpd * const Spd,IN const UINT16 XmpStart)164 InternalVerifyXmp (
165 IN OUT MrcSpd *const Spd,
166 IN const UINT16 XmpStart
167 )
168 {
169 SPD_EXTREME_MEMORY_PROFILE_HEADER *Header1;
170 SPD_EXTREME_MEMORY_PROFILE_HEADER_2_0 *Header2;
171 BOOLEAN Xmp;
172
173 Xmp = FALSE;
174
175 switch (((UINT8 *)Spd)[2]) {
176 case SPD_DDR3_SDRAM_TYPE_NUMBER:
177 Header1 = &Spd->Ddr3.Xmp.Header;
178 if (XmpStart == ((UINT32) (Header1) - (UINT32) Spd)) {
179 Xmp = TRUE;
180 if ((Header1->XmpRevision.Data & 0xFE) == 0x12) {
181 return (TRUE);
182 } else {
183 Header1->XmpId = 0;
184 Header1->XmpOrgConf.Data = 0;
185 Header1->XmpRevision.Data = 0;
186 }
187 }
188 break;
189 case SPD_DDR4_SDRAM_TYPE_NUMBER:
190 Header2 = &Spd->Ddr4.EndUser.Xmp.Header;
191 if (XmpStart == ((UINT32) (Header2) - (UINT32) Spd)) {
192 Xmp = TRUE;
193 if ((Header2->XmpRevision.Data) == 0x20) {
194 return (TRUE);
195 } else {
196 Header2->XmpId = 0;
197 Header2->XmpOrgConf.Data = 0;
198 Header2->XmpRevision.Data = 0;
199 }
200 }
201 break;
202 case SPD_JEDEC_LPDDR3_SDRAM_TYPE_NUMBER:
203 case SPD_LPDDR3_SDRAM_TYPE_NUMBER:
204 return (TRUE);
205 default:
206 return (FALSE);
207 }
208 if (!Xmp) {
209 return (TRUE);
210 }
211 return (FALSE);
212 }
213
214 /**
215 Read the SPD data over the SMBus, at the given SmBus SPD address and copy the data to the data structure.
216 The SPD data locations read is controlled by the current boot mode.
217
218 @param[in] BootMode - The current MRC boot mode.
219 @param[in] Address - SPD SmBus address offset.
220 @param[in] Buffer - Buffer that contains the data read from the SPD.
221 @param[in] SpdDdr3Table - Indicates which SPD bytes to read.
222 @param[in] SpdDdr3TableSize - Size of SpdDdr3Table in bytes.
223 @param[in] SpdDdr4Table - Indicates which SPD bytes to read.
224 @param[in] SpdDdr4TableSize - Size of SpdDdr4Table in bytes.
225 @param[in] SpdLpddrTable - Indicates which SPD bytes to read.
226 @param[in] SpdLpddrTableSize - Size of SpdLpddrTable in bytes.
227
228 @retval TRUE if the read is successful, otherwise FALSE on error.
229 **/
230 BOOLEAN
InternalGetSpdData(IN SPD_BOOT_MODE BootMode,IN UINT8 Address,IN OUT UINT8 * Buffer,IN UINT8 * SpdDdr3Table,IN UINT32 SpdDdr3TableSize,IN UINT8 * SpdDdr4Table,IN UINT32 SpdDdr4TableSize,IN UINT8 * SpdLpddrTable,IN UINT32 SpdLpddrTableSize)231 InternalGetSpdData (
232 IN SPD_BOOT_MODE BootMode,
233 IN UINT8 Address,
234 IN OUT UINT8 *Buffer,
235 IN UINT8 *SpdDdr3Table,
236 IN UINT32 SpdDdr3TableSize,
237 IN UINT8 *SpdDdr4Table,
238 IN UINT32 SpdDdr4TableSize,
239 IN UINT8 *SpdLpddrTable,
240 IN UINT32 SpdLpddrTableSize
241 )
242 {
243 const SPD_OFFSET_TABLE *Tbl;
244 const SPD_OFFSET_TABLE *TableSelect;
245 EFI_STATUS Status;
246 UINT32 Byte;
247 UINT32 Stop;
248 UINT8 Page;
249
250 Page = (UINT8) (~0);
251 Status = InternalDoSpdRead (Address, &Buffer[SPD_DDR3_SDRAM_TYPE_OFFSET], 2, 1, &Page);
252 if (EFI_SUCCESS == Status) {
253 switch (Buffer[SPD_DDR3_SDRAM_TYPE_OFFSET]) {
254 case SPD_DDR3_SDRAM_TYPE_NUMBER:
255 case SPD_LPDDR3_SDRAM_TYPE_NUMBER:
256 default:
257 TableSelect = (SPD_OFFSET_TABLE *) SpdDdr3Table;
258 Stop = (SpdDdr3TableSize / sizeof (SPD_OFFSET_TABLE));
259 break;
260 case SPD_DDR4_SDRAM_TYPE_NUMBER:
261 TableSelect = (SPD_OFFSET_TABLE *) SpdDdr4Table;
262 Stop = (SpdDdr4TableSize / sizeof (SPD_OFFSET_TABLE));
263 break;
264 case SPD_JEDEC_LPDDR3_SDRAM_TYPE_NUMBER:
265 TableSelect = (SPD_OFFSET_TABLE *) SpdLpddrTable;
266 Stop = (SpdLpddrTableSize / sizeof (SPD_OFFSET_TABLE));
267 break;
268 }
269 for (Byte = 0; (EFI_SUCCESS == Status) && (Byte < Stop); Byte++) {
270 Tbl = &TableSelect[Byte];
271 if ((1 << BootMode) & Tbl->BootMode) {
272 Status = InternalDoSpdRead (Address, &Buffer[Tbl->Start], Tbl->Start, Tbl->End - Tbl->Start + 1, &Page);
273 if (Status == EFI_SUCCESS) {
274 if (SpdCold == BootMode) {
275 if (FALSE == InternalVerifyXmp ((MrcSpd *) Buffer, Tbl->Start)) {
276 break;
277 }
278 }
279 } else {
280 break;
281 }
282 }
283 }
284 }
285
286 return ((EFI_SUCCESS == Status) ? TRUE : FALSE);
287 }
288
289 /**
290 Initialize the Smbus PPI and program the Smbus BAR
291
292 @retval EFI_SUCCESS The function completes successfully
293 @retval EFI_OUT_OF_RESOURCES Insufficient resources to create database
294 **/
295 EFI_STATUS
InternalInitializePchSmbus(VOID)296 InternalInitializePchSmbus (
297 VOID
298 )
299 {
300 UINTN SmbusRegBase;
301 SmbusRegBase = MmPciBase (
302 DEFAULT_PCI_BUS_NUMBER_PCH,
303 PCI_DEVICE_NUMBER_PCH_SMBUS,
304 PCI_FUNCTION_NUMBER_PCH_SMBUS
305 );
306
307 ///
308 /// Since PEI has no PCI enumerator, set the BAR & I/O space enable ourselves
309 ///
310 MmioAndThenOr32 (SmbusRegBase + R_PCH_SMBUS_BASE, B_PCH_SMBUS_BASE_BAR, PcdGet16 (PcdSmbusBaseAddress));
311
312 MmioOr8 (SmbusRegBase + PCI_COMMAND_OFFSET, EFI_PCI_COMMAND_IO_SPACE);
313
314 ///
315 /// Reset the SMBus host controller
316 ///
317 MmioOr8 (SmbusRegBase + R_PCH_SMBUS_HOSTC, B_PCH_SMBUS_HOSTC_SSRESET);
318
319 ///
320 /// Enable the SMBus host controller
321 ///
322 MmioAndThenOr8 (
323 SmbusRegBase + R_PCH_SMBUS_HOSTC,
324 (UINT8)(~(B_PCH_SMBUS_HOSTC_SMI_EN | B_PCH_SMBUS_HOSTC_I2C_EN)),
325 B_PCH_SMBUS_HOSTC_HST_EN
326 );
327
328 ///
329 /// Clear Status Register before anyone uses the interfaces
330 ///
331 IoWrite8 (PcdGet16(PcdSmbusBaseAddress) + R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
332
333 return EFI_SUCCESS;
334 }
335
336 /**
337 Update Spd Data
338
339 @param[in][out] FspmUpd Pointer to FSP UPD Data.
340 @param[in] MemConfigNoCrc Pointer to Mem Config No Crc.
341 @param[in] MiscPeiPreMemConfig Pointer to Misc Config.
342
343 @retval EFI_SUCCESS The function completes successfully
344 @retval Other The function fail
345 **/
346 VOID
347 EFIAPI
InternalUpdateSpdData(IN OUT FSPM_UPD * FspmUpd,IN MEMORY_CONFIG_NO_CRC * MemConfigNoCrc,IN SA_MISC_PEI_PREMEM_CONFIG * MiscPeiPreMemConfig)348 InternalUpdateSpdData (
349 IN OUT FSPM_UPD *FspmUpd,
350 IN MEMORY_CONFIG_NO_CRC *MemConfigNoCrc,
351 IN SA_MISC_PEI_PREMEM_CONFIG *MiscPeiPreMemConfig
352 )
353 {
354 UINT8 Socket;
355 UINT8 *SpdData;
356
357 InternalInitializePchSmbus ();
358
359 DEBUG ((DEBUG_INFO, "Updating UPD:Memory Spd Pointers...\n"));
360 if (FspmUpd == NULL || MemConfigNoCrc == NULL) {
361 DEBUG ((DEBUG_ERROR, "EFI_INVALID_PARAMETER.\n"));
362 DEBUG ((DEBUG_ERROR, "Fail to access SPD from SiPolicyPpi\n"));
363 return;
364 }
365
366 if (*((UINT32 *)MiscPeiPreMemConfig->SpdAddressTable) != 0x0) {
367 //
368 // Update MemConfigNoCrc->SpdData->SpdData
369 //
370 for (Socket = 0; Socket < SA_MC_MAX_SOCKETS; Socket++) {
371 SpdData = (UINT8 *)((UINT32)MemConfigNoCrc->SpdData->SpdData + (Socket * SA_MC_MAX_SPD_SIZE));
372 InternalGetSpdData (
373 0,
374 MiscPeiPreMemConfig->SpdAddressTable[Socket],
375 (UINT8 *)SpdData,
376 (UINT8 *)&mSpdDdr3Table,
377 sizeof(mSpdDdr3Table),
378 (UINT8 *)&mSpdDdr4Table,
379 sizeof(mSpdDdr4Table),
380 (UINT8 *)&mSpdLpddrTable,
381 sizeof(mSpdLpddrTable)
382 );
383 }
384 }
385
386 FspmUpd->FspmConfig.MemorySpdPtr00 = (UINT32)MemConfigNoCrc->SpdData->SpdData;
387 FspmUpd->FspmConfig.MemorySpdPtr01 = (UINT32)MemConfigNoCrc->SpdData->SpdData + (1 * SA_MC_MAX_SPD_SIZE);
388 FspmUpd->FspmConfig.MemorySpdPtr10 = (UINT32)MemConfigNoCrc->SpdData->SpdData + (2 * SA_MC_MAX_SPD_SIZE);
389 FspmUpd->FspmConfig.MemorySpdPtr11 = (UINT32)MemConfigNoCrc->SpdData->SpdData + (3 * SA_MC_MAX_SPD_SIZE);
390
391 DEBUG ((DEBUG_INFO, "UPD:MemorySpdPtr Updated\n"));
392 }
393
394 /**
395 Performs FSP SA PEI Policy initialization in pre-memory.
396
397 @param[in][out] FspmUpd Pointer to FSP UPD Data.
398
399 @retval EFI_SUCCESS FSP UPD Data is updated.
400 @retval EFI_NOT_FOUND Fail to locate required PPI.
401 @retval Other FSP UPD Data update process fail.
402 **/
403 EFI_STATUS
404 EFIAPI
PeiFspSaPolicyInitPreMem(IN OUT FSPM_UPD * FspmUpd)405 PeiFspSaPolicyInitPreMem (
406 IN OUT FSPM_UPD *FspmUpd
407 )
408 {
409 EFI_STATUS Status;
410 SA_MISC_PEI_PREMEM_CONFIG *MiscPeiPreMemConfig;
411 MEMORY_CONFIGURATION *MemConfig;
412 MEMORY_CONFIG_NO_CRC *MemConfigNoCrc;
413 SI_PREMEM_POLICY_PPI *SiPreMemPolicyPpi;
414
415 //
416 // Locate SiPreMemPolicyPpi
417 //
418 SiPreMemPolicyPpi = NULL;
419 MiscPeiPreMemConfig = NULL;
420 MemConfig = NULL;
421 MemConfigNoCrc = NULL;
422
423
424 Status = PeiServicesLocatePpi(
425 &gSiPreMemPolicyPpiGuid,
426 0,
427 NULL,
428 (VOID **) &SiPreMemPolicyPpi
429 );
430 ASSERT_EFI_ERROR (Status);
431 if (EFI_ERROR (Status) == FALSE) {
432 Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gSaMiscPeiPreMemConfigGuid, (VOID *) &MiscPeiPreMemConfig);
433 ASSERT_EFI_ERROR (Status);
434 Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gMemoryConfigNoCrcGuid, (VOID *) &MemConfigNoCrc);
435 ASSERT_EFI_ERROR (Status);
436 Status = GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gMemoryConfigGuid, (VOID *) &MemConfig);
437 ASSERT_EFI_ERROR (Status);
438 }
439
440 //
441 // Update UPD:DqPinsInterleaved
442 //
443 FspmUpd->FspmConfig.DqPinsInterleaved = (UINT8)MemConfig->DqPinsInterleaved;
444
445 //
446 // Update UPD:DqPinsInterleaved
447 //
448 FspmUpd->FspmConfig.CaVrefConfig = MemConfig->CaVrefConfig;
449
450 //
451 // Update UPD:MemorySpdPtrXX
452 //
453 InternalUpdateSpdData (FspmUpd, MemConfigNoCrc, MiscPeiPreMemConfig);
454
455 //
456 // Update UPD:MemorySpdDataLen
457 //
458 FspmUpd->FspmConfig.MemorySpdDataLen = SA_MC_MAX_SPD_SIZE;
459
460 //
461 // Update UPD:PlatformMemorySize
462 //
463 //
464 // @todo: This value is used since #183932. Revisit.
465 //
466 FspmUpd->FspmConfig.PlatformMemorySize = MemConfigNoCrc->PlatformMemorySize;
467 FspmUpd->FspmConfig.SaGv = MemConfig->SaGv;
468 FspmUpd->FspmConfig.RMT = (UINT8) MemConfig->RMT;
469 FspmUpd->FspmConfig.DdrFreqLimit = MemConfig->DdrFreqLimit;
470
471 FspmUpd->FspmConfig.SpdProfileSelected = MemConfig->SpdProfileSelected;
472 FspmUpd->FspmConfig.VddVoltage = MemConfig->VddVoltage;
473 FspmUpd->FspmConfig.RefClk = MemConfig->RefClk;
474 FspmUpd->FspmConfig.Ratio = MemConfig->Ratio;
475 FspmUpd->FspmConfig.OddRatioMode = (UINT8) MemConfig->OddRatioMode;
476 FspmUpd->FspmConfig.tCL = (UINT8) MemConfig->tCL;
477 FspmUpd->FspmConfig.tCWL = (UINT8) MemConfig->tCWL;
478 FspmUpd->FspmConfig.tFAW = MemConfig->tFAW;
479 FspmUpd->FspmConfig.tRAS = MemConfig->tRAS;
480 FspmUpd->FspmConfig.tRCDtRP = (UINT8) MemConfig->tRCDtRP;
481 FspmUpd->FspmConfig.tREFI = MemConfig->tREFI;
482 FspmUpd->FspmConfig.tRFC = MemConfig->tRFC;
483 FspmUpd->FspmConfig.tRRD = (UINT8) MemConfig->tRRD;
484 FspmUpd->FspmConfig.tRTP = (UINT8) MemConfig->tRTP;
485 FspmUpd->FspmConfig.tWR = (UINT8) MemConfig->tWR;
486 FspmUpd->FspmConfig.tWTR = (UINT8) MemConfig->tWTR;
487 FspmUpd->FspmConfig.NModeSupport = MemConfig->NModeSupport;
488 FspmUpd->FspmConfig.DllBwEn0 = MemConfig->DllBwEn0;
489 FspmUpd->FspmConfig.DllBwEn1 = MemConfig->DllBwEn1;
490 FspmUpd->FspmConfig.DllBwEn2 = MemConfig->DllBwEn2;
491 FspmUpd->FspmConfig.DllBwEn3 = MemConfig->DllBwEn3;
492 FspmUpd->FspmConfig.EvLoader = (UINT8) MemConfig->EvLoader;
493
494 //
495 // Update UPD:SmramMask
496 //
497 if (MemConfig != NULL) {
498 FspmUpd->FspmConfig.SmramMask = MemConfig->SmramMask;
499 }
500
501 return EFI_SUCCESS;
502 }
503
504 /**
505 Performs FSP SA PEI Policy initialization.
506
507 @param[in][out] FspsUpd Pointer to FSP UPD Data.
508
509 @retval EFI_SUCCESS FSP UPD Data is updated.
510 @retval EFI_NOT_FOUND Fail to locate required PPI.
511 @retval Other FSP UPD Data update process fail.
512 **/
513 EFI_STATUS
514 EFIAPI
PeiFspSaPolicyInit(IN OUT FSPS_UPD * FspsUpd)515 PeiFspSaPolicyInit (
516 IN OUT FSPS_UPD *FspsUpd
517 )
518 {
519 EFI_STATUS Status;
520 SI_POLICY_PPI *SiPolicyPpi;
521 GRAPHICS_PEI_CONFIG *GtConfig;
522 VTD_CONFIG *Vtd;
523 //
524 // Locate SiPolicyPpi
525 //
526 SiPolicyPpi = NULL;
527 Status = PeiServicesLocatePpi(
528 &gSiPolicyPpiGuid,
529 0,
530 NULL,
531 (VOID **)&SiPolicyPpi
532 );
533 if ((Status == EFI_SUCCESS) && (SiPolicyPpi != NULL)) {
534 GtConfig = NULL;
535 Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gGraphicsPeiConfigGuid, (VOID *) &GtConfig);
536 ASSERT_EFI_ERROR (Status);
537
538 Vtd = NULL;
539 Status = GetConfigBlock ((VOID *) SiPolicyPpi, &gVtdConfigGuid, (VOID *) &Vtd);
540 ASSERT_EFI_ERROR (Status);
541
542 }
543
544 DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP UpdatePeiSaPolicy\n"));
545 if (GtConfig != NULL) {
546 //
547 // For FSP, FspsUpd->FspsConfig.PeiGraphicsPeimInit is always enabled as default.
548 //
549 FspsUpd->FspsConfig.PeiGraphicsPeimInit = (UINT8) GtConfig->PeiGraphicsPeimInit; // SA: InternalOnly: For Internal validation we still need to enable both Enable/Disable Cases
550
551 //
552 // Update UPD: VBT & LogoPtr
553 //
554 FspsUpd->FspsConfig.GraphicsConfigPtr = (UINT32) GtConfig->GraphicsConfigPtr;
555 DEBUG(( DEBUG_INFO, "VbtPtr from GraphicsPeiConfig is 0x%x\n", FspsUpd->FspsConfig.GraphicsConfigPtr));
556
557 FspsUpd->FspsConfig.LogoPtr = (UINT32) GtConfig->LogoPtr;
558 FspsUpd->FspsConfig.LogoSize = GtConfig->LogoSize;
559 DEBUG(( DEBUG_INFO, "LogoPtr from PeiFspSaPolicyInit GraphicsPeiConfig is 0x%x\n", FspsUpd->FspsConfig.LogoPtr));
560 DEBUG(( DEBUG_INFO, "LogoSize from PeiFspSaPolicyInit GraphicsPeiConfig is 0x%x\n", FspsUpd->FspsConfig.LogoSize));
561
562
563
564 }
565 if (Vtd != NULL) {
566 FspsUpd->FspsConfig.X2ApicOptOut = (UINT8) Vtd->X2ApicOptOut;
567 FspsUpd->FspsConfig.VtdBaseAddress[0] = Vtd->BaseAddress[0];
568 FspsUpd->FspsConfig.VtdBaseAddress[1] = Vtd->BaseAddress[1];
569 FspsUpd->FspsTestConfig.VtdDisable = (UINT8) Vtd->VtdDisable;
570 }
571 return EFI_SUCCESS;
572 }
573