diff options
Diffstat (limited to 'ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib')
7 files changed, 1440 insertions, 0 deletions
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/IobpAccess.c b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/IobpAccess.c new file mode 100644 index 0000000..d21a181 --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/IobpAccess.c @@ -0,0 +1,295 @@ +/** @file + Program IOBP register. + +@copyright + Copyright (c) 2009 - 2013 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains an 'Intel Peripheral Driver' and uniquely + identified as "Intel Reference Module" and is + licensed for Intel CPUs and chipsets under the terms of your + license agreement with Intel or your vendor. This file may + be modified by the user, subject to additional terms of the + license agreement +**/ +#include "PchPlatformLibrary.h" + +/** + Configures PCH IOBP + + @param[in] RootComplexBar RootComplexBar value of this PCH device + @param[in] Address Address of the IOBP register block + @param[in] AndMask Mask to AND with the register + @param[in] OrMask Mask to OR with the register + + @retval EFI_SUCCESS Successfully completed. + @retval EFI_DEVICE_ERROR Transaction fail +**/ +EFI_STATUS +EFIAPI +ProgramIobp ( + IN UINT32 RootComplexBar, + IN UINT32 Address, + IN UINT32 AndMask, + IN UINT32 OrMask + ) +{ + UINT32 Data32; + UINT8 ResponseStatus; + EFI_STATUS Status; + + /// + /// PCH BIOS Spec Rev 0.5.0, Section 7.1.4 IOSF SBI Programming + /// Step 1 to Step 8 + /// + Status = ReadIobp (RootComplexBar, Address, &Data32); + if (EFI_ERROR (Status)) { + return Status; + } + /// + /// Step 9 + /// Update the SBI data accordingly + /// + Data32 &= AndMask; + Data32 |= OrMask; + /// + /// Step 10 + /// Set RCBA + 2338h[15:8] = 00000111b + /// + MmioAndThenOr16 ( + (RootComplexBar + R_PCH_RCRB_IOBPS), + (UINT16) (~B_PCH_RCRB_IOBPS_IOBPIA), + (UINT16) V_PCH_RCRB_IOBPS_IOBPIA_W + ); + /// + /// Step 11 + /// Write RCBA + 2334h[31:0] with updated SBI data + /// + MmioWrite32 ((RootComplexBar + R_PCH_RCRB_IOBPD), Data32); + + /// + /// Step 12 + /// Set RCBA + 233Ah[15:0] = F000h + /// + MmioWrite16 ( + (RootComplexBar + 0x233A), + 0xF000 + ); + + /// + /// Step 13 + /// Set RCBA + 2338h[0] = 1b + /// + MmioOr16 ( + (RootComplexBar + R_PCH_RCRB_IOBPS), + (UINT16) BIT0 + ); + + /// + /// Step 14 + /// Poll RCBA + Offset 2338h[0] = 0b + /// + while (MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS_BUSY); + + /// + /// Step 15 + /// Check if RCBA + 2338h[2:1] = 00b for successful transaction + /// + ResponseStatus = MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS; + if (ResponseStatus == V_PCH_RCRB_IOBPS_SUCCESS) { + return EFI_SUCCESS; + } else { + return EFI_DEVICE_ERROR; + } +} + +/** + Read data from PCH IOBP register block + + @param[in] RootComplexBar RootComplexBar value of this PCH device + @param[in] Address Address of the IOBP register block + @param[out] Data Data contain in the IOBP register block + + @retval EFI_SUCCESS Successfully completed. + @retval EFI_DEVICE_ERROR Transaction fail +**/ +EFI_STATUS +EFIAPI +ReadIobp ( + IN UINT32 RootComplexBar, + IN UINT32 Address, + OUT UINT32 *Data + ) +{ + UINT8 ResponseStatus; + + /// + /// Step 1 Poll RCBA + 2338[0] = 0b + /// + while (MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS_BUSY); + + /// + /// Step 2 + /// Write RCBA + Offset 2330h[31:0] with IOBP register address + /// + MmioWrite32 ((RootComplexBar + R_PCH_RCRB_IOBPIRI), Address); + /// + /// Step 3 + /// Set RCBA + 2338h[15:8] = 00000110b + /// + MmioAndThenOr16 ( + (RootComplexBar + R_PCH_RCRB_IOBPS), + (UINT16) (~B_PCH_RCRB_IOBPS_IOBPIA), + (UINT16) V_PCH_RCRB_IOBPS_IOBPIA_R + ); + /// + /// Step 4 + /// Set RCBA + 233Ah[15:0] = F000h + /// + MmioWrite16 ( + (RootComplexBar + 0x233A), + 0xF000 + ); + /// + /// Step 5 + /// Set RCBA + 2338h[0] = 1b + /// + MmioOr16 ( + (RootComplexBar + R_PCH_RCRB_IOBPS), + (UINT16) BIT0 + ); + + /// + /// Step 6 + /// Poll RCBA + Offset 2338h[0] = 0b, Polling for Busy bit + /// + while (MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS_BUSY); + + /// + /// Step 7 + /// Check if RCBA + 2338h[2:1] = 00b for successful transaction + /// + ResponseStatus = MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS; + if (ResponseStatus == V_PCH_RCRB_IOBPS_SUCCESS) { + /// + /// Step 8 + /// Read RCBA + 2334h[31:0] for IOBP data + /// + *Data = MmioRead32 (RootComplexBar + R_PCH_RCRB_IOBPD); + return EFI_SUCCESS; + } else { + return EFI_DEVICE_ERROR; + } +} + +/** + Configures PCH IOBP + + @param[in] RootComplexBar RootComplexBar value of this PCH device + @param[in] Address Address of the IOBP register block + @param[in] Opcode Iobp Opcode + @param[in] RouteId Route Id + @param[in, out] Data32 Read/Write data + @param[out] Response Response + + @retval EFI_SUCCESS Successfully completed. + @retval EFI_DEVICE_ERROR Transaction fail +**/ +EFI_STATUS +EFIAPI +PchIobpExecution ( + IN UINT32 RootComplexBar, + IN UINT32 Address, + IN PCH_IOBP_OPCODE Opcode, + IN UINT8 RouteId, + IN OUT UINT32 *Data32, + OUT UINT8 *Response + ) +{ + /// + /// Step 1 Poll RCBA + 2338[0] = 0b + /// + while (MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS_BUSY); + /// + /// Step 2 + /// Write RCBA + Offset 2330h[31:0] with IOBP register address + /// + MmioWrite32 ((RootComplexBar + R_PCH_RCRB_IOBPIRI), Address); + /// + /// Step 3 + /// Set RCBA + 2338h[15:8] to the opcode passed in + /// + MmioAndThenOr16 ( + (RootComplexBar + R_PCH_RCRB_IOBPS), + (UINT16) (~B_PCH_RCRB_IOBPS_IOBPIA), + (UINT16) (Opcode << 8) + ); + /// + /// Step 4 + /// Set RCBA + 233Ah[15:8] = F0h + /// Set RCBA + 233Ah[7:0] = Route Id passed in + /// + MmioWrite16 ( + (RootComplexBar + 0x233A), + (0xF000 | RouteId) + ); + switch (Opcode) { + case MemoryMapWrite: + case IoMapWrite: + case PciConfigWrite: + case PrivateControlWrite: + /// + /// Step 5 + /// Write RCBA + 2334h[31:0] with updated SBI data + /// + MmioWrite32 ((RootComplexBar + R_PCH_RCRB_IOBPD), *Data32); + break; + default: + break; + } + /// + /// Step 6 + /// Set RCBA + 2338h[0] = 1b + /// + MmioOr16 ( + (RootComplexBar + R_PCH_RCRB_IOBPS), + (UINT16) BIT0 + ); + + /// + /// Step 7 + /// Poll RCBA + Offset 2338h[0] = 0b, Polling for Busy bit + /// + while (MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS_BUSY); + + /// + /// Step 8 + /// Check if RCBA + 2338h[2:1] = 00b for successful transaction + /// + *Response = MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS; + if (*Response == V_PCH_RCRB_IOBPS_SUCCESS) { + switch (Opcode) { + case MemoryMapRead: + case IoMapRead: + case PciConfigRead: + case PrivateControlRead: + /// + /// Step 9 + /// Read RCBA + 2334h[31:0] for IOBP data + /// + *Data32 = MmioRead32 (RootComplexBar + R_PCH_RCRB_IOBPD); + break; + default: + break; + } + + return EFI_SUCCESS; + } + return EFI_DEVICE_ERROR; +} diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.cif b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.cif new file mode 100644 index 0000000..d146e3b --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.cif @@ -0,0 +1,13 @@ +<component> + name = "PchPlatformLib" + category = ModulePart + LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\PchPlatformLib" + RefName = "PchPlatformLib" +[files] +"PchPlatformLib.mak" +"PchPlatformLib.sdl" +"PchPlatformLibrary.h" +"PchPlatformLibrary.c" +"PchPlatformLib.inf" +"IobpAccess.c" +<endComponent> diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.inf b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.inf new file mode 100644 index 0000000..2aa9a25 --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.inf @@ -0,0 +1,67 @@ +## @file +# Component description file for PEI/DXE PCH Platform Lib +# +#@copyright +# Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved +# This software and associated documentation (if any) is furnished +# under a license and may only be used or copied in accordance +# with the terms of the license. Except as permitted by such +# license, no part of this software or documentation may be +# reproduced, stored in a retrieval system, or transmitted in any +# form or by any means without the express written consent of +# Intel Corporation. +# +# This file contains a 'Sample Driver' and is licensed as such +# under the terms of your license agreement with Intel or your +# vendor. This file may be modified by the user, subject to +# the additional terms of the license agreement +# + + +[defines] +BASE_NAME = PchPlatformLib +COMPONENT_TYPE = LIBRARY + +[sources.common] + PchPlatformLibrary.h + PchPlatformLibrary.c + IobpAccess.c + +[sources.ia32] + +[sources.x64] + +[sources.ipf] + +[includes.common] + $(EDK_SOURCE)/Foundation/Efi + . + $(EDK_SOURCE)/Foundation/Include + $(EDK_SOURCE)/Foundation/Efi/Include + $(EDK_SOURCE)/Foundation/Framework/Include + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT) + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library +# +# EDK II Glue Library utilizes some standard headers from EDK +# + $(EFI_SOURCE) + $(EDK_SOURCE)/Foundation + $(EDK_SOURCE)/Foundation/Framework + $(EDK_SOURCE)/Foundation/Include/IndustryStandard + $(EDK_SOURCE)/Foundation/Core/Dxe + $(EDK_SOURCE)/Foundation/Include/Pei + $(EDK_SOURCE)/Foundation/Library/Dxe/Include + $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include +# +# Typically the sample code referenced will be available in the code base already +# So keep this include at the end to defer to the source base definition +# and only use the sample code definition if source base does not include these files. +# + $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/SampleCode + +[libraries.common] + EdkIIGlueBasePciLibPciExpress + EdkIIGlueBaseLib + +[nmake.common] diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.mak b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.mak new file mode 100644 index 0000000..d6ca967 --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.mak @@ -0,0 +1,112 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchPlatformLib/PchPlatformLib.mak 3 10/16/12 2:52a Scottyang $ +# +# $Revision: 3 $ +# +# $Date: 10/16/12 2:52a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchPlatformLib/PchPlatformLib.mak $ +# +# 3 10/16/12 2:52a Scottyang +# [TAG] EIP103924 +# [Category] Improvement +# [Description] Update RC 0.7.1 +# [Files] ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SB.sd, +# SbSetupData.c, GetSetupDate.c +# +# 2 7/02/12 9:17a Victortu +# +# 1 2/08/12 8:48a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* + +# MAK file for the ModulePart:PchPlatformLib +EDK : PchPlatformLib + +PchPlatformLib : PchPlatformSmmLib PchPlatformDxeLib PchPlatformPeiLib + +$(PchPlatformSmmLib_LIB) : PchPlatformSmmLib +$(PchPlatformDxeLib_LIB) : PchPlatformDxeLib +$(PchPlatformPeiLib_LIB) : PchPlatformPeiLib + +PchPlatformSmmLib : $(BUILD_DIR)\PchPlatformLib.mak PchPlatformLibSmmBin + +PchPlatformDxeLib : $(BUILD_DIR)\PchPlatformLib.mak PchPlatformLibDxeBin + +PchPlatformPeiLib : $(BUILD_DIR)\PchPlatformLib.mak PchPlatformLibPeiBin + +$(BUILD_DIR)\PchPlatformLib.mak : $(PchPlatformLib_DIR)\$(@B).cif $(PchPlatformLib_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(PchPlatformLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +PchPlatformLib_INCLUDES =\ + $(EdkIIGlueLib_INCLUDES)\ + $(INTEL_PCH_INCLUDES)\ + $(EDK_INCLUDES)\ + +PchPlatformLib_LIBS=\ + $(EdkIIGlueBaseLib_LIB)\ +!IF "$(x64_BUILD)"=="1" + $(EdkIIGlueBaseLibX64_LIB)\ +!ELSE + $(EdkIIGlueBaseLibIA32_LIB)\ +!ENDIF + +PchPlatformLibSmmBin : $(PchPlatformLib_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\PchPlatformLib.mak all\ + "MY_INCLUDES=$(PchPlatformLib_INCLUDES)" \ + TYPE=LIBRARY \ + LIBRARIES=\ + LIBRARY_NAME=$(PchPlatformSmmLib_LIB) + +PchPlatformLibDxeBin : $(PchPlatformLib_LIBS) + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ + /f $(BUILD_DIR)\PchPlatformLib.mak all\ + "MY_INCLUDES=$(PchPlatformLib_INCLUDES)" \ + "CFLAGS=$(CFLAGS) $(PchPlatformLib_DEFINES)"\ + TYPE=LIBRARY \ + LIBRARIES=\ + LIBRARY_NAME=$(PchPlatformDxeLib_LIB) + +PchPlatformLibPeiBin : $(PchPlatformLib_LIBS) +!IF "$(x64_BUILD)"=="1" + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32\ +!ELSE + $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\ +!ENDIF + /f $(BUILD_DIR)\PchPlatformLib.mak all\ + "MY_INCLUDES=$(PchPlatformLib_INCLUDES)"\ + "CFLAGS=$(CFLAGS) $(PchPlatformLib_DEFINES)"\ + TYPE=PEI_LIBRARY \ + LIBRARIES=\ + LIBRARY_NAME=$(PchPlatformPeiLib_LIB) +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.sdl b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.sdl new file mode 100644 index 0000000..4704a8c --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.sdl @@ -0,0 +1,93 @@ +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* + +#************************************************************************* +# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchPlatformLib/PchPlatformLib.sdl 1 2/08/12 8:48a Yurenlai $ +# +# $Revision: 1 $ +# +# $Date: 2/08/12 8:48a $ +#************************************************************************* +# Revision History +# ---------------- +# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchPlatformLib/PchPlatformLib.sdl $ +# +# 1 2/08/12 8:48a Yurenlai +# Intel Lynx Point/SB eChipset initially releases. +# +#************************************************************************* +TOKEN + Name = "PchPlatformLib_SUPPORT" + Value = "1" + Help = "Main switch to enable PchPlatformLib support in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes +End + +PATH + Name = "PchPlatformLib_DIR" +End + +MODULE + Help = "Includes PchPlatformLib.mak to Project" + File = "PchPlatformLib.mak" +End + +ELINK + Name = "PchPlatformSmmLib_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\PchPlatformSmmLib.lib" + Parent = "PchPlatformSmmLib_LIB" + InvokeOrder = AfterParent +End + +ELINK + Name = "PchPlatformDxeLib_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\PchPlatformDxeLib.lib" + Parent = "PchPlatformDxeLib_LIB" + InvokeOrder = AfterParent +End + +ELINK + Name = "PchPlatformPeiLib_LIB" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "$(BUILD_DIR)\PchPlatformPeiLib.lib" + Parent = "PchPlatformPeiLib_LIB" + InvokeOrder = AfterParent +End +#************************************************************************* +#************************************************************************* +#** ** +#** (C)Copyright 1985-2011, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#************************************************************************* +#************************************************************************* diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.c b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.c new file mode 100644 index 0000000..2d9c6ac --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.c @@ -0,0 +1,831 @@ +/** @file + PCH Platform Lib implementation. +@copyright + Copyright (c) 2004 - 2013 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains an 'Intel Peripheral Driver' and uniquely + identified as "Intel Reference Module" and is + licensed for Intel CPUs and chipsets under the terms of your + license agreement with Intel or your vendor. This file may + be modified by the user, subject to additional terms of the + license agreement + +**/ +#include "PchPlatformLibrary.h" + +/** + Delay for at least the request number of microseconds. + This function would be called by runtime driver, please do not use any MMIO marco here. + + @param[in] Microseconds Number of microseconds to delay. + + @retval NONE +**/ +VOID +EFIAPI +PchPmTimerStall ( + IN UINTN Microseconds + ) +{ + UINTN Ticks; + UINTN Counts; + UINTN CurrentTick; + UINTN OriginalTick; + UINTN RemainingTick; + UINT16 AcpiBaseAddr; + + if (Microseconds == 0) { + return; + } + /// + /// Please use PciRead here, it will link to MmioRead + /// if the caller is a Runtime driver, please use PchDxeRuntimePciLibPciExpress library, refer + /// PciExpressRead() on Library\DxeRuntimePciLibPciExpress\DxeRuntimePciLibPciExpress.c for the details. + /// For the rest please use EdkIIGlueBasePciLibPciExpress library + /// + AcpiBaseAddr = PciRead16 ( + PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH, + PCI_DEVICE_NUMBER_PCH_LPC, + PCI_FUNCTION_NUMBER_PCH_LPC, + R_PCH_LPC_ACPI_BASE) + ) & B_PCH_LPC_ACPI_BASE_BAR; + + OriginalTick = IoRead32 ((UINTN) (AcpiBaseAddr + R_PCH_ACPI_PM1_TMR)) & B_PCH_ACPI_PM1_TMR_VAL; + CurrentTick = OriginalTick; + + /// + /// The timer frequency is 3.579545 MHz, so 1 ms corresponds 3.58 clocks + /// + Ticks = Microseconds * 358 / 100 + OriginalTick + 1; + + /// + /// The loops needed by timer overflow + /// + Counts = Ticks / V_PCH_ACPI_PM1_TMR_MAX_VAL; + + /// + /// Remaining clocks within one loop + /// + RemainingTick = Ticks % V_PCH_ACPI_PM1_TMR_MAX_VAL; + + /// + /// not intend to use TMROF_STS bit of register PM1_STS, because this adds extra + /// one I/O operation, and maybe generate SMI + /// + while ((Counts != 0) || (RemainingTick > CurrentTick)) { + CurrentTick = IoRead32 ((UINTN) (AcpiBaseAddr + R_PCH_ACPI_PM1_TMR)) & B_PCH_ACPI_PM1_TMR_VAL; + /// + /// Check if timer overflow + /// + if ((CurrentTick < OriginalTick)) { + if (Counts != 0) { + Counts--; + } else { + /// + /// If timer overflow and Counts equ to 0, that means we already stalled more than + /// RemainingTick, break the loop here + /// + break; + } + } + + OriginalTick = CurrentTick; + } +} + +/** + Check whether SPI is in descriptor mode + + @param[in] PchRootComplexBar The PCH Root Complex Bar + + @retval TRUE SPI is in descriptor mode + @retval FALSE SPI is not in descriptor mode +**/ +BOOLEAN +EFIAPI +PchIsSpiDescriptorMode ( + IN UINTN PchRootComplexBar + ) +{ + if ((MmioRead16 (PchRootComplexBar + R_PCH_SPI_HSFS) & B_PCH_SPI_HSFS_FDV) == B_PCH_SPI_HSFS_FDV) { + MmioAndThenOr32 ( + PchRootComplexBar + R_PCH_SPI_FDOC, + (UINT32) (~(B_PCH_SPI_FDOC_FDSS_MASK | B_PCH_SPI_FDOC_FDSI_MASK)), + (UINT32) (V_PCH_SPI_FDOC_FDSS_FSDM | R_PCH_SPI_FDBAR_FLVALSIG) + ); + if ((MmioRead32 (PchRootComplexBar + R_PCH_SPI_FDOD)) == V_PCH_SPI_FDBAR_FLVALSIG) { + return TRUE; + } else { + return FALSE; + } + } else { + return FALSE; + } +} + +/** + Return Pch stepping type + + @param[in] None + + @retval PCH_STEPPING Pch stepping type +**/ +PCH_STEPPING +EFIAPI +PchStepping ( + VOID + ) +{ + UINT8 RevId; + UINT16 LpcDeviceId; + + RevId = MmioRead8 ( + MmPciAddress (0, + DEFAULT_PCI_BUS_NUMBER_PCH, + PCI_DEVICE_NUMBER_PCH_LPC, + PCI_FUNCTION_NUMBER_PCH_LPC, + R_PCH_LPC_RID) + ); + + LpcDeviceId = MmioRead16 ( + MmPciAddress (0, + DEFAULT_PCI_BUS_NUMBER_PCH, + PCI_DEVICE_NUMBER_PCH_LPC, + PCI_FUNCTION_NUMBER_PCH_LPC, + R_PCH_LPC_DEVICE_ID) + ); + + if (IS_PCH_LPTH_LPC_DEVICE_ID (LpcDeviceId)) { + switch (RevId) { + case V_PCH_LPT_LPC_RID_2: + return LptHB0; + break; + + case V_PCH_LPT_LPC_RID_3: + return LptHC0; + break; + + case V_PCH_LPT_LPC_RID_4: + return LptHC1; + break; + + case V_PCH_LPT_LPC_RID_5: + return LptHC2; + break; + + default: + return PchSteppingMax; + break; + } + } + + if (IS_PCH_LPTLP_LPC_DEVICE_ID (LpcDeviceId)) { + switch (RevId) { + case V_PCH_LPT_LPC_RID_2: + return LptLpB0; + break; + + case V_PCH_LPT_LPC_RID_3: + return LptLpB1; + break; + + case V_PCH_LPT_LPC_RID_4: + return LptLpB2; + break; + + default: + return PchSteppingMax; + break; + } + } + + return PchSteppingMax; +} + +/** + Determine if PCH is supported + + @param[in] None + + @retval TRUE PCH is supported + @retval FALSE PCH is not supported +**/ +BOOLEAN +IsPchSupported ( + VOID + ) +{ + UINT16 LpcDeviceId; + + LpcDeviceId = MmioRead16 ( + MmPciAddress (0, + DEFAULT_PCI_BUS_NUMBER_PCH, + PCI_DEVICE_NUMBER_PCH_LPC, + PCI_FUNCTION_NUMBER_PCH_LPC, + R_PCH_LPC_DEVICE_ID) + ); + + /// + /// Verify that this is a supported chipset + /// + if (MmioRead16 ( + MmPciAddress (0, + DEFAULT_PCI_BUS_NUMBER_PCH, + PCI_DEVICE_NUMBER_PCH_LPC, + PCI_FUNCTION_NUMBER_PCH_LPC, + R_PCH_LPC_VENDOR_ID) + ) != V_PCH_LPC_VENDOR_ID || + !IS_PCH_LPT_LPC_DEVICE_ID (LpcDeviceId)) { + DEBUG ((EFI_D_ERROR, "PCH code doesn't support the LpcDeviceId: 0x%04x!\n", LpcDeviceId)); + return FALSE; + } + + return TRUE; +} + +/** + This function can be called to enable/disable Alternate Access Mode + + @param[in] PchRootComplexBar The PCH Root Complex Bar + @param[in] AmeCtrl If TRUE, enable Alternate Access Mode. + If FALSE, disable Alternate Access Mode. + + @retval NONE +**/ +VOID +EFIAPI +PchAlternateAccessMode ( + IN UINTN PchRootComplexBar, + IN BOOLEAN AmeCtrl + ) +{ + UINT32 Data32Or; + UINT32 Data32And; + + Data32Or = 0; + Data32And = 0xFFFFFFFF; + + if (AmeCtrl == TRUE) { + /// + /// Enable Alternate Access Mode + /// Note: The RTC Index field (including the NMI mask at bit7) is write-only + /// for normal operation and can only be read in Alt Access Mode. + /// + Data32Or = (UINT32) (B_PCH_RCRB_GCS_AME); + } + + if (AmeCtrl == FALSE) { + /// + /// Disable Alternate Access Mode + /// + Data32And = (UINT32) ~(B_PCH_RCRB_GCS_AME); + } + + /// + /// Program Alternate Access Mode Enable bit + /// + MmioAndThenOr32 ( + PchRootComplexBar + R_PCH_RCRB_GCS, + Data32And, + Data32Or + ); + + /// + /// Reads back for posted write to take effect + /// + MmioRead32(PchRootComplexBar + R_PCH_RCRB_GCS); +} + +/** + Check whether Gbe Region is valid in SPI Flash + + @param[in] PchRootComplexBar The PCH Root Complex Bar + + @retval TRUE Gbe Region is valid + @retval FALSE Gbe Region is invalid +**/ +BOOLEAN +EFIAPI +PchIsGbeRegionValid ( + IN UINTN PchRootComplexBar + ) +{ + /// + /// If the GbE region is not used, + /// Region Limit of Flash Region 3 (GbE) Register (SPIBAR + 60h[30:16]) must be programmed to 0000h + /// Region Base of Flash Region 3 (GbE) Register (SPIBAR + 60h[14:0] ) must be programmed to 7FFFh + /// + if (PchIsSpiDescriptorMode (PchRootComplexBar) == TRUE) { + if (MmioRead32 (PchRootComplexBar + R_PCH_SPI_FREG3_GBE) == 0x00007FFF) { + return FALSE; + } else { + return TRUE; + } + } else { + return FALSE; + } +} + +/** + Check if integrated Gbe controller present + + @param[in] None + + @retval TRUE Integrated Gbe present + @retval FALSE Integrated Gbe not present +**/ +BOOLEAN +EFIAPI +PchIsIntegratedGbePresent ( + IN VOID + ) +{ + UINT32 Softstrap4; + UINT32 Softstrap15; + BOOLEAN IntegratedGbe; + + /// + /// Check if Gbe region is present by reading PCH straps 15 (bit 6) and 4 (bits 1:0) + /// + MmioAnd32 ( + PCH_RCRB_BASE + R_PCH_SPI_FDOC, + (UINT32) (~(B_PCH_SPI_FDOC_FDSS_MASK | B_PCH_SPI_FDOC_FDSI_MASK)) + ); + + MmioOr32 ( + PCH_RCRB_BASE + R_PCH_SPI_FDOC, + (UINT32) (V_PCH_SPI_FDOC_FDSS_PCHS | R_PCH_SPI_STRP4) + ); + + Softstrap4 = MmioRead32 (PCH_RCRB_BASE + R_PCH_SPI_FDOD); + + MmioAnd32 ( + PCH_RCRB_BASE + R_PCH_SPI_FDOC, + (UINT32) (~(B_PCH_SPI_FDOC_FDSS_MASK | B_PCH_SPI_FDOC_FDSI_MASK)) + ); + + MmioOr32 ( + PCH_RCRB_BASE + R_PCH_SPI_FDOC, + (UINT32) (V_PCH_SPI_FDOC_FDSS_PCHS | R_PCH_SPI_STRP15) + ); + + Softstrap15 = MmioRead32 (PCH_RCRB_BASE + R_PCH_SPI_FDOD); + + /// + /// Both values have to be non-zero if integrated phy present + /// + IntegratedGbe = !!(Softstrap4 & B_PCH_SPI_STRP4_PHYCON) && !!(Softstrap15 & B_PCH_SPI_STRP15_IWL_EN); + + return IntegratedGbe; +} + +/** + Return Pch Series + + @param[in] None + + @retval PCH_SERIES Pch Series +**/ +PCH_SERIES +EFIAPI +GetPchSeries ( + VOID + ) +{ + UINT16 LpcDeviceId; + UINT32 PchSeries; + + /// + /// Please use PciRead here, it will link to MmioRead + /// if the caller is a Runtime driver, please use PchDxeRuntimePciLibPciExpress library, refer + /// PciExpressRead() on Library\DxeRuntimePciLibPciExpress\DxeRuntimePciLibPciExpress.c for the details. + /// For the rest please use EdkIIGlueBasePciLibPciExpress library + /// + LpcDeviceId = PciRead16 ( + PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH, + PCI_DEVICE_NUMBER_PCH_LPC, + PCI_FUNCTION_NUMBER_PCH_LPC, + R_PCH_LPC_DEVICE_ID) + ); + + if (IS_PCH_LPTH_LPC_DEVICE_ID (LpcDeviceId)) { + PchSeries = PchH; + } else if (IS_PCH_LPTLP_LPC_DEVICE_ID (LpcDeviceId)) { + PchSeries = PchLp; + } else { + PchSeries = PchUnknownSeries; + DEBUG ((EFI_D_ERROR, "Unsupported PCH SKU, LpcDeviceId: 0x%04x!\n", LpcDeviceId)); + ASSERT (FALSE); + } + + return PchSeries; +} + +/** + Get Pch Maximum Pcie Root Port Number + + @param[in] None + + @retval Pch Maximum Pcie Root Port Number +**/ +UINT8 +EFIAPI +GetPchMaxPciePortNum ( + VOID + ) +{ + PCH_SERIES PchSeries; + + PchSeries = GetPchSeries(); + switch (PchSeries) { + case PchLp: + return LPTLP_PCIE_MAX_ROOT_PORTS; + + case PchH: + return LPTH_PCIE_MAX_ROOT_PORTS; + + default: + return 0; + } +} + +/** + Get Pch Maximum Sata Port Number + + @param[in] None + + @retval Pch Maximum Sata Port Number +**/ +UINT8 +EFIAPI +GetPchMaxSataPortNum ( + VOID + ) +{ + PCH_SERIES PchSeries; + + PchSeries = GetPchSeries(); + switch (PchSeries) { + case PchLp: + return LPTLP_AHCI_MAX_PORTS; + + case PchH: + return LPTH_AHCI_MAX_PORTS; + + default: + return 0; + } +} + +/** + Get Pch Maximum Sata Controller Number + + @param[in] None + + @retval Pch Maximum Sata Controller Number +**/ +UINT8 +EFIAPI +GetPchMaxSataControllerNum ( + VOID + ) +{ + PCH_SERIES PchSeries; + + PchSeries = GetPchSeries(); + switch (PchSeries) { + case PchLp: + return LPTLP_SATA_MAX_CONTROLLERS; + + case PchH: + return LPTH_SATA_MAX_CONTROLLERS; + + default: + return 0; + } +} + +/** + Get Pch Maximum Usb Port Number of EHCI Controller + + @param[in] None + + @retval Pch Maximum Usb Port Number of EHCI Controller +**/ +UINT8 +EFIAPI +GetPchEhciMaxUsbPortNum ( + VOID + ) +{ + PCH_SERIES PchSeries; + + PchSeries = GetPchSeries(); + switch (PchSeries) { + case PchLp: + return LPTLP_EHCI_MAX_PORTS; + + case PchH: + return LPTH_EHCI_MAX_PORTS; + + default: + return 0; + } +} + +/** + Get Pch Maximum EHCI Controller Number + + @param[in] None + + @retval Pch Maximum EHCI Controller Number +**/ +UINT8 +EFIAPI +GetPchEhciMaxControllerNum ( + VOID + ) +{ + PCH_SERIES PchSeries; + + PchSeries = GetPchSeries(); + switch (PchSeries) { + case PchLp: + return LPTLP_EHCI_MAX_CONTROLLERS; + + case PchH: + return LPTH_EHCI_MAX_CONTROLLERS; + + default: + return 0; + } +} + +/** + Get Pch Usb Maximum Physical Port Number + + @param[in] None + + @retval Pch Usb Maximum Physical Port Number +**/ +UINT8 +EFIAPI +GetPchUsbMaxPhysicalPortNum ( + VOID + ) +{ + PCH_SERIES PchSeries; + + PchSeries = GetPchSeries(); + switch (PchSeries) { + case PchLp: + return LPTLP_USB_MAX_PHYSICAL_PORTS; + + case PchH: + return LPTH_USB_MAX_PHYSICAL_PORTS; + + default: + return 0; + } +} + +/** + Get Pch Maximum Usb2 Port Number of XHCI Controller + + @param[in] None + + @retval Pch Maximum Usb2 Port Number of XHCI Controller +**/ +UINT8 +EFIAPI +GetPchXhciMaxUsb2PortNum ( + VOID + ) +{ + PCH_SERIES PchSeries; + + PchSeries = GetPchSeries(); + switch (PchSeries) { + case PchLp: + return LPTLP_XHCI_MAX_USB2_PORTS; + + case PchH: + return LPTH_XHCI_MAX_USB2_PORTS; + + default: + return 0; + } +} + +/** + Get Pch Maximum Usb3 Port Number of XHCI Controller + + @param[in] None + + @retval Pch Maximum Usb3 Port Number of XHCI Controller +**/ +UINT8 +EFIAPI +GetPchXhciMaxUsb3PortNum ( + VOID + ) +{ + PCH_SERIES PchSeries; + + PchSeries = GetPchSeries(); + switch (PchSeries) { + case PchLp: + return LPTLP_XHCI_MAX_USB3_PORTS; + + case PchH: + return LPTH_XHCI_MAX_USB3_PORTS; + + default: + return 0; + } +} + +/** + Query PCH to determine the Pm Status + + @param[in] PmStatus - The Pch Pm Status to be probed + + @retval Return TRUE if Status querried is Valid or FALSE if otherwise +**/ +BOOLEAN +GetPchPmStatus ( + PCH_PM_STATUS PmStatus + ) +{ + UINT16 PmCon2; + UINT16 PmCon3; + + PmCon2 = MmioRead16 ( + MmPciAddress (0, + DEFAULT_PCI_BUS_NUMBER_PCH, + PCI_DEVICE_NUMBER_PCH_LPC, + PCI_FUNCTION_NUMBER_PCH_LPC, + R_PCH_LPC_GEN_PMCON_2 + ) + ); + PmCon3 = MmioRead16 ( + MmPciAddress (0, + DEFAULT_PCI_BUS_NUMBER_PCH, + PCI_DEVICE_NUMBER_PCH_LPC, + PCI_FUNCTION_NUMBER_PCH_LPC, + R_PCH_LPC_GEN_PMCON_3 + ) + ); + + switch(PmStatus){ + case WarmBoot: + if (PmCon2 & B_PCH_LPC_GEN_PMCON_MEM_SR) { + return TRUE; + } + break; + + case PwrFlr: + if (PmCon3 & B_PCH_LPC_GEN_PMCON_PWR_FLR) { + return TRUE; + } + break; + + case PwrFlrSys: + if (PmCon2 & B_PCH_LPC_GEN_PMCON_SYSPWR_FLR) { + return TRUE; + } + break; + + case PwrFlrPch: + if (PmCon2 & B_PCH_LPC_GEN_PMCON_PWROK_FLR) { + return TRUE; + } + break; + + case ColdBoot: + /// + /// Check following conditions for cold boot. + /// (1)GEN_PMCON_2 (0:31:0 offset 0A2) bit[5] = 0 + /// (2)GEN_PMCON_2 (0:31:0 offset 0A2) bit[1] = 1 + /// (3)GEN_PMCON_3 (0:31:0 offset 0A4) bit[1] = 1 + /// + if ((PmCon3 & B_PCH_LPC_GEN_PMCON_PWR_FLR) && + (PmCon2 & B_PCH_LPC_GEN_PMCON_SYSPWR_FLR) && + (!(PmCon2 & B_PCH_LPC_GEN_PMCON_MEM_SR))) { + return TRUE; + } + break; + + default: + break; + } + + return FALSE; +} + +/** + Get Pch Pcie Root Port Function Number by Root Port Number + + @param[in] UINT8 Root Port Number (start from 0) + + @retval Pch Pcie Root Port Function Number +**/ +UINT8 +EFIAPI +GetPchPcieRpfn ( + IN UINTN PchRootComplexBar, + IN UINT8 RpNumber + ) +{ + return ((MmioRead32(PchRootComplexBar + R_PCH_RCRB_RPFN) >> (RpNumber * S_PCH_RCRB_PRFN_RP_FIELD)) & B_PCH_RCRB_RPFN_RP1FN); +} + +/** + Get Pch Pcie Root Port Number by Root Port Function Number + + @param[in] UINT8 Root Port Function Number + + @retval Pch Pcie Root Port Number + @retval 0xFF No Root Port Number found +**/ +UINT8 +EFIAPI +GetPchPcieRpNumber ( + IN UINTN PchRootComplexBar, + IN UINT8 Rpfn + ) +{ + UINT8 PortIndex; + for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum(); PortIndex++) { + if (((MmioRead32(PchRootComplexBar + R_PCH_RCRB_RPFN) >> (PortIndex * S_PCH_RCRB_PRFN_RP_FIELD)) & B_PCH_RCRB_RPFN_RP1FN) == Rpfn) { + return PortIndex; + } + } + + //Assert if function number not found for a root port + ASSERT (FALSE); + return 0xff; +} + + +/** + Returns GbE over PCIe port number. + + @return Root port number (0-based) + @retval 0xff +**/ +UINTN +PchGetGbePortNumber ( + VOID + ) +{ + UINT32 Softstrap9; + UINT32 GbePortSel; + + /// + /// Check if Intel PHY Over PCI Express Enable by reading PCH straps 9 (bit 11) + /// + MmioAnd32 ( + PCH_RCRB_BASE + R_PCH_SPI_FDOC, + (UINT32) (~(B_PCH_SPI_FDOC_FDSS_MASK | B_PCH_SPI_FDOC_FDSI_MASK)) + ); + + MmioOr32 ( + PCH_RCRB_BASE + R_PCH_SPI_FDOC, + (UINT32) (V_PCH_SPI_FDOC_FDSS_PCHS | R_PCH_SPI_STRP9) + ); + + Softstrap9 = MmioRead32 (PCH_RCRB_BASE + R_PCH_SPI_FDOD); + + /// + /// If Intel PHY Over PCI Express Enable bit is set, return GbE port number + /// + if (Softstrap9 & B_PCH_SPI_STRP9_GBE_PCIE_EN) { + GbePortSel = (Softstrap9 & B_PCH_SPI_STRP9_GBE_PCIE_PSC) >> N_PCH_SPI_STRP9_GBE_PCIE_PSC; + DEBUG ((EFI_D_INFO, "GbePortSel=%d\n", GbePortSel)); + if (GetPchSeries () == PchLp) { + switch (GbePortSel) { + case 0: return 2; // Root Port 3 + case 1: return 3; // Root Port 4 + case 2: // Root Port 5, lane 0 + case 3: // Root Port 5, lane 1 + case 4: // Root Port 5, lane 2 + case 5: // Root Port 5, lane 3 + return 4; + default: + ASSERT (FALSE); + } + } else { + return GbePortSel; + } + } + + return 0xff; +} diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.h b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.h new file mode 100644 index 0000000..0eec474 --- /dev/null +++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.h @@ -0,0 +1,29 @@ +/** @file + Header file for PCH Platform Lib implementation. + +@copyright + Copyright (c) 2008 - 2012 Intel Corporation. All rights reserved + This software and associated documentation (if any) is furnished + under a license and may only be used or copied in accordance + with the terms of the license. Except as permitted by such + license, no part of this software or documentation may be + reproduced, stored in a retrieval system, or transmitted in any + form or by any means without the express written consent of + Intel Corporation. + + This file contains a 'Sample Driver' and is licensed as such + under the terms of your license agreement with Intel or your + vendor. This file may be modified by the user, subject to + the additional terms of the license agreement +**/ +#ifndef _PCH_PLATFORM_LIBRARY_IMPLEMENTATION_H_ +#define _PCH_PLATFORM_LIBRARY_IMPLEMENTATION_H_ + +#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#include "EdkIIGlueBase.h" +#include "Library/EdkIIGlueMemoryAllocationLib.h" +#include "PchAccess.h" +#include "PchPlatformLib.h" +#endif + +#endif |