示例#1
0
/**
 * Change the hardware state for all Links according to the now optimized data in the
 * port list data structure for link frequency.
 *
 * @HtNbMethod{::F_SET_LINK_FREQUENCY}
 *
 * Handle extended frequencies.  For HT3 frequencies, ensure Retry and Scrambling are
 * set. For HT1, clear them.
 *
 * @param[in]     Node        the node on which to set frequency for a link
 * @param[in]     Link        the link to set frequency
 * @param[in]     Frequency   the frequency to set
 * @param[in]     Nb          this northbridge
 */
VOID
SetLinkFrequency (
  IN       UINT8          Node,
  IN       UINT8          Link,
  IN       UINT8          Frequency,
  IN       NORTHBRIDGE    *Nb
  )
{
  UINT32 Temp;
  PCI_ADDR Reg;

  ASSERT ((Frequency >= HT_FREQUENCY_600M && Frequency <= HT_FREQUENCY_3200M)
          || (Frequency == HT_FREQUENCY_200M) || (Frequency == HT_FREQUENCY_400M));

  // Handle extended frequencies, 2800 MHz and above.  31 > Frequency > 16 in this case.
  if (Frequency > HT_FREQUENCY_2600M) {
    Temp = 1;
  } else {
    // Clear it if not extended.
    Temp = 0;
  }
  Reg = Nb->MakeLinkBase (Node, Link, Nb);
  Reg.Address.Register += HTHOST_FREQ_EXTENSION;
  LibAmdPciWriteBits (Reg, 0, 0, &Temp, Nb->ConfigHandle);
  Reg = Nb->MakeLinkBase (Node, Link, Nb);
  Reg.Address.Register += HTHOST_FREQ_REV_REG;
  Temp = (Frequency & 0x0F);
  LibAmdPciWriteBits (Reg, 11, 8, &Temp, Nb->ConfigHandle);
  //  Gen1 = 200Mhz -> 1000MHz, Gen3 = 1200MHz -> 2600MHz
  if (Frequency > HT_FREQUENCY_1000M) {
    // Enable  for Gen3 frequencies
    Temp = 1;
  } else {
    // Disable  for Gen1 frequencies
    Temp = 0;
  }
  // HT3 retry mode enable / disable
  Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
                                 MakePciBusFromNode (Node),
                                 MakePciDeviceFromNode (Node),
                                 CPU_HTNB_FUNC_00,
                                 REG_HT_LINK_RETRY0_0X130 + (4 * Link));
  LibAmdPciWriteBits (Reg, 0, 0, &Temp, Nb->ConfigHandle);
  // and Scrambling enable / disable
  Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
                                 MakePciBusFromNode (Node),
                                 MakePciDeviceFromNode (Node),
                                 CPU_HTNB_FUNC_00,
                                 REG_HT_LINK_EXT_CONTROL0_0X170 + (4 * Link));
  LibAmdPciWriteBits (Reg, 3, 3, &Temp, Nb->ConfigHandle);
}
示例#2
0
/**
 * Enable config access to a non-coherent chain for the given bus range.
 *
 * @HtNbMethod{::F_SET_CONFIG_ADDR_MAP}
 *
 * @param[in]     ConfigMapIndex the map entry to set
 * @param[in]     SecBus         The secondary bus number to use
 * @param[in]     SubBus         The subordinate bus number to use
 * @param[in]     TargetNode     The Node  that shall be the recipient of the traffic
 * @param[in]     TargetLink     The Link that shall be the recipient of the traffic
 * @param[in]     State          our global state
 * @param[in]     Nb             this northbridge
 */
