/*++ Routine Description: SMI handler to restore ACPI mode Arguments: DispatchHandle - The handle of this callback, obtained when registering DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT Returns: None. --*/ EFI_STATUS EFIAPI AmdSmiBeforePciS3RestoreCallback ( IN EFI_HANDLE DispatchHandle, IN FCH_SMM_SW_REGISTER_CONTEXT *DispatchContext ) { FCH_DATA_BLOCK *pFchPolicy; EFI_STATUS Status; UINT8 Index; UINT8 *pData; Status = EFI_SUCCESS; // Restore entire FCH PCI IRQ routing space (C00/C01) pData = mFchPciIrqRoutingTable; Index = 0xFF; do { Index++; LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC00, &Index, NULL); LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC01, pData++, NULL); } while (Index != 0xFF); pFchPolicy = &gFchInitInSmm.FchPolicy; FchInitS3EarlyRestore (pFchPolicy); return Status; }
/** * FchInitEnv - Config Fch before PCI emulation * * * * @param[in] EnvParams * */ AGESA_STATUS FchInitEnv ( IN AMD_ENV_PARAMS *EnvParams ) { UINT8 i; UINT8 Data; FCH_DATA_BLOCK *FchParams; AGESA_STATUS Status; IDS_HDT_CONSOLE (FCH_TRACE, " FchInitEnv Enter... \n"); FchParams = FchInitEnvCreatePrivateData (EnvParams); // Override internal data with IDS (Optional, internal build only) IDS_OPTION_CALLOUT (IDS_CALLOUT_FCH_INIT_ENV, FchParams, FchParams->StdHeader); // //to_do-Initialize PCI IRQ routing registers for INTA#-INTH# // for (i = 0; i < 8; i++) { Data = i | BIT7; // Select IRQ routing to APIC LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC00, &Data, &EnvParams->StdHeader); Data = i | BIT4; LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC01, &Data, &EnvParams->StdHeader); } AgesaFchOemCallout (FchParams); Status = FchTaskLauncher (&FchInitEnvTaskTable[0], FchParams); IDS_HDT_CONSOLE (FCH_TRACE, " FchInitEnv Exit... Status = [0x%x]\n", Status); return Status; }
/** * FchInitLateHwAcpi - Prepare HwAcpi controller to boot to OS. * * @param[in] FchDataPtr Fch configuration structure pointer. * */ VOID FchInitLateHwAcpi ( IN VOID *FchDataPtr ) { FCH_DATA_BLOCK *LocalCfgPtr; AMD_CONFIG_PARAMS *StdHeader; UINT8 i; LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; StdHeader = LocalCfgPtr->StdHeader; GcpuRelatedSetting (LocalCfgPtr); // Mt C1E Enable MtC1eEnable (LocalCfgPtr); if (LocalCfgPtr->Gpp.SerialDebugBusEnable == TRUE ) { RwMem (ACPI_MMIO_BASE + SERIAL_DEBUG_BASE + FCH_SDB_REG00, AccessWidth8, 0xFF, 0x05); } StressResetModeLate (LocalCfgPtr); SbSleepTrapControl (FALSE); for (i = 0; i < NUM_OF_DEVICE_FOR_APICIRQ; i++) { LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC00, &FchInternalDeviceIrqForApicMode[i].PciIrqIndex, StdHeader); LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC01, &FchInternalDeviceIrqForApicMode[i].PciIrqData, StdHeader); } }
/** * Clear EnableCf8ExtCfg on all socket * * Clear F3x8C bit 14 EnableCf8ExtCfg * * @param[in] StdHeader Config handle for library and services * * */ VOID DisableCf8ExtCfg ( IN AMD_CONFIG_PARAMS *StdHeader ) { AGESA_STATUS AgesaStatus; PCI_ADDR PciAddress; UINT32 Socket; UINT32 Module; UINT32 PciData; UINT32 LegacyPciAccess; ASSERT (IsBsp (StdHeader, &AgesaStatus)); for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) { for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) { if (GetPciAddress (StdHeader, Socket, Module, &PciAddress, &AgesaStatus)) { PciAddress.Address.Function = FUNC_3; PciAddress.Address.Register = NB_CFG_HIGH_REG; LegacyPciAccess = ((1 << 31) + (PciAddress.Address.Register & 0xFC) + (PciAddress.Address.Function << 8) + (PciAddress.Address.Device << 11) + (PciAddress.Address.Bus << 16) + ((PciAddress.Address.Register & 0xF00) << (24 - 8))); // read from PCI register LibAmdIoWrite (AccessWidth32, IOCF8, &LegacyPciAccess, StdHeader); LibAmdIoRead (AccessWidth32, IOCFC, &PciData, StdHeader); // Disable Cf8ExtCfg PciData &= 0xFFFFBFFF; // write to PCI register LibAmdIoWrite (AccessWidth32, IOCF8, &LegacyPciAccess, StdHeader); LibAmdIoWrite (AccessWidth32, IOCFC, &PciData, StdHeader); } } } }
/** * sataSetIrqIntResource - Config SATA IRQ/INT# resource * * * * @param[in] FchDataPtr Fch configuration structure pointer. * @param[in] StdHeader * */ VOID SataSetIrqIntResource ( IN VOID *FchDataPtr, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT8 ValueByte; FCH_DATA_BLOCK *LocalCfgPtr; LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; // // IRQ14/IRQ15 come from IDE or SATA // ValueByte = 0x08; LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC00, &ValueByte, StdHeader); LibAmdIoRead (AccessWidth8, FCH_IOMAP_REGC01, &ValueByte, StdHeader); ValueByte = ValueByte & 0x0F; if (LocalCfgPtr->Sata.SataClass == SataLegacyIde) { ValueByte = ValueByte | 0x50; } else { if (LocalCfgPtr->Sata.SataIdeMode == 1) { // // Both IDE & SATA set to Native mode // ValueByte = ValueByte | 0xF0; } } LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC01, &ValueByte, StdHeader); }
/** * WriteEc8 - Write date into EC register * * * * @param[in] Address - EC Register Offset Value * @param[in] Value - Write Data Buffer * @param[in] StdHeader * */ VOID WriteEc8 ( IN UINT8 Address, IN UINT8 *Value, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT16 EcIndexPortDword; ReadPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGA4, AccessWidth16, &EcIndexPortDword, StdHeader); EcIndexPortDword &= ~(BIT0); LibAmdIoWrite (AccessWidth8, EcIndexPortDword, &Address, StdHeader); LibAmdIoWrite (AccessWidth8, EcIndexPortDword + 1, Value, StdHeader); }
AGESA_STATUS BiosReset (UINT32 Func, UINT32 Data, VOID *ConfigPtr) { AGESA_STATUS Status; UINT8 Value; UINTN ResetType; AMD_CONFIG_PARAMS *StdHeader; ResetType = Data; StdHeader = ConfigPtr; // // Perform the RESET based upon the ResetType. In case of // WARM_RESET_WHENVER and COLD_RESET_WHENEVER, the request will go to // AmdResetManager. During the critical condition, where reset is required // immediately, the reset will be invoked directly by writing 0x04 to port // 0xCF9 (Reset Port). // switch (ResetType) { case WARM_RESET_WHENEVER: case COLD_RESET_WHENEVER: break; case WARM_RESET_IMMEDIATELY: case COLD_RESET_IMMEDIATELY: Value = 0x06; LibAmdIoWrite (AccessWidth8, 0xCf9, &Value, StdHeader); break; default: break; } Status = 0; return Status; }
/*++ Routine Description: Arguments: DispatchHandle - The handle of this callback, obtained when registering DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT Returns: None. --*/ EFI_STATUS EFIAPI AmdSmiS3SleepEntryCallback ( IN EFI_HANDLE DispatchHandle, IN FCH_SMM_SX_REGISTER_CONTEXT *DispatchContext ) { UINT8 Index; UINT8 *pData; FCH_DATA_BLOCK *pFchPolicy; pFchPolicy = &gFchInitInSmm.FchPolicy; // Save entire FCH PCI IRQ routing space (C00/C01) pData = mFchPciIrqRoutingTable; Index = 0xFF; do { Index++; LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC00, &Index, NULL); LibAmdIoRead (AccessWidth8, FCH_IOMAP_REGC01, pData++, NULL); } while (Index != 0xFF); //Put Usb3 to S0 power rail RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REGEE, AccessWidth8, ~(BIT0 + BIT1), (BIT1 + BIT0)); BackUpCG2 (); FixPsp4Ehang (); return EFI_SUCCESS; }
/** * SoftwareDisableImc - Software disable IMC strap * * * @param[in] FchDataPtr Fch configuration structure pointer. * */ VOID SoftwareDisableImc ( IN VOID *FchDataPtr ) { UINT8 ValueByte; UINT8 PortStatusByte; UINT32 AbValue; UINT32 ABStrapOverrideReg; AMD_CONFIG_PARAMS *StdHeader; StdHeader = ((FCH_DATA_BLOCK *) FchDataPtr)->StdHeader; GetChipSysMode (&PortStatusByte, StdHeader); RwPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGC8 + 3, AccessWidth8, 0x7F, BIT7, StdHeader); ReadPmio (FCH_PMIOA_REGBF, AccessWidth8, &ValueByte, StdHeader); ReadMem ((ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG80), AccessWidth32, &AbValue); ABStrapOverrideReg = AbValue; ABStrapOverrideReg &= ~BIT2; // bit2=0 EcEnableStrap WriteMem ((ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG84), AccessWidth32, &ABStrapOverrideReg); ReadPmio (FCH_PMIOA_REGD7, AccessWidth8, &ValueByte, StdHeader); ValueByte |= BIT1; // Set GenImcClkEn to 1 WritePmio (FCH_PMIOA_REGD7, AccessWidth8, &ValueByte, StdHeader); ValueByte = 06; LibAmdIoWrite (AccessWidth8, 0xcf9, &ValueByte, StdHeader); FchStall (0xffffffff, StdHeader); }
/** * AbCfgTbl - Program ABCFG by input table. * * * @param[in] ABTbl ABCFG config table. * @param[in] StdHeader * */ VOID AbCfgTbl ( IN AB_TBL_ENTRY *ABTbl, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 AbValue; while ( (ABTbl->RegType) != 0xFF ) { if ( ABTbl->RegType == AXINDC ) { AbValue = 0x30 | (ABTbl->RegType << 29); WriteAlink (AbValue, (ABTbl->RegIndex & 0x00FFFFFF), StdHeader); AbValue = 0x34 | (ABTbl->RegType << 29); WriteAlink (AbValue, ((ReadAlink (AbValue, StdHeader)) & (0xFFFFFFFF^ (ABTbl->RegMask))) | ABTbl->RegData, StdHeader); } else if ( ABTbl->RegType == AXINDP ) { AbValue = 0x38 | (ABTbl->RegType << 29); WriteAlink (AbValue, (ABTbl->RegIndex & 0x00FFFFFF), StdHeader); AbValue = 0x3C | (ABTbl->RegType << 29); WriteAlink (AbValue, ((ReadAlink (AbValue, StdHeader)) & (0xFFFFFFFF^ (ABTbl->RegMask))) | ABTbl->RegData, StdHeader); } else { AbValue = ABTbl->RegIndex | (ABTbl->RegType << 29); WriteAlink (AbValue, ((ReadAlink (AbValue, StdHeader)) & (0xFFFFFFFF^ (ABTbl->RegMask))) | ABTbl->RegData, StdHeader); } ++ABTbl; } // //Clear ALink Access Index // AbValue = 0; LibAmdIoWrite (AccessWidth32, ALINK_ACCESS_INDEX, &AbValue, StdHeader); }
/** * FchInitEnvIr - Config Ir controller before PCI emulation * * * * @param[in] FchDataPtr Fch configuration structure pointer. * */ VOID FchInitEnvIr ( IN VOID *FchDataPtr ) { IR_CONFIG FchIrConfig; UINT8 Data; FCH_DATA_BLOCK *LocalCfgPtr; AMD_CONFIG_PARAMS *StdHeader; LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; StdHeader = LocalCfgPtr->StdHeader; FchIrConfig = LocalCfgPtr->Ir.IrConfig; // //IR init Logical device 0x05 // if (FchIrConfig != IrDisable) { EnterEcConfig (StdHeader); RwEc8 (0x07, 0x00, 0x05, StdHeader); ///Select logical device 05, IR controller RwEc8 (0x60, 0x00, 0x05, StdHeader); ///Set Base Address to 550h RwEc8 (0x61, 0x00, 0x50, StdHeader); RwEc8 (0x70, 0xF0, 0x05, StdHeader); ///Set IRQ to 05h RwEc8 (0x30, 0x00, 0x01, StdHeader); ///Enable logical device 5, IR controller Data = 0xAB; LibAmdIoWrite (AccessWidth8, 0x550, &Data, StdHeader); LibAmdIoRead (AccessWidth8, 0x551, &Data, StdHeader); Data = (((Data & 0xFC ) | 0x20) | (UINT8) FchIrConfig); LibAmdIoWrite (AccessWidth8, 0x551, &Data, StdHeader); ExitEcConfig (StdHeader); Data = 0xA0; /// EC APIC index LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC00, &Data, StdHeader); Data = 0x05; /// IRQ5 LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC01, &Data, StdHeader); } else { EnterEcConfig (StdHeader); RwEc8 (0x07, 0x00, 0x05, StdHeader); ///Select logical device 05, IR controller RwEc8 (0x30, 0x00, 0x00, StdHeader); ///Disable logical device 5, IR controller ExitEcConfig (StdHeader); } }
/** * Write PCI config space * * * @param[in] AccessWidth Access width * @param[in] PciAddress Pci address * @param[in] Value Pointer to data * @param[in] StdHeader Standard configuration header * */ VOID LibAmdPciWrite ( IN ACCESS_WIDTH AccessWidth, IN PCI_ADDR PciAddress, IN VOID *Value, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { UINT32 Address32; Address32 = BIT31 + (UINT32) ((PciAddress.Address.Bus << 16) + \ (PciAddress.Address.Device << 11) + \ (PciAddress.Address.Function << 8) + \ (PciAddress.Address.Register & 0xFF)); LibAmdIoWrite (AccessWidth32, CFG_ADDR_PORT, &Address32, StdHeader); LibAmdIoWrite (AccessWidth, CFG_DATA_PORT, Value, StdHeader); }
/**< outPort80 - Reserved */ VOID OutPort80 ( IN UINT32 pcode, IN AMD_CONFIG_PARAMS *StdHeader ) { LibAmdIoWrite (AccessWidth8, FCHOEM_OUTPUT_DEBUG_PORT, &pcode, StdHeader); return; }
/**< outPort1080 - Reserved */ VOID OutPort1080 ( IN UINT32 pcode, IN AMD_CONFIG_PARAMS *StdHeader ) { LibAmdIoWrite (AccessWidth32, 0x1080, &pcode, StdHeader); return; }
/** * FchSataDriveDetectionFpga * * @param[in] LocalCfgPtr * @param[in] Bar5 * */ VOID FchSataDriveDetectionFpga ( IN FCH_DATA_BLOCK *LocalCfgPtr, IN UINT32 *Bar5 ) { UINT32 SataBarFpgaInfo; UINT8 PortNum; UINT8 SataFpaPortType; UINT16 IoBase; UINT32 SataFpgaLoopVarWord; AMD_CONFIG_PARAMS *StdHeader; StdHeader = LocalCfgPtr->StdHeader; TRACE ((DMSG_FCH_TRACE, "FCH - Entering sata drive detection procedure\n\n")); TRACE ((DMSG_FCH_TRACE, "SATA BAR5 is %X \n", *pBar5)); for ( PortNum = 0; PortNum < 4; PortNum++ ) { ReadMem (*Bar5 + FCH_SATA_BAR5_REG128 + PortNum * 0x80, AccWidthUint32, &SataBarFpgaInfo); if ( ( SataBarFpgaInfo & 0x0F ) == 0x03 ) { if ( PortNum & BIT0 ) { //this port belongs to secondary channel ReadPci (((UINT32) (SATA_BUS_DEV_FUN_FPGA << 16) + FCH_SATA_REG18), AccWidthUint16, &IoBase); } else { //this port belongs to primary channel ReadPci (((UINT32) (SATA_BUS_DEV_FUN_FPGA << 16) + FCH_SATA_REG10), AccWidthUint16, &IoBase); } //if legacy ide mode, then the bar registers don't contain the correct values. So we need to hardcode them if ( LocalCfgPtr->Sata.SataClass == SataLegacyIde ) { IoBase = ( (0x170) | ((UINT16) ( (~((UINT8) (PortNum & BIT0) << 7)) & 0x80 )) ); } if ( PortNum & BIT1 ) { //this port is slave SataFpaPortType = 0xB0; } else { //this port is master SataFpaPortType = 0xA0; } IoBase &= 0xFFF8; LibAmdIoWrite (AccessWidth8, IoBase + 6, &SataFpaPortType, StdHeader); //Wait in loop for 30s for the drive to become ready for ( SataFpgaLoopVarWord = 0; SataFpgaLoopVarWord < 300000; SataFpgaLoopVarWord++ ) { LibAmdIoRead (AccessWidth8, IoBase + 7, &SataFpaPortType, StdHeader); if ( (SataFpaPortType & 0x88) == 0 ) { break; } FchStall (100, StdHeader); } } } }
/** * Print formated string with redirect IO * * @param[in] Buffer - Point to input buffer * @param[in] BufferSize - Buffer size * @param[in] debugPrintPrivate - Option * **/ VOID AmdIdsRedirectIoPrint ( IN CHAR8 *Buffer, IN UINTN BufferSize, IN IDS_DEBUG_PRINT_PRIVATE_DATA *debugPrintPrivate ) { UINT32 Value; Value = REDIRECT_IO_DATA_BEGIN; LibAmdIoWrite (AccessWidth32, IDS_DEBUG_PRINT_IO_PORT, &Value, NULL); while (BufferSize--) { LibAmdIoWrite (AccessWidth8, IDS_DEBUG_PRINT_IO_PORT, Buffer++, NULL); } Value = REDIRECT_IO_DATA_END; LibAmdIoWrite (AccessWidth32, IDS_DEBUG_PRINT_IO_PORT, &Value, NULL); }
/**< FchReset - Reserved */ VOID FchReset ( IN AMD_CONFIG_PARAMS *StdHeader ) { UINT8 PciRstValue; PciRstValue = 0x06; LibAmdIoWrite (AccessWidth8, FCH_PCIRST_BASE_IO, &PciRstValue, StdHeader); }
EFI_STATUS EFIAPI AmdStopTimerSmiCallback ( IN EFI_HANDLE DispatchHandle, IN FCH_SMM_SW_REGISTER_CONTEXT *DispatchContext ) { ACPIMMIO16 (ACPI_MMIO_BASE + SMI_BASE + FCH_SMI_REG96) &= ~SMI_TIMER_ENABLE; LibAmdIoWrite (AccessWidth16, 0x80, &SavePort80, NULL); return EFI_SUCCESS; }
VOID GnbLibIoWrite ( IN UINT16 Address, IN ACCESS_WIDTH Width, IN VOID *Value, IN VOID *StdHeader ) { if (Width >= AccessS3SaveWidth8) { S3_SAVE_IO_WRITE (StdHeader, Address, Width, Value); } LibAmdIoWrite (Width, Address, Value, StdHeader); }
/** * ExitEcConfig - Force EC exit Config mode * * * * */ VOID ExitEcConfig ( IN AMD_CONFIG_PARAMS *StdHeader ) { UINT16 EcIndexPortDword; UINT8 FchEcData8; ReadPci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REGA4, AccessWidth16, &EcIndexPortDword, StdHeader); EcIndexPortDword &= ~(BIT0); FchEcData8 = 0xA5; LibAmdIoWrite (AccessWidth8, EcIndexPortDword, &FchEcData8, StdHeader); }
VOID WriteECmsg ( IN UINT8 Address, IN UINT8 OpFlag, IN VOID *Value, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT8 Index; OpFlag = OpFlag & 0x7f; if (OpFlag == 0x02) { OpFlag = 0x03; } for (Index = 0; Index <= OpFlag; Index++) { /// EC_LDN9_MAILBOX_BASE_ADDRESS LibAmdIoWrite (AccessWidth8, 0x3E, &Address, StdHeader); Address++; /// EC_LDN9_MAILBOX_BASE_ADDRESS LibAmdIoWrite (AccessWidth8, 0x3F, (UINT8 *)Value + Index, StdHeader); } }
/** * StressResetModeLate - Stress Reset Mode * * * * @param[in] FchDataPtr * */ VOID StressResetModeLate ( IN VOID *FchDataPtr ) { UINT8 ResetValue; FCH_DATA_BLOCK *LocalCfgPtr; AMD_CONFIG_PARAMS *StdHeader; LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; StdHeader = LocalCfgPtr->StdHeader; switch ( LocalCfgPtr->HwAcpi.StressResetMode ) { case 0: return; case 1: ResetValue = FCH_KBC_RESET_COMMAND; LibAmdIoWrite (AccessWidth8, FCH_KBDRST_BASE_IO, &ResetValue, StdHeader); break; case 2: ResetValue = FCH_PCI_RESET_COMMAND06; LibAmdIoWrite (AccessWidth8, FCH_PCIRST_BASE_IO, &ResetValue, StdHeader); break; case 3: ResetValue = FCH_PCI_RESET_COMMAND0E; LibAmdIoWrite (AccessWidth8, FCH_PCIRST_BASE_IO, &ResetValue, StdHeader); break; case 4: LocalCfgPtr->HwAcpi.StressResetMode = 3; return; default: ASSERT (FALSE); return; } while (LocalCfgPtr->HwAcpi.StressResetMode) { } }
/** * AgesaDoReset * * Description * Call the host environment interface to perform reset. * * @param[in] ResetType * @param[in,out] *StdHeader * * @return void * */ VOID AgesaDoReset ( IN UINTN ResetType, IN OUT AMD_CONFIG_PARAMS *StdHeader ) { EFI_PEI_SERVICES **PeiServices; UINT8 Value; EFI_STATUS Status; WARM_RESET_REQUEST Request; PeiServices = (EFI_PEI_SERVICES **)StdHeader->ImageBasePtr; GetWarmResetFlag (StdHeader, &Request); Request.RequestBit = FALSE; Request.StateBits = Request.PostStage; SetWarmResetFlag (StdHeader, &Request); // // Perform the RESET based upon the ResetType. In case of // WARM_RESET_WHENVER and COLD_RESET_WHENEVER, the request will go to // AmdResetManager. During the critical condition, where reset is required // immediately, the reset will be invoked directly by writing 0x04 to port // 0xCF9 (Reset Port). // switch (ResetType) { case WARM_RESET_WHENEVER: case COLD_RESET_WHENEVER: (**PeiServices).InstallPpi (PeiServices, &mAmdPeiResetRequestPpi); break; case WARM_RESET_IMMEDIATELY: case COLD_RESET_IMMEDIATELY: Status = (**PeiServices).PeiResetSystem (PeiServices); // // We should not come here if PeiResetSystem is present. // In case it is missing and gets reported through // EFI_NOT_AVAILABLE_YET, perform the force reset // if (EFI_ERROR (Status)) { Value = 0x06; LibAmdIoWrite (AccessWidth8, 0xCf9, &Value, StdHeader); } break; default: (**PeiServices).InstallPpi (PeiServices, &mAmdPeiResetRequestPpi); break; } }
EFI_STATUS EFIAPI AmdSmiAcpiOffCallback ( IN EFI_HANDLE DispatchHandle, IN FCH_SMM_SW_REGISTER_CONTEXT *DispatchContext ) { UINT16 AcpiPmbase; UINT32 ddValue; GetFchAcpiPmBase (&AcpiPmbase, NULL); // Turn off SCI LibAmdIoRead (AccessWidth32, AcpiPmbase + R_FCH_ACPI_PM_CONTROL, &ddValue, NULL); ddValue &= ~BIT0; LibAmdIoWrite (AccessWidth32, AcpiPmbase + R_FCH_ACPI_PM_CONTROL, &ddValue, NULL); return EFI_SUCCESS; }
/********************************************************************************* * Name: FchSataOnRecovery * * Description * * * Input * FchPrivate : FCH PEI private data structure * SataBar0 : BAR0 register value of Sata controller * SataBar5 : BAR5 register value of Sata controller * * Output * * *********************************************************************************/ EFI_STATUS FchSataOnRecovery ( IN FCH_PEI_PRIVATE FchPrivate, IN UINT32 SataBar0, IN UINT32 SataBar5 ) { UINT8 ValueByte; AMD_CONFIG_PARAMS StdHeader; StdHeader = FchPrivate.StdHdr; RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG40), AccessWidth8, 0xff, BIT0, &StdHeader); RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG44), AccessWidth8, 0xff, BIT0, &StdHeader); RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG44 + 2), AccessWidth8, 0, 0x20, &StdHeader); RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG40), AccessWidth8, 0xff, BIT4, &StdHeader); RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG48 + 3), AccessWidth8, 0xff, BIT7, &StdHeader); RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG4C + 3), AccessWidth8, 0x07, 0xF8, &StdHeader); RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG4C), AccessWidth32, (UINT32) (~ (0xF8 << 26)), (UINT32) (0xF8 << 26), &StdHeader); RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG48), AccessWidth32, (UINT32) (~ (0x01 << 11)), (UINT32) (0x01 << 11), &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_REG08), AccessWidth32, 0, 0x01018F40, &StdHeader); RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG02), AccessWidth16, 0, FCH_SATA_DID, &StdHeader); ValueByte = 0x08; LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC00, &ValueByte, &StdHeader); LibAmdIoRead (AccessWidth8, FCH_IOMAP_REGC01, &ValueByte, &StdHeader); // // SATA PHY Programming Sequence // FchRecoveryProgramSataPhy (&StdHeader); RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG10), AccessWidth32, BIT0, SataBar0, &StdHeader); RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG14), AccessWidth32, BIT0, SataBar0 + 0x100, &StdHeader); RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG18), AccessWidth32, BIT0, SataBar0 + 0x200, &StdHeader); RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG1C), AccessWidth32, BIT0, SataBar0 + 0x300, &StdHeader); RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG20), AccessWidth32, BIT0, SataBar0 + 0x400, &StdHeader); RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG24), AccessWidth32, 0xff, SataBar5, &StdHeader); RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG04), AccessWidth8, 0, BIT0 + BIT1, &StdHeader); RwPci (((SATA_BUS_DEV_FUN << 16) + FCH_SATA_REG40), AccessWidth8, ~BIT0, 0, &StdHeader); return EFI_SUCCESS; }
EFI_STATUS EFIAPI AmdSmiAcpiOnCallback ( IN EFI_HANDLE DispatchHandle, IN FCH_SMM_SW_REGISTER_CONTEXT *DispatchContext ) { FCH_DATA_BLOCK *pFchPolicy; UINT16 AcpiPmbase; UINT8 dbIndex; UINT8 dbIrq; UINT32 ddValue; //EFI_DEADLOOP (); // WriteIO16 (0x80, 0xAACC); GetFchAcpiPmBase (&AcpiPmbase, NULL); pFchPolicy = &gFchInitInSmm.FchPolicy; FchSmmAcpiOn (pFchPolicy); // Disable all GPE events and clear all GPE status ddValue = 0; LibAmdIoWrite (AccessWidth32, AcpiPmbase + R_FCH_ACPI_EVENT_ENABLE, &ddValue, NULL); LibAmdIoWrite (AccessWidth32, AcpiPmbase + R_FCH_ACPI_EVENT_STATUS, &ddValue, NULL); // Set ACPI IRQ to IRQ9 for non-APIC OSes dbIndex = 0x10; // PIC - SCI dbIrq = 9; LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC00, &dbIndex, NULL); LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC01, &dbIrq, NULL); dbIndex |= BIT7; // IOAPIC - SCI LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC00, &dbIndex, NULL); LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC01, &dbIrq, NULL); // Finally enable SCI LibAmdIoRead (AccessWidth32, AcpiPmbase + R_FCH_ACPI_PM_CONTROL, &ddValue, NULL); ddValue |= BIT0; LibAmdIoWrite (AccessWidth32, AcpiPmbase + R_FCH_ACPI_PM_CONTROL, &ddValue, NULL); return EFI_SUCCESS; }
/** * Prepare an FCH AB link entry on a family 15h Carrizo core. * * @param[in] CurrentEntry Current entry to process * * @return Pointer to next table entry */ CS_RESTORATION_ENTRY_HEADER* F15CzProcessFchAbEntry ( IN CS_RESTORATION_ENTRY_HEADER *CurrentEntry ) { UINT32 RegisterIndex; UINT64 MmioAddr; CS_FCH_AB *FchAbEntry; FchAbEntry = (CS_FCH_AB *) CurrentEntry; if (FchAbEntry->Header.SaveReadValue) { if (AbIoAddress == 0xFFFF) { MmioAddr = 0xFED803E0; LibAmdMemRead (AccessWidth16, MmioAddr, &AbIoAddress, NULL); } RegisterIndex = FchAbEntry->Address + 0xC0000000; LibAmdIoWrite (AccessWidth32, AbIoAddress, &RegisterIndex, NULL); LibAmdIoRead (AccessWidth32, AbIoAddress + 4, &FchAbEntry->Value, NULL); } FchAbEntry++; return &FchAbEntry->Header; }
/** * Send byte to Serial Port * * Before use this routine, please make sure Serial Communications Chip have been initialed * * @param[in] ByteSended Byte to be sended * * @retval TRUE Byte sended successfully * @retval FALSE Byte sended failed * **/ BOOLEAN AmdIdsSerialSendByte ( IN CHAR8 ByteSended ) { UINT32 RetryCount; UINT8 Value; //Wait until LSR.Bit5 (Transmitter holding register Empty) RetryCount = 200; do { LibAmdIoRead (AccessWidth8, IDS_SERIAL_PORT_LSR, &Value, NULL); RetryCount--; } while (((Value & IDS_LSR_TRANSMIT_HOLDING_REGISTER_EMPTY_MASK) == 0) && (RetryCount > 0)); if (RetryCount == 0) { //Time expired return FALSE; } else { LibAmdIoWrite (AccessWidth8, IDS_SERIAL_PORT, &ByteSended, NULL); return TRUE; } }
/** * FchInitEnvAbLinkInit - Set ABCFG registers before PCI * emulation. * * * @param[in] FchDataPtr Fch configuration structure pointer. * */ VOID FchInitEnvAbLinkInit ( IN VOID *FchDataPtr ) { UINT16 AbTempVar; UINT8 AbValue8; UINT8 FchALinkClkGateOff; UINT8 FchBLinkClkGateOff; AB_TBL_ENTRY *AbTblPtr; FCH_DATA_BLOCK *LocalCfgPtr; AMD_CONFIG_PARAMS *StdHeader; LocalCfgPtr = (FCH_DATA_BLOCK *) FchDataPtr; StdHeader = LocalCfgPtr->StdHeader; FchALinkClkGateOff = (UINT8) LocalCfgPtr->Ab.ALinkClkGateOff; FchBLinkClkGateOff = (UINT8) LocalCfgPtr->Ab.BLinkClkGateOff; // // AB CFG programming // if ( LocalCfgPtr->Ab.SlowSpeedAbLinkClock ) { RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG40, AccessWidth8, ~(UINT32) BIT1, BIT1); } else { RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG40, AccessWidth8, ~(UINT32) BIT1, 0); } // // Read Arbiter address, Arbiter address is in PMIO 6Ch // ReadMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG6C, AccessWidth16, &AbTempVar); /// Write 0 to enable the arbiter AbValue8 = 0; LibAmdIoWrite (AccessWidth8, AbTempVar, &AbValue8, StdHeader); if ( LocalCfgPtr->Ab.PcieOrderRule == 1 ) { AbTblPtr = (AB_TBL_ENTRY *) (&Hudson2PcieOrderRule[0]); AbCfgTbl (AbTblPtr, StdHeader); } if ( LocalCfgPtr->Ab.PcieOrderRule == 2 ) { RwAlink (FCH_ABCFG_REG10090 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x7 << 10), (UINT32) (0x7 << 10), StdHeader); RwAlink (FCH_ABCFG_REG58 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1F << 11), (UINT32) (0x1C << 11), StdHeader); RwAlink (FCH_ABCFG_REGB4 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x3 << 0), (UINT32) (0x3 << 0), StdHeader); } AbTblPtr = (AB_TBL_ENTRY *) (&Hudson2InitEnvAbTable[0]); AbCfgTbl (AbTblPtr, StdHeader); if ( LocalCfgPtr->Ab.ResetCpuOnSyncFlood ) { RwAlink (FCH_ABCFG_REG10050 | (UINT32) (ABCFG << 29), ~(UINT32) BIT2, BIT2, StdHeader); } if ( LocalCfgPtr->Ab.AbClockGating ) { RwAlink (FCH_ABCFG_REG10054 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xFF << 16), (UINT32) (0x4 << 16), StdHeader); RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xFF << 16), (UINT32) (0x4 << 16), StdHeader); RwAlink (FCH_ABCFG_REG10054 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 24), (UINT32) (0x1 << 24), StdHeader); RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 24), (UINT32) (0x1 << 24), StdHeader); } else { RwAlink (FCH_ABCFG_REG10054 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 24), (UINT32) (0x0 << 24), StdHeader); RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 24), (UINT32) (0x0 << 24), StdHeader); } if ( LocalCfgPtr->Ab.GppClockGating ) { RwAlink (FCH_ABCFG_REG98 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xF << 12), (UINT32) (0x4 << 12), StdHeader); RwAlink (FCH_ABCFG_REG98 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xF << 8), (UINT32) (0x7 << 8), StdHeader); RwAlink (FCH_ABCFG_REG90 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 0), (UINT32) (0x1 << 0), StdHeader); } else { RwAlink (FCH_ABCFG_REG98 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xF << 8), (UINT32) (0x0 << 8), StdHeader); RwAlink (FCH_ABCFG_REG90 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 0), (UINT32) (0x0 << 0), StdHeader); } if ( LocalCfgPtr->Ab.UmiL1TimerOverride ) { RwAlink (FCH_ABCFG_REG90 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x7 << 12), (UINT32) (LocalCfgPtr->Ab.UmiL1TimerOverride << 12), StdHeader); RwAlink (FCH_ABCFG_REG90 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 15), (UINT32) (0x1 << 15), StdHeader); } if ( LocalCfgPtr->Ab.UmiLinkWidth ) { // RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xFF << 16), (UINT32) (0x4 << 16)); } if ( LocalCfgPtr->Ab.PcieRefClockOverClocking ) { // RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xFF << 16), (UINT32) (0x4 << 16)); } if ( LocalCfgPtr->Ab.UmiGppTxDriverStrength ) { RwAlink (FCH_ABCFG_REGA8 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x3 << 18), (UINT32) ((LocalCfgPtr->Ab.UmiGppTxDriverStrength - 1) << 18), StdHeader); RwAlink (FCH_ABCFG_REGA0 | (UINT32) (ABCFG << 29), ~ (UINT32) (0x1 << 8), (UINT32) (0x1 << 8), StdHeader); } if ( LocalCfgPtr->Gpp.PcieAer ) { // RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xFF << 16), (UINT32) (0x4 << 16)); } if ( LocalCfgPtr->Gpp.PcieRas ) { // RwAlink (FCH_ABCFG_REG54 | (UINT32) (ABCFG << 29), ~ (UINT32) (0xFF << 16), (UINT32) (0x4 << 16)); } // // Ab Bridge MSI // if ( LocalCfgPtr->Ab.AbMsiEnable) { // AbValue = ReadAlink (FCH_ABCFG_REG94 | (UINT32) (ABCFG << 29), StdHeader); // AbValue = AbValue | BIT20; // WriteAlink (FCH_ABCFG_REG94 | (UINT32) (ABCFG << 29), AbValue, StdHeader); } // // A/B Clock Gate-OFF // if ( FchALinkClkGateOff ) { RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG2C + 2, AccessWidth8, 0xFE, BIT0); } else { RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG2C + 2, AccessWidth8, 0xFE, 0x00); } if ( FchBLinkClkGateOff ) { //RwMem (ACPI_MMIO_BASE + MISC_BASE + 0x2D, AccessWidth8, 0xEF, 0x10); /// A11 Only RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG2C + 2, AccessWidth8, 0xFD, BIT1); } else { RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG2C + 2, AccessWidth8, 0xFD, 0x00); } if ( FchALinkClkGateOff | FchBLinkClkGateOff ) { RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG04 + 2, AccessWidth8, 0xFE, BIT0); } else { RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG04 + 2, AccessWidth8, 0xFE, 0); } if ( ReadFchChipsetRevision ( StdHeader ) == FCH_BOLTON ) { // Enable fix for race problem between PLL calibrator and LC wake up from L1. RwAlink (FCH_AX_INDXC_REG02, ~(UINT32) (BIT8), BIT8, StdHeader); // Set this bit to 1 to allow for proper ASPM L1 and L0s transitions when PLL power-down in L1 is enabled. RwAlink ((FCH_ABCFG_REGB8 | (UINT32) (ABCFG << 29)), 0xFFFFFFFF, BIT30, StdHeader); // A/B Clock Gate-OFF RwMem (ACPI_MMIO_BASE + MISC_BASE + FCH_MISC_REG2C + 2, AccessWidth8, 0xFC, 0x03); RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG04 + 2, AccessWidth8, 0xFE, BIT0); } }
/** * FchInitResetHwAcpi - Config HwAcpi controller during Power-On * * * * @param[in] FchDataPtr Fch configuration structure pointer. * */ VOID FchInitResetHwAcpi ( IN VOID *FchDataPtr ) { UINT16 SmbusBase; UINT8 Value; UINT16 AsfPort; FCH_RESET_DATA_BLOCK *LocalCfgPtr; AMD_CONFIG_PARAMS *StdHeader; LocalCfgPtr = (FCH_RESET_DATA_BLOCK *) FchDataPtr; StdHeader = LocalCfgPtr->StdHeader; // // Set Build option into SB // WritePci ((LPC_BUS_DEV_FUN << 16) + FCH_LPC_REG64, AccessWidth16, &(UserOptions.CfgSioPmeBaseAddress), StdHeader); // // Enabled SMBUS0/SMBUS1 (ASF) Base Address // RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG2C, AccessWidth16, 06, (UserOptions.CfgSmbus0BaseAddress) + BIT0); ///protect BIT[2:1] RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG28, AccessWidth16, 06, (UserOptions.CfgSmbus1BaseAddress) + BIT0); RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG60, AccessWidth16, 00, (UserOptions.CfgAcpiPm1EvtBlkAddr)); RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG62, AccessWidth16, 00, (UserOptions.CfgAcpiPm1CntBlkAddr)); RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG64, AccessWidth16, 00, (UserOptions.CfgAcpiPmTmrBlkAddr)); RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG66, AccessWidth16, 00, (UserOptions.CfgCpuControlBlkAddr)); RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG68, AccessWidth16, 00, (UserOptions.CfgAcpiGpe0BlkAddr)); RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG6A, AccessWidth16, 00, (UserOptions.CfgSmiCmdPortAddr)); RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG6C, AccessWidth16, 00, (UserOptions.CfgAcpiPmaCntBlkAddr)); RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG6E, AccessWidth16, 00, (UserOptions.CfgSmiCmdPortAddr) + 8); RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG48, AccessWidth32, 00, (UserOptions.CfgWatchDogTimerBase)); RwMem (ACPI_MMIO_BASE + PMIO_BASE + FCH_PMIOA_REG2E, AccessWidth8, ~(BIT1 + BIT2), 0); ///clear BIT[2:1] SmbusBase = (UINT16) (UserOptions.CfgSmbus0BaseAddress); Value = 0x00; LibAmdIoWrite (AccessWidth8, SmbusBase + 0x14, &Value, StdHeader); ProgramFchAcpiMmioTbl ((ACPI_REG_WRITE*) (&FchInitResetAcpiMmioTable[0]), StdHeader); // // Prevent RTC error // Value = 0x0A; LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REG70, &Value, StdHeader); LibAmdIoRead (AccessWidth8, FCH_IOMAP_REG71, &Value, StdHeader); Value &= 0xEF; LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REG71, &Value, StdHeader); Value = 0x08; LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC00, &Value, StdHeader); LibAmdIoRead (AccessWidth8, FCH_IOMAP_REGC01, &Value, StdHeader); if ( !LocalCfgPtr->EcKbd ) { // // Route SIO IRQ1/IRQ12 to USB IRQ1/IRQ12 input // Value = Value | 0x0A; } LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC01, &Value, StdHeader); Value = 0x09; LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC00, &Value, StdHeader); LibAmdIoRead (AccessWidth8, FCH_IOMAP_REGC01, &Value, StdHeader); if ( !LocalCfgPtr->EcKbd ) { // // Route SIO IRQ1/IRQ12 to USB IRQ1/IRQ12 input // Value = Value & 0xF9; } if ( LocalCfgPtr->LegacyFree ) { // // Disable IRQ1/IRQ12 filter enable for Legacy free with USB KBC emulation. // Value = Value & 0x9F; } // // Enabled IRQ input // Value = Value | BIT4; LibAmdIoWrite (AccessWidth8, FCH_IOMAP_REGC01, &Value, StdHeader); AsfPort = ((UINT16) UserOptions.CfgSmbus1BaseAddress & 0xFFF0); if ( AsfPort != 0 ) { UINT8 dbValue; dbValue = 0x70; LibAmdIoWrite (AccessWidth8, AsfPort + 0x0E, &dbValue, StdHeader); } }