/** The function builds the PCD database. @param FileHandle Handle of the file the external PCD database binary located. @return Pointer to PCD database. **/ PEI_PCD_DATABASE * BuildPcdDatabase ( IN EFI_PEI_FILE_HANDLE FileHandle ) { PEI_PCD_DATABASE *Database; PEI_PCD_DATABASE *PeiPcdDbBinary; VOID *CallbackFnTable; UINTN SizeOfCallbackFnTable; // // Locate the external PCD database binary for one section of current FFS // PeiPcdDbBinary = LocateExPcdBinary (FileHandle); ASSERT(PeiPcdDbBinary != NULL); Database = BuildGuidHob (&gPcdDataBaseHobGuid, PeiPcdDbBinary->Length + PeiPcdDbBinary->UninitDataBaseSize); ZeroMem (Database, PeiPcdDbBinary->Length + PeiPcdDbBinary->UninitDataBaseSize); // // PeiPcdDbBinary is smaller than Database // CopyMem (Database, PeiPcdDbBinary, PeiPcdDbBinary->Length); SizeOfCallbackFnTable = Database->LocalTokenCount * sizeof (PCD_PPI_CALLBACK) * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry); CallbackFnTable = BuildGuidHob (&gEfiCallerIdGuid, SizeOfCallbackFnTable); ZeroMem (CallbackFnTable, SizeOfCallbackFnTable); return Database; }
/** The function builds the PCD database. **/ VOID BuildPcdDatabase ( VOID ) { PEI_PCD_DATABASE *Database; VOID *CallbackFnTable; UINTN SizeOfCallbackFnTable; Database = BuildGuidHob (&gPcdDataBaseHobGuid, sizeof (PEI_PCD_DATABASE)); ZeroMem (Database, sizeof (PEI_PCD_DATABASE)); // // gPEIPcdDbInit is smaller than PEI_PCD_DATABASE // CopyMem (&Database->Init, &gPEIPcdDbInit, sizeof (gPEIPcdDbInit)); SizeOfCallbackFnTable = PEI_LOCAL_TOKEN_NUMBER * sizeof (PCD_PPI_CALLBACK) * PcdGet32 (PcdMaxPeiPcdCallBackNumberPerPcdEntry); CallbackFnTable = BuildGuidHob (&gEfiCallerIdGuid, SizeOfCallbackFnTable); ZeroMem (CallbackFnTable, SizeOfCallbackFnTable); }
/** Create the first memory status code GUID'ed HOB as initialization for memory status code worker. @retval EFI_SUCCESS The GUID'ed HOB is created successfully. **/ EFI_STATUS MemoryStatusCodeInitializeWorker ( VOID ) { // // Create memory status code GUID'ed HOB. // MEMORY_STATUSCODE_PACKET_HEADER *PacketHeader; // // Build GUID'ed HOB with PCD defined size. // PacketHeader = BuildGuidHob ( &gMemoryStatusCodeRecordGuid, PcdGet16 (PcdStatusCodeMemorySize) * 1024 + sizeof (MEMORY_STATUSCODE_PACKET_HEADER) ); ASSERT (PacketHeader != NULL); PacketHeader->MaxRecordsNumber = (PcdGet16 (PcdStatusCodeMemorySize) * 1024) / sizeof (MEMORY_STATUSCODE_RECORD); PacketHeader->PacketIndex = 0; PacketHeader->RecordIndex = 0; return EFI_SUCCESS; }
/** Gets PEI the GUID HOB for PEI performance. This internal function searches for the GUID HOB for PEI performance. If that GUID HOB is not found, it will build a new one. It returns the data area of that GUID HOB to record performance log. @param Handle Pointer to environment specific context used to identify the component being measured. @param Token Pointer to a Null-terminated ASCII string that identifies the component being measured. @param Module Pointer to a Null-terminated ASCII string that identifies the module being measured. @retval The index of log entry in the array. **/ PEI_PERFORMANCE_LOG_HEADER * InternalGetPerformanceHobLog ( VOID ) { EFI_HOB_GUID_TYPE *GuidHob; PEI_PERFORMANCE_LOG_HEADER *PeiPerformanceLog; UINTN PeiPerformanceLogSize; GuidHob = GetFirstGuidHob (&gPerformanceProtocolGuid); if (GuidHob != NULL) { // // PEI Performance HOB was found, then return the existing one. // PeiPerformanceLog = GET_GUID_HOB_DATA (GuidHob); } else { // // PEI Performance HOB was not found, then build one. // PeiPerformanceLogSize = sizeof (PEI_PERFORMANCE_LOG_HEADER) + sizeof (PEI_PERFORMANCE_LOG_ENTRY) * PcdGet8 (PcdMaxPeiPerformanceLogEntries); PeiPerformanceLog = BuildGuidHob (&gPerformanceProtocolGuid, PeiPerformanceLogSize); PeiPerformanceLog = ZeroMem (PeiPerformanceLog, PeiPerformanceLogSize); } return PeiPerformanceLog; }
EFI_STATUS PlatformHobCreateFromFsp ( IN CONST EFI_PEI_SERVICES **PeiServices, VOID *HobList ) { VOID *HobData; VOID *NewHobData; UINTN DataSize; // // Other hob, todo: put this into FspWrapPlatformLib // if ((HobList = GetNextGuidHob (&gEfiMemoryConfigDataGuid, HobList)) != NULL) { HobData = GET_GUID_HOB_DATA (HobList); DataSize = GET_GUID_HOB_DATA_SIZE(HobList); DEBUG((EFI_D_ERROR, "gEfiMemoryConfigDataGuid Hob found: 0x%x.\n", DataSize)); NewHobData = BuildGuidHob (&gEfiMemoryConfigDataGuid, DataSize); (*PeiServices)->CopyMem ( NewHobData, HobData, DataSize ); } return EFI_SUCCESS; }
/** Gets the GUID HOB for PEI performance. This internal function searches for the GUID HOB for PEI performance. If that GUID HOB is not found, it will build a new one. It outputs the data area of that GUID HOB to record performance log. @param PeiPerformanceLog Pointer to Pointer to PEI performance log header. @param PeiPerformanceIdArray Pointer to Pointer to PEI performance identifier array. **/ VOID InternalGetPerformanceHobLog ( OUT PEI_PERFORMANCE_LOG_HEADER **PeiPerformanceLog, OUT UINT32 **PeiPerformanceIdArray ) { EFI_HOB_GUID_TYPE *GuidHob; UINTN PeiPerformanceSize; UINT16 PeiPerformanceLogEntries; ASSERT (PeiPerformanceLog != NULL); ASSERT (PeiPerformanceIdArray != NULL); PeiPerformanceLogEntries = (UINT16) (PcdGet16 (PcdMaxPeiPerformanceLogEntries16) != 0 ? PcdGet16 (PcdMaxPeiPerformanceLogEntries16) : PcdGet8 (PcdMaxPeiPerformanceLogEntries)); GuidHob = GetFirstGuidHob (&gPerformanceProtocolGuid); if (GuidHob != NULL) { // // PEI Performance HOB was found, then return the existing one. // *PeiPerformanceLog = GET_GUID_HOB_DATA (GuidHob); GuidHob = GetFirstGuidHob (&gPerformanceExProtocolGuid); ASSERT (GuidHob != NULL); *PeiPerformanceIdArray = GET_GUID_HOB_DATA (GuidHob); } else { // // PEI Performance HOB was not found, then build one. // PeiPerformanceSize = sizeof (PEI_PERFORMANCE_LOG_HEADER) + sizeof (PEI_PERFORMANCE_LOG_ENTRY) * PeiPerformanceLogEntries; *PeiPerformanceLog = BuildGuidHob (&gPerformanceProtocolGuid, PeiPerformanceSize); *PeiPerformanceLog = ZeroMem (*PeiPerformanceLog, PeiPerformanceSize); PeiPerformanceSize = sizeof (UINT32) * PeiPerformanceLogEntries; *PeiPerformanceIdArray = BuildGuidHob (&gPerformanceExProtocolGuid, PeiPerformanceSize); *PeiPerformanceIdArray = ZeroMem (*PeiPerformanceIdArray, PeiPerformanceSize); } }
/** Parse DMAR DRHD table. @param[in] AcpiDmarTable DMAR ACPI table @return EFI_SUCCESS The DMAR DRHD table is parsed. **/ EFI_STATUS ParseDmarAcpiTableDrhd ( IN EFI_ACPI_DMAR_HEADER *AcpiDmarTable ) { EFI_ACPI_DMAR_STRUCTURE_HEADER *DmarHeader; UINTN VtdUnitNumber; UINTN VtdIndex; VTD_INFO *VTdInfo; VtdUnitNumber = GetVtdEngineNumber (AcpiDmarTable); if (VtdUnitNumber == 0) { return EFI_UNSUPPORTED; } VTdInfo = BuildGuidHob (&mVTdInfoGuid, sizeof(VTD_INFO) + (VtdUnitNumber - 1) * sizeof(UINT64)); ASSERT(VTdInfo != NULL); if (VTdInfo == NULL) { return EFI_OUT_OF_RESOURCES; } // // Initialize the engine mask to all. // VTdInfo->AcpiDmarTable = AcpiDmarTable; VTdInfo->EngineMask = LShiftU64 (1, VtdUnitNumber) - 1; VTdInfo->HostAddressWidth = AcpiDmarTable->HostAddressWidth; VTdInfo->VTdEngineCount = VtdUnitNumber; VtdIndex = 0; DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)(AcpiDmarTable + 1)); while ((UINTN)DmarHeader < (UINTN)AcpiDmarTable + AcpiDmarTable->Header.Length) { switch (DmarHeader->Type) { case EFI_ACPI_DMAR_TYPE_DRHD: ASSERT (VtdIndex < VtdUnitNumber); ProcessDhrd (VTdInfo, VtdIndex, (EFI_ACPI_DMAR_DRHD_HEADER *)DmarHeader); VtdIndex++; break; default: break; } DmarHeader = (EFI_ACPI_DMAR_STRUCTURE_HEADER *)((UINTN)DmarHeader + DmarHeader->Length); } ASSERT (VtdIndex == VtdUnitNumber); return EFI_SUCCESS; }
EFIAPI BuildGuidDataHob ( IN CONST EFI_GUID *Guid, IN VOID *Data, IN UINTN DataLength ) { VOID *HobData; ASSERT (Data != NULL || DataLength == 0); HobData = BuildGuidHob (Guid, DataLength); return CopyMem (HobData, Data, DataLength); }
/** Set SMM communication context. @param SmmCommunicationContext SMM communication context. **/ VOID SetCommunicationContext ( IN EFI_SMM_COMMUNICATION_CONTEXT *SmmCommunicationContext ) { EFI_PEI_HOB_POINTERS Hob; UINTN BufferSize; BufferSize = sizeof (*SmmCommunicationContext); Hob.Raw = BuildGuidHob ( &gEfiPeiSmmCommunicationPpiGuid, BufferSize ); ASSERT (Hob.Raw); CopyMem ((VOID *)Hob.Raw, SmmCommunicationContext, sizeof(*SmmCommunicationContext)); }
/** Get variable header that has consecutive content. @param StoreInfo Pointer to variable store info structure. @param Variable Pointer to the Variable Header. @param VariableHeader Pointer to Pointer to the Variable Header that has consecutive content. @retval TRUE Variable header is valid. @retval FALSE Variable header is not valid. **/ BOOLEAN GetVariableHeader ( IN VARIABLE_STORE_INFO *StoreInfo, IN VARIABLE_HEADER *Variable, OUT VARIABLE_HEADER **VariableHeader ) { EFI_PHYSICAL_ADDRESS TargetAddress; EFI_PHYSICAL_ADDRESS SpareAddress; EFI_HOB_GUID_TYPE *GuidHob; UINTN PartialHeaderSize; // // First assume variable header pointed by Variable is consecutive. // *VariableHeader = Variable; if ((Variable != NULL) && (StoreInfo->FtwLastWriteData != NULL)) { TargetAddress = StoreInfo->FtwLastWriteData->TargetAddress; SpareAddress = StoreInfo->FtwLastWriteData->SpareAddress; if (((UINTN) Variable < (UINTN) TargetAddress) && (((UINTN) Variable + sizeof (VARIABLE_HEADER)) > (UINTN) TargetAddress)) { // // Variable header pointed by Variable is inconsecutive, // create a guid hob to combine the two partial variable header content together. // GuidHob = GetFirstGuidHob (&gEfiCallerIdGuid); if (GuidHob != NULL) { *VariableHeader = (VARIABLE_HEADER *) GET_GUID_HOB_DATA (GuidHob); } else { *VariableHeader = (VARIABLE_HEADER *) BuildGuidHob (&gEfiCallerIdGuid, sizeof (VARIABLE_HEADER)); PartialHeaderSize = (UINTN) TargetAddress - (UINTN) Variable; // // Partial content is in NV storage. // CopyMem ((UINT8 *) *VariableHeader, (UINT8 *) Variable, PartialHeaderSize); // // Another partial content is in spare block. // CopyMem ((UINT8 *) *VariableHeader + PartialHeaderSize, (UINT8 *) (UINTN) SpareAddress, sizeof (VARIABLE_HEADER) - PartialHeaderSize); } } } return IsValidVariableHeader (*VariableHeader); }
/** Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result, and build a GUIDed HOB recording the event which will be passed to the DXE phase and added into the Event Log. @param[in] PeiServices Describes the list of possible PEI Services. @param[in] HashData Physical address of the start of the data buffer to be hashed, extended, and logged. @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData. @param[in] TpmHandle TPM handle. @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. @param[in] NewEventData Pointer to the new event data. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. @retval EFI_DEVICE_ERROR The command was unsuccessful. **/ EFI_STATUS HashLogExtendEvent ( IN EFI_PEI_SERVICES **PeiServices, IN UINT8 *HashData, IN UINTN HashDataLen, IN TIS_TPM_HANDLE TpmHandle, IN TCG_PCR_EVENT_HDR *NewEventHdr, IN UINT8 *NewEventData ) { EFI_STATUS Status; VOID *HobData; HobData = NULL; if (HashDataLen != 0) { Status = TpmCommHashAll ( HashData, HashDataLen, &NewEventHdr->Digest ); ASSERT_EFI_ERROR (Status); } Status = TpmCommExtend ( PeiServices, TpmHandle, &NewEventHdr->Digest, NewEventHdr->PCRIndex, NULL ); ASSERT_EFI_ERROR (Status); HobData = BuildGuidHob ( &gTcgEventEntryHobGuid, sizeof (*NewEventHdr) + NewEventHdr->EventSize ); if (HobData == NULL) { return EFI_OUT_OF_RESOURCES; } CopyMem (HobData, NewEventHdr, sizeof (*NewEventHdr)); HobData = (VOID *) ((UINT8*)HobData + sizeof (*NewEventHdr)); CopyMem (HobData, NewEventData, NewEventHdr->EventSize); return EFI_SUCCESS; }
/** Initializes the Intel VTd PMR PEIM. @param FileHandle Handle of the file being invoked. @param PeiServices Describes the list of possible PEI Services. @retval EFI_SUCCESS Usb bot driver is successfully initialized. @retval EFI_OUT_OF_RESOURCES Can't initialize the driver. **/ EFI_STATUS EFIAPI IntelVTdPmrInitialize ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; EFI_BOOT_MODE BootMode; DMA_BUFFER_INFO *DmaBufferInfo; DEBUG ((DEBUG_INFO, "IntelVTdPmrInitialize\n")); if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT0) == 0) { return EFI_UNSUPPORTED; } DmaBufferInfo = BuildGuidHob (&mDmaBufferInfoGuid, sizeof(DMA_BUFFER_INFO)); ASSERT(DmaBufferInfo != NULL); if (DmaBufferInfo == NULL) { return EFI_OUT_OF_RESOURCES; } ZeroMem (DmaBufferInfo, sizeof(DMA_BUFFER_INFO)); PeiServicesGetBootMode (&BootMode); if (BootMode == BOOT_ON_S3_RESUME) { DmaBufferInfo->DmaBufferSize = PcdGet32 (PcdVTdPeiDmaBufferSizeS3); } else { DmaBufferInfo->DmaBufferSize = PcdGet32 (PcdVTdPeiDmaBufferSize); } Status = PeiServicesNotifyPpi (&mVTdInfoNotifyDesc); ASSERT_EFI_ERROR (Status); // // Register EndOfPei Notify for S3 // if (BootMode == BOOT_ON_S3_RESUME) { Status = PeiServicesNotifyPpi (&mS3EndOfPeiNotifyDesc); ASSERT_EFI_ERROR (Status); } return EFI_SUCCESS; }
/** Record all measured Firmware Volum Information into a Guid Hob Guid Hob payload layout is UINT32 *************************** FIRMWARE_BLOB number EFI_PLATFORM_FIRMWARE_BLOB******** BLOB Array @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. @param[in] NotifyDescriptor Address of the notification descriptor data structure. @param[in] Ppi Address of the PPI that was installed. @retval EFI_SUCCESS The FV Info is measured and recorded to TPM. @return Others Fail to measure FV. **/ EFI_STATUS EFIAPI EndofPeiSignalNotifyCallBack ( IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, IN VOID *Ppi ) { MEASURED_HOB_DATA *MeasuredHobData; MeasuredHobData = NULL; PERF_CALLBACK_BEGIN (&gEfiEndOfPeiSignalPpiGuid); // // Create a Guid hob to save all measured Fv // MeasuredHobData = BuildGuidHob( &gMeasuredFvHobGuid, sizeof(UINTN) + sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex + mMeasuredChildFvIndex) ); if (MeasuredHobData != NULL){ // // Save measured FV info enty number // MeasuredHobData->Num = mMeasuredBaseFvIndex + mMeasuredChildFvIndex; // // Save measured base Fv info // CopyMem (MeasuredHobData->MeasuredFvBuf, mMeasuredBaseFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredBaseFvIndex)); // // Save measured child Fv info // CopyMem (&MeasuredHobData->MeasuredFvBuf[mMeasuredBaseFvIndex] , mMeasuredChildFvInfo, sizeof(EFI_PLATFORM_FIRMWARE_BLOB) * (mMeasuredChildFvIndex)); } PERF_CALLBACK_END (&gEfiEndOfPeiSignalPpiGuid); return EFI_SUCCESS; }
/** Worker function to create one memory status code GUID'ed HOB, using PacketIndex to identify the packet. @param PacketIndex Index of records packet. @return Pointer to the memory status code packet. **/ UINTN * CreateRscHandlerCallbackPacket ( VOID ) { UINTN *NumberOfEntries; // // Build GUID'ed HOB with PCD defined size. // NumberOfEntries = BuildGuidHob ( &gStatusCodeCallbackGuid, sizeof (EFI_PEI_RSC_HANDLER_CALLBACK) * 64 + sizeof (UINTN) ); ASSERT (NumberOfEntries != NULL); *NumberOfEntries = 0; return NumberOfEntries; }
/** Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result, and build a GUIDed HOB recording the event which will be passed to the DXE phase and added into the Event Log. @param[in] Flags Bitmap providing additional information. @param[in] HashData Physical address of the start of the data buffer to be hashed, extended, and logged. @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData. @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. @param[in] NewEventData Pointer to the new event data. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. @retval EFI_DEVICE_ERROR The command was unsuccessful. **/ EFI_STATUS HashLogExtendEvent ( IN UINT64 Flags, IN UINT8 *HashData, IN UINTN HashDataLen, IN TCG_PCR_EVENT_HDR *NewEventHdr, IN UINT8 *NewEventData ) { EFI_STATUS Status; TPML_DIGEST_VALUES DigestList; if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) { return EFI_DEVICE_ERROR; } Status = HashAndExtend ( NewEventHdr->PCRIndex, HashData, HashDataLen, &DigestList ); if (!EFI_ERROR (Status)) { if ((Flags & EFI_TCG2_EXTEND_ONLY) == 0) { Status = LogHashEvent (&DigestList, NewEventHdr, NewEventData); } } if (Status == EFI_DEVICE_ERROR) { DEBUG ((EFI_D_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n", Status)); BuildGuidHob (&gTpmErrorHobGuid,0); REPORT_STATUS_CODE ( EFI_ERROR_CODE | EFI_ERROR_MINOR, (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR) ); } return Status; }
/** Add a new entry to the Event Log. @param[in] DigestList A list of digest. @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. @param[in] NewEventData Pointer to the new event data. @retval EFI_SUCCESS The new event log entry was added. @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. **/ EFI_STATUS LogHashEvent ( IN TPML_DIGEST_VALUES *DigestList, IN OUT TCG_PCR_EVENT_HDR *NewEventHdr, IN UINT8 *NewEventData ) { VOID *HobData; EFI_STATUS Status; UINTN Index; EFI_STATUS RetStatus; RetStatus = EFI_SUCCESS; for (Index = 0; Index < sizeof(mTreeEventInfo)/sizeof(mTreeEventInfo[0]); Index++) { DEBUG ((EFI_D_INFO, " LogFormat - 0x%08x\n", mTreeEventInfo[Index].LogFormat)); switch (mTreeEventInfo[Index].LogFormat) { case TREE_EVENT_LOG_FORMAT_TCG_1_2: Status = Tpm2GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest); if (!EFI_ERROR (Status)) { HobData = BuildGuidHob ( &gTcgEventEntryHobGuid, sizeof (*NewEventHdr) + NewEventHdr->EventSize ); if (HobData == NULL) { RetStatus = EFI_OUT_OF_RESOURCES; break; } CopyMem (HobData, NewEventHdr, sizeof (*NewEventHdr)); HobData = (VOID *) ((UINT8*)HobData + sizeof (*NewEventHdr)); CopyMem (HobData, NewEventData, NewEventHdr->EventSize); } break; } } return RetStatus; }
/** Convert PEI performance log to FPDT String boot record. @param IsStart TRUE if the performance log is start log. @param Handle Pointer to environment specific context used to identify the component being measured. @param Token Pointer to a Null-terminated ASCII string that identifies the component being measured. @param Module Pointer to a Null-terminated ASCII string that identifies the module being measured. @param Ticker 64-bit time stamp. @param Identifier 32-bit identifier. If the value is 0, the created record is same as the one created by StartGauge of PERFORMANCE_PROTOCOL. @retval EFI_SUCCESS Add FPDT boot record. @retval EFI_OUT_OF_RESOURCES There are not enough resources to record the measurement. @retval EFI_UNSUPPORTED No matched FPDT record. **/ EFI_STATUS InsertPeiFpdtMeasurement ( IN BOOLEAN IsStart, IN CONST VOID *Handle, OPTIONAL IN CONST CHAR8 *Token, OPTIONAL IN CONST CHAR8 *Module, OPTIONAL IN UINT64 Ticker, IN UINT32 Identifier ) { EFI_HOB_GUID_TYPE *GuidHob; UINTN PeiPerformanceSize; UINT8 *PeiFirmwarePerformance; FPDT_PEI_EXT_PERF_HEADER *PeiPerformanceLogHeader; FPDT_RECORD_PTR FpdtRecordPtr; FPDT_BASIC_RECORD_INFO RecordInfo; CONST VOID *ModuleGuid; UINTN DestMax; UINTN StrLength; CONST CHAR8 *StringPtr; EFI_STATUS Status; UINT16 PeiPerformanceLogEntries; UINT64 TimeStamp; StringPtr = NULL; FpdtRecordPtr.RecordHeader = NULL; PeiPerformanceLogHeader = NULL; // // Get record info (type, size, ProgressID and Module Guid). // Status = GetFpdtRecordInfo (IsStart, Handle, Token, Module, &RecordInfo); if (EFI_ERROR (Status)) { return Status; } // // If PERF_START()/PERF_END() have specified the ProgressID,it has high priority. // !!! Note: If the Perf is not the known Token used in the core but have same // ID with the core Token, this case will not be supported. // And in currtnt usage mode, for the unkown ID, there is a general rule: // If it is start pref: the lower 4 bits of the ID should be 0. // If it is end pref: the lower 4 bits of the ID should not be 0. // If input ID doesn't follow the rule, we will adjust it. // if ((Identifier != 0) && (IsKnownID (Identifier)) && (!IsKnownTokens (Token))) { return EFI_UNSUPPORTED; } else if ((Identifier != 0) && (!IsKnownID (Identifier)) && (!IsKnownTokens (Token))) { if (IsStart && ((Identifier & 0x000F) != 0)) { Identifier &= 0xFFF0; } else if ((!IsStart) && ((Identifier & 0x000F) == 0)) { Identifier += 1; } RecordInfo.ProgressID = (UINT16)Identifier; } // // Get the number of PeiPerformanceLogEntries form PCD. // PeiPerformanceLogEntries = (UINT16) (PcdGet16 (PcdMaxPeiPerformanceLogEntries16) != 0 ? PcdGet16 (PcdMaxPeiPerformanceLogEntries16) : PcdGet8 (PcdMaxPeiPerformanceLogEntries)); // // Create GUID HOB Data. // GuidHob = GetFirstGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid); PeiFirmwarePerformance = NULL; while (GuidHob != NULL) { // // PEI Performance HOB was found, then return the existing one. // PeiFirmwarePerformance = (UINT8*)GET_GUID_HOB_DATA (GuidHob); PeiPerformanceLogHeader = (FPDT_PEI_EXT_PERF_HEADER *)PeiFirmwarePerformance; if (!PeiPerformanceLogHeader->HobIsFull && PeiPerformanceLogHeader->SizeOfAllEntries + RecordInfo.RecordSize > PeiPerformanceLogEntries * MAX_RECORD_SIZE) { PeiPerformanceLogHeader->HobIsFull = TRUE; } if (!PeiPerformanceLogHeader->HobIsFull && PeiPerformanceLogHeader->SizeOfAllEntries + RecordInfo.RecordSize <= PeiPerformanceLogEntries * MAX_RECORD_SIZE) { FpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(PeiFirmwarePerformance + sizeof (FPDT_PEI_EXT_PERF_HEADER) + PeiPerformanceLogHeader->SizeOfAllEntries); break; } // // Previous HOB is used, then find next one. // GuidHob = GetNextGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, GET_NEXT_HOB (GuidHob)); } if (GuidHob == NULL) { // // PEI Performance HOB was not found, then build one. // PeiPerformanceSize = sizeof (FPDT_PEI_EXT_PERF_HEADER) + MAX_RECORD_SIZE * PeiPerformanceLogEntries; PeiFirmwarePerformance = (UINT8*)BuildGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, PeiPerformanceSize); if (PeiFirmwarePerformance != NULL) { ZeroMem (PeiFirmwarePerformance, PeiPerformanceSize); } PeiPerformanceLogHeader = (FPDT_PEI_EXT_PERF_HEADER *)PeiFirmwarePerformance; FpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(PeiFirmwarePerformance + sizeof (FPDT_PEI_EXT_PERF_HEADER)); } if (PeiFirmwarePerformance == NULL) { // // there is no enough resource to store performance data // return EFI_OUT_OF_RESOURCES; } // // Get the TimeStamp. // if (Ticker == 0) { Ticker = GetPerformanceCounter (); TimeStamp = GetTimeInNanoSecond (Ticker); } else if (Ticker == 1) { TimeStamp = 0; } else { TimeStamp = GetTimeInNanoSecond (Ticker); } // // Get the ModuleGuid. // if (Handle != NULL) { ModuleGuid = Handle; } else { ModuleGuid = &gEfiCallerIdGuid; } switch (RecordInfo.Type) { case FPDT_GUID_EVENT_TYPE: FpdtRecordPtr.GuidEvent->Header.Type = FPDT_GUID_EVENT_TYPE; FpdtRecordPtr.GuidEvent->Header.Length = RecordInfo.RecordSize;; FpdtRecordPtr.GuidEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.GuidEvent->ProgressID = RecordInfo.ProgressID; FpdtRecordPtr.GuidEvent->Timestamp = TimeStamp; CopyMem (&FpdtRecordPtr.GuidEvent->Guid, ModuleGuid, sizeof (EFI_GUID)); PeiPerformanceLogHeader->SizeOfAllEntries += RecordInfo.RecordSize; break; case FPDT_GUID_QWORD_EVENT_TYPE: FpdtRecordPtr.GuidQwordEvent->Header.Type = FPDT_GUID_QWORD_EVENT_TYPE; FpdtRecordPtr.GuidQwordEvent->Header.Length = RecordInfo.RecordSize;; FpdtRecordPtr.GuidQwordEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.GuidQwordEvent->ProgressID = RecordInfo.ProgressID; FpdtRecordPtr.GuidQwordEvent->Timestamp = TimeStamp; PeiPerformanceLogHeader->LoadImageCount++; FpdtRecordPtr.GuidQwordEvent->Qword = PeiPerformanceLogHeader->LoadImageCount; CopyMem (&FpdtRecordPtr.GuidQwordEvent->Guid, ModuleGuid, sizeof (EFI_GUID)); PeiPerformanceLogHeader->SizeOfAllEntries += RecordInfo.RecordSize; break; case FPDT_DYNAMIC_STRING_EVENT_TYPE: FpdtRecordPtr.DynamicStringEvent->Header.Type = FPDT_DYNAMIC_STRING_EVENT_TYPE; FpdtRecordPtr.DynamicStringEvent->Header.Length = RecordInfo.RecordSize; FpdtRecordPtr.DynamicStringEvent->Header.Revision = FPDT_RECORD_REVISION_1; FpdtRecordPtr.DynamicStringEvent->ProgressID = RecordInfo.ProgressID; FpdtRecordPtr.DynamicStringEvent->Timestamp = TimeStamp; CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, ModuleGuid, sizeof (EFI_GUID)); PeiPerformanceLogHeader->SizeOfAllEntries += RecordInfo.RecordSize; if (Token != NULL) { StringPtr = Token; } else if (Module != NULL) { StringPtr = Module; } if (StringPtr != NULL && AsciiStrLen (StringPtr) != 0) { DestMax = (RecordInfo.RecordSize - sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD)) / sizeof (CHAR8); StrLength = AsciiStrLen (StringPtr); if (StrLength >= DestMax) { StrLength = DestMax -1; } AsciiStrnCpyS (FpdtRecordPtr.DynamicStringEvent->String, DestMax, StringPtr, StrLength); } else { AsciiStrCpyS (FpdtRecordPtr.DynamicStringEvent->String, FPDT_STRING_EVENT_RECORD_NAME_LENGTH, "unknown name"); } break; default: // // Record is not supported in current PEI phase, return EFI_ABORTED // return EFI_UNSUPPORTED; } return EFI_SUCCESS; }
/** Entry point of this module. @param[in] FileHandle Handle of the file being invoked. @param[in] PeiServices Describes the list of possible PEI Services. @return Status. **/ EFI_STATUS EFIAPI PeimEntryMA ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; EFI_STATUS Status2; EFI_BOOT_MODE BootMode; if (!CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)){ DEBUG ((EFI_D_ERROR, "No TPM12 instance required!\n")); return EFI_UNSUPPORTED; } if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) { DEBUG ((EFI_D_ERROR, "TPM error!\n")); return EFI_DEVICE_ERROR; } // // Initialize TPM device // Status = PeiServicesGetBootMode (&BootMode); ASSERT_EFI_ERROR (Status); // // In S3 path, skip shadow logic. no measurement is required // if (BootMode != BOOT_ON_S3_RESUME) { Status = (**PeiServices).RegisterForShadow(FileHandle); if (Status == EFI_ALREADY_STARTED) { mImageInMemory = TRUE; } else if (Status == EFI_NOT_FOUND) { ASSERT_EFI_ERROR (Status); } } if (!mImageInMemory) { Status = Tpm12RequestUseTpm (); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "TPM not detected!\n")); goto Done; } if (PcdGet8 (PcdTpmInitializationPolicy) == 1) { if (BootMode == BOOT_ON_S3_RESUME) { Status = Tpm12Startup (TPM_ST_STATE); } else { Status = Tpm12Startup (TPM_ST_CLEAR); } if (EFI_ERROR (Status) ) { goto Done; } } // // TpmSelfTest is optional on S3 path, skip it to save S3 time // if (BootMode != BOOT_ON_S3_RESUME) { Status = Tpm12ContinueSelfTest (); if (EFI_ERROR (Status)) { goto Done; } } // // Only intall TpmInitializedPpi on success // Status = PeiServicesInstallPpi (&mTpmInitializedPpiList); ASSERT_EFI_ERROR (Status); } if (mImageInMemory) { Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices); return Status; } Done: if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "TPM error! Build Hob\n")); BuildGuidHob (&gTpmErrorHobGuid,0); REPORT_STATUS_CODE ( EFI_ERROR_CODE | EFI_ERROR_MINOR, (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR) ); } // // Always intall TpmInitializationDonePpi no matter success or fail. // Other driver can know TPM initialization state by TpmInitializedPpi. // Status2 = PeiServicesInstallPpi (&mTpmInitializationDonePpiList); ASSERT_EFI_ERROR (Status2); return Status; }
/** Do a hash operation on a data buffer, extend a specific TPM PCR with the hash result, and build a GUIDed HOB recording the event which will be passed to the DXE phase and added into the Event Log. @param[in] PeiServices Describes the list of possible PEI Services. @param[in] HashData Physical address of the start of the data buffer to be hashed, extended, and logged. @param[in] HashDataLen The length, in bytes, of the buffer referenced by HashData. @param[in] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. @param[in] NewEventData Pointer to the new event data. @retval EFI_SUCCESS Operation completed successfully. @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. @retval EFI_DEVICE_ERROR The command was unsuccessful. **/ EFI_STATUS HashLogExtendEvent ( IN EFI_PEI_SERVICES **PeiServices, IN UINT8 *HashData, IN UINTN HashDataLen, IN TCG_PCR_EVENT_HDR *NewEventHdr, IN UINT8 *NewEventData ) { EFI_STATUS Status; VOID *HobData; if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) { return EFI_DEVICE_ERROR; } HobData = NULL; if (HashDataLen != 0) { Status = TpmCommHashAll ( HashData, HashDataLen, &NewEventHdr->Digest ); if (EFI_ERROR (Status)) { goto Done; } } Status = Tpm12Extend ( &NewEventHdr->Digest, NewEventHdr->PCRIndex, NULL ); if (EFI_ERROR (Status)) { goto Done; } HobData = BuildGuidHob ( &gTcgEventEntryHobGuid, sizeof (*NewEventHdr) + NewEventHdr->EventSize ); if (HobData == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Done; } CopyMem (HobData, NewEventHdr, sizeof (*NewEventHdr)); HobData = (VOID *) ((UINT8*)HobData + sizeof (*NewEventHdr)); CopyMem (HobData, NewEventData, NewEventHdr->EventSize); Done: if ((Status == EFI_DEVICE_ERROR) || (Status == EFI_TIMEOUT)) { DEBUG ((EFI_D_ERROR, "HashLogExtendEvent - %r. Disable TPM.\n", Status)); BuildGuidHob (&gTpmErrorHobGuid,0); REPORT_STATUS_CODE ( EFI_ERROR_CODE | EFI_ERROR_MINOR, (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR) ); Status = EFI_DEVICE_ERROR; } return Status; }
/** BIOS process FspBobList. @param FspHobList Pointer to the HOB data structure produced by FSP. @return If platform process the FSP hob list successfully. **/ EFI_STATUS EFIAPI FspHobProcessForMemoryResource ( IN VOID *FspHobList ) { EFI_PEI_HOB_POINTERS Hob; UINT64 LowMemorySize; UINT64 FspMemorySize; EFI_PHYSICAL_ADDRESS FspMemoryBase; UINT64 PeiMemSize; EFI_PHYSICAL_ADDRESS PeiMemBase; UINT64 S3PeiMemSize; EFI_PHYSICAL_ADDRESS S3PeiMemBase; BOOLEAN FoundFspMemHob; EFI_STATUS Status; EFI_BOOT_MODE BootMode; PEI_CAPSULE_PPI *Capsule; VOID *CapsuleBuffer; UINTN CapsuleBufferLength; UINT64 RequiredMemSize; EFI_PEI_SERVICES **PeiServices; UINT64 TsegSize; EFI_PHYSICAL_ADDRESS TsegBase; BOOLEAN FoundTsegHob; PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer (); PeiServicesGetBootMode (&BootMode); PeiMemBase = 0; LowMemorySize = 0; FspMemorySize = 0; FspMemoryBase = 0; FoundFspMemHob = FALSE; TsegSize = 0; TsegBase = 0; FoundTsegHob = FALSE; // // Parse the hob list from fsp // Report all the resource hob except the memory between 1M and 4G // Hob.Raw = (UINT8 *)(UINTN)FspHobList; DEBUG((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList)); while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw)) != NULL) { DEBUG((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType)); if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) || (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)) { DEBUG((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute)); DEBUG((DEBUG_INFO, "PhysicalStart: 0x%x\n", Hob.ResourceDescriptor->PhysicalStart)); DEBUG((DEBUG_INFO, "ResourceLength: 0x%x\n", Hob.ResourceDescriptor->ResourceLength)); DEBUG((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner)); } if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) // Found the low memory length below 4G && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB) && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)) { LowMemorySize += Hob.ResourceDescriptor->ResourceLength; Hob.Raw = GET_NEXT_HOB (Hob); continue; } if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) // Found the low memory length below 4G && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB) && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB) && (CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspReservedMemoryResourceHobGuid))) { FoundFspMemHob = TRUE; FspMemoryBase = Hob.ResourceDescriptor->PhysicalStart; FspMemorySize = Hob.ResourceDescriptor->ResourceLength; DEBUG((DEBUG_INFO, "Find fsp mem hob, base 0x%x, len 0x%x\n", FspMemoryBase, FspMemorySize)); } if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) // Found the low memory length below 4G && (Hob.ResourceDescriptor->PhysicalStart >= 0x100000) && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= 0x100000000) && (CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspReservedMemoryResourceHobTsegGuid))) { FoundTsegHob = TRUE; TsegBase = Hob.ResourceDescriptor->PhysicalStart; if ((Hob.ResourceDescriptor->ResourceLength == 0 ) || (Hob.ResourceDescriptor->ResourceLength > 0x800000)){ Hob.ResourceDescriptor->ResourceLength = 0x800000; } TsegSize = Hob.ResourceDescriptor->ResourceLength; DEBUG((EFI_D_ERROR, "Find Tseg mem hob, base 0x%lx, len 0x%lx\n", TsegBase, TsegSize)); } // // Report the resource hob // BuildResourceDescriptorHob ( Hob.ResourceDescriptor->ResourceType, Hob.ResourceDescriptor->ResourceAttribute, Hob.ResourceDescriptor->PhysicalStart, Hob.ResourceDescriptor->ResourceLength ); Hob.Raw = GET_NEXT_HOB (Hob); } if (!FoundFspMemHob) { DEBUG((DEBUG_INFO, "Didn't find the fsp used memory information.\n")); //ASSERT(FALSE); } DEBUG((DEBUG_INFO, "LowMemorySize: 0x%x.\n", LowMemorySize)); DEBUG((DEBUG_INFO, "FspMemoryBase: 0x%x.\n", FspMemoryBase)); DEBUG((DEBUG_INFO, "FspMemorySize: 0x%x.\n", FspMemorySize)); if (BootMode == BOOT_ON_S3_RESUME) { BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, ( EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | // EFI_RESOURCE_ATTRIBUTE_TESTED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE ), BASE_1MB, LowMemorySize ); Status = GetS3MemoryInfo (&S3PeiMemBase, &S3PeiMemSize); ASSERT_EFI_ERROR (Status); DEBUG((DEBUG_INFO, "S3 memory %Xh - %Xh bytes\n", S3PeiMemBase, S3PeiMemSize)); // // Make sure Stack and PeiMemory are not overlap - JYAO1 // Status = PeiServicesInstallPeiMemory ( S3PeiMemBase, S3PeiMemSize ); ASSERT_EFI_ERROR (Status); } else { PeiMemSize = GetPeiMemSize (PeiServices, BootMode); DEBUG((DEBUG_INFO, "PEI memory size = %Xh bytes\n", PeiMemSize)); // // Capsule mode // Capsule = NULL; CapsuleBuffer = NULL; CapsuleBufferLength = 0; if (BootMode == BOOT_ON_FLASH_UPDATE) { Status = PeiServicesLocatePpi ( &gPeiCapsulePpiGuid, 0, NULL, (VOID **) &Capsule ); ASSERT_EFI_ERROR (Status); if (Status == EFI_SUCCESS) { // // Make sure Stack and CapsuleBuffer are not overlap - JYAO1 // CapsuleBuffer = (VOID *)(UINTN)BASE_1MB; CapsuleBufferLength = (UINTN)(LowMemorySize - PeiMemSize); // // Call the Capsule PPI Coalesce function to coalesce the capsule data. // Status = Capsule->Coalesce (PeiServices, &CapsuleBuffer, &CapsuleBufferLength); } } RequiredMemSize = RetrieveRequiredMemorySize (PeiServices); DEBUG((DEBUG_INFO, "Required memory size = %Xh bytes\n", RequiredMemSize)); // // Report the main memory // BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, ( EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_TESTED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE ), BASE_1MB, LowMemorySize ); // // Make sure Stack and CapsuleBuffer are not overlap - JYAO1 // // // Install efi memory // PeiMemBase = BASE_1MB + LowMemorySize - PeiMemSize; Status = PeiServicesInstallPeiMemory ( PeiMemBase, PeiMemSize - RequiredMemSize ); ASSERT_EFI_ERROR (Status); if (Capsule != NULL) { Status = Capsule->CreateState (PeiServices, CapsuleBuffer, CapsuleBufferLength); } } // // Report GUIDed HOB for reserving SMRAM regions // if (FoundTsegHob) { EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *SmramHobDescriptorBlock; SmramHobDescriptorBlock = BuildGuidHob ( &gEfiSmmPeiSmramMemoryReserveGuid, sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK) ); ASSERT (SmramHobDescriptorBlock != NULL); SmramHobDescriptorBlock->NumberOfSmmReservedRegions = 1; SmramHobDescriptorBlock->Descriptor[0].PhysicalStart = TsegBase; SmramHobDescriptorBlock->Descriptor[0].CpuStart = TsegBase; SmramHobDescriptorBlock->Descriptor[0].PhysicalSize = TsegSize; SmramHobDescriptorBlock->Descriptor[0].RegionState = EFI_SMRAM_CLOSED; } return EFI_SUCCESS; }
/** Build guid hob for the global memory to store the registered guid and Handler list. If GuidHob exists, HandlerInfo will be directly got from Guid hob data. @param[in, out] InfoPointer The pointer to pei handler information structure. @retval RETURN_SUCCESS Build Guid hob for the global memory space to store guid and function tables. @retval RETURN_OUT_OF_RESOURCES No enough memory to allocated. **/ RETURN_STATUS PeiGetExtractGuidedSectionHandlerInfo ( IN OUT PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO **InfoPointer ) { PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *HandlerInfo; EFI_PEI_HOB_POINTERS Hob; // // First try to get handler information from guid hob specified by CallerId. // Hob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GetHobList ()); while (Hob.Raw != NULL) { if (CompareGuid (&(Hob.Guid->Name), &gEfiCallerIdGuid)) { HandlerInfo = (PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO *) GET_GUID_HOB_DATA (Hob.Guid); if (HandlerInfo->Signature == PEI_EXTRACT_HANDLER_INFO_SIGNATURE) { // // Update Table Pointer when hob start address is changed. // if (HandlerInfo->ExtractHandlerGuidTable != (GUID *) (HandlerInfo + 1)) { HandlerInfo->ExtractHandlerGuidTable = (GUID *) (HandlerInfo + 1); HandlerInfo->ExtractDecodeHandlerTable = (EXTRACT_GUIDED_SECTION_DECODE_HANDLER *) ( (UINT8 *)HandlerInfo->ExtractHandlerGuidTable + PcdGet32 (PcdMaximumGuidedExtractHandler) * sizeof (GUID) ); HandlerInfo->ExtractGetInfoHandlerTable = (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *) ( (UINT8 *)HandlerInfo->ExtractDecodeHandlerTable + PcdGet32 (PcdMaximumGuidedExtractHandler) * sizeof (EXTRACT_GUIDED_SECTION_DECODE_HANDLER) ); } // // Return HandlerInfo pointer. // *InfoPointer = HandlerInfo; return EFI_SUCCESS; } } Hob.Raw = GET_NEXT_HOB (Hob); Hob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, Hob.Raw); } // // If Guid Hob is not found, Build CallerId Guid hob to store Handler Info // HandlerInfo = BuildGuidHob ( &gEfiCallerIdGuid, sizeof (PEI_EXTRACT_GUIDED_SECTION_HANDLER_INFO) + PcdGet32 (PcdMaximumGuidedExtractHandler) * (sizeof (GUID) + sizeof (EXTRACT_GUIDED_SECTION_DECODE_HANDLER) + sizeof (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER)) ); if (HandlerInfo == NULL) { // // No enough resource to build guid hob. // *InfoPointer = NULL; return EFI_OUT_OF_RESOURCES; } // // Init HandlerInfo structure // HandlerInfo->Signature = PEI_EXTRACT_HANDLER_INFO_SIGNATURE; HandlerInfo->NumberOfExtractHandler = 0; HandlerInfo->ExtractHandlerGuidTable = (GUID *) (HandlerInfo + 1); HandlerInfo->ExtractDecodeHandlerTable = (EXTRACT_GUIDED_SECTION_DECODE_HANDLER *) ( (UINT8 *)HandlerInfo->ExtractHandlerGuidTable + PcdGet32 (PcdMaximumGuidedExtractHandler) * sizeof (GUID) ); HandlerInfo->ExtractGetInfoHandlerTable = (EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER *) ( (UINT8 *)HandlerInfo->ExtractDecodeHandlerTable + PcdGet32 (PcdMaximumGuidedExtractHandler) * sizeof (EXTRACT_GUIDED_SECTION_DECODE_HANDLER) ); // // return the created HandlerInfo. // *InfoPointer = HandlerInfo; return EFI_SUCCESS; }
/** Migrate BootLoader data before destroying CAR. **/ VOID EFIAPI FspMigrateTemporaryMemory ( VOID ) { FSP_INIT_RT_COMMON_BUFFER *FspInitRtBuffer; UINT32 BootLoaderTempRamStart; UINT32 BootLoaderTempRamEnd; UINT32 BootLoaderTempRamSize; UINT32 OffsetGap; UINT32 FspParamPtr; FSP_INIT_PARAMS *FspInitParams; UINT32 *NewStackTop; VOID *BootLoaderTempRamHob; UINT32 UpdDataRgnPtr; UINT32 MemoryInitUpdPtr; UINT32 SiliconInitUpdPtr; VOID *PlatformDataPtr; UINT8 ApiMode; ApiMode = GetFspApiCallingMode (); // // Get the temporary memory range used by the BootLoader // BootLoaderTempRamStart = PcdGet32(PcdTemporaryRamBase); BootLoaderTempRamSize = PcdGet32(PcdTemporaryRamSize) - PcdGet32(PcdFspTemporaryRamSize); BootLoaderTempRamEnd = BootLoaderTempRamStart + BootLoaderTempRamSize; // // Build a Boot Loader Temporary Memory GUID HOB // if (ApiMode == 0) { BootLoaderTempRamHob = BuildGuidHob (&gFspBootLoaderTemporaryMemoryGuid, BootLoaderTempRamSize); } else { BootLoaderTempRamHob = (VOID *)AllocatePages (EFI_SIZE_TO_PAGES (BootLoaderTempRamSize)); } ASSERT(BootLoaderTempRamHob != NULL); CopyMem (BootLoaderTempRamHob, (VOID *)BootLoaderTempRamStart, BootLoaderTempRamSize); OffsetGap = (UINT32)BootLoaderTempRamHob - BootLoaderTempRamStart; // // Set a new stack frame for the continuation function // if (ApiMode == 0) { FspInitParams = (FSP_INIT_PARAMS *)GetFspApiParameter (); FspInitRtBuffer = (FSP_INIT_RT_COMMON_BUFFER *)FspInitParams->RtBufferPtr; NewStackTop = (UINT32 *)FspInitRtBuffer->StackTop - 1; SetFspCoreStackPointer (NewStackTop); } // // Fix the FspInit Parameter Pointers to the new location. // FspParamPtr = GetFspApiParameter (); if (FspParamPtr >= BootLoaderTempRamStart && FspParamPtr < BootLoaderTempRamEnd) { SetFspApiParameter(FspParamPtr + OffsetGap); } FspInitParams = (FSP_INIT_PARAMS *)GetFspApiParameter (); if ((UINT32)(FspInitParams->RtBufferPtr) >= BootLoaderTempRamStart && (UINT32)(FspInitParams->RtBufferPtr) < BootLoaderTempRamEnd) { FspInitParams->RtBufferPtr = (VOID *)((UINT32)(FspInitParams->RtBufferPtr) + OffsetGap); } if ((UINT32)(FspInitParams->NvsBufferPtr) >= BootLoaderTempRamStart && (UINT32)(FspInitParams->NvsBufferPtr) < BootLoaderTempRamEnd) { FspInitParams->NvsBufferPtr = (VOID *)((UINT32)(FspInitParams->NvsBufferPtr) + OffsetGap); } if ((UINT32)(((FSP_INIT_RT_COMMON_BUFFER *)(FspInitParams->RtBufferPtr))->UpdDataRgnPtr) >= BootLoaderTempRamStart && (UINT32)(((FSP_INIT_RT_COMMON_BUFFER *)(FspInitParams->RtBufferPtr))->UpdDataRgnPtr) < BootLoaderTempRamEnd) { ((FSP_INIT_RT_COMMON_BUFFER *)(FspInitParams->RtBufferPtr))->UpdDataRgnPtr = \ (VOID *)((UINT32)(((FSP_INIT_RT_COMMON_BUFFER *)(FspInitParams->RtBufferPtr))->UpdDataRgnPtr) + OffsetGap); } // // Update UPD pointer in FSP Global Data // if (ApiMode == 0) { UpdDataRgnPtr = (UINT32)((UINT32 *)GetFspUpdDataPointer ()); if (UpdDataRgnPtr >= BootLoaderTempRamStart && UpdDataRgnPtr < BootLoaderTempRamEnd) { MemoryInitUpdPtr = (UINT32)((UINT32 *)GetFspMemoryInitUpdDataPointer ()); SiliconInitUpdPtr = (UINT32)((UINT32 *)GetFspSiliconInitUpdDataPointer ()); SetFspUpdDataPointer ((VOID *)(UpdDataRgnPtr + OffsetGap)); SetFspMemoryInitUpdDataPointer ((VOID *)(MemoryInitUpdPtr + OffsetGap)); SetFspSiliconInitUpdDataPointer ((VOID *)(SiliconInitUpdPtr + OffsetGap)); } } else { MemoryInitUpdPtr = (UINT32)((UINT32 *)GetFspMemoryInitUpdDataPointer ()); if (MemoryInitUpdPtr >= BootLoaderTempRamStart && MemoryInitUpdPtr < BootLoaderTempRamEnd) { SetFspMemoryInitUpdDataPointer ((VOID *)(MemoryInitUpdPtr + OffsetGap)); } } // // Update Platform data pointer in FSP Global Data // PlatformDataPtr = GetFspPlatformDataPointer (); if (((UINT32)PlatformDataPtr >= BootLoaderTempRamStart) && ((UINT32)PlatformDataPtr < BootLoaderTempRamEnd)) { SetFspPlatformDataPointer ((UINT8 *)PlatformDataPtr + OffsetGap); } }
/** Entry point of this module. @param[in] FileHandle Handle of the file being invoked. @param[in] PeiServices Describes the list of possible PEI Services. @return Status. **/ EFI_STATUS EFIAPI PeimEntryMA ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; EFI_STATUS Status2; EFI_BOOT_MODE BootMode; TPM_PCRINDEX PcrIndex; BOOLEAN S3ErrorReport; if (CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceNoneGuid) || CompareGuid (PcdGetPtr(PcdTpmInstanceGuid), &gEfiTpmDeviceInstanceTpm12Guid)) { DEBUG ((EFI_D_ERROR, "No TPM2 instance required!\n")); return EFI_UNSUPPORTED; } if (GetFirstGuidHob (&gTpmErrorHobGuid) != NULL) { DEBUG ((EFI_D_ERROR, "TPM2 error!\n")); return EFI_DEVICE_ERROR; } Status = PeiServicesGetBootMode (&BootMode); ASSERT_EFI_ERROR (Status); // // In S3 path, skip shadow logic. no measurement is required // if (BootMode != BOOT_ON_S3_RESUME) { Status = (**PeiServices).RegisterForShadow(FileHandle); if (Status == EFI_ALREADY_STARTED) { mImageInMemory = TRUE; mFileHandle = FileHandle; } else if (Status == EFI_NOT_FOUND) { ASSERT_EFI_ERROR (Status); } } if (!mImageInMemory) { // // Initialize TPM device // Status = Tpm2RequestUseTpm (); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "TPM2 not detected!\n")); goto Done; } S3ErrorReport = FALSE; if (PcdGet8 (PcdTpm2InitializationPolicy) == 1) { if (BootMode == BOOT_ON_S3_RESUME) { Status = Tpm2Startup (TPM_SU_STATE); if (EFI_ERROR (Status) ) { Status = Tpm2Startup (TPM_SU_CLEAR); if (!EFI_ERROR(Status)) { S3ErrorReport = TRUE; } } } else { Status = Tpm2Startup (TPM_SU_CLEAR); } if (EFI_ERROR (Status) ) { goto Done; } } // // Update Tpm2HashMask according to PCR bank. // SyncPcrAllocationsAndPcrMask (); if (S3ErrorReport) { // // The system firmware that resumes from S3 MUST deal with a // TPM2_Startup error appropriately. // For example, issue a TPM2_Startup(TPM_SU_CLEAR) command and // configuring the device securely by taking actions like extending a // separator with an error digest (0x01) into PCRs 0 through 7. // for (PcrIndex = 0; PcrIndex < 8; PcrIndex++) { Status = MeasureSeparatorEventWithError (PcrIndex); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Separator Event with Error not Measured. Error!\n")); } } } // // TpmSelfTest is optional on S3 path, skip it to save S3 time // if (BootMode != BOOT_ON_S3_RESUME) { if (PcdGet8 (PcdTpm2SelfTestPolicy) == 1) { Status = Tpm2SelfTest (NO); if (EFI_ERROR (Status)) { goto Done; } } } // // Only intall TpmInitializedPpi on success // Status = PeiServicesInstallPpi (&mTpmInitializedPpiList); ASSERT_EFI_ERROR (Status); } if (mImageInMemory) { Status = PeimEntryMP ((EFI_PEI_SERVICES**)PeiServices); return Status; } Done: if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "TPM2 error! Build Hob\n")); BuildGuidHob (&gTpmErrorHobGuid,0); REPORT_STATUS_CODE ( EFI_ERROR_CODE | EFI_ERROR_MINOR, (PcdGet32 (PcdStatusCodeSubClassTpmDevice) | EFI_P_EC_INTERFACE_ERROR) ); } // // Always intall TpmInitializationDonePpi no matter success or fail. // Other driver can know TPM initialization state by TpmInitializedPpi. // Status2 = PeiServicesInstallPpi (&mTpmInitializationDonePpiList); ASSERT_EFI_ERROR (Status2); return Status; }
/** Add a new entry to the Event Log. @param[in] DigestList A list of digest. @param[in,out] NewEventHdr Pointer to a TCG_PCR_EVENT_HDR data structure. @param[in] NewEventData Pointer to the new event data. @retval EFI_SUCCESS The new event log entry was added. @retval EFI_OUT_OF_RESOURCES No enough memory to log the new event. **/ EFI_STATUS LogHashEvent ( IN TPML_DIGEST_VALUES *DigestList, IN OUT TCG_PCR_EVENT_HDR *NewEventHdr, IN UINT8 *NewEventData ) { VOID *HobData; EFI_STATUS Status; UINTN Index; EFI_STATUS RetStatus; UINT32 SupportedEventLogs; TCG_PCR_EVENT2 *TcgPcrEvent2; UINT8 *DigestBuffer; SupportedEventLogs = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_2; RetStatus = EFI_SUCCESS; for (Index = 0; Index < sizeof(mTcg2EventInfo)/sizeof(mTcg2EventInfo[0]); Index++) { if ((SupportedEventLogs & mTcg2EventInfo[Index].LogFormat) != 0) { DEBUG ((EFI_D_INFO, " LogFormat - 0x%08x\n", mTcg2EventInfo[Index].LogFormat)); switch (mTcg2EventInfo[Index].LogFormat) { case EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2: Status = GetDigestFromDigestList (TPM_ALG_SHA1, DigestList, &NewEventHdr->Digest); if (!EFI_ERROR (Status)) { HobData = BuildGuidHob ( &gTcgEventEntryHobGuid, sizeof (*NewEventHdr) + NewEventHdr->EventSize ); if (HobData == NULL) { RetStatus = EFI_OUT_OF_RESOURCES; break; } CopyMem (HobData, NewEventHdr, sizeof (*NewEventHdr)); HobData = (VOID *) ((UINT8*)HobData + sizeof (*NewEventHdr)); CopyMem (HobData, NewEventData, NewEventHdr->EventSize); } break; case EFI_TCG2_EVENT_LOG_FORMAT_TCG_2: HobData = BuildGuidHob ( &gTcgEvent2EntryHobGuid, sizeof(TcgPcrEvent2->PCRIndex) + sizeof(TcgPcrEvent2->EventType) + GetDigestListSize (DigestList) + sizeof(TcgPcrEvent2->EventSize) + NewEventHdr->EventSize ); if (HobData == NULL) { RetStatus = EFI_OUT_OF_RESOURCES; break; } TcgPcrEvent2 = HobData; TcgPcrEvent2->PCRIndex = NewEventHdr->PCRIndex; TcgPcrEvent2->EventType = NewEventHdr->EventType; DigestBuffer = (UINT8 *)&TcgPcrEvent2->Digest; DigestBuffer = CopyDigestListToBuffer (DigestBuffer, DigestList, PcdGet32 (PcdTpm2HashMask)); CopyMem (DigestBuffer, &NewEventHdr->EventSize, sizeof(TcgPcrEvent2->EventSize)); DigestBuffer = DigestBuffer + sizeof(TcgPcrEvent2->EventSize); CopyMem (DigestBuffer, NewEventData, NewEventHdr->EventSize); break; } } } return RetStatus; }
/** This is the entrypoint of PEIM @param FileHandle Handle of the file being invoked. @param PeiServices Describes the list of possible PEI Services. @retval EFI_SUCCESS if it completed successfully. **/ EFI_STATUS EFIAPI CbPeiEntryPoint ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; UINT64 LowMemorySize, HighMemorySize; UINT64 PeiMemSize = SIZE_64MB; // 64 MB EFI_PHYSICAL_ADDRESS PeiMemBase = 0; UINT32 RegEax; UINT8 PhysicalAddressBits; VOID* pCbHeader; VOID* pAcpiTable; UINT32 AcpiTableSize; VOID* pSmbiosTable; UINT32 SmbiosTableSize; SYSTEM_TABLE_INFO* pSystemTableInfo; FRAME_BUFFER_INFO FbInfo; FRAME_BUFFER_INFO* pFbInfo; ACPI_BOARD_INFO* pAcpiBoardInfo; UINTN PmCtrlRegBase, PmTimerRegBase, ResetRegAddress, ResetValue; LowMemorySize = 0; HighMemorySize = 0; Status = CbParseMemoryInfo (&LowMemorySize, &HighMemorySize); if (EFI_ERROR(Status)) return Status; DEBUG((EFI_D_ERROR, "LowMemorySize: 0x%lx.\n", LowMemorySize)); DEBUG((EFI_D_ERROR, "HighMemorySize: 0x%lx.\n", HighMemorySize)); ASSERT (LowMemorySize > 0); BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, ( EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_TESTED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE ), (EFI_PHYSICAL_ADDRESS)(0), (UINT64)(0xA0000) ); BuildResourceDescriptorHob ( EFI_RESOURCE_MEMORY_RESERVED, ( EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_TESTED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE ), (EFI_PHYSICAL_ADDRESS)(0xA0000), (UINT64)(0x60000) ); BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, ( EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_TESTED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE ), (EFI_PHYSICAL_ADDRESS)(0x100000), (UINT64) (LowMemorySize - 0x100000) ); if (HighMemorySize > 0) { BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, ( EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE ), (EFI_PHYSICAL_ADDRESS)(0x100000000ULL), HighMemorySize ); } // // Should be 64k aligned // PeiMemBase = (LowMemorySize - PeiMemSize) & (~(BASE_64KB - 1)); DEBUG((EFI_D_ERROR, "PeiMemBase: 0x%lx.\n", PeiMemBase)); DEBUG((EFI_D_ERROR, "PeiMemSize: 0x%lx.\n", PeiMemSize)); Status = PeiServicesInstallPeiMemory ( PeiMemBase, PeiMemSize ); ASSERT_EFI_ERROR (Status); // // Set cache on the physical memory // MtrrSetMemoryAttribute (BASE_1MB, LowMemorySize - BASE_1MB, CacheWriteBack); MtrrSetMemoryAttribute (0, 0xA0000, CacheWriteBack); // // Create Memory Type Information HOB // BuildGuidDataHob ( &gEfiMemoryTypeInformationGuid, mDefaultMemoryTypeInformation, sizeof(mDefaultMemoryTypeInformation) ); // // Create Fv hob // CbPeiReportRemainedFvs (); BuildMemoryAllocationHob ( PcdGet32 (PcdPayloadFdMemBase), PcdGet32 (PcdPayloadFdMemSize), EfiBootServicesData ); // // Build CPU memory space and IO space hob // AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); if (RegEax >= 0x80000008) { AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); PhysicalAddressBits = (UINT8) RegEax; } else { PhysicalAddressBits = 36; } // // Create a CPU hand-off information // BuildCpuHob (PhysicalAddressBits, 16); // // Report Local APIC range // BuildMemoryMappedIoRangeHob (0xFEC80000, SIZE_512KB); // // Boot mode // Status = PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION); ASSERT_EFI_ERROR (Status); Status = PeiServicesInstallPpi (mPpiBootMode); ASSERT_EFI_ERROR (Status); // // Set pcd to save the upper coreboot header in case the dxecore will // erase 0~4k memory // pCbHeader = NULL; if ((CbParseGetCbHeader (1, &pCbHeader) == RETURN_SUCCESS) && ((UINTN)pCbHeader > BASE_4KB)) { DEBUG((EFI_D_ERROR, "Actual Coreboot header: %p.\n", pCbHeader)); PcdSet32 (PcdCbHeaderPointer, (UINT32)(UINTN)pCbHeader); } // // Create guid hob for system tables like acpi table and smbios table // pAcpiTable = NULL; AcpiTableSize = 0; pSmbiosTable = NULL; SmbiosTableSize = 0; Status = CbParseAcpiTable (&pAcpiTable, &AcpiTableSize); if (EFI_ERROR (Status)) { // ACPI table is oblidgible DEBUG ((EFI_D_ERROR, "Failed to find the required acpi table\n")); ASSERT (FALSE); } CbParseSmbiosTable (&pSmbiosTable, &SmbiosTableSize); pSystemTableInfo = NULL; pSystemTableInfo = BuildGuidHob (&gUefiSystemTableInfoGuid, sizeof (SYSTEM_TABLE_INFO)); ASSERT (pSystemTableInfo != NULL); pSystemTableInfo->AcpiTableBase = (UINT64) (UINTN)pAcpiTable; pSystemTableInfo->AcpiTableSize = AcpiTableSize; pSystemTableInfo->SmbiosTableBase = (UINT64) (UINTN)pSmbiosTable; pSystemTableInfo->SmbiosTableSize = SmbiosTableSize; DEBUG ((EFI_D_ERROR, "Detected Acpi Table at 0x%lx, length 0x%x\n", pSystemTableInfo->AcpiTableBase, pSystemTableInfo->AcpiTableSize)); DEBUG ((EFI_D_ERROR, "Detected Smbios Table at 0x%lx, length 0x%x\n", pSystemTableInfo->SmbiosTableBase, pSystemTableInfo->SmbiosTableSize)); DEBUG ((EFI_D_ERROR, "Create system table info guid hob\n")); // // Create guid hob for acpi board information // Status = CbParseFadtInfo (&PmCtrlRegBase, &PmTimerRegBase, &ResetRegAddress, &ResetValue); ASSERT_EFI_ERROR (Status); pAcpiBoardInfo = NULL; pAcpiBoardInfo = BuildGuidHob (&gUefiAcpiBoardInfoGuid, sizeof (ACPI_BOARD_INFO)); ASSERT (pAcpiBoardInfo != NULL); pAcpiBoardInfo->PmCtrlRegBase = (UINT64)PmCtrlRegBase; pAcpiBoardInfo->PmTimerRegBase = (UINT64)PmTimerRegBase; pAcpiBoardInfo->ResetRegAddress = (UINT64)ResetRegAddress; pAcpiBoardInfo->ResetValue = (UINT8)ResetValue; DEBUG ((EFI_D_ERROR, "Create acpi board info guid hob\n")); // // Create guid hob for frame buffer information // ZeroMem (&FbInfo, sizeof (FRAME_BUFFER_INFO)); Status = CbParseFbInfo (&FbInfo); if (!EFI_ERROR (Status)) { pFbInfo = BuildGuidHob (&gUefiFrameBufferInfoGuid, sizeof (FRAME_BUFFER_INFO)); ASSERT (pSystemTableInfo != NULL); CopyMem (pFbInfo, &FbInfo, sizeof (FRAME_BUFFER_INFO)); DEBUG ((EFI_D_ERROR, "Create frame buffer info guid hob\n")); } // // Mask off all legacy 8259 interrupt sources // IoWrite8 (LEGACY_8259_MASK_REGISTER_MASTER, 0xFF); IoWrite8 (LEGACY_8259_MASK_REGISTER_SLAVE, 0xFF); return EFI_SUCCESS; }
/** Call FspMemoryInit API. @return Status returned by FspMemoryInit API. **/ EFI_STATUS PeiFspMemoryInit ( VOID ) { FSP_INFO_HEADER *FspmHeaderPtr; EFI_STATUS Status; UINT64 TimeStampCounterStart; VOID *FspHobListPtr; VOID *HobData; FSPM_UPD_COMMON *FspmUpdDataPtr; UINTN *SourceData; DEBUG ((DEBUG_INFO, "PeiFspMemoryInit enter\n")); FspHobListPtr = NULL; // // Copy default FSP-M UPD data from Flash // FspmHeaderPtr = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress)); FspmUpdDataPtr = (FSPM_UPD_COMMON *)AllocateZeroPool ((UINTN)FspmHeaderPtr->CfgRegionSize); ASSERT (FspmUpdDataPtr != NULL); SourceData = (UINTN *)((UINTN)FspmHeaderPtr->ImageBase + (UINTN)FspmHeaderPtr->CfgRegionOffset); CopyMem (FspmUpdDataPtr, SourceData, (UINTN)FspmHeaderPtr->CfgRegionSize); DEBUG ((DEBUG_INFO, "UpdateFspmUpdData enter\n")); UpdateFspmUpdData ((VOID *)FspmUpdDataPtr); DEBUG ((DEBUG_INFO, " NvsBufferPtr - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.NvsBufferPtr)); DEBUG ((DEBUG_INFO, " StackBase - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.StackBase)); DEBUG ((DEBUG_INFO, " StackSize - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.StackSize)); DEBUG ((DEBUG_INFO, " BootLoaderTolumSize - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.BootLoaderTolumSize)); DEBUG ((DEBUG_INFO, " BootMode - 0x%x\n", FspmUpdDataPtr->FspmArchUpd.BootMode)); DEBUG ((DEBUG_INFO, " HobListPtr - 0x%x\n", &FspHobListPtr)); TimeStampCounterStart = AsmReadTsc (); Status = CallFspMemoryInit (FspmUpdDataPtr, &FspHobListPtr); // Create hobs after memory initialization and not in temp RAM. Hence passing the recorded timestamp here PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, TimeStampCounterStart, 0xD000); PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0xD07F); DEBUG ((DEBUG_INFO, "Total time spent executing FspMemoryInitApi: %d millisecond\n", DivU64x32 (GetTimeInNanoSecond (AsmReadTsc () - TimeStampCounterStart), 1000000))); if (EFI_ERROR(Status)) { DEBUG ((DEBUG_ERROR, "ERROR - Failed to execute FspMemoryInitApi(), Status = %r\n", Status)); } DEBUG((DEBUG_INFO, "FspMemoryInit status: 0x%x\n", Status)); ASSERT_EFI_ERROR (Status); Status = TestFspMemoryInitApiOutput (FspmUpdDataPtr, &FspHobListPtr); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "ERROR - TestFspMemoryInitApiOutput () fail, Status = %r\n", Status)); } DEBUG ((DEBUG_INFO, " FspHobListPtr (returned) - 0x%x\n", FspHobListPtr)); ASSERT (FspHobListPtr != NULL); PostFspmHobProcess (FspHobListPtr); // // FspHobList is not complete at this moment. // Save FspHobList pointer to hob, so that it can be got later // HobData = BuildGuidHob ( &gFspHobGuid, sizeof (VOID *) ); ASSERT (HobData != NULL); CopyMem (HobData, &FspHobListPtr, sizeof (FspHobListPtr)); return Status; }
EFI_STATUS EFIAPI PeimInitializeWinNtAutoScan ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) /*++ Routine Description: Perform a call-back into the SEC simulator to get a memory value Arguments: FfsHeader - General purpose data available to every PEIM PeiServices - General purpose services available to every PEIM. Returns: None --*/ { EFI_STATUS Status; EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor; PEI_NT_AUTOSCAN_PPI *PeiNtService; UINT64 MemorySize; EFI_PHYSICAL_ADDRESS MemoryBase; UINTN Index; EFI_RESOURCE_ATTRIBUTE_TYPE Attributes; UINT64 PeiMemorySize; EFI_PHYSICAL_ADDRESS PeiMemoryBase; EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable; UINTN DataSize; EFI_MEMORY_TYPE_INFORMATION MemoryData [EfiMaxMemoryType + 1]; UINT64 SmramMemorySize; EFI_PHYSICAL_ADDRESS SmramMemoryBase; EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *SmramHobDescriptorBlock; PEI_CAPSULE_PPI *Capsule; VOID *CapsuleBuffer; UINTN CapsuleBufferLength; EFI_BOOT_MODE BootMode; EFI_WIN_NT_MEMORY_LAYOUT *MemoryLayout; UINTN MaxSystemMemoryCount; DEBUG ((EFI_D_ERROR, "NT 32 Autoscan PEIM Loaded\n")); // // Get the PEI NT Autoscan PPI // Status = PeiServicesLocatePpi ( &gPeiNtAutoScanPpiGuid, // GUID 0, // INSTANCE &PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR (VOID**)&PeiNtService // PPI ); ASSERT_EFI_ERROR (Status); Status = PeiServicesGetBootMode (&BootMode); ASSERT_EFI_ERROR (Status); DEBUG ((EFI_D_ERROR, "BootMode - %x\n", BootMode)); if (FeaturePcdGet (PcdWinNtCapsuleEnable)) { MaxSystemMemoryCount = GetMaxSystemMemoryCount(); MemoryLayout = BuildGuidHob ( &gEfiWinNtMemoryLayoutGuid, sizeof (EFI_WIN_NT_MEMORY_LAYOUT) + sizeof (EFI_WIN_NT_MEMORY_DESCRIPTOR) * (MaxSystemMemoryCount - 1) ); ASSERT (MemoryLayout != NULL); MemoryLayout->NumberOfRegions = 0; Capsule = NULL; CapsuleBuffer = NULL; CapsuleBufferLength = 0; if (BootMode == BOOT_ON_FLASH_UPDATE) { Status = PeiServicesLocatePpi (&gPeiCapsulePpiGuid, 0, NULL, (VOID**) &Capsule); ASSERT_EFI_ERROR (Status); } } Index = 0; SmramMemorySize = 0; SmramMemoryBase = 0; do { Status = PeiNtService->NtAutoScan (Index, &MemoryBase, &MemorySize); DEBUG ((EFI_D_ERROR, "NtAutoScan(%d) Status - %r\n", Index, Status)); if (!EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "NtAutoScan(%d) Base - 0x%lx\n", Index, MemoryBase)); DEBUG ((EFI_D_ERROR, "NtAutoScan(%d) Size - 0x%lx\n", Index, MemorySize)); if (FeaturePcdGet (PcdWinNtCapsuleEnable)) { if (MemoryLayout->NumberOfRegions < MaxSystemMemoryCount) { MemoryLayout->Descriptor[MemoryLayout->NumberOfRegions].Base = MemoryBase; MemoryLayout->Descriptor[MemoryLayout->NumberOfRegions].Size = MemorySize; MemoryLayout->NumberOfRegions ++; } } Attributes = ( EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE ); if (Index == 0) { // // Register the memory with the PEI Core // if (FeaturePcdGet(PcdWinNtSmmEnable)) { // // SMRAM // SmramMemorySize = PcdGet64(PcdWinNtSmramSize); SmramMemoryBase = MemoryBase + MemorySize - SmramMemorySize; DEBUG ((EFI_D_ERROR, "SmramMemoryBase - 0x%lx\n", SmramMemoryBase)); DEBUG ((EFI_D_ERROR, "SmramMemorySize - 0x%lx\n", SmramMemorySize)); MemorySize = MemorySize - SmramMemorySize; } PeiMemoryBase = MemoryBase; PeiMemorySize = MemorySize; if (FeaturePcdGet(PcdWinNtCapsuleEnable)) { // // Capsule // if (Capsule != NULL) { CapsuleBufferLength = ((UINTN) PeiMemorySize / 2); PeiMemorySize = CapsuleBufferLength; CapsuleBuffer = (VOID*) (UINTN) (PeiMemoryBase + CapsuleBufferLength); } } Attributes |= EFI_RESOURCE_ATTRIBUTE_TESTED; } BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, Attributes, MemoryBase, MemorySize ); DEBUG ((EFI_D_ERROR, "ResourceHob - 0x%lx - 0x%lx\n", MemoryBase, MemorySize)); } Index++; } while (!EFI_ERROR (Status)); if (FeaturePcdGet(PcdWinNtCapsuleEnable)) { if (Capsule != NULL) { // // Call the Capsule PPI Coalesce function to coalesce the capsule data. // Status = Capsule->Coalesce ( (EFI_PEI_SERVICES**) PeiServices, &CapsuleBuffer, &CapsuleBufferLength ); DEBUG ((EFI_D_ERROR, "CoalesceStatus - %r\n", Status)); DEBUG ((EFI_D_ERROR, "CapsuleBuffer - %x\n", CapsuleBuffer)); DEBUG ((EFI_D_ERROR, "CapsuleBufferLength - %x\n", CapsuleBufferLength)); // // If it failed, then NULL out our capsule PPI pointer so that the capsule // HOB does not get created below. // if (Status != EFI_SUCCESS) { Capsule = NULL; } } } Status = PeiServicesInstallPeiMemory (PeiMemoryBase, PeiMemorySize); ASSERT_EFI_ERROR (Status); if (FeaturePcdGet(PcdWinNtCapsuleEnable)) { // // If we found the capsule PPI (and we didn't have errors), then // call the capsule PEIM to allocate memory for the capsule. // if (Capsule != NULL) { Status = Capsule->CreateState((EFI_PEI_SERVICES **)PeiServices, CapsuleBuffer, CapsuleBufferLength); } } // // Build the CPU hob with 52-bit addressing and 16-bits of IO space. // BuildCpuHob (52, 16); // // Build GUIDed Hob that contains the Memory Type Information array // Status = PeiServicesLocatePpi ( &gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **)&Variable ); ASSERT_EFI_ERROR (Status); DataSize = sizeof (MemoryData); Status = Variable->GetVariable ( Variable, EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME, &gEfiMemoryTypeInformationGuid, NULL, &DataSize, &MemoryData ); if (EFI_ERROR (Status) || !ValidateMemoryTypeInfoVariable(MemoryData, DataSize)) { // // Create Memory Type Information HOB // BuildGuidDataHob ( &gEfiMemoryTypeInformationGuid, mDefaultMemoryTypeInformation, sizeof(mDefaultMemoryTypeInformation) ); } else { // // Create Memory Type Information HOB // BuildGuidDataHob ( &gEfiMemoryTypeInformationGuid, MemoryData, DataSize ); } if (FeaturePcdGet(PcdWinNtSmmEnable)) { // // BuildSmramHob // if ((SmramMemoryBase != 0) && (SmramMemorySize != 0)) { SmramHobDescriptorBlock = BuildGuidHob ( &gEfiSmmPeiSmramMemoryReserveGuid, sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK) + sizeof (EFI_SMRAM_DESCRIPTOR) ); ASSERT (SmramHobDescriptorBlock != NULL); SmramHobDescriptorBlock->NumberOfSmmReservedRegions = 1; SmramHobDescriptorBlock->Descriptor[0].PhysicalStart = SmramMemoryBase; SmramHobDescriptorBlock->Descriptor[0].CpuStart = SmramMemoryBase; SmramHobDescriptorBlock->Descriptor[0].PhysicalSize = SmramMemorySize; SmramHobDescriptorBlock->Descriptor[0].RegionState = EFI_SMRAM_CLOSED; } } return Status; }
/** This is the entrypoint of PEIM @param FileHandle Handle of the file being invoked. @param PeiServices Describes the list of possible PEI Services. @retval EFI_SUCCESS if it completed successfully. **/ EFI_STATUS EFIAPI CbPeiEntryPoint ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; UINT64 LowMemorySize; UINT64 PeiMemSize = SIZE_64MB; // 64 MB EFI_PHYSICAL_ADDRESS PeiMemBase = 0; UINT32 RegEax; UINT8 PhysicalAddressBits; VOID* pCbHeader; VOID* pAcpiTable; UINT32 AcpiTableSize; VOID* pSmbiosTable; UINT32 SmbiosTableSize; SYSTEM_TABLE_INFO* pSystemTableInfo; FRAME_BUFFER_INFO FbInfo; FRAME_BUFFER_INFO* pFbInfo; ACPI_BOARD_INFO* pAcpiBoardInfo; UINTN PmCtrlRegBase, PmTimerRegBase, ResetRegAddress, ResetValue; UINTN PmEvtBase; UINTN PmGpeEnBase; CB_MEM_INFO CbMemInfo; // // Report lower 640KB of RAM. Attribute EFI_RESOURCE_ATTRIBUTE_TESTED // is intentionally omitted to prevent erasing of the coreboot header // record before it is processed by CbParseMemoryInfo. // BuildResourceDescriptorHob ( EFI_RESOURCE_SYSTEM_MEMORY, ( EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE ), // Lower 640KB, except for first 4KB where the lower coreboot pointer ("LBIO") resides (EFI_PHYSICAL_ADDRESS)(0 + 0x1000), (UINT64)(0xA0000 - 0x1000) ); BuildResourceDescriptorHob ( EFI_RESOURCE_MEMORY_RESERVED, ( EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_TESTED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE ), (EFI_PHYSICAL_ADDRESS)(0xA0000), (UINT64)(0x60000) ); ZeroMem (&CbMemInfo, sizeof(CbMemInfo)); Status = CbParseMemoryInfo (CbMemInfoCallback, (VOID *)&CbMemInfo); if (EFI_ERROR(Status)) { return Status; } LowMemorySize = CbMemInfo.UsableLowMemTop; DEBUG ((EFI_D_INFO, "Low memory 0x%lx\n", LowMemorySize)); DEBUG ((EFI_D_INFO, "SystemLowMemTop 0x%x\n", CbMemInfo.SystemLowMemTop)); // // Should be 64k aligned // PeiMemBase = (LowMemorySize - PeiMemSize) & (~(BASE_64KB - 1)); DEBUG((EFI_D_ERROR, "PeiMemBase: 0x%lx.\n", PeiMemBase)); DEBUG((EFI_D_ERROR, "PeiMemSize: 0x%lx.\n", PeiMemSize)); Status = PeiServicesInstallPeiMemory ( PeiMemBase, PeiMemSize ); ASSERT_EFI_ERROR (Status); // // Set cache on the physical memory // MtrrSetMemoryAttribute (BASE_1MB, LowMemorySize - BASE_1MB, CacheWriteBack); MtrrSetMemoryAttribute (0, 0xA0000, CacheWriteBack); // // Create Memory Type Information HOB // BuildGuidDataHob ( &gEfiMemoryTypeInformationGuid, mDefaultMemoryTypeInformation, sizeof(mDefaultMemoryTypeInformation) ); // // Create Fv hob // CbPeiReportRemainedFvs (); BuildMemoryAllocationHob ( PcdGet32 (PcdPayloadFdMemBase), PcdGet32 (PcdPayloadFdMemSize), EfiBootServicesData ); // // Build CPU memory space and IO space hob // AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL); if (RegEax >= 0x80000008) { AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL); PhysicalAddressBits = (UINT8) RegEax; } else { PhysicalAddressBits = 36; } // // Create a CPU hand-off information // BuildCpuHob (PhysicalAddressBits, 16); // // Report Local APIC range // BuildMemoryMappedIoRangeHob (0xFEC80000, SIZE_512KB); // // Boot mode // Status = PeiServicesSetBootMode (BOOT_WITH_FULL_CONFIGURATION); ASSERT_EFI_ERROR (Status); Status = PeiServicesInstallPpi (mPpiBootMode); ASSERT_EFI_ERROR (Status); // // Set pcd to save the upper coreboot header in case the dxecore will // erase 0~4k memory // pCbHeader = NULL; if ((CbParseGetCbHeader (1, &pCbHeader) == RETURN_SUCCESS) && ((UINTN)pCbHeader > BASE_4KB)) { DEBUG((EFI_D_ERROR, "Actual Coreboot header: %p.\n", pCbHeader)); Status = PcdSet32S (PcdCbHeaderPointer, (UINT32)(UINTN)pCbHeader); ASSERT_EFI_ERROR (Status); } // // Create guid hob for system tables like acpi table and smbios table // pAcpiTable = NULL; AcpiTableSize = 0; pSmbiosTable = NULL; SmbiosTableSize = 0; Status = CbParseAcpiTable (&pAcpiTable, &AcpiTableSize); if (EFI_ERROR (Status)) { // ACPI table is oblidgible DEBUG ((EFI_D_ERROR, "Failed to find the required acpi table\n")); ASSERT (FALSE); } CbParseSmbiosTable (&pSmbiosTable, &SmbiosTableSize); pSystemTableInfo = NULL; pSystemTableInfo = BuildGuidHob (&gUefiSystemTableInfoGuid, sizeof (SYSTEM_TABLE_INFO)); ASSERT (pSystemTableInfo != NULL); pSystemTableInfo->AcpiTableBase = (UINT64) (UINTN)pAcpiTable; pSystemTableInfo->AcpiTableSize = AcpiTableSize; pSystemTableInfo->SmbiosTableBase = (UINT64) (UINTN)pSmbiosTable; pSystemTableInfo->SmbiosTableSize = SmbiosTableSize; DEBUG ((EFI_D_ERROR, "Detected Acpi Table at 0x%lx, length 0x%x\n", pSystemTableInfo->AcpiTableBase, pSystemTableInfo->AcpiTableSize)); DEBUG ((EFI_D_ERROR, "Detected Smbios Table at 0x%lx, length 0x%x\n", pSystemTableInfo->SmbiosTableBase, pSystemTableInfo->SmbiosTableSize)); DEBUG ((EFI_D_ERROR, "Create system table info guid hob\n")); // // Create guid hob for acpi board information // Status = CbParseFadtInfo (&PmCtrlRegBase, &PmTimerRegBase, &ResetRegAddress, &ResetValue, &PmEvtBase, &PmGpeEnBase); ASSERT_EFI_ERROR (Status); pAcpiBoardInfo = NULL; pAcpiBoardInfo = BuildGuidHob (&gUefiAcpiBoardInfoGuid, sizeof (ACPI_BOARD_INFO)); ASSERT (pAcpiBoardInfo != NULL); pAcpiBoardInfo->PmCtrlRegBase = (UINT64)PmCtrlRegBase; pAcpiBoardInfo->PmTimerRegBase = (UINT64)PmTimerRegBase; pAcpiBoardInfo->ResetRegAddress = (UINT64)ResetRegAddress; pAcpiBoardInfo->ResetValue = (UINT8)ResetValue; pAcpiBoardInfo->PmEvtBase = (UINT64)PmEvtBase; pAcpiBoardInfo->PmGpeEnBase = (UINT64)PmGpeEnBase; DEBUG ((EFI_D_ERROR, "Create acpi board info guid hob\n")); // // Create guid hob for frame buffer information // ZeroMem (&FbInfo, sizeof (FRAME_BUFFER_INFO)); Status = CbParseFbInfo (&FbInfo); if (!EFI_ERROR (Status)) { pFbInfo = BuildGuidHob (&gUefiFrameBufferInfoGuid, sizeof (FRAME_BUFFER_INFO)); ASSERT (pSystemTableInfo != NULL); CopyMem (pFbInfo, &FbInfo, sizeof (FRAME_BUFFER_INFO)); DEBUG ((EFI_D_ERROR, "Create frame buffer info guid hob\n")); } // // Parse platform specific information from coreboot. // Status = CbParsePlatformInfo (); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Error when parsing platform info, Status = %r\n", Status)); return Status; } return EFI_SUCCESS; }
/** Return the variable store header and the store info based on the Index. @param Type The type of the variable store. @param StoreInfo Return the store info. @return Pointer to the variable store header. **/ VARIABLE_STORE_HEADER * GetVariableStore ( IN VARIABLE_STORE_TYPE Type, OUT VARIABLE_STORE_INFO *StoreInfo ) { EFI_HOB_GUID_TYPE *GuidHob; EFI_FIRMWARE_VOLUME_HEADER *FvHeader; VARIABLE_STORE_HEADER *VariableStoreHeader; EFI_PHYSICAL_ADDRESS NvStorageBase; UINT32 NvStorageSize; FAULT_TOLERANT_WRITE_LAST_WRITE_DATA *FtwLastWriteData; UINT32 BackUpOffset; StoreInfo->IndexTable = NULL; StoreInfo->FtwLastWriteData = NULL; StoreInfo->AuthFlag = FALSE; VariableStoreHeader = NULL; switch (Type) { case VariableStoreTypeHob: GuidHob = GetFirstGuidHob (&gEfiAuthenticatedVariableGuid); if (GuidHob != NULL) { VariableStoreHeader = (VARIABLE_STORE_HEADER *) GET_GUID_HOB_DATA (GuidHob); StoreInfo->AuthFlag = TRUE; } else { GuidHob = GetFirstGuidHob (&gEfiVariableGuid); if (GuidHob != NULL) { VariableStoreHeader = (VARIABLE_STORE_HEADER *) GET_GUID_HOB_DATA (GuidHob); StoreInfo->AuthFlag = FALSE; } } break; case VariableStoreTypeNv: if (GetBootModeHob () != BOOT_IN_RECOVERY_MODE) { // // The content of NV storage for variable is not reliable in recovery boot mode. // NvStorageSize = PcdGet32 (PcdFlashNvStorageVariableSize); NvStorageBase = (EFI_PHYSICAL_ADDRESS) (PcdGet64 (PcdFlashNvStorageVariableBase64) != 0 ? PcdGet64 (PcdFlashNvStorageVariableBase64) : PcdGet32 (PcdFlashNvStorageVariableBase) ); // // First let FvHeader point to NV storage base. // FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) NvStorageBase; // // Check the FTW last write data hob. // BackUpOffset = 0; GuidHob = GetFirstGuidHob (&gEdkiiFaultTolerantWriteGuid); if (GuidHob != NULL) { FtwLastWriteData = (FAULT_TOLERANT_WRITE_LAST_WRITE_DATA *) GET_GUID_HOB_DATA (GuidHob); if (FtwLastWriteData->TargetAddress == NvStorageBase) { // // Let FvHeader point to spare block. // FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) FtwLastWriteData->SpareAddress; DEBUG ((EFI_D_INFO, "PeiVariable: NV storage is backed up in spare block: 0x%x\n", (UINTN) FtwLastWriteData->SpareAddress)); } else if ((FtwLastWriteData->TargetAddress > NvStorageBase) && (FtwLastWriteData->TargetAddress < (NvStorageBase + NvStorageSize))) { StoreInfo->FtwLastWriteData = FtwLastWriteData; // // Flash NV storage from the offset is backed up in spare block. // BackUpOffset = (UINT32) (FtwLastWriteData->TargetAddress - NvStorageBase); DEBUG ((EFI_D_INFO, "PeiVariable: High partial NV storage from offset: %x is backed up in spare block: 0x%x\n", BackUpOffset, (UINTN) FtwLastWriteData->SpareAddress)); // // At least one block data in flash NV storage is still valid, so still leave FvHeader point to NV storage base. // } } // // Check if the Firmware Volume is not corrupted // if ((FvHeader->Signature != EFI_FVH_SIGNATURE) || (!CompareGuid (&gEfiSystemNvDataFvGuid, &FvHeader->FileSystemGuid))) { DEBUG ((EFI_D_ERROR, "Firmware Volume for Variable Store is corrupted\n")); break; } VariableStoreHeader = (VARIABLE_STORE_HEADER *) ((UINT8 *) FvHeader + FvHeader->HeaderLength); StoreInfo->AuthFlag = (BOOLEAN) (CompareGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid)); GuidHob = GetFirstGuidHob (&gEfiVariableIndexTableGuid); if (GuidHob != NULL) { StoreInfo->IndexTable = GET_GUID_HOB_DATA (GuidHob); } else { // // If it's the first time to access variable region in flash, create a guid hob to record // VAR_ADDED type variable info. // Note that as the resource of PEI phase is limited, only store the limited number of // VAR_ADDED type variables to reduce access time. // StoreInfo->IndexTable = (VARIABLE_INDEX_TABLE *) BuildGuidHob (&gEfiVariableIndexTableGuid, sizeof (VARIABLE_INDEX_TABLE)); StoreInfo->IndexTable->Length = 0; StoreInfo->IndexTable->StartPtr = GetStartPointer (VariableStoreHeader); StoreInfo->IndexTable->EndPtr = GetEndPointer (VariableStoreHeader); StoreInfo->IndexTable->GoneThrough = 0; } } break; default: ASSERT (FALSE); break; } StoreInfo->VariableStoreHeader = VariableStoreHeader; return VariableStoreHeader; }