VOID
Fam10SetConfigAddrMap (
  IN       UINT8       ConfigMapIndex,
  IN       UINT8       SecBus,
  IN       UINT8       SubBus,
  IN       UINT8       TargetNode,
  IN       UINT8       TargetLink,
  IN       STATE_DATA  *State,
  IN       NORTHBRIDGE *Nb
  )
{
  UINT8 CurNode;
  PCI_ADDR Reg;
  UINT32 Temp;

  Reg = Nb->MakeLinkBase (TargetNode, TargetLink, Nb);

  ASSERT (SecBus <= SubBus);
  ASSERT (TargetNode <= State->NodesDiscovered);
  ASSERT (TargetLink < Nb->MaxLinks);
  Temp = SecBus;
  Reg.Address.Register += HTHOST_ISOC_REG;
  LibAmdPciWriteBits (Reg, 15, 8, &Temp, Nb->ConfigHandle);

  Temp = ((UINT32)SubBus << 24) + ((UINT32)SecBus << 16) + ((UINT32)TargetLink << 8) +
    ((UINT32)TargetNode << 4) + (UINT32)3;
  for (CurNode = 0; CurNode < (State->NodesDiscovered + 1); CurNode++) {
    Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (CurNode),
                                   MakePciBusFromNode (CurNode),
                                   MakePciDeviceFromNode (CurNode),
                                   CPU_ADDR_FUNC_01,
                                   REG_ADDR_CONFIG_MAP0_1XE0 + (4 * ConfigMapIndex));
    LibAmdPciWrite (AccessWidth32, Reg, &Temp, Nb->ConfigHandle);
  }
}
示例#3
0
/**
 * Stop a link, so that it is isolated from a connected device.
 *
 * @HtNbMethod{::F_STOP_LINK}.
 *
 * Use is for fatal incompatible configurations, or for user interface
 * request to power off a link (IgnoreLink, SkipRegang).
 * Set ConnDly to make the power effective at the warm reset.
 * Set XMT and RCV off.
 *
 * @param[in] Node   the node to stop a link on.
 * @param[in] Link   the link to stop.
 * @param[in] State  access to special routine for writing link control register
 * @param[in] Nb     this northbridge.
 */
VOID
Fam10StopLink (
  IN       UINT8       Node,
  IN       UINT8       Link,
  IN       STATE_DATA  *State,
  IN       NORTHBRIDGE *Nb
  )
{
  UINT32 Temp;
  PCI_ADDR Reg;

  // Set ConnDly
  Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
                                 MakePciBusFromNode (Node),
                                 MakePciDeviceFromNode (Node),
                                 CPU_HTNB_FUNC_00,
                                 REG_LINK_GLOBAL_EXT_CONTROL_0x16C);
  Temp = 1;
  LibAmdPciWriteBits (Reg, 8, 8, &Temp, Nb->ConfigHandle);
  // Set TransOff and EndOfChain
  Reg = Nb->MakeLinkBase (Node, Link, Nb);
  Reg.Address.Register += HTHOST_LINK_CONTROL_REG;
  Temp = 3;
  State->HtFeatures->SetHtControlRegisterBits (Reg, 7, 6, &Temp, State);
}
示例#4
0
文件: IdsLib.c 项目: B-Rich/coreboot
/**
 * Ids Write PCI register to All node
 *
 *
 * @param[in] PciAddress    Pci address
 * @param[in]   Highbit       High bit position of the field in DWORD
 * @param[in]   Lowbit        Low bit position of the field in DWORD
 * @param[in] Value         Pointer to input value
 * @param[in] StdHeader     Standard configuration header
 *
 */
VOID
IdsLibPciWriteBitsToAllNode (
  IN       PCI_ADDR PciAddress,
  IN       UINT8 Highbit,
  IN       UINT8 Lowbit,
  IN       UINT32 *Value,
  IN OUT   AMD_CONFIG_PARAMS *StdHeader
  )
{
  UINT32 Socket;
  UINT32 Module;
  AGESA_STATUS IgnoreStatus;
  PCI_ADDR PciAddr;


  for (Socket = 0; Socket < GetPlatformNumberOfSockets (); Socket++) {
    for (Module = 0; Module < GetPlatformNumberOfModules (); Module++) {
      if (GetPciAddress (StdHeader, Socket, Module, &PciAddr, &IgnoreStatus)) {
        PciAddr.Address.Function = PciAddress.Address.Function;
        PciAddr.Address.Register = PciAddress.Address.Register;
        LibAmdPciWriteBits (PciAddr, Highbit, Lowbit, Value, StdHeader);
      }
    }
  }
}
示例#5
0
/**
 * Turns routing tables off for a given Node
 *
 * @HtNbMethod{::F_DISABLE_ROUTING_TABLES}
 *
 * @param[in] Node the Node that will have it's routing tables disabled
 * @param[in] Nb   this northbridge
 */
