EFI_STATUS EFIAPI AmdSmiEinjSystemContextRestore ( IN OUT VOID ) { UINT8 PortId; UINT32 Value32; EFI_STATUS Status; AMD_CONFIG_PARAMS StdHeader; Status = EFI_SUCCESS; if ((mEinjData != NULL) && (mEinjData->Valid)) { for ( PortId = 0; PortId < MAX_GPP_PORTS; PortId++ ) { ReadPci (PCI_ADDRESS (0, GPP_DEV_NUM, PortId, 0x00), AccessWidth32, &Value32, &StdHeader); if (Value32 != 0xffffffff) { ACPIMMIO16 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x04)) = mEinjData->SystemContext[PortId].CmdReg; ACPIMMIO16 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x3E)) = mEinjData->SystemContext[PortId].BridgeCntlReg; ACPIMMIO16 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x60)) = mEinjData->SystemContext[PortId].DeviceStatusReg; ACPIMMIO16 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x74)) = mEinjData->SystemContext[PortId].RootCntlReg; ACPIMMIO32 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x158)) = mEinjData->SystemContext[PortId].PcieUncorrErrMaskReg; ACPIMMIO32 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x15C)) = mEinjData->SystemContext[PortId].PcieUncorrErrSeverityReg; ACPIMMIO32 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x164)) = mEinjData->SystemContext[PortId].PcieCorrErrMaskReg; ACPIMMIO32 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x168)) = mEinjData->SystemContext[PortId].PcieAdvErrCapCntlReg; ACPIMMIO32 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x174)) = mEinjData->SystemContext[PortId].PcieRootErrCmdReg; } } mEinjData->Valid = FALSE; } return Status; }
EFI_STATUS EFIAPI AmdSmiEinjErrorInjectionSetup ( IN OUT VOID ) { UINT8 PortId; UINT32 Value32; EFI_STATUS Status; AMD_CONFIG_PARAMS StdHeader; Status = EFI_SUCCESS; for ( PortId = 0; PortId < MAX_GPP_PORTS; PortId++ ) { ReadPci (PCI_ADDRESS (0, GPP_DEV_NUM, PortId, 0x00), AccessWidth32, &Value32, &StdHeader); if (Value32 != 0xffffffff) { ACPIMMIO8 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x60)) |= 0x0F; ACPIMMIO8 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x17C)) |= 0x07; ACPIMMIO8 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x74)) |= 0x07; ACPIMMIO16 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x04)) |= 0x0100; ACPIMMIO8 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x3E)) |= 0x02; ACPIMMIO32 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x158)) &= 0xffc22fef; ACPIMMIO32 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x15C)) &= 0xffc22fef; ACPIMMIO16 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x164)) &= 0xce3f; ACPIMMIO16 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x168)) |= 0x0140; } } RwAlink (FCH_ABCFG_REGF4 | (UINT32) (ABCFG << 29), ~BIT4, 0x00, &StdHeader); return Status; }
/*++ Routine Description: SMI handler to HPET Interval Write Trap Arguments: DispatchHandle - The handle of this callback, obtained when registering DispatchContext - Pointer to the FCH_SMM_SW_DISPATCH_CONTEXT Returns: None. --*/ EFI_STATUS EFIAPI AmdMiscFchHpetIntervalCallback ( IN EFI_HANDLE DispatchHandle, IN FCH_SMM_MISC_REGISTER_CONTEXT *DispatchContext ) { ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REG90) |= BIT24; // //Enable IRQ2 trap ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGB8) |= BIT4; // return EFI_SUCCESS; }
/** * FixPsp4Ehang * * * @retval VOID * */ VOID FixPsp4Ehang ( OUT VOID ) { UINT32 IoApicNumber; for (IoApicNumber = 0; IoApicNumber < 24; IoApicNumber++) { ACPIMMIO32 (0xFEC00000) = 0x10 + (IoApicNumber << 1); ACPIMMIO32 (0xFEC00010) = BIT16; } ACPIMMIO32 (FCH_AOACx94S013_CONTROL) |= FCH_AOACx94S013_CONTROL_ARBITER_DIS + FCH_AOACx94S013_CONTROL_INTERRUPT_DIS; }
EFI_STATUS EnablePspFakeStsSmi ( VOID ) { FCH_SMM_MISC_DISPATCH_PROTOCOL *AmdFchSmmMiscDispatch; EFI_HANDLE MiscHandle; FCH_SMM_MISC_REGISTER_CONTEXT MiscRegisterContext; EFI_STATUS Status; UINT32 OrMask; UINT32 AndMask; // enable PSP SMM via Fake Sts0 ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REG84) |= BIT1; //Clear FakeSts0 OrMask = BIT1; AndMask = 0xFFFFFFFFul; S3BootScriptSaveMemReadWrite (S3BootScriptWidthUint32, (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REG84), &OrMask, &AndMask); ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REG98) &= ~BIT25; // Deassert fakeSts0 OrMask = 0; AndMask = (UINT32) ~BIT25; S3BootScriptSaveMemReadWrite (S3BootScriptWidthUint32, (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REG98), &OrMask, &AndMask); ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGA8) &= ~(BIT3 + BIT2); // Enable SMI [3:2] = 1 ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGA8) |= BIT2; OrMask = BIT2; AndMask = (UINT32) ~(BIT3 + BIT2); S3BootScriptSaveMemReadWrite (S3BootScriptWidthUint32, (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGA8), &OrMask, &AndMask); MiscRegisterContext.SmiStatusReg = FCH_SMI_REG84; MiscRegisterContext.SmiStatusBit = BIT1; MiscRegisterContext.Order = 0x80; Status = gSmst->SmmLocateProtocol ( &gFchSmmMiscDispatchProtocolGuid, NULL, &AmdFchSmmMiscDispatch ); if (EFI_ERROR (Status)) { return Status; } Status = AmdFchSmmMiscDispatch->Register ( AmdFchSmmMiscDispatch, &P2CmboxMiscSmiCallback, &MiscRegisterContext, &MiscHandle ); return Status; }
/** * Is External Clock Mode? * * * @retval TRUE or FALSE * */ BOOLEAN IsExternalClockMode ( OUT VOID ) { return ( (BOOLEAN) ((ACPIMMIO32 (ACPI_MMIO_BASE + MISC_BASE + SB_MISC_REG80) & BIT4) == 0) ); }
/** * Is LPC Rom? * * * @retval TRUE or FALSE * */ BOOLEAN IsLpcRom ( OUT VOID ) { return ( (BOOLEAN) ((ACPIMMIO32 (ACPI_MMIO_BASE + MISC_BASE + SB_MISC_REG80) & BIT1) == 0) ); }
/** * FchInitEnvUsbXhci - Config XHCI controller before PCI * emulation * * * * @param[in] FchDataPtr Fch configuration structure pointer. * */ VOID FchInitEnvUsbXhci ( IN VOID *FchDataPtr ) { FCH_DATA_BLOCK *LocalCfgPtr; AMD_CONFIG_PARAMS *StdHeader; LocalCfgPtr = (FCH_DATA_BLOCK *)FchDataPtr; StdHeader = LocalCfgPtr->StdHeader; if ( LocalCfgPtr->Usb.Xhci0Enable == TRUE ) { if ( LocalCfgPtr->Misc.S3Resume == 0 ) { XhciInitBeforePciInit (LocalCfgPtr); } else { if ( !((ACPIMMIO8 (FCH_AOACx6E_USB3_D3_CONTROL) & 0x3) == 0x3)) { if ( ACPIMMIO32 (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00) & BIT0 ) { XhciInitIndirectReg (LocalCfgPtr); } else { XhciInitBeforePciInit (LocalCfgPtr); } } } } else { // // for power saving. // FchXhciPowerSavingProgram (LocalCfgPtr); } }
EFI_STATUS EFIAPI AmdSmiEinjClrStatus ( IN OUT VOID ) { UINT8 PortId; UINT32 Value32; EFI_STATUS Status; AMD_CONFIG_PARAMS StdHeader; Status = EFI_SUCCESS; for ( PortId = 0; PortId < MAX_GPP_PORTS; PortId++ ) { ReadPci (PCI_ADDRESS (0, GPP_DEV_NUM, PortId, 0x00), AccessWidth32, &Value32, &StdHeader); if (Value32 != 0xffffffff) { ACPIMMIO8 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x62)) |= 0x0f; ACPIMMIO32 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x154)) |= 0x003ff030; ACPIMMIO16 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x160)) |= 0x31c0; ACPIMMIO8 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x180)) |= 0x7f; ACPIMMIO16 (PCIE_ADDRESS (mEinjData->PcieBaseAddress, 0, GPP_DEV_NUM, PortId, 0x06)) |= 0x4000; } } RwAlink (0x104C | (UINT32) (ABCFG << 29), 0xffffff0f, 0xf0, &StdHeader); RwMem (ACPI_MMIO_BASE + SMI_BASE + 0x3C, AccessWidth8, 0x00, BIT2); return Status; }
/** * FixPsp4Ehang * * * @retval VOID * */ VOID FixPsp4Ehang ( OUT VOID ) { UINT8 Value8; UINT32 IoApicNumber; AMD_CONFIG_PARAMS *StdHeader; FCH_DATA_BLOCK *pFchPolicy; pFchPolicy = &gFchInitInSmm.FchPolicy; StdHeader = pFchPolicy->StdHeader; //FCH_DEADLOOP (); ACPIMMIO32 (FCH_AOACx94S013_CONTROL) |= FCH_AOACx94S013_CONTROL_ARBITER_DIS + FCH_AOACx94S013_CONTROL_INTERRUPT_DIS; ACPIMMIO32 (0xFEC00000) = 0x3E; ACPIMMIO32 (0xFEC00010) = 0xFF; LibAmdIoRead (AccessWidth8, FCH_IOMAP_REGED, &Value8, StdHeader); ACPIMMIO32 (0xFEC00020) = 0x17; LibAmdIoRead (AccessWidth8, FCH_IOMAP_REGED, &Value8, StdHeader); IoApicNumber = ACPIMMIO32 (0xFEC00020); for (IoApicNumber = 0; IoApicNumber < 24; IoApicNumber++) { ACPIMMIO32 (0xFEC00000) = 0x10 + (IoApicNumber << 1); ACPIMMIO32 (0xFEC00010) = BIT16; } }
/*++ Routine Description: SMI handler to Irq2 Trap Arguments: DispatchHandle - The handle of this callback, obtained when registering DispatchContext - Pointer to the FCH_SMM_SW_DISPATCH_CONTEXT Returns: None. --*/ EFI_STATUS EFIAPI AmdMiscFchIrq2TrapCallback ( IN EFI_HANDLE DispatchHandle, IN FCH_SMM_MISC_REGISTER_CONTEXT *DispatchContext ) { UINT32 HpetInterval; UINT8 RtcIndex; UINT8 RtcRegA; UINT8 RtcRegB; //Disable IRQ2 trap ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGB8) &= ~(BIT4 + BIT5); // HpetInterval = ACPIMMIO32 (0xFED00108) - ACPIMMIO32 (0xFED000F0); //while (HpetInterval >= 0) { //} if (HpetInterval > 15000000 / 70) { RWPMIO (FCH_PMIOA_REGA0, AccessWidth8, ~BIT1, 0); RtcIndex = ReadIO8 (0x70); WriteIO8 (0x70, 0x0A); RtcRegA = ReadIO8 (0x71); WriteIO8 (0x71, ((RtcRegA & 0xF0) | 0x0E)); WriteIO8 (0x70, 0x0B); RtcRegB = ReadIO8 (0x71); WriteIO8 (0x71, (RtcRegB | BIT6)); RWPMIO (FCH_PMIOA_REGA0 + 2, AccessWidth8, ~BIT1, BIT1); RWPMIO (FCH_PMIOA_REGA0, AccessWidth8, ~BIT1, BIT1); RWPMIO (FCH_PMIOA_REGA0 + 2, AccessWidth8, ~BIT1, 0); RWPMIO (FCH_PMIOA_REGA0, AccessWidth8, ~BIT1, 0); WriteIO8 (0x70, 0x0A); WriteIO8 (0x71, RtcRegA); WriteIO8 (0x70, 0x0B); WriteIO8 (0x71, RtcRegB); WriteIO8 (0x70, RtcIndex); } else { RWPMIO (FCH_PMIOA_REGA0, AccessWidth8, ~BIT1, BIT1); } //Disable IRQ2 trap ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGB8) &= ~(BIT4 + BIT5); // ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REG8C) |= BIT2; // return EFI_SUCCESS; }
/** * SbSleepTrapControl - SB Sleep Trap Control * * * * @param[in] SleepTrap - Whether sleep trap is enabled * */ VOID SbSleepTrapControl ( IN BOOLEAN SleepTrap ) { if (SleepTrap) { ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGB0) &= ~(BIT2 + BIT3); ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGB0) |= BIT2; ACPIMMIO8 (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGBE) &= ~ (BIT5); ACPIMMIO8 (ACPI_MMIO_BASE + PMIO_BASE + 0xB) &= ~ (BIT0 + BIT1); ACPIMMIO8 (ACPI_MMIO_BASE + PMIO_BASE + 0xB) |= BIT1; } else { ACPIMMIO8 (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGBE) |= BIT5; ACPIMMIO8 (ACPI_MMIO_BASE + PMIO_BASE + 0xB) &= ~ (BIT0 + BIT1); ACPIMMIO8 (ACPI_MMIO_BASE + PMIO_BASE + 0xB) |= BIT0; ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGB0) &= ~(BIT2 + BIT3); } }
/** * FchCombineSigRomInfo - Combine SIG ROM information * * * @param[in] FchDataPtr Fch configuration structure pointer. * */ UINT32 FchCombineSigRomInfo ( IN FCH_DATA_BLOCK *FchDataPtr ) { UINTN RomSigStartingAddr; UINT32 RomStore[NUM_OF_ROMSIG_FILED]; FCH_DATA_BLOCK *LocalCfgPtr; AMD_CONFIG_PARAMS *StdHeader; UINT32 SelNum; UINT32 RomSignatureTag; UINT16 XhciFwTag; LocalCfgPtr = (FCH_DATA_BLOCK *)FchDataPtr; StdHeader = LocalCfgPtr->StdHeader; GetRomSigPtr (&RomSigStartingAddr, StdHeader); RomSignatureTag = ACPIMMIO32 (RomSigStartingAddr); if ( RomSignatureTag == ROMSIG_SIG ) { for ( SelNum = 0; SelNum < NUM_OF_ROMSIG_FILED; SelNum++) { RomStore[SelNum] = ACPIMMIO32 (RomSigStartingAddr + (SelNum << 2)); } } else { RomStore[XHCI_FILED_NUM] = 0; } if ( LocalCfgPtr->Usb.UserDefineXhciRomAddr != NULL ) { RomStore[XHCI_FILED_NUM] = LocalCfgPtr->Usb.UserDefineXhciRomAddr; } RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGC8 + 3, AccessWidth8, 0x7F, BIT7, StdHeader); for ( SelNum = 1; SelNum < NUM_OF_ROMSIG_FILED; SelNum++) { RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGCC, AccessWidth32, ~(UINT32) (BIT2 + BIT1 + BIT0), (BIT2 + SelNum), StdHeader); RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGCC, AccessWidth32, ROMSIG_CFG_MASK, RomStore[SelNum], StdHeader); } XhciFwTag = (UINT16) ACPIMMIO32 (RomStore[XHCI_FILED_NUM]); if ( XhciFwTag != INSTRUCTION_RAM_SIG ) { RomStore[XHCI_FILED_NUM] = 0; } return RomStore[XHCI_FILED_NUM]; }
EFI_STATUS EFIAPI P2CmboxMiscSmiCallback ( IN EFI_HANDLE DispatchHandle, IN FCH_SMM_MISC_REGISTER_CONTEXT *MiscRegisterContext ) { EFI_STATUS Status; Status = P2CmboxSmmCallBackWorker (); ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REG98) &= ~BIT25; // Deassert fakeSts0 return Status; }
/******************************************************************************** * Name: AmdFchWheaInitEntry * * Description * AmdFchWheaSmmInit Entrypoint * * Input * * Output * EFI_UNSUPPORTED : unsupported function * *********************************************************************************/ EFI_STATUS AmdFchWheaSmmInitEntry ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; FCH_INIT_PROTOCOL *AmdFchInit; FCH_SMM_SW_DISPATCH2_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; Status = gBS->LocateProtocol ( &gFchInitProtocolGuid, NULL, &AmdFchInit ); ASSERT_EFI_ERROR (Status); if (AmdFchInit->FchPolicy.Gpp.PcieAer == 0) { return Status; } Status = gBS->LocateProtocol ( &gEfiAmdFchWheaDataProtocolGuid, NULL, &mEinjData ); if (EFI_ERROR (Status)) { return Status; } Status = gSmst->SmmLocateProtocol ( &gFchSmmSwDispatch2ProtocolGuid, 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 = gSmst->SmmLocateProtocol ( &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; }
/** * FchXhciInitBeforePciInit - Config XHCI controller before PCI * emulation * * * * @param[in] FchDataPtr Fch configuration structure pointer. * */ VOID FchXhciInitBeforePciInit ( IN FCH_DATA_BLOCK *FchDataPtr ) { UINT16 BcdAddress; UINT16 BcdSize; UINT16 AcdAddress; UINT16 AcdSize; UINT16 FwAddress; UINT16 FwSize; UINTN XhciFwStarting; UINT32 SpiValidBase; UINT32 RegData; UINT16 Index; BOOLEAN Xhci0Enable; BOOLEAN Xhci1Enable; FCH_DATA_BLOCK *LocalCfgPtr; AMD_CONFIG_PARAMS *StdHeader; LocalCfgPtr = (FCH_DATA_BLOCK *)FchDataPtr; StdHeader = LocalCfgPtr->StdHeader; Xhci0Enable = LocalCfgPtr->Usb.Xhci0Enable; Xhci1Enable = LocalCfgPtr->Usb.Xhci1Enable; if (( Xhci0Enable == 0 ) && (Xhci1Enable == 0)) { return; } RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, 0x00000000, 0x00400700); FchStall (20, StdHeader); if ( LocalCfgPtr->Usb.UserDefineXhciRomAddr == 0 ) { // // Get ROM SIG starting address for USB firmware starting address (offset 0x0C to SIG address) // GetRomSigPtr (&XhciFwStarting, StdHeader); if (XhciFwStarting == 0) { return; } XhciFwStarting = ACPIMMIO32 (XhciFwStarting + FW_TO_SIGADDR_OFFSET); } else { XhciFwStarting = ( UINTN ) LocalCfgPtr->Usb.UserDefineXhciRomAddr; } if (IsLpcRom ()) { // // XHCI firmware re-load // RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGCC, AccessWidth32, (UINT32)~BIT2, (UINT32)(BIT2 + BIT1 + BIT0), StdHeader); RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGCC, AccessWidth32, 0x00000FFF, (UINT32) (XhciFwStarting), StdHeader); } // // Enable SuperSpeed receive special error case logic. 0x20 bit8 // Enable USB2.0 RX_Valid Synchronization. 0x20 bit9 // Enable USB2.0 DIN/SE0 Synchronization. 0x20 bit10 // RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, 0xFFFFF8FF, 0x00000700); // // SuperSpeed PHY Configuration (adaptation timer setting) // XHC U1 LFPS Exit time // RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG90, AccessWidth32, 0xCFF00000, 0x000AAAAA); //RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG90 + 0x40, AccessWidth32, 0xFFF00000, 0x000AAAAA); // // Step 1. to enable Xhci IO and Firmware load mode // RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEF, AccessWidth8, (UINT32)~(BIT4 + BIT5), 0); /// Disable Device 22 RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEF, AccessWidth8, (UINT32)~(BIT7), (UINT32)BIT7); /// Enable 2.0 devices RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, 0xF0FFFFFC, (Xhci0Enable + (Xhci1Enable << 1)) & 0x03); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, 0xEFFFFFFF, 0x10000000); // // Step 2. to read a portion of the USB3_APPLICATION_CODE from BIOS ROM area and program certain registers. // RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA0, AccessWidth32, 0x00000000, (SPI_HEAD_LENGTH << 16)); BcdAddress = ACPIMMIO16 (XhciFwStarting + BCD_ADDR_OFFSET); BcdSize = ACPIMMIO16 (XhciFwStarting + BCD_SIZE_OFFSET); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA4, AccessWidth16, 0x0000, BcdAddress); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA4 + 2, AccessWidth16, 0x0000, BcdSize); AcdAddress = ACPIMMIO16 (XhciFwStarting + ACD_ADDR_OFFSET); AcdSize = ACPIMMIO16 (XhciFwStarting + ACD_SIZE_OFFSET); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA8, AccessWidth16, 0x0000, AcdAddress); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA8 + 2, AccessWidth16, 0x0000, AcdSize); SpiValidBase = SPI_BASE2 (XhciFwStarting + 4) | SPI_BAR0_VLD | SPI_BASE0 | SPI_BAR1_VLD | SPI_BASE1 | SPI_BAR2_VLD; RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB0, AccessWidth32, 0x00000000, SpiValidBase); // // Copy Type0/1/2 data block from ROM image to MMIO starting from 0xC0 // for (Index = 0; Index < SPI_HEAD_LENGTH; Index++) { RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGC0 + Index, AccessWidth8, 0, ACPIMMIO8 (XhciFwStarting + Index)); } for (Index = 0; Index < BcdSize; Index++) { RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGC0 + SPI_HEAD_LENGTH + Index, AccessWidth8, 0, ACPIMMIO8 (XhciFwStarting + BcdAddress + Index)); } for (Index = 0; Index < AcdSize; Index++) { RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGC0 + SPI_HEAD_LENGTH + BcdSize + Index, AccessWidth8, 0, ACPIMMIO8 (XhciFwStarting + AcdAddress + Index)); } // // Step 3. to enable the instruction RAM preload functionality. // FwAddress = ACPIMMIO16 (XhciFwStarting + FW_ADDR_OFFSET); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccessWidth16, 0x0000, ACPIMMIO16 (XhciFwStarting + FwAddress)); FwAddress += 2; RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG04, AccessWidth16, 0x0000, FwAddress); FwSize = ACPIMMIO16 (XhciFwStarting + FW_SIZE_OFFSET); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG04 + 2, AccessWidth16, 0x0000, FwSize); // // Set the starting address offset for Instruction RAM preload. // RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG08, AccessWidth16, 0x0000, 0); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~BIT29, (UINT32)BIT29); for (;;) { ReadMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00 , AccessWidth32, &RegData); if (RegData & BIT30) { break; } } RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~BIT29, 0); // // Step 4. to release resets in XHCI_ACPI_MMIO_AMD_REG00. wait for USPLL to lock by polling USPLL lock. // RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~U3PLL_RESET, 0); ///Release U3PLLreset for (;;) { ReadMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00 , AccessWidth32, &RegData); if (RegData & U3PLL_LOCK) { break; } } RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~U3PHY_RESET, 0); ///Release U3PHY RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~U3CORE_RESET, 0); ///Release core reset // // SuperSpeed PHY Configuration // //RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG90, AccessWidth32, 0xFFF00000, 0x000AAAAA); //RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGD0, AccessWidth32, 0xFFF00000, 0x000AAAAA); FchXhciInitIndirectReg (StdHeader); RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEF, AccessWidth8, (UINT32)~(BIT4 + BIT5), 0); /// Disable Device 22 RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEF, AccessWidth8, (UINT32)~(BIT7), (UINT32)BIT7); /// Enable 2.0 devices RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~(BIT21), (UINT32)BIT21); // // Step 5. // RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, (UINT32)~(BIT17 + BIT18 + BIT19), (UINT32)(BIT17 + BIT18)); XhciA12Fix (); // // UMI Lane Configuration Information for XHCI Firmware to Calculate the Bandwidth for USB 3.0 ISOC Devices // if (!(IsUmiOneLaneGen1Mode (StdHeader))) { RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, (UINT32)~(BIT25 + BIT24), (UINT32)BIT24); } // RPR 8.23 FS/LS devices not functional after resume from S4 fix enable (SB02699) RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, (UINT32)~(BIT22), (UINT32)BIT22); // RPR 8.24 XHC USB2.0 Hub disable issue fix enable (SB02702) RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccessWidth32, (UINT32)~(BIT20), (UINT32)BIT20); }
*/ /*----------------------------------------------------------------------------------------*/ EFI_STATUS EFIAPI FchSmmIoTrapDispatchHandler ( IN EFI_HANDLE SmmImageHandle, IN OUT VOID *CommunicationBuffer OPTIONAL, IN OUT UINTN *SourceSize OPTIONAL ) { EFI_STATUS Status; UINTN Index; UINT32 SmiIoTrapStatusBitmap; Status = EFI_UNSUPPORTED; SmiIoTrapStatusBitmap = ACPIMMIO32 (AcpiMmioBase + 0x290); SmiIoTrapStatusBitmap &= (BIT20 | BIT21 | BIT22 | BIT23); if (SmiIoTrapStatusBitmap != 0) { for (Index = 0; Index < (sizeof (mFchIoTrapList) / sizeof (FCH_IO_TRAP_ENTRY)); Index++) { if ((mFchIoTrapList[Index].StatusMask & SmiIoTrapStatusBitmap) != 0) { ACPIMMIO32 (AcpiMmioBase + 0x290) = mFchIoTrapList[Index].StatusMask; if (mFchIoTrapList[Index].DispatchFunction) { Status = mFchIoTrapList[Index].DispatchFunction ( mFchIoTrapList[Index].DispatchHandle, &mFchIoTrapList[Index].Context, NULL, NULL ); } break; }
/*----------------------------------------------------------------------------------------*/ EFI_STATUS FchSmmDispatcherEntry ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_HANDLE DispatchHandle; EFI_HANDLE FchSmmDispatcherHandle; UINTN i; Status = gSmst->SmmLocateProtocol ( &gEfiSmmCpuProtocolGuid, NULL, &mSmmCpuProtocol ); ASSERT_EFI_ERROR (Status); for (i = 0 ; i < sizeof (FchProtocolList) / sizeof (FCH_PROTOCOL_LIST); i++ ) { FchSmmDispatcherHandle = NULL; Status = gSmst->SmmInstallProtocolInterface ( &FchSmmDispatcherHandle, FchProtocolList[i].Guid, EFI_NATIVE_INTERFACE, FchProtocolList[i].Interface); if (EFI_ERROR (Status)) { return Status; } } Status = gSmst->SmiHandlerRegister ( FchSmmDispatchHandler, NULL, &DispatchHandle ); if (EFI_ERROR (Status)) { return Status; } Status = gSmst->SmmAllocatePool ( EfiRuntimeServicesData, sizeof (FCH_SMM_SW_NODE), &HeadFchSmmSwNodePtr ); if (EFI_ERROR (Status)) { return Status; } ZeroMem (HeadFchSmmSwNodePtr, sizeof (FCH_SMM_SW_NODE)); Status = gSmst->SmmAllocatePool ( EfiRuntimeServicesData, sizeof (FCH_SMM_SX_NODE), &HeadFchSmmSxNodePtr ); if (EFI_ERROR (Status)) { return Status; } ZeroMem (HeadFchSmmSxNodePtr, sizeof (FCH_SMM_SX_NODE)); Status = gSmst->SmmAllocatePool ( EfiRuntimeServicesData, sizeof (FCH_SMM_PWRBTN_NODE), &HeadFchSmmPwrBtnNodePtr ); if (EFI_ERROR (Status)) { return Status; } ZeroMem (HeadFchSmmPwrBtnNodePtr, sizeof (FCH_SMM_PWRBTN_NODE)); Status = gSmst->SmmAllocatePool ( EfiRuntimeServicesData, sizeof (FCH_SMM_PERIODICAL_NODE), &HeadFchSmmPeriodicalNodePtr ); if (EFI_ERROR (Status)) { return Status; } ZeroMem (HeadFchSmmPeriodicalNodePtr, sizeof (FCH_SMM_PERIODICAL_NODE)); Status = gSmst->SmmAllocatePool ( EfiRuntimeServicesData, sizeof (FCH_SMM_GPI_NODE), &HeadFchSmmGpiNodePtr ); if (EFI_ERROR (Status)) { return Status; } ZeroMem (HeadFchSmmGpiNodePtr, sizeof (FCH_SMM_GPI_NODE)); HeadFchSmmGpiNodePtr->Context.GpiNum = 0xffff; Status = gSmst->SmmAllocatePool ( EfiRuntimeServicesData, sizeof (FCH_SMM_USB_NODE), &HeadFchSmmUsbNodePtr ); if (EFI_ERROR (Status)) { return Status; } ZeroMem (HeadFchSmmUsbNodePtr, sizeof (FCH_SMM_USB_NODE)); HeadFchSmmUsbNodePtr->Context.Order = 0xFF; Status = gSmst->SmmAllocatePool ( EfiRuntimeServicesData, sizeof (FCH_SMM_MISC_NODE), &HeadFchSmmMiscNodePtr ); if (EFI_ERROR (Status)) { return Status; } ZeroMem (HeadFchSmmMiscNodePtr, sizeof (FCH_SMM_MISC_NODE)); Status = gSmst->SmmAllocatePool ( EfiRuntimeServicesData, sizeof (FCH_SMM_SW_CONTEXT), &EfiSmmSwContext ); if (EFI_ERROR (Status)) { return Status; } ZeroMem (EfiSmmSwContext, sizeof (FCH_SMM_SW_CONTEXT)); Status = gSmst->SmmAllocatePool ( EfiRuntimeServicesData, sizeof (FCH_SMM_COMMUNICATION_BUFFER), &CommunicationBufferPtr ); if (EFI_ERROR (Status)) { return Status; } { UINT32 SmmDispatcherData32; UINT32 SmmDispatcherIndex; // // Clear all handled SMI status bit // for (SmmDispatcherIndex = 0; SmmDispatcherIndex < NumOfDispatcherTableEntry; SmmDispatcherIndex++ ) { SmmDispatcherData32 = ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FchSmmDispatcherTable[SmmDispatcherIndex].StatusReg); SmmDispatcherData32 &= FchSmmDispatcherTable[SmmDispatcherIndex].SmiStatusBit; ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FchSmmDispatcherTable[SmmDispatcherIndex].StatusReg) = SmmDispatcherData32; } // // Clear SmiEnB and Set EOS // SmmDispatcherData32 = ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REG98); SmmDispatcherData32 &= ~(BIT31); SmmDispatcherData32 |= BIT28; ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REG98) = SmmDispatcherData32; } return Status; }
/** * FchInitEnvProgramSataPciRegs - Sata Pci Configuration Space * register setting * * * @param[in] FchDataPtr Fch configuration structure pointer. * */ VOID FchInitEnvProgramSataPciRegs ( IN VOID *FchDataPtr ) { UINT8 *PortRegByte; UINT16 *PortRegWord; FCH_DATA_BLOCK *LocalCfgPtr; AMD_CONFIG_PARAMS *StdHeader; LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; StdHeader = LocalCfgPtr->StdHeader; // //Caculate SataPortReg for SATA_ESP_PORT // PortRegByte = &(LocalCfgPtr->Sata.SataEspPort.SataPortReg); FchSataCombineControlDataByte (PortRegByte); PortRegByte = &(LocalCfgPtr->Sata.SataPortPower.SataPortReg); FchSataCombineControlDataByte (PortRegByte); PortRegWord = &(LocalCfgPtr->Sata.SataPortMd.SataPortMode); FchSataCombineControlDataWord (PortRegWord); PortRegByte = &(LocalCfgPtr->Sata.SataHotRemovalEnhPort.SataPortReg); FchSataCombineControlDataByte (PortRegByte); // // Reset DevSlp S5 Pin here // if (LocalCfgPtr->Sata.SataDevSlpPort0) { if (LocalCfgPtr->FchRunTime.SataDevSlpPort0S5Pin) { ACPIMMIO32 (ACPI_MMIO_BASE + GPIO_BANK0_BASE + (LocalCfgPtr->FchRunTime.SataDevSlpPort0S5Pin << 2)) |= BIT22 + BIT23; } ACPIMMIO32 (ACPI_MMIO_BASE + GPIO_BANK0_BASE + FCH_GPIO_10C_GPIO55_AGPI067) &= ~ BIT22; ACPIMMIO32 (ACPI_MMIO_BASE + GPIO_BANK0_BASE + FCH_GPIO_10C_GPIO55_AGPI067) |= BIT23; } if (LocalCfgPtr->Sata.SataDevSlpPort1) { if (LocalCfgPtr->FchRunTime.SataDevSlpPort1S5Pin) { ACPIMMIO32 (ACPI_MMIO_BASE + GPIO_BANK0_BASE + (LocalCfgPtr->FchRunTime.SataDevSlpPort1S5Pin << 2)) |= BIT22 + BIT23; } ACPIMMIO32 (ACPI_MMIO_BASE + GPIO_BANK0_BASE + FCH_GPIO_118_GPIO59_AGPI070) &= ~ BIT22; ACPIMMIO32 (ACPI_MMIO_BASE + GPIO_BANK0_BASE + FCH_GPIO_118_GPIO59_AGPI070) |= BIT23; } // // Set Sata PCI Configuration Space Write enable // SataEnableWriteAccess (StdHeader); // * // Enables the SATA watchdog timer register prior to the SATA BIOS post // RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG44), AccessWidth8, 0xff, BIT0, StdHeader); // * // SATA PCI Watchdog timer setting // Set timer out to 0x20 to fix IDE to SATA Bridge dropping drive issue. // RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG44 + 2), AccessWidth8, 0, 0x20, StdHeader); // // BIT4: Enable fast boot (SpeedupXPBoot) // RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG40), AccessWidth8, 0xef, 0, StdHeader); // // HBA Initialization setting // RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG48 + 3), AccessWidth8, 0xff, BIT7, StdHeader); // // Unused SATA Ports Disabled // RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG40 + 2), AccessWidth8, 0, LocalCfgPtr->Sata.SataPortPower.SataPortReg, StdHeader); // // Disable Prefetch In Ahci Mode // RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG40 + 1), AccessWidth8, 0xDF, BIT5, StdHeader); RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG84), AccessWidth32, (UINT32) (~ (0x01 << 31)), (UINT32) (0x00 << 31), StdHeader); RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG40), AccessWidth32, (UINT32) (~ (0x3 << 1)), (UINT32) (0x01 << 1), StdHeader); RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG48), AccessWidth32, (UINT32) (~ (0x1 << 3)), (UINT32) (0x01 << 3), StdHeader); }
FchSmmDispatchHandler ( IN EFI_HANDLE SmmImageHandle, IN OUT VOID *CommunicationBuffer OPTIONAL, IN OUT UINTN *SourceSize OPTIONAL ) { UINT8 SmmDispatcherIndex; UINT32 SmiStatusData; UINT32 SmiReg88StatusData; UINT8 PmRegEDStatusData; UINT32 EosStatus; EFI_STATUS Status; Status = EFI_UNSUPPORTED; SaveB2BRegisters (); SmiReg88StatusData = ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REG88) & SmiCmdPort; PmRegEDStatusData = ACPIMMIO8 (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGED) & BIT4; do { if (PmRegEDStatusData) { ACPIMMIO8 (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGED) &= ~(BIT4); } for (SmmDispatcherIndex = 0; SmmDispatcherIndex < NumOfDispatcherTableEntry; SmmDispatcherIndex++ ) { SmiStatusData = ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FchSmmDispatcherTable[SmmDispatcherIndex].StatusReg); if (( SmiStatusData &= FchSmmDispatcherTable[SmmDispatcherIndex].SmiStatusBit) != 0) { CommunicationBufferPtr->SmiStatusReg = FchSmmDispatcherTable[SmmDispatcherIndex].StatusReg; CommunicationBufferPtr->SmiStatusBit = SmiStatusData; CommunicationBuffer = (VOID *) CommunicationBufferPtr; Status = FchSmmDispatcherTable[SmmDispatcherIndex].SmiDispatcher (SmmImageHandle, CommunicationBuffer, SourceSize); if (Status != EFI_SUCCESS) { DEBUG ((EFI_D_WARN, "Child SMM Dispatcher returns no SUCCESS!\n")); }
EFI_STATUS FchSmmRegisterMiscSmi ( VOID ) { EFI_STATUS Status; FCH_SMM_MISC_DISPATCH_PROTOCOL *FchSmmMiscDispatch; FCH_SMM_MISC_REGISTER_CONTEXT MiscRegisterContext; EFI_HANDLE MiscHandle; FCH_DATA_BLOCK *FchDb; UINT8 GppHpGeventNum; FchDb = &gFchInitInSmm.FchPolicy; Status = gSmst->SmmLocateProtocol ( &gFchSmmMiscDispatchProtocolGuid, NULL, &FchSmmMiscDispatch ); ASSERT_EFI_ERROR (Status); MiscRegisterContext.Order = 0x80; MiscHandle = NULL; //// //// Smi SBTSI test Done //// //Status = gBS->LocateProtocol ( // &gFchSmmMiscDispatchProtocolGuid, // NULL, // &FchSmmMiscDispatch // ); //ASSERT_EFI_ERROR (Status); //MiscRegisterContext.SmiStatusReg = FCH_SMI_REG84; //MiscRegisterContext.SmiStatusBit = BIT15; //MiscRegisterContext.Order = 0x80; //Status = FchSmmMiscDispatch->Register ( // FchSmmMiscDispatch, // AmdMiscFchTsiSmiCallback, // &MiscRegisterContext, // &MiscHandle // ); //ACPIMMIO8 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGAB) &= ~(BIT7); //ACPIMMIO8 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGAB) |= (BIT6); // // Initialize GPP hotplug SMI // if (FchDb->Gpp.PortCfg[0].PortHotPlug || FchDb->Gpp.PortCfg[1].PortHotPlug || \ FchDb->Gpp.PortCfg[2].PortHotPlug || FchDb->Gpp.PortCfg[3].PortHotPlug) { GppHpGeventNum = FchDb->Gpp.GppHotPlugGeventNum & 31; MiscRegisterContext.SmiStatusReg = FCH_SMI_REG80; MiscRegisterContext.SmiStatusBit = 1 << GppHpGeventNum; MiscRegisterContext.Order = 0x80; Status = FchSmmMiscDispatch->Register ( FchSmmMiscDispatch, AmdMiscFchGppHpSmiCallback, &MiscRegisterContext, &MiscHandle ); ACPIMMIO8 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGA0 + ((GppHpGeventNum << 1) / 8)) &= ~(0x03 << ((GppHpGeventNum << 1) % 8)); ACPIMMIO8 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGA0 + ((GppHpGeventNum << 1) / 8)) |= (0x01 << ((GppHpGeventNum << 1) % 8)); } #ifdef FCH_TIMER_TICK_INTERVAL_WA // // Initialize timer tick interval workaround // MiscRegisterContext.SmiStatusReg = FCH_SMI_REG90; MiscRegisterContext.SmiStatusBit = BIT24; MiscRegisterContext.Order = 0x80; Status = FchSmmMiscDispatch->Register ( FchSmmMiscDispatch, AmdMiscFchHpetIntervalCallback, &MiscRegisterContext, &MiscHandle ); ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGD0) = 0xFED00109; ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REGC4) |= BIT16; // // Initialize timer tick interval workaround // MiscRegisterContext.SmiStatusReg = FCH_SMI_REG8C; MiscRegisterContext.SmiStatusBit = BIT2; MiscRegisterContext.Order = 0x80; Status = FchSmmMiscDispatch->Register ( FchSmmMiscDispatch, AmdMiscFchIrq2TrapCallback, &MiscRegisterContext, &MiscHandle ); //Set IRQ2 smi active high ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REG9C) |= BIT2; //Select IoApic IRQ2 smi trap ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REG98) &= ~(BIT24); #endif return Status; }
/********************************************************************************* * Name: FchXhciOnRecovery * * Description * * * Input * FchPrivate : FCH PEI private data structure * XhciRomAddress : temporary base address value of Xhci controller * * Output * * *********************************************************************************/ EFI_STATUS FchXhciOnRecovery ( IN FCH_PEI_PRIVATE FchPrivate, IN UINT32 XhciRomAddress ) { UINT16 BcdAddress; UINT16 BcdSize; UINT16 AcdAddress; UINT16 AcdSize; UINT16 FwAddress; UINT16 FwSize; UINT32 XhciFwStarting; UINT32 SpiValidBase; UINT32 RegData; UINT16 Index; AMD_CONFIG_PARAMS *StdHeader; UINT8 FchRevision; UINT32 XhcBootRamSize; UINTN RomSigStartingAddr; UINT32 RomStore[NUM_OF_ROMSIG_FILED]; UINT32 SelNum; StdHeader = &FchPrivate.StdHdr; FchRevision = 0; ReadPci (PCI_ADDRESS (0, FCH_ISA_DEV, 0, 0x08), AccessWidth8, &FchRevision, StdHeader); GetRomSigPtr (&RomSigStartingAddr, StdHeader); for ( SelNum = 0; SelNum < NUM_OF_ROMSIG_FILED; SelNum++) { RomStore[SelNum] = ACPIMMIO32 (RomSigStartingAddr + (SelNum << 2)); } if ( XhciRomAddress != 0 ) { RomStore[XHCI_FILED_NUM] = XhciRomAddress; } RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGC8 + 3, AccessWidth8, 0x7F, BIT7, StdHeader); for ( SelNum = 1; SelNum < NUM_OF_ROMSIG_FILED; SelNum++) { RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGCC, AccessWidth32, ~ (BIT2 + BIT1 + BIT0), (BIT2 + SelNum), StdHeader); RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGCC, AccessWidth32, ROMSIG_CFG_MASK, RomStore[SelNum], StdHeader); } XhciFwStarting = RomStore[XHCI_FILED_NUM]; RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, 0x00090000, 0x00400700); FchStall (20, StdHeader); // // Enable SuperSpeed receive special error case logic. 0x20 bit8 // Enable USB2.0 RX_Valid Synchronization. 0x20 bit9 // Enable USB2.0 DIN/SE0 Synchronization. 0x20 bit10 // XhcBootRamSize = XHC_BOOT_RAM_SIZE; RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, 0xFFFFF9FF, 0x00000600); RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG50 + 1, AccessWidth8, ~BIT1, BIT1); // // SuperSpeed PHY Configuration (adaptation timer setting) // XHC U1 LFPS Exit time // RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG90, AccessWidth32, 0xCFF00000, 0x000AAAAA); //RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG90 + 0x40, AccessWidth32, 0xFFF00000, 0x000AAAAA); // // Step 1. to enable Xhci IO and Firmware load mode // RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEF, AccessWidth8, ~(BIT4 + BIT5), 0); /// Disable Device 22 RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEF, AccessWidth8, ~(BIT7), BIT7); /// Enable 2.0 devices RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, 0xF0FFFFFC, 0x01); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, 0xEFFFFFFF, 0x10000000); // // Step 2. to read a portion of the USB3_APPLICATION_CODE from BIOS ROM area and program certain registers. // RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA0, AccessWidth32, 0x00000000, (SPI_HEAD_LENGTH << 16)); BcdAddress = ACPIMMIO16 (XhciFwStarting + BCD_ADDR_OFFSET + XhcBootRamSize); BcdSize = ACPIMMIO16 (XhciFwStarting + BCD_SIZE_OFFSET + XhcBootRamSize); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA4, AccessWidth16, 0x0000, BcdAddress); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA4 + 2, AccessWidth16, 0x0000, BcdSize); AcdAddress = ACPIMMIO16 (XhciFwStarting + ACD_ADDR_OFFSET + XhcBootRamSize); AcdSize = ACPIMMIO16 (XhciFwStarting + ACD_SIZE_OFFSET + XhcBootRamSize); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA8, AccessWidth16, 0x0000, AcdAddress); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGA8 + 2, AccessWidth16, 0x0000, AcdSize); SpiValidBase = SPI_BASE2 (XhciFwStarting + 4 + XHC_BOOT_RAM_SIZE) | SPI_BAR0_VLD | SPI_BASE0 | SPI_BAR1_VLD | SPI_BASE1 | SPI_BAR2_VLD; RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB0, AccessWidth32, 0x00000000, SpiValidBase); // // Copy Type0/1/2 data block from ROM image to MMIO starting from 0xC0 // for (Index = 0; Index < SPI_HEAD_LENGTH; Index++) { RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGC0 + Index, AccessWidth8, 0, ACPIMMIO8 (XhciFwStarting + XhcBootRamSize + Index)); } for (Index = 0; Index < BcdSize; Index++) { RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGC0 + SPI_HEAD_LENGTH + Index, AccessWidth8, 0, ACPIMMIO8 (XhciFwStarting + BcdAddress + Index)); } for (Index = 0; Index < AcdSize; Index++) { RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGC0 + SPI_HEAD_LENGTH + BcdSize + Index, AccessWidth8, 0, ACPIMMIO8 (XhciFwStarting + AcdAddress + Index)); } // // Step 3. to enable the BOOT RAM preload functionality. // RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, ~BIT0, BIT0); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, ~BIT29, 0); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG04 + 2, AccessWidth16, 0x7FFF, BIT15); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG04, AccessWidth16, 0x0000, 0); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG08 + 2, AccessWidth16, 0x0000, 0x8000); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG08, AccessWidth16, 0x0000, 0); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, ~BIT29, BIT29); for (;;) { ReadMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00 , AccessWidth32, &RegData); if (RegData & BIT30) { break; } } RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, ~BIT29, 0); // // Set the starting address offset for Instruction RAM preload. // FwAddress = ACPIMMIO16 (XhciFwStarting + FW_ADDR_OFFSET + XhcBootRamSize); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccessWidth16, 0x0000, ACPIMMIO16 (XhciFwStarting + FwAddress)); FwAddress += 2; RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG04, AccessWidth16, 0x0000, FwAddress + XhcBootRamSize); FwSize = ACPIMMIO16 (XhciFwStarting + FW_SIZE_OFFSET + XhcBootRamSize); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG08, AccessWidth16, 0x0000, 0); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG08 + 2, AccessWidth16, 0x0000, FwSize); // // Step 3.5 to enable the instruction RAM preload functionality. // RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG04 + 2, AccessWidth16, 0x7FFF, 0); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, ~BIT29, BIT29); for (;;) { ReadMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00 , AccessWidth32, &RegData); if (RegData & BIT30) { break; } } RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, ~BIT29, 0); // // Step 4. to release resets in XHCI_ACPI_MMIO_AMD_REG00. wait for USPLL to lock by polling USPLL lock. // RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, ~U3PLL_RESET, 0); ///Release U3PLLreset for (;;) { ReadMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00 , AccessWidth32, &RegData); if (RegData & U3PLL_LOCK) { break; } } RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, ~U3PHY_RESET, 0); ///Release U3PHY RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, ~U3CORE_RESET, 0); ///Release core reset FchXhciRecoveryInitIndirectReg ( StdHeader, FchRevision ); RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEF, AccessWidth8, ~(BIT4 + BIT5), 0); /// Disable Device 22 RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEF, AccessWidth8, ~(BIT7), BIT7); /// Enable 2.0 devices RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, ~(BIT21), BIT21); // // Step 5. // RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG00, AccessWidth32, ~(BIT17 + BIT18 + BIT19), BIT17 + BIT18 + BIT19); // // PLUG/UNPLUG of USB 2.0 devices make the XHCI USB 2.0 ports unfunctional - fix enable // ACPI_USB3.0_REG 0x20[12:11] = 2'b11 RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, ~((UINT32) (0x3 << 11)), (UINT32) (0x3 << 11)); // // XHC 2 USB2 ports interactional issue - fix enable // ACPI_USB3.0_REG 0x20[16] = 1'b1 RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, ~((UINT32) (0x1 << 16)), (UINT32) (0x1 << 16)); // // XHC USB2.0 Ports suspend Enhancement // ACPI_USB3.0_REG 0x20[15] = 1'b1 // RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, ~((UINT32) (0x1 << 15)), (UINT32) (0x1 << 15)); // // XHC HS/FS IN Data Buffer Underflow issue - fix enable // ACPI_USB3.0_REG 0x20[20:18] = 0x7 // RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, ~((UINT32) (0x7 << 18)), (UINT32) (0x7 << 18)); // // EHCI3/OHCI3 blocks Blink Global Clock Gating when EHCI/OHCI Dev 22 fn 0/2 are disabled // ACPI_PMIO_F0[13] =1 // RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGF0, AccessWidth32, ~((UINT32) (0x1 << 13)), (UINT32) (0x1 << 13)); // // USB leakage current on differential lines when ports are switched to XHCI - Fix enable // ACPI_PMIO_F0[14] =1 // RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGF0, AccessWidth32, ~((UINT32) (0x1 << 14)), (UINT32) (0x1 << 14)); // RRG 8.26 XHCI Clear pending PME on Sx entry RwXhciIndReg ( FCH_XHCI_IND_REG54, ~(BIT15), BIT15, StdHeader); // // UMI Lane Configuration Information for XHCI Firmware to Calculate the Bandwidth for USB 3.0 ISOC Devices // RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, ~(BIT25 + BIT24), BIT24); // RPR 8.23 FS/LS devices not functional after resume from S4 fix enable (SB02699) RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, ~(BIT22), BIT22); // RPR 8.24 XHC USB2.0 Hub disable issue fix enable (SB02702) RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccessWidth32, ~(BIT20), BIT20); // Set HCIVERSION to 1.0 RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, ~(BIT15), BIT15); // xHCI 1.0 Sub-Features Supported // Blobk Event Interrupt Flag (BEI) RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, ~(BIT1), BIT1); // Force Stopped Event (FSE) RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, ~(BIT2), BIT2); // Software LPM RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, ~(BIT3), 0); // Hardware LPM // Skip TRB IOC Event RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, ~(BIT6), BIT6); // Remove Secondary Bandwith Domain Reporting RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, ~(BIT7), BIT7); // Cold Attach Status RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, ~(BIT8), BIT8); // Endpoint Status Update Ordering RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, ~(BIT9), BIT9); // Report Event during SKIP on Missed Service Error RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, ~(BIT10), BIT10); // Soft Retry RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, ~(BIT11), BIT11); // U3 Exit RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, ~(BIT12), BIT12); // USB3.0 Link Command RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, ~(BIT13), BIT13); // MSE FrameId invalid RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, ~(BIT14), BIT14); // Port Test Mode RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, ~(BIT16), BIT16); // Miscellaneous Design Improvements RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG40, AccessWidth32, ~(BIT0), BIT0); //RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG40, AccessWidth32, ~(BIT25), 0); // XHC USB2 Loopback RX SE0 RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG20, AccessWidth32, ~(BIT13 + BIT14 + BIT21), BIT13 + BIT14 + BIT21); // XHC U2IF_Enabled_Quiettermination off RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccessWidth32, ~(BIT20), BIT20); // XHC S0 BLM Reset Mode RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGF2, AccessWidth8, ~(BIT3), BIT3); // Enhance XHC Ent_Flag RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccessWidth32, ~(BIT22), BIT22); // Enhance TRB Pointer when both MSE and SKIP TRB IOC evt opened RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, ~(BIT17), BIT17); // LPM Broadcast disable RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, ~(BIT18), BIT18); // Enhance XHC FS/LS connect RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccessWidth32, ~(BIT24), BIT24); // Enhance XHC ISOCH td_cmp RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccessWidth32, ~(BIT25), BIT25); // LPM Clock 5us Select RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG24, AccessWidth32, ~(BIT8), BIT8); // Enhance DPP ERR as XactErr RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG24, AccessWidth32, ~(BIT9), BIT9); // Enhance U2IF PME Enable RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG24, AccessWidth32, ~(BIT10), BIT10); // U2IF S3 Disconnect detection RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG24, AccessWidth32, ~(BIT12), BIT12); // Stream Error Handling RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, ~(BIT20 + BIT21 + BIT22), (BIT20 + BIT21 + BIT22)); // FLA Deassert RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, ~(BIT23), BIT23); // Enhance LPM Host initial L1 Exit RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, ~BIT29, BIT29); // Enhance resume after disconnect RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG98, AccessWidth32, ~(BIT30), BIT30); // Enhance SS HD Detected on Plug-in during S3 RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG98, AccessWidth32, ~(BIT31), BIT31); // Frame Babble Reporting RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccessWidth32, ~(BIT27), BIT27); // xHCI Debug Capability // DCP Halt RSTSM OFF // Enable DCP DPH check // DCP LTSSM Inactive to Rxdetect // Enhance DCP EP State // DCP Remote Wakeup Capable // Enable ERDY send once DBC detectes HIT/HOT // Block HIT/HOT until service interval done RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, FCH_XHCI_IND_REG100); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, ~(BIT0 + BIT1 + BIT2), BIT0 + BIT1 + BIT2); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, FCH_XHCI_IND_REG120); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, ~(BIT3), BIT3); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, FCH_XHCI_IND_REG100); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, ~(BIT21), BIT21); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, FCH_XHCI_IND_REG128); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, ~(BIT0), BIT0); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, FCH_XHCI_IND_REG100); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, ~(BIT3 + BIT4), BIT3 + BIT4); // Enhance SS HS detected during S3 RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, FCH_XHCI_IND_REG48); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, ~(BIT1), BIT1); // Enhance U1 timer (shorten U1 exit response time) RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, FCH_XHCI_IND_REG48); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, ~(BIT14), BIT14); // Enhance HW LPM U2Entry state RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG24, AccessWidth32, ~(BIT17), BIT17); // Enhance SSIF PME RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG24, AccessWidth32, ~(BIT15 + BIT14), (BIT15 + BIT14)); // U2IF Remote Wake Select RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG24, AccessWidth32, ~(BIT11), BIT11); // HS Data Toggle Error Handling RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG24, AccessWidth32, ~(BIT16), BIT16); // USB20PHY FL Speed select RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REGB4, AccessWidth32, ~(BIT28), BIT28); // Enable Fix for DBC compatibility RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, FCH_XHCI_IND_REG100); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, ~(BIT5), BIT5); // Enable Fix for ACPI registers write issue. RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG28, AccessWidth32, ~(BIT0), BIT0); // // For BTS only // // LPM reated items // HwLpmAddrSel (22) U2LpmTranArbEn, ColdAttachMode. RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG24, AccessWidth32, ~(BIT20 + BIT21 + BIT22), (BIT20 + BIT21 + BIT22)); // HwLpmStateSel (24), HwLpmDeconfigL1Exit (25), HwLpmL1StopEpEn (26). RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG24, AccessWidth32, ~(BIT24 + BIT25 + BIT26), (BIT24 + BIT25 + BIT26)); // Xhci10En: xHCI 10 Enable (0), HwLpmEn (4), SkipTrbIocEvtLenMode (24) RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG30, AccessWidth32, ~(BIT0 + BIT4 + BIT24), (BIT4 + BIT24)); // DcpNumP1En RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, FCH_XHCI_IND_REG100); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, ~ BIT5, BIT5); // LtssmDisconnectToConnect RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, FCH_XHCI_IND_REG48); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, ~(BIT16), BIT16); // CcuMode RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG10, AccessWidth32, 0xFFFF00FF, 0x2A00); // XtalPciClk_UseEcClkSel clear RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG50 + 1, AccessWidth8, ~BIT1, 0); // Change PHY LFPS Detection threshold (RX_LFPSDET_TH[2:0]) to 6h from default setting 4h RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, 0x80); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, 0xFFFFFFF8, 0x06); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG48, AccessWidth32, 0x00000000, 0xC0); RwMem (ACPI_MMIO_BASE + XHCI_BASE + XHCI_ACPI_MMIO_AMD_REG4C, AccessWidth32, 0xFFFFFFF8, 0x06); return EFI_SUCCESS; }
/*----------------------------------------------------------------------------------------*/ EFI_STATUS FchSmmDispatcherEntry ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_HANDLE Handle; BOOLEAN InSmm; EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath; EFI_DEVICE_PATH_PROTOCOL *CompleteFilePath; // Initialize Global Variable gST = SystemTable; gBS = SystemTable->BootServices; gRT = SystemTable->RuntimeServices; InSmm = FALSE; Status = gBS->LocateProtocol ( &gEfiSmmBaseProtocolGuid, NULL, &mSmmBasePtr ); ASSERT_EFI_ERROR (Status); if (EFI_ERROR (Status)) { return Status; } mSmmBasePtr->InSmm (mSmmBasePtr, &InSmm); mSmmBasePtr->GetSmstLocation (mSmmBasePtr, &mSmstPtr); if (!InSmm) { 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 ); Status = mSmmBasePtr->Register ( mSmmBasePtr, CompleteFilePath, NULL, 0, &Handle, FALSE ); ASSERT_EFI_ERROR (Status); } else { Status = gBS->InstallMultipleProtocolInterfaces ( &ImageHandle, &gFchSmmSxDispatchProtocolGuid, &gFchSmmSxDispatchProtocol, &gFchSmmSwDispatchProtocolGuid, &gFchSmmSwDispatchProtocol, &gFchSmmPwrBtnDispatchProtocolGuid, &gFchSmmPwrBtnDispatchProtocol, &gFchSmmIoTrapDispatchProtocolGuid, &gFchSmmIoTrapDispatchProtocol, &gFchSmmPeriodicalDispatchProtocolGuid, &gFchSmmPeriodicalDispatchProtocol, &gFchSmmGpeDispatchProtocolGuid, &gFchSmmGpeDispatchProtocol, &gFchSmmUsbDispatchProtocolGuid, &gFchSmmUsbDispatchProtocol, &gFchSmmMiscDispatchProtocolGuid, &gFchSmmMiscDispatchProtocol, NULL ); Status = gBS->InstallMultipleProtocolInterfaces ( &ImageHandle, &gFchSmmSwDispatch2ProtocolGuid, &gFchSmmSwDispatch2Protocol, &gFchSmmSxDispatch2ProtocolGuid, &gFchSmmSxDispatch2Protocol, &gFchSmmUsbDispatch2ProtocolGuid, &gFchSmmUsbDispatch2Protocol, &gFchSmmPwrBtnDispatch2ProtocolGuid, &gFchSmmPwrBtnDispatch2Protocol, NULL ); if (EFI_ERROR (Status)) { return Status; } Status = mSmmBasePtr->RegisterCallback ( mSmmBasePtr, ImageHandle, FchSmmDispatchHandler, FALSE, FALSE ); if (EFI_ERROR (Status)) { return Status; } Status = mSmmBasePtr->SmmAllocatePool ( mSmmBasePtr, EfiRuntimeServicesData, sizeof (FCH_SMM_SW_NODE), &HeadFchSmmSwNodePtr ); if (EFI_ERROR (Status)) { return Status; } HeadFchSmmSwNodePtr->FchSwNodePtr = NULL; HeadFchSmmSwNodePtr->CallBackFunction = NULL; HeadFchSmmSwNodePtr->CallBack2Function = NULL; HeadFchSmmSwNodePtr->Context.AmdSwValue = 0; HeadFchSmmSwNodePtr->DispatchHandle = NULL; Status = mSmmBasePtr->SmmAllocatePool ( mSmmBasePtr, EfiRuntimeServicesData, sizeof (FCH_SMM_SX_NODE), &HeadFchSmmSxNodePtr ); if (EFI_ERROR (Status)) { return Status; } HeadFchSmmSxNodePtr->FchSxNodePtr = NULL; HeadFchSmmSxNodePtr->CallBackFunction = NULL; HeadFchSmmSxNodePtr->CallBack2Function = NULL; HeadFchSmmSxNodePtr->Context.Type = 0; HeadFchSmmSxNodePtr->Context.Phase = 0; HeadFchSmmSxNodePtr->DispatchHandle = NULL; Status = mSmmBasePtr->SmmAllocatePool ( mSmmBasePtr, EfiRuntimeServicesData, sizeof (FCH_SMM_PWRBTN_NODE), &HeadFchSmmPwrBtnNodePtr ); if (EFI_ERROR (Status)) { return Status; } HeadFchSmmPwrBtnNodePtr->FchPwrBtnNodePtr = NULL; HeadFchSmmPwrBtnNodePtr->CallBackFunction = NULL; HeadFchSmmPwrBtnNodePtr->CallBack2Function = NULL; HeadFchSmmPwrBtnNodePtr->DispatchHandle = NULL; Status = mSmmBasePtr->SmmAllocatePool ( mSmmBasePtr, EfiRuntimeServicesData, sizeof (FCH_SMM_PERIODICAL_NODE), &HeadFchSmmPeriodicalNodePtr ); if (EFI_ERROR (Status)) { return Status; } HeadFchSmmPeriodicalNodePtr->FchPeriodicalNodePtr = NULL; HeadFchSmmPeriodicalNodePtr->CallBackFunction = NULL; HeadFchSmmPeriodicalNodePtr->DispatchHandle = NULL; Status = mSmmBasePtr->SmmAllocatePool ( mSmmBasePtr, EfiRuntimeServicesData, sizeof (FCH_SMM_GPE_NODE), &HeadFchSmmGpeNodePtr ); if (EFI_ERROR (Status)) { return Status; } HeadFchSmmGpeNodePtr->FchGpeNodePtr = NULL; HeadFchSmmGpeNodePtr->CallBackFunction = NULL; HeadFchSmmGpeNodePtr->Context.AmdGpeNum = 0xffff; HeadFchSmmGpeNodePtr->DispatchHandle = NULL; Status = mSmmBasePtr->SmmAllocatePool ( mSmmBasePtr, EfiRuntimeServicesData, sizeof (FCH_SMM_USB_NODE), &HeadFchSmmUsbNodePtr ); if (EFI_ERROR (Status)) { return Status; } HeadFchSmmUsbNodePtr->FchUsbNodePtr = NULL; HeadFchSmmUsbNodePtr->CallBackFunction = NULL; HeadFchSmmUsbNodePtr->CallBack2Function = NULL; HeadFchSmmUsbNodePtr->Context.Type = Wake; HeadFchSmmUsbNodePtr->Context.Device = NULL; HeadFchSmmUsbNodePtr->Context.Order = 0xFF; HeadFchSmmUsbNodePtr->DispatchHandle = NULL; Status = mSmmBasePtr->SmmAllocatePool ( mSmmBasePtr, EfiRuntimeServicesData, sizeof (FCH_SMM_MISC_NODE), &HeadFchSmmMiscNodePtr ); if (EFI_ERROR (Status)) { return Status; } HeadFchSmmMiscNodePtr->FchMiscNodePtr = NULL; HeadFchSmmMiscNodePtr->CallBackFunction = NULL; HeadFchSmmMiscNodePtr->Context.SmiStatusReg = 0; HeadFchSmmMiscNodePtr->Context.SmiStatusBit = 0; HeadFchSmmMiscNodePtr->DispatchHandle = NULL; Status = mSmmBasePtr->SmmAllocatePool ( mSmmBasePtr, EfiRuntimeServicesData, sizeof (FCH_SMM_SW_CONTEXT), &EfiSmmSwContext ); if (EFI_ERROR (Status)) { return Status; } EfiSmmSwContext->SwSmiCpuIndex = 0; EfiSmmSwContext->CommandPort = 0; EfiSmmSwContext->DataPort = 0; Status = mSmmBasePtr->SmmAllocatePool ( mSmmBasePtr, EfiRuntimeServicesData, sizeof (FCH_SMM_COMMUNICATION_BUFFER), &CommunicationBufferPtr ); if (EFI_ERROR (Status)) { return Status; } } { UINT32 SmmDispatcherData32; UINT32 SmmDispatcherIndex; // // Clear all handled SMI status bit // for (SmmDispatcherIndex = 0; SmmDispatcherIndex < NumOfDispatcherTableEntry; SmmDispatcherIndex++ ) { SmmDispatcherData32 = ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FchSmmDispatcherTable[SmmDispatcherIndex].StatusReg); SmmDispatcherData32 &= FchSmmDispatcherTable[SmmDispatcherIndex].SmiStatusBit; ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FchSmmDispatcherTable[SmmDispatcherIndex].StatusReg) = SmmDispatcherData32; } // // Clear SmiEnB and Set EOS // SmmDispatcherData32 = ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REG98); SmmDispatcherData32 &= ~(BIT31); SmmDispatcherData32 |= BIT28; ACPIMMIO32 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REG98) = SmmDispatcherData32; } return Status; }
/******************************************************************************** * 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; }