/********************************************************************************* * Name: FchAcpiCsInit * * Description * Entry point of the AMD FCH ACPI driver * * Input * ImageHandle : EFI Image Handle for the DXE driver * SystemTable : pointer to the EFI system table * * Output * EFI_SUCCESS : Module initialized successfully * EFI_ERROR : Initialization failed (see error for more details) * *********************************************************************************/ EFI_STATUS EFIAPI FchAcpiCsInit ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { VOID *Registration; EFI_STATUS Status; EFI_EVENT Event; DxeInitializeDriverLib (ImageHandle, SystemTable); Status = LibFchDxeInitialization (SystemTable); // Allocate memory for the private data Status = gBS->AllocatePool ( EfiReservedMemoryType, sizeof (AMD_FCH_COMMON_DATA), &mFchCommonData ); ASSERT_EFI_ERROR (Status); // Initialize the Config table with default value Status = FchInitDefaultConfigDxe (mFchCommonData); //Register event to do FCH ACPI Initialization at Ready-to-Boot Status = EfiCreateEventReadyToBoot ( EFI_TPL_CALLBACK, FchAcpiReadyToBootInit, NULL, &Event ); // // Register event for FchAcpiInstallNotify // EfiLibCreateProtocolNotifyEvent ( &gEfiAcpiSdtProtocolGuid, EFI_TPL_CALLBACK, FchAcpiInstallNotify, NULL, &Registration ); // // Register event for FchAcpiInstallNotify // EfiLibCreateProtocolNotifyEvent ( &gEfiPciIoProtocolGuid, EFI_TPL_CALLBACK, FchAcpiInstall2Notify, NULL, &Registration ); return Status; }
/** Create, Signal, and Close the Ready to Boot event using EfiSignalEventReadyToBoot(). This function abstracts the signaling of the Ready to Boot Event. The Framework moved from a proprietary to UEFI 2.0 based mechanism. This library abstracts the caller from how this event is created to prevent to code form having to change with the version of the specification supported. **/ VOID EFIAPI EfiSignalEventReadyToBoot ( VOID ) { EFI_STATUS Status; EFI_EVENT ReadyToBootEvent; Status = EfiCreateEventReadyToBoot (&ReadyToBootEvent); if (!EFI_ERROR (Status)) { gBS->SignalEvent (ReadyToBootEvent); gBS->CloseEvent (ReadyToBootEvent); } }
/******************************************************************************** * Name: AmdFchWheaInitEntry * * Description * AmdFchWheaInit Entrypoint * * Input * * Output * EFI_UNSUPPORTED : unsupported function * *********************************************************************************/ EFI_STATUS AmdFchWheaInitEntry ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; BOOLEAN InSmm; FCH_INIT_PROTOCOL *AmdFchInit; EFI_SMM_BASE_PROTOCOL *SmmBase; FCH_SMM_SW_DISPATCH_PROTOCOL *AmdSwDispatch; FCH_SMM_SW_REGISTER_CONTEXT SwRegisterContext; EFI_HANDLE SwHandle; FCH_SMM_MISC_DISPATCH_PROTOCOL *AmdFchSmmMiscDispatch; FCH_SMM_MISC_REGISTER_CONTEXT MiscRegisterContext; EFI_HANDLE MiscHandle; EFI_SMM_SYSTEM_TABLE *mSmst; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath; EFI_DEVICE_PATH_PROTOCOL *CompleteFilePath; EFI_HANDLE SmmImageHandle; EFI_EVENT InstallAmdTableEvent; EFI_HANDLE Handle; UINT8 *buffer; InSmm = FALSE; DxeInitializeDriverLib (ImageHandle, SystemTable); Status = gBS->LocateProtocol ( &gFchInitProtocolGuid, NULL, &AmdFchInit ); ASSERT_EFI_ERROR (Status); if (AmdFchInit->FchPolicy.Gpp.PcieAer == 0) { return Status; } Status = gBS->LocateProtocol ( &gEfiSmmBaseProtocolGuid, NULL, &SmmBase ); if (EFI_ERROR (Status)) { return Status; } SmmBase->GetSmstLocation ( SmmBase, &mSmst ); SmmBase->InSmm ( SmmBase, &InSmm ); if (!InSmm) { Status = EfiCreateEventReadyToBoot ( EFI_TPL_CALLBACK, AmdWheaCheckInstallTables, NULL, &InstallAmdTableEvent ); // // Allocate memory and Initialize for Data block // Status = gBS->AllocatePool ( EfiReservedMemoryType, sizeof (AMD_FCH_WHEA_EINJ_BUFFER), (VOID **)&buffer ); if (EFI_ERROR (Status)) { return Status; } EfiZeroMem (buffer, sizeof (AMD_FCH_WHEA_EINJ_BUFFER)); mEinjData = (AMD_FCH_WHEA_EINJ_BUFFER *)buffer; mEinjData->Valid = FALSE; mEinjData->PlatformEinjValid = FALSE; // // Allocate memory and Initialize for Error Data block // Status = gBS->AllocatePool ( EfiReservedMemoryType, MAX_ERROR_BLOCK_SIZE, (VOID **)&buffer ); if (EFI_ERROR (Status)) { return Status; } EfiZeroMem (buffer, MAX_ERROR_BLOCK_SIZE); mEinjData->AmdHwErrBlk = (GENERIC_ERROR_STATUS_BLOCK *)buffer; AmdErrBlkAddressUpdate (); Handle = ImageHandle; Status = gBS->InstallProtocolInterface ( &Handle, &mEfiAmdFchWheaDataGuid, EFI_NATIVE_INTERFACE, mEinjData ); if (EFI_ERROR (Status)) { return (Status); } if (ImageHandle != NULL) { Status = gBS->HandleProtocol ( ImageHandle, &gEfiLoadedImageProtocolGuid, &LoadedImage ); if (EFI_ERROR (Status)) { return Status; } Status = gBS->HandleProtocol ( LoadedImage->DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID*) &ImageDevicePath ); if (EFI_ERROR (Status)) { return Status; } CompleteFilePath = AppendDevicePath ( ImageDevicePath, LoadedImage->FilePath ); // Load the image in memory to SMRAM, this automatically triggers SMI SmmBase->Register ( SmmBase, CompleteFilePath, NULL, 0, &SmmImageHandle, FALSE ); } } else { Status = gBS->LocateProtocol ( &mEfiAmdFchWheaDataGuid, NULL, &mEinjData ); if (EFI_ERROR (Status)) { return Status; } Status = gBS->LocateProtocol ( &gFchSmmSwDispatchProtocolGuid, NULL, &AmdSwDispatch ); ASSERT_EFI_ERROR (Status); SwRegisterContext.AmdSwValue = EINJ_TRIGGER_ACTION_SWSMI; Status = AmdSwDispatch->Register ( AmdSwDispatch, AmdSmiEinjTriggerActionCallBack, &SwRegisterContext, &SwHandle ); if (EFI_ERROR (Status)) { return Status; } Status = gBS->LocateProtocol ( &gFchSmmMiscDispatchProtocolGuid, NULL, &AmdFchSmmMiscDispatch ); ASSERT_EFI_ERROR (Status); MiscRegisterContext.SmiStatusReg = FCH_SMI_REG88; MiscRegisterContext.SmiStatusBit = BIT21; MiscRegisterContext.Order = 0x80; Status = AmdFchSmmMiscDispatch->Register ( AmdFchSmmMiscDispatch, AmdMiscFchWheaHwSmiCallback, &MiscRegisterContext, &MiscHandle ); MiscRegisterContext.SmiStatusReg = FCH_SMI_REG88; MiscRegisterContext.SmiStatusBit = BIT22; MiscRegisterContext.Order = 0x80; Status = AmdFchSmmMiscDispatch->Register ( AmdFchSmmMiscDispatch, AmdMiscFchWheaHwSmiCallback, &MiscRegisterContext, &MiscHandle ); MiscRegisterContext.SmiStatusReg = FCH_SMI_REG88; MiscRegisterContext.SmiStatusBit = BIT23; MiscRegisterContext.Order = 0x80; Status = AmdFchSmmMiscDispatch->Register ( AmdFchSmmMiscDispatch, AmdMiscFchWheaHwSmiCallback, &MiscRegisterContext, &MiscHandle ); MiscRegisterContext.SmiStatusReg = FCH_SMI_REG88; MiscRegisterContext.SmiStatusBit = BIT24; MiscRegisterContext.Order = 0x80; Status = AmdFchSmmMiscDispatch->Register ( AmdFchSmmMiscDispatch, AmdMiscFchWheaHwSmiCallback, &MiscRegisterContext, &MiscHandle ); ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGB4) &= ~(BIT11 + BIT13 + BIT15 + BIT17); ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGB4) |= (BIT10 + BIT12 + BIT14 + BIT16); } return Status; }
/********************************************************************************* * Name: FchDxeInit * * Description * Entry point of the AMD FCH DXE driver * Perform the configuration init, resource reservation, early post init * and install all the supported protocol * * Input * ImageHandle : EFI Image Handle for the DXE driver * SystemTable : pointer to the EFI system table * * Output * EFI_SUCCESS : Module initialized successfully * EFI_ERROR : Initialization failed (see error for more details) * *********************************************************************************/ EFI_STATUS EFIAPI FchDxeInit ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { FCH_DXE_PRIVATE *FchPrivate; EFI_STATUS Status; EFI_HANDLE Handle; FCH_DATA_BLOCK *FchDataBlock; // // Initialize EFI library // Status = LibFchDxeInitialization (SystemTable); ASSERT_EFI_ERROR (Status); // // Initialize the configuration structure and private data area // // Allocate memory for the private data Status = gBS->AllocatePool ( EfiACPIMemoryNVS, sizeof (FCH_DXE_PRIVATE), &FchPrivate ); ASSERT_EFI_ERROR (Status); // Initialize the private data structure FchPrivate->Signature = FCH_DXE_PRIVATE_DATA_SIGNATURE; // Initialize the FCHInit protocol FchPrivate->FchInit.Revision = FCH_INIT_REV; FchPrivate->FchInit.FchRev = FCH_VERSION; FchPrivate->FchInit.FpUsbOverCurrent = UsbOverCurrentControl; FchDataBlock = FchLocateHeapBuffer (); gBS->CopyMem ( &FchPrivate->FchInit.FchPolicy, FchDataBlock, sizeof (FCH_DATA_BLOCK) ); // // Publish the FCHInit protocol // Handle = ImageHandle; Status = gBS->InstallProtocolInterface ( &Handle, &gFchInitProtocolGuid, EFI_NATIVE_INTERFACE, &FchPrivate->FchInit ); if (EFI_ERROR (Status)) { return (Status); } Status = EfiCreateEventReadyToBoot ( EFI_TPL_CALLBACK, FchInitOnReadyToBoot, (VOID*) &(FchPrivate->FchInit.FchPolicy), &FchPrivate->EventReadyToBoot ); Handle = ImageHandle; Status = gBS->InstallProtocolInterface ( &Handle, &gFchInitDonePolicyProtocolGuid, EFI_NATIVE_INTERFACE, NULL ); return (Status); }