VOID
DisableRoutingTables (
  IN       UINT8       Node,
  IN       NORTHBRIDGE *Nb
  )
{
  PCI_ADDR Reg;
  UINT32 Temp;
  Temp = 1;
  ASSERT ((Node < MAX_NODES));
  Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
                                 MakePciBusFromNode (Node),
                                 MakePciDeviceFromNode (Node),
                                 CPU_HTNB_FUNC_00,
                                 REG_LINK_INIT_CONTROL_0X6C);
  LibAmdPciWriteBits (Reg, 0, 0, &Temp, Nb->ConfigHandle);
}
示例#6
0
/**
 * Modifies the NodeID register on the target Node
 *
 * @HtNbMethod{::F_WRITE_NODEID}
 *
 * @param[in]     Node   the Node that will have its NodeID altered.
 * @param[in]     NodeID the new value for NodeID
 * @param[in]     Nb     this northbridge
 */
VOID
WriteNodeID (
  IN       UINT8       Node,
  IN       UINT8       NodeID,
  IN       NORTHBRIDGE *Nb
  )
{
  PCI_ADDR Reg;
  UINT32 Temp;
  Temp = NodeID;
  ASSERT ((Node < MAX_NODES) && (NodeID < MAX_NODES));
  Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
                                 MakePciBusFromNode (Node),
                                 MakePciDeviceFromNode (Node),
                                 CPU_HTNB_FUNC_00,
                                 REG_NODE_ID_0X60);
  LibAmdPciWriteBits (Reg, 2, 0, &Temp, Nb->ConfigHandle);
}
示例#7
0
/**
 * Write the token stored in the scratchpad register
 *
 * @HtNbMethod{::F_WRITE_TOKEN}
 *
 * Use the CPU core count as a scratch pad.
 *
 * @note The location used to store the token is arbitrary.  The only requirement is
 * that the location warm resets to zero, and that using it will have no ill-effects
 * during HyperTransport initialization.
 *
 * @param[in]     Node  the Node that marked with token
 * @param[in]     Value the token Value
 * @param[in]     Nb    this northbridge
 */
VOID
WriteToken (
  IN       UINT8       Node,
  IN       UINT8       Value,
  IN       NORTHBRIDGE *Nb
  )
{
  PCI_ADDR Reg;
  UINT32 Temp;
  Temp = Value;
  ASSERT ((Node < MAX_NODES));
  // Use CpuCnt as a scratch register
  Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
                                 MakePciBusFromNode (Node),
                                 MakePciDeviceFromNode (Node),
                                 CPU_HTNB_FUNC_00,
                                 REG_NODE_ID_0X60);
  LibAmdPciWriteBits (Reg, 19, 16, &Temp, Nb->ConfigHandle);
}
示例#8
0
/**
 * Change the hardware state for all Links according to the now optimized data in the
 * port list data structure for link reganging.
 *
 * @HtNbMethod{::F_SET_LINK_REGANG}
 *
 * @param[in]     Node   the node on which to regang a link
 * @param[in]     Link   the sublink 0 of the sublink pair to regang
 * @param[in]     Nb     this northbridge
 */
VOID
SetLinkRegang (
  IN       UINT8       Node,
  IN       UINT8       Link,
  IN       NORTHBRIDGE *Nb
  )
{
  PCI_ADDR Reg;
  UINT32 Temp;

  Temp = 1;
  Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
                                 MakePciBusFromNode (Node),
                                 MakePciDeviceFromNode (Node),
                                 CPU_HTNB_FUNC_00,
                                 REG_HT_LINK_EXT_CONTROL0_0X170 + (4 * Link));

  LibAmdPciWriteBits (Reg, 0, 0, &Temp, Nb->ConfigHandle);
}
示例#9
0
/**
 * Write the total number of cores to the Node
 *
 * @TopoNbMethod{::F_SET_TOTAL_NODES_AND_CORES}
 *
 * @param[in]     Node         the Node that will be examined
 * @param[in]     TotalNodes   the total number of Nodes
 * @param[in]     TotalCores   the total number of cores
 * @param[in]     Nb           this northbridge
 */
