/** Display the forbid load device path list (mAccessInfo.LoadForbid). **/ VOID DisplayLoadForbid ( VOID ) { UINTN Offset; UINTN DPSize; UINTN Index; EFI_DEVICE_PATH_PROTOCOL *Dp; VOID *StartOpCodeHandle; VOID *EndOpCodeHandle; EFI_IFR_GUID_LABEL *StartLabel; EFI_IFR_GUID_LABEL *EndLabel; // // Initialize the container for dynamic opcodes. // StartOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (StartOpCodeHandle != NULL); EndOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (EndOpCodeHandle != NULL); // // Create Hii Extend Label OpCode. // StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL) ); StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; StartLabel->Number = LABLE_FORBID_LOAD_FUNC; EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL) ); EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; EndLabel->Number = LABEL_END; // // Add each forbid load drivers. // Offset = 0; Index = 0; while (Offset < mAccessInfo.LoadForbidLen) { Dp = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + Offset); DPSize = GetDevicePathSize (Dp); AddDevicePath ( KEY_MODIFY_USER | KEY_MODIFY_AP_DP | KEY_LOAD_FORBID_MODIFY | Index, Dp, StartOpCodeHandle ); Index++; Offset += DPSize; } HiiUpdateForm ( mCallbackInfo->HiiHandle, // HII handle &gUserProfileManagerGuid, // Formset GUID FORMID_FORBID_LOAD_DP, // Form ID StartOpCodeHandle, // Label for where to insert opcodes EndOpCodeHandle // Replace data ); HiiFreeOpCodeHandle (StartOpCodeHandle); HiiFreeOpCodeHandle (EndOpCodeHandle); }
EFI_STATUS EFIAPI AmdRasSmmDxeDriverEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; BOOLEAN InSmm; EFI_HANDLE hNrthBrdgError = NULL; EFI_SMM_BASE_PROTOCOL *SmmBase = NULL; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage = NULL; EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath = NULL; EFI_DEVICE_PATH_PROTOCOL *NewFilePath = NULL; AMD_RAS_DXE_INTERFACE_PROTOCOL *RasIntProtocol = NULL; SMM_SETUP_CONFIG SmmSetupCfg; // Initialize Global Variables Status = InitializeRasRuntime ( ImageHandle, // IN EFI_HANDLE SystemTable // IN EFI_SYSTEM_TABLE ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; // Error detected while trying to locate SMM Base Protocol } // Locate SMM Base Protocol Status = gBS->LocateProtocol ( &gEfiSmmBaseProtocolGuid, // IN EFI_GUID Published unique identifier of requested protocol GUID to locate NULL, // IN VOID* Published unique identifier of requested protocol GUID &SmmBase // OUT VOID** Returns address of pointer for SMM Base protocol interface ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; // Error detected while trying to locate SMM Base Protocol } // Save the SMM Base system table pointer SmmBase->GetSmstLocation (SmmBase, &gSmst); // Determine if we are in SMM or not SmmBase->InSmm (SmmBase, &InSmm); if (!InSmm) { // // Not in SMM so load this driver's SMM image to memory // // Configure Northbridge Interrupt Event to make an I/O Write to SMI Command Port in the // Southbridge and cause a Software SMI for which we will handle in the NbSmiHandler // SMI service routine. Status = ConfigNbSmiProcessing (); // Query image handle to see if it supports a requested protocol and then get an address of the protocol image to be loaded Status = gBS->HandleProtocol ( ImageHandle, // Handle of requested protocol &gEfiLoadedImageProtocolGuid, // Published unique identifier of requested protocol GUID (VOID*)&LoadedImage // Returns address of pointer for requested protocol interface of the image ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; // Error detected while trying to query LoadImage protocol } // Query device handle of loaded image to see if it supports a requested protocol and then get an address of the prototocl device path Status = gBS->HandleProtocol ( LoadedImage->DeviceHandle, // Handle of requested protocol &gEfiDevicePathProtocolGuid, // Published unique identifier of requested protocol GUID (VOID*)&ImageDevicePath // Returns address of pointer for requested protocol interface ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; } // Add this image's device path to the loaded image device path image and return // a pointer to the new file path. NewFilePath = AddDevicePath ( ImageDevicePath, // IN EFI_DEVICE_PATH_PROTOCOL LoadedImage->FilePath // IN EFI_DEVICE_PATH_PROTOCOL Device Path Image to add ); //Load the image in System Management RAM; it will automatically generate SMI. Status = SmmBase->Register ( SmmBase, // IN *This Addreess of pointer for SMM Base protocol interface) NewFilePath, // IN EFI_DEVICE_PATH_PROTOCOL NULL, // IN SourceBuffer OPTIONAL 0, // IN SourceSize OPTIONAL &hNrthBrdgError, // OUT *ImageHandle FALSE // IN LegacyIA32Binary OPTIONAL ); // Free up residual heap memory if not equal to NULL if (NewFilePath) { gBS->FreePool (NewFilePath); } } else { // We are in SMM // // Callout to use platform-specific Setup // Status = AmdRasSmmCallout (ECC_HNDLR_CALLOUT_ID, &SmmSetupCfg); if (EFI_ERROR (Status)) { SmmSetupCfg.EccHandlerEnable = FALSE; //Load default value = ECC Disabled } // Enable / Disable RAS MCA ECC Support if (SmmSetupCfg.EccHandlerEnable == TRUE) { // Callback to execute from within SMM, error occurs if called from Boot Services mode Status = SmmBase->RegisterCallback ( SmmBase, // IN *This ImageHandle, // IN SmmImageHandle MC4SmmHandler, // IN EFI SMM Dispatcher Callback Entry Point Address FALSE, // IN Makelast (SMM Dispatcher should call this handler last) OPTIONAL FALSE // IN FloatingPointSave OPTIONAL ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; } // Update Global Varibles for this driver Status = UpdateGlobalVars (); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; } } //End-- Enable / Disable ECC Handler Support } // End-- if(!InSmm) if (!InSmm) { // Allocate memory for a new protocol structure Status = gBS->AllocatePool ( EfiBootServicesData, sizeof (AMD_RAS_DXE_INTERFACE_PROTOCOL), &RasIntProtocol ); if (RasIntProtocol == NULL) { return EFI_OUT_OF_RESOURCES; } // Zero out memory buffer EfiCommonLibZeroMem ( RasIntProtocol, sizeof (AMD_RAS_DXE_INTERFACE_PROTOCOL) ); // Locate AMD RAS Interface Protocol Status = gBS->LocateProtocol ( &gAmdRasDxeInterfaceProtocolGuid, // IN EFI_GUID Published unique identifier of requested protocol GUID to locate NULL, // IN VOID* Published unique identifier of requested protocol GUID (VOID **)&RasIntProtocol // OUT VOID** Returns address of pointer for SMM Base protocol interface ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; // Error detected while trying to locate RAS Interface Protocol } // Callout to get ECC Threshold BIOS Setup option config. Status = AmdRasSmmCallout (ECC_THRESH_COUNTER_CALLOUT_ID, &SmmSetupCfg); if (EFI_ERROR (Status)) { gRasNbCorrMemConfig.ThreshLimit = 0xFFE; // Load default value = threshold value of 1 (1's complement) } else { gRasNbCorrMemConfig.ThreshLimit = SmmSetupCfg.DramErrorThreshold; } // Callout to get RAS Handle Type BIOS Setup option config. Status = AmdRasSmmCallout (RAS_HANDLE_CALLOUT_ID, &SmmSetupCfg); if (EFI_ERROR (Status)) { gRasNbCorrMemConfig.DevCommon.ErrorMonitorType = APIC; // Default to APIC interrupt = 1 on error } else { if (SmmSetupCfg.RasHandleType == 1) { gRasNbCorrMemConfig.DevCommon.ErrorMonitorType = APIC; // APIC interrupt = 1 } } // Configure Correctable Memory Error Operation Status = RasIntProtocol->AmdSetErrorConfigDevice ( RasIntProtocol, // IN *This gRasNbCorrMemConfig.DevCommon.DeviceID, // IN UINTN (enum AMD_RAS_DEVICE_ID) (VOID*) &gRasNbCorrMemConfig // IN OUT VOID* RAS Device Struct ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; // Error detected while trying to locate SMM Base Protocol } // Configure UnCorrectable Memory Error Operation Status = RasIntProtocol->AmdSetErrorConfigDevice ( RasIntProtocol, // IN *This gRasNbUnCorrMemConfig.DevCommon.DeviceID, // IN UINTN (enum AMD_RAS_DEVICE_ID) (VOID*) &gRasNbUnCorrMemConfig // IN OUT VOID* RAS Device Struct ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return EFI_SUCCESS; // Error detected while trying to locate SMM Base Protocol } } // End-- if (!InSmm) return Status; }
/** Display the permit load device path in the loadable device path list. **/ VOID DisplayLoadPermit( VOID ) { EFI_STATUS Status; CHAR16 *Order; UINTN OrderSize; UINTN ListCount; UINTN Index; UINT8 *Var; UINT8 *VarPtr; CHAR16 VarName[12]; VOID *StartOpCodeHandle; VOID *EndOpCodeHandle; EFI_IFR_GUID_LABEL *StartLabel; EFI_IFR_GUID_LABEL *EndLabel; // // Get DriverOrder. // OrderSize = 0; Status = gRT->GetVariable ( L"DriverOrder", &gEfiGlobalVariableGuid, NULL, &OrderSize, NULL ); if (Status != EFI_BUFFER_TOO_SMALL) { return ; } Order = AllocateZeroPool (OrderSize); if (Order == NULL) { return ; } Status = gRT->GetVariable ( L"DriverOrder", &gEfiGlobalVariableGuid, NULL, &OrderSize, Order ); if (EFI_ERROR (Status)) { return ; } // // Initialize the container for dynamic opcodes. // StartOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (StartOpCodeHandle != NULL); EndOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (EndOpCodeHandle != NULL); // // Create Hii Extend Label OpCode. // StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL) ); StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; StartLabel->Number = LABEL_PERMIT_LOAD_FUNC; EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL) ); EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; EndLabel->Number = LABEL_END; // // Add each driver option. // Var = NULL; ListCount = OrderSize / sizeof (UINT16); for (Index = 0; Index < ListCount; Index++) { // // Get driver device path. // UnicodeSPrint (VarName, sizeof (VarName), L"Driver%04x", Order[Index]); Var = GetEfiGlobalVariable (VarName); if (Var == NULL) { continue; } // // Check whether the driver is already forbidden. // VarPtr = Var; // // Skip attribute. // VarPtr += sizeof (UINT32); // // Skip device path lenth. // VarPtr += sizeof (UINT16); // // Skip descript string. // VarPtr += StrSize ((UINT16 *) VarPtr); if (IsLoadForbidden ((EFI_DEVICE_PATH_PROTOCOL *) VarPtr)) { FreePool (Var); Var = NULL; continue; } AddDevicePath ( KEY_MODIFY_USER | KEY_MODIFY_AP_DP | KEY_LOAD_PERMIT_MODIFY | Order[Index], (EFI_DEVICE_PATH_PROTOCOL *) VarPtr, StartOpCodeHandle ); FreePool (Var); Var = NULL; } HiiUpdateForm ( mCallbackInfo->HiiHandle, // HII handle &gUserProfileManagerGuid, // Formset GUID FORMID_PERMIT_LOAD_DP, // Form ID StartOpCodeHandle, // Label for where to insert opcodes EndOpCodeHandle // Replace data ); HiiFreeOpCodeHandle (StartOpCodeHandle); HiiFreeOpCodeHandle (EndOpCodeHandle); // // Clear Environment. // if (Var != NULL) { FreePool (Var); } FreePool (Order); }
EFI_STATUS EFIAPI AmdRasApeiDxeDriverEntryPoint ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status = EFI_SUCCESS; EFI_HANDLE Handle = NULL; EFI_HANDLE hEinj = NULL; AMD_RAS_APEI_PROTOCOL *AmdRasApeiProtocol; BOOLEAN InSmm; EFI_SMM_BASE_PROTOCOL *SmmBase = NULL; EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath = NULL; EFI_DEVICE_PATH_PROTOCOL *NewFilePath = NULL; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage = NULL; EFI_SMM_SW_DISPATCH_PROTOCOL *SwDispatch = NULL; EFI_SMM_SW_DISPATCH_CONTEXT SwContext; EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupportProtocol = NULL; EFI_HANDLE SwHandle = NULL; EFI_HANDLE hNewHandle = NULL; UINTN BufferSize; UINTN HestTblHandle; UINT64 Address64; UINT32 Value32; // // Initialize Local Variables // InSmm = FALSE; BufferSize = 0; HestTblHandle = 0; // // Initialize Global Variables // EfiInitializeApei (ImageHandle, SystemTable); // Locate SMM Base Protocol Status = gBS->LocateProtocol ( &gEfiSmmBaseProtocolGuid, // IN EFI_GUID Published unique identifier of requested protocol GUID to locate NULL, // IN VOID* Published unique identifier of requested protocol GUID &SmmBase // OUT VOID** Returns address of pointer for SMM Base protocol interface ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; // Error detected while trying to locate SMM Base Protocol } // Save the SMM Base system table pointer SmmBase->GetSmstLocation (SmmBase, &gSmst); // Determine if we are in SMM or not SmmBase->InSmm (SmmBase, &InSmm); if (!InSmm) { // Query image handle to see if it supports a requested protocol and then get an address of the protocol image to be loaded Status = gBS->HandleProtocol ( ImageHandle, // Handle of requested protocol &gEfiLoadedImageProtocolGuid, // Published unique identifier of requested protocol GUID (VOID*)&LoadedImage // Returns address of pointer for requested protocol interface of the image ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; // Error detected while trying to query LoadImage protocol } // Query device handle of loaded image to see if it supports a requested protocol and then get an address of the prototocl device path Status = gBS->HandleProtocol ( LoadedImage->DeviceHandle, // Handle of requested protocol &gEfiDevicePathProtocolGuid, // Published unique identifier of requested protocol GUID (VOID*) &ImageDevicePath // Returns address of pointer for requested protocol interface ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; } // Add this image's device path to the loaded image device path image and return // a pointer to the new file path. NewFilePath = AddDevicePath ( ImageDevicePath, // IN EFI_DEVICE_PATH_PROTOCOL* LoadedImage->FilePath // IN EFI_DEVICE_PATH_PROTOCOL* Device Path Image to add ); //Load the image in System Management RAM; it will automatically generate an SMI. Status = SmmBase->Register ( SmmBase, // IN *This Addreess of pointer for SMM Base protocol interface) NewFilePath, // IN EFI_DEVICE_PATH_PROTOCOL NULL, // IN SourceBuffer OPTIONAL 0, // IN SourceSize OPTIONAL &hEinj, // OUT *ImageHandle FALSE // IN LegacyIA32Binary OPTIONAL ); // Free up residual heap memory if not equal to NULL if (NewFilePath) { gBS->FreePool (NewFilePath); } if (EFI_ERROR (Status)) { switch (EFIERR (Status)) { case EFI_LOAD_ERROR: break; case EFI_INVALID_PARAMETER: break; case EFI_UNSUPPORTED: break; default: ; } return Status; } } else { // We are in SMM... // Allocate Memory for type Runtime Services Data - APEI Module Private Data Status = gBS->AllocatePool (EfiRuntimeServicesData, sizeof (APEI_DRIVER_PRIVATE_DATA), &mApeiPrivData); if (EFI_ERROR (Status)) { return Status; } // Allocate Memory for type Runtime Services Data - APEI Interface Status = gBS->AllocatePool (EfiRuntimeServicesData, sizeof (AMD_APEI_INTERFACE), &mApeiInterface); if (EFI_ERROR (Status)) { return Status; } // Locate SW SMM Dispatch Protocol Status = gBS->LocateProtocol ( &gEfiSmmSwDispatchProtocolGuid, // IN EFI_GUID Published unique identifier of requested protocol GUID to locate NULL, // IN VOID* Published unique identifier of requested protocol GUID &SwDispatch // OUT VOID** Returns address of pointer for SMM Base protocol interface ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; } SwContext.SwSmiInputValue = EINJ_BEGIN_INJ_CMD; // Register EINJ SMM callback handler. Status = SwDispatch->Register ( SwDispatch, // IN *This ApeiEinjSwSmiHandler, // IN EFI SW SMM Dispatcher Callback Entry Point Address &SwContext, // IN SwContext &SwHandle // IN OUT SwHandle ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; } SwContext.SwSmiInputValue = ERST_EXECUTE_OPERATION_CMD; // Register ERST SMM callback handler. Status = SwDispatch->Register ( SwDispatch, ApeiErstSwSmiHandler, &SwContext, &SwHandle ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return Status; } // Allocate Memory for the the AMD_RAS_APEI_PROTOCOL protocol. Status = gBS->AllocatePool ( EfiBootServicesData, // IN EFI_MEMORY_TYPE PoolType sizeof (AMD_RAS_APEI_PROTOCOL), // IN UINTN Size &AmdRasApeiProtocol // OUT VOID **Buffer ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return EFI_OUT_OF_RESOURCES; // Error detected while trying to locate SMM Base Protocol } EfiCommonLibZeroMem (AmdRasApeiProtocol, sizeof (AMD_RAS_APEI_PROTOCOL)); // Initialize BERT ApeiBertInit (); // Initialize HEST ApeiHestInit (); // Determine if we have ECC error enable bits set Address64 = mCfgMmioBase | ((0x18 << 15) | (3 << 12) | 0x44); //F3:44 MC4_NB_CFG Value32 = RasSmmReadMem32 (Address64); if (Value32 & (1 << 22)) { //Initialize EINJ if ECC is Enabled ApeiEinjInit (); } // Initialize ERST ApeiErstInit (); AmdRasApeiProtocol->AmdApeiInterface = mApeiInterface; mApeiInterface->ApeiPrivData = mApeiPrivData; AmdRasApeiProtocol->AddBootErrorRecordEntry = 0; AmdRasApeiProtocol->AddHestErrorSourceEntry = 0; Status = gBS->InstallProtocolInterface ( &Handle, // IN OUT EFI_HANDLE &gAmdRasApeiProtocolGuid, // IN EFI_GUID EFI_NATIVE_INTERFACE, // IN EFI_INITERFACE_TYPE AmdRasApeiProtocol // IN VOID* Interface ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return EFI_PROTOCOL_ERROR; // Error detected while trying to locate SMM Base Protocol } } // End-- if(!InSmm) // // Do more non-SMM configuration // if (!InSmm) { Status = gBS->LocateProtocol ( &gAmdRasApeiProtocolGuid, NULL, &AmdRasApeiProtocol ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return EFI_PROTOCOL_ERROR; // Error detected while trying to locate SMM Base Protocol } mApeiInterface = AmdRasApeiProtocol->AmdApeiInterface; mApeiPrivData = mApeiInterface->ApeiPrivData; // Initialize function pointers to protocol interfaces AmdRasApeiProtocol->AddBootErrorRecordEntry = &AddBertErrorRecord; AmdRasApeiProtocol->AddHestErrorSourceEntry = &AddHestErrorRecord; // // Find the protocol that was installed during SMM phase and reinstall it during // Non-SMM phase as well. // // Get the buffer size for the EFI_HANDLE BufferSize = sizeof (EFI_HANDLE); // Returns an array of handles that support a specified protocol. Status = gBS->LocateHandle ( ByProtocol, // IN EFI_LOCATE_SEARCH_TYPE SearchType &gAmdRasApeiProtocolGuid, // IN EFI_GUID *Protocol OPTIONAL NULL, // IN VOID *SearchKey OPTIONAL &BufferSize, // IN OUT UINTN BufferSize &hNewHandle // OUT EFI_HANDLE *Buffer ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return EFI_PROTOCOL_ERROR; // Error detected while trying to locate SMM Base Protocol } // Queries a handle to determine if it supports a specified protocol. Status = gBS->HandleProtocol ( hNewHandle, // IN EFI_HANDLE Handle &gAmdRasApeiProtocolGuid, // IN EFI_GUID *Protocol (VOID **) &AmdRasApeiProtocol // OUT VOID *NewInterface ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return EFI_PROTOCOL_ERROR; // Error detected while trying to locate SMM Base Protocol } // Local ACPI Protocol Status = gBS->LocateProtocol ( &gAcpiSupportGuid, NULL, (VOID **) &AcpiSupportProtocol ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return EFI_PROTOCOL_ERROR; // Error detected while trying to locate ACPI Support Protocol } //Add HEST table to the ACPI aware OS Status = AcpiSupportProtocol->SetAcpiTable ( AcpiSupportProtocol, // IN EFI_ACPI_SUPPORT_PROTOCOL *This mApeiInterface->ApeiPrivData->ApeiHestTbl, // IN VOID *Table OPTIONAL TRUE, // IN BOOLEAN Checksum EFI_ACPI_TABLE_VERSION_ALL, // IN EFI_ACPI_TABLE_VERSION Version &HestTblHandle // IN OUT UINTN *TableHandle ); ASSERT_EFI_ERROR (Status); // Reinstalls a protocol interface on a device handle. Status = gBS->ReinstallProtocolInterface ( hNewHandle, // IN EFI_HANDLE Handle &gAmdRasApeiProtocolGuid, // IN EFI_GUID *Protocol AmdRasApeiProtocol, // IN VOID *OldInterface AmdRasApeiProtocol // IN VOID *NewInterface ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return EFI_PROTOCOL_ERROR; // Error detected while trying to locate SMM Base Protocol } // Create a callback event to be executed at ReadyToBoot to publish APEI tables to OS. Status = gBS->CreateEventEx ( EFI_EVENT_NOTIFY_SIGNAL, EFI_TPL_NOTIFY, AddApeiTables, NULL, &gEfiEventReadyToBootGuid, &mEvtApeiReadyToBoot ); if (EFI_ERROR (Status)) { ASSERT_EFI_ERROR (Status); return EFI_OUT_OF_RESOURCES; // Error detected while trying to locate SMM Base Protocol } } return Status; }