/** Load and execute the platform configuration. @retval EFI_SUCCESS Configuration loaded and executed. @return Status codes from PlatformConfigLoad(). **/ STATIC EFI_STATUS EFIAPI ExecutePlatformConfig ( VOID ) { EFI_STATUS Status; PLATFORM_CONFIG PlatformConfig; UINT64 OptionalElements; Status = PlatformConfigLoad (&PlatformConfig, &OptionalElements); if (EFI_ERROR (Status)) { DEBUG (((Status == EFI_NOT_FOUND) ? EFI_D_VERBOSE : EFI_D_ERROR, "%a: failed to load platform config: %r\n", __FUNCTION__, Status)); return Status; } if (OptionalElements & PLATFORM_CONFIG_F_GRAPHICS_RESOLUTION) { // // Pass the preferred resolution to GraphicsConsoleDxe via dynamic PCDs. // PcdSet32 (PcdVideoHorizontalResolution, PlatformConfig.HorizontalResolution); PcdSet32 (PcdVideoVerticalResolution, PlatformConfig.VerticalResolution); } return EFI_SUCCESS; }
EFI_STATUS EFIAPI PeimInitializeFlashMap ( IN EFI_FFS_FILE_HEADER *FfsHeader, IN EFI_PEI_SERVICES **PeiServices ) /*++ Routine Description: Build GUIDed HOBs for platform specific flash map Arguments: FfsHeader - A pointer to the EFI_FFS_FILE_HEADER structure. PeiServices - General purpose services available to every PEIM. Returns: EFI_STATUS --*/ // TODO: EFI_SUCCESS - add return value to function comment { EFI_STATUS Status; NT_FWH_PPI *NtFwhPpi; EFI_PHYSICAL_ADDRESS FdBase; UINT64 FdSize; EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor; DEBUG ((EFI_D_ERROR, "NT 32 Flash Map PEIM Loaded\n")); // // Get the Fwh Information PPI // Status = PeiServicesLocatePpi ( &gNtFwhPpiGuid, // GUID 0, // INSTANCE &PpiDescriptor, // EFI_PEI_PPI_DESCRIPTOR (VOID**)&NtFwhPpi // PPI ); ASSERT_EFI_ERROR (Status); // // Assume that FD0 contains the Flash map. // Status = NtFwhPpi->NtFwh (0, &FdBase, &FdSize); if (EFI_ERROR (Status)) { return Status; } // // Relocate the base of FV region // PcdSet32 (PcdFlashNvStorageVariableBase, PcdGet32 (PcdWinNtFlashNvStorageVariableBase) + (UINT32) FdBase); PcdSet32 (PcdFlashNvStorageFtwWorkingBase, PcdGet32 (PcdWinNtFlashNvStorageFtwWorkingBase) + (UINT32) FdBase); PcdSet32 (PcdFlashNvStorageFtwSpareBase, PcdGet32 (PcdWinNtFlashNvStorageFtwSpareBase) + (UINT32) FdBase); return EFI_SUCCESS; }
/** Configures Processor Feature Lists for XD feature for all processors. This function configures Processor Feature Lists for XD feature for all processors. **/ VOID XdConfigFeatureList ( VOID ) { UINTN ProcessorNumber; BOOLEAN XdSupported; BOOLEAN Setting; XdSupported = TRUE; Setting = FALSE; // // Check whether all logical processors support XD // for (ProcessorNumber = 0; ProcessorNumber < mCpuConfigConextBuffer.NumberOfProcessors; ProcessorNumber++) { if (!GetProcessorFeatureCapability (ProcessorNumber, ExecuteDisableBit, NULL)) { XdSupported = FALSE; break; } } if (XdSupported) { // // Set the bit of XD capability // PcdSet32 (PcdCpuProcessorFeatureCapability, PcdGet32 (PcdCpuProcessorFeatureCapability) | PCD_CPU_EXECUTE_DISABLE_BIT); // // Checks whether user indicates to enable XD // if ((PcdGet32 (PcdCpuProcessorFeatureUserConfiguration) & PCD_CPU_EXECUTE_DISABLE_BIT) != 0) { // // Set the bit of XD setting // PcdSet32 (PcdCpuProcessorFeatureSetting, PcdGet32 (PcdCpuProcessorFeatureSetting) | PCD_CPU_EXECUTE_DISABLE_BIT); Setting = TRUE; } } // // If XD is not supported by all logical processors, or user indicates to disable XD, then disable XD on all processors. // for (ProcessorNumber = 0; ProcessorNumber < mCpuConfigConextBuffer.NumberOfProcessors; ProcessorNumber++) { // // The operation can only be performed on the processors supporting XD feature. // if (GetProcessorFeatureCapability (ProcessorNumber, ExecuteDisableBit, NULL)) { EnableExecuteDisableBit[ProcessorNumber] = Setting; AppendProcessorFeatureIntoList (ProcessorNumber, ExecuteDisableBit, &(EnableExecuteDisableBit[ProcessorNumber])); } } }
/** 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)) { PcdSet32 (PcdSetupConOutColumn, (UINT32) ModeInfo.Column); PcdSet32 (PcdSetupConOutRow, (UINT32) ModeInfo.Row); } return EFI_SUCCESS; }
/** Configures Processor Feature Lists for Max CPUID Limit feature for all processors. This function configures Processor Feature Lists for Max CPUID Limit feature for all processors. **/ VOID MaxCpuidLimitConfigFeatureList ( VOID ) { UINTN ProcessorNumber; BOOLEAN UserConfigurationSet; UserConfigurationSet = FALSE; if ((PcdGet32 (PcdCpuProcessorFeatureUserConfiguration) & PCD_CPU_MAX_CPUID_VALUE_LIMIT_BIT) != 0) { UserConfigurationSet = TRUE; } for (ProcessorNumber = 0; ProcessorNumber < mCpuConfigConextBuffer.NumberOfProcessors; ProcessorNumber++) { // // Check whether this logical processor supports Max CPUID Value Limit // if (GetProcessorFeatureCapability (ProcessorNumber, MaxCpuidValueLimit, NULL)) { if (ProcessorNumber == mCpuConfigConextBuffer.BspNumber) { // // Set the bit of Max CPUID Value Limit capability according to BSP capability. // PcdSet32 (PcdCpuProcessorFeatureCapability, PcdGet32 (PcdCpuProcessorFeatureCapability) | PCD_CPU_MAX_CPUID_VALUE_LIMIT_BIT); // // Set the bit of Max CPUID Value Limit setting according to BSP setting. // if (UserConfigurationSet) { PcdSet32 (PcdCpuProcessorFeatureSetting, PcdGet32 (PcdCpuProcessorFeatureSetting) | PCD_CPU_MAX_CPUID_VALUE_LIMIT_BIT); } } // // If this logical processor supports Max CPUID Value Limit, then add feature into feature list for operation // on corresponding register. // EnableLimitCpuIdValue[ProcessorNumber] = UserConfigurationSet; AppendProcessorFeatureIntoList (ProcessorNumber, MaxCpuidValueLimit, &(EnableLimitCpuIdValue[ProcessorNumber])); } } }
/** *--------------------------------------------------------------------------------------- * PlatInitPeiEntryPoint * * Description: * Entry point of the PlatInit PEI module. * * Control flow: * Query platform parameters via ISCP. * * Parameters: * @param[in] FfsHeader EFI_PEI_FILE_HANDLE * @param[in] **PeiServices Pointer to the PEI Services Table. * * @return EFI_STATUS * *--------------------------------------------------------------------------------------- */ EFI_STATUS EFIAPI PlatInitPeiEntryPoint ( IN EFI_PEI_FILE_HANDLE FfsHeader, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status = EFI_SUCCESS; AMD_MEMORY_RANGE_DESCRIPTOR IscpMemDescriptor = {0}; ISCP_FUSE_INFO IscpFuseInfo = {0}; ISCP_CPU_RESET_INFO CpuResetInfo = {0}; #if DO_XGBE == 1 ISCP_MAC_INFO MacAddrInfo = {0}; UINT64 MacAddr0, MacAddr1; #endif UINTN CpuCoreCount, CpuMap, CpuMapSize; UINTN Index, CoreNum; UINT32 *CpuIdReg = (UINT32 *)FixedPcdGet32 (PcdCpuIdRegister); DEBUG ((EFI_D_ERROR, "PlatInit PEIM Loaded\n")); // CPUID PcdSet32 (PcdSocCpuId, *CpuIdReg); DEBUG ((EFI_D_ERROR, "SocCpuId = 0x%X\n", PcdGet32 (PcdSocCpuId))); // Update core count based on PCD option if (mAmdCoreCount > PcdGet32 (PcdSocCoreCount)) { mAmdCoreCount = PcdGet32 (PcdSocCoreCount); } if (FixedPcdGetBool (PcdIscpSupport)) { Status = PeiServicesLocatePpi (&gPeiIscpPpiGuid, 0, NULL, (VOID**)&PeiIscpPpi); ASSERT_EFI_ERROR (Status); // Get fuse information from ISCP Status = PeiIscpPpi->ExecuteFuseTransaction (PeiServices, &IscpFuseInfo); ASSERT_EFI_ERROR (Status); CpuMap = IscpFuseInfo.SocConfiguration.CpuMap; CpuCoreCount = IscpFuseInfo.SocConfiguration.CpuCoreCount; CpuMapSize = sizeof (IscpFuseInfo.SocConfiguration.CpuMap) * 8; ASSERT (CpuMap != 0); ASSERT (CpuCoreCount != 0); ASSERT (CpuCoreCount <= CpuMapSize); // Update core count based on fusing if (mAmdCoreCount > CpuCoreCount) { mAmdCoreCount = CpuCoreCount; } } // // Update per-core information from ISCP // if (!FixedPcdGetBool (PcdIscpSupport)) { DEBUG ((EFI_D_ERROR, "Warning: Could not get CPU info via ISCP, using default values.\n")); } else { // // Walk CPU map to enumerate active cores // for (CoreNum = 0, Index = 0; CoreNum < CpuMapSize && Index < mAmdCoreCount; ++CoreNum) { if (CpuMap & 1) { CpuResetInfo.CoreNum = CoreNum; Status = PeiIscpPpi->ExecuteCpuRetrieveIdTransaction ( PeiServices, &CpuResetInfo ); ASSERT_EFI_ERROR (Status); ASSERT (CpuResetInfo.CoreStatus.Status != CPU_CORE_DISABLED); ASSERT (CpuResetInfo.CoreStatus.Status != CPU_CORE_UNDEFINED); mAmdMpCoreInfoTable[Index].ClusterId = CpuResetInfo.CoreStatus.ClusterId; mAmdMpCoreInfoTable[Index].CoreId = CpuResetInfo.CoreStatus.CoreId; DEBUG ((EFI_D_ERROR, "Core[%d]: ClusterId = %d CoreId = %d\n", Index, mAmdMpCoreInfoTable[Index].ClusterId, mAmdMpCoreInfoTable[Index].CoreId)); // Next core in Table ++Index; } // Next core in Map CpuMap >>= 1; } // Update core count based on CPU map if (mAmdCoreCount > Index) { mAmdCoreCount = Index; } } // Update SocCoreCount on Dynamic PCD if (PcdGet32 (PcdSocCoreCount) != mAmdCoreCount) { PcdSet32 (PcdSocCoreCount, mAmdCoreCount); } DEBUG ((EFI_D_ERROR, "SocCoreCount = %d\n", PcdGet32 (PcdSocCoreCount))); // Build AmdMpCoreInfo HOB BuildGuidDataHob (&gAmdStyxMpCoreInfoGuid, mAmdMpCoreInfoTable, sizeof (ARM_CORE_INFO) * mAmdCoreCount); // Get SystemMemorySize from ISCP IscpMemDescriptor.Size0 = 0; if (FixedPcdGetBool (PcdIscpSupport)) { Status = PeiIscpPpi->ExecuteMemoryTransaction (PeiServices, &IscpMemDescriptor); ASSERT_EFI_ERROR (Status); // Update SystemMemorySize on Dynamic PCD if (IscpMemDescriptor.Size0) { PcdSet64 (PcdSystemMemorySize, IscpMemDescriptor.Size0); } } if (IscpMemDescriptor.Size0 == 0) { DEBUG ((EFI_D_ERROR, "Warning: Could not get SystemMemorySize via ISCP, using default value.\n")); } DEBUG ((EFI_D_ERROR, "SystemMemorySize = %ld\n", PcdGet64 (PcdSystemMemorySize))); #if DO_XGBE == 1 // Get MAC Address from ISCP if (FixedPcdGetBool (PcdIscpSupport)) { Status = PeiIscpPpi->ExecuteGetMacAddressTransaction ( PeiServices, &MacAddrInfo ); ASSERT_EFI_ERROR (Status); MacAddr0 = MacAddr1 = 0; for (Index = 0; Index < 6; ++Index) { MacAddr0 |= (UINT64)MacAddrInfo.MacAddress0[Index] << (Index * 8); MacAddr1 |= (UINT64)MacAddrInfo.MacAddress1[Index] << (Index * 8); } PcdSet64 (PcdEthMacA, MacAddr0); PcdSet64 (PcdEthMacB, MacAddr1); } DEBUG ((EFI_D_ERROR, "EthMacA = 0x%lX\n", PcdGet64 (PcdEthMacA))); DEBUG ((EFI_D_ERROR, "EthMacB = 0x%lX\n", PcdGet64 (PcdEthMacB))); #endif // Let other PEI modules know we're done! Status = (*PeiServices)->InstallPpi (PeiServices, &mPlatInitPpiDescriptor); ASSERT_EFI_ERROR (Status); return Status; }
/** 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 BdsSetConsoleMode ( 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 = mSetupHorizontalResolution; NewVerticalResolution = mSetupVerticalResolution; NewColumns = mSetupTextModeColumn; NewRows = mSetupTextModeRow; } else { // // The required resolution and text mode is boot mode. // NewHorizontalResolution = mBootHorizontalResolution; NewVerticalResolution = mBootVerticalResolution; NewColumns = mBootTextModeColumn; NewRows = mBootTextModeRow; } 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. // PcdSet32 (PcdConOutColumn, mSetupTextModeColumn); PcdSet32 (PcdConOutRow, mSetupTextModeRow); 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. // PcdSet32 (PcdVideoHorizontalResolution, NewHorizontalResolution); PcdSet32 (PcdVideoVerticalResolution, NewVerticalResolution); PcdSet32 (PcdConOutColumn, NewColumns); PcdSet32 (PcdConOutRow, NewRows); // // 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; }
/** 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; }
/** 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; 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); } PcdSet64 (PcdFlashNvStorageVariableBase64, (UINT32)(UINTN) Ptr); // // Initialize the Fault Tolerant Write data area // SubPtr = (VOID*) ((UINT8*) Ptr + PcdGet32 (PcdVariableStoreSize)); PcdSet32 (PcdFlashNvStorageFtwWorkingBase, (UINT32)(UINTN) SubPtr); // // Initialize the Fault Tolerant Write spare block // SubPtr = (VOID*) ((UINT8*) Ptr + EMU_FVB_BLOCK_SIZE); PcdSet32 (PcdFlashNvStorageFtwSpareBase, (UINT32)(UINTN) SubPtr); // // 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; }
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 ); PcdSet32(PcdVideoHorizontalResolution, Private->ModeData[Private->GraphicsOutput.Mode->Mode].HorizontalResolution); PcdSet32(PcdVideoVerticalResolution, Private->ModeData[Private->GraphicsOutput.Mode->Mode].VerticalResolution); return EFI_SUCCESS; }
EFI_STATUS EFIAPI QemuVideoGraphicsOutputSetMode ( IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN UINT32 ModeNumber ) /*++ Routine Description: Graphics Output protocol interface to set video mode Arguments: This - Protocol instance pointer. ModeNumber - The mode number to be set. Returns: EFI_SUCCESS - Graphics mode was changed. EFI_DEVICE_ERROR - The device had an error and could not complete the request. EFI_UNSUPPORTED - ModeNumber is not supported by this device. --*/ { QEMU_VIDEO_PRIVATE_DATA *Private; QEMU_VIDEO_MODE_DATA *ModeData; // UINTN Count; BOOLEAN VideoModeChanged; Private = QEMU_VIDEO_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (This); if (ModeNumber >= This->Mode->MaxMode) { return EFI_UNSUPPORTED; } ModeData = &Private->ModeData[ModeNumber]; if (Private->LineBuffer) { gBS->FreePool (Private->LineBuffer); } Private->LineBuffer = AllocatePool (4 * ModeData->HorizontalResolution); if (Private->LineBuffer == NULL) { return EFI_OUT_OF_RESOURCES; } switch (Private->Variant) { case QEMU_VIDEO_CIRRUS_5430: case QEMU_VIDEO_CIRRUS_5446: InitializeCirrusGraphicsMode (Private, &QemuVideoCirrusModes[ModeData->InternalModeIndex]); break; case QEMU_VIDEO_BOCHS_MMIO: case QEMU_VIDEO_BOCHS: InitializeBochsGraphicsMode (Private, &QemuVideoBochsModes[ModeData->InternalModeIndex]); break; default: ASSERT (FALSE); gBS->FreePool (Private->LineBuffer); Private->LineBuffer = NULL; return EFI_DEVICE_ERROR; } // Check if this is a new mode VideoModeChanged = (This->Mode->Mode != ModeNumber); This->Mode->Mode = ModeNumber; This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution; This->Mode->Info->VerticalResolution = ModeData->VerticalResolution; This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION); QemuVideoCompleteModeData (Private, This->Mode); BltLibConfigure ( (VOID*)(UINTN) This->Mode->FrameBufferBase, This->Mode->Info ); if (VideoModeChanged) { UINTN Index; UINTN HandleCount; EFI_HANDLE *HandleBuffer; EFI_STATUS Status; // // Set PCDs to Inform GraphicsConsole of video resolution. // PcdSet32 (PcdVideoHorizontalResolution, This->Mode->Info->HorizontalResolution); PcdSet32 (PcdVideoVerticalResolution, This->Mode->Info->VerticalResolution); // // 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; }