VOID
Fam16SetTotalCores (
    IN       UINT8       Node,
    IN       UINT8       TotalNodes,
    IN       UINT8       TotalCores,
    IN       NORTHBRIDGE *Nb
)
{
    PCI_ADDR NodeIDReg;
    UINT32 Temp;

    NodeIDReg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
                                         MakePciBusFromNode (Node),
                                         MakePciDeviceFromNode (Node),
                                         CPU_NB_FUNC_00,
                                         REG_NODE_ID_0X60);

    Temp = ((TotalCores - 1) & REG_NODE_CPUCNT_4_0);
    LibAmdPciWriteBits (NodeIDReg, 20, 16, &Temp, Nb->ConfigHandle);
}
示例#10
0
/**
 * Change the hardware state for all Links according to the now optimized data in the
 * port list data structure  for Unit Id Clumping.
 *
 * @HtNbMethod{::F_SET_LINK_UNITID_CLUMPING}
 *
 * This applies to the host root of a non-coherent chain.
 *
 * @param[in]     Node              the node on which to enable clumping
 * @param[in]     Link              the link for which to enable clumping
 * @param[in]     ClumpingEnables   the unit id clumping enables
 * @param[in]     Nb                this northbridge
 */
VOID
SetLinkUnitIdClumping (
  IN       UINT8       Node,
  IN       UINT8       Link,
  IN       UINT32      ClumpingEnables,
  IN       NORTHBRIDGE *Nb
  )
{
  PCI_ADDR Reg;

  // Host Unit Ids are not clumped.
  ASSERT ((ClumpingEnables & 0x3) == 0);

  Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node),
                                 MakePciBusFromNode (Node),
                                 MakePciDeviceFromNode (Node),
                                 CPU_HTNB_FUNC_00,
                                 REG_HT_LINK_CLUMPING0_0X110 + (4 * Link));

  LibAmdPciWriteBits (Reg, 31, 0, &ClumpingEnables, Nb->ConfigHandle);
}
示例#11
0
/**
 * Process a non-coherent Link.
 *
 * @HtFeatMethod{::F_PROCESS_LINK}
 *
 * Enable a range of bus numbers, and set the device ID for all devices found.  Add
 * non-coherent devices, links to the system data structure.
 *
 * @param[in]     Node          Node on which to process nc init
 * @param[in]     Link          The non-coherent Link on that Node
 * @param[in]     IsCompatChain Is this the chain with the southbridge? TRUE if yes.
 * @param[in,out] State         our global state
 */
