12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574 |
- /** @file
- ACPI Platform Driver Hooks
- @copyright
- Copyright 1996 - 2020 Intel Corporation. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- //
- // Statements that include other files
- //
- #include "AcpiPlatformLibLocal.h"
- #include <Library/CrcLib.h>
- #include <BdatSchema.h>
- #include <Guid/MemoryMapData.h>
- #include <Library/CompressedVariableLib.h>
- #include <Protocol/DynamicSiLibraryProtocol2.h>
- #include <Protocol/DynamicSiLibraryProtocol2.h>
- extern struct SystemMemoryMapHob *mSystemMemoryMap;
- extern EFI_IIO_UDS_PROTOCOL *mIioUds;
- #include <Acpi/Bdat.h>
- #ifndef MAX_HOB_ENTRY_SIZE
- #define MAX_HOB_ENTRY_SIZE 60*1024
- #endif
- /**
- Save BSSA results to BDAT
- @param[in,out] BdatHeaderStructPtr - Pointer to BDAT Structure
- @param[in] OffsetFromLastSchema- Offset (in bytes) from the last schema. Need it to update the schema offsets array.
- @param[in] SchemaStartAddress - Starting address where the BSSA result schema will be added
- @param[in, out] SchemaIndex - Current schema index inside the BDAT. Need it to update the schema offsets array.
- @param[in] SchemaSize - The size of the BSSA results schema.
- @param[out] SchemaSpaceUsed - The numebr bytes were filled in all schema
- @param[out] LastSchemaSpaceUsed - The numebr bytes were filled in the last schema
- @retval EFI_SUCCESS - BSSA BDAT scehma created successfully
- @retval !EFI_SUCCESS - BSSA BDAT scehma creation failed
- **/
- EFI_STATUS
- SaveBssaResultsToBdat (
- IN OUT BDAT_STRUCTURE *BdatHeaderStructPtr,
- IN UINT32 OffsetFromLastSchema,
- IN EFI_PHYSICAL_ADDRESS *SchemaStartAddress,
- IN OUT UINT8 *SchemaIndex,
- IN UINT32 SchemaSize,
- OUT UINT32 *SchemaSpaceUsed,
- OUT UINT32 *LastSchemaSpaceUsed
- );
- /**
- Save EWL results to BDAT
- @param[in,out] BdatHeaderStructPtr - Pointer to BDAT Structure
- @param[in] OffsetFromLastSchema- Offset (in bytes) from the last schema. Need it to update the schema offsets array.
- @param[in] SchemaStartAddress - Starting address where the EWL schema will be added
- @param[in, out] SchemaIndex - Current schema index inside the BDAT. Need it to update the schema offsets array.
- @param[out] SchemaSpaceUsed - The numebr bytes were filled
- @retval EFI_SUCCESS - EWL BDAT scehma created successfully
- @retval !EFI_SUCCESS - EWL BDAT scehma creation failed
- **/
- EFI_STATUS
- SaveEwlToBdat (
- IN OUT BDAT_STRUCTURE *BdatHeaderStructPtr,
- IN UINT32 OffsetFromLastSchema,
- IN EFI_PHYSICAL_ADDRESS *SchemaStartAddress,
- IN OUT UINT8 *SchemaIndex,
- OUT UINT32 *SchemaSpaceUsed
- );
- /**
- Save SPD date structure to BDAT
- @param[in,out] BdatHeaderStructPtr - Pointer to BDAT Structure
- @param[in] OffsetFromLastSchema- Offset (in bytes) from the last schema. Need it to update the schema offsets array.
- @param[in] SchemaStartAddress - Starting address where the SPD data schema will be added
- @param[in, out] SchemaIndex - Current schema index inside the BDAT. Need it to update the schema offsets array.
- @param[out] SchemaSpaceUsed - The numebr bytes were filled
- @retval EFI_SUCCESS - SPD BDAT scehma created successfully
- @retval !EFI_SUCCESS - SPD BDAT scehma creation failed
- **/
- EFI_STATUS
- SaveSpdToBdat (
- IN OUT BDAT_STRUCTURE *BdatHeaderStructPtr,
- IN UINT32 OffsetFromLastSchema,
- IN EFI_PHYSICAL_ADDRESS *SchemaStartAddress,
- IN OUT UINT8 *SchemaIndex,
- OUT UINT32 *SchemaSpaceUsed
- );
- /**
- Save memory training date structure to BDAT
- @param[in,out] BdatHeaderStructPtr - Pointer to BDAT Structure
- @param[in] OffsetFromLastSchema- Offset (in bytes) from the last schema. Need it to update the schema offsets array.
- @param[in] SchemaStartAddress - Starting address where the memory training data schema will be added
- @param[in, out] SchemaIndex - Current schema index inside the BDAT. Need it to update the schema offsets array.
- @param[out] SchemaSpaceUsed - The numebr bytes were filled
- @retval EFI_SUCCESS - Memory training data BDAT scehma created successfully
- @retval !EFI_SUCCESS - Memory training data BDAT scehma creation failed
- **/
- EFI_STATUS
- SaveTrainingDataToBdat (
- IN OUT BDAT_STRUCTURE *BdatHeaderStructPtr,
- IN UINT32 OffsetFromLastSchema,
- IN EFI_PHYSICAL_ADDRESS *SchemaStartAddress,
- IN OUT UINT8 *SchemaIndex,
- OUT UINT32 *SchemaSpaceUsed
- );
- /**
- Get the size of SPD data structure not include the SPD BDAT schema header.
- @retval UINT32 - Size of SPD data structure in bytes
- **/
- UINT32
- GetSpdDataSize (
- VOID
- );
- /**
- Read the SPD data for one dimm and fill up SPD entry inside SPD BDAT schema space.
- @param[out] Address - Start Address of the buffer where the SPD entry to be filled
- @param[in] Socket - Socket number
- @param[in] Channel - Channel number inside the Socket
- @param[in] Dimm - Dimm slot number
- @param[in] MaxSpdByteOffset - The max SPD byte offset. DDR4 is 512
- @retval EFI_SUCCESS - SPD Structure filled successfully
- @retval !EFI_SUCCESS - SPD structure creation failed
- **/
- EFI_STATUS
- FillSpdPerDimmEntry (
- OUT EFI_PHYSICAL_ADDRESS Address,
- IN UINT8 Socket,
- IN UINT8 Channel,
- IN UINT8 Dimm,
- IN UINT16 MaxSpdByteOffset
- );
- /**
- Fill the SPD data structure inside the BDAT schema space.
- @param[out] StartAddress - Start Address of the buffer where SPD data structure to be filled
- @param[in] SpdDataSize - Size of SPD data structure includes the header
- @retval EFI_SUCCESS - SPD Structure filled successfully
- @retval !EFI_SUCCESS - SPD structure creation failed
- **/
- EFI_STATUS
- FillSpdSchema (
- OUT EFI_PHYSICAL_ADDRESS StartAddress,
- IN UINT32 SpdDataSize
- );
- /**
- Displays SPD content for debugging.
- @param[in] Address - The starting address of the SPD entry
- @retval N/A
- **/
- VOID
- DisplaySpdContents (
- IN EFI_PHYSICAL_ADDRESS Address
- );
- /**
- Get Number of Schemas From BSSA HOB
- @retval UINT16 - Number of BSSA Schemas
- **/
- UINT16
- GetNumberOfSchemasFromBssaHob (
- VOID
- )
- {
- UINT32 GuidIdx = 0;
- UINT16 NumberOfBssaSchemas = 0;
- EFI_STATUS Status = EFI_SUCCESS;
- DYNAMIC_SI_LIBARY_PROTOCOL *DynamicSiLibraryProtocol = NULL;
- Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, (VOID **) &DynamicSiLibraryProtocol);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return 0;
- }
- if (mSystemMemoryMap == NULL) {
- mSystemMemoryMap = DynamicSiLibraryProtocol->GetSystemMemoryMapData ();
- }
- ASSERT (mSystemMemoryMap != NULL);
- if (mSystemMemoryMap == NULL) {
- return 0;
- }
- for (GuidIdx = 0; GuidIdx < mSystemMemoryMap->Reserved9; GuidIdx++) {
- //
- // No. of HOBS per GUID added up for all GUIDs created from calls to saveToBdat ()
- //
- NumberOfBssaSchemas += mSystemMemoryMap->Reserved7[GuidIdx];
- DEBUG ((DEBUG_VERBOSE, "GuidIdx = %d, total num hobs: %d\n", GuidIdx, mSystemMemoryMap->Reserved7[GuidIdx]));
- }
- return NumberOfBssaSchemas;
- }
- /**
- Create BDAT Header with necessary information.
- Allocate memory with BdatSize and if failure return status.
- If Success return the pointer address for copying the schema information
- @param[out] BdatHeaderStructPtr - Pointer to BDAT Structure
- @param[in] BdatSize - Size of BDAT Structure
- @param[in] NumberOfSchema - Total nunber of of schema
- @retval EFI_SUCCESS - BDAT Structure created successfully
- @retval !EFI_SUCCESS - BDAT structure creation failed
- **/
- EFI_STATUS
- CreateBdatHeader (
- OUT BDAT_STRUCTURE **BdatHeaderStructPtr,
- IN UINT32 BdatSize,
- IN UINT16 NumberOfSchema
- )
- {
- EFI_TIME EfiTime;
- UINT64 Address = 0xffffffff;
- EFI_STATUS Status = EFI_SUCCESS;
- //
- // Allocating RealTime Memory for BDAT.
- //
- Status = gBS->AllocatePages (
- AllocateMaxAddress,
- EfiACPIMemoryNVS,
- EFI_SIZE_TO_PAGES(BdatSize),
- &Address
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // The memory location where the HOB's are to be copied to
- //
- ZeroMem ((VOID *)Address, BdatSize);
- *BdatHeaderStructPtr = (BDAT_STRUCTURE *)Address;
- DEBUG ((DEBUG_VERBOSE, "\nBDAT Allocated Address = %x\n", Address));
- //
- // Create BIOS Data Signature
- //
- (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[0] = 'B';
- (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[1] = 'D';
- (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[2] = 'A';
- (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[3] = 'T';
- (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[4] = 'H';
- (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[5] = 'E';
- (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[6] = 'A';
- (*BdatHeaderStructPtr)->BdatHeader.BiosDataSignature[7] = 'D';
- //
- // Structure size
- //
- (*BdatHeaderStructPtr)->BdatHeader.BiosDataStructSize = BdatSize;
- //
- // Primary Version
- //
- (*BdatHeaderStructPtr)->BdatHeader.PrimaryVersion = BDAT_PRIMARY_VER;
- //
- // Secondary Version
- //
- (*BdatHeaderStructPtr)->BdatHeader.SecondaryVersion = BDAT_SECONDARY_VER;
- //
- // CRC16 value of the BDAT_STRUCTURE
- //
- (*BdatHeaderStructPtr)->BdatHeader.Crc16 = 0;
- Status = CalculateCrc16 (
- (VOID *)(*BdatHeaderStructPtr),
- BdatSize,
- &(*BdatHeaderStructPtr)->BdatHeader.Crc16
- );
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR (Status)) {
- (*BdatHeaderStructPtr)->BdatHeader.Crc16 = 0xFFFF;
- }
- (*BdatHeaderStructPtr)->BdatSchemas.SchemaListLength = NumberOfSchema;
- (*BdatHeaderStructPtr)->BdatSchemas.Reserved = 0;
- (*BdatHeaderStructPtr)->BdatSchemas.Reserved1 = 0;
- //
- // Initialize the Time parameters in the SCHEMA_LIST_STRUCTURE
- //
- Status = gRT->GetTime (&EfiTime, NULL);
- if (!EFI_ERROR (Status)) {
- (*BdatHeaderStructPtr)->BdatSchemas.Year = EfiTime.Year;
- (*BdatHeaderStructPtr)->BdatSchemas.Month = EfiTime.Month;
- (*BdatHeaderStructPtr)->BdatSchemas.Day = EfiTime.Day;
- (*BdatHeaderStructPtr)->BdatSchemas.Hour = EfiTime.Hour;
- (*BdatHeaderStructPtr)->BdatSchemas.Minute = EfiTime.Minute;
- (*BdatHeaderStructPtr)->BdatSchemas.Second = EfiTime.Second;
- }
- return Status;
- }
- /**
- Dump BDAT Table to serial log
- Example 1: There are 2 schema: BSSA RMT and EWL.
- Print BDAT Table
- Address 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 00000000 0x42 0x44 0x41 0x54 0x48 0x45 0x41 0x44 0x30 0x18 0x00 0x00 0xD7 0x7A 0x00 0x00
- 00000010 0x04 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
- 00000020 0x02 0x00 0x00 0x00 0xE4 0x07 0x08 0x0E 0x00 0x29 0x03 0x00 0x34 0x00 0x00 0x00
- 00000030 0xFA 0x07 0x00 0x00 0x28 0xE9 0xF4 0x08 0x5F 0x0F 0xD4 0x46 0x84 0x10 0x47 0x9F
- 00000040 0xDA 0x27 0x9D 0xB6 0xC6 0x07 0x00 0x00 0x57 0x7F 0x00 0x00 0x00 0x00 0x00 0xA5
- 00000050 0x98 0x88 0xFE 0x4C 0x00 0x00 0x00 0x0D 0xEB 0x7A 0x47 0x07 0xDE 0x77 0x42 0xA4
- 00000060 0xE7 0x87 0x81 0x0B 0x10 0x00 0x31 0xF1 0x98 0x88 0xFE 0xF2 0x45 0x81 0xD9 0xF4
- ...
- ...
- 000007F0 0x00 0x00 0x00 0x5A 0xA5 0x5A 0xA5 0x5A 0xA5 0x5A 0x2F 0x53 0xFE 0xBF 0x3B 0xCA
- 00000800 0x6C 0x41 0xA0 0xF6 0xFF 0xE4 0xE7 0x1E 0x3A 0x0D 0x36 0x10 0x00 0x00 0x9F 0xEF
- 00000810 0x70 0x33 0x71 0x75 0x05 0x38 0xB0 0x46 0x9F 0xED 0x60 0xF2 0x82 0x48 0x6C 0xFC
- 00000820 0x20 0x10 0x00 0x00 0x12 0x00 0x00 0x00 0x2E 0x81 0x50 0x51 0x00 0x00 0x00 0x00
- 00000830 0x01 0x00 0x00 0x00 0x12 0x00 0x01 0x00 0x00 0x00 0x7E 0x07 0x17 0x18 0x01 0xFF
- 00000840 0xFF 0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
- Example 2: There is 1 schema: EWL
- Address 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 00000000 0x42 0x44 0x41 0x54 0x48 0x45 0x41 0x44 0x66 0x10 0x00 0x00 0xA9 0x44 0x00 0x00
- 00000010 0x04 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
- 00000020 0x01 0x00 0x00 0x00 0xE4 0x07 0x08 0x0E 0x01 0x0F 0x2C 0x00 0x30 0x00 0x00 0x00
- 00000030 0x2F 0x53 0xFE 0xBF 0x3B 0xCA 0x6C 0x41 0xA0 0xF6 0xFF 0xE4 0xE7 0x1E 0x3A 0x0D
- 00000040 0x36 0x10 0x00 0x00 0x9F 0xEF 0x70 0x33 0x71 0x75 0x05 0x38 0xB0 0x46 0x9F 0xED
- 00000050 0x60 0xF2 0x82 0x48 0x6C 0xFC 0x20 0x10 0x00 0x00 0x12 0x00 0x00 0x00 0x2E 0x81
- 00000060 0x50 0x51 0x00 0x00 0x00 0x00 0x01 0x00 0x00 0x00 0x12 0x00 0x01 0x00 0x00 0x00
- 00000070 0x7E 0x07 0x17 0x18 0x01 0xFF 0xFF 0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
- 00000080 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
- @param[out] BdatHeaderStructPtr - Pointer to BDAT Structure
- @param[in] BdatSize - Size of BDAT Structure
- @retval None
- **/
- VOID
- DumpBdatTable(
- IN BDAT_STRUCTURE **BdatHeaderStructPtr,
- IN UINT32 BdatSize
- )
- {
- UINT32 i = 0;
- UINT8 *Table = NULL;
- Table = (UINT8 *)(*BdatHeaderStructPtr);
- DEBUG ((DEBUG_VERBOSE, "\nPrint BDAT Table\n"));
- //
- // Print address header
- //
- DEBUG ((DEBUG_VERBOSE, "Address "));
- for (i = 0; i < 16; i++) {
- DEBUG ((DEBUG_VERBOSE, " %01x", i));
- }
- i = 0;
- while (i < BdatSize) {
- if ((i % 16) == 0) {
- DEBUG ((DEBUG_VERBOSE, "\n%08x ", (i / 16) * 16));
- } else {
- DEBUG ((DEBUG_VERBOSE, " "));
- }
- DEBUG ((DEBUG_VERBOSE, "0x%02x", Table[i]));
- if (i == BdatSize - 1) {
- DEBUG ((DEBUG_VERBOSE, "\n"));
- }
- i++;
- }
- DEBUG ((DEBUG_VERBOSE, "\n"));
- }
- /**
- Copy BDAT Table pointer to scratchpad 5 register
- @param[in] BdatAddress - Bdat Table Address to be copied to Scratchpad 5 register
- @retval None
- **/
- VOID
- CopyBdatPointerToScratchPad5 (
- IN UINT64 BdatAddress
- )
- {
- UINT8 Socket = 0;
- EFI_STATUS Status = EFI_SUCCESS;
- DYNAMIC_SI_LIBARY_PROTOCOL *DynamicSiLibraryProtocol = NULL;
- Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, (VOID **) &DynamicSiLibraryProtocol);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return;
- }
- //
- // Copy BDAT base address to ScratchPad5
- //
- for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
- if (mIioUds->IioUdsPtr->PlatformData.CpuQpiInfo[Socket].Valid) {
- DynamicSiLibraryProtocol->WriteScratchpad5 (Socket, (UINT32) BdatAddress);
- DEBUG ((DEBUG_VERBOSE, "Scratchpad_Debug PatchBdaAcpiTable: Verify Non Sticky Scratchpad5 0x%08x\n", BdatAddress));
- }
- }
- }
- /**
- Update the BDAT ACPI table: Multiple instances of the BDAT DATA HOB are placed into one contiguos memory range
- @param *TableHeader - The table to be set
- @retval EFI_SUCCESS - Returns Success
- **/
- EFI_STATUS
- PatchBdatAcpiTable (
- IN OUT EFI_ACPI_COMMON_HEADER *Table
- )
- {
- EFI_STATUS Status = EFI_SUCCESS;
- EFI_PHYSICAL_ADDRESS Address = 0;
- UINT32 Idx = 0;
- UINT8 Checksum = 0;
- BDAT_STRUCTURE *BdatHeaderStructPtr = NULL;
- UINT32 TotalBDATstructureSize = 0;
- UINT32 BdatHeaderSize = 0;
- EFI_HOB_GUID_TYPE *GuidHob = NULL;
- UINT16 NumberBssaSchemas = 0;
- UINT16 TotalNumberSchemas = 0;
- UINT32 BssaSchemaSize = 0;
- EFI_BDAT_ACPI_DESCRIPTION_TABLE *BdatAcpiTable = NULL;
- EWL_PRIVATE_DATA *EwlPrivateData = NULL;
- EFI_GUID EWLDataGuid = EWL_ID_GUID;
- UINT32 EwlSchemaSize = 0;
- MEM_TRAINING_DATA_STRUCTURE *MemTrainingData = NULL;
- MEM_TRAINING_DATA_HOB_HEADER *TrainingDataHobHeader = NULL;
- UINT32 TrainingDataSchemaSize = 0;
- UINT32 RemainingSchemaSpace = 0;
- UINT32 SpdDataSize = 0;
- UINT32 SpdSchemaSize = 0;
- UINT8 SchemaIndex = 0;
- UINT32 SpaceUsed = 0;
- UINT32 LastSchemaSpaceUsed = 0;
- UINT32 OffsetFromLastSchema = 0;
- BdatAcpiTable = (EFI_BDAT_ACPI_DESCRIPTION_TABLE *)Table;
- DEBUG ((DEBUG_INFO, "\nPatchBdatAcpiTable Started\n"));
- //
- // Gather BSSA schema info
- //
- NumberBssaSchemas = GetNumberOfSchemasFromBssaHob ();
- BssaSchemaSize = mSystemMemoryMap->Reserved6 + (NumberBssaSchemas * sizeof (BDAT_SCHEMA_HEADER_STRUCTURE)); //Total size of all HOBs created by SaveToBdat() + NumberBssaSchemas*headerPerSchema
- DEBUG ((DEBUG_VERBOSE, "NumberBssaSchemas = %d, total BSSA schema size: %d\n", NumberBssaSchemas, BssaSchemaSize));
- TotalNumberSchemas = NumberBssaSchemas;
- TotalBDATstructureSize += BssaSchemaSize;
- //
- // Gather EWL schema info
- //
- GuidHob = GetFirstGuidHob (&EWLDataGuid);
- if (GuidHob != NULL) {
- DEBUG ((DEBUG_VERBOSE, "Found EWL with GUID %g\n", &EWLDataGuid));
- TotalNumberSchemas += 1;
- EwlPrivateData = GET_GUID_HOB_DATA (GuidHob);
- EwlSchemaSize = sizeof (BDAT_SCHEMA_HEADER_STRUCTURE) + EwlPrivateData->status.Header.Size;
- DEBUG ((DEBUG_VERBOSE, "EWL schema size: %d\n", EwlSchemaSize));
- TotalBDATstructureSize += EwlSchemaSize;
- }
- //
- // Gather SPD schema info
- //
- SpdSchemaSize = 0;
- if (PcdGetBool (SaveSpdToBdat)) {
- SpdDataSize = GetSpdDataSize ();
- if (SpdDataSize > 0) {
- TotalNumberSchemas += 1;
- SpdSchemaSize = sizeof (BDAT_SCHEMA_HEADER_STRUCTURE) + SpdDataSize;
- DEBUG ((DEBUG_VERBOSE, "SPD data schema size: %d\n", SpdSchemaSize));
- TotalBDATstructureSize += SpdSchemaSize;
- }
- } // PcdGetBool (SaveSpdToBdat)
- //
- // Gather Memory training data schema info
- //
- TrainingDataSchemaSize = 0;
- if (PcdGetBool (SaveMrcTrainingDataToBdat)) {
- GuidHob = GetFirstGuidHob (&gMemTrainingDataHobGuid);
- if (GuidHob != NULL) {
- DEBUG ((DEBUG_VERBOSE, "Found memory training data HOB with GUID %g\n", &gMemTrainingDataHobGuid));
- TotalNumberSchemas += 1;
- TrainingDataHobHeader = GET_GUID_HOB_DATA (GuidHob);
- MemTrainingData = (MEM_TRAINING_DATA_STRUCTURE *)((EFI_PHYSICAL_ADDRESS)TrainingDataHobHeader + sizeof (MEM_TRAINING_DATA_HOB_HEADER));
- TrainingDataSchemaSize = sizeof (BDAT_SCHEMA_HEADER_STRUCTURE) + MemTrainingData->Header.Size;
- DEBUG ((DEBUG_VERBOSE, "Memory training data schema size: %d\n", TrainingDataSchemaSize));
- TotalBDATstructureSize += TrainingDataSchemaSize;
- }
- } // PcdGetBool (SaveMrcTrainingDataToBdat)
- BdatHeaderSize = sizeof (BDAT_STRUCTURE) + (TotalNumberSchemas * (sizeof (UINT32)));
- TotalBDATstructureSize += BdatHeaderSize;
- //
- // This variable is used to keep track the remain space in the BDAT payload (schema section) to
- // prevent overflow the allocated RT BDAT buffer.
- //
- RemainingSchemaSpace = TotalBDATstructureSize - BdatHeaderSize;
- DEBUG ((DEBUG_INFO, "Total BDAT size:%d, BDAT header size: %d, Total schema:%d \n", TotalBDATstructureSize, BdatHeaderSize, TotalNumberSchemas));
- Status = CreateBdatHeader (&BdatHeaderStructPtr, TotalBDATstructureSize, TotalNumberSchemas);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- DEBUG ((DEBUG_INFO, "BdatRegionAddress = 0x%x\n", (UINT64)BdatHeaderStructPtr));
- CopyBdatPointerToScratchPad5 ((UINT64)BdatHeaderStructPtr);
- //
- // Update BDAT ACPI table
- //
- BdatAcpiTable->BdatGas.Address = (UINT64)BdatHeaderStructPtr;
- //
- // Starting address of the first schema
- //
- Address = (EFI_PHYSICAL_ADDRESS)BdatHeaderStructPtr + BdatHeaderSize;
- //
- // Saving to RT Memory BDAT Data received from HOBs generated due to BSSA call/calls to SaveToBdat()
- //
- SpaceUsed = 0;
- //
- // The first schema starts right after the BDAT header structure
- //
- LastSchemaSpaceUsed = BdatHeaderSize; // It will used as the OffsetFromLastSchema for the next schema if BSSA is not available
- OffsetFromLastSchema = BdatHeaderSize;
- if (BssaSchemaSize > 0) {
- Status = SaveBssaResultsToBdat (BdatHeaderStructPtr, OffsetFromLastSchema, &Address, &SchemaIndex, BssaSchemaSize, &SpaceUsed, &LastSchemaSpaceUsed);
- if (Status != EFI_SUCCESS) {
- DEBUG ((DEBUG_ERROR, "Faield to add BSSA result to BDAT\n"));
- }
- }
- //
- // Update the starting address of next schema and remaining space.
- //
- Address += SpaceUsed;
- RemainingSchemaSpace -= SpaceUsed;
- OffsetFromLastSchema = LastSchemaSpaceUsed;
- //
- // Saving to RT Memory BDAT Data received from EWL HOB
- //
- SpaceUsed = 0;
- if (EwlSchemaSize > 0) {
- if (RemainingSchemaSpace < EwlSchemaSize) {
- DEBUG ((DEBUG_ERROR, "Not enough space to add EWL schema.\n"));
- goto End;
- }
- Status = SaveEwlToBdat (BdatHeaderStructPtr, OffsetFromLastSchema ,&Address, &SchemaIndex, &SpaceUsed);
- if (Status != EFI_SUCCESS) {
- DEBUG ((DEBUG_ERROR, "Failed to add EWL to BDAT.\n"));
- }
- }
- //
- // Update the starting address of next schema and remaining space.
- //
- Address += SpaceUsed;
- RemainingSchemaSpace -= SpaceUsed;
- OffsetFromLastSchema = SpaceUsed;
- //
- // Add SPD schema
- //
- SpaceUsed = 0;
- if (SpdSchemaSize > 0) {
- if (RemainingSchemaSpace < SpdSchemaSize) {
- DEBUG ((DEBUG_ERROR, "Not enough space to add SPD schema.\n"));
- goto End;
- }
- Status = SaveSpdToBdat (BdatHeaderStructPtr, OffsetFromLastSchema, &Address, &SchemaIndex, &SpaceUsed);
- if (Status != EFI_SUCCESS) {
- DEBUG ((DEBUG_ERROR, "Failed to add SPD to BDAT.\n"));
- }
- }
- //
- // Update the starting address of next schema and remaining space.
- //
- Address += SpaceUsed;
- RemainingSchemaSpace -= SpaceUsed;
- OffsetFromLastSchema = SpaceUsed;
- //
- // Add memory training data schema
- //
- SpaceUsed = 0;
- if (TrainingDataSchemaSize > 0) {
- if (RemainingSchemaSpace < TrainingDataSchemaSize) {
- DEBUG ((DEBUG_ERROR, "Not enough space to add memory training data schema.\n"));
- goto End;
- }
- Status = SaveTrainingDataToBdat (BdatHeaderStructPtr, OffsetFromLastSchema, &Address, &SchemaIndex, &SpaceUsed);
- if (Status != EFI_SUCCESS) {
- DEBUG ((DEBUG_ERROR, "Failed to add memory training data to BDAT.\n"));
- }
- }
- //
- // Update the starting address of next schema and remaining space.
- //
- Address += SpaceUsed;
- RemainingSchemaSpace -= SpaceUsed;
- OffsetFromLastSchema = SpaceUsed;
- DEBUG ((DEBUG_VERBOSE, "Final SchemaIndex:%d RemainingSchemaSpace:%d\n", SchemaIndex, RemainingSchemaSpace));
- End:
- //
- // Update checksum
- //
- BdatAcpiTable->Header.Checksum = 0;
- Checksum = 0;
- for(Idx = 0; Idx < sizeof(EFI_BDAT_ACPI_DESCRIPTION_TABLE); Idx++) {
- Checksum = Checksum + (UINT8) (((UINT8 *)(BdatAcpiTable))[Idx]);
- }
- BdatAcpiTable->Header.Checksum = (UINT8) (0 - Checksum);
- DumpBdatTable (&BdatHeaderStructPtr, TotalBDATstructureSize);
- return Status;
- }
- /**
- Displays SPD content for debugging.
- @param[in] Address - The starting address of the SPD entry
- @retval N/A
- **/
- VOID
- DisplaySpdContents (
- IN EFI_PHYSICAL_ADDRESS Address
- )
- {
- UINT16 Index;
- MEM_SPD_ENTRY_TYPE0 *EntryHeaderPtr;
- EntryHeaderPtr = (MEM_SPD_ENTRY_TYPE0 *)Address;
- //
- // Print the Socket, Channel and Dimm information.
- //
- DEBUG ((DEBUG_VERBOSE, "START_PRINT_SPD S%dC%dD%d:\n",
- EntryHeaderPtr->MemoryLocation.Socket,
- EntryHeaderPtr->MemoryLocation.Channel,
- EntryHeaderPtr->MemoryLocation.Dimm));
- //
- // Print the Column Number of the SPD data.
- //
- for (Index = 0; Index < 0x10; Index++) {
- DEBUG ((DEBUG_VERBOSE, " %02x", Index));
- }
- Address += sizeof (MEM_SPD_ENTRY_TYPE0);
- for (Index = 0; Index < EntryHeaderPtr->NumberOfBytes; Index++) {
- //
- // Print the Carriage Return and Byte Index of SPD data.
- //
- if ((Index % 0x10) == 0) {
- //
- // Split the SPD data for every 256 bytes
- //
- if (((Index % 0x100) == 0) && (Index != 0)) {
- DEBUG ((DEBUG_VERBOSE, "\n"));
- }
- DEBUG ((DEBUG_VERBOSE, "\n%02x:", (UINT8) (Index & 0x00F0)));
- }
- DEBUG ((DEBUG_VERBOSE, " %02x", *(UINT8 *)(Address + (EFI_PHYSICAL_ADDRESS)Index)));
- }
- DEBUG ((DEBUG_VERBOSE, "\n"));
- DEBUG ((DEBUG_VERBOSE, "STOP_PRINT_SPD\n"));
- } // DisplaySpdContents
- /**
- Get the size of SPD data structure not include the SPD BDAT schema header.
- @retval UINT32 - Size of SPD data structure in bytes
- **/
- UINT32
- GetSpdDataSize (
- VOID
- )
- {
- UINT32 SchemaSize = 0;
- UINT8 Socket;
- UINT8 Channel;
- UINT8 Dimm;
- UINT32 SpdBytesPerDimm = 0;
- UINT8 NumberOfDimmPresent = 0;
- EFI_STATUS Status = EFI_SUCCESS;
- DYNAMIC_SI_LIBARY_PROTOCOL *DynamicSiLibraryProtocol = NULL;
- Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, (VOID **) &DynamicSiLibraryProtocol);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return 0;
- }
- if (mSystemMemoryMap == NULL) {
- mSystemMemoryMap = DynamicSiLibraryProtocol->GetSystemMemoryMapData ();
- }
- if (mSystemMemoryMap == NULL) {
- return 0;
- }
- ASSERT (mSystemMemoryMap->DramType == SPD_TYPE_DDR4);
- SpdBytesPerDimm = MAX_SPD_BYTE_DDR4;
- for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
- for (Channel = 0; Channel < MAX_CH; Channel++) {
- for (Dimm = 0; Dimm < MAX_DIMM; Dimm++) {
- if (mSystemMemoryMap->Socket[Socket].ChannelInfo[Channel].DimmInfo[Dimm].Present != 0) {
- NumberOfDimmPresent += 1;
- }
- }
- }
- }
- //
- // Total entries
- //
- SchemaSize = (SpdBytesPerDimm + sizeof (MEM_SPD_ENTRY_TYPE0)) * NumberOfDimmPresent;
- //
- // Add the SPD raw data header
- //
- SchemaSize += sizeof (MEM_SPD_RAW_DATA_HEADER);
- return SchemaSize;
- }
- /**
- Read the SPD data for one dimm and fill up SPD entry inside SPD BDAT schema space.
- @param[out] Address - Start Address of the buffer where the SPD entry to be filled
- @param[in] Socket - Socket number
- @param[in] Channel - Channel number inside the Socket
- @param[in] Dimm - Dimm slot number
- @param[in] MaxSpdByteOffset - The max SPD byte offset. DDR4 is 512
- @retval EFI_SUCCESS - SPD Structure filled successfully
- @retval !EFI_SUCCESS - SPD structure creation failed
- **/
- EFI_STATUS
- FillSpdPerDimmEntry (
- OUT EFI_PHYSICAL_ADDRESS Address,
- IN UINT8 Socket,
- IN UINT8 Channel,
- IN UINT8 Dimm,
- IN UINT16 MaxSpdByteOffset
- )
- {
- UINT16 SpdByteOffset = 0;
- UINT8 SpdData = 0;
- MEM_SPD_ENTRY_TYPE0 *EntryHeaderPtr;
- EFI_STATUS Status = EFI_SUCCESS;
- DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 = NULL;
- DEBUG ((DEBUG_VERBOSE, "Fill Spd entry for Socket:%d Channel:%d Dimm:%d at location:0x%x \n", Socket, Channel, Dimm, Address));
- Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, (VOID **) &DynamicSiLibraryProtocol2);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return Status;
- }
- EntryHeaderPtr = (MEM_SPD_ENTRY_TYPE0 *)Address;
- //
- // Add the entry header. We use type 0.
- //
- EntryHeaderPtr->Header.Type = MemSpdDataType0;
- EntryHeaderPtr->Header.Size = sizeof (MEM_SPD_ENTRY_TYPE0) + MaxSpdByteOffset;
- EntryHeaderPtr->MemoryLocation.Socket = Socket;
- EntryHeaderPtr->MemoryLocation.Channel = Channel;
- EntryHeaderPtr->MemoryLocation.Dimm = Dimm;
- EntryHeaderPtr->NumberOfBytes = MaxSpdByteOffset;
- Address += sizeof (MEM_SPD_ENTRY_TYPE0);
- for (SpdByteOffset = 0; SpdByteOffset < MaxSpdByteOffset; SpdByteOffset++) {
- Status = DynamicSiLibraryProtocol2->SpdReadByte (Socket, Channel, Dimm, SpdByteOffset, &SpdData);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_WARN, "Failed to read SPD data at Socket:%d Channel:%d Dimm:%d SpdByteOffset:%d Status:0x%x\n",
- Socket, Channel, Dimm, SpdByteOffset, Status));
- return Status;
- }
- *(UINT8 *)Address = SpdData;
- Address += 1;
- } // SpdByteOffset
- return Status;
- }
- /**
- Fill the SPD data structure inside the BDAT schema space.
- @param[out] StartAddress - Start Address of the buffer where SPD data structure to be filled
- @param[in] SpdDataSize - Size of SPD data structure includes the header
- @retval EFI_SUCCESS - SPD Structure filled successfully
- @retval !EFI_SUCCESS - SPD structure creation failed
- **/
- EFI_STATUS
- FillSpdSchema (
- OUT EFI_PHYSICAL_ADDRESS StartAddress,
- IN UINT32 SpdDataSize
- )
- {
- UINT8 Socket;
- UINT8 Channel;
- UINT8 Dimm;
- UINT16 MaxSpdByteOffset = 0;
- UINT32 RemainedSpace;
- EFI_PHYSICAL_ADDRESS Address;
- MEM_SPD_RAW_DATA_HEADER *SpdDataHeaderStructPtr;
- EFI_STATUS Status = EFI_SUCCESS;
- DYNAMIC_SI_LIBARY_PROTOCOL *DynamicSiLibraryProtocol = NULL;
- Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, (VOID **) &DynamicSiLibraryProtocol);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return Status;
- }
- if (mSystemMemoryMap == NULL) {
- mSystemMemoryMap = DynamicSiLibraryProtocol->GetSystemMemoryMapData ();
- }
- if (mSystemMemoryMap == NULL) {
- return EFI_DEVICE_ERROR;;
- }
- if (StartAddress == 0) {
- return EFI_INVALID_PARAMETER;
- }
- RemainedSpace = SpdDataSize;
- Address = StartAddress;
- SpdDataHeaderStructPtr = (MEM_SPD_RAW_DATA_HEADER *)StartAddress;
- //
- // Fill up the header of the SPD data strcuture
- //
- SpdDataHeaderStructPtr->MemSpdGuid = gSpdVersion1Guid;
- SpdDataHeaderStructPtr->Size = SpdDataSize;
- SpdDataHeaderStructPtr->Reserved = 0;
- Address += sizeof (MEM_SPD_RAW_DATA_HEADER);
- RemainedSpace -= sizeof (MEM_SPD_RAW_DATA_HEADER);
- ASSERT (mSystemMemoryMap->DramType == SPD_TYPE_DDR4);
- MaxSpdByteOffset = MAX_SPD_BYTE_DDR4;
- //
- // Iterate through all populated DIMMs and add them
- //
- for (Socket = 0; Socket < MAX_SOCKET; Socket++) {
- for (Channel = 0; Channel < MAX_CH; Channel++) {
- for (Dimm = 0; Dimm < MAX_DIMM; Dimm++) {
- if (mSystemMemoryMap->Socket[Socket].ChannelInfo[Channel].DimmInfo[Dimm].Present != 0) {
- if (RemainedSpace < sizeof (MEM_SPD_ENTRY_TYPE0) + MaxSpdByteOffset) {
- DEBUG ((DEBUG_ERROR, "Run out of allocated SPD data space. RemainedSpace:%d required space:%d\n",
- RemainedSpace, sizeof (MEM_SPD_ENTRY_TYPE0) + MaxSpdByteOffset));
- return RETURN_OUT_OF_RESOURCES;
- }
- Status = FillSpdPerDimmEntry (Address, Socket, Channel, Dimm, MaxSpdByteOffset);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Failed to read SPD data at Socket:%d Channel:%d Dimm:%d Status:0x%x.\n", Socket, Channel, Dimm, Status));
- return Status;
- }
- DisplaySpdContents (Address);
- Address += sizeof (MEM_SPD_ENTRY_TYPE0) + MaxSpdByteOffset;
- RemainedSpace -= sizeof (MEM_SPD_ENTRY_TYPE0) + MaxSpdByteOffset;
- }
- } // Dimm
- } // Channel
- } // Socket
- //
- // Update CRC
- //
- SpdDataHeaderStructPtr->Crc = 0;
- SpdDataHeaderStructPtr->Crc = CalculateCrc32 ((VOID *) SpdDataHeaderStructPtr, SpdDataHeaderStructPtr->Size);
- return EFI_SUCCESS;
- }
- /**
- Save BSSA results to BDAT
- @param[in,out] BdatHeaderStructPtr - Pointer to BDAT Structure
- @param[in] OffsetFromLastSchema- Offset (in bytes) from the last schema. Need it to update the schema offsets array.
- @param[in] SchemaStartAddress - Starting address where the BSSA result schema will be added
- @param[in, out] SchemaIndex - Current schema index inside the BDAT. Need it to update the schema offsets array.
- @param[in] SchemaSize - The size of the BSSA results schema.
- @param[out] SchemaSpaceUsed - The numebr bytes were filled in all schema
- @param[out] LastSchemaSpaceUsed - The numebr bytes were filled in the last schema
- @retval EFI_SUCCESS - BSSA BDAT scehma created successfully
- @retval !EFI_SUCCESS - BSSA BDAT scehma creation failed
- **/
- EFI_STATUS
- SaveBssaResultsToBdat (
- IN OUT BDAT_STRUCTURE *BdatHeaderStructPtr,
- IN UINT32 OffsetFromLastSchema,
- IN EFI_PHYSICAL_ADDRESS *SchemaStartAddress,
- IN OUT UINT8 *SchemaIndex,
- IN UINT32 SchemaSize,
- OUT UINT32 *SchemaSpaceUsed,
- OUT UINT32 *LastSchemaSpaceUsed
- )
- {
- EFI_STATUS Status = EFI_SUCCESS;
- UINT32 *SchemaAddrLocationArray = NULL;
- UINT32 CurrentHobSize = 0;
- EFI_HOB_GUID_TYPE *GuidHob = NULL;
- VOID *HobData = NULL;
- UINT32 PreviousSchemaSize = 0;
- EFI_GUID gEfiMemoryMapDataHobBdatBssaGuid = {0};
- UINT32 GuidIdx = 0;
- UINT32 HobIdx = 0;
- UINT32 RemainingHobSizeBssaSchema = 0;
- BDAT_SCHEMA_HEADER_STRUCTURE *BssaSchemaHeaderPtr = NULL;
- EFI_PHYSICAL_ADDRESS Address = 0;
- if ((BdatHeaderStructPtr == NULL) || (SchemaStartAddress == NULL) || (SchemaIndex == NULL) || (SchemaSpaceUsed == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- RemainingHobSizeBssaSchema = SchemaSize;
- Address = *SchemaStartAddress;
- *SchemaSpaceUsed = 0;
- //
- // Update the schema offset array for its first BSSA schema
- //
- SchemaAddrLocationArray = (UINT32 *)((EFI_PHYSICAL_ADDRESS)BdatHeaderStructPtr + sizeof(BDAT_STRUCTURE));
- if (*SchemaIndex < BdatHeaderStructPtr->BdatSchemas.SchemaListLength) {
- if (*SchemaIndex == 0) {
- SchemaAddrLocationArray[*SchemaIndex] = OffsetFromLastSchema;
- }
- else {
- SchemaAddrLocationArray[*SchemaIndex] = SchemaAddrLocationArray[*SchemaIndex - 1] + OffsetFromLastSchema;
- }
- }
- for (GuidIdx = 0; GuidIdx < mSystemMemoryMap->Reserved9; GuidIdx++) {
- gEfiMemoryMapDataHobBdatBssaGuid = mSystemMemoryMap->Reserved8[GuidIdx]; //get first GUID instance
- GuidHob = GetFirstGuidHob (&gEfiMemoryMapDataHobBdatBssaGuid);
- for (HobIdx = 0; HobIdx < mSystemMemoryMap->Reserved7[GuidIdx]; HobIdx++) { //looping through all HOBs linked to that GUID
- ASSERT (GuidHob != NULL);
- if (GuidHob == NULL) {
- return EFI_NOT_FOUND;
- }
- HobData = GET_GUID_HOB_DATA (GuidHob);
- CurrentHobSize = GET_GUID_HOB_DATA_SIZE (GuidHob);
- DEBUG ((DEBUG_VERBOSE, "Initial HOB size %d; remaining HOB size %d\n", CurrentHobSize, RemainingHobSizeBssaSchema));
- //
- // Setting the header first
- //
- if (RemainingHobSizeBssaSchema < sizeof(BDAT_SCHEMA_HEADER_STRUCTURE)) {
- //
- // Nothing we can do, break execution
- //
- DEBUG ((DEBUG_WARN, "Not enough space to add schema header to BIOS SSA result\n"));
- RemainingHobSizeBssaSchema = 0;
- break;
- }
- //
- // Each HOB has a header added to it (BDAT_SCHEMA_HEADER_STRUCTURE)
- //
- Address = Address + (EFI_PHYSICAL_ADDRESS)PreviousSchemaSize;
- BssaSchemaHeaderPtr = (BDAT_SCHEMA_HEADER_STRUCTURE *)Address;
- BssaSchemaHeaderPtr->SchemaId = gEfiMemoryMapDataHobBdatBssaGuid;
- RemainingHobSizeBssaSchema -= sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
- *SchemaSpaceUsed = *SchemaSpaceUsed + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
- Address = Address + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
- //
- // CRC16 value of the BDAT_SCHEMA_HEADER_STRUCTURE
- //
- BssaSchemaHeaderPtr->Crc16 = 0;
- Status = CalculateCrc16 (
- (VOID *) BssaSchemaHeaderPtr,
- sizeof (BDAT_SCHEMA_HEADER_STRUCTURE),
- &BssaSchemaHeaderPtr->Crc16
- );
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR (Status)) {
- BssaSchemaHeaderPtr->Crc16 = 0xFFFF;
- }
- if (RemainingHobSizeBssaSchema < CurrentHobSize) {
- DEBUG ((DEBUG_WARN, "Not enough space to add complete BIOS SSA result\n"));
- CurrentHobSize = RemainingHobSizeBssaSchema;
- }
- //
- // HOB size won't overflow a UINT32.
- //
- BssaSchemaHeaderPtr->DataSize = (UINT32)CurrentHobSize + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
- DEBUG ((DEBUG_VERBOSE, "Setting schema %g size to %d\n", &(BssaSchemaHeaderPtr->SchemaId), BssaSchemaHeaderPtr->DataSize));
- //
- // HOB size won't overflow a UINT32.
- //
- PreviousSchemaSize = (UINT32)CurrentHobSize + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
- //
- // Copy HOB to RT Memory
- //
- CopyMem ((VOID *)Address, (VOID *)HobData, (UINT32)CurrentHobSize);
- //
- // HOB size won't overflow a UINT32.
- //
- DEBUG ((DEBUG_VERBOSE, "HOB size %d; remaining SSA HOB size %d\n", CurrentHobSize, RemainingHobSizeBssaSchema));
- RemainingHobSizeBssaSchema -= (UINT32)CurrentHobSize;
- *SchemaSpaceUsed = *SchemaSpaceUsed + (UINT32)CurrentHobSize;
- *SchemaIndex = *SchemaIndex + 1;
- if (RemainingHobSizeBssaSchema == 0) {
- break;
- }
- GuidHob = GET_NEXT_HOB (GuidHob); // Increment to next HOB
- GuidHob = GetNextGuidHob (&gEfiMemoryMapDataHobBdatBssaGuid, GuidHob); // Now search for next instance of the BDAT HOB
- if (GuidHob == NULL) {
- break;
- }
- //
- // Update the schema offset arrary
- //
- if (*SchemaIndex < BdatHeaderStructPtr->BdatSchemas.SchemaListLength) {
- SchemaAddrLocationArray[*SchemaIndex] = SchemaAddrLocationArray[*SchemaIndex - 1] + PreviousSchemaSize;
- }
- }
- if (RemainingHobSizeBssaSchema == 0) {
- break;
- }
- }
- *LastSchemaSpaceUsed = PreviousSchemaSize;
- return EFI_SUCCESS;
- } // SaveBssaResultsToBdat
- /**
- Save EWL results to BDAT
- @param[in,out] BdatHeaderStructPtr - Pointer to BDAT Structure
- @param[in] OffsetFromLastSchema- Offset (in bytes) from the last schema. Need it to update the schema offsets array.
- @param[in] SchemaStartAddress - Starting address where the EWL schema will be added
- @param[in, out] SchemaIndex - Current schema index inside the BDAT. Need it to update the schema offsets array.
- @param[out] SchemaSpaceUsed - The numebr bytes were filled
- @retval EFI_SUCCESS - EWL BDAT scehma created successfully
- @retval !EFI_SUCCESS - EWL BDAT scehma creation failed
- **/
- EFI_STATUS
- SaveEwlToBdat (
- IN OUT BDAT_STRUCTURE *BdatHeaderStructPtr,
- IN UINT32 OffsetFromLastSchema,
- IN EFI_PHYSICAL_ADDRESS *SchemaStartAddress,
- IN OUT UINT8 *SchemaIndex,
- OUT UINT32 *SchemaSpaceUsed
- )
- {
- EFI_STATUS Status = EFI_SUCCESS;
- UINT32 *SchemaAddrLocationArray = NULL;
- EFI_HOB_GUID_TYPE *GuidHob = NULL;
- EFI_PHYSICAL_ADDRESS Address = 0;
- EWL_PRIVATE_DATA *EwlPrivateData = NULL;
- EFI_GUID EWLDataGuid = EWL_ID_GUID;
- BDAT_SCHEMA_HEADER_STRUCTURE *EwlSchemaHeaderPtr = NULL;
- UINT32 EwlSize = 0;
- if ((BdatHeaderStructPtr == NULL) || (SchemaStartAddress == NULL) || (SchemaIndex == NULL) || (SchemaSpaceUsed == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- Address = *SchemaStartAddress;
- *SchemaSpaceUsed = 0;
- DEBUG ((DEBUG_VERBOSE, "\nStarting to copy EWL schema at Address = 0x%x\n", Address));
- //
- // Update the schema offset arrary
- //
- SchemaAddrLocationArray = (UINT32 *)((EFI_PHYSICAL_ADDRESS)BdatHeaderStructPtr + sizeof(BDAT_STRUCTURE));
- if (*SchemaIndex < BdatHeaderStructPtr->BdatSchemas.SchemaListLength) {
- if (*SchemaIndex == 0) {
- SchemaAddrLocationArray[*SchemaIndex] = OffsetFromLastSchema;
- }
- else {
- SchemaAddrLocationArray[*SchemaIndex] = SchemaAddrLocationArray[*SchemaIndex - 1] + OffsetFromLastSchema;
- }
- }
- EwlSchemaHeaderPtr = (BDAT_SCHEMA_HEADER_STRUCTURE *)Address;
- EwlSchemaHeaderPtr->SchemaId = gEwlBdatSchemaGuid;
- *SchemaSpaceUsed = *SchemaSpaceUsed + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
- //
- // CRC16 value of the BDAT_SCHEMA_HEADER_STRUCTURE
- //
- EwlSchemaHeaderPtr->Crc16 = 0;
- Status = CalculateCrc16 (
- (VOID *)EwlSchemaHeaderPtr,
- sizeof(BDAT_SCHEMA_HEADER_STRUCTURE),
- &EwlSchemaHeaderPtr->Crc16
- );
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR (Status)) {
- EwlSchemaHeaderPtr->Crc16 = 0xFFFF;
- }
- GuidHob = GetFirstGuidHob (&EWLDataGuid);
- EwlPrivateData = GET_GUID_HOB_DATA (GuidHob);
- EwlSize = EwlPrivateData->status.Header.Size;
- EwlSchemaHeaderPtr->DataSize = EwlSize + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
- //
- // Copy EWL HOB to RT Memory
- //
- Address = Address + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
- CopyMem ((VOID *)Address, (VOID *)&(EwlPrivateData->status), EwlSize);
- *SchemaSpaceUsed = *SchemaSpaceUsed + EwlSize;
- *SchemaIndex = *SchemaIndex + 1;
- return EFI_SUCCESS;
- } //SaveEwlToBdat
- /**
- Check if current boot is slow boot or not
- @retval TRUE - Slow boot path
- @retval FALSE - not slow boot path
- **/
- BOOLEAN
- IsSlowBoot (
- VOID
- )
- {
- EFI_STATUS Status = EFI_SUCCESS;
- DYNAMIC_SI_LIBARY_PROTOCOL2 *DynamicSiLibraryProtocol2 = NULL;
- Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocol2Guid, NULL, (VOID **) &DynamicSiLibraryProtocol2);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return TRUE;
- }
- return DynamicSiLibraryProtocol2->IsSlowBoot ();
- } // IsSlowBoot
- /**
- Save SPD date structure to BDAT
- @param[in,out] BdatHeaderStructPtr - Pointer to BDAT Structure
- @param[in] OffsetFromLastSchema- Offset (in bytes) from the last schema. Need it to update the schema offsets array.
- @param[in] SchemaStartAddress - Starting address where the SPD data schema will be added
- @param[in, out] SchemaIndex - Current schema index inside the BDAT. Need it to update the schema offsets array.
- @param[out] SchemaSpaceUsed - The numebr bytes were filled
- @retval EFI_SUCCESS - SPD BDAT scehma created successfully
- @retval !EFI_SUCCESS - SPD BDAT scehma creation failed
- **/
- EFI_STATUS
- SaveSpdToBdat (
- IN OUT BDAT_STRUCTURE *BdatHeaderStructPtr,
- IN UINT32 OffsetFromLastSchema,
- IN EFI_PHYSICAL_ADDRESS *SchemaStartAddress,
- IN OUT UINT8 *SchemaIndex,
- OUT UINT32 *SchemaSpaceUsed
- )
- {
- EFI_STATUS Status = EFI_SUCCESS;
- UINT32 *SchemaAddrLocationArray = NULL;
- UINT32 SpdDataSize = 0;
- EFI_PHYSICAL_ADDRESS Address = 0;
- BDAT_SCHEMA_HEADER_STRUCTURE *SpdSchemaHeaderPtr = NULL;
- // UINT16 *SpdVariableName = L"SpdData";
- VOID *VariableData = NULL;
- BOOLEAN SaveToVariable = TRUE;
- UINTN CompareValue;
- if ((BdatHeaderStructPtr == NULL) || (SchemaStartAddress == NULL) || (SchemaIndex == NULL) || (SchemaSpaceUsed == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- Address = *SchemaStartAddress;
- *SchemaSpaceUsed = 0;
- //
- // Add SPD schema
- //
- DEBUG ((DEBUG_VERBOSE, "\nStarting to add SPD schema at Address = 0x%x\n", Address));
- //
- // Update the schema offset arrary
- //
- SchemaAddrLocationArray = (UINT32 *)((EFI_PHYSICAL_ADDRESS)BdatHeaderStructPtr + sizeof(BDAT_STRUCTURE));
- if (*SchemaIndex < BdatHeaderStructPtr->BdatSchemas.SchemaListLength) {
- if (*SchemaIndex == 0) {
- SchemaAddrLocationArray[*SchemaIndex] = OffsetFromLastSchema;
- }
- else {
- SchemaAddrLocationArray[*SchemaIndex] = SchemaAddrLocationArray[*SchemaIndex - 1] + OffsetFromLastSchema;
- }
- }
- SpdSchemaHeaderPtr = (BDAT_SCHEMA_HEADER_STRUCTURE *)Address;
- SpdSchemaHeaderPtr->SchemaId = gSpdBdatSchemaGuid;
- //
- // CRC16 value of the BDAT_SCHEMA_HEADER_STRUCTURE
- //
- SpdSchemaHeaderPtr->Crc16 = 0;
- Status = CalculateCrc16 (
- (VOID *)SpdSchemaHeaderPtr,
- sizeof(BDAT_SCHEMA_HEADER_STRUCTURE),
- &SpdSchemaHeaderPtr->Crc16
- );
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR (Status)) {
- SpdSchemaHeaderPtr->Crc16 = 0xFFFF;
- }
- Address = Address + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
- *SchemaSpaceUsed = *SchemaSpaceUsed + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
- SpdDataSize = GetSpdDataSize ();
- if (IsSlowBoot ()) {
- //
- // Read SPD via Smbus, fill up the SPD data structure.
- //
- FillSpdSchema (Address, SpdDataSize);
- //
- // Save the SPD data structure to EFI variables to save fast boot time
- //
- // Before save variable, read and comapre to current data. If they are the same, then
- // don't save it.
- // If fail to read the variable(the variable doesn't exist), save variable.
- //
- SaveToVariable = TRUE;
- VariableData = AllocatePool (SpdDataSize);
- if (VariableData == NULL) {
- DEBUG ((DEBUG_ERROR, "Not able to allocate space to store SPD variable data.\n"));
- Status = EFI_OUT_OF_RESOURCES;
- goto End;
- }
- // Status = LoadCompressedVariable (SpdVariableName, gSpdVariableGuid, VariableData, SpdDataSize);
- if (!EFI_ERROR (Status)) {
- CompareValue = CompareMem ((VOID *)Address, VariableData, SpdDataSize);
- if (CompareValue == 0) {
- SaveToVariable = FALSE;
- DEBUG ((DEBUG_VERBOSE, "No change to the SPD data, don't save variable.\n"));
- }
- }
- if (SaveToVariable) {
- // Status = CompressAndSaveToVariable (SpdVariableName, gSpdVariableGuid, (VOID *)Address, SpdDataSize);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Failed to save SPD data to variable.\n"));
- goto End;
- }
- DEBUG ((DEBUG_VERBOSE, "Save SPD data to EFI variable.\n"));
- }
- } else {
- //
- // Fast boot, read the SPD data from vaiable
- //
- // Status = LoadCompressedVariable (SpdVariableName, gSpdVariableGuid, (VOID *)Address, SpdDataSize);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Failed to load SPD data from variable.\n"));
- goto End;
- }
- DEBUG ((DEBUG_VERBOSE, "Fill with SPD data from EFI variable.\n"));
- }
- End:
- if (VariableData != NULL) {
- FreePool (VariableData);
- }
- SpdSchemaHeaderPtr->DataSize = SpdDataSize + sizeof (BDAT_SCHEMA_HEADER_STRUCTURE);
- *SchemaSpaceUsed = *SchemaSpaceUsed + SpdDataSize;
- *SchemaIndex = *SchemaIndex + 1;
- return Status;
- } //SaveSpdToBdat
- /**
- Save memory training date structure to BDAT
- @param[in,out] BdatHeaderStructPtr - Pointer to BDAT Structure
- @param[in] OffsetFromLastSchema- Offset (in bytes) from the last schema. Need it to update the schema offsets array.
- @param[in] SchemaStartAddress - Starting address where the memory training data schema will be added
- @param[in, out] SchemaIndex - Current schema index inside the BDAT. Need it to update the schema offsets array.
- @param[out] SchemaSpaceUsed - The numebr bytes were filled
- @retval EFI_SUCCESS - Memory training data BDAT scehma created successfully
- @retval !EFI_SUCCESS - Memory training data BDAT scehma creation failed
- **/
- EFI_STATUS
- SaveTrainingDataToBdat (
- IN OUT BDAT_STRUCTURE *BdatHeaderStructPtr,
- IN UINT32 OffsetFromLastSchema,
- IN EFI_PHYSICAL_ADDRESS *SchemaStartAddress,
- IN OUT UINT8 *SchemaIndex,
- OUT UINT32 *SchemaSpaceUsed
- )
- {
- EFI_STATUS Status = EFI_SUCCESS;
- UINT32 *SchemaAddrLocationArray = NULL;
- EFI_HOB_GUID_TYPE *GuidHob = NULL;
- EFI_PHYSICAL_ADDRESS Address = 0;
- MEM_TRAINING_DATA_HEADER *TrainingDataHeader = NULL;
- MEM_TRAINING_DATA_HOB_HEADER *TrainingDataHobHeader = NULL;
- EFI_GUID TrainingDataGuid = gMemTrainingDataHobGuid;
- BDAT_SCHEMA_HEADER_STRUCTURE *SchemaHeaderPtr = NULL;
- INT32 RemainingDataSize = 0;
- UINT32 HobSize = 0;
- UINT32 TrainingDataSize = 0;
- UINT8 HobIndex = 0;
- if ((BdatHeaderStructPtr == NULL) || (SchemaStartAddress == NULL) || (SchemaIndex == NULL) || (SchemaSpaceUsed == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
- Address = *SchemaStartAddress;
- *SchemaSpaceUsed = 0;
- DEBUG ((DEBUG_VERBOSE, "\nStarting to copy memory training data schema at Address = 0x%x\n", Address));
- //
- // Update the schema offset arrary
- //
- SchemaAddrLocationArray = (UINT32 *)((EFI_PHYSICAL_ADDRESS)BdatHeaderStructPtr + sizeof(BDAT_STRUCTURE));
- if (*SchemaIndex < BdatHeaderStructPtr->BdatSchemas.SchemaListLength) {
- if (*SchemaIndex == 0) {
- SchemaAddrLocationArray[*SchemaIndex] = OffsetFromLastSchema;
- }
- else {
- SchemaAddrLocationArray[*SchemaIndex] = SchemaAddrLocationArray[*SchemaIndex - 1] + OffsetFromLastSchema;
- }
- }
- SchemaHeaderPtr = (BDAT_SCHEMA_HEADER_STRUCTURE *)Address;
- SchemaHeaderPtr->SchemaId = gMemTrainingDataBdatSchemaGuid;
- *SchemaSpaceUsed = *SchemaSpaceUsed + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
- //
- // CRC16 value of the BDAT_SCHEMA_HEADER_STRUCTURE
- //
- SchemaHeaderPtr->Crc16 = 0;
- Status = CalculateCrc16 (
- (VOID *)SchemaHeaderPtr,
- sizeof(BDAT_SCHEMA_HEADER_STRUCTURE),
- &SchemaHeaderPtr->Crc16
- );
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR (Status)) {
- SchemaHeaderPtr->Crc16 = 0xFFFF;
- }
- GuidHob = GetFirstGuidHob (&TrainingDataGuid);
- ASSERT (GuidHob != NULL);
- if (GuidHob == NULL) {
- DEBUG ((DEBUG_ERROR, "Not found training data HOB with GUID:%g\n", &TrainingDataGuid));
- return EFI_NOT_FOUND;
- }
- TrainingDataHobHeader = GET_GUID_HOB_DATA (GuidHob);
- TrainingDataSize = TrainingDataHobHeader->Size - sizeof (MEM_TRAINING_DATA_HOB_HEADER); // This is the size of data to copy to the RT memory.
- TrainingDataHeader = (MEM_TRAINING_DATA_HEADER *)((EFI_PHYSICAL_ADDRESS)TrainingDataHobHeader + sizeof (MEM_TRAINING_DATA_HOB_HEADER));
- HobSize = GET_GUID_HOB_DATA_SIZE (GuidHob);
- ASSERT (TrainingDataSize <= HobSize);
- HobIndex += 1;
- DEBUG ((DEBUG_VERBOSE, "Memory training data structre size:%d\n", TrainingDataHeader->Size));
- SchemaHeaderPtr->DataSize = TrainingDataHeader->Size + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
- //
- // This is the total data size in the training data structure.
- //
- RemainingDataSize = (INT32) TrainingDataHeader->Size;
- DEBUG ((DEBUG_VERBOSE, "Remaining training data:%d\n", RemainingDataSize));
- //
- // Copy training data HOBs to RT Memory
- //
- Address = Address + sizeof(BDAT_SCHEMA_HEADER_STRUCTURE);
- CopyMem ((VOID *)Address, (VOID *)TrainingDataHeader, TrainingDataSize);
- *SchemaSpaceUsed = *SchemaSpaceUsed + TrainingDataSize;
- Address = Address + TrainingDataSize;
- RemainingDataSize -= TrainingDataSize;
- while (RemainingDataSize > 0) {
- GuidHob = GET_NEXT_HOB (GuidHob); // Increment to next HOB
- GuidHob = GetNextGuidHob (&TrainingDataGuid, GuidHob); // Now search for next instance of the BDAT HOB
- ASSERT (GuidHob != NULL);
- if (GuidHob == NULL) {
- DEBUG ((DEBUG_ERROR, "Not found training data HOB with GUID:%g\n", &TrainingDataGuid));
- return EFI_NOT_FOUND;
- }
- TrainingDataHobHeader = GET_GUID_HOB_DATA (GuidHob);
- TrainingDataSize = TrainingDataHobHeader->Size - sizeof (MEM_TRAINING_DATA_HOB_HEADER); // This is the size of data to copy to the RT memory.
- HobSize = GET_GUID_HOB_DATA_SIZE (GuidHob);
- ASSERT (TrainingDataSize <= HobSize);
- HobIndex += 1;
- //
- // Copy training data HOBs to RT Memory
- //
- CopyMem ((VOID *)Address, (VOID *)((EFI_PHYSICAL_ADDRESS)TrainingDataHobHeader + sizeof (MEM_TRAINING_DATA_HOB_HEADER)), TrainingDataSize);
- *SchemaSpaceUsed = *SchemaSpaceUsed + TrainingDataSize;
- Address = Address + TrainingDataSize;
- RemainingDataSize -= TrainingDataSize;
- DEBUG ((DEBUG_VERBOSE, "Remaining training data:%d after copying Hob:%d \n", RemainingDataSize, HobIndex));
- }
- //
- // Update training data header structure CRC, after all the training data were copied from HOBs to a RT contiguous memory region.
- //
- TrainingDataHeader->Crc = 0;
- TrainingDataHeader->Crc = CalculateCrc32 ((VOID *) TrainingDataHeader, TrainingDataHeader->Size);
- *SchemaIndex = *SchemaIndex + 1;
- return EFI_SUCCESS;
- } //SaveTrainingDataToBdat
|