summaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/agesa/f15tn/Proc/GNB/Modules/GnbCommonLib/GnbLibPci.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode/amd/agesa/f15tn/Proc/GNB/Modules/GnbCommonLib/GnbLibPci.c')
-rw-r--r--src/vendorcode/amd/agesa/f15tn/Proc/GNB/Modules/GnbCommonLib/GnbLibPci.c430
1 files changed, 430 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f15tn/Proc/GNB/Modules/GnbCommonLib/GnbLibPci.c b/src/vendorcode/amd/agesa/f15tn/Proc/GNB/Modules/GnbCommonLib/GnbLibPci.c
new file mode 100644
index 0000000000..1353342a54
--- /dev/null
+++ b/src/vendorcode/amd/agesa/f15tn/Proc/GNB/Modules/GnbCommonLib/GnbLibPci.c
@@ -0,0 +1,430 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * Various PCI service routines.
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: GNB
+ * @e \$Revision: 63425 $ @e \$Date: 2011-12-22 11:24:10 -0600 (Thu, 22 Dec 2011) $
+ *
+ */
+/*
+*****************************************************************************
+*
+* Copyright 2008 - 2012 ADVANCED MICRO DEVICES, INC. All Rights Reserved.
+*
+* AMD is granting you permission to use this software (the Materials)
+* pursuant to the terms and conditions of your Software License Agreement
+* with AMD. This header does *NOT* give you permission to use the Materials
+* or any rights under AMD's intellectual property. Your use of any portion
+* of these Materials shall constitute your acceptance of those terms and
+* conditions. If you do not agree to the terms and conditions of the Software
+* License Agreement, please do not use any portion of these Materials.
+*
+* CONFIDENTIALITY: The Materials and all other information, identified as
+* confidential and provided to you by AMD shall be kept confidential in
+* accordance with the terms and conditions of the Software License Agreement.
+*
+* LIMITATION OF LIABILITY: THE MATERIALS AND ANY OTHER RELATED INFORMATION
+* PROVIDED TO YOU BY AMD ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED
+* WARRANTY OF ANY KIND, INCLUDING BUT NOT LIMITED TO WARRANTIES OF
+* MERCHANTABILITY, NONINFRINGEMENT, TITLE, FITNESS FOR ANY PARTICULAR PURPOSE,
+* OR WARRANTIES ARISING FROM CONDUCT, COURSE OF DEALING, OR USAGE OF TRADE.
+* IN NO EVENT SHALL AMD OR ITS LICENSORS BE LIABLE FOR ANY DAMAGES WHATSOEVER
+* (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF PROFITS, BUSINESS
+* INTERRUPTION, OR LOSS OF INFORMATION) ARISING OUT OF AMD'S NEGLIGENCE,
+* GROSS NEGLIGENCE, THE USE OF OR INABILITY TO USE THE MATERIALS OR ANY OTHER
+* RELATED INFORMATION PROVIDED TO YOU BY AMD, EVEN IF AMD HAS BEEN ADVISED OF
+* THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME JURISDICTIONS PROHIBIT THE
+* EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES,
+* THE ABOVE LIMITATION MAY NOT APPLY TO YOU.
+*
+* AMD does not assume any responsibility for any errors which may appear in
+* the Materials or any other related information provided to you by AMD, or
+* result from use of the Materials or any related information.
+*
+* You agree that you will not reverse engineer or decompile the Materials.
+*
+* NO SUPPORT OBLIGATION: AMD is not obligated to furnish, support, or make any
+* further information, software, technical information, know-how, or show-how
+* available to you. Additionally, AMD retains the right to modify the
+* Materials at any time, without notice, and is not obligated to provide such
+* modified Materials to you.
+*
+* U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with
+* "RESTRICTED RIGHTS." Use, duplication, or disclosure by the Government is
+* subject to the restrictions as set forth in FAR 52.227-14 and
+* DFAR252.227-7013, et seq., or its successor. Use of the Materials by the
+* Government constitutes acknowledgement of AMD's proprietary rights in them.
+*
+* EXPORT ASSURANCE: You agree and certify that neither the Materials, nor any
+* direct product thereof will be exported directly or indirectly, into any
+* country prohibited by the United States Export Administration Act and the
+* regulations thereunder, without the required authorization from the U.S.
+* government nor will be used for any purpose prohibited by the same.
+* ***************************************************************************
+*
+*/
+
+
+#include "AGESA.h"
+#include "amdlib.h"
+#include "Gnb.h"
+#include "GnbLibPciAcc.h"
+#include "GnbLibPci.h"
+#include "GnbLib.h"
+#include "Filecode.h"
+#define FILECODE PROC_GNB_MODULES_GNBCOMMONLIB_GNBLIBPCI_FILECODE
+
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Check if device present
+ *
+ *
+ *
+ * @param[in] Address PCI address (as described in PCI_ADDR)
+ * @param[in] StdHeader Standard configuration header
+ * @retval TRUE Device is present
+ * @retval FALSE Device is not present
+ */
+
+BOOLEAN
+GnbLibPciIsDevicePresent (
+ IN UINT32 Address,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT32 DeviceId;
+ GnbLibPciRead (Address, AccessWidth32, &DeviceId, StdHeader);
+ if (DeviceId == 0xffffffff) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Check if device is bridge
+ *
+ *
+ *
+ * @param[in] Address PCI address (as described in PCI_ADDR)
+ * @param[in] StdHeader Standard configuration header
+ * @retval TRUE Device is a bridge
+ * @retval FALSE Device is not a bridge
+ */
+
+BOOLEAN
+GnbLibPciIsBridgeDevice (
+ IN UINT32 Address,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT8 Header;
+ GnbLibPciRead (Address | 0xe, AccessWidth8, &Header, StdHeader);
+ if ((Header & 0x7f) == 1) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Check if device is multifunction
+ *
+ *
+ *
+ * @param[in] Address PCI address (as described in PCI_ADDR)
+ * @param[in] StdHeader Standard configuration header
+ * @retval TRUE Device is a multifunction device.
+ * @retval FALSE Device is a single function device.
+ *
+ */
+BOOLEAN
+GnbLibPciIsMultiFunctionDevice (
+ IN UINT32 Address,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT8 Header;
+ GnbLibPciRead (Address | 0xe, AccessWidth8, &Header, StdHeader);
+ if ((Header & 0x80) != 0) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Check if device is PCIe device
+ *
+ *
+ *
+ * @param[in] Address PCI address (as described in PCI_ADDR)
+ * @param[in] StdHeader Standard configuration header
+ * @retval TRUE Device is a PCIe device
+ * @retval FALSE Device is not a PCIe device
+ *
+ */
+
+BOOLEAN
+GnbLibPciIsPcieDevice (
+ IN UINT32 Address,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ if (GnbLibFindPciCapability (Address, PCIE_CAP_ID, StdHeader) != 0 ) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Find PCI capability pointer
+ *
+ *
+ *
+ * @param[in] Address PCI address (as described in PCI_ADDR)
+ * @param[in] CapabilityId PCI capability ID
+ * @param[in] StdHeader Standard configuration header
+ * @retval Register address of capability pointer
+ *
+ */
+
+UINT8
+GnbLibFindPciCapability (
+ IN UINT32 Address,
+ IN UINT8 CapabilityId,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT8 CapabilityPtr;
+ UINT8 CurrentCapabilityId;
+ CapabilityPtr = 0x34;
+ if (!GnbLibPciIsDevicePresent (Address, StdHeader)) {
+ return 0;
+ }
+ while (CapabilityPtr != 0) {
+ GnbLibPciRead (Address | CapabilityPtr, AccessWidth8 , &CapabilityPtr, StdHeader);
+ if (CapabilityPtr != 0) {
+ GnbLibPciRead (Address | CapabilityPtr , AccessWidth8 , &CurrentCapabilityId, StdHeader);
+ if (CurrentCapabilityId == CapabilityId) {
+ break;
+ }
+ CapabilityPtr++;
+ }
+ }
+ return CapabilityPtr;
+}
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Find PCIe extended capability pointer
+ *
+ *
+ *
+ * @param[in] Address PCI address (as described in PCI_ADDR)
+ * @param[in] ExtendedCapabilityId Extended PCIe capability ID
+ * @param[in] StdHeader Standard configuration header
+ * @retval Register address of extended capability pointer
+ *
+ */
+
+#if 0 /* Not used */
+UINT16
+GnbLibFindPcieExtendedCapability (
+ IN UINT32 Address,
+ IN UINT16 ExtendedCapabilityId,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT16 CapabilityPtr;
+ UINT32 ExtendedCapabilityIdBlock;
+ if (GnbLibPciIsPcieDevice (Address, StdHeader)) {
+ GnbLibPciRead (Address | 0x100 , AccessWidth32 , &ExtendedCapabilityIdBlock, StdHeader);
+ if ((ExtendedCapabilityIdBlock != 0) && ((UINT16)ExtendedCapabilityIdBlock != 0xffff)) {
+ do {
+ CapabilityPtr = (UINT16) ((ExtendedCapabilityIdBlock >> 20) & 0xfff);
+ if ((UINT16)ExtendedCapabilityIdBlock == ExtendedCapabilityId) {
+ return CapabilityPtr;
+ }
+ GnbLibPciRead (Address | CapabilityPtr , AccessWidth32 , &ExtendedCapabilityIdBlock, StdHeader);
+ } while (((ExtendedCapabilityIdBlock >> 20) & 0xfff) != 0);
+ }
+ }
+ return 0;
+}
+#endif
+/*----------------------------------------------------------------------------------------*/
+/*
+ * Scan range of device on PCI bus.
+ *
+ *
+ *
+ * @param[in] Start Start address to start scan from
+ * @param[in] End End address of scan
+ * @param[in] ScanData Supporting data
+ *
+ */
+/*----------------------------------------------------------------------------------------*/
+VOID
+GnbLibPciScan (
+ IN PCI_ADDR Start,
+ IN PCI_ADDR End,
+ IN GNB_PCI_SCAN_DATA *ScanData
+ )
+{
+ UINTN Bus;
+ UINTN Device;
+ UINTN LastDevice;
+ UINTN Function;
+ UINTN LastFunction;
+ PCI_ADDR PciDevice;
+ SCAN_STATUS Status;
+
+ for (Bus = Start.Address.Bus; Bus <= End.Address.Bus; Bus++) {
+ Device = (Bus == Start.Address.Bus) ? Start.Address.Device : 0x00;
+ LastDevice = (Bus == End.Address.Bus) ? End.Address.Device : 0x1F;
+ for ( ; Device <= LastDevice; Device++) {
+ if ((Bus == Start.Address.Bus) && (Device == Start.Address.Device)) {
+ Function = Start.Address.Function;
+ } else {
+ Function = 0x0;
+ }
+ PciDevice.AddressValue = MAKE_SBDFO (0, Bus, Device, Function, 0);
+ if (!GnbLibPciIsDevicePresent (PciDevice.AddressValue, ScanData->StdHeader)) {
+ continue;
+ }
+ if (GnbLibPciIsMultiFunctionDevice (PciDevice.AddressValue, ScanData->StdHeader)) {
+ if ((Bus == End.Address.Bus) && (Device == End.Address.Device)) {
+ LastFunction = Start.Address.Function;
+ } else {
+ LastFunction = 0x7;
+ }
+ } else {
+ LastFunction = 0x0;
+ }
+ for ( ; Function <= LastFunction; Function++) {
+ PciDevice.AddressValue = MAKE_SBDFO (0, Bus, Device, Function, 0);
+ if (GnbLibPciIsDevicePresent (PciDevice.AddressValue, ScanData->StdHeader)) {
+ Status = ScanData->GnbScanCallback (PciDevice, ScanData);
+ if ((Status & SCAN_SKIP_FUNCTIONS) != 0) {
+ Function = LastFunction + 1;
+ }
+ if ((Status & SCAN_SKIP_DEVICES) != 0) {
+ Device = LastDevice + 1;
+ }
+ if ((Status & SCAN_SKIP_BUSES) != 0) {
+ Bus = End.Address.Bus + 1;
+ }
+ }
+ }
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Scan all subordinate buses
+ *
+ *
+ * @param[in] Bridge PCI bridge address
+ * @param[in,out] ScanData Scan configuration data
+ *
+ */
+VOID
+GnbLibPciScanSecondaryBus (
+ IN PCI_ADDR Bridge,
+ IN OUT GNB_PCI_SCAN_DATA *ScanData
+ )
+{
+ PCI_ADDR StartRange;
+ PCI_ADDR EndRange;
+ UINT8 SecondaryBus;
+ GnbLibPciRead (Bridge.AddressValue | 0x19, AccessWidth8, &SecondaryBus, ScanData->StdHeader);
+ if (SecondaryBus != 0) {
+ StartRange.AddressValue = MAKE_SBDFO (0, SecondaryBus, 0, 0, 0);
+ EndRange.AddressValue = MAKE_SBDFO (0, SecondaryBus, 0x1f, 0x7, 0);
+ GnbLibPciScan (StartRange, EndRange, ScanData);
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Get PCIe device type
+ *
+ *
+ *
+ * @param[in] Device PCI address of device.
+ * @param[in] StdHeader Northbridge configuration structure pointer.
+ *
+ * @retval PCIE_DEVICE_TYPE
+ */
+ /*----------------------------------------------------------------------------------------*/
+
+PCIE_DEVICE_TYPE
+GnbLibGetPcieDeviceType (
+ IN PCI_ADDR Device,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT8 PcieCapPtr;
+ UINT8 Value;
+
+ PcieCapPtr = GnbLibFindPciCapability (Device.AddressValue, PCIE_CAP_ID, StdHeader);
+ if (PcieCapPtr != 0) {
+ GnbLibPciRead (Device.AddressValue | (PcieCapPtr + 0x2) , AccessWidth8, &Value, StdHeader);
+ return Value >> 4;
+ }
+ return PcieNotPcieDevice;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Save config space area
+ *
+ *
+ *
+ * @param[in] Address PCI address of device.
+ * @param[in] StartRegisterAddress Start register address.
+ * @param[in] EndRegisterAddress End register address.
+ * @param[in] Width Acess width.
+ * @param[in] StdHeader Standard header.
+ *
+ */
+ /*----------------------------------------------------------------------------------------*/
+
+VOID
+GnbLibS3SaveConfigSpace (
+ IN UINT32 Address,
+ IN UINT16 StartRegisterAddress,
+ IN UINT16 EndRegisterAddress,
+ IN ACCESS_WIDTH Width,
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ UINT16 Index;
+ UINT16 Delta;
+ UINT16 Length;
+ Length = (StartRegisterAddress < EndRegisterAddress) ? (EndRegisterAddress - StartRegisterAddress) : (StartRegisterAddress - EndRegisterAddress);
+ Delta = LibAmdAccessWidth (Width);
+ for (Index = 0; Index <= Length; Index = Index + Delta) {
+ GnbLibPciRMW (
+ Address | ((StartRegisterAddress < EndRegisterAddress) ? (StartRegisterAddress + Index) : (StartRegisterAddress - Index)),
+ Width,
+ 0xffffffff,
+ 0x0,
+ StdHeader
+ );
+ }
+}