VOID
ProcessLink (
  IN       UINT8         Node,
  IN       UINT8         Link,
  IN       BOOLEAN       IsCompatChain,
  IN OUT   STATE_DATA    *State
  )
{
  UINT8 SecBus;
  UINT8 SubBus;
  UINT32 CurrentBuid;
  UINT32 Temp;
  UINT32 UnitIdCount;
  PCI_ADDR CurrentPtr;
  PCI_ADDR Link1ControlRegister;
  UINT8 Depth;
  BUID_SWAP_LIST *SwapPtr;
  UINT8  LastLink;
  BOOLEAN IsCaveDevice;

  ASSERT ((Node < MAX_NODES) && (Link < State->Nb->MaxLinks));

  if (!State->HtInterface->GetOverrideBusNumbers (Node, Link, &SecBus, &SubBus, State)) {
    // Assign Bus numbers
    if (State->AutoBusCurrent >= State->HtBlock->AutoBusMax) {
      //  If we run out of Bus Numbers, notify and skip this chain
      //
      IDS_ERROR_TRAP;
      NotifyErrorNcohBusMaxExceed (Node, Link, State->AutoBusCurrent, State);
      return;
    }

    if (State->UsedCfgMapEntries >= 4) {
      // If we have used all the PCI Config maps we can't add another chain.
      // Notify and if call back is unimplemented or returns, skip this chain.
      //
      IDS_ERROR_TRAP;
      NotifyErrorNcohCfgMapExceed (Node, Link, State);
      return;
    }

    SecBus = State->AutoBusCurrent;
    SubBus = SecBus + State->HtBlock->AutoBusIncrement - 1;
    State->AutoBusCurrent = State->AutoBusCurrent + State->HtBlock->AutoBusIncrement;
  }

  State->Nb->SetConfigAddrMap (State->UsedCfgMapEntries, SecBus, SubBus, Node, Link, State, State->Nb);
  State->UsedCfgMapEntries++;

  if (State->HtInterface->GetManualBuidSwapList (Node, Link, &SwapPtr, State)) {
    // Manual non-coherent BUID assignment
    AGESA_TESTPOINT (TpProcHtManualNc, State->ConfigHandle);


    if (!IsCompatChain || !State->IsUsingRecoveryHt) {
      //  If this is the not southbridge chain or Recovery HT was not used
      // then we need to assign BUIDs here.
      //
      Depth = 0;
      // Assign BUID's per manual override
      while (SwapPtr->Swaps[Depth].FromId != 0xFF) {
        CurrentPtr.AddressValue = MAKE_SBDFO (0, SecBus, SwapPtr->Swaps[Depth].FromId, 0, 0);
        if (DoesDeviceHaveHtSubtypeCap (CurrentPtr, HT_SLAVE_CAPABILITY, &CurrentPtr, State)) {
          // Set the device's BUID field [20:16] to the current buid
          CurrentBuid = SwapPtr->Swaps[Depth].ToId;
          LibAmdPciWriteBits (CurrentPtr, 20, 16, &CurrentBuid, State->ConfigHandle);
          Depth++;
        } else {
          // All non-coherent devices must have a slave interface capability.
          ASSERT (FALSE);
          break;
        }
      }
    }

    // Build chain of devices. Do this even if Recovery HT assign BUIDs for this chain.
    Depth = 0;
    while (SwapPtr->FinalIds[Depth] != 0xFF) {
      ASSERT (State->TotalLinks < MAX_PLATFORM_LINKS);
      (*State->PortList)[(State->TotalLinks * 2)].NodeID = Node;
      // Note: depth == 0 is true before depth > 0. This makes LastLink variable work.
      if (Depth == 0) {
        (*State->PortList)[(State->TotalLinks * 2)].Type = PORTLIST_TYPE_CPU;
        (*State->PortList)[(State->TotalLinks * 2)].Link = Link;
      } else {
        // Fill in the host side port.  Link and base pointer can be deduced from the upstream link's
        // downstream port.
        (*State->PortList)[(State->TotalLinks * 2)].Type = PORTLIST_TYPE_IO;
        (*State->PortList)[(State->TotalLinks * 2)].Link = 1 - (*State->PortList)[(((State->TotalLinks - 1) * 2) + 1)].Link;
        (*State->PortList)[(State->TotalLinks * 2)].HostLink = Link;
        (*State->PortList)[(State->TotalLinks * 2)].HostDepth = Depth - 1;
        (*State->PortList)[(State->TotalLinks * 2)].Pointer = (*State->PortList)[(((State->TotalLinks - 1) * 2) + 1)].Pointer;
      }

      (*State->PortList)[(State->TotalLinks * 2) + 1].Type = PORTLIST_TYPE_IO;
      (*State->PortList)[(State->TotalLinks * 2) + 1].NodeID = Node;
      (*State->PortList)[(State->TotalLinks * 2) + 1].HostLink = Link;
      (*State->PortList)[(State->TotalLinks * 2) + 1].HostDepth = Depth;

      CurrentPtr.AddressValue = MAKE_SBDFO (0, SecBus, (SwapPtr->FinalIds[Depth] & 0x3F), 0, 0);
      if (DoesDeviceHaveHtSubtypeCap (CurrentPtr, HT_SLAVE_CAPABILITY, &CurrentPtr, State)) {
        (*State->PortList)[(State->TotalLinks * 2) + 1].Pointer = CurrentPtr;
      } else {
        // All non-coherent devices must have a slave interface capability.
        ASSERT (FALSE);
        break;
      }

      // Bit 6 indicates whether orientation override is desired.
      // Bit 7 indicates the upstream Link if overriding.
      //
      // assert catches at least the one known incorrect setting, that a non-zero link
      // is specified, but override desired is not set.
      ASSERT (((SwapPtr->FinalIds[Depth] & 0x40) != 0) || ((SwapPtr->FinalIds[Depth] & 0x80) == 0));
      if ((SwapPtr->FinalIds[Depth] & 0x40) != 0) {
        // Override the device's orientation
        LastLink = SwapPtr->FinalIds[Depth] >> 7;
      } else {
示例#12
0
/**
 * Change the hardware state for all Links according to the now optimized data in the
 * port list data structure.
 *
 * @HtFeatMethod{::F_SET_LINK_DATA}
 *
 * @param[in]     State   our global state, port list
 */
VOID
SetLinkData (
  IN       STATE_DATA *State
  )
{
  UINT8 i;
  PCI_ADDR LinkBase;
  PCI_ADDR Reg;
  UINT32 Temp;
  UINT32 Widthin;
  UINT32 Widthout;
  UINT32 Bits;
  PCI_ADDR CurrentPtr;
  HTIDS_PORT_OVERRIDE_LIST PortOverrides;

  PortOverrides = NULL;

  for (i = 0; i < (State->TotalLinks * 2); i++) {

    ASSERT ((*State->PortList)[i & 0xFE].SelWidthOut == (*State->PortList)[ (i & 0xFE) + 1].SelWidthIn);
    ASSERT ((*State->PortList)[i & 0xFE].SelWidthIn == (*State->PortList)[ (i & 0xFE) + 1].SelWidthOut);
    ASSERT ((*State->PortList)[i & 0xFE].SelFrequency == (*State->PortList)[ (i & 0xFE) + 1].SelFrequency);

    if ((*State->PortList)[i].SelRegang) {
      ASSERT ((*State->PortList)[i].Type == PORTLIST_TYPE_CPU);
      ASSERT ((*State->PortList)[i].Link < 4);
      State->Nb->SetLinkRegang (
        (*State->PortList)[i].NodeID,
        (*State->PortList)[i].Link,
        State->Nb
        );
    }

    //
    // IDS port override for CPUs and IO Devices
    //
    pf_HtIdsGetPortOverride ((BOOLEAN) ((i & 1) == 0), &(*State->PortList)[i], &(*State->PortList)[i + 1], &PortOverrides, State);

    LinkBase = (*State->PortList)[i].Pointer;
    if (((*State->PortList)[i].Type == PORTLIST_TYPE_IO) && ((*State->PortList)[i].Link == 1)) {
      LinkBase.Address.Register += HTSLAVE_LINK01_OFFSET;
    }

    // HT CRC Feature, set if configured.  The default is not to set it, because with some chipsets it
    // will lock up if done here.
    if (State->IsSetHtCrcFlood) {
      Temp = 1;
      Reg = LinkBase;
      Reg.Address.Register += HTHOST_LINK_CONTROL_REG;
      State->HtFeatures->SetHtControlRegisterBits (Reg, 1, 1, &Temp, State);
      if ((*State->PortList)[i].Type == PORTLIST_TYPE_IO) {
        // IO Devices also need to have SERR enabled.
        Reg = LinkBase;
        Reg.Address.Register = PCI_CONFIG_COMMAND_REG04;
        LibAmdPciWriteBits (Reg, 8, 8, &Temp, State->ConfigHandle);
      }
    }

    // Some IO devices don't work properly when setting widths, so write them in a single operation,
    // rather than individually.
    //
    Widthout = ConvertWidthToBits ((*State->PortList)[i].SelWidthOut);
    ASSERT (Widthout == 1 || Widthout == 0 || Widthout == 5 || Widthout == 4);
    Widthin = ConvertWidthToBits ((*State->PortList)[i].SelWidthIn);
    ASSERT (Widthin == 1 || Widthin == 0 || Widthin == 5 || Widthin == 4);

    Temp = (Widthin & 7) | ((Widthout & 7) << 4);
    Reg = LinkBase;
    Reg.Address.Register += HTHOST_LINK_CONTROL_REG;
    State->HtFeatures->SetHtControlRegisterBits (Reg, 31, 24, &Temp, State);

    Temp = (*State->PortList)[i].SelFrequency;
    IDS_HDT_CONSOLE (HT_TRACE, "Link Frequency: Node %02d: Link %02d: is running at %2d00MHz\n",
        (*State->PortList)[i].NodeID, (*State->PortList)[i].Link,
        (Temp < HT_FREQUENCY_800M) ? Temp + 2 : ((Temp < HT_FREQUENCY_2800M) ? 2 * (Temp - 1) : 2 * (Temp - 3)));

    if ((*State->PortList)[i].Type == PORTLIST_TYPE_CPU) {
      State->Nb->SetLinkFrequency (
        (*State->PortList)[i].NodeID,
        (*State->PortList)[i].Link,
        (UINT8)Temp,
        State->Nb
        );
    } else {
      ASSERT (Temp <= HT_FREQUENCY_2600M);
      // Write the frequency setting
      Reg = LinkBase;
      Reg.Address.Register += HTSLAVE_FREQ_REV_0_REG;
      SetHtIoFrequencyRegisterBits (Reg, 11, 8, &Temp, State);

      // Handle additional HT3 frequency requirements, if needed,
      // or clear them if switching down to ht1 on a warm reset.
      // Gen1 = 200Mhz -> 1000MHz, Gen3 = 1200MHz -> 2600MHz
      //
      // Even though we assert if debugging, we need to check that the capability was
      // found always, since this is an unknown hardware device, also we are taking
      // unqualified frequency from the external interface (could be trying to do ht3
      // on an ht1 IO device).
      //

      if (Temp > HT_FREQUENCY_1000M) {
        // Enabling features if gen 3
        Bits = 1;
      } else {
        // Disabling features if gen 1
        Bits = 0;
      }

      // Retry Enable
      if (DoesDeviceHaveHtSubtypeCap (LinkBase, HT_RETRY_CAPABILITY, &CurrentPtr, State)) {
        ASSERT ((*State->PortList)[i].Link < 2);
        CurrentPtr.Address.Register += HTRETRY_CONTROL_REG;
        LibAmdPciWriteBits (CurrentPtr,
                            ((*State->PortList)[i].Link * 16),
                            ((*State->PortList)[i].Link * 16),
                            &Bits,
                            State->ConfigHandle);
      } else {
        //  If we are turning it off, that may mean the device was only ht1 capable,
        // so don't complain that we can't do it.
        //
        if (Bits != 0) {
          NotifyWarningOptRequiredCapRetry ((*State->PortList)[i].NodeID,
                                            (*State->PortList)[i].HostLink,
                                            (*State->PortList)[i].HostDepth,
                                            State);
        }
      }

      // Scrambling enable
      if (DoesDeviceHaveHtSubtypeCap (LinkBase, HT_GEN3_CAPABILITY, &CurrentPtr, State)) {
        ASSERT ((*State->PortList)[i].Link < 2);
        CurrentPtr.Address.Register = CurrentPtr.Address.Register +
          HTGEN3_LINK_TRAINING_0_REG +
          ((*State->PortList)[i].Link * HTGEN3_LINK01_OFFSET);
        LibAmdPciWriteBits (CurrentPtr, 3, 3, &Bits, State->ConfigHandle);
      } else {
        //  If we are turning it off, that may mean the device was only ht1 capable,
        // so don't complain that we can't do it.
        //
        if (Bits != 0) {
          NotifyWarningOptRequiredCapGen3 ((*State->PortList)[i].NodeID,
                                           (*State->PortList)[i].HostLink,
                                           (*State->PortList)[i].HostDepth,
                                           State);
        }
      }
    }
    // Enable Unit ID Clumping if supported.
    if (State->IsUsingUnitIdClumping) {
      if (((*State->PortList)[i].ClumpingSupport != HT_CLUMPING_PASSIVE) &&
          ((*State->PortList)[i].ClumpingSupport != HT_CLUMPING_DISABLE)) {
        Bits = (*State->PortList)[i].ClumpingSupport;
        if ((*State->PortList)[i].Type == PORTLIST_TYPE_CPU) {
          State->Nb->SetLinkUnitIdClumping (
            (*State->PortList)[i].NodeID,
            (*State->PortList)[i].Link,
            (*State->PortList)[i].ClumpingSupport,
            State->Nb
            );
        } else {
          if (DoesDeviceHaveHtSubtypeCap (LinkBase, HT_UNITID_CAPABILITY, &Reg, State)) {
            Reg.Address.Register += HTUNIT_ENABLE_REG;
            LibAmdPciWriteBits (Reg, 31, 0, &Bits, State->ConfigHandle);
          } else {
            // If we found one when gathering support, we have to find one now.
            ASSERT (FALSE);
          }
        }
      }
    }
  }
}
示例#13
0
/**
 * Get Link features into system data structure.
 *
 * @HtFeatMethod{::F_GATHER_LINK_DATA}
 *
 * For all discovered Links, populate the port list with the frequency and width
 * capabilities. Gather support data for:
 * - Unit ID Clumping
 *
 * @param[in]     State our global state, port list
 */
VOID
GatherLinkData (
  IN       STATE_DATA *State
  )
{
  UINT8 i;
  PCI_ADDR LinkBase;
  PCI_ADDR Reg;
  UINT32 Bits;
  UINT8 Revision;

  // Get the capability base for whatever device type the link port is on
  for (i = 0; i < (State->TotalLinks * 2); i++) {
    if ((*State->PortList)[i].Type == PORTLIST_TYPE_CPU) {
      LinkBase = State->Nb->MakeLinkBase ((*State->PortList)[i].NodeID, (*State->PortList)[i].Link, State->Nb);
      (*State->PortList)[i].Pointer = LinkBase;
    } else {
      LinkBase = (*State->PortList)[i].Pointer;
      if ((*State->PortList)[i].Link == 1) {
        LinkBase.Address.Register += HTSLAVE_LINK01_OFFSET;
      }
    }

    // Getting the Width is standard across device types
    Reg = LinkBase;
    Reg.Address.Register += HTSLAVE_LINK_CONTROL_0_REG;
    LibAmdPciReadBits (Reg, 22, 20, &Bits, State->ConfigHandle);
    (*State->PortList)[i].PrvWidthOutCap = ConvertBitsToWidth ((UINT8)Bits);

    LibAmdPciReadBits (Reg, 18, 16, &Bits, State->ConfigHandle);
    (*State->PortList)[i].PrvWidthInCap = ConvertBitsToWidth ((UINT8)Bits);

    // Get Frequency and other device type specific features
    if ((*State->PortList)[i].Type == PORTLIST_TYPE_CPU) {
      State->Nb->GatherLinkFeatures (&(*State->PortList)[i], State->HtInterface, State->PlatformConfiguration, State->Nb);
    } else {
      Reg = LinkBase;
      Reg.Address.Register += HTSLAVE_FREQ_REV_0_REG;
      LibAmdPciReadBits (Reg, 31, 16, &Bits, State->ConfigHandle);
      (*State->PortList)[i].PrvFrequencyCap = Bits;

      // Unit ID Clumping Support
      if (State->IsUsingUnitIdClumping) {
        if (DoesDeviceHaveHtSubtypeCap (LinkBase, HT_UNITID_CAPABILITY, &Reg, State)) {
          Reg.Address.Register += HTUNIT_SUPPORT_REG;
          LibAmdPciReadBits (Reg, 31, 0, &Bits, State->ConfigHandle);
        } else {
          // Not there, that's ok, we don't know that it should have one.
          // Check for Passive support. (Bit 0 won't be set if full support is implemented,
          // so we can use it to indicate passive support in our portlist struct).
          Reg = LinkBase;
          Reg.Address.Register += HTSLAVE_FEATURECAP_REG;
          Bits = 1;
          LibAmdPciWriteBits (Reg, 5, 5, &Bits, State->ConfigHandle);
          LibAmdPciReadBits (Reg, 5, 5, &Bits, State->ConfigHandle);
        }
        (*State->PortList)[i].ClumpingSupport = Bits;
      } else {
        (*State->PortList)[i].ClumpingSupport = HT_CLUMPING_DISABLE;
      }

      Reg = LinkBase;
      Reg.Address.Register = PCI_CONFIG_REVISION_REG08;
      LibAmdPciReadBits ( LinkBase, 7, 0, &Bits, State->ConfigHandle);
      Revision = (UINT8) Bits;

      LinkBase.Address.Register = 0;
      LibAmdPciRead (AccessWidth32, LinkBase, &Bits, State->ConfigHandle);

      State->HtInterface->GetDeviceCapOverride ((*State->PortList)[i].NodeID,
                           (*State->PortList)[i].HostLink,
                           (*State->PortList)[i].HostDepth,
                           (*State->PortList)[i].Pointer,
                           Bits,
                           Revision,
                           (*State->PortList)[i].Link,
                           &((*State->PortList)[i].PrvWidthInCap),
                           &((*State->PortList)[i].PrvWidthOutCap),
                           &((*State->PortList)[i].PrvFrequencyCap),
                           &((*State->PortList)[i].ClumpingSupport),
                           State);
    }
  }
}