/** Fetch the number of boot CPUs from QEMU and expose it to UefiCpuPkg modules. Set the mMaxCpuCount variable. **/ VOID MaxCpuCountInitialization ( VOID ) { UINT16 ProcessorCount; RETURN_STATUS PcdStatus; QemuFwCfgSelectItem (QemuFwCfgItemSmpCpuCount); ProcessorCount = QemuFwCfgRead16 (); // // If the fw_cfg key or fw_cfg entirely is unavailable, load mMaxCpuCount // from the PCD default. No change to PCDs. // if (ProcessorCount == 0) { mMaxCpuCount = PcdGet32 (PcdCpuMaxLogicalProcessorNumber); return; } // // Otherwise, set mMaxCpuCount to the value reported by QEMU. // mMaxCpuCount = ProcessorCount; // // Additionally, tell UefiCpuPkg modules (a) the exact number of VCPUs, (b) // to wait, in the initial AP bringup, exactly as long as it takes for all of // the APs to report in. For this, we set the longest representable timeout // (approx. 71 minutes). // PcdStatus = PcdSet32S (PcdCpuMaxLogicalProcessorNumber, ProcessorCount); ASSERT_RETURN_ERROR (PcdStatus); PcdStatus = PcdSet32S (PcdCpuApInitTimeOutInMicroSeconds, MAX_UINT32); ASSERT_RETURN_ERROR (PcdStatus); DEBUG ((DEBUG_INFO, "%a: QEMU reports %d processor(s)\n", __FUNCTION__, ProcessorCount)); }
RETURN_STATUS EFIAPI ArmVirtTimerFdtClientLibConstructor ( VOID ) { EFI_STATUS Status; FDT_CLIENT_PROTOCOL *FdtClient; CONST INTERRUPT_PROPERTY *InterruptProp; UINT32 PropSize; INT32 SecIntrNum, IntrNum, VirtIntrNum, HypIntrNum; RETURN_STATUS PcdStatus; Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL, (VOID **)&FdtClient); ASSERT_EFI_ERROR (Status); Status = FdtClient->FindCompatibleNodeProperty (FdtClient, "arm,armv7-timer", "interrupts", (CONST VOID **)&InterruptProp, &PropSize); if (Status == EFI_NOT_FOUND) { Status = FdtClient->FindCompatibleNodeProperty (FdtClient, "arm,armv8-timer", "interrupts", (CONST VOID **)&InterruptProp, &PropSize); } if (EFI_ERROR (Status)) { return Status; } // // - interrupts : Interrupt list for secure, non-secure, virtual and // hypervisor timers, in that order. // ASSERT (PropSize == 36 || PropSize == 48); SecIntrNum = SwapBytes32 (InterruptProp[0].Number) + (InterruptProp[0].Type ? 16 : 0); IntrNum = SwapBytes32 (InterruptProp[1].Number) + (InterruptProp[1].Type ? 16 : 0); VirtIntrNum = SwapBytes32 (InterruptProp[2].Number) + (InterruptProp[2].Type ? 16 : 0); HypIntrNum = PropSize < 48 ? 0 : SwapBytes32 (InterruptProp[3].Number) + (InterruptProp[3].Type ? 16 : 0); DEBUG ((EFI_D_INFO, "Found Timer interrupts %d, %d, %d, %d\n", SecIntrNum, IntrNum, VirtIntrNum, HypIntrNum)); PcdStatus = PcdSet32S (PcdArmArchTimerSecIntrNum, SecIntrNum); ASSERT_RETURN_ERROR (PcdStatus); PcdStatus = PcdSet32S (PcdArmArchTimerIntrNum, IntrNum); ASSERT_RETURN_ERROR (PcdStatus); PcdStatus = PcdSet32S (PcdArmArchTimerVirtIntrNum, VirtIntrNum); ASSERT_RETURN_ERROR (PcdStatus); PcdStatus = PcdSet32S (PcdArmArchTimerHypIntrNum, HypIntrNum); ASSERT_RETURN_ERROR (PcdStatus); return EFI_SUCCESS; }
EFI_STATUS EFIAPI BoardDetectionCallback ( IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, IN VOID *Ppi ) { EFI_STATUS Status; VOID *Instance; DEBUG ((EFI_D_INFO, "Detecting Galileo ...\n")); // // Check if board detection is finished. // Status = PeiServicesLocatePpi ( &gBoardDetectedPpiGuid, 0, NULL, &Instance ); if (!EFI_ERROR(Status)) { return EFI_SUCCESS; } // // In most real platform, here should be the code to detect board type. // // For galileo, we only support build time board selection, so use PCD to do the fake detection. // if (PcdGet16(PcdPlatformType) != Galileo) { return EFI_UNSUPPORTED; } DEBUG ((EFI_D_INFO, "Detected Galileo!\n")); Status = PcdSet64S (PcdBoardInitPreMem, (UINT64)(UINTN)BoarInitPreMem); ASSERT_EFI_ERROR(Status); Status = PcdSet64S (PcdBoardInitPostMem, (UINT64)(UINTN)BoarInitPostMem); ASSERT_EFI_ERROR(Status); Status = PcdSet32S (PcdPciExpPerstResumeWellGpio, PCIEXP_PERST_RESUMEWELL_GPIO); ASSERT_EFI_ERROR(Status); Status = PcdSet32S (PcdFlashUpdateLedResumeWellGpio, GALILEO_FLASH_UPDATE_LED_RESUMEWELL_GPIO); ASSERT_EFI_ERROR(Status); Status = PeiServicesInstallPpi(&mDetectedPpi); ASSERT_EFI_ERROR(Status); return Status; }
RETURN_STATUS EFIAPI ArmVirtPL031FdtClientLibConstructor ( VOID ) { EFI_STATUS Status; FDT_CLIENT_PROTOCOL *FdtClient; INT32 Node; CONST UINT64 *Reg; UINT32 RegSize; UINT64 RegBase; RETURN_STATUS PcdStatus; Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL, (VOID **)&FdtClient); ASSERT_EFI_ERROR (Status); Status = FdtClient->FindCompatibleNode (FdtClient, "arm,pl031", &Node); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_WARN, "%a: No 'arm,pl031' compatible DT node found\n", __FUNCTION__)); return EFI_SUCCESS; } Status = FdtClient->GetNodeProperty (FdtClient, Node, "reg", (CONST VOID **)&Reg, &RegSize); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_WARN, "%a: No 'reg' property found in 'arm,pl031' compatible DT node\n", __FUNCTION__)); return EFI_SUCCESS; } ASSERT (RegSize == 16); RegBase = SwapBytes64 (Reg[0]); ASSERT (RegBase < MAX_UINT32); PcdStatus = PcdSet32S (PcdPL031RtcBase, (UINT32)RegBase); ASSERT_RETURN_ERROR (PcdStatus); DEBUG ((EFI_D_INFO, "Found PL031 RTC @ 0x%Lx\n", RegBase)); if (!FeaturePcdGet (PcdPureAcpiBoot)) { // // UEFI takes ownership of the RTC hardware, and exposes its functionality // through the UEFI Runtime Services GetTime, SetTime, etc. This means we // need to disable it in the device tree to prevent the OS from attaching // its device driver as well. // Status = FdtClient->SetNodeProperty (FdtClient, Node, "status", "disabled", sizeof ("disabled")); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_WARN, "Failed to set PL031 status to 'disabled'\n")); } } return EFI_SUCCESS; }
/** This service register Hash. @param HashInterface Hash interface @retval EFI_SUCCESS This hash interface is registered successfully. @retval EFI_UNSUPPORTED System does not support register this interface. @retval EFI_ALREADY_STARTED System already register this interface. **/ EFI_STATUS EFIAPI RegisterHashInterfaceLib ( IN HASH_INTERFACE *HashInterface ) { UINTN Index; HASH_INTERFACE_HOB *HashInterfaceHob; HASH_INTERFACE_HOB LocalHashInterfaceHob; UINT32 HashMask; UINT32 BiosSupportedHashMask; EFI_STATUS Status; // // Check allow // HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid); if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) { return EFI_UNSUPPORTED; } HashInterfaceHob = InternalGetHashInterface (); if (HashInterfaceHob == NULL) { ZeroMem (&LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob)); HashInterfaceHob = BuildGuidDataHob (&mHashLibPeiRouterGuid, &LocalHashInterfaceHob, sizeof(LocalHashInterfaceHob)); if (HashInterfaceHob == NULL) { return EFI_OUT_OF_RESOURCES; } } if (HashInterfaceHob->HashInterfaceCount >= HASH_COUNT) { return EFI_OUT_OF_RESOURCES; } BiosSupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap); Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, BiosSupportedHashMask | HashMask); ASSERT_EFI_ERROR (Status); // // Check duplication // for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) { if (CompareGuid (&HashInterfaceHob->HashInterface[Index].HashGuid, &HashInterface->HashGuid)) { // // In PEI phase, there will be shadow driver dispatched again. // DEBUG ((EFI_D_INFO, "RegisterHashInterfaceLib - Override\n")); CopyMem (&HashInterfaceHob->HashInterface[Index], HashInterface, sizeof(*HashInterface)); return EFI_SUCCESS; } } CopyMem (&HashInterfaceHob->HashInterface[HashInterfaceHob->HashInterfaceCount], HashInterface, sizeof(*HashInterface)); HashInterfaceHob->HashInterfaceCount ++; return EFI_SUCCESS; }
/** Update the Text Mode of Console. @param CallbackData The context data for BMM. @retval EFI_SUCCSS If the Text Mode of Console is updated. @return Other value if the Text Mode of Console is not updated. **/ EFI_STATUS Var_UpdateConMode ( IN BMM_CALLBACK_DATA *CallbackData ) { EFI_STATUS Status; UINTN Mode; CONSOLE_OUT_MODE ModeInfo; Mode = CallbackData->BmmFakeNvData.ConsoleOutMode; Status = gST->ConOut->QueryMode (gST->ConOut, Mode, &(ModeInfo.Column), &(ModeInfo.Row)); if (!EFI_ERROR(Status)) { Status = PcdSet32S (PcdSetupConOutColumn, (UINT32) ModeInfo.Column); if (!EFI_ERROR (Status)) { Status = PcdSet32S (PcdSetupConOutRow, (UINT32) ModeInfo.Row); } } return Status; }
/** Set Tpm2HashMask PCD value accroding to TPM2 PCR bank. **/ VOID SetTpm2HashMask ( VOID ) { EFI_STATUS Status; UINT32 ActivePcrBanks; TPML_PCR_SELECTION Pcrs; UINTN Index; DEBUG ((EFI_D_ERROR, "SetTpm2HashMask!\n")); Status = Tpm2GetCapabilityPcrs (&Pcrs); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "Tpm2GetCapabilityPcrs fail!\n")); ActivePcrBanks = EFI_TCG2_BOOT_HASH_ALG_SHA1; } else { DEBUG ((EFI_D_INFO, "Tpm2GetCapabilityPcrs Count - %08x\n", Pcrs.count)); ActivePcrBanks = 0; for (Index = 0; Index < Pcrs.count; Index++) { DEBUG ((EFI_D_INFO, "hash - %x\n", Pcrs.pcrSelections[Index].hash)); switch (Pcrs.pcrSelections[Index].hash) { case TPM_ALG_SHA1: if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) { ActivePcrBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA1; } break; case TPM_ALG_SHA256: if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) { ActivePcrBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA256; } break; case TPM_ALG_SHA384: if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) { ActivePcrBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA384; } break; case TPM_ALG_SHA512: if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) { ActivePcrBanks |= EFI_TCG2_BOOT_HASH_ALG_SHA512; } break; case TPM_ALG_SM3_256: if (!IsZeroBuffer (Pcrs.pcrSelections[Index].pcrSelect, Pcrs.pcrSelections[Index].sizeofSelect)) { ActivePcrBanks |= EFI_TCG2_BOOT_HASH_ALG_SM3_256; } break; } } } Status = PcdSet32S (PcdTpm2HashMask, ActivePcrBanks); ASSERT_EFI_ERROR (Status); }
/** This service register Hash. @param HashInterface Hash interface @retval EFI_SUCCESS This hash interface is registered successfully. @retval EFI_UNSUPPORTED System does not support register this interface. @retval EFI_ALREADY_STARTED System already register this interface. **/ EFI_STATUS EFIAPI RegisterHashInterfaceLib ( IN HASH_INTERFACE *HashInterface ) { UINTN Index; HASH_INTERFACE_HOB *HashInterfaceHob; UINT32 HashMask; EFI_STATUS Status; // // Check allow // HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid); if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) { return EFI_UNSUPPORTED; } HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid); if (HashInterfaceHob == NULL) { HashInterfaceHob = InternalCreateHashInterfaceHob (&gEfiCallerIdGuid); if (HashInterfaceHob == NULL) { return EFI_OUT_OF_RESOURCES; } } if (HashInterfaceHob->HashInterfaceCount >= HASH_COUNT) { return EFI_OUT_OF_RESOURCES; } // // Check duplication // for (Index = 0; Index < HashInterfaceHob->HashInterfaceCount; Index++) { if (CompareGuid (&HashInterfaceHob->HashInterface[Index].HashGuid, &HashInterface->HashGuid)) { DEBUG ((DEBUG_ERROR, "Hash Interface (%g) has been registered\n", &HashInterface->HashGuid)); return EFI_ALREADY_STARTED; } } // // Record hash algorithm bitmap of CURRENT module which consumes HashLib. // HashInterfaceHob->SupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap) | HashMask; Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, HashInterfaceHob->SupportedHashMask); ASSERT_EFI_ERROR (Status); CopyMem (&HashInterfaceHob->HashInterface[HashInterfaceHob->HashInterfaceCount], HashInterface, sizeof(*HashInterface)); HashInterfaceHob->HashInterfaceCount ++; return EFI_SUCCESS; }
/** The constructor function of HashLibBaseCryptoRouterPei. @param FileHandle The handle of FFS header the loaded driver. @param PeiServices The pointer to the PEI services. @retval EFI_SUCCESS The constructor executes successfully. @retval EFI_OUT_OF_RESOURCES There is no enough resource for the constructor. **/ EFI_STATUS EFIAPI HashLibBaseCryptoRouterPeiConstructor ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; HASH_INTERFACE_HOB *HashInterfaceHob; HashInterfaceHob = InternalGetHashInterfaceHob (&gZeroGuid); if (HashInterfaceHob == NULL) { // // No HOB with gZeroGuid Identifier has been created, // this is FIRST module which consumes HashLib. // Create the HOB with gZeroGuid Identifier. // HashInterfaceHob = InternalCreateHashInterfaceHob (&gZeroGuid); if (HashInterfaceHob == NULL) { return EFI_OUT_OF_RESOURCES; } } else { // // Record hash algorithm bitmap of LAST module which also consumes HashLib. // HashInterfaceHob->SupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap); } HashInterfaceHob = InternalGetHashInterfaceHob (&gEfiCallerIdGuid); if (HashInterfaceHob != NULL) { // // In PEI phase, some modules may call RegisterForShadow and will be // shadowed and executed again after memory is discovered. // This is the second execution of this module, clear the hash interface // information registered at its first execution. // ZeroMem (&HashInterfaceHob->HashInterface, sizeof (*HashInterfaceHob) - sizeof (EFI_GUID)); } // // Set PcdTcg2HashAlgorithmBitmap to 0 in CONSTRUCTOR for CURRENT module. // Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, 0); ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; }
/** This service register Hash. @param HashInterface Hash interface @retval EFI_SUCCESS This hash interface is registered successfully. @retval EFI_UNSUPPORTED System does not support register this interface. @retval EFI_ALREADY_STARTED System already register this interface. **/ EFI_STATUS EFIAPI RegisterHashInterfaceLib ( IN HASH_INTERFACE *HashInterface ) { UINTN Index; UINT32 HashMask; UINT32 BiosSupportedHashMask; EFI_STATUS Status; // // Check allow // HashMask = Tpm2GetHashMaskFromAlgo (&HashInterface->HashGuid); if ((HashMask & PcdGet32 (PcdTpm2HashMask)) == 0) { return EFI_UNSUPPORTED; } if (mHashInterfaceCount >= sizeof(mHashInterface)/sizeof(mHashInterface[0])) { return EFI_OUT_OF_RESOURCES; } BiosSupportedHashMask = PcdGet32 (PcdTcg2HashAlgorithmBitmap); Status = PcdSet32S (PcdTcg2HashAlgorithmBitmap, BiosSupportedHashMask | HashMask); ASSERT_EFI_ERROR (Status); // // Check duplication // for (Index = 0; Index < mHashInterfaceCount; Index++) { if (CompareGuid (&mHashInterface[Index].HashGuid, &HashInterface->HashGuid)) { return EFI_ALREADY_STARTED; } } CopyMem (&mHashInterface[mHashInterfaceCount], HashInterface, sizeof(*HashInterface)); mHashInterfaceCount ++; return EFI_SUCCESS; }
/** 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; }
/** This function will change video resolution and text mode according to defined setup mode or defined boot mode @param IsSetupMode Indicate mode is changed to setup mode or boot mode. @retval EFI_SUCCESS Mode is changed successfully. @retval Others Mode failed to be changed. **/ EFI_STATUS EFIAPI BmBdsSetConsoleMode ( BOOLEAN IsSetupMode ) { EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut; UINTN SizeOfInfo; EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; UINT32 MaxGopMode; UINT32 MaxTextMode; UINT32 ModeNumber; UINT32 NewHorizontalResolution; UINT32 NewVerticalResolution; UINT32 NewColumns; UINT32 NewRows; UINTN HandleCount; EFI_HANDLE *HandleBuffer; EFI_STATUS Status; UINTN Index; UINTN CurrentColumn; UINTN CurrentRow; MaxGopMode = 0; MaxTextMode = 0; // // Get current video resolution and text mode // Status = gBS->HandleProtocol ( gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid, (VOID**)&GraphicsOutput ); if (EFI_ERROR (Status)) { GraphicsOutput = NULL; } Status = gBS->HandleProtocol ( gST->ConsoleOutHandle, &gEfiSimpleTextOutProtocolGuid, (VOID**)&SimpleTextOut ); if (EFI_ERROR (Status)) { SimpleTextOut = NULL; } if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) { return EFI_UNSUPPORTED; } if (IsSetupMode) { // // The requried resolution and text mode is setup mode. // NewHorizontalResolution = mBmSetupHorizontalResolution; NewVerticalResolution = mBmSetupVerticalResolution; NewColumns = mBmSetupTextModeColumn; NewRows = mBmSetupTextModeRow; } else { // // The required resolution and text mode is boot mode. // NewHorizontalResolution = mBmBootHorizontalResolution; NewVerticalResolution = mBmBootVerticalResolution; NewColumns = mBmBootTextModeColumn; NewRows = mBmBootTextModeRow; } if (GraphicsOutput != NULL) { MaxGopMode = GraphicsOutput->Mode->MaxMode; } if (SimpleTextOut != NULL) { MaxTextMode = SimpleTextOut->Mode->MaxMode; } // // 1. If current video resolution is same with required video resolution, // video resolution need not be changed. // 1.1. If current text mode is same with required text mode, text mode need not be changed. // 1.2. If current text mode is different from required text mode, text mode need be changed. // 2. If current video resolution is different from required video resolution, we need restart whole console drivers. // for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) { Status = GraphicsOutput->QueryMode ( GraphicsOutput, ModeNumber, &SizeOfInfo, &Info ); if (!EFI_ERROR (Status)) { if ((Info->HorizontalResolution == NewHorizontalResolution) && (Info->VerticalResolution == NewVerticalResolution)) { if ((GraphicsOutput->Mode->Info->HorizontalResolution == NewHorizontalResolution) && (GraphicsOutput->Mode->Info->VerticalResolution == NewVerticalResolution)) { // // Current resolution is same with required resolution, check if text mode need be set // Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow); ASSERT_EFI_ERROR (Status); if (CurrentColumn == NewColumns && CurrentRow == NewRows) { // // If current text mode is same with required text mode. Do nothing // FreePool (Info); return EFI_SUCCESS; } else { // // If current text mode is different from requried text mode. Set new video mode // for (Index = 0; Index < MaxTextMode; Index++) { Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow); if (!EFI_ERROR(Status)) { if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) { // // Required text mode is supported, set it. // Status = SimpleTextOut->SetMode (SimpleTextOut, Index); ASSERT_EFI_ERROR (Status); // // Update text mode PCD. // Status = PcdSet32S (PcdConOutColumn, mBmSetupTextModeColumn); ASSERT_EFI_ERROR (Status); Status = PcdSet32S (PcdConOutRow, mBmSetupTextModeRow); ASSERT_EFI_ERROR (Status); FreePool (Info); return EFI_SUCCESS; } } } if (Index == MaxTextMode) { // // If requried text mode is not supported, return error. // FreePool (Info); return EFI_UNSUPPORTED; } } } else { // // If current video resolution is not same with the new one, set new video resolution. // In this case, the driver which produces simple text out need be restarted. // Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber); if (!EFI_ERROR (Status)) { FreePool (Info); break; } } } FreePool (Info); } } if (ModeNumber == MaxGopMode) { // // If the resolution is not supported, return error. // return EFI_UNSUPPORTED; } // // Set PCD to Inform GraphicsConsole to change video resolution. // Set PCD to Inform Consplitter to change text mode. // Status = PcdSet32S (PcdVideoHorizontalResolution, NewHorizontalResolution); ASSERT_EFI_ERROR (Status); Status = PcdSet32S (PcdVideoVerticalResolution, NewVerticalResolution); ASSERT_EFI_ERROR (Status); Status = PcdSet32S (PcdConOutColumn, NewColumns); ASSERT_EFI_ERROR (Status); Status = PcdSet32S (PcdConOutRow, NewRows); ASSERT_EFI_ERROR (Status); // // Video mode is changed, so restart graphics console driver and higher level driver. // Reconnect graphics console driver and higher level driver. // Locate all the handles with GOP protocol and reconnect it. // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiSimpleTextOutProtocolGuid, NULL, &HandleCount, &HandleBuffer ); if (!EFI_ERROR (Status)) { for (Index = 0; Index < HandleCount; Index++) { gBS->DisconnectController (HandleBuffer[Index], NULL, NULL); } for (Index = 0; Index < HandleCount; Index++) { gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE); } if (HandleBuffer != NULL) { FreePool (HandleBuffer); } } return EFI_SUCCESS; }
/** Main entry point. @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS Successfully initialized. **/ EFI_STATUS EFIAPI FvbInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; VOID *Ptr; VOID *SubPtr; BOOLEAN Initialize; EFI_HANDLE Handle; EFI_PHYSICAL_ADDRESS Address; RETURN_STATUS PcdStatus; DEBUG ((EFI_D_INFO, "EMU Variable FVB Started\n")); // // Verify that the PCD's are set correctly. // if ( (PcdGet32 (PcdVariableStoreSize) + PcdGet32 (PcdFlashNvStorageFtwWorkingSize) ) > EMU_FVB_BLOCK_SIZE ) { DEBUG ((EFI_D_ERROR, "EMU Variable invalid PCD sizes\n")); return EFI_INVALID_PARAMETER; } if (PcdGet64 (PcdFlashNvStorageVariableBase64) != 0) { DEBUG ((EFI_D_INFO, "Disabling EMU Variable FVB since " "flash variables appear to be supported.\n")); return EFI_ABORTED; } // // By default we will initialize the FV contents. But, if // PcdEmuVariableNvStoreReserved is non-zero, then we will // use this location for our buffer. // // If this location does not have a proper FV header, then // we will initialize it. // Initialize = TRUE; if (PcdGet64 (PcdEmuVariableNvStoreReserved) != 0) { Ptr = (VOID*)(UINTN) PcdGet64 (PcdEmuVariableNvStoreReserved); DEBUG (( EFI_D_INFO, "EMU Variable FVB: Using pre-reserved block at %p\n", Ptr )); Status = ValidateFvHeader (Ptr); if (!EFI_ERROR (Status)) { DEBUG ((EFI_D_INFO, "EMU Variable FVB: Found valid pre-existing FV\n")); Initialize = FALSE; } } else { Ptr = AllocateAlignedRuntimePages ( EFI_SIZE_TO_PAGES (EMU_FVB_SIZE), SIZE_64KB ); } mEmuVarsFvb.BufferPtr = Ptr; // // Initialize the main FV header and variable store header // if (Initialize) { SetMem (Ptr, EMU_FVB_SIZE, ERASED_UINT8); InitializeFvAndVariableStoreHeaders (Ptr); } PcdStatus = PcdSet64S (PcdFlashNvStorageVariableBase64, (UINT32)(UINTN) Ptr); ASSERT_RETURN_ERROR (PcdStatus); // // Initialize the Fault Tolerant Write data area // SubPtr = (VOID*) ((UINT8*) Ptr + PcdGet32 (PcdVariableStoreSize)); PcdStatus = PcdSet32S (PcdFlashNvStorageFtwWorkingBase, (UINT32)(UINTN) SubPtr); ASSERT_RETURN_ERROR (PcdStatus); // // Initialize the Fault Tolerant Write spare block // SubPtr = (VOID*) ((UINT8*) Ptr + EMU_FVB_BLOCK_SIZE); PcdStatus = PcdSet32S (PcdFlashNvStorageFtwSpareBase, (UINT32)(UINTN) SubPtr); ASSERT_RETURN_ERROR (PcdStatus); // // Setup FVB device path // Address = (EFI_PHYSICAL_ADDRESS)(UINTN) Ptr; mEmuVarsFvb.DevicePath.MemMapDevPath.StartingAddress = Address; mEmuVarsFvb.DevicePath.MemMapDevPath.EndingAddress = Address + EMU_FVB_SIZE - 1; // // Install the protocols // DEBUG ((EFI_D_INFO, "Installing FVB for EMU Variable support\n")); Handle = 0; Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiFirmwareVolumeBlock2ProtocolGuid, &mEmuVarsFvb.FwVolBlockInstance, &gEfiDevicePathProtocolGuid, &mEmuVarsFvb.DevicePath, NULL ); ASSERT_EFI_ERROR (Status); // // Register for the virtual address change event // Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, FvbVirtualAddressChangeEvent, NULL, &gEfiEventVirtualAddressChangeGuid, &mEmuVarsFvbAddrChangeEvent ); ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; }
/** Make sure that the current PCR allocations, the TPM supported PCRs, and the PcdTpm2HashMask are all in agreement. **/ VOID SyncPcrAllocationsAndPcrMask ( VOID ) { EFI_STATUS Status; EFI_TCG2_EVENT_ALGORITHM_BITMAP TpmHashAlgorithmBitmap; UINT32 TpmActivePcrBanks; UINT32 NewTpmActivePcrBanks; UINT32 Tpm2PcrMask; UINT32 NewTpm2PcrMask; DEBUG ((EFI_D_ERROR, "SyncPcrAllocationsAndPcrMask!\n")); // // Determine the current TPM support and the Platform PCR mask. // Status = Tpm2GetCapabilitySupportedAndActivePcrs (&TpmHashAlgorithmBitmap, &TpmActivePcrBanks); ASSERT_EFI_ERROR (Status); Tpm2PcrMask = PcdGet32 (PcdTpm2HashMask); // // Find the intersection of Pcd support and TPM support. // If banks are missing from the TPM support that are in the PCD, update the PCD. // If banks are missing from the PCD that are active in the TPM, reallocate the banks and reboot. // // // If there are active PCR banks that are not supported by the Platform mask, // update the TPM allocations and reboot the machine. // if ((TpmActivePcrBanks & Tpm2PcrMask) != TpmActivePcrBanks) { NewTpmActivePcrBanks = TpmActivePcrBanks & Tpm2PcrMask; DEBUG ((EFI_D_INFO, "%a - Reallocating PCR banks from 0x%X to 0x%X.\n", __FUNCTION__, TpmActivePcrBanks, NewTpmActivePcrBanks)); if (NewTpmActivePcrBanks == 0) { DEBUG ((EFI_D_ERROR, "%a - No viable PCRs active! Please set a less restrictive value for PcdTpm2HashMask!\n", __FUNCTION__)); ASSERT (FALSE); } else { Status = Tpm2PcrAllocateBanks (NULL, (UINT32)TpmHashAlgorithmBitmap, NewTpmActivePcrBanks); if (EFI_ERROR (Status)) { // // We can't do much here, but we hope that this doesn't happen. // DEBUG ((EFI_D_ERROR, "%a - Failed to reallocate PCRs!\n", __FUNCTION__)); ASSERT_EFI_ERROR (Status); } // // Need reset system, since we just called Tpm2PcrAllocateBanks(). // ResetCold(); } } // // If there are any PCRs that claim support in the Platform mask that are // not supported by the TPM, update the mask. // if ((Tpm2PcrMask & TpmHashAlgorithmBitmap) != Tpm2PcrMask) { NewTpm2PcrMask = Tpm2PcrMask & TpmHashAlgorithmBitmap; DEBUG ((EFI_D_INFO, "%a - Updating PcdTpm2HashMask from 0x%X to 0x%X.\n", __FUNCTION__, Tpm2PcrMask, NewTpm2PcrMask)); if (NewTpm2PcrMask == 0) { DEBUG ((EFI_D_ERROR, "%a - No viable PCRs supported! Please set a less restrictive value for PcdTpm2HashMask!\n", __FUNCTION__)); ASSERT (FALSE); } Status = PcdSet32S (PcdTpm2HashMask, NewTpm2PcrMask); ASSERT_EFI_ERROR (Status); } }
/** Main entry for the Coreboot Support DXE module. @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The entry point is executed successfully. @retval other Some error occurs when executing this entry point. **/ EFI_STATUS EFIAPI CbDxeEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_HOB_GUID_TYPE *GuidHob; SYSTEM_TABLE_INFO *pSystemTableInfo; FRAME_BUFFER_INFO *FbInfo; Status = EFI_SUCCESS; // // Report MMIO/IO Resources // Status = CbReserveResourceInGcd (TRUE, EfiGcdMemoryTypeMemoryMappedIo, 0xFEC00000, SIZE_4KB, 0, SystemTable); // IOAPIC ASSERT_EFI_ERROR (Status); Status = CbReserveResourceInGcd (TRUE, EfiGcdMemoryTypeMemoryMappedIo, 0xFED00000, SIZE_1KB, 0, SystemTable); // HPET ASSERT_EFI_ERROR (Status); // // Find the system table information guid hob // GuidHob = GetFirstGuidHob (&gUefiSystemTableInfoGuid); ASSERT (GuidHob != NULL); pSystemTableInfo = (SYSTEM_TABLE_INFO *)GET_GUID_HOB_DATA (GuidHob); // // Install Acpi Table // if (pSystemTableInfo->AcpiTableBase != 0 && pSystemTableInfo->AcpiTableSize != 0) { DEBUG ((EFI_D_ERROR, "Install Acpi Table at 0x%lx, length 0x%x\n", pSystemTableInfo->AcpiTableBase, pSystemTableInfo->AcpiTableSize)); Status = gBS->InstallConfigurationTable (&gEfiAcpiTableGuid, (VOID *)(UINTN)pSystemTableInfo->AcpiTableBase); ASSERT_EFI_ERROR (Status); } // // Install Smbios Table // if (pSystemTableInfo->SmbiosTableBase != 0 && pSystemTableInfo->SmbiosTableSize != 0) { DEBUG ((EFI_D_ERROR, "Install Smbios Table at 0x%lx, length 0x%x\n", pSystemTableInfo->SmbiosTableBase, pSystemTableInfo->SmbiosTableSize)); Status = gBS->InstallConfigurationTable (&gEfiSmbiosTableGuid, (VOID *)(UINTN)pSystemTableInfo->SmbiosTableBase); ASSERT_EFI_ERROR (Status); } // // Find the frame buffer information and update PCDs // GuidHob = GetFirstGuidHob (&gUefiFrameBufferInfoGuid); if (GuidHob != NULL) { FbInfo = (FRAME_BUFFER_INFO *)GET_GUID_HOB_DATA (GuidHob); Status = PcdSet32S (PcdVideoHorizontalResolution, FbInfo->HorizontalResolution); ASSERT_EFI_ERROR (Status); Status = PcdSet32S (PcdVideoVerticalResolution, FbInfo->VerticalResolution); ASSERT_EFI_ERROR (Status); Status = PcdSet32S (PcdSetupVideoHorizontalResolution, FbInfo->HorizontalResolution); ASSERT_EFI_ERROR (Status); Status = PcdSet32S (PcdSetupVideoVerticalResolution, FbInfo->VerticalResolution); ASSERT_EFI_ERROR (Status); } return EFI_SUCCESS; }
EFI_STATUS VBoxVgaGraphicsOutputConstructor ( VBOX_VGA_PRIVATE_DATA *Private ) { EFI_STATUS Status; EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; UINT32 Index; UINT32 HorizontalResolution = 1024; UINT32 VerticalResolution = 768; UINT32 ColorDepth = 32; DEBUG((DEBUG_INFO, "%a:%d construct\n", __FILE__, __LINE__)); GraphicsOutput = &Private->GraphicsOutput; GraphicsOutput->QueryMode = VBoxVgaGraphicsOutputQueryMode; GraphicsOutput->SetMode = VBoxVgaGraphicsOutputSetMode; GraphicsOutput->Blt = VBoxVgaGraphicsOutputBlt; // // Initialize the private data // Status = gBS->AllocatePool ( EfiBootServicesData, sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE), (VOID **) &Private->GraphicsOutput.Mode ); if (EFI_ERROR (Status)) { return Status; } Status = gBS->AllocatePool ( EfiBootServicesData, sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), (VOID **) &Private->GraphicsOutput.Mode->Info ); if (EFI_ERROR (Status)) { return Status; } Private->GraphicsOutput.Mode->MaxMode = (UINT32) Private->MaxMode; Private->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER; Private->HardwareNeedsStarting = TRUE; // // Initialize the hardware // VBoxVgaGetVmVariable(EFI_INFO_INDEX_HORIZONTAL_RESOLUTION, (CHAR8 *)&HorizontalResolution, sizeof(HorizontalResolution)); VBoxVgaGetVmVariable(EFI_INFO_INDEX_VERTICAL_RESOLUTION, (CHAR8 *)&VerticalResolution, sizeof(VerticalResolution)); for (Index = 0; Index < Private->MaxMode; Index++) { if ( HorizontalResolution == Private->ModeData[Index].HorizontalResolution && VerticalResolution == Private->ModeData[Index].VerticalResolution && ColorDepth == Private->ModeData[Index].ColorDepth) break; } // not found? try mode number if (Index >= Private->MaxMode) { VBoxVgaGetVmVariable(EFI_INFO_INDEX_GRAPHICS_MODE, (CHAR8 *)&Index, sizeof(Index)); // try with mode 2 (usually 1024x768) as a fallback if (Index >= Private->MaxMode) Index = 2; // try with mode 0 (usually 640x480) as a fallback if (Index >= Private->MaxMode) Index = 0; } // skip mode setting completely if there is no valid mode if (Index >= Private->MaxMode) return EFI_UNSUPPORTED; GraphicsOutput->SetMode (GraphicsOutput, Index); DrawLogo ( Private, Private->ModeData[Private->GraphicsOutput.Mode->Mode].HorizontalResolution, Private->ModeData[Private->GraphicsOutput.Mode->Mode].VerticalResolution ); PcdSet32S(PcdVideoHorizontalResolution, Private->ModeData[Private->GraphicsOutput.Mode->Mode].HorizontalResolution); PcdSet32S(PcdVideoVerticalResolution, Private->ModeData[Private->GraphicsOutput.Mode->Mode].VerticalResolution); return EFI_SUCCESS; }