123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- /** @file
- Support FSP Wrapper MultiPhase process.
- Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <Library/BaseLib.h>
- #include <Library/DebugLib.h>
- #include <Library/PcdLib.h>
- #include <Library/FspWrapperApiLib.h>
- #include <Library/FspWrapperPlatformLib.h>
- #include <FspEas.h>
- #include <FspGlobalData.h>
- #include <Ppi/ReadOnlyVariable2.h>
- #include <Ppi/Variable.h>
- #include <Library/PeiServicesLib.h>
- #include <Library/FspWrapperPlatformMultiPhaseLib.h>
- /**
- Execute 32-bit FSP API entry code.
- @param[in] Function The 32bit code entry to be executed.
- @param[in] Param1 The first parameter to pass to 32bit code.
- @param[in] Param2 The second parameter to pass to 32bit code.
- @return EFI_STATUS.
- **/
- EFI_STATUS
- Execute32BitCode (
- IN UINT64 Function,
- IN UINT64 Param1,
- IN UINT64 Param2
- );
- /**
- Execute 64-bit FSP API entry code.
- @param[in] Function The 64bit code entry to be executed.
- @param[in] Param1 The first parameter to pass to 64bit code.
- @param[in] Param2 The second parameter to pass to 64bit code.
- @return EFI_STATUS.
- **/
- EFI_STATUS
- Execute64BitCode (
- IN UINT64 Function,
- IN UINT64 Param1,
- IN UINT64 Param2
- );
- /**
- Call FspsMultiPhase API.
- @param[in] FspsMultiPhaseParams - Parameters for MultiPhase API.
- @param[in] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed)
- @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization.
- @return EFI_UNSUPPORTED - the requested FspsMultiPhase API is not supported.
- @return EFI_DEVICE_ERROR - the FSP header was not found.
- @return EFI status returned by FspsMultiPhase API.
- **/
- EFI_STATUS
- EFIAPI
- CallFspMultiPhaseEntry (
- IN VOID *FspMultiPhaseParams,
- IN OUT VOID **FspHobListPtr,
- IN UINT8 ComponentIndex
- )
- {
- FSP_INFO_HEADER *FspHeader;
- //
- // FSP_MULTI_PHASE_INIT and FSP_MULTI_PHASE_SI_INIT API functions having same prototype.
- //
- UINTN FspMultiPhaseApiEntry;
- UINTN FspMultiPhaseApiOffset;
- EFI_STATUS Status;
- BOOLEAN InterruptState;
- BOOLEAN IsVariableServiceRequest;
- FSP_MULTI_PHASE_PARAMS *FspMultiPhaseParamsPtr;
- FspMultiPhaseParamsPtr = (FSP_MULTI_PHASE_PARAMS *)FspMultiPhaseParams;
- IsVariableServiceRequest = FALSE;
- if ((FspMultiPhaseParamsPtr->MultiPhaseAction == EnumMultiPhaseGetVariableRequestInfo) ||
- (FspMultiPhaseParamsPtr->MultiPhaseAction == EnumMultiPhaseCompleteVariableRequest))
- {
- IsVariableServiceRequest = TRUE;
- }
- if (ComponentIndex == FspMultiPhaseMemInitApiIndex) {
- FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress));
- if (FspHeader == NULL) {
- return EFI_DEVICE_ERROR;
- } else if (FspHeader->SpecVersion < 0x24) {
- return EFI_UNSUPPORTED;
- }
- FspMultiPhaseApiOffset = FspHeader->FspMultiPhaseMemInitEntryOffset;
- } else if (ComponentIndex == FspMultiPhaseSiInitApiIndex) {
- FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress));
- if (FspHeader == NULL) {
- return EFI_DEVICE_ERROR;
- } else if (FspHeader->SpecVersion < 0x22) {
- return EFI_UNSUPPORTED;
- } else if ((FspHeader->SpecVersion < 0x24) && (IsVariableServiceRequest == TRUE)) {
- return EFI_UNSUPPORTED;
- }
- FspMultiPhaseApiOffset = FspHeader->FspMultiPhaseSiInitEntryOffset;
- }
- if (FspMultiPhaseApiOffset == 0) {
- return EFI_UNSUPPORTED;
- }
- FspMultiPhaseApiEntry = FspHeader->ImageBase + FspMultiPhaseApiOffset;
- InterruptState = SaveAndDisableInterrupts ();
- if ((FspHeader->ImageAttribute & BIT2) == 0) {
- // BIT2: IMAGE_ATTRIBUTE_64BIT_MODE_SUPPORT
- Status = Execute32BitCode ((UINTN)FspMultiPhaseApiEntry, (UINTN)FspMultiPhaseParams, (UINTN)NULL);
- } else {
- Status = Execute64BitCode ((UINTN)FspMultiPhaseApiEntry, (UINTN)FspMultiPhaseParams, (UINTN)NULL);
- }
- SetInterruptState (InterruptState);
- DEBUG ((DEBUG_ERROR, "CallFspMultiPhaseEntry return Status %r \n", Status));
- return Status;
- }
- /**
- FSP Wrapper Variable Request Handler
- @param[in, out] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed)
- @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization.
- @retval EFI_UNSUPPORTED FSP Wrapper cannot support the specific variable request,
- or FSP does not support VariableService
- @retval EFI_STATUS Return FSP returned status
- **/
- EFI_STATUS
- EFIAPI
- FspWrapperVariableRequestHandler (
- IN OUT VOID **FspHobListPtr,
- IN UINT8 ComponentIndex
- )
- {
- EFI_STATUS Status;
- FSP_MULTI_PHASE_PARAMS FspMultiPhaseParams;
- FSP_MULTI_PHASE_VARIABLE_REQUEST_INFO_PARAMS *FspVariableRequestParams;
- EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariablePpi;
- EDKII_PEI_VARIABLE_PPI *VariablePpi;
- BOOLEAN WriteVariableSupport;
- FSP_MULTI_PHASE_COMPLETE_VARIABLE_REQUEST_PARAMS CompleteVariableRequestParams;
- WriteVariableSupport = TRUE;
- Status = PeiServicesLocatePpi (
- &gEdkiiPeiVariablePpiGuid,
- 0,
- NULL,
- (VOID **)&VariablePpi
- );
- if (EFI_ERROR (Status)) {
- WriteVariableSupport = FALSE;
- Status = PeiServicesLocatePpi (
- &gEfiPeiReadOnlyVariable2PpiGuid,
- 0,
- NULL,
- (VOID **)&ReadOnlyVariablePpi
- );
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR (Status)) {
- return EFI_UNSUPPORTED;
- }
- }
- Status = FSP_STATUS_VARIABLE_REQUEST;
- while (Status == FSP_STATUS_VARIABLE_REQUEST) {
- //
- // Get the variable request information from FSP.
- //
- FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseGetVariableRequestInfo;
- FspMultiPhaseParams.PhaseIndex = 0;
- Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
- ASSERT_EFI_ERROR (Status);
- //
- // FSP should output this pointer for variable request information.
- //
- FspVariableRequestParams = (FSP_MULTI_PHASE_VARIABLE_REQUEST_INFO_PARAMS *)FspMultiPhaseParams.MultiPhaseParamPtr;
- switch (FspVariableRequestParams->VariableRequest) {
- case EnumFspVariableRequestGetVariable:
- if (WriteVariableSupport) {
- Status = VariablePpi->GetVariable (
- VariablePpi,
- FspVariableRequestParams->VariableName,
- FspVariableRequestParams->VariableGuid,
- FspVariableRequestParams->Attributes,
- (UINTN *)FspVariableRequestParams->DataSize,
- FspVariableRequestParams->Data
- );
- } else {
- Status = ReadOnlyVariablePpi->GetVariable (
- ReadOnlyVariablePpi,
- FspVariableRequestParams->VariableName,
- FspVariableRequestParams->VariableGuid,
- FspVariableRequestParams->Attributes,
- (UINTN *)FspVariableRequestParams->DataSize,
- FspVariableRequestParams->Data
- );
- }
- CompleteVariableRequestParams.VariableRequestStatus = Status;
- FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;
- FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;
- Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
- break;
- case EnumFspVariableRequestSetVariable:
- if (WriteVariableSupport) {
- Status = VariablePpi->SetVariable (
- VariablePpi,
- FspVariableRequestParams->VariableName,
- FspVariableRequestParams->VariableGuid,
- *FspVariableRequestParams->Attributes,
- (UINTN)*FspVariableRequestParams->DataSize,
- FspVariableRequestParams->Data
- );
- } else {
- Status = EFI_UNSUPPORTED;
- }
- CompleteVariableRequestParams.VariableRequestStatus = Status;
- FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;
- FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;
- Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
- break;
- case EnumFspVariableRequestGetNextVariableName:
- if (WriteVariableSupport) {
- Status = VariablePpi->GetNextVariableName (
- VariablePpi,
- (UINTN *)FspVariableRequestParams->VariableNameSize,
- FspVariableRequestParams->VariableName,
- FspVariableRequestParams->VariableGuid
- );
- } else {
- Status = ReadOnlyVariablePpi->NextVariableName (
- ReadOnlyVariablePpi,
- (UINTN *)FspVariableRequestParams->VariableNameSize,
- FspVariableRequestParams->VariableName,
- FspVariableRequestParams->VariableGuid
- );
- }
- CompleteVariableRequestParams.VariableRequestStatus = Status;
- FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;
- FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;
- Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
- break;
- case EnumFspVariableRequestQueryVariableInfo:
- if (WriteVariableSupport) {
- Status = VariablePpi->QueryVariableInfo (
- VariablePpi,
- *FspVariableRequestParams->Attributes,
- FspVariableRequestParams->MaximumVariableStorageSize,
- FspVariableRequestParams->RemainingVariableStorageSize,
- FspVariableRequestParams->MaximumVariableSize
- );
- } else {
- Status = EFI_UNSUPPORTED;
- }
- CompleteVariableRequestParams.VariableRequestStatus = Status;
- FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams;
- FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest;
- Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
- break;
- default:
- DEBUG ((DEBUG_ERROR, "Unknown VariableRequest type!\n"));
- Status = EFI_UNSUPPORTED;
- break;
- }
- }
- //
- // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
- //
- if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {
- DEBUG ((DEBUG_INFO, "FspMultiPhaseApi-0x%x requested reset %r\n", ComponentIndex, Status));
- CallFspWrapperResetSystem ((UINTN)Status);
- }
- return Status;
- }
- /**
- FSP Wrapper MultiPhase Handler
- @param[in, out] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed)
- @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization.
- @retval EFI_UNSUPPORTED Specific MultiPhase action was not supported.
- @retval EFI_SUCCESS MultiPhase action were completed successfully.
- **/
- EFI_STATUS
- EFIAPI
- FspWrapperMultiPhaseHandler (
- IN OUT VOID **FspHobListPtr,
- IN UINT8 ComponentIndex
- )
- {
- EFI_STATUS Status;
- FSP_MULTI_PHASE_PARAMS FspMultiPhaseParams;
- FSP_MULTI_PHASE_GET_NUMBER_OF_PHASES_PARAMS FspMultiPhaseGetNumber;
- UINT32 Index;
- UINT32 NumOfPhases;
- //
- // Query FSP for the number of phases supported.
- //
- FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseGetNumberOfPhases;
- FspMultiPhaseParams.PhaseIndex = 0;
- FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&FspMultiPhaseGetNumber;
- Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
- if (Status == EFI_UNSUPPORTED) {
- //
- // MultiPhase API was not supported
- //
- return Status;
- } else {
- ASSERT_EFI_ERROR (Status);
- }
- NumOfPhases = FspMultiPhaseGetNumber.NumberOfPhases;
- for (Index = 1; Index <= NumOfPhases; Index++) {
- DEBUG ((DEBUG_ERROR, "MultiPhase Index/NumOfPhases = %d of %d\n", Index, NumOfPhases));
- //
- // Platform actions can be added in below function for each component and phase before returning control back to FSP.
- //
- FspWrapperPlatformMultiPhaseHandler (FspHobListPtr, ComponentIndex, Index);
- FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseExecutePhase;
- FspMultiPhaseParams.PhaseIndex = Index;
- FspMultiPhaseParams.MultiPhaseParamPtr = NULL;
- Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex);
- if (Status == FSP_STATUS_VARIABLE_REQUEST) {
- //
- // call to Variable request handler
- //
- FspWrapperVariableRequestHandler (FspHobListPtr, ComponentIndex);
- }
- //
- // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status
- //
- if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) {
- DEBUG ((DEBUG_INFO, "FspMultiPhaseApi-0x%x requested reset %r\n", ComponentIndex, Status));
- CallFspWrapperResetSystem ((UINTN)Status);
- }
- ASSERT_EFI_ERROR (Status);
- }
- return EFI_SUCCESS;
- }
|