/** * 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); }
/** * Return whether the current configuration exceeds the capability. * * @HtNbMethod{::F_IS_EXCEEDED_CAPABLE}. * * Get Node capability and update the minimum supported system capability. * * @param[in] Node the Node * @param[in] State sysMpCap (updated) and NodesDiscovered * @param[in] Nb this northbridge * * @retval TRUE system is not capable of current config. * @retval FALSE system is capable of current config. */ BOOLEAN Fam10IsExceededCapable ( IN UINT8 Node, IN STATE_DATA *State, IN NORTHBRIDGE *Nb ) { UINT32 Temp; UINT8 MaxNodes; PCI_ADDR Reg; ASSERT (Node < MAX_NODES); Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node), MakePciBusFromNode (Node), MakePciDeviceFromNode (Node), CPU_NB_FUNC_03, REG_NB_CAPABILITY_3XE8); LibAmdPciReadBits (Reg, 18, 16, &Temp, Nb->ConfigHandle); if (Temp != 0) { MaxNodes = (UINT8) (1 << (~Temp & 0x3)); // That is, 1, 2, 4, or 8 } else { MaxNodes = 8; } if (State->SysMpCap > MaxNodes) { State->SysMpCap = MaxNodes; } // Note since sysMpCap is one based and NodesDiscovered is zero based, equal returns true // return ((BOOLEAN) (State->SysMpCap <= State->NodesDiscovered)); }
/** * Fix (hopefully) exceptional conditions. * * @HtNbMethod{::F_HANDLE_SPECIAL_NODE_CASE}. * * Currently, this routine is implemented for all coherent HT families to check * vendor ID of coherent Node. If the vendor ID is 0x1022 then return FALSE, * or return TRUE. * * @param[in] Node The Node which need to be checked. * @param[in] Link The link to check for special conditions. * @param[in] State our global state. * @param[in] Nb this northbridge. * * @retval TRUE This node received special handling. * @retval FALSE This node was not handled specially, handle it normally. * */ BOOLEAN HandleSpecialNodeCase ( IN UINT8 Node, IN UINT8 Link, IN STATE_DATA *State, IN NORTHBRIDGE *Nb ) { BOOLEAN Result; PCI_ADDR Reg; UINT32 VendorID; Result = TRUE; Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node), MakePciBusFromNode (Node), MakePciDeviceFromNode (Node), 0, 0); LibAmdPciReadBits (Reg, 15, 0, &VendorID, Nb->ConfigHandle); if (VendorID == 0x1022) { Result = FALSE; } return Result; }
/** * 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); }
/** * 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); } }
/** * Return the number of cores (1 based count) on Node. * * @HtNbMethod{::F_GET_NUM_CORES_ON_NODE} * * @param[in] Node the Node that will be examined * @param[in] Nb this northbridge * * @return the number of cores */ UINT8 Fam15Mod1xGetNumCoresOnNode ( IN UINT8 Node, IN NORTHBRIDGE *Nb ) { UINT32 Result; UINT32 Leveling; UINT32 Cores; UINT8 i; PCI_ADDR Reg; ASSERT ((Node < MAX_NODES)); // Read CmpCap Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node), MakePciBusFromNode (Node), MakePciDeviceFromNode (Node), CPU_NB_FUNC_05, REG_NB_CAPABILITY_2_5X84); LibAmdPciReadBits (Reg, 7, 0, &Result, Nb->ConfigHandle); // Support Downcoring Cores = Result; Cores++; Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node), MakePciBusFromNode (Node), MakePciDeviceFromNode (Node), CPU_NB_FUNC_03, REG_NB_DOWNCORE_3X190); LibAmdPciReadBits (Reg, 31, 0, &Leveling, Nb->ConfigHandle); for (i = 0; i < Cores; i++) { if ((Leveling & ((UINT32) 1 << i)) != 0) { Result--; } } return (UINT8) (Result + 1); }
/** * Return the Link to the Southbridge * * @HtNbMethod{::F_READ_SB_LINK} * * @param[in] Nb this northbridge * * @return the Link to the southbridge */ UINT8 ReadSouthbridgeLink ( IN NORTHBRIDGE *Nb ) { UINT32 Temp; PCI_ADDR Reg; Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (0), MakePciBusFromNode (0), MakePciDeviceFromNode (0), CPU_HTNB_FUNC_00, REG_UNIT_ID_0X64); LibAmdPciReadBits (Reg, 10, 8, &Temp, Nb->ConfigHandle); return (UINT8)Temp; }
/** * 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); }
/** * 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); }
/** * 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); }
/** * Get the dual core compute unit status for this node. * * @HtNbMethod{::PF_GET_DUALCORE_COMPUTE_UNITS} * * @param[in] Node The node for which we want the dual core status * @param[in] Nb Our Northbridge. * * @return The dual core compute unit status. */ UINT8 Fam15Mod1xGetDualcoreComputeUnits ( IN UINT8 Node, IN NORTHBRIDGE *Nb ) { UINT32 Dual; PCI_ADDR Reg; ASSERT ((Node < MAX_NODES)); Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node), MakePciBusFromNode (Node), MakePciDeviceFromNode (Node), CPU_NB_FUNC_05, REG_NB_COMPUTE_UNIT_5X80); LibAmdPciReadBits (Reg, 17, 16, &Dual, Nb->ConfigHandle); return ((UINT8) Dual); }
/** * Get the quad core compute unit status for this node. * * @TopoNbMethod{::PF_GET_QUADCORE_COMPUTE_UNITS} * * @param[in] Node The node for which we want the quad core status * @param[in] Nb Our Northbridge. * * @return The quad core compute unit status. */ UINT8 Fam16GetQuadcoreComputeUnits ( IN UINT8 Node, IN NORTHBRIDGE *Nb ) { UINT32 Quad; PCI_ADDR Reg; ASSERT ((Node < MAX_NODES)); Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node), MakePciBusFromNode (Node), MakePciDeviceFromNode (Node), CPU_NB_FUNC_05, REG_NB_COMPUTE_UNIT_5X80); LibAmdPciReadBits (Reg, 27, 24, &Quad, Nb->ConfigHandle); return ((UINT8) Quad); }
/** * 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); }
/** * Construct a new northbridge. * * This routine encapsulates knowledge of how to tell significant differences between * families of supported northbridges and what routines can be used in common and * which are unique. A fully populated northbridge interface is provided by Nb. * * @param[in] Node create a northbridge interface for this Node. * @param[in] State global state * @param[out] Nb the caller's northbridge structure to initialize. */ VOID NewNorthBridge ( IN UINT8 Node, IN STATE_DATA *State, OUT NORTHBRIDGE *Nb ) { CPU_LOGICAL_ID LogicalId; UINT64 Match; UINT32 RawCpuId; PCI_ADDR Reg; NORTHBRIDGE **InitializerInstance; // Start with enough of the key to identify the northbridge interface Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node), MakePciBusFromNode (Node), MakePciDeviceFromNode (Node), CPU_NB_FUNC_03, REG_NB_CPUID_3XFC); LibAmdPciReadBits (Reg, 31, 0, &RawCpuId, State->ConfigHandle); IDS_HDT_CONSOLE (TOPO_TRACE, "AMD Processor at Node %d has raw CPUID=%x.\n", Node, RawCpuId); GetLogicalIdFromCpuid (RawCpuId, &LogicalId, State->ConfigHandle); Match = LogicalId.Family; // Test each Northbridge interface in turn looking for a match. // Use it to Init the Nb struct if a match is found. // ASSERT (OptionTopoConfiguration.TopoOptionFamilyNorthbridgeList != NULL); InitializerInstance = (NORTHBRIDGE **) (OptionTopoConfiguration.TopoOptionFamilyNorthbridgeList); while (*InitializerInstance != NULL) { if ((Match & (*InitializerInstance)->CompatibleKey) != 0) { LibAmdMemCopy ((VOID *)Nb, (VOID *)*InitializerInstance, (UINT32) sizeof (NORTHBRIDGE), State->ConfigHandle); break; } InitializerInstance++; } // There must be an available northbridge implementation. ASSERT (*InitializerInstance != NULL); // Set the config handle for passing to the library. Nb->ConfigHandle = State->ConfigHandle; }
/** * Make a compatibility key. * * @TopoNbMethod{::F_MAKE_KEY} * * Private routine to northbridge code. * Create a key which can be used to determine whether a Node is compatible with * the discovered configuration so far. Currently, that means the family, * extended family of the new Node are the same as the BSP's. Family specific * implementations can add whatever else is necessary. * * @param[in] Node the Node * @param[in] Nb this northbridge * * @return the key */ UINT64 MakeKey ( IN UINT8 Node, IN NORTHBRIDGE *Nb ) { CPU_LOGICAL_ID LogicalId; UINT32 RawCpuId; PCI_ADDR Reg; Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node), MakePciBusFromNode (Node), MakePciDeviceFromNode (Node), CPU_NB_FUNC_03, REG_NB_CPUID_3XFC); LibAmdPciReadBits (Reg, 31, 0, &RawCpuId, Nb->ConfigHandle); GetLogicalIdFromCpuid (RawCpuId, &LogicalId, Nb->ConfigHandle); return LogicalId.Family; }
/** * Establish a Temporary route from one Node to another. * * @HtNbMethod{::F_WRITE_ROUTING_TABLE} * * This routine will modify the routing tables on the * SourceNode to cause it to route both request and response traffic to the * targetNode through the specified Link. * * @note: This routine is to be used for early discovery and initialization. The * final routing tables must be loaded some other way because this * routine does not address the issue of probes, or independent request * response paths. * * @param[in] Node the Node that will have it's routing tables modified. * @param[in] Target For routing to Node target * @param[in] Link Link from Node to target * @param[in] Nb this northbridge */ VOID WriteRoutingTable ( IN UINT8 Node, IN UINT8 Target, IN UINT8 Link, IN NORTHBRIDGE *Nb ) { PCI_ADDR Reg; UINT32 Temp; ASSERT ((Node < MAX_NODES) && (Target < MAX_NODES) && (Link < Nb->MaxLinks)); Temp = (Nb->SelfRouteResponseMask | Nb->SelfRouteRequestMask) << (Link + 1); Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node), MakePciBusFromNode (Node), MakePciDeviceFromNode (Node), CPU_HTNB_FUNC_00, REG_ROUTE0_0X40 + (Target * 4)); LibAmdPciWrite (AccessWidth32, Reg, &Temp, Nb->ConfigHandle); }
/** * 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); }
/** * Return the number of cores (1 based count) on Node. * * @HtNbMethod{::F_GET_NUM_CORES_ON_NODE} * * @param[in] Node the Node that will be examined * @param[in] Nb this northbridge * * @return the number of cores */ UINT8 Fam12GetNumCoresOnNode ( IN UINT8 Node, IN NORTHBRIDGE *Nb ) { UINT32 Cores; PCI_ADDR Reg; ASSERT ((Node < MAX_NODES)); // Read CmpCap Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node), MakePciBusFromNode (Node), MakePciDeviceFromNode (Node), CPU_NB_FUNC_03, REG_NB_CAPABILITY_3XE8); LibAmdPciReadBits (Reg, 13, 12, &Cores, Nb->ConfigHandle); return (UINT8) (Cores + 1); }
/** * 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); }
/** * Full Routing Table Register initialization * * @HtNbMethod{::F_WRITE_FULL_ROUTING_TABLE} * * Write the routing table entry for Node to target, using the request Link, response * Link, and broadcast Links provided. * * @param[in] Node the Node that will be examined * @param[in] Target the Target Node for these routes * @param[in] ReqLink the Link for requests to Target * @param[in] RspLink the Link for responses to Target * @param[in] BroadcastLinks the broadcast Links * @param[in] Nb this northbridge */ VOID WriteFullRoutingTable ( IN UINT8 Node, IN UINT8 Target, IN UINT8 ReqLink, IN UINT8 RspLink, IN UINT32 BroadcastLinks, IN NORTHBRIDGE *Nb ) { PCI_ADDR Reg; UINT32 Value; Value = 0; ASSERT ((Node < MAX_NODES) && (Target < MAX_NODES)); if (ReqLink == ROUTE_TO_SELF) { Value |= Nb->SelfRouteRequestMask; } else { Value |= Nb->SelfRouteRequestMask << (ReqLink + 1); } if (RspLink == ROUTE_TO_SELF) { Value |= Nb->SelfRouteResponseMask; } else { Value |= Nb->SelfRouteResponseMask << (RspLink + 1); } // Allow us to accept a Broadcast ourselves, then set broadcasts for routes Value |= (UINT32)1 << Nb->BroadcastSelfBit; Value |= (UINT32)BroadcastLinks << (Nb->BroadcastSelfBit + 1); Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node), MakePciBusFromNode (Node), MakePciDeviceFromNode (Node), CPU_HTNB_FUNC_00, REG_ROUTE0_0X40 + (Target * 4)); LibAmdPciWrite (AccessWidth32, Reg, &Value, Nb->ConfigHandle); }
/** * Read the Default Link * * @HtNbMethod{::F_READ_DEFAULT_LINK} * * Read the DefLnk (the source Link of the current packet) from Node. Since this code * is running on the BSP, this should be the Link pointing back towards the BSP. * * @param[in] Node the Node that will have its NodeID altered. * @param[in] Nb this northbridge * * @return The HyperTransport Link where the request to * read the default Link came from. */ UINT8 ReadDefaultLink ( IN UINT8 Node, IN NORTHBRIDGE *Nb ) { UINT32 DefaultLink; PCI_ADDR Reg; UINT32 Temp; DefaultLink = 0; Reg.AddressValue = MAKE_SBDFO (MakePciSegmentFromNode (Node), MakePciBusFromNode (Node), MakePciDeviceFromNode (Node), CPU_HTNB_FUNC_00, REG_LINK_INIT_CONTROL_0X6C); ASSERT ((Node < MAX_NODES)); LibAmdPciReadBits (Reg, 3, 2, &DefaultLink, Nb->ConfigHandle); LibAmdPciReadBits (Reg, 8, 8, &Temp, Nb->ConfigHandle); DefaultLink |= (Temp << 2); return (UINT8)DefaultLink; }