/** Initialize the platform default console variables when the console variable is empty. @param PlatformConsole Predfined platform default console device array. **/ VOID InitializeConsoleVariables ( IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole ) { UINTN Index; EFI_DEVICE_PATH_PROTOCOL *VarConOut; EFI_DEVICE_PATH_PROTOCOL *VarConIn; EFI_BOOT_MODE BootMode; BootMode = GetBootModeHob (); VarConOut = GetEfiGlobalVariable (L"ConOut"); if (VarConOut != NULL) { FreePool (VarConOut); } VarConIn = GetEfiGlobalVariable (L"ConIn"); if (VarConIn != NULL) { FreePool (VarConIn); } if (VarConOut == NULL || VarConIn == NULL) { // // Only fill ConIn/ConOut when ConIn/ConOut is empty because we may drop to Full Configuration boot mode in non-first boot // for (Index = 0; PlatformConsole[Index].DevicePath != NULL; Index++) { // // Update the console variable with the connect type // if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) { EfiBootManagerUpdateConsoleVariable (ConIn, PlatformConsole[Index].DevicePath, NULL); } if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) { EfiBootManagerUpdateConsoleVariable (ConOut, PlatformConsole[Index].DevicePath, NULL); } if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) { EfiBootManagerUpdateConsoleVariable (ErrOut, PlatformConsole[Index].DevicePath, NULL); } } } }
/** Entry point of DXE IPL PEIM. This function installs DXE IPL PPI and Decompress PPI. It also reloads itself to memory on non-S3 resume boot path. @param FileHandle Handle of the file being invoked. @param PeiServices Describes the list of possible PEI Services. @retval EFI_SUCESS The entry point of DXE IPL PEIM executes successfully. @retval Others Some error occurs during the execution of this function. **/ EFI_STATUS EFIAPI PeimInitializeDxeIpl ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; EFI_BOOT_MODE BootMode; EFI_GUID *ExtractHandlerGuidTable; UINTN ExtractHandlerNumber; EFI_PEI_PPI_DESCRIPTOR *GuidPpi; BootMode = GetBootModeHob (); if (BootMode != BOOT_ON_S3_RESUME) { Status = PeiServicesRegisterForShadow (FileHandle); if (Status == EFI_SUCCESS) { // // EFI_SUCESS means it is the first time to call register for shadow. // return Status; } // // Ensure that DXE IPL is shadowed to permanent memory. // ASSERT (Status == EFI_ALREADY_STARTED); // // Get custom extract guided section method guid list // ExtractHandlerNumber = ExtractGuidedSectionGetGuidList (&ExtractHandlerGuidTable); // // Install custom extraction guid PPI // if (ExtractHandlerNumber > 0) { GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePool (ExtractHandlerNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR)); ASSERT (GuidPpi != NULL); while (ExtractHandlerNumber-- > 0) { GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; GuidPpi->Ppi = (VOID *) &mCustomGuidedSectionExtractionPpi; GuidPpi->Guid = &ExtractHandlerGuidTable[ExtractHandlerNumber]; Status = PeiServicesInstallPpi (GuidPpi++); ASSERT_EFI_ERROR(Status); } } } // // Install DxeIpl and Decompress PPIs. // Status = PeiServicesInstallPpi (mPpiList); ASSERT_EFI_ERROR(Status); return Status; }
/** Get boot mode by looking up configuration table and parsing HOB list @param BootMode Boot mode from PEI handoff HOB. @retval EFI_SUCCESS Successfully get boot mode **/ EFI_STATUS EFIAPI BdsLibGetBootMode ( OUT EFI_BOOT_MODE *BootMode ) { *BootMode = GetBootModeHob (); return EFI_SUCCESS; }
/** Entry Point for PI SMM communication PEIM. @param FileHandle Handle of the file being invoked. @param PeiServices Pointer to PEI Services table. @retval EFI_SUCEESS @return Others Some error occurs. **/ EFI_STATUS EFIAPI PiSmmCommunicationPeiEntryPoint ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; PEI_SMM_ACCESS_PPI *SmmAccess; EFI_BOOT_MODE BootMode; UINTN Index; BootMode = GetBootModeHob (); if (BootMode != BOOT_ON_S3_RESUME) { return EFI_UNSUPPORTED; } Status = PeiServicesLocatePpi ( &gPeiSmmAccessPpiGuid, 0, NULL, (VOID **)&SmmAccess ); if (EFI_ERROR (Status)) { return EFI_NOT_STARTED; } // // Check SMRAM locked, it should be done before SMRAM lock. // if (SmmAccess->LockState) { DEBUG ((EFI_D_INFO, "PiSmmCommunicationPei LockState - %x\n", (UINTN)SmmAccess->LockState)); return EFI_ACCESS_DENIED; } // // Open all SMRAM // for (Index = 0; !EFI_ERROR (Status); Index++) { Status = SmmAccess->Open ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index); } InitCommunicationContext (); PeiServicesInstallPpi (&mPpiList); return RETURN_SUCCESS; }
EFI_STATUS EFIAPI NorFlashFvbInitialize ( IN NOR_FLASH_INSTANCE* Instance ) { EFI_STATUS Status; UINT32 FvbNumLba; EFI_BOOT_MODE BootMode; DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n")); Instance->Initialized = TRUE; // Set the index of the first LBA for the FVB Instance->StartLba = (PcdGet32 (PcdFlashNvStorageVariableBase) - Instance->RegionBaseAddress) / Instance->Media.BlockSize; BootMode = GetBootModeHob (); if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) { Status = EFI_INVALID_PARAMETER; } else { // Determine if there is a valid header at the beginning of the NorFlash Status = ValidateFvHeader (Instance); } // Install the Default FVB header if required if (EFI_ERROR(Status)) { // There is no valid header, so time to install one. DEBUG((EFI_D_ERROR,"NorFlashFvbInitialize: ERROR - The FVB Header is not valid. Installing a correct one for this volume.\n")); // Erase all the NorFlash that is reserved for variable storage FvbNumLba = (PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + PcdGet32(PcdFlashNvStorageFtwSpareSize)) / Instance->Media.BlockSize; Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba, EFI_LBA_LIST_TERMINATOR); if (EFI_ERROR(Status)) { return Status; } // Install all appropriate headers Status = InitializeFvAndVariableStoreHeaders (Instance); if (EFI_ERROR(Status)) { return Status; } } return Status; }
/** Main entry point to last PEIM. This function finds DXE Core in the firmware volume and transfer the control to DXE core. @param This Entry point for DXE IPL PPI. @param PeiServices General purpose services available to every PEIM. @param HobList Address to the Pei HOB list. @return EFI_SUCCESS DXE core was successfully loaded. @return EFI_OUT_OF_RESOURCES There are not enough resources to load DXE core. **/ EFI_STATUS EFIAPI DxeLoadCore ( IN CONST EFI_DXE_IPL_PPI *This, IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_HOB_POINTERS HobList ) { EFI_STATUS Status; EFI_FV_FILE_INFO DxeCoreFileInfo; EFI_PHYSICAL_ADDRESS DxeCoreAddress; UINT64 DxeCoreSize; EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint; EFI_BOOT_MODE BootMode; EFI_PEI_FILE_HANDLE FileHandle; EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable; EFI_PEI_LOAD_FILE_PPI *LoadFile; UINTN Instance; UINT32 AuthenticationState; UINTN DataSize; EFI_PEI_S3_RESUME2_PPI *S3Resume; EFI_PEI_RECOVERY_MODULE_PPI *PeiRecovery; EFI_MEMORY_TYPE_INFORMATION MemoryData[EfiMaxMemoryType + 1]; // // if in S3 Resume, restore configure // BootMode = GetBootModeHob (); if (BootMode == BOOT_ON_S3_RESUME) { Status = PeiServicesLocatePpi ( &gEfiPeiS3Resume2PpiGuid, 0, NULL, (VOID **) &S3Resume ); if (EFI_ERROR (Status)) { // // Report Status code that S3Resume PPI can not be found // REPORT_STATUS_CODE ( EFI_ERROR_CODE | EFI_ERROR_MAJOR, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_PPI_NOT_FOUND) ); } ASSERT_EFI_ERROR (Status); Status = S3Resume->S3RestoreConfig2 (S3Resume); ASSERT_EFI_ERROR (Status); } else if (BootMode == BOOT_IN_RECOVERY_MODE) { REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_BEGIN)); Status = PeiServicesLocatePpi ( &gEfiPeiRecoveryModulePpiGuid, 0, NULL, (VOID **) &PeiRecovery ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Locate Recovery PPI Failed.(Status = %r)\n", Status)); // // Report Status code the failure of locating Recovery PPI // REPORT_STATUS_CODE ( EFI_ERROR_CODE | EFI_ERROR_MAJOR, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_RECOVERY_PPI_NOT_FOUND) ); CpuDeadLoop (); } REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_LOAD)); Status = PeiRecovery->LoadRecoveryCapsule (PeiServices, PeiRecovery); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Load Recovery Capsule Failed.(Status = %r)\n", Status)); // // Report Status code that recovery image can not be found // REPORT_STATUS_CODE ( EFI_ERROR_CODE | EFI_ERROR_MAJOR, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_NO_RECOVERY_CAPSULE) ); CpuDeadLoop (); } REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_START)); // // Now should have a HOB with the DXE core // } if (GetFirstGuidHob ((CONST EFI_GUID *)&gEfiMemoryTypeInformationGuid) == NULL) { // // Don't build GuidHob if GuidHob has been installed. // Status = PeiServicesLocatePpi ( &gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **)&Variable ); if (!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)) { // // Build the GUID'd HOB for DXE // BuildGuidDataHob ( &gEfiMemoryTypeInformationGuid, MemoryData, DataSize ); } } } // // Look in all the FVs present in PEI and find the DXE Core FileHandle // FileHandle = DxeIplFindDxeCore (); // // Load the DXE Core from a Firmware Volume. // Instance = 0; do { Status = PeiServicesLocatePpi (&gEfiPeiLoadFilePpiGuid, Instance++, NULL, (VOID **) &LoadFile); // // These must exist an instance of EFI_PEI_LOAD_FILE_PPI to support to load DxeCore file handle successfully. // ASSERT_EFI_ERROR (Status); Status = LoadFile->LoadFile ( LoadFile, FileHandle, &DxeCoreAddress, &DxeCoreSize, &DxeCoreEntryPoint, &AuthenticationState ); } while (EFI_ERROR (Status)); // // Get the DxeCore File Info from the FileHandle for the DxeCore GUID file name. // Status = PeiServicesFfsGetFileInfo (FileHandle, &DxeCoreFileInfo); ASSERT_EFI_ERROR (Status); // // Add HOB for the DXE Core // BuildModuleHob ( &DxeCoreFileInfo.FileName, DxeCoreAddress, ALIGN_VALUE (DxeCoreSize, EFI_PAGE_SIZE), DxeCoreEntryPoint ); // // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT // REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT)); DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading DXE CORE at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN)DxeCoreAddress, FUNCTION_ENTRY_POINT (DxeCoreEntryPoint))); // // Transfer control to the DXE Core // The hand off state is simply a pointer to the HOB list // HandOffToDxeCore (DxeCoreEntryPoint, HobList); // // If we get here, then the DXE Core returned. This is an error // DxeCore should not return. // ASSERT (FALSE); CpuDeadLoop (); return EFI_OUT_OF_RESOURCES; }
/** Initialize CapsuleLast variables. **/ VOID InitCapsuleLastVariable ( VOID ) { EFI_STATUS Status; EFI_BOOT_MODE BootMode; EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock; VOID *CapsuleResult; UINTN Size; CHAR16 CapsuleLastStr[sizeof("Capsule####")]; BootMode = GetBootModeHob(); if (BootMode == BOOT_ON_FLASH_UPDATE) { Status = gRT->SetVariable( L"CapsuleLast", &gEfiCapsuleReportGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 0, NULL ); // Do not lock it because it will be updated later. } else { // // Check if OS/APP cleared L"Capsule####" // ZeroMem(CapsuleLastStr, sizeof(CapsuleLastStr)); Size = sizeof(L"Capsule####") - sizeof(CHAR16); // no zero terminator Status = gRT->GetVariable( L"CapsuleLast", &gEfiCapsuleReportGuid, NULL, &Size, CapsuleLastStr ); if (!EFI_ERROR(Status)) { // // L"CapsuleLast" is got, check if data is there. // Status = GetVariable2 ( CapsuleLastStr, &gEfiCapsuleReportGuid, (VOID **) &CapsuleResult, NULL ); if (EFI_ERROR(Status)) { // // If no data, delete L"CapsuleLast" // Status = gRT->SetVariable( L"CapsuleLast", &gEfiCapsuleReportGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 0, NULL ); } } // Lock it in normal boot path per UEFI spec. Status = gBS->LocateProtocol(&gEdkiiVariableLockProtocolGuid, NULL, (VOID **)&VariableLock); if (!EFI_ERROR(Status)) { Status = VariableLock->RequestToLock(VariableLock, L"CapsuleLast", &gEfiCapsuleReportGuid); ASSERT_EFI_ERROR(Status); } } }
/** This routine adjust the memory information for different memory type and save them into the variables for next boot. **/ VOID BdsSetMemoryTypeInformationVariable ( VOID ) { EFI_STATUS Status; EFI_MEMORY_TYPE_INFORMATION *PreviousMemoryTypeInformation; EFI_MEMORY_TYPE_INFORMATION *CurrentMemoryTypeInformation; UINTN VariableSize; UINTN Index; UINTN Index1; UINT32 Previous; UINT32 Current; UINT32 Next; EFI_HOB_GUID_TYPE *GuidHob; BOOLEAN MemoryTypeInformationModified; BOOLEAN MemoryTypeInformationVariableExists; EFI_BOOT_MODE BootMode; MemoryTypeInformationModified = FALSE; MemoryTypeInformationVariableExists = FALSE; BootMode = GetBootModeHob (); // // In BOOT_IN_RECOVERY_MODE, Variable region is not reliable. // if (BootMode == BOOT_IN_RECOVERY_MODE) { return; } // // Only check the the Memory Type Information variable in the boot mode // other than BOOT_WITH_DEFAULT_SETTINGS because the Memory Type // Information is not valid in this boot mode. // if (BootMode != BOOT_WITH_DEFAULT_SETTINGS) { VariableSize = 0; Status = gRT->GetVariable ( EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME, &gEfiMemoryTypeInformationGuid, NULL, &VariableSize, NULL ); if (Status == EFI_BUFFER_TOO_SMALL) { MemoryTypeInformationVariableExists = TRUE; } } // // Retrieve the current memory usage statistics. If they are not found, then // no adjustments can be made to the Memory Type Information variable. // Status = EfiGetSystemConfigurationTable ( &gEfiMemoryTypeInformationGuid, (VOID **) &CurrentMemoryTypeInformation ); if (EFI_ERROR (Status) || CurrentMemoryTypeInformation == NULL) { return; } // // Get the Memory Type Information settings from Hob if they exist, // PEI is responsible for getting them from variable and build a Hob to save them. // If the previous Memory Type Information is not available, then set defaults // GuidHob = GetFirstGuidHob (&gEfiMemoryTypeInformationGuid); if (GuidHob == NULL) { // // If Platform has not built Memory Type Info into the Hob, just return. // return; } PreviousMemoryTypeInformation = GET_GUID_HOB_DATA (GuidHob); VariableSize = GET_GUID_HOB_DATA_SIZE (GuidHob); // // Use a heuristic to adjust the Memory Type Information for the next boot // // DEBUG ((EFI_D_INFO, "Memory Previous Current Next \n")); // DEBUG ((EFI_D_INFO, " Type Pages Pages Pages \n")); // DEBUG ((EFI_D_INFO, "====== ======== ======== ========\n")); for (Index = 0; PreviousMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) { for (Index1 = 0; CurrentMemoryTypeInformation[Index1].Type != EfiMaxMemoryType; Index1++) { if (PreviousMemoryTypeInformation[Index].Type == CurrentMemoryTypeInformation[Index1].Type) { break; } } if (CurrentMemoryTypeInformation[Index1].Type == EfiMaxMemoryType) { continue; } // // Previous is the number of pages pre-allocated // Current is the number of pages actually needed // Previous = PreviousMemoryTypeInformation[Index].NumberOfPages; Current = CurrentMemoryTypeInformation[Index1].NumberOfPages; Next = Previous; // // Inconsistent Memory Reserved across bootings may lead to S4 fail // Write next varible to 125% * current when the pre-allocated memory is: // 1. More than 150% of needed memory and boot mode is BOOT_WITH_DEFAULT_SETTING // 2. Less than the needed memory // if (Current < Previous) { if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) { Next = Current + (Current >> 2); } else if (!MemoryTypeInformationVariableExists) { Next = MAX (Current + (Current >> 2), Previous); }
/** Entry point of DXE IPL PEIM. This function installs DXE IPL PPI. It also reloads itself to memory on non-S3 resume boot path. @param FileHandle Handle of the file being invoked. @param PeiServices Describes the list of possible PEI Services. @retval EFI_SUCESS The entry point of DXE IPL PEIM executes successfully. @retval Others Some error occurs during the execution of this function. **/ EFI_STATUS EFIAPI PeimInitializeDxeIpl ( IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices ) { EFI_STATUS Status; EFI_BOOT_MODE BootMode; VOID *Dummy; BootMode = GetBootModeHob (); if (BootMode != BOOT_ON_S3_RESUME) { Status = PeiServicesRegisterForShadow (FileHandle); if (Status == EFI_SUCCESS) { // // EFI_SUCESS means it is the first time to call register for shadow. // return Status; } // // Ensure that DXE IPL is shadowed to permanent memory. // ASSERT (Status == EFI_ALREADY_STARTED); // // DXE core load requires permanent memory. // Status = PeiServicesLocatePpi ( &gEfiPeiMemoryDiscoveredPpiGuid, 0, NULL, (VOID **) &Dummy ); ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { return Status; } // // Now the permanent memory exists, install the PPIs for decompression // and section extraction. // Status = InstallIplPermanentMemoryPpis (NULL, NULL, NULL); ASSERT_EFI_ERROR (Status); } else { // // Install memory discovered PPI notification to install PPIs for // decompression and section extraction. // Status = PeiServicesNotifyPpi (&mMemoryDiscoveredNotifyList); ASSERT_EFI_ERROR (Status); } // // Install DxeIpl PPI. // Status = PeiServicesInstallPpi (&mDxeIplPpiList); ASSERT_EFI_ERROR(Status); return Status; }
VOID EFIAPI PlatformConfigOnSpiReady ( IN EFI_EVENT Event, IN VOID *Context ) /*++ Routine Description: Function runs in PI-DXE to perform platform specific config when SPI interface is ready. Arguments: Event - The event that occured. Context - For EFI compatiblity. Not used. Returns: None. --*/ { EFI_STATUS Status; VOID *SpiReadyProt = NULL; EFI_PLATFORM_TYPE_PROTOCOL *PlatformType; EFI_BOOT_MODE BootMode; BootMode = GetBootModeHob (); PlatformType = &mPrivatePlatformData.PlatformType; Status = gBS->LocateProtocol (&gEfiSmmSpiReadyProtocolGuid, NULL, &SpiReadyProt); if (Status != EFI_SUCCESS){ DEBUG ((DEBUG_INFO, "gEfiSmmSpiReadyProtocolGuid triggered but not valid.\n")); return; } // // Lock regions SPI flash. // PlatformFlashLockPolicy (FALSE); // // Configurations and checks to be done when DXE tracing available. // // // Platform specific Signal routing. // // // Skip any signal not needed for recovery and flash update. // if (BootMode != BOOT_ON_FLASH_UPDATE && BootMode != BOOT_IN_RECOVERY_MODE) { // // Galileo Platform UART0 support. // if (PlatformType->Type == Galileo) { // // Use MUX to connect out UART0 pins. // PlatformInitializeUart0MuxGalileo (); } // // GalileoGen2 Platform UART0 support. // if (PlatformType->Type == GalileoGen2) { // // Use route out UART0 pins. // PlatformInitializeUart0MuxGalileoGen2 (); } } }
/** 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; }
/** The driver entry point for Firmware Volume Block Driver. The function does the necessary initialization work Firmware Volume Block Driver. @param[in] ImageHandle The firmware allocated handle for the UEFI image. @param[in] SystemTable A pointer to the EFI system table. @retval EFI_SUCCESS This funtion always return EFI_SUCCESS. It will ASSERT on errors. **/ EFI_STATUS FvbInitialize ( ) { EFI_FW_VOL_INSTANCE *FwhInstance; EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; EFI_FIRMWARE_VOLUME_HEADER *FvHeader; EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry; EFI_PHYSICAL_ADDRESS BaseAddress; EFI_STATUS Status; UINTN BufferSize; UINTN TmpHeaderLength; UINTN Idx; UINT32 MaxLbaSize; BOOLEAN FvHeaderValid; UINTN FvFlashLinearAddress; EFI_BOOT_MODE BootMode; UINT32 Index; UINT32 PlatformFvBaseAddress[5]; UINT32 PlatformFvBaseAddressCount; UINT32 PlatformFvLockList[4]; UINT32 PlatformFvLockListCount; // // This platform driver knows there are 3 FVs on // FD, which are FvRecovery, FvMain and FvNvStorage. // BootMode = GetBootModeHob (); if (BootMode == BOOT_IN_RECOVERY_MODE) { // // On recovery boot, don't report any firmware FV images except payload, because their data can't be trusted. // PlatformFvBaseAddressCount = 2; PlatformFvBaseAddress[0] = PcdGet32 (PcdFlashNvStorageVariableBase); PlatformFvBaseAddress[1] = PcdGet32 (PcdFlashPayloadBase); } else { PlatformFvBaseAddressCount = 5; PlatformFvBaseAddress[0] = PcdGet32 (PcdFlashFvMainBase); PlatformFvBaseAddress[1] = PcdGet32 (PcdFlashNvStorageVariableBase); PlatformFvBaseAddress[2] = PcdGet32 (PcdFlashFvRecoveryBase); PlatformFvBaseAddress[3] = PcdGet32 (PcdFlashFvRecovery2Base); PlatformFvBaseAddress[4] = PcdGet32 (PcdFlashPayloadBase); } // // List of FVs that should be write protected on normal boots. // PlatformFvLockListCount = 4; PlatformFvLockList[0] = PcdGet32 (PcdFlashFvMainBase); PlatformFvLockList[1] = PcdGet32 (PcdFlashFvRecoveryBase); PlatformFvLockList[2] = PcdGet32 (PcdFlashFvRecovery2Base); PlatformFvLockList[3] = PcdGet32 (PcdFlashPayloadBase); // // Calculate the total size for all firmware volume block instances and // allocate a buffer to store them in. // BufferSize = 0; for (Idx = 0; Idx < PlatformFvBaseAddressCount; Idx++) { FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) PlatformFvBaseAddress[Idx]; if (FvHeader == NULL) { continue; } BufferSize += (FvHeader->HeaderLength + sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER) ); } mFvbModuleGlobal.FvInstance = (EFI_FW_VOL_INSTANCE *) AllocateRuntimeZeroPool (BufferSize); ASSERT (NULL != mFvbModuleGlobal.FvInstance); // // Perform other variable initialization. // MaxLbaSize = 0; FwhInstance = mFvbModuleGlobal.FvInstance; mFvbModuleGlobal.NumFv = 0; for (Idx = 0; Idx < PlatformFvBaseAddressCount; Idx++) { if ((BootMode == BOOT_ASSUMING_NO_CONFIGURATION_CHANGES) && PlatformFvBaseAddress[Idx]!= PcdGet32 (PcdFlashNvStorageVariableBase) && PlatformFvBaseAddress[Idx]!= PcdGet32 (PcdFlashPayloadBase)) { continue; } // // Get base address information. // BaseAddress = PlatformFvBaseAddress[Idx]; FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress; if (FwVolHeader == NULL) { continue; } // // Find the flash linear address of the current FV. // FvFlashLinearAddress = (UINTN) FLASH_LINEAR_ADDRESS(BaseAddress); if (!IsFvHeaderValid (BaseAddress, FwVolHeader)) { FvHeaderValid = FALSE; // // If not valid, get FvbInfo from the information carried in // FVB driver. // DEBUG ((EFI_D_ERROR, "Fvb: FV header @ 0x%lx invalid\n", BaseAddress)); Status = GetFvbInfo (BaseAddress, &FwVolHeader); ASSERT_EFI_ERROR(Status); // // Write back a healthy FV header. // DEBUG ((EFI_D_INFO, "FwBlockService.c: Writing back healthy FV header\n")); mSpiDeviceProtocol->SpiLock (FvFlashLinearAddress, FwVolHeader->BlockMap->Length, FALSE); Status = mSpiDeviceProtocol->SpiErase (FvFlashLinearAddress, FwVolHeader->BlockMap->Length); TmpHeaderLength = (UINTN) FwVolHeader->HeaderLength; Status = mSpiDeviceProtocol->SpiWrite ( FvFlashLinearAddress, &TmpHeaderLength, (UINT8 *) FwVolHeader ); mSpiDeviceProtocol->SpiLock (FvFlashLinearAddress, FwVolHeader->BlockMap->Length, TRUE); WriteBackInvalidateDataCacheRange ( (VOID *) (UINTN) BaseAddress, FwVolHeader->BlockMap->Length ); } // // Copy FV header into local storage and assign base address. // CopyMem (&(FwhInstance->VolumeHeader), FwVolHeader, FwVolHeader->HeaderLength); FwVolHeader = &(FwhInstance->VolumeHeader); FwhInstance->FvBase = (UINTN)BaseAddress; FwhInstance->FvFlashLinearAddress = FvFlashLinearAddress; // // In some cases the Recovery and Main FVs should be considered locked from // write access by this protocol. Only in the case of flash updates and // configuration mode should they be left unlocked. // if (BootMode != BOOT_IN_RECOVERY_MODE && BootMode != BOOT_ON_FLASH_UPDATE) { for (Index = 0; Index < PlatformFvLockListCount; Index++) { if (FwhInstance->FvBase == PlatformFvLockList[Index]) { // // For all FVs in the lock list we need to clear the write status bit // and lock write status updates. This will make sure this protocol // will not attempt to write to the FV. // FwhInstance->VolumeHeader.Attributes &= (UINT64) ~EFI_FVB2_WRITE_STATUS; FwhInstance->VolumeHeader.Attributes |= (EFI_FVB2_LOCK_STATUS | EFI_FVB2_WRITE_LOCK_STATUS); } } } // // Process the block map for each FV // FwhInstance->NumOfBlocks = 0; for (PtrBlockMapEntry = FwVolHeader->BlockMap; PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) { // // Get the maximum size of a block. // if (MaxLbaSize < PtrBlockMapEntry->Length) { MaxLbaSize = PtrBlockMapEntry->Length; } FwhInstance->NumOfBlocks += PtrBlockMapEntry->NumBlocks; } // // Add a FVB Protocol Instance // mFvbModuleGlobal.NumFv++; InstallFvbProtocol (FwhInstance, mFvbModuleGlobal.NumFv - 1); // // Move on to the next FwhInstance // FwhInstance = (EFI_FW_VOL_INSTANCE *) ((UINTN)((UINT8 *)FwhInstance) + FwVolHeader->HeaderLength + (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER))); } if ((PcdGet32 (PcdFlashNvStorageFtwWorkingBase) == 0) || (PcdGet32 (PcdFlashNvStorageFtwSpareBase) == 0)) { return EFI_SUCCESS; } // // Install FVB protocols for FTW spare space and FTW working space. // These is no FV header for these 2 spaces. // mFvbModuleGlobal.FvInstance = (EFI_FW_VOL_INSTANCE *) ReallocateRuntimePool ( BufferSize, BufferSize + (sizeof (EFI_FW_VOL_INSTANCE) + sizeof (EFI_FV_BLOCK_MAP_ENTRY)) * 2, mFvbModuleGlobal.FvInstance ); ASSERT (NULL != mFvbModuleGlobal.FvInstance); PlatformFvBaseAddress[0] = PcdGet32 (PcdFlashNvStorageFtwWorkingBase); PlatformFvBaseAddress[1] = PcdGet32 (PcdFlashNvStorageFtwSpareBase); for (Idx = 0; Idx < 2; Idx++) { BaseAddress = PlatformFvBaseAddress[Idx]; Status = GetFtwFvbInfo (BaseAddress, &FwVolHeader); ASSERT_EFI_ERROR(Status); // // Copy FV header into local storage and assign base address. // mFvbModuleGlobal.NumFv++; FwhInstance = GetFvbInstance (mFvbModuleGlobal.NumFv - 1); CopyMem (&(FwhInstance->VolumeHeader), FwVolHeader, FwVolHeader->HeaderLength); FwVolHeader = &(FwhInstance->VolumeHeader); // // Process the block map for each FV // FwhInstance->NumOfBlocks = 0; for (PtrBlockMapEntry = FwVolHeader->BlockMap; PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) { FwhInstance->NumOfBlocks += PtrBlockMapEntry->NumBlocks; } FwhInstance->FvBase = (UINTN)BaseAddress; FwhInstance->FvFlashLinearAddress = (UINTN) FLASH_LINEAR_ADDRESS(BaseAddress); InstallFvbProtocol (FwhInstance, mFvbModuleGlobal.NumFv - 1); } return EFI_SUCCESS; }
EFI_STATUS EFIAPI NorFlashFvbInitialize ( IN NOR_FLASH_INSTANCE* Instance ) { EFI_STATUS Status; UINT32 FvbNumLba; EFI_BOOT_MODE BootMode; UINTN RuntimeMmioRegionSize; DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n")); ASSERT((Instance != NULL)); // // Declare the Non-Volatile storage as EFI_MEMORY_RUNTIME // // Note: all the NOR Flash region needs to be reserved into the UEFI Runtime memory; // even if we only use the small block region at the top of the NOR Flash. // The reason is when the NOR Flash memory is set into program mode, the command // is written as the base of the flash region (ie: Instance->DeviceBaseAddress) RuntimeMmioRegionSize = (Instance->RegionBaseAddress - Instance->DeviceBaseAddress) + Instance->Size; Status = gDS->AddMemorySpace ( EfiGcdMemoryTypeMemoryMappedIo, Instance->DeviceBaseAddress, RuntimeMmioRegionSize, EFI_MEMORY_UC | EFI_MEMORY_RUNTIME ); ASSERT_EFI_ERROR (Status); Status = gDS->SetMemorySpaceAttributes ( Instance->DeviceBaseAddress, RuntimeMmioRegionSize, EFI_MEMORY_UC | EFI_MEMORY_RUNTIME); ASSERT_EFI_ERROR (Status); mFlashNvStorageVariableBase = FixedPcdGet32 (PcdFlashNvStorageVariableBase); // Set the index of the first LBA for the FVB Instance->StartLba = (PcdGet32 (PcdFlashNvStorageVariableBase) - Instance->RegionBaseAddress) / Instance->Media.BlockSize; BootMode = GetBootModeHob (); if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) { Status = EFI_INVALID_PARAMETER; } else { // Determine if there is a valid header at the beginning of the NorFlash Status = ValidateFvHeader (Instance); } // Install the Default FVB header if required if (EFI_ERROR(Status)) { // There is no valid header, so time to install one. DEBUG ((EFI_D_INFO, "%a: The FVB Header is not valid.\n", __FUNCTION__)); DEBUG ((EFI_D_INFO, "%a: Installing a correct one for this volume.\n", __FUNCTION__)); // Erase all the NorFlash that is reserved for variable storage FvbNumLba = (PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + PcdGet32(PcdFlashNvStorageFtwSpareSize)) / Instance->Media.BlockSize; Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba, EFI_LBA_LIST_TERMINATOR); if (EFI_ERROR(Status)) { return Status; } // Install all appropriate headers Status = InitializeFvAndVariableStoreHeaders (Instance); if (EFI_ERROR(Status)) { return Status; } } // // The driver implementing the variable read service can now be dispatched; // the varstore headers are in place. // Status = gBS->InstallProtocolInterface ( &gImageHandle, &gEdkiiNvVarStoreFormattedGuid, EFI_NATIVE_INTERFACE, NULL ); ASSERT_EFI_ERROR (Status); // // Register for the virtual address change event // Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_NOTIFY, FvbVirtualNotifyEvent, NULL, &gEfiEventVirtualAddressChangeGuid, &mFvbVirtualAddrChangeEvent ); ASSERT_EFI_ERROR (Status); return Status; }
EFI_STATUS UpdatePlatformInformation ( CHAR16 *SECVer, CHAR16 *uCodeVer, CHAR16 *GOPVer, CHAR16 *MrcVer, CHAR16 *PmcVer, CHAR16 *UlpmcVer, CHAR16 *PunitVer, CHAR16 *SocVer, CHAR16 *BoardVer, CHAR16 *FabVer, CHAR16 *CpuFlavorString, CHAR16 *BiosVer, CHAR16 *PmicVer, CHAR16 *TouchVer, CHAR16 *SecureBootMode, CHAR16 *BootModeString, CHAR16 *SpeedStepMode, CHAR16 *MaxCState, CHAR16 *CpuTurbo, CHAR16 *GfxTurbo, CHAR16 *S0ix, CHAR16 *RC6 ) { UINT32 MicroCodeVersion; CHAR16 Buffer[SMBIOS_STRING_MAX_LENGTH + 2]; EFI_STATUS Status; UINT8 CpuFlavor=0; EFI_PEI_HOB_POINTERS GuidHob; EFI_PLATFORM_INFO_HOB *mPlatformInfo=NULL; UINTN NumHandles; EFI_HANDLE *HandleBuffer; UINTN Index; DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy; UINTN PciD31F0RegBase; UINT8 count; UINT8 Data8; UINT8 Data8_1; CHAR16 Name[40]; UINT32 MrcVersion; CHAR16 *Version; SYSTEM_CONFIGURATION SystemConfiguration; EFI_BOOT_MODE BootMode; UINTN VarSize; EFI_PLATFORM_INFO_HOB *mPlatformInfo; Version = AllocateZeroPool (SMBIOS_STRING_MAX_LENGTH + 2); // // Get the System configuration // CopyMem (&SystemConfiguration, PcdGetPtr (PcdSystemConfiguration), sizeof(SYSTEM_CONFIGURATION)); // // Get the HOB list. If it is not present, then ASSERT. // mPlatformInfo = PcdGetPtr (PcdPlatformInfo); GetSeCVersion (SECVer); Status = GetBiosVersionDateTime (Version, NULL, NULL); UnicodeSPrint (Buffer, sizeof (Buffer), L"%s", Version); FreePool(Version); StrCpy (BiosVer, Buffer); Status = TGetGOPDriverName(Name); if(!EFI_ERROR(Status)) { StrCpy (GOPVer, Name); } // //CpuFlavor // //CHV //CHV-DC Tablet 000 //CHV-QC Notebook 001 //CHV-QC Desktop 010 //CPU flavor CpuFlavor = RShiftU64 (EfiReadMsr (MSR_IA32_PLATFORM_ID), 50) & 0x07; switch(CpuFlavor){ case 0x0: UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"CHV-DC Tablet", CpuFlavor); StrCpy (CpuFlavorString, Buffer); break; case 0x01: #if (TABLET_PF_ENABLE == 1) UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"CHV-QC Tablet", CpuFlavor); #else UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"CHV-QC Notebook", CpuFlavor); #endif StrCpy (CpuFlavorString, Buffer); break; case 0x02: UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"CHV-QC Desktop", CpuFlavor); StrCpy (CpuFlavorString, Buffer); break; case 0x03: UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"CHV-QC Notebook", CpuFlavor); StrCpy (CpuFlavorString, Buffer); break; default: UnicodeSPrint (Buffer, sizeof (Buffer), L"%s (%01x)", L"Unknown CPU", CpuFlavor); StrCpy (CpuFlavorString, Buffer); break; } if ( NULL != mPlatformInfo) { // // Board Id // UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", mPlatformInfo->BoardId); StrCpy (BoardVer, Buffer); // // FAB ID // UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", mPlatformInfo->FABID); StrCpy (FabVer, Buffer); } // //Update MRC Version // MrcVersion = MmioRead32 (MmPciAddress (0, 0, 0, 0, 0xF0)); MrcVersion &= 0xffff; Index = EfiValueToString (Buffer, MrcVersion/100, PREFIX_ZERO, 0); StrCat (Buffer, L"."); EfiValueToString (Buffer + Index + 1, (MrcVersion%100)/10, PREFIX_ZERO, 0); EfiValueToString (Buffer + Index + 2, (MrcVersion%100)%10, PREFIX_ZERO, 0); StrCpy (MrcVer, Buffer); // //Update Soc Version // // // Retrieve all instances of PCH Platform Policy protocol // Status = gBS->LocateHandleBuffer ( ByProtocol, &gDxePchPlatformPolicyProtocolGuid, NULL, &NumHandles, &HandleBuffer ); if (!EFI_ERROR (Status)) { // // Find the matching PCH Policy protocol // for (Index = 0; Index < NumHandles; Index++) { Status = gBS->HandleProtocol ( HandleBuffer[Index], &gDxePchPlatformPolicyProtocolGuid, &PchPlatformPolicy ); if (!EFI_ERROR (Status)) { PciD31F0RegBase = MmPciAddress ( 0, PchPlatformPolicy->BusNumber, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC, 0 ); Data8 = MmioRead8 (PciD31F0RegBase + R_PCH_LPC_RID_CC) & B_PCH_LPC_RID_STEPPING_MASK; count = sizeof (SBRevisionTable) / sizeof (SBRevisionTable[0]); for (Index = 0; Index < count; Index++) { if(Data8 == SBRevisionTable[Index].RevId) { UnicodeSPrint (Buffer, sizeof (Buffer), L"%02x %a", Data8, SBRevisionTable[Index].String); StrCpy (SocVer, Buffer); break; } } break; } } } // // Microcode Revision // EfiWriteMsr (EFI_MSR_IA32_BIOS_SIGN_ID, 0); EfiCpuid (EFI_CPUID_VERSION_INFO, NULL); MicroCodeVersion = (UINT32) RShiftU64 (EfiReadMsr (EFI_MSR_IA32_BIOS_SIGN_ID), 32); UnicodeSPrint (Buffer, sizeof (Buffer), L"%x", MicroCodeVersion); StrCpy (uCodeVer, Buffer); // //Secure boot // Data8 = SystemConfiguration.SecureBoot; UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8); StrCpy (SecureBootMode, Buffer); // //Bootmode // BootMode = GetBootModeHob(); UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", BootMode); StrCpy (BootModeString, Buffer); // //SpeedStep // Data8 = SystemConfiguration.EnableGv; UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8); StrCpy (SpeedStepMode, Buffer); // //CPU Turbo // Data8 = SystemConfiguration.TurboModeEnable; UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8); StrCpy (CpuTurbo, Buffer); // //CState // Data8 = SystemConfiguration.MaxCState; UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8); StrCpy (MaxCState, Buffer); // //GFX Turbo // Data8 = SystemConfiguration.IgdTurboEnabled; UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8); StrCpy (GfxTurbo, Buffer); // //S0ix // Data8 = SystemConfiguration.S0ix; UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8); StrCpy (S0ix, Buffer); // //RC6 // Data8 = SystemConfiguration.EnableRenderStandby; UnicodeSPrint (Buffer, sizeof(Buffer), L"%x", Data8); StrCpy (RC6, Buffer); // // Punit Version // Data8 = (UINT8) EfiReadMsr (0x667); UnicodeSPrint (Buffer, sizeof (Buffer), L"0x%x", Data8); StrCpy (PunitVer, Buffer); // // PMC Version // Data8 = (UINT8)((MmioRead32 (PMC_BASE_ADDRESS + R_PCH_PMC_PRSTS)>>16)&0x00FF); Data8_1 = (UINT8)((MmioRead32 (PMC_BASE_ADDRESS + R_PCH_PMC_PRSTS)>>24)&0x00FF); UnicodeSPrint (Buffer, sizeof (Buffer), L"0x%X_%X", Data8_1, Data8); StrCpy (PmcVer, Buffer); TGetTouchFirmwareVersion(TouchVer); return EFI_SUCCESS; }
EFI_STATUS EFIAPI InitializePlatformSmm ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; UINT8 Index; EFI_HANDLE Handle; EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT PowerButtonContext; EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL *PowerButtonDispatch; EFI_SMM_ICHN_DISPATCH_CONTEXT IchnContext; EFI_SMM_ICHN_DISPATCH_PROTOCOL *IchnDispatch; EFI_SMM_SX_DISPATCH_PROTOCOL *SxDispatch; EFI_SMM_SX_DISPATCH_CONTEXT EntryDispatchContext; EFI_SMM_SW_DISPATCH_PROTOCOL *SwDispatch; EFI_SMM_SW_DISPATCH_CONTEXT SwContext; UINTN VarSize; EFI_BOOT_MODE BootMode; Handle = NULL; // // Locate the Global NVS Protocol. // Status = gBS->LocateProtocol ( &gEfiGlobalNvsAreaProtocolGuid, NULL, (void **)&mGlobalNvsAreaPtr ); ASSERT_EFI_ERROR (Status); // // Get the ACPI Base Address // mAcpiBaseAddr = PchLpcPciCfg16( R_PCH_LPC_ACPI_BASE ) & B_PCH_LPC_ACPI_BASE_BAR; VarSize = sizeof(SYSTEM_CONFIGURATION); Status = SystemTable->RuntimeServices->GetVariable( L"Setup", &gEfiSetupVariableGuid, NULL, &VarSize, &mSystemConfiguration ); if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) { //The setup variable is corrupted VarSize = sizeof(SYSTEM_CONFIGURATION); Status = SystemTable->RuntimeServices->GetVariable( L"SetupRecovery", &gEfiSetupVariableGuid, NULL, &VarSize, &mSystemConfiguration ); ASSERT_EFI_ERROR (Status); } if (!EFI_ERROR(Status)) { mAcLossVariable = mSystemConfiguration.StateAfterG3; // // If LAN is disabled, WOL function should be disabled too. // if (mSystemConfiguration.Lan == 0x01){ mWakeOnLanS5Variable = mSystemConfiguration.WakeOnLanS5; } else { mWakeOnLanS5Variable = FALSE; } mWakeOnRtcVariable = mSystemConfiguration.WakeOnRtcS5; } BootMode = GetBootModeHob (); // // Get the Power Button protocol // Status = gBS->LocateProtocol( &gEfiSmmPowerButtonDispatchProtocolGuid, NULL, (void **)&PowerButtonDispatch ); ASSERT_EFI_ERROR(Status); if (BootMode != BOOT_ON_FLASH_UPDATE) { // // Register for the power button event // PowerButtonContext.Phase = PowerButtonEntry; Status = PowerButtonDispatch->Register( PowerButtonDispatch, PowerButtonCallback, &PowerButtonContext, &Handle ); ASSERT_EFI_ERROR(Status); } // // Get the Sx dispatch protocol // Status = gBS->LocateProtocol ( &gEfiSmmSxDispatchProtocolGuid, NULL, (void **)&SxDispatch ); ASSERT_EFI_ERROR(Status); // // Register entry phase call back function // EntryDispatchContext.Type = SxS3; EntryDispatchContext.Phase = SxEntry; Status = SxDispatch->Register ( SxDispatch, (EFI_SMM_SX_DISPATCH)SxSleepEntryCallBack, &EntryDispatchContext, &Handle ); EntryDispatchContext.Type = SxS4; Status = SxDispatch->Register ( SxDispatch, S4S5CallBack, &EntryDispatchContext, &Handle ); ASSERT_EFI_ERROR(Status); EntryDispatchContext.Type = SxS5; Status = SxDispatch->Register ( SxDispatch, S4S5CallBack, &EntryDispatchContext, &Handle ); ASSERT_EFI_ERROR(Status); Status = SxDispatch->Register ( SxDispatch, S5SleepAcLossCallBack, &EntryDispatchContext, &Handle ); ASSERT_EFI_ERROR(Status); // // Get the Sw dispatch protocol // Status = gBS->LocateProtocol ( &gEfiSmmSwDispatchProtocolGuid, NULL, (void **)&SwDispatch ); ASSERT_EFI_ERROR(Status); // // Register ACPI enable handler // SwContext.SwSmiInputValue = ACPI_ENABLE; Status = SwDispatch->Register ( SwDispatch, EnableAcpiCallback, &SwContext, &Handle ); ASSERT_EFI_ERROR(Status); // // Register ACPI disable handler // SwContext.SwSmiInputValue = ACPI_DISABLE; Status = SwDispatch->Register ( SwDispatch, DisableAcpiCallback, &SwContext, &Handle ); ASSERT_EFI_ERROR(Status); // // Register for SmmReadyToBootCallback // SwContext.SwSmiInputValue = SMI_SET_SMMVARIABLE_PROTOCOL; Status = SwDispatch->Register( SwDispatch, SmmReadyToBootCallback, &SwContext, &Handle ); ASSERT_EFI_ERROR(Status); // // Get the ICHn protocol // Status = gBS->LocateProtocol( &gEfiSmmIchnDispatchProtocolGuid, NULL, (void **)&IchnDispatch ); ASSERT_EFI_ERROR(Status); // // Register for the events that may happen that we do not care. // This is true for SMI related to TCO since TCO is enabled by BIOS WP // for (Index = 0; Index < sizeof(mTco1Sources)/sizeof(UINT8); Index++) { IchnContext.Type = mTco1Sources[Index]; Status = IchnDispatch->Register( IchnDispatch, (EFI_SMM_ICHN_DISPATCH)DummyTco1Callback, &IchnContext, &Handle ); ASSERT_EFI_ERROR( Status ); } // // Lock TCO_EN bit. // IoWrite16( mAcpiBaseAddr + R_PCH_TCO_CNT, IoRead16( mAcpiBaseAddr + R_PCH_TCO_CNT ) | B_PCH_TCO_CNT_LOCK ); // // Set to power on from G3 dependent on WOL instead of AC Loss variable in order to support WOL from G3 feature. // // // Set wake from G3 dependent on AC Loss variable and Wake On LAN variable. // This is because no matter how, if WOL enabled or AC Loss variable not disabled, the board needs to wake from G3 to program the LAN WOL settings. // This needs to be done after LAN enable/disable so that the PWR_FLR state clear not impacted the WOL from G3 feature. // if (mAcLossVariable != 0x00) { SetAfterG3On (TRUE); } else { SetAfterG3On (FALSE); } return EFI_SUCCESS; }