diff options
Diffstat (limited to 'src/northbridge/amd/amdht')
-rw-r--r-- | src/northbridge/amd/amdht/AsPsDefs.h | 273 | ||||
-rw-r--r-- | src/northbridge/amd/amdht/AsPsNb.c | 121 | ||||
-rw-r--r-- | src/northbridge/amd/amdht/AsPsNb.h | 22 | ||||
-rw-r--r-- | src/northbridge/amd/amdht/Makefile.inc | 5 | ||||
-rw-r--r-- | src/northbridge/amd/amdht/comlib.c | 238 | ||||
-rw-r--r-- | src/northbridge/amd/amdht/comlib.h | 42 | ||||
-rw-r--r-- | src/northbridge/amd/amdht/h3ffeat.h | 180 | ||||
-rw-r--r-- | src/northbridge/amd/amdht/h3finit.c | 1879 | ||||
-rw-r--r-- | src/northbridge/amd/amdht/h3finit.h | 620 | ||||
-rw-r--r-- | src/northbridge/amd/amdht/h3gtopo.h | 355 | ||||
-rw-r--r-- | src/northbridge/amd/amdht/h3ncmn.c | 2549 | ||||
-rw-r--r-- | src/northbridge/amd/amdht/h3ncmn.h | 115 | ||||
-rw-r--r-- | src/northbridge/amd/amdht/ht_wrapper.c | 384 | ||||
-rw-r--r-- | src/northbridge/amd/amdht/ht_wrapper.h | 28 | ||||
-rw-r--r-- | src/northbridge/amd/amdht/porting.h | 79 |
15 files changed, 0 insertions, 6890 deletions
diff --git a/src/northbridge/amd/amdht/AsPsDefs.h b/src/northbridge/amd/amdht/AsPsDefs.h deleted file mode 100644 index 30f4d759b6..0000000000 --- a/src/northbridge/amd/amdht/AsPsDefs.h +++ /dev/null @@ -1,273 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007-2008 Advanced Micro Devices, Inc. - * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - - -#ifndef ASPSDEFS_H -#define ASPSDEFS_H - -/* P-state register offset */ -#define PS_REG0 0 /* offset for P0 */ -#define PS_REG1 1 /* offset for P1 */ -#define PS_REG2 2 /* offset for P2 */ -#define PS_REG3 3 /* offset for P3 */ -#define PS_REG4 4 /* offset for P4 */ - -#define PS_IDD_VALUE_SHFT 0 /* IddValue: current value - field offset for msr.hi */ -#define PS_IDD_VALUE_MASK 0xFF /* IddValue: current value - field mask for msr.hi */ -#define PS_PSDIS_MASK 0x7fffffff /* disable P-state register */ -#define PS_EN_MASK 0x80000000 /* P-state register enable mask */ -#define PS_NB_DID_MASK 0x400000 /* P-state Reg[NbDid] Mask */ -#define PS_NB_VID_M_OFF 0x01ffffff /* P-state Reg[NbVid] Mask OFF */ -#define PS_CPU_VID_M_ON 0x0fe00 /* P-state Reg[CpuVid] Mask On */ -#define PS_NB_VID_M_ON 0x0fe000000 /* P-state Reg[NbVid] Mask On */ -#define PS_CPU_VID_SHFT 9 /* P-state bit shift for CpuVid */ -#define PS_NB_VID_SHFT 25 /* P-state bit shift for NbVid */ -#define PS_BOTH_VID_OFF 0x01ff01ff /* Mask NbVid & CpuVid */ -#define PS_CPU_NB_VID_SHFT 16 /* P-state bit shift from CpuVid to NbVid */ -#define PS_DIS 0x7fffffff /* disable P-state reg */ -#define PS_EN 0x80000000 /* enable P-state reg */ -#define PS_CPU_FID_MASK 0x03f /* MSRC001_00[68:64][CpuFid] - Core Frequency Id */ -#define PS_CURDIV_SHFT 8 /* P-state Current Divisor shift position */ -#define PS_CPUDID_SHIFT 6 /* P-state CPU DID shift position */ - -/* for unfused parts */ -#define PS_NB_VID_110V 0x48000000 -#define PS_NB_VID_1175V 0x3c000000 -/* NB VID 1.100V =0x12[PVI]=0x24[SVI] = 0100100b 7-bit code */ - -#define PS_NB_DID0 0 /* NB DID 0 */ -#define PS_NB_DID1 0x400000 /* NB DID 1 */ -#define PS_CPU_VID_110V 0x4800 /* CPU VID 1.100V */ -#define PS_CPU_VID_1175V 0x3c00 /* CPU VID 1.175V */ -#define PS_CPU_DID 0x40 /* CPU DID 1 = divisor of 2 */ -#define PS_CPU_DID0 0 /* CPU DID 0 = divisor of 1 */ -#define PS_CPU_FID_16G 0x00 /* CPU FID of 00 = 1.6GHz */ -#define PS_CPU_FID_16G1 0x10 /* CPU FId of 16 COF = 16+16/2 = 16 */ -#define PS_CPU_FID_18G 20 /* CPU FId of 20 COF = 20+16/2 = 18 */ -#define PS_CPU_FID_19G 22 /* CPU FId of 20 COF = 22+16/2 = 19 */ -#define PS_CPU_FID_20G 24 /* CPU FId of 20 COF = 24+16/2 = 20 */ -#define PS_CPU_FID_22G 28 /* CPU FId of 2C COF = 28+16/2 = 22 */ -#define PS_CPU_FID_30G 44 /* CPU FId of 2C COF = 44+16/2 = 30 */ - - - -#define PCI_DEV_BASE 24 /* System PCI device ID base */ -#define LOCAL_APIC_ID_SHIFT 24 /* Local APIC ID shift bit # */ -#define APIC_CID_SIZE_SHIFT 12 /* ApicCoreIdSize shift bit # */ -#define FN_0 0 /* Function 0 */ -#define FN_1 1 /* Function 1 */ -#define FN_2 2 /* Function 2 */ -#define FN_3 3 /* Function 3 */ -#define FN_4 4 /* Function 4 */ -#define FN_5 5 /* Function 5 */ -#define FN_80000000 0x80000000 /* Function 8000_0000 */ -#define FN_80000001 0x80000001 /* Function 8000_0001 */ -#define FN_80000008 0x80000008 /* Function 8000_0008 */ - -#define LNK_INIT_REG 0x6C /* F0x6C link initialization control register */ -#define WARM_RESET_BIT 0x10 /* bit 4 =1 : warm reset */ - -#define HTC_REG 0x64 /* hardware thermal control reg */ -#define HTC_PS_LMT_MASK 0x8fffffff /* HtcPstateLimit mask off */ -#define PS_LIMIT_POS 28 /* PstateLimit position for HTC & STC */ - -#define STC_REG 0x68 /* software thermal control reg */ -#define STC_PS_LMT_MASK 0x8fffffff /* StcPstateLimit mask off */ - -#define CPTC0 0x0d4 /* Clock Power/Timing Control0 Register*/ -#define CPTC0_MASK 0x000cffff /* Reset mask for this register */ -#define CPTC0_NBFID_MASK 0xffffffe0 /* NbFid mask off for this register */ -#define CPTC0_NBFID_MON 0x1f /* NbFid mask on for this register */ -#define NB_FID_EN 0x20 /* NbFidEn bit ON */ -#define NB_CLKDID_ALL 0x80000000 /* NbClkDidApplyAll bit ON */ -#define NB_CLKDID 0x40000000 /* NbClkDid value set by BIOS */ -#define NB_CLKDID_SHIFT 28 /* NbClkDid bit shift */ -#define PW_STP_UP50 0x08000000 /* PowerStepUp 50nS(1000b) */ -#define PW_STP_DN50 0x00800000 /* PowerStepDown 50nS (1000b)*/ -#define PW_STP_UP100 0x03000000 /* PowerStepUp 100nS(0011b) */ -#define PW_STP_DN100 0x00300000 /* PowerStepDown 100nS (0011b)*/ -#define PW_STP_UP200 0x02000000 /* PowerStepUp 200nS(0010b) */ -#define PW_STP_DN200 0x00200000 /* PowerStepDown 200nS (0010b)*/ -#define PW_STP_UP400 0x00000000 /* PowerStepUp 400nS(0000b) */ -#define PW_STP_DN400 0x00000000 /* PowerStepDown 400nS (0000b)*/ -#define CLK_RAMP_HYST_SEL_VAL 0x00000f00 /* value mask for clock ramp - hysteresis select. BIOS - should program - F3xC4[ClkRampHystSel] to - 1111b */ - - -#define LNK_PLL_LOCK 0x00010000 /* LnkPllLock value set (01b) by BIOS */ - - - -#define PSTATE_CTL 0xC0010070 /* P-state Control Register */ -#define NB_VID_POS 25 /* NbVid bit shift for position */ -#define NB_VID_MASK_OFF 0x01ffffff /* NbVid bits mask off */ -#define NB_VID_MASK_ON 0xfe000000 /* NbVid bits mask on */ -#define CPU_VID_POS 0x9 /* CpuVid bit shift for position */ -#define CPU_VID_MASK_OFF 0xffff01ff /* CpuVid bits mask off */ -#define CPU_VID_MASK_ON 0x0000fe00 /* CpuVid bits mask on */ -#define CPU_FID_DID_M_ON 0x000001ff /* CpuFid & CpuDid mask on */ -#define CPU_FID_DID_M_OFF 0xfffffe00 /* CpuFid & CpuDid mask off */ -#define NB_DID_VID_M_ON 0xfe400000 /* NbDid & NbVid mask on */ -#define NB_DID_M_ON 0x00400000 /* NbDid mask on */ -#define NB_DID_M_OFF 0xffbfffff /* NbDid mask off */ -#define NB_DID_POS 22 /* NbDid bit shift for position */ -#define PS_M_OFF 0xfff8ffff /* Cur Pstate mask off */ -#define PS_1 0x00010000 /* P-state 1 */ -#define PS_2 0x00020000 /* P-state 2 */ -#define PS_CPU_DID_1 0x40 /* Cpu Did 1 */ - -#define NB_VID1_MASK 0x00003f80 /* F3x1F4[NbVid1]*/ -#define NB_VID1_SHIFT 7 /* F3x1F4[NbVid1] */ - - - -#define PSTATE_STS 0xC0010071 /* P-state Status Register */ -#define STARTUP_PS_MASK 0x7 /* StartupPstate Mask */ - -/* define for NB VID & CPU VID transition functions */ -#define IS_NB 1 -#define IS_CPU 0 - -/* F3xD8 Clock Power/Timing Control 1 Register */ -#define CPTC1 0xd8 /* Clock Power/Timing Control1 Register*/ -#define VSRAMP_SLAM_MASK 0xffffff88 /* MaskOff [VSRampTime]&[VSSlamTime] */ -#define VSRAMP_SLAM_VALUE 0x16 /* [VSRampTime]=001b&[VSSlamTime]=110b */ -#define VSRAMP_MASK 0xffffff8f /* MaskOff [VSRampTime] */ -#define VSRAMP_VALUE 0x10 /* [VSRampTime]=001b */ -#define VS_RAMP_T 4 /* VSRampTime bit position */ -#define VSSLAM_MASK 0xfffffff8 /* MaskOff [VSSlamTime] */ -#define PWR_PLN_SHIFT 28 /* PwrPlanes bit shift */ -#define PWR_PLN_ON 0x10000000 /* PwrPlanes bit ON */ -#define PWR_PLN_OFF 0x0efffffff /* PwrPlanes bit OFF */ - - - -/* Northbridge Capability Register */ -#define NB_CAP 0xe8 /* Northbridge Cap Reg */ -#define CMP_CAP_SHFT 12 /* CMP CAP - number of enabled cores */ - -/* F3xDC Clock Power/Timing Control 2 Register */ -#define CPTC2 0xdc /* Clock Power/Timing Control2 Register*/ -#define PS_MAX_VAL_POS 8 /* PstateMaxValue bit shift */ -#define PS_MAX_VAL_MASK 0xfffff8ff /* PstateMaxValue Mask off */ -#define NB_SYN_PTR_ADJ_POS 12 /* NbsynPtrAdj bit shift */ -#define NB_SYN_PTR_ADJ_MASK (0x7 << NB_SYN_PTR_ADJ_POS) /* NbsynPtrAdj bit mask */ - -#define PRCT_INFO 0x1fc /* Product Info Register */ -#define DUAL_PLANE_ONLY_MASK 0x80000000 /* F3x1FC[DualPlaneOnly] */ -#define UNI_NB_FID_BIT 2 /* UniNbFid bit position */ -#define UNI_NB_VID_BIT 7 /* UniNbVid bit position */ -#define SPLT_NB_FID_OFFSET 14 /* SpltNbFidOffset value bit position */ -#define SPLT_NB_VID_OFFSET 17 /* SpltNbVidOffset value bit position */ -#define NB_CV_UPDATE 0x01 /* F3x1FC[NbCofVidUpdated] bit mask */ -#define NB_VID_UPDATE_ALL 0x02 /* F3x1FC[NbVidUpdatedAll] bit mask */ -#define C_FID_DID_M_OFF 0xfffffe00 /* mask off Core FID & DID */ - -#define CPB_MASK 0x00000020 /* core performance - boost. CPUID Fn8000 0007 edx */ -#define NC_MASK 0x000000FF /* number of cores - 1. CPUID - Fn8000 0008 ecx */ -#define PW_CTL_MISC 0x0a0 /* Power Control Miscellaneous Register */ -#define COF_VID_PROG_BIT 0x80000000 /* CofVidProg bit. 0= unfused part */ -#define DUAL_VDD_BIT 0x40000000 /* DualVdd bit. */ -#define NB_COFVID_UPDATE_BIT 0x01 /* NbCOFVIDUpdated bit */ -#define PVI_MODE 0x100 /* PviMode bit mask */ -#define VID_SLAM_OFF 0x0dfffffff /* set VidSlamMode OFF */ -#define VID_SLAM_ON 0x020000000 /* set VidSlamMode ON */ -#define NB_PSTATE_FORCE_ON 0x010000000 /* set Northbridge P-state - force on next LDTSTOP - assertion on, in F3xA0 */ -#define BP_INS_TRI_EN_ON 0x00004000 /* breakpoint pins tristate - enable in F3xA0 */ -#define PLLLOCK_OFF 0x0ffffc7ff /* PllLockTime Mask OFF */ -#define PLLLOCK_DFT 0x00001800 /* PllLockTime default value = 011b */ -#define PLLLOCK_DFT_L 0x00002800 /* PllLockTime long value = 101b */ - -#define SVI_HIGH_FREQ_ON 0x00000200 /* F3xA0[SviHighFreqSel] for - 3.4 MHz SVI in rev. C3 */ - -/* P-state Specification register base in PCI space */ -#define PS_SPEC_REG 0x1e0 /* PS Spec register base address */ -#define PCI_REG_LEN 4 /* PCI register length */ -#define NB_DID_MASK 0x10000 /* NbDid bit mask */ -#define NB_DID_2 2 /* NbDid = 2 */ -#define NB_DID_1 1 /* NbDid = 1 */ -#define SPEC_PWRDIV_M_ON 0x06000000 /* PwrDiv mask on */ -#define SPEC_PWRVAL_M_ON 0x01e00000 /* PwrValue mask on */ -#define SPEC_PWRDIV_SHFT 25 /* PwrDiv shift */ -#define SPEC_PWRVAL_SHFT 17 /* PwrValue shift */ - -/* F4x1F4 Northbridge P-state spec register */ -#define NB_PS_SPEC_REG 0x1f4 /* Nb PS spec reg */ - -/* F3x1F0 Product Information Register */ -#define NB_PSTATE_MASK 0x00070000 /* NbPstate for CPU rev C3 */ - -/* F3x1FC Product Information Register */ -#define NB_COF_VID_UPDATE_MASK 1 /* for CPU rev <= C */ -#define SINGLE_PLANE_NB_FID_MASK 0x007c/* for CPU rev <= C */ -#define SINGLE_PLANE_NB_FID_SHIFT 2/* for CPU rev <= C */ -#define SINGLE_PLANE_NB_VID_MASK 0x3f80/* for CPU rev <= C */ -#define SINGLE_PLANE_NB_VID_SHIFT 7/* for CPU rev <= C */ - -#define DUAL_PLANE_NB_FID_OFF_MASK 0x001c000/* for CPU rev <= C */ -#define DUAL_PLANE_NB_FID_SHIFT 14/* for CPU rev <= C */ -#define DUAL_PLANE_NB_VID_OFF_MASK 0x3e0000/* for CPU rev <= C */ -#define DUAL_PLANE_NB_VID_SHIFT 17/* for CPU rev <= C */ - -#define NM_PS_REG (is_fam15h()?8:5) /* number of P-state MSR registers */ - -/* sFidVidInit.outFlags defines */ -#define PWR_CK_OK 0 /* System board check OK */ -#define PWR_CK_NO_PS 1 /* All P-state registers are over - the limit */ - -/* bit mask */ -#define BIT_MASK_1 0x1 -#define BIT_MASK_2 0x3 -#define BIT_MASK_3 0x7 -#define BIT_MASK_4 0x0f -#define BIT_MASK_5 0x1f -#define BIT_MASK_6 0x3f -#define BIT_MASK_7 0x7f -#define BIT_MASK_8 0x0ff - -/* VID Code */ -#define VID_1_100V 0x12 /* 1.100V */ -#define VID_1_175V 0x1E /* 1.175V */ - -/* Nb Fid Code */ -#define NB_FID_800M 0x00 /* 800MHz */ - -/* Nb DID Code */ -#define NB_DID_0 0 -#define NB_DID_1 1 - -/* GH Logical ID */ -#define GH_REV_A2 0x4 /* GH Rev A2 logical ID, Upper half */ - -#define TSC_FREQ_SEL_SHIFT 24 -#define TSC_FREQ_SEL_MASK (1 << TSC_FREQ_SEL_SHIFT) - -#define WAIT_PSTATE_TIMEOUT 80000000 /* 0.1 s , unit : 1.25 ns */ - -#endif diff --git a/src/northbridge/amd/amdht/AsPsNb.c b/src/northbridge/amd/amdht/AsPsNb.c deleted file mode 100644 index 70dbacfbab..0000000000 --- a/src/northbridge/amd/amdht/AsPsNb.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "comlib.h" -#include "AsPsDefs.h" -#include "AsPsNb.h" - -u8 getNumOfNodeNb(void); -u8 translateNodeIdToDeviceIdNb(u8 nodeId); - -/** - * Return the minimum possible NbCOF (in 100MHz) for the system. - * - * This function can be run on any core and is used by the HT & Memory init - * code in Phase 1. - * - * @return minNbCOF (in multiple of half of CLKIN, 100MHz). - */ -u8 getMinNbCOF(void) -{ - u8 numOfNode, i, j, deviceId, nbDid, nbFid, nextNbFid; - u32 dtemp; - - nbDid = 0; - nbFid = 0; - - /* get number of node in the system */ - numOfNode = getNumOfNodeNb(); - - /* go through each node for the minimum NbCOF (in multiple of CLKIN/2) */ - for (i = 0; i < numOfNode; i++) - { - /* stub function for APIC ID virtualization for large MP system later */ - deviceId = translateNodeIdToDeviceIdNb(i); - - /* read all P-state spec registers for NbDid = 1 */ - for (j = 0; j < 5; j++) - { - AmdPCIRead(MAKE_SBDFO(0,0,deviceId,FN_4,PS_SPEC_REG+(j*PCI_REG_LEN)), &dtemp); /*F4x1E0 + j*4 */ - /* get NbDid */ - if (dtemp & NB_DID_MASK) - nbDid = 1; - } - /* if F3x1FC[NbCofVidUpdate]=0, NbFid = default value */ - AmdPCIRead(MAKE_SBDFO(0,0,deviceId,FN_3,PRCT_INFO), &dtemp); /*F3x1FC*/ - if (!(dtemp & NB_CV_UPDATE)) /* F3x1FC[NbCofVidUpdated]=0, use default VID */ - { - AmdPCIRead(MAKE_SBDFO(0,0,deviceId,FN_3,CPTC0), &dtemp); /*F3xD4*/ - nextNbFid = (u8) (dtemp & BIT_MASK_5); - if (nbDid) - nextNbFid = (u8) (nextNbFid >> 1); - } - else - { - /* check PVI/SPI */ - AmdPCIRead(MAKE_SBDFO(0,0,deviceId,FN_3,PW_CTL_MISC), &dtemp); /*F3xA0*/ - if (dtemp & PVI_MODE) /* PVI */ - { - AmdPCIRead(MAKE_SBDFO(0,0,deviceId,FN_3,PRCT_INFO), &dtemp); /*F3x1FC*/ - nextNbFid = (u8) (dtemp >> UNI_NB_FID_BIT); - nextNbFid &= BIT_MASK_5; - /* if (nbDid) - nextNbFid = nextNbFid >> 1; */ - } - else /* SVI */ - { - AmdPCIRead(MAKE_SBDFO(0,0,deviceId,FN_3,PRCT_INFO), &dtemp); /*F3x1FC*/ - nextNbFid = (u8) ((dtemp >> UNI_NB_FID_BIT) & BIT_MASK_5); - nextNbFid = (u8) (nextNbFid + ((dtemp >> SPLT_NB_FID_OFFSET) & BIT_MASK_3)); - /* if (nbDid) - nextNbFid = nextNbFid >> 1; */ - } - } - if (i == 0) - nbFid = nextNbFid; - else if (nbFid > nextNbFid) - nbFid = nextNbFid; - } - - /* add the base and convert to 100MHz divide by 2 if DID = 1 */ - if (nbDid) - nbFid = (u8) (nbFid + 4); - else - nbFid = (u8) ((nbFid + 4) << 1); - return nbFid; -} - -u8 getNumOfNodeNb(void) -{ - u32 dtemp; - - AmdPCIRead(MAKE_SBDFO(0,0,24,0,0x60), &dtemp); - dtemp = (dtemp >> 4) & BIT_MASK_3; - dtemp++; - return (u8)dtemp; -} - -/** - * Return the PCI device ID for PCI access using node ID. - * - * This function may need to change node ID to device ID in big MP systems. - * - * @param nodeId Node ID of the node. - * @return PCI device ID of the node. - */ -u8 translateNodeIdToDeviceIdNb(u8 nodeId) -{ - return (u8) (nodeId+PCI_DEV_BASE); -} diff --git a/src/northbridge/amd/amdht/AsPsNb.h b/src/northbridge/amd/amdht/AsPsNb.h deleted file mode 100644 index 35008920fe..0000000000 --- a/src/northbridge/amd/amdht/AsPsNb.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - - -#ifndef ASPSNB_H -#define ASPSNB_H - -u8 getMinNbCOF(void); - -#endif diff --git a/src/northbridge/amd/amdht/Makefile.inc b/src/northbridge/amd/amdht/Makefile.inc deleted file mode 100644 index 0b33352e7c..0000000000 --- a/src/northbridge/amd/amdht/Makefile.inc +++ /dev/null @@ -1,5 +0,0 @@ -ifeq ($(CONFIG_NORTHBRIDGE_AMD_AMDFAM10),y) - -romstage-y += h3finit.c ht_wrapper.c comlib.c AsPsNb.c h3ncmn.c - -endif diff --git a/src/northbridge/amd/amdht/comlib.c b/src/northbridge/amd/amdht/comlib.c deleted file mode 100644 index 883f634c74..0000000000 --- a/src/northbridge/amd/amdht/comlib.c +++ /dev/null @@ -1,238 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "comlib.h" - -#include <device/pci.h> -#include <device/pci_ops.h> -#include <cpu/amd/msr.h> -#include <device/pci_def.h> - - -/* - *--------------------------------------------------------------------------- - * EXPORTED FUNCTIONS - * - *--------------------------------------------------------------------------- - */ - -void CALLCONV AmdPCIReadBits(SBDFO loc, u8 highbit, u8 lowbit, u32 *pValue) -{ - ASSERT(highbit < 32 && lowbit < 32 && highbit >= lowbit && (loc & 3) == 0); - - AmdPCIRead(loc, pValue); - *pValue = *pValue >> lowbit; /* Shift */ - - /* A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case */ - if ((highbit-lowbit) != 31) - *pValue &= (((u32)1 << (highbit-lowbit+1))-1); -} - - -void CALLCONV AmdPCIWriteBits(SBDFO loc, u8 highbit, u8 lowbit, u32 *pValue) -{ - u32 temp, mask; - - ASSERT(highbit < 32 && lowbit < 32 && highbit >= lowbit && (loc & 3) == 0); - - /* A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case */ - if ((highbit-lowbit) != 31) - mask = (((u32)1 << (highbit-lowbit+1))-1); - else - mask = (u32)0xFFFFFFFF; - - AmdPCIRead(loc, &temp); - temp &= ~(mask << lowbit); - temp |= (*pValue & mask) << lowbit; - AmdPCIWrite(loc, &temp); -} - - -/* - * Given a SBDFO this routine will find the next PCI capabilities list entry. - * If the end of the list of reached, or if a problem is detected, then - * ILLEGAL_SBDFO is returned. - * - * To start a new search from the beginning of head of the list, specify a - * SBDFO with a offset of zero. - */ -void CALLCONV AmdPCIFindNextCap(SBDFO *pCurrent) -{ - SBDFO base; - u32 offset; - u32 temp; - - if (*pCurrent == ILLEGAL_SBDFO) - return; - - offset = SBDFO_OFF(*pCurrent); - base = *pCurrent - offset; - *pCurrent = ILLEGAL_SBDFO; - - /* Verify that the SBDFO points to a valid PCI device SANITY CHECK */ - AmdPCIRead(base, &temp); - if (temp == 0xFFFFFFFF) - return; /* There is no device at this address */ - - /* Verify that the device supports a capability list */ - AmdPCIReadBits(base + 0x04, 20, 20, &temp); - if (temp == 0) - return; /* This PCI device does not support capability lists */ - - if (offset != 0) - { - /* If we are continuing on an existing list */ - AmdPCIReadBits(base + offset, 15, 8, &temp); - } - else - { - /* We are starting on a new list */ - AmdPCIReadBits(base + 0x34, 7, 0, &temp); - } - - if (temp == 0) - return; /* We have reached the end of the capabilties list */ - - /* Error detection and recovery- The statement below protects against - PCI devices with broken PCI capabilities lists. Detect a pointer - that is not u32 aligned, points into the first 64 reserved DWORDs - or points back to itself. - */ - if (((temp & 3) != 0) || (temp == offset) || (temp < 0x40)) - return; - - *pCurrent = base + temp; - return; -} - - -void CALLCONV Amdmemcpy(void *pDst, const void *pSrc, u32 length) -{ - ASSERT(length <= 32768); - ASSERT(pDst != NULL); - ASSERT(pSrc != NULL); - - while (length--) { - // *(((u8*)pDst)++) = *(((u8*)pSrc)++); - *((u8*)pDst) = *((u8*)pSrc); - pDst++; - pSrc++; - } -} - - -void CALLCONV Amdmemset(void *pBuf, u8 val, u32 length) -{ - ASSERT(length <= 32768); - ASSERT(pBuf != NULL); - - while (length--) { - //*(((u8*)pBuf)++) = val; - *(((u8*)pBuf)) = val; - pBuf++; - } -} - - -u8 CALLCONV AmdBitScanReverse(u32 value) -{ - u8 i; - - for (i = 31; i != 0xFF; i--) - { - if (value & ((u32)1 << i)) - break; - } - - return i; -} - - -u32 CALLCONV AmdRotateRight(u32 value, u8 size, u32 count) -{ - u32 msb, mask; - ASSERT(size > 0 && size <= 32); - - msb = (u32)1 << (size-1); - mask = ((msb-1) << 1) + 1; - - value = value & mask; - - while (count--) - { - if (value & 1) - value = (value >> 1) | msb; - else - value = value >> 1; - } - - return value; -} - - -u32 CALLCONV AmdRotateLeft(u32 value, u8 size, u32 count) -{ - u32 msb, mask; - ASSERT(size > 0 && size <= 32); - - msb = (u32)1 << (size-1); - mask = ((msb-1) << 1) + 1; - - value = value & mask; - - while (count--) - { - if (value & msb) - value = ((value << 1) & mask) | (u32)1; - else - value = ((value << 1) & mask); - } - - return value; -} - - -void CALLCONV AmdPCIRead(SBDFO loc, u32 *Value) -{ - /* Use coreboot PCI functions */ - *Value = pci_read_config32((loc & 0xFFFFF000), SBDFO_OFF(loc)); -} - - -void CALLCONV AmdPCIWrite(SBDFO loc, u32 *Value) -{ - /* Use coreboot PCI functions */ - pci_write_config32((loc & 0xFFFFF000), SBDFO_OFF(loc), *Value); -} - - -void CALLCONV AmdMSRRead(uint32 Address, uint64 *Value) -{ - msr_t msr; - - msr = rdmsr(Address); - Value->lo = msr.lo; - Value->hi = msr.hi; -} - - -void CALLCONV AmdMSRWrite(uint32 Address, uint64 *Value) -{ - msr_t msr; - - msr.lo = Value->lo; - msr.hi = Value->hi; - wrmsr(Address, msr); -} diff --git a/src/northbridge/amd/amdht/comlib.h b/src/northbridge/amd/amdht/comlib.h deleted file mode 100644 index 98326b280f..0000000000 --- a/src/northbridge/amd/amdht/comlib.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef COMLIB_H -#define COMLIB_H - -#include <assert.h> -#include <stdint.h> -#include <stdlib.h> -#include "porting.h" - -#ifdef AMD_DEBUG_ERROR_STOP - /* Macro to aid debugging, causes program to halt and display the line number of the halt */ - #define STOP_HERE ASSERT(0) -#else - #define STOP_HERE -#endif - -void CALLCONV AmdPCIReadBits(SBDFO loc, uint8 highbit, uint8 lowbit, uint32 *value); -void CALLCONV AmdPCIWriteBits(SBDFO loc, uint8 highbit, uint8 lowbit, uint32 *value); -void CALLCONV AmdPCIFindNextCap(SBDFO *current); - -void CALLCONV Amdmemcpy(void *dst, const void *src, uint32 length); -void CALLCONV Amdmemset(void *buf, uint8 val, uint32 length); - -uint8 CALLCONV AmdBitScanReverse(uint32 value); -uint32 CALLCONV AmdRotateRight(uint32 value, uint8 size, uint32 count); -uint32 CALLCONV AmdRotateLeft(uint32 value, uint8 size, uint32 count); - -#endif diff --git a/src/northbridge/amd/amdht/h3ffeat.h b/src/northbridge/amd/amdht/h3ffeat.h deleted file mode 100644 index 2cf4bd1a1c..0000000000 --- a/src/northbridge/amd/amdht/h3ffeat.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007-2008 Advanced Micro Devices, Inc. - * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - - -#ifndef H3FFEAT_H -#define H3FFEAT_H - -#include "h3finit.h" - -/*---------------------------------------------------------------------------- - * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) - * - *---------------------------------------------------------------------------- - */ - -/*----------------------------------------------------------------------------- - * DEFINITIONS AND MACROS - * - *----------------------------------------------------------------------------- - */ - -#define MAX_NODES 8 -#define MAX_LINKS 8 -#define MAX_PLATFORM_LINKS 64 /* 8x8 fully connected (28) + 4 chains with two HT devices */ - -/* These following are internal definitions */ -#define ROUTETOSELF 0x0F -#define INVALID_LINK 0xCC /* Used in port list data structure to mark unused data entries. - Can also be used for no link found in a port list search */ - -/* definitions for working with the port list structure */ -#define PORTLIST_TYPE_CPU 0 -#define PORTLIST_TYPE_IO 1 - -/* - * Hypertransport Capability definitions and macros - * - */ - -/* HT Host Capability */ -/* bool isHTHostCapability(u32 reg) */ -#define IS_HT_HOST_CAPABILITY(reg) \ - ((reg & (u32)0xE00000FF) == (u32)0x20000008) - -#define HT_HOST_CAP_SIZE 0x20 - -/* Host CapabilityRegisters */ -#define HTHOST_LINK_CAPABILITY_REG 0x00 -#define HTHOST_LINK_CONTROL_REG 0x04 -#define HTHOST_FREQ_REV_REG 0x08 -#define HTHOST_FREQ_REV_REG_2 0x1c - #define HT_HOST_REV_REV3 0x60 -#define HTHOST_FEATURE_CAP_REG 0x0C -#define HTHOST_BUFFER_COUNT_REG 0x10 -#define HTHOST_ISOC_REG 0x14 -#define HTHOST_LINK_TYPE_REG 0x18 - #define HTHOST_TYPE_COHERENT 3 - #define HTHOST_TYPE_NONCOHERENT 7 - #define HTHOST_TYPE_MASK 0x1F - -/* HT Slave Capability (HT1 compat) */ -#define IS_HT_SLAVE_CAPABILITY(reg) \ - ((reg & (u32)0xE00000FF) == (u32)0x00000008) -#define HTSLAVE_LINK01_OFFSET 4 -#define HTSLAVE_LINK_CONTROL_0_REG 4 -#define HTSLAVE_FREQ_REV_0_REG 0xC -#define HTSLAVE_FEATURE_CAP_REG 0x10 - -/* HT3 gen Capability */ -#define IS_HT_GEN3_CAPABILITY(reg) \ - ((reg & (u32)0xF80000FF) == (u32)0xD0000008) -#define HTGEN3_LINK01_OFFSET 0x10 -#define HTGEN3_LINK_TRAINING_0_REG 0x10 - -/* HT3 Retry Capability */ -#define IS_HT_RETRY_CAPABILITY(reg) \ - ((reg & (u32)0xF80000FF) == (u32)0xC0000008) - -#define HTRETRY_CONTROL_REG 4 - -/* Unit ID Clumping Capability */ -#define IS_HT_UNITID_CAPABILITY(reg) \ - ((reg & (u32)0xF80000FF) == (u32)0x90000008) - -#define HTUNIT_SUPPORT_REG 4 -#define HTUNIT_ENABLE_REG 8 - -/*---------------------------------------------------------------------------- - * TYPEDEFS, STRUCTURES, ENUMS - * - *---------------------------------------------------------------------------- - */ - -typedef struct cNorthBridge cNorthBridge; - -/* A pair consists of a source node, a link to the destination node, the - * destination node, and its link back to source node. The even indices are - * the source nodes and links, and the odd indices are for the destination - * nodes and links. - */ -typedef struct -{ - /* This section is where the link is in the system and how to find it */ - u8 Type; /* 0 = CPU, 1 = Device, all others reserved */ - u8 Link; /* 0-1 for devices, 0-7 for CPUs */ - u8 NodeID; /* The node, or a pointer to the devices parent node */ - u8 HostLink, HostDepth; /* Link of parent node + depth in chain. Only used by devices */ - SBDFO Pointer; /* A pointer to the device's slave HT capability, so we don't have to keep searching */ - - /* This section is for the final settings, which are written to hardware */ - BOOL SelRegang; /* Only used for CPU->CPU links */ - u8 SelWidthIn; - u8 SelWidthOut; - u8 SelFrequency; - uint8_t enable_isochronous_mode; - - /* This section is for keeping track of capabilities and possible configurations */ - BOOL RegangCap; - uint32_t PrvFrequencyCap; - uint32_t PrvFeatureCap; - u8 PrvWidthInCap; - u8 PrvWidthOutCap; - uint32_t CompositeFrequencyCap; - -} sPortDescriptor; - - -/* - * Our global state data structure - */ -typedef struct { - AMD_HTBLOCK *HtBlock; - - u8 NodesDiscovered; /* One less than the number of nodes found in the system */ - u8 TotalLinks; - u8 sysMpCap; /* The maximum number of nodes that all processors are capable of */ - - /* Two ports for each link - * Note: The Port pair 2*N and 2*N+1 are connected together to form a link - * (e.g. 0,1 and 8,9 are ports on either end of an HT link) The lower number - * port (2*N) is the source port. The device that owns the source port is - * always the device closer to the BSP. (i.e. nearer the CPU in a - * non-coherent chain, or the CPU with the lower NodeID). - */ - sPortDescriptor PortList[MAX_PLATFORM_LINKS*2]; - - /* The number of coherent links coming off of each node (i.e. the 'Degree' of the node) */ - u8 sysDegree[MAX_NODES]; - /* The systems adjency (sysMatrix[i][j] is true if Node_i has a link to Node_j) */ - BOOL sysMatrix[MAX_NODES][MAX_NODES]; - - /* Same as above, but for the currently selected database entry */ - u8 dbDegree[MAX_NODES]; - BOOL dbMatrix[MAX_NODES][MAX_NODES]; - - u8 Perm[MAX_NODES]; /* The node mapping from the database to the system */ - u8 ReversePerm[MAX_NODES]; /* The node mapping from the system to the database */ - - /* Data for non-coherent initialization */ - u8 AutoBusCurrent; - u8 UsedCfgMapEntires; - - /* 'This' pointer for northbridge */ - cNorthBridge *nb; -} sMainData; - -#endif /* H3FFEAT_H */ diff --git a/src/northbridge/amd/amdht/h3finit.c b/src/northbridge/amd/amdht/h3finit.c deleted file mode 100644 index cda0a28cef..0000000000 --- a/src/northbridge/amd/amdht/h3finit.c +++ /dev/null @@ -1,1879 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -/* - *---------------------------------------------------------------------------- - * MODULES USED - * - *---------------------------------------------------------------------------- - */ - -#include "h3finit.h" -#include "h3ffeat.h" -#include "h3ncmn.h" -#include "h3gtopo.h" -#include "AsPsNb.h" - -#include <arch/cpu.h> -#include <device/pci.h> -#include <device/pci_ops.h> -#include <console/console.h> -#include <cpu/x86/lapic_def.h> -#include <cpu/amd/msr.h> -#include <device/pci_def.h> -#include <northbridge/amd/amdfam10/raminit.h> -#include <northbridge/amd/amdfam10/amdfam10.h> -#include <types.h> - -/*---------------------------------------------------------------------------- - * DEFINITIONS AND MACROS - * - *---------------------------------------------------------------------------- - */ - -#define NVRAM_LIMIT_HT_SPEED_200 0x12 -#define NVRAM_LIMIT_HT_SPEED_300 0x11 -#define NVRAM_LIMIT_HT_SPEED_400 0x10 -#define NVRAM_LIMIT_HT_SPEED_500 0xf -#define NVRAM_LIMIT_HT_SPEED_600 0xe -#define NVRAM_LIMIT_HT_SPEED_800 0xd -#define NVRAM_LIMIT_HT_SPEED_1000 0xc -#define NVRAM_LIMIT_HT_SPEED_1200 0xb -#define NVRAM_LIMIT_HT_SPEED_1400 0xa -#define NVRAM_LIMIT_HT_SPEED_1600 0x9 -#define NVRAM_LIMIT_HT_SPEED_1800 0x8 -#define NVRAM_LIMIT_HT_SPEED_2000 0x7 -#define NVRAM_LIMIT_HT_SPEED_2200 0x6 -#define NVRAM_LIMIT_HT_SPEED_2400 0x5 -#define NVRAM_LIMIT_HT_SPEED_2600 0x4 -#define NVRAM_LIMIT_HT_SPEED_2800 0x3 -#define NVRAM_LIMIT_HT_SPEED_3000 0x2 -#define NVRAM_LIMIT_HT_SPEED_3200 0x1 -#define NVRAM_LIMIT_HT_SPEED_AUTO 0x0 - -static const uint32_t ht_speed_limit[20] = - {0xFFFFF, 0xFFFFF, 0x7FFFF, 0x3FFFF, - 0x0FFFF, 0x07FFF, 0x03FFF, 0x01FFF, - 0x00FFF, 0x007FF, 0x003FF, 0x001FF, - 0x000FF, 0x0007F, 0x0003F, 0x0001F, - 0x0000F, 0x00007, 0x00003, 0x00001}; - -static const struct ht_speed_limit_map_t { - uint16_t mhz; - uint8_t nvram; -} ht_speed_limit_map[] = { - {0, NVRAM_LIMIT_HT_SPEED_AUTO}, - {200, NVRAM_LIMIT_HT_SPEED_200}, - {300, NVRAM_LIMIT_HT_SPEED_300}, - {400, NVRAM_LIMIT_HT_SPEED_400}, - {500, NVRAM_LIMIT_HT_SPEED_500}, - {600, NVRAM_LIMIT_HT_SPEED_600}, - {800, NVRAM_LIMIT_HT_SPEED_800}, - {1000, NVRAM_LIMIT_HT_SPEED_1000}, - {1200, NVRAM_LIMIT_HT_SPEED_1200}, - {1400, NVRAM_LIMIT_HT_SPEED_1400}, - {1600, NVRAM_LIMIT_HT_SPEED_1600}, - {1800, NVRAM_LIMIT_HT_SPEED_1800}, - {2000, NVRAM_LIMIT_HT_SPEED_2000}, - {2200, NVRAM_LIMIT_HT_SPEED_2200}, - {2400, NVRAM_LIMIT_HT_SPEED_2400}, - {2600, NVRAM_LIMIT_HT_SPEED_2600}, - {2800, NVRAM_LIMIT_HT_SPEED_2800}, - {3000, NVRAM_LIMIT_HT_SPEED_3000}, - {3200, NVRAM_LIMIT_HT_SPEED_3200}, -}; - -static const uint32_t ht_speed_mhz_to_hw(uint16_t mhz) -{ - size_t i; - for (i = 0; i < ARRAY_SIZE(ht_speed_limit_map); i++) - if (ht_speed_limit_map[i].mhz == mhz) - return ht_speed_limit[ht_speed_limit_map[i].nvram]; - - printk(BIOS_WARNING, - "WARNING: Invalid HT link limit frequency %d specified, ignoring...\n", - mhz); - return ht_speed_limit[NVRAM_LIMIT_HT_SPEED_AUTO]; -} - -/*---------------------------------------------------------------------------- - * TYPEDEFS AND STRUCTURES - * - *---------------------------------------------------------------------------- - */ - -/*---------------------------------------------------------------------------- - * PROTOTYPES OF LOCAL FUNCTIONS - * - *---------------------------------------------------------------------------- - */ - -/*---------------------------------------------------------------------------- - * EXPORTED FUNCTIONS - * - *---------------------------------------------------------------------------- - */ - -/*---------------------------------------------------------------------------- - * LOCAL FUNCTIONS - * - *---------------------------------------------------------------------------- - */ -#ifndef HT_BUILD_NC_ONLY -/* - ************************************************************************** - * Routing table decompressor - ************************************************************************** - */ - -/* - ************************************************************************** - * Graph Support routines - * These routines provide support for dealing with the graph representation - * of the topologies, along with the routing table information for that topology. - * The routing information is compressed and these routines currently decompress - * 'on the fly'. A graph is represented as a set of routes. All the edges in the - * graph are routes; a direct route from node i to node j exists in the graph IFF - * there is an edge directly connecting node i to node j. All other routes designate - * the edge which the route to that node initially takes, by designating a node - * to which a direct connection exists. That is, the route to non-adjacent node j - * from node i specifies node k where node i directly connects to node k. - * - * - * pseudo definition of compressed graph: - * typedef struct - * { - * BIT broadcast[8]; - * uint4 responseRoute; - * uint4 requestRoute; - * } sRoute; - * typedef struct - * { - * u8 size; - * sRoute graph[size][size]; - * } sGraph; - * - ************************************************************************** - */ - -/*---------------------------------------------------------------------------------------- - * u8 - * graphHowManyNodes(u8 *graph) - * - * Description: - * Returns the number of nodes in the compressed graph - * - * Parameters: - * @param[in] graph = a compressed graph - * @param[out] results = the number of nodes in the graph - * --------------------------------------------------------------------------------------- - */ -static u8 graphHowManyNodes(u8 *graph) -{ - return graph[0]; -} - -/*---------------------------------------------------------------------------------------- - * BOOL - * graphIsAdjacent(u8 *graph, u8 nodeA, u8 nodeB) - * - * Description: - * Returns true if NodeA is directly connected to NodeB, false otherwise - * (if NodeA == NodeB also returns false) - * Relies on rule that directly connected nodes always route requests directly. - * - * Parameters: - * @param[in] graph = the graph to examine - * @param[in] nodeA = the node number of the first node - * @param[in] nodeB = the node number of the second node - * @param[out] results = true if nodeA connects to nodeB false if not - * --------------------------------------------------------------------------------------- - */ -static BOOL graphIsAdjacent(u8 *graph, u8 nodeA, u8 nodeB) -{ - u8 size = graph[0]; - ASSERT(size <= MAX_NODES); - ASSERT((nodeA < size) && (nodeB < size)); - return (graph[1+(nodeA*size+nodeB)*2+1] & 0x0F) == nodeB; -} - -/*---------------------------------------------------------------------------------------- - * u8 - * graphGetRsp(u8 *graph, u8 nodeA, u8 nodeB) - * - * Description: - * Returns the graph node used by nodeA to route responses targeted at nodeB. - * This will be a node directly connected to nodeA (possibly nodeB itself), - * or "Route to Self" if nodeA and nodeB are the same node. - * Note that all node numbers are abstract node numbers of the topology graph, - * it is the responsibility of the caller to apply any permutation needed. - * - * Parameters: - * @param[in] u8 graph = the graph to examine - * @param[in] u8 nodeA = the node number of the first node - * @param[in] u8 nodeB = the node number of the second node - * @param[out] u8 results = The response route node - * --------------------------------------------------------------------------------------- - */ -static u8 graphGetRsp(u8 *graph, u8 nodeA, u8 nodeB) -{ - u8 size = graph[0]; - ASSERT(size <= MAX_NODES); - ASSERT((nodeA < size) && (nodeB < size)); - return (graph[1+(nodeA*size+nodeB)*2+1] & 0xF0)>>4; -} - -/*---------------------------------------------------------------------------------------- - * u8 - * graphGetReq(u8 *graph, u8 nodeA, u8 nodeB) - * - * Description: - * Returns the graph node used by nodeA to route requests targeted at nodeB. - * This will be a node directly connected to nodeA (possibly nodeB itself), - * or "Route to Self" if nodeA and nodeB are the same node. - * Note that all node numbers are abstract node numbers of the topology graph, - * it is the responsibility of the caller to apply any permutation needed. - * - * Parameters: - * @param[in] graph = the graph to examine - * @param[in] nodeA = the node number of the first node - * @param[in] nodeB = the node number of the second node - * @param[out] results = The request route node - * --------------------------------------------------------------------------------------- - */ -static u8 graphGetReq(u8 *graph, u8 nodeA, u8 nodeB) -{ - u8 size = graph[0]; - ASSERT(size <= MAX_NODES); - ASSERT((nodeA < size) && (nodeB < size)); - return (graph[1+(nodeA*size+nodeB)*2+1] & 0x0F); -} - -/*---------------------------------------------------------------------------------------- - * u8 - * graphGetBc(u8 *graph, u8 nodeA, u8 nodeB) - * - * Description: - * Returns a bit vector of nodes that nodeA should forward a broadcast from - * nodeB towards - * - * Parameters: - * @param[in] graph = the graph to examine - * @param[in] nodeA = the node number of the first node - * @param[in] nodeB = the node number of the second node - * OU results = the broadcast routes for nodeA from nodeB - * --------------------------------------------------------------------------------------- - */ -static u8 graphGetBc(u8 *graph, u8 nodeA, u8 nodeB) -{ - u8 size = graph[0]; - ASSERT(size <= MAX_NODES); - ASSERT((nodeA < size) && (nodeB < size)); - return graph[1+(nodeA*size+nodeB)*2]; -} - - -/*************************************************************************** - *** GENERIC HYPERTRANSPORT DISCOVERY CODE *** - ***************************************************************************/ - -/*---------------------------------------------------------------------------------------- - * void - * routeFromBSP(u8 targetNode, u8 actualTarget, sMainData *pDat) - * - * Description: - * Ensure a request / response route from target node to bsp. Since target node is - * always a predecessor of actual target node, each node gets a route to actual target - * on the link that goes to target. The routing produced by this routine is adequate - * for config access during discovery, but NOT for coherency. - * - * Parameters: - * @param[in] u8 targetNode = the path to actual target goes through target - * @param[in] u8 actualTarget = the ultimate target being routed to - * @param[in] sMainData* pDat = our global state, port config info - * --------------------------------------------------------------------------------------- - */ -static void routeFromBSP(u8 targetNode, u8 actualTarget, sMainData *pDat) -{ - u8 predecessorNode, predecessorLink, currentPair; - - if (targetNode == 0) - return; /* BSP has no predecessor, stop */ - - /* Search for the link that connects targetNode to its predecessor */ - currentPair = 0; - while (pDat->PortList[currentPair*2+1].NodeID != targetNode) - { - currentPair++; - ASSERT(currentPair < pDat->TotalLinks); - } - - predecessorNode = pDat->PortList[currentPair*2].NodeID; - predecessorLink = pDat->PortList[currentPair*2].Link; - - /* Recursively call self to ensure the route from the BSP to the Predecessor */ - /* Node is established */ - routeFromBSP(predecessorNode, actualTarget, pDat); - - pDat->nb->writeRoutingTable(predecessorNode, actualTarget, predecessorLink, pDat->nb); -} - -/*---------------------------------------------------------------------------*/ - -/** - * u8 - * convertNodeToLink(u8 srcNode, u8 targetNode, sMainData *pDat) - * - * Description: - * Return the link on source node which connects to target node - * - * Parameters: - * @param[in] srcNode = the source node - * @param[in] targetNode = the target node to find the link to - * @param[in] pDat = our global state - * @return the link on source which connects to target - * - */ -static u8 convertNodeToLink(u8 srcNode, u8 targetNode, sMainData *pDat) -{ - u8 targetlink = INVALID_LINK; - u8 k; - - for (k = 0; k < pDat->TotalLinks*2; k += 2) - { - if ((pDat->PortList[k+0].NodeID == srcNode) && (pDat->PortList[k+1].NodeID == targetNode)) - { - targetlink = pDat->PortList[k+0].Link; - break; - } - else if ((pDat->PortList[k+1].NodeID == srcNode) && (pDat->PortList[k+0].NodeID == targetNode)) - { - targetlink = pDat->PortList[k+1].Link; - break; - } - } - ASSERT(targetlink != INVALID_LINK); - - return targetlink; -} - - -/*---------------------------------------------------------------------------------------- - * void - * htDiscoveryFloodFill(sMainData *pDat) - * - * Description: - * Discover all coherent devices in the system, initializing some basics like node IDs - * and total nodes found in the process. As we go we also build a representation of the - * discovered system which we will use later to program the routing tables. During this - * step, the routing is via default link back to BSP and to each new node on the link it - * was discovered on (no coherency is active yet). - * - * Parameters: - * @param[in] sMainData* pDat = our global state - * --------------------------------------------------------------------------------------- - */ -static void htDiscoveryFloodFill(sMainData *pDat) -{ - uint8_t currentNode = 0; - uint8_t currentLink; - uint8_t currentLinkID; - - /* NOTE - * Each node inside a dual node (socket G34) processor must share - * an adjacent node ID. Alter the link scan order such that the - * other internal node is always scanned first... - */ - uint8_t currentLinkScanOrder_Default[8] = {0, 1, 2, 3, 4, 5, 6, 7}; - uint8_t currentLinkScanOrder_G34_Fam10[8] = {1, 0, 2, 3, 4, 5, 6, 7}; - uint8_t currentLinkScanOrder_G34_Fam15[8] = {2, 0, 1, 3, 4, 5, 6, 7}; - - uint8_t fam15h = 0; - uint8_t rev_gte_d = 0; - uint8_t dual_node = 0; - uint32_t f3xe8; - uint32_t family; - uint32_t model; - - f3xe8 = pci_read_config32(NODE_PCI(0, 3), 0xe8); - - family = model = cpuid_eax(0x80000001); - model = ((model & 0xf0000) >> 12) | ((model & 0xf0) >> 4); - family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8); - - if (family >= 0x6f) { - /* Family 15h or later */ - fam15h = 1; - } - - if ((model >= 0x8) || fam15h) - /* Revision D or later */ - rev_gte_d = 1; - - if (rev_gte_d) - /* Check for dual node capability */ - if (f3xe8 & 0x20000000) - dual_node = 1; - - /* Entries are always added in pairs, the even indices are the 'source' - * side closest to the BSP, the odd indices are the 'destination' side - */ - while (currentNode <= pDat->NodesDiscovered) - { - u32 temp; - - if (currentNode != 0) - { - /* Set path from BSP to currentNode */ - routeFromBSP(currentNode, currentNode, pDat); - - /* Set path from BSP to currentNode for currentNode+1 if - * currentNode+1 != MAX_NODES - */ - if (currentNode+1 != MAX_NODES) - routeFromBSP(currentNode, currentNode+1, pDat); - - /* Configure currentNode to route traffic to the BSP through its - * default link - */ - pDat->nb->writeRoutingTable(currentNode, 0, pDat->nb->readDefLnk(currentNode, pDat->nb), pDat->nb); - } - - /* Set currentNode's NodeID field to currentNode */ - pDat->nb->writeNodeID(currentNode, currentNode, pDat->nb); - - /* Enable routing tables on currentNode */ - pDat->nb->enableRoutingTables(currentNode, pDat->nb); - - for (currentLinkID = 0; currentLinkID < pDat->nb->maxLinks; currentLinkID++) - { - BOOL linkfound; - u8 token; - - if (currentLinkID < 8) { - if (dual_node) { - if (fam15h) - currentLink = currentLinkScanOrder_G34_Fam15[currentLinkID]; - else - currentLink = currentLinkScanOrder_G34_Fam10[currentLinkID]; - } else { - currentLink = currentLinkScanOrder_Default[currentLinkID]; - } - } else { - currentLink = currentLinkID; - } - - if (pDat->HtBlock->AMD_CB_IgnoreLink && pDat->HtBlock->AMD_CB_IgnoreLink(currentNode, currentLink)) - continue; - - if (pDat->nb->readTrueLinkFailStatus(currentNode, currentLink, pDat, pDat->nb)) - continue; - - /* Make sure that the link is connected, coherent, and ready */ - if (!pDat->nb->verifyLinkIsCoherent(currentNode, currentLink, pDat->nb)) - continue; - - - /* Test to see if the currentLink has already been explored */ - linkfound = FALSE; - for (temp = 0; temp < pDat->TotalLinks; temp++) - { - if ((pDat->PortList[temp*2+1].NodeID == currentNode) && - (pDat->PortList[temp*2+1].Link == currentLink)) - { - linkfound = TRUE; - break; - } - } - if (linkfound) - { - /* We had already expored this link */ - continue; - } - - if (pDat->nb->handleSpecialLinkCase(currentNode, currentLink, pDat, pDat->nb)) - { - continue; - } - - /* Modify currentNode's routing table to use currentLink to send - * traffic to currentNode+1 - */ - pDat->nb->writeRoutingTable(currentNode, currentNode+1, currentLink, pDat->nb); - - /* Check the northbridge of the node we just found, to make sure it is compatible - * before doing anything else to it. - */ - if (!pDat->nb->isCompatible(currentNode+1, pDat->nb)) - { - u8 nodeToKill; - - /* Notify BIOS of event (while variables are still the same) */ - if (pDat->HtBlock->AMD_CB_EventNotify) - { - sHtEventCohFamilyFeud evt; - evt.eSize = sizeof(sHtEventCohFamilyFeud); - evt.node = currentNode; - evt.link = currentLink; - evt.totalNodes = pDat->NodesDiscovered; - - pDat->HtBlock->AMD_CB_EventNotify(HT_EVENT_CLASS_ERROR, - HT_EVENT_COH_FAMILY_FEUD, - (u8 *)&evt); - } - - /* If node is not compatible, force boot to 1P - * If they are not compatible stop cHT init and: - * 1. Disable all cHT links on the BSP - * 2. Configure the BSP routing tables as a UP. - * 3. Notify main BIOS. - */ - pDat->NodesDiscovered = 0; - currentNode = 0; - pDat->TotalLinks = 0; - /* Abandon our coherent link data structure. At this point there may - * be coherent links on the BSP that are not yet in the portList, and - * we have to turn them off anyway. So depend on the hardware to tell us. - */ - for (currentLink = 0; currentLink < pDat->nb->maxLinks; currentLink++) - { - /* Stop all links which are connected, coherent, and ready */ - if (pDat->nb->verifyLinkIsCoherent(currentNode, currentLink, pDat->nb)) - pDat->nb->stopLink(currentNode, currentLink, pDat->nb); - } - - for (nodeToKill = 0; nodeToKill < pDat->nb->maxNodes; nodeToKill++) - { - pDat->nb->writeFullRoutingTable(0, nodeToKill, ROUTETOSELF, ROUTETOSELF, 0, pDat->nb); - } - - /* End Coherent Discovery */ - STOP_HERE; - break; - } - - /* Read token from Current+1 */ - token = pDat->nb->readToken(currentNode+1, pDat->nb); - ASSERT(token <= pDat->NodesDiscovered); - if (token == 0) - { - pDat->NodesDiscovered++; - ASSERT(pDat->NodesDiscovered < pDat->nb->maxNodes); - /* Check the capability of northbridges against the currently known configuration */ - if (!pDat->nb->isCapable(currentNode+1, pDat, pDat->nb)) - { - u8 nodeToKill; - - /* Notify BIOS of event */ - if (pDat->HtBlock->AMD_CB_EventNotify) - { - sHtEventCohMpCapMismatch evt; - evt.eSize = sizeof(sHtEventCohMpCapMismatch); - evt.node = currentNode; - evt.link = currentLink; - evt.sysMpCap = pDat->sysMpCap; - evt.totalNodes = pDat->NodesDiscovered; - - pDat->HtBlock->AMD_CB_EventNotify(HT_EVENT_CLASS_ERROR, - HT_EVENT_COH_MPCAP_MISMATCH, - (u8 *)&evt); - } - - pDat->NodesDiscovered = 0; - currentNode = 0; - pDat->TotalLinks = 0; - - for (nodeToKill = 0; nodeToKill < pDat->nb->maxNodes; nodeToKill++) - { - pDat->nb->writeFullRoutingTable(0, nodeToKill, ROUTETOSELF, ROUTETOSELF, 0, pDat->nb); - } - - /* End Coherent Discovery */ - STOP_HERE; - break; - } - - token = pDat->NodesDiscovered; - pDat->nb->writeToken(currentNode+1, token, pDat->nb); - /* Inform that we have discovered a node, so that logical id to - * socket mapping info can be recorded. - */ - if (pDat->HtBlock->AMD_CB_EventNotify) - { - sHtEventCohNodeDiscovered evt; - evt.eSize = sizeof(sHtEventCohNodeDiscovered); - evt.node = currentNode; - evt.link = currentLink; - evt.newNode = token; - - pDat->HtBlock->AMD_CB_EventNotify(HT_EVENT_CLASS_INFO, - HT_EVENT_COH_NODE_DISCOVERED, - (u8 *)&evt); - } - } - - if (pDat->TotalLinks == MAX_PLATFORM_LINKS) - { - /* - * Exceeded our capacity to describe all coherent links found in the system. - * Error strategy: - * Auto recovery is not possible because data space is already all used. - * If the callback is not implemented or returns we will continue to initialize - * the fabric we are capable of representing, adding no more nodes or links. - * This should yield a bootable topology, but likely not the one intended. - * We cannot continue discovery, there may not be any way to route a new - * node back to the BSP if we can't add links to our representation of the system. - */ - if (pDat->HtBlock->AMD_CB_EventNotify) - { - sHtEventCohLinkExceed evt; - evt.eSize = sizeof(sHtEventCohLinkExceed); - evt.node = currentNode; - evt.link = currentLink; - evt.targetNode = token; - evt.totalNodes = pDat->NodesDiscovered; - evt.maxLinks = pDat->nb->maxLinks; - - pDat->HtBlock->AMD_CB_EventNotify(HT_EVENT_CLASS_ERROR, - HT_EVENT_COH_LINK_EXCEED, - (u8 *)&evt); - } - /* Force link and node loops to halt */ - STOP_HERE; - currentNode = pDat->NodesDiscovered; - break; - } - - pDat->PortList[pDat->TotalLinks*2].Type = PORTLIST_TYPE_CPU; - pDat->PortList[pDat->TotalLinks*2].Link = currentLink; - pDat->PortList[pDat->TotalLinks*2].NodeID = currentNode; - - pDat->PortList[pDat->TotalLinks*2+1].Type = PORTLIST_TYPE_CPU; - pDat->PortList[pDat->TotalLinks*2+1].Link = pDat->nb->readDefLnk(currentNode+1, pDat->nb); - pDat->PortList[pDat->TotalLinks*2+1].NodeID = token; - - pDat->TotalLinks++; - - if (!pDat->sysMatrix[currentNode][token]) - { - pDat->sysDegree[currentNode]++; - pDat->sysDegree[token]++; - pDat->sysMatrix[currentNode][token] = TRUE; - pDat->sysMatrix[token][currentNode] = TRUE; - } - } - currentNode++; - } -} - - -/*************************************************************************** - *** ISOMORPHISM BASED ROUTING TABLE GENERATION CODE *** - ***************************************************************************/ - -/*---------------------------------------------------------------------------------------- - * BOOL - * isoMorph(u8 i, sMainData *pDat) - * - * Description: - * Is graphA isomorphic to graphB? - * if this function returns true, then Perm will contain the permutation - * required to transform graphB into graphA. - * We also use the degree of each node, that is the number of connections it has, to - * speed up rejection of non-isomorphic graphs (if there is a node in graphA with n - * connections, there must be at least one unmatched in graphB with n connections). - * - * Parameters: - * @param[in] u8 i = the discovered node which we are trying to match - * with a permutation the topology - * @param[in]/@param[out] sMainData* pDat = our global state, degree and adjacency matrix, - * output a permutation if successful - * @param[out] BOOL results = the graphs are (or are not) isomorphic - * --------------------------------------------------------------------------------------- - */ -static BOOL isoMorph(u8 i, sMainData *pDat) -{ - u8 j, k; - u8 nodecnt; - - /* We have only been called if nodecnt == pSelected->size ! */ - nodecnt = pDat->NodesDiscovered+1; - - if (i != nodecnt) - { - /* Keep building the permutation */ - for (j = 0; j < nodecnt; j++) - { - /* Make sure the degree matches */ - if (pDat->sysDegree[i] != pDat->dbDegree[j]) - continue; - - /* Make sure that j hasn't been used yet (ought to use a "used" */ - /* array instead, might be faster) */ - for (k = 0; k < i; k++) - { - if (pDat->Perm[k] == j) - break; - } - if (k != i) - continue; - pDat->Perm[i] = j; - if (isoMorph(i+1, pDat)) - return TRUE; - } - return FALSE; - } else { - /* Test to see if the permutation is isomorphic */ - for (j = 0; j < nodecnt; j++) - { - for (k = 0; k < nodecnt; k++) - { - if (pDat->sysMatrix[j][k] != - pDat->dbMatrix[pDat->Perm[j]][pDat->Perm[k]]) - return FALSE; - } - } - return TRUE; - } -} - - -/*---------------------------------------------------------------------------------------- - * void - * lookupComputeAndLoadRoutingTables(sMainData *pDat) - * - * Description: - * Using the description of the fabric topology we discovered, try to find a match - * among the supported topologies. A supported topology description matches - * the discovered fabric if the nodes can be matched in such a way that all the nodes connected - * in one set are exactly the nodes connected in the other (formally, that the graphs are - * isomorphic). Which links are used is not really important to matching. If the graphs - * match, then there is a permutation of one that translates the node positions and linkages - * to the other. - * - * In order to make the isomorphism test efficient, we test for matched number of nodes - * (a 4 node fabric is not isomorphic to a 2 node topology), and provide degrees of nodes - * to the isomorphism test. - * - * The generic routing table solution for any topology is predetermined and represented - * as part of the topology. The permutation we computed tells us how to interpret the - * routing onto the fabric we discovered. We do this working backward from the last - * node discovered to the BSP, writing the routing tables as we go. - * - * Parameters: - * @param[in] sMainData* pDat = our global state, the discovered fabric, - * @param[out] degree matrix, permutation - * --------------------------------------------------------------------------------------- - */ -static void lookupComputeAndLoadRoutingTables(sMainData *pDat) -{ - u8 **pTopologyList; - u8 *pSelected; - - int i, j, k, size; - - size = pDat->NodesDiscovered + 1; - /* Use the provided topology list or the internal, default one. */ - pTopologyList = pDat->HtBlock->topolist; - if (pTopologyList == NULL) - { - getAmdTopolist(&pTopologyList); - } - - pSelected = *pTopologyList; - while (pSelected != NULL) - { - if (graphHowManyNodes(pSelected) == size) - { - /* Build Degree vector and Adjency Matrix for this entry */ - for (i = 0; i < size; i++) - { - pDat->dbDegree[i] = 0; - for (j = 0; j < size; j++) - { - if (graphIsAdjacent(pSelected, i, j)) - { - pDat->dbMatrix[i][j] = 1; - pDat->dbDegree[i]++; - } - else - { - pDat->dbMatrix[i][j] = 0; - } - } - } - if (isoMorph(0, pDat)) - break; /* A matching topology was found */ - } - - pTopologyList++; - pSelected = *pTopologyList; - } - - if (pSelected != NULL) - { - /* Compute the reverse Permutation */ - for (i = 0; i < size; i++) - { - pDat->ReversePerm[pDat->Perm[i]] = i; - } - - /* Start with the last discovered node, and move towards the BSP */ - for (i = size-1; i >= 0; i--) - { - for (j = 0; j < size; j++) - { - u8 ReqTargetLink, RspTargetLink; - u8 ReqTargetNode, RspTargetNode; - - u8 AbstractBcTargetNodes = graphGetBc(pSelected, pDat->Perm[i], pDat->Perm[j]); - u32 BcTargetLinks = 0; - - for (k = 0; k < MAX_NODES; k++) - { - if (AbstractBcTargetNodes & ((u32)1<<k)) - { - BcTargetLinks |= (u32)1 << convertNodeToLink(i, pDat->ReversePerm[k], pDat); - } - } - - if (i == j) - { - ReqTargetLink = ROUTETOSELF; - RspTargetLink = ROUTETOSELF; - } - else - { - ReqTargetNode = graphGetReq(pSelected, pDat->Perm[i], pDat->Perm[j]); - ReqTargetLink = convertNodeToLink(i, pDat->ReversePerm[ReqTargetNode], pDat); - - RspTargetNode = graphGetRsp(pSelected, pDat->Perm[i], pDat->Perm[j]); - RspTargetLink = convertNodeToLink(i, pDat->ReversePerm[RspTargetNode], pDat); - } - - pDat->nb->writeFullRoutingTable(i, j, ReqTargetLink, RspTargetLink, BcTargetLinks, pDat->nb); - } - /* Clean up discovery 'footprint' that otherwise remains in the routing table. It didn't hurt - * anything, but might cause confusion during debug and validation. Do this by setting the - * route back to all self routes. Since it's the node that would be one more than actually installed, - * this only applies if less than maxNodes were found. - */ - if (size < pDat->nb->maxNodes) - { - pDat->nb->writeFullRoutingTable(i, size, ROUTETOSELF, ROUTETOSELF, 0, pDat->nb); - } - } - - } - else - { - /* - * No Matching Topology was found - * Error Strategy: - * Auto recovery doesn't seem likely, Force boot as 1P. - * For reporting, logging, provide number of nodes - * If not implemented or returns, boot as BSP uniprocessor. - */ - if (pDat->HtBlock->AMD_CB_EventNotify) - { - sHtEventCohNoTopology evt; - evt.eSize = sizeof(sHtEventCohNoTopology); - evt.totalNodes = pDat->NodesDiscovered; - - pDat->HtBlock->AMD_CB_EventNotify(HT_EVENT_CLASS_ERROR, - HT_EVENT_COH_NO_TOPOLOGY, - (u8 *)&evt); - } - STOP_HERE; - /* Force 1P */ - pDat->NodesDiscovered = 0; - pDat->TotalLinks = 0; - pDat->nb->enableRoutingTables(0, pDat->nb); - } -} -#endif /* HT_BUILD_NC_ONLY */ - - -/*---------------------------------------------------------------------------------------- - * void - * finializeCoherentInit(sMainData *pDat) - * - * Description: - * Find the total number of cores and update the number of nodes and cores in all cpus. - * Limit CPU config access to installed cpus. - * - * Parameters: - * @param[in] sMainData* pDat = our global state, number of nodes discovered. - * --------------------------------------------------------------------------------------- - */ -static void finializeCoherentInit(sMainData *pDat) -{ - u8 curNode; - - u8 totalCores = 0; - for (curNode = 0; curNode < pDat->NodesDiscovered+1; curNode++) - { - totalCores += pDat->nb->getNumCoresOnNode(curNode, pDat->nb); - } - - for (curNode = 0; curNode < pDat->NodesDiscovered+1; curNode++) - { - pDat->nb->setTotalNodesAndCores(curNode, pDat->NodesDiscovered+1, totalCores, pDat->nb); - } - - for (curNode = 0; curNode < pDat->NodesDiscovered+1; curNode++) - { - pDat->nb->limitNodes(curNode, pDat->nb); - } - -} - -/*---------------------------------------------------------------------------------------- - * void - * coherentInit(sMainData *pDat) - * - * Description: - * Perform discovery and initialization of the coherent fabric. - * - * Parameters: - * @param[in] sMainData* pDat = our global state - * --------------------------------------------------------------------------------------- - */ -static void coherentInit(sMainData *pDat) -{ -#ifdef HT_BUILD_NC_ONLY - /* Replace discovery process with: - * No other nodes, no coherent links - * Enable routing tables on currentNode, for power on self route - */ - pDat->NodesDiscovered = 0; - pDat->TotalLinks = 0; - pDat->nb->enableRoutingTables(0, pDat->nb); -#else - u8 i, j; - - pDat->NodesDiscovered = 0; - pDat->TotalLinks = 0; - for (i = 0; i < MAX_NODES; i++) - { - pDat->sysDegree[i] = 0; - for (j = 0; j < MAX_NODES; j++) - { - pDat->sysMatrix[i][j] = 0; - } - } - - htDiscoveryFloodFill(pDat); - lookupComputeAndLoadRoutingTables(pDat); -#endif - finializeCoherentInit(pDat); -} - -/*************************************************************************** - *** Non-coherent init code *** - *** Algorithms *** - ***************************************************************************/ -/*---------------------------------------------------------------------------------------- - * void - * processLink(u8 node, u8 link, sMainData *pDat) - * - * Description: - * Process a non-coherent link, enabling a range of bus numbers, and setting the device - * ID for all devices found - * - * Parameters: - * @param[in] u8 node = Node on which to process nc init - * @param[in] u8 link = The non-coherent link on that node - * @param[in] sMainData* pDat = our global state - * --------------------------------------------------------------------------------------- - */ -static void processLink(u8 node, u8 link, sMainData *pDat) -{ - u8 secBus, subBus; - u32 currentBUID; - u32 temp; - u32 unitIDcnt; - SBDFO currentPtr; - u8 depth; - const u8 *pSwapPtr; - - SBDFO lastSBDFO = ILLEGAL_SBDFO; - u8 lastLink = 0; - - ASSERT(node < pDat->nb->maxNodes && link < pDat->nb->maxLinks); - - if ((pDat->HtBlock->AMD_CB_OverrideBusNumbers == NULL) - || !pDat->HtBlock->AMD_CB_OverrideBusNumbers(node, link, &secBus, &subBus)) - { - /* Assign Bus numbers */ - if (pDat->AutoBusCurrent >= pDat->HtBlock->AutoBusMax) - { - /* If we run out of Bus Numbers notify, if call back unimplemented or if it - * returns, skip this chain - */ - if (pDat->HtBlock->AMD_CB_EventNotify) - { - sHTEventNcohBusMaxExceed evt; - evt.eSize = sizeof(sHTEventNcohBusMaxExceed); - evt.node = node; - evt.link = link; - evt.bus = pDat->AutoBusCurrent; - - pDat->HtBlock->AMD_CB_EventNotify(HT_EVENT_CLASS_ERROR,HT_EVENT_NCOH_BUS_MAX_EXCEED,(u8 *)&evt); - } - STOP_HERE; - return; - } - - if (pDat->UsedCfgMapEntires >= 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. - */ - if (pDat->HtBlock->AMD_CB_EventNotify) - { - sHtEventNcohCfgMapExceed evt; - evt.eSize = sizeof(sHtEventNcohCfgMapExceed); - evt.node = node; - evt.link = link; - - pDat->HtBlock->AMD_CB_EventNotify(HT_EVENT_CLASS_ERROR, - HT_EVENT_NCOH_CFG_MAP_EXCEED, - (u8 *)&evt); - } - STOP_HERE; - return; - } - - secBus = pDat->AutoBusCurrent; - subBus = secBus + pDat->HtBlock->AutoBusIncrement-1; - pDat->AutoBusCurrent += pDat->HtBlock->AutoBusIncrement; - } - - pDat->nb->setCFGAddrMap(pDat->UsedCfgMapEntires, secBus, subBus, node, link, pDat, pDat->nb); - pDat->UsedCfgMapEntires++; - - if ((pDat->HtBlock->AMD_CB_ManualBUIDSwapList != NULL) - && pDat->HtBlock->AMD_CB_ManualBUIDSwapList(node, link, &pSwapPtr)) - { - /* Manual non-coherent BUID assignment */ - currentBUID = 1; - - /* Assign BUID's per manual override */ - while (*pSwapPtr != 0xFF) - { - currentPtr = MAKE_SBDFO(0, secBus, *pSwapPtr, 0, 0); - pSwapPtr++; - - do - { - AmdPCIFindNextCap(¤tPtr); - ASSERT(currentPtr != ILLEGAL_SBDFO); - AmdPCIRead(currentPtr, &temp); - } while (!IS_HT_SLAVE_CAPABILITY(temp)); - - currentBUID = *pSwapPtr; - pSwapPtr++; - AmdPCIWriteBits(currentPtr, 20, 16, ¤tBUID); - } - - /* Build chain of devices */ - depth = 0; - pSwapPtr++; - while (*pSwapPtr != 0xFF) - { - pDat->PortList[pDat->TotalLinks*2].NodeID = node; - if (depth == 0) - { - pDat->PortList[pDat->TotalLinks*2].Type = PORTLIST_TYPE_CPU; - pDat->PortList[pDat->TotalLinks*2].Link = link; - } - else - { - pDat->PortList[pDat->TotalLinks*2].Type = PORTLIST_TYPE_IO; - pDat->PortList[pDat->TotalLinks*2].Link = 1-lastLink; - pDat->PortList[pDat->TotalLinks*2].HostLink = link; - pDat->PortList[pDat->TotalLinks*2].HostDepth = depth-1; - pDat->PortList[pDat->TotalLinks*2].Pointer = lastSBDFO; - } - - pDat->PortList[pDat->TotalLinks*2+1].Type = PORTLIST_TYPE_IO; - pDat->PortList[pDat->TotalLinks*2+1].NodeID = node; - pDat->PortList[pDat->TotalLinks*2+1].HostLink = link; - pDat->PortList[pDat->TotalLinks*2+1].HostDepth = depth; - - currentPtr = MAKE_SBDFO(0, secBus, (*pSwapPtr & 0x3F), 0, 0); - do - { - AmdPCIFindNextCap(¤tPtr); - ASSERT(currentPtr != ILLEGAL_SBDFO); - AmdPCIRead(currentPtr, &temp); - } while (!IS_HT_SLAVE_CAPABILITY(temp)); - pDat->PortList[pDat->TotalLinks*2+1].Pointer = currentPtr; - lastSBDFO = currentPtr; - - /* 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 */ - ASSERT ((*pSwapPtr & 0x40) || (!(*pSwapPtr & 0x80))); - if (*pSwapPtr & 0x40) - { - /* Override the device's orientation */ - lastLink = *pSwapPtr >> 7; - } - else - { - /* Detect the device's orientation */ - AmdPCIReadBits(currentPtr, 26, 26, &temp); - lastLink = (u8)temp; - } - pDat->PortList[pDat->TotalLinks*2+1].Link = lastLink; - - depth++; - pDat->TotalLinks++; - pSwapPtr++; - } - } - else - { - /* Automatic non-coherent device detection */ - depth = 0; - currentBUID = 1; - while (1) - { - currentPtr = MAKE_SBDFO(0, secBus, 0, 0, 0); - - AmdPCIRead(currentPtr, &temp); - if (temp == 0xFFFFFFFF) - /* No device found at currentPtr */ - break; - - if (pDat->TotalLinks == MAX_PLATFORM_LINKS) - { - /* - * Exceeded our capacity to describe all non-coherent links found in the system. - * Error strategy: - * Auto recovery is not possible because data space is already all used. - */ - if (pDat->HtBlock->AMD_CB_EventNotify) - { - sHtEventNcohLinkExceed evt; - evt.eSize = sizeof(sHtEventNcohLinkExceed); - evt.node = node; - evt.link = link; - evt.depth = depth; - evt.maxLinks = pDat->nb->maxLinks; - - pDat->HtBlock->AMD_CB_EventNotify(HT_EVENT_CLASS_ERROR, - HT_EVENT_NCOH_LINK_EXCEED, - (u8 *)&evt); - } - /* Force link loop to halt */ - STOP_HERE; - break; - } - - pDat->PortList[pDat->TotalLinks*2].NodeID = node; - if (depth == 0) - { - pDat->PortList[pDat->TotalLinks*2].Type = PORTLIST_TYPE_CPU; - pDat->PortList[pDat->TotalLinks*2].Link = link; - } - else - { - pDat->PortList[pDat->TotalLinks*2].Type = PORTLIST_TYPE_IO; - pDat->PortList[pDat->TotalLinks*2].Link = 1-lastLink; - pDat->PortList[pDat->TotalLinks*2].HostLink = link; - pDat->PortList[pDat->TotalLinks*2].HostDepth = depth-1; - pDat->PortList[pDat->TotalLinks*2].Pointer = lastSBDFO; - } - - pDat->PortList[pDat->TotalLinks*2+1].Type = PORTLIST_TYPE_IO; - pDat->PortList[pDat->TotalLinks*2+1].NodeID = node; - pDat->PortList[pDat->TotalLinks*2+1].HostLink = link; - pDat->PortList[pDat->TotalLinks*2+1].HostDepth = depth; - - do - { - AmdPCIFindNextCap(¤tPtr); - ASSERT(currentPtr != ILLEGAL_SBDFO); - AmdPCIRead(currentPtr, &temp); - } while (!IS_HT_SLAVE_CAPABILITY(temp)); - - AmdPCIReadBits(currentPtr, 25, 21, &unitIDcnt); - if ((unitIDcnt + currentBUID > 31) || ((secBus == 0) && (unitIDcnt + currentBUID > 24))) - { - /* An error handler for the case where we run out of BUID's on a chain */ - if (pDat->HtBlock->AMD_CB_EventNotify) - { - sHtEventNcohBuidExceed evt; - evt.eSize = sizeof(sHtEventNcohBuidExceed); - evt.node = node; - evt.link = link; - evt.depth = depth; - evt.currentBUID = (uint8)currentBUID; - evt.unitCount = (uint8)unitIDcnt; - - pDat->HtBlock->AMD_CB_EventNotify(HT_EVENT_CLASS_ERROR,HT_EVENT_NCOH_BUID_EXCEED,(u8 *)&evt); - } - STOP_HERE; - break; - } - AmdPCIWriteBits(currentPtr, 20, 16, ¤tBUID); - - - currentPtr += MAKE_SBDFO(0, 0, currentBUID, 0, 0); - AmdPCIReadBits(currentPtr, 20, 16, &temp); - if (temp != currentBUID) - { - /* An error handler for this critical error */ - if (pDat->HtBlock->AMD_CB_EventNotify) - { - sHtEventNcohDeviceFailed evt; - evt.eSize = sizeof(sHtEventNcohDeviceFailed); - evt.node = node; - evt.link = link; - evt.depth = depth; - evt.attemptedBUID = (uint8)currentBUID; - - pDat->HtBlock->AMD_CB_EventNotify(HT_EVENT_CLASS_ERROR,HT_EVENT_NCOH_DEVICE_FAILED,(u8 *)&evt); - } - STOP_HERE; - break; - } - - AmdPCIReadBits(currentPtr, 26, 26, &temp); - pDat->PortList[pDat->TotalLinks*2+1].Link = (u8)temp; - pDat->PortList[pDat->TotalLinks*2+1].Pointer = currentPtr; - - lastLink = (u8)temp; - lastSBDFO = currentPtr; - - depth++; - pDat->TotalLinks++; - currentBUID += unitIDcnt; - } - if (pDat->HtBlock->AMD_CB_EventNotify) - { - /* Provide information on automatic device results */ - sHtEventNcohAutoDepth evt; - evt.eSize = sizeof(sHtEventNcohAutoDepth); - evt.node = node; - evt.link = link; - evt.depth = (depth - 1); - - pDat->HtBlock->AMD_CB_EventNotify(HT_EVENT_CLASS_INFO,HT_EVENT_NCOH_AUTO_DEPTH,(u8 *)&evt); - } - } -} - - -/*---------------------------------------------------------------------------------------- - * void - * ncInit(sMainData *pDat) - * - * Description: - * Initialize the non-coherent fabric. Begin with the compat link on the BSP, then - * find and initialize all other non-coherent chains. - * - * Parameters: - * @param[in] sMainData* pDat = our global state - * --------------------------------------------------------------------------------------- - */ -static void ncInit(sMainData *pDat) -{ - u8 node, link; - u8 compatLink; - - compatLink = pDat->nb->readSbLink(pDat->nb); - processLink(0, compatLink, pDat); - - for (node = 0; node <= pDat->NodesDiscovered; node++) - { - for (link = 0; link < pDat->nb->maxLinks; link++) - { - if (pDat->HtBlock->AMD_CB_IgnoreLink && pDat->HtBlock->AMD_CB_IgnoreLink(node, link)) - continue; /* Skip the link */ - - if (node == 0 && link == compatLink) - continue; - - if (pDat->nb->readTrueLinkFailStatus(node, link, pDat, pDat->nb)) - continue; - - if (pDat->nb->verifyLinkIsNonCoherent(node, link, pDat->nb)) - processLink(node, link, pDat); - } - } -} - -/*************************************************************************** - *** Link Optimization *** - ***************************************************************************/ - -/*---------------------------------------------------------------------------------------- - * void - * regangLinks(sMainData *pDat) - * - * Description: - * Test the sublinks of a link to see if they qualify to be reganged. If they do, - * update the port list data to indicate that this should be done. Note that no - * actual hardware state is changed in this routine. - * - * Parameters: - * @param[in,out] sMainData* pDat = our global state - * --------------------------------------------------------------------------------------- - */ -static void regangLinks(sMainData *pDat) -{ -#ifndef HT_BUILD_NC_ONLY - u8 i, j; - for (i = 0; i < pDat->TotalLinks*2; i += 2) - { - ASSERT(pDat->PortList[i].Type < 2 && pDat->PortList[i].Link < pDat->nb->maxLinks); /* Data validation */ - ASSERT(pDat->PortList[i+1].Type < 2 && pDat->PortList[i+1].Link < pDat->nb->maxLinks); /* data validation */ - ASSERT(!(pDat->PortList[i].Type == PORTLIST_TYPE_IO && pDat->PortList[i+1].Type == PORTLIST_TYPE_CPU)); /* ensure src is closer to the bsp than dst */ - - /* Regang is false unless we pass all conditions below */ - pDat->PortList[i].SelRegang = FALSE; - pDat->PortList[i+1].SelRegang = FALSE; - - if ((pDat->PortList[i].Type != PORTLIST_TYPE_CPU) || (pDat->PortList[i+1].Type != PORTLIST_TYPE_CPU)) - continue; /* Only process CPU to CPU links */ - - for (j = i+2; j < pDat->TotalLinks*2; j += 2) - { - if ((pDat->PortList[j].Type != PORTLIST_TYPE_CPU) || (pDat->PortList[j+1].Type != PORTLIST_TYPE_CPU)) - continue; /* Only process CPU to CPU links */ - - if (pDat->PortList[i].NodeID != pDat->PortList[j].NodeID) - continue; /* Links must be from the same source */ - - if (pDat->PortList[i+1].NodeID != pDat->PortList[j+1].NodeID) - continue; /* Link must be to the same target */ - - if ((pDat->PortList[i].Link & 3) != (pDat->PortList[j].Link & 3)) - continue; /* Ensure same source base port */ - - if ((pDat->PortList[i+1].Link & 3) != (pDat->PortList[j+1].Link & 3)) - continue; /* Ensure same destination base port */ - - if ((pDat->PortList[i].Link & 4) != (pDat->PortList[i+1].Link & 4)) - continue; /* Ensure sublink0 routes to sublink0 */ - - ASSERT((pDat->PortList[j].Link & 4) == (pDat->PortList[j+1].Link & 4)); /* (therefore sublink1 routes to sublink1) */ - - if (pDat->HtBlock->AMD_CB_SkipRegang && - pDat->HtBlock->AMD_CB_SkipRegang(pDat->PortList[i].NodeID, - pDat->PortList[i].Link & 0x03, - pDat->PortList[i+1].NodeID, - pDat->PortList[i+1].Link & 0x03)) - { - continue; /* Skip regang */ - } - - - pDat->PortList[i].Link &= 0x03; /* Force to point to sublink0 */ - pDat->PortList[i+1].Link &= 0x03; - pDat->PortList[i].SelRegang = TRUE; /* Enable link reganging */ - pDat->PortList[i+1].SelRegang = TRUE; - pDat->PortList[i].PrvWidthOutCap = HT_WIDTH_16_BITS; - pDat->PortList[i+1].PrvWidthOutCap = HT_WIDTH_16_BITS; - pDat->PortList[i].PrvWidthInCap = HT_WIDTH_16_BITS; - pDat->PortList[i+1].PrvWidthInCap = HT_WIDTH_16_BITS; - - /* Delete PortList[j, j+1], slow but easy to debug implementation */ - pDat->TotalLinks--; - Amdmemcpy(&(pDat->PortList[j]), &(pDat->PortList[j+2]), sizeof(sPortDescriptor)*(pDat->TotalLinks*2-j)); - Amdmemset(&(pDat->PortList[pDat->TotalLinks*2]), INVALID_LINK, sizeof(sPortDescriptor)*2); - - /* //High performance, but would make debuging harder due to 'shuffling' of the records */ - /* //Amdmemcpy(PortList[TotalPorts-2], PortList[j], SIZEOF(sPortDescriptor)*2); */ - /* //TotalPorts -=2; */ - - break; /* Exit loop, advance to PortList[i+2] */ - } - } -#endif /* HT_BUILD_NC_ONLY */ -} - -static void detectIoLinkIsochronousCapable(sMainData *pDat) -{ - uint8_t i; - unsigned char iommu; - uint8_t isochronous_capable = 0; - - iommu = 1; - get_option(&iommu, "iommu"); - - for (i = 0; i < pDat->TotalLinks*2; i += 2) { - if ((pDat->PortList[i].Type == PORTLIST_TYPE_CPU) && (pDat->PortList[i+1].Type == PORTLIST_TYPE_IO)) { - if ((pDat->PortList[i].PrvFeatureCap & 0x1) && (pDat->PortList[i+1].PrvFeatureCap & 0x1)) { - pDat->PortList[i].enable_isochronous_mode = 1; - pDat->PortList[i+1].enable_isochronous_mode = 1; - isochronous_capable = 1; - } else { - pDat->PortList[i].enable_isochronous_mode = 0; - pDat->PortList[i+1].enable_isochronous_mode = 0; - } - } - } - - if (isochronous_capable && iommu) { - printk(BIOS_DEBUG, "Forcing HT links to isochronous mode due to enabled IOMMU\n"); - /* Isochronous mode must be set on all links if the IOMMU is enabled */ - for (i = 0; i < pDat->TotalLinks*2; i += 2) { - pDat->PortList[i].enable_isochronous_mode = 1; - pDat->PortList[i+1].enable_isochronous_mode = 1; - } - } -} - -/*---------------------------------------------------------------------------------------- - * void - * selectOptimalWidthAndFrequency(sMainData *pDat) - * - * Description: - * For all links: - * Examine both sides of a link and determine the optimal frequency and width, - * taking into account externally provided limits and enforcing any other limit - * or matching rules as applicable except sublink balancing. Update the port - * list date with the optimal settings. - * Note no hardware state changes in this routine. - * - * Parameters: - * @param[in,out] sMainData* pDat = our global state, port list data - * --------------------------------------------------------------------------------------- - */ -static void selectOptimalWidthAndFrequency(sMainData *pDat) -{ - u8 i, j; - uint32_t temp; - uint32_t cbPCBFreqLimit; - uint32_t cbPCBFreqLimit_NVRAM; - u8 cbPCBABDownstreamWidth; - u8 cbPCBBAUpstreamWidth; - - cbPCBFreqLimit_NVRAM = 0xfffff; - if (get_option(&temp, "hypertransport_speed_limit") == CB_SUCCESS) - cbPCBFreqLimit_NVRAM = ht_speed_limit[temp & 0xf]; - - if (!is_fam15h()) { - /* FIXME - * By default limit frequency to 2.6 GHz as there are residual - * problems with HT v3.1 implementation on at least some Socket G34 - * mainboards / Fam10h CPUs. - * Debug the issues and reenable this... - */ - if (cbPCBFreqLimit_NVRAM > 0xffff) - cbPCBFreqLimit_NVRAM = 0xffff; - } - - for (i = 0; i < pDat->TotalLinks*2; i += 2) - { - cbPCBFreqLimit = 0xfffff; // Maximum allowed by autoconfiguration - if (pDat->HtBlock->ht_link_configuration) - cbPCBFreqLimit = ht_speed_mhz_to_hw(pDat->HtBlock->ht_link_configuration->ht_speed_limit); - cbPCBFreqLimit = min(cbPCBFreqLimit, cbPCBFreqLimit_NVRAM); - -#if CONFIG(LIMIT_HT_DOWN_WIDTH_8) - cbPCBABDownstreamWidth = 8; -#else - cbPCBABDownstreamWidth = 16; -#endif - -#if CONFIG(LIMIT_HT_UP_WIDTH_8) - cbPCBBAUpstreamWidth = 8; -#else - cbPCBBAUpstreamWidth = 16; -#endif - - if ((pDat->PortList[i].Type == PORTLIST_TYPE_CPU) && (pDat->PortList[i+1].Type == PORTLIST_TYPE_CPU)) - { - if (pDat->HtBlock->AMD_CB_Cpu2CpuPCBLimits) - { - pDat->HtBlock->AMD_CB_Cpu2CpuPCBLimits( - pDat->PortList[i].NodeID, - pDat->PortList[i].Link, - pDat->PortList[i+1].NodeID, - pDat->PortList[i+1].Link, - &cbPCBABDownstreamWidth, - &cbPCBBAUpstreamWidth, &cbPCBFreqLimit - ); - } - } - else - { - if (pDat->HtBlock->AMD_CB_IOPCBLimits) - { - pDat->HtBlock->AMD_CB_IOPCBLimits( - pDat->PortList[i+1].NodeID, - pDat->PortList[i+1].HostLink, - pDat->PortList[i+1].HostDepth, - &cbPCBABDownstreamWidth, - &cbPCBBAUpstreamWidth, &cbPCBFreqLimit - ); - } - } - - temp = pDat->PortList[i].PrvFrequencyCap; - temp &= pDat->PortList[i+1].PrvFrequencyCap; - temp &= cbPCBFreqLimit; - pDat->PortList[i].CompositeFrequencyCap = temp; - pDat->PortList[i+1].CompositeFrequencyCap = temp; - - ASSERT (temp != 0); - for (j = 19;; j--) - { - if ((j == 16) || (j == 15)) - continue; - if (temp & ((uint32_t)1 << j)) - break; - } - - pDat->PortList[i].SelFrequency = j; - pDat->PortList[i+1].SelFrequency = j; - - temp = pDat->PortList[i].PrvWidthOutCap; - if (pDat->PortList[i+1].PrvWidthInCap < temp) - temp = pDat->PortList[i+1].PrvWidthInCap; - if (cbPCBABDownstreamWidth < temp) - temp = cbPCBABDownstreamWidth; - pDat->PortList[i].SelWidthOut = (u8)temp; - pDat->PortList[i+1].SelWidthIn = (u8)temp; - - temp = pDat->PortList[i].PrvWidthInCap; - if (pDat->PortList[i+1].PrvWidthOutCap < temp) - temp = pDat->PortList[i+1].PrvWidthOutCap; - if (cbPCBBAUpstreamWidth < temp) - temp = cbPCBBAUpstreamWidth; - pDat->PortList[i].SelWidthIn = (u8)temp; - pDat->PortList[i+1].SelWidthOut = (u8)temp; - } -} - -/*---------------------------------------------------------------------------------------- - * void - * hammerSublinkFixup(sMainData *pDat) - * - * Description: - * Iterate through all links, checking the frequency of each sublink pair. Make the - * adjustment to the port list data so that the frequencies are at a valid ratio, - * reducing frequency as needed to achieve this. (All links support the minimum 200 MHz - * frequency.) Repeat the above until no adjustments are needed. - * Note no hardware state changes in this routine. - * - * Parameters: - * @param[in,out] sMainData* pDat = our global state, link state and port list - * --------------------------------------------------------------------------------------- - */ -static void hammerSublinkFixup(sMainData *pDat) -{ -#ifndef HT_BUILD_NC_ONLY - u8 i, j, k; - BOOL changes, downgrade; - - u8 hiIndex; - u8 hiFreq, loFreq; - - u32 temp; - - do - { - changes = FALSE; - for (i = 0; i < pDat->TotalLinks*2; i++) - { - if (pDat->PortList[i].Type != PORTLIST_TYPE_CPU) /* Must be a CPU link */ - continue; - if (pDat->PortList[i].Link < 4) /* Only look for sublink1's */ - continue; - - for (j = 0; j < pDat->TotalLinks*2; j++) - { - /* Step 1. Find the matching sublink0 */ - if (pDat->PortList[j].Type != PORTLIST_TYPE_CPU) - continue; - if (pDat->PortList[j].NodeID != pDat->PortList[i].NodeID) - continue; - if (pDat->PortList[j].Link != (pDat->PortList[i].Link & 0x03)) - continue; - - /* Step 2. Check for an illegal frequency ratio */ - if (pDat->PortList[i].SelFrequency >= pDat->PortList[j].SelFrequency) - { - hiIndex = i; - hiFreq = pDat->PortList[i].SelFrequency; - loFreq = pDat->PortList[j].SelFrequency; - } - else - { - hiIndex = j; - hiFreq = pDat->PortList[j].SelFrequency; - loFreq = pDat->PortList[i].SelFrequency; - } - - if (hiFreq == loFreq) - break; /* The frequencies are 1:1, no need to do anything */ - - downgrade = FALSE; - - if (hiFreq == 13) - { - if ((loFreq != 7) && /* {13, 7} 2400MHz / 1200MHz 2:1 */ - (loFreq != 4) && /* {13, 4} 2400MHz / 600MHz 4:1 */ - (loFreq != 2)) /* {13, 2} 2400MHz / 400MHz 6:1 */ - downgrade = TRUE; - } - else if (hiFreq == 11) - { - if ((loFreq != 6)) /* {11, 6} 2000MHz / 1000MHz 2:1 */ - downgrade = TRUE; - } - else if (hiFreq == 9) - { - if ((loFreq != 5) && /* { 9, 5} 1600MHz / 800MHz 2:1 */ - (loFreq != 2) && /* { 9, 2} 1600MHz / 400MHz 4:1 */ - (loFreq != 0)) /* { 9, 0} 1600MHz / 200MHz 8:1 */ - downgrade = TRUE; - } - else if (hiFreq == 7) - { - if ((loFreq != 4) && /* { 7, 4} 1200MHz / 600MHz 2:1 */ - (loFreq != 0)) /* { 7, 0} 1200MHz / 200MHz 6:1 */ - downgrade = TRUE; - } - else if (hiFreq == 5) - { - if ((loFreq != 2) && /* { 5, 2} 800MHz / 400MHz 2:1 */ - (loFreq != 0)) /* { 5, 0} 800MHz / 200MHz 4:1 */ - downgrade = TRUE; - } - else if (hiFreq == 2) - { - if ((loFreq != 0)) /* { 2, 0} 400MHz / 200MHz 2:1 */ - downgrade = TRUE; - } - else - { - downgrade = TRUE; /* no legal ratios for hiFreq */ - } - - /* Step 3. Downgrade the higher of the two frequencies, and set nochanges to FALSE */ - if (downgrade) - { - /* Although the problem was with the port specified by hiIndex, we need to */ - /* downgrade both ends of the link. */ - hiIndex = hiIndex & 0xFE; /* Select the 'upstream' (i.e. even) port */ - - temp = pDat->PortList[hiIndex].CompositeFrequencyCap; - - /* Remove hiFreq from the list of valid frequencies */ - temp = temp & ~((uint32)1 << hiFreq); - ASSERT (temp != 0); - pDat->PortList[hiIndex].CompositeFrequencyCap = temp; - pDat->PortList[hiIndex+1].CompositeFrequencyCap = temp; - - for (k = 19;; k--) - { - if ((j == 16) || (j == 15)) - continue; - if (temp & ((uint32_t)1 << k)) - break; - } - - pDat->PortList[hiIndex].SelFrequency = k; - pDat->PortList[hiIndex+1].SelFrequency = k; - - changes = TRUE; - } - } - } - } while (changes); /* Repeat until a valid configuration is reached */ -#endif /* HT_BUILD_NC_ONLY */ -} - -/*---------------------------------------------------------------------------------------- - * void - * linkOptimization(sMainData *pDat) - * - * Description: - * Based on link capabilities, apply optimization rules to come up with the real best - * settings, including several external limit decision from call backs. This includes - * handling of sublinks. Finally, after the port list data is updated, set the hardware - * state for all links. - * - * Parameters: - * @param[in] sMainData* pDat = our global state - * --------------------------------------------------------------------------------------- - */ -static void linkOptimization(sMainData *pDat) -{ - pDat->nb->gatherLinkData(pDat, pDat->nb); - regangLinks(pDat); - if (is_fam15h()) - detectIoLinkIsochronousCapable(pDat); - selectOptimalWidthAndFrequency(pDat); - hammerSublinkFixup(pDat); - pDat->nb->setLinkData(pDat, pDat->nb); -} - - -/*---------------------------------------------------------------------------------------- - * void - * trafficDistribution(sMainData *pDat) - * - * Description: - * In the case of a two node system with both sublinks used, enable the traffic - * distribution feature. - * - * Parameters: - * @param[in] sMainData* pDat = our global state, port list data - * --------------------------------------------------------------------------------------- - */ -static void trafficDistribution(sMainData *pDat) -{ -#ifndef HT_BUILD_NC_ONLY - u32 links01, links10; - u8 linkCount; - u8 i; - - /* Traffic Distribution is only used when there are exactly two nodes in the system */ - if (pDat->NodesDiscovered+1 != 2) - return; - - links01 = 0; - links10 = 0; - linkCount = 0; - for (i = 0; i < pDat->TotalLinks*2; i += 2) - { - if ((pDat->PortList[i].Type == PORTLIST_TYPE_CPU) && (pDat->PortList[i+1].Type == PORTLIST_TYPE_CPU)) - { - links01 |= (u32)1 << pDat->PortList[i].Link; - links10 |= (u32)1 << pDat->PortList[i+1].Link; - linkCount++; - } - } - ASSERT(linkCount != 0); - if (linkCount == 1) - return; /* Don't setup Traffic Distribution if only one link is being used */ - - pDat->nb->writeTrafficDistribution(links01, links10, pDat->nb); -#endif /* HT_BUILD_NC_ONLY */ -} - -/*---------------------------------------------------------------------------------------- - * void - * tuning(sMainData *pDat) - * - * Description: - * Handle system and performance tunings, such as traffic distribution, fifo and - * buffer tuning, and special config tunings. - * - * Parameters: - * @param[in] sMainData* pDat = our global state, port list data - * --------------------------------------------------------------------------------------- - */ -static void tuning(sMainData *pDat) -{ - u8 i; - - /* See if traffic distribution can be done and do it if so - * or allow system specific customization - */ - if ((pDat->HtBlock->AMD_CB_CustomizeTrafficDistribution == NULL) - || !pDat->HtBlock->AMD_CB_CustomizeTrafficDistribution()) - { - trafficDistribution(pDat); - } - - /* For each node, invoke northbridge specific buffer tunings or - * system specific customizations. - */ - for (i = 0; i < pDat->NodesDiscovered + 1; i++) - { - if ((pDat->HtBlock->AMD_CB_CustomizeBuffers == NULL) - || !pDat->HtBlock->AMD_CB_CustomizeBuffers(i)) - { - pDat->nb->bufferOptimizations(i, pDat, pDat->nb); - } - } -} - -/*---------------------------------------------------------------------------------------- - * BOOL - * isSanityCheckOk() - * - * Description: - * Perform any general sanity checks which should prevent HT from running if they fail. - * Currently only the "Must run on BSP only" check. - * - * Parameters: - * @param[out] result BOOL = true if check is ok, false if it failed - * --------------------------------------------------------------------------------------- - */ -static BOOL isSanityCheckOk(void) -{ - uint64 qValue; - - AmdMSRRead(LAPIC_BASE_MSR, &qValue); - - return ((qValue.lo & LAPIC_BASE_MSR_BOOTSTRAP_PROCESSOR) != 0); -} - -/*************************************************************************** - *** HT Initialize *** - ***************************************************************************/ - -/*---------------------------------------------------------------------------------------- - * void - * htInitialize(AMD_HTBLOCK *pBlock) - * - * Description: - * This is the top level external interface for Hypertransport Initialization. - * Create our initial internal state, initialize the coherent fabric, - * initialize the non-coherent chains, and perform any required fabric tuning or - * optimization. - * - * Parameters: - * @param[in] AMD_HTBLOCK* pBlock = Our Initial State including possible - * topologies and routings, non coherent bus - * assignment info, and actual - * wrapper or OEM call back routines. - * --------------------------------------------------------------------------------------- - */ -void amdHtInitialize(AMD_HTBLOCK *pBlock) -{ - sMainData pDat; - cNorthBridge nb; - - if (isSanityCheckOk()) - { - newNorthBridge(0, &nb); - - pDat.HtBlock = pBlock; - pDat.nb = &nb; - pDat.sysMpCap = nb.maxNodes; - nb.isCapable(0, &pDat, pDat.nb); - coherentInit(&pDat); - - pDat.AutoBusCurrent = pBlock->AutoBusStart; - pDat.UsedCfgMapEntires = 0; - ncInit(&pDat); - linkOptimization(&pDat); - tuning(&pDat); - } -} diff --git a/src/northbridge/amd/amdht/h3finit.h b/src/northbridge/amd/amdht/h3finit.h deleted file mode 100644 index 743ae97065..0000000000 --- a/src/northbridge/amd/amdht/h3finit.h +++ /dev/null @@ -1,620 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef H3FINIT_H -#define H3FINIT_H - -#include "comlib.h" - -/*---------------------------------------------------------------------------- - * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) - * - *---------------------------------------------------------------------------- - */ - -/*----------------------------------------------------------------------------- - * DEFINITIONS AND MACROS - * - *----------------------------------------------------------------------------- - */ - -/* Width equates for call backs */ -#define HT_WIDTH_8_BITS 8 -#define HT_WIDTH_16_BITS 16 -#define HT_WIDTH_4_BITS 4 -#define HT_WIDTH_2_BITS 2 - -/* Frequency equates for call backs which take an actual frequency setting */ -#define HT_FREQUENCY_200M 0 -#define HT_FREQUENCY_400M 2 -#define HT_FREQUENCY_600M 4 -#define HT_FREQUENCY_800M 5 -#define HT_FREQUENCY_1000M 6 -#define HT_FREQUENCY_1200M 7 -#define HT_FREQUENCY_1400M 8 -#define HT_FREQUENCY_1600M 9 -#define HT_FREQUENCY_1800M 10 -#define HT_FREQUENCY_2000M 11 -#define HT_FREQUENCY_2200M 12 -#define HT_FREQUENCY_2400M 13 -#define HT_FREQUENCY_2600M 14 -#define HT_FREQUENCY_2800M 17 -#define HT_FREQUENCY_3000M 18 -#define HT_FREQUENCY_3200M 19 - -/* Frequency Limit equates for call backs which take a frequency supported mask. */ -#define HT_FREQUENCY_LIMIT_200M 1 -#define HT_FREQUENCY_LIMIT_400M 7 -#define HT_FREQUENCY_LIMIT_600M 0x1F -#define HT_FREQUENCY_LIMIT_800M 0x3F -#define HT_FREQUENCY_LIMIT_1000M 0x7F -#define HT_FREQUENCY_LIMIT_HT1_ONLY 0x7F -#define HT_FREQUENCY_LIMIT_1200M 0xFF -#define HT_FREQUENCY_LIMIT_1400M 0x1FF -#define HT_FREQUENCY_LIMIT_1600M 0x3FF -#define HT_FREQUENCY_LIMIT_1800M 0x7FF -#define HT_FREQUENCY_LIMIT_2000M 0xFFF -#define HT_FREQUENCY_LIMIT_2200M 0x1FFF -#define HT_FREQUENCY_LIMIT_2400M 0x3FFF -#define HT_FREQUENCY_LIMIT_2600M 0x7FFF -#define HT_FREQUENCY_LIMIT_2800M 0x3FFFF -#define HT_FREQUENCY_LIMIT_3000M 0x7FFFF -#define HT_FREQUENCY_LIMIT_3200M 0xFFFFF - -/* - * Event Notify definitions - */ - -/* Event Class definitions */ -#define HT_EVENT_CLASS_CRITICAL 1 -#define HT_EVENT_CLASS_ERROR 2 -#define HT_EVENT_CLASS_HW_FAULT 3 -#define HT_EVENT_CLASS_WARNING 4 -#define HT_EVENT_CLASS_INFO 5 - -/* Event definitions. */ - -/* Coherent subfunction events */ -#define HT_EVENT_COH_EVENTS 0x1000 -#define HT_EVENT_COH_NO_TOPOLOGY 0x1001 -#define HT_EVENT_COH_LINK_EXCEED 0x1002 -#define HT_EVENT_COH_FAMILY_FEUD 0x1003 -#define HT_EVENT_COH_NODE_DISCOVERED 0x1004 -#define HT_EVENT_COH_MPCAP_MISMATCH 0x1005 - -/* Non-coherent subfunction events */ -#define HT_EVENT_NCOH_EVENTS 0x2000 -#define HT_EVENT_NCOH_BUID_EXCEED 0x2001 -#define HT_EVENT_NCOH_LINK_EXCEED 0x2002 -#define HT_EVENT_NCOH_BUS_MAX_EXCEED 0x2003 -#define HT_EVENT_NCOH_CFG_MAP_EXCEED 0x2004 -#define HT_EVENT_NCOH_DEVICE_FAILED 0x2005 -#define HT_EVENT_NCOH_AUTO_DEPTH 0x2006 - -/* Optimization subfunction events */ -#define HT_EVENT_OPT_EVENTS 0x3000 -#define HT_EVENT_OPT_REQUIRED_CAP_RETRY 0x3001 -#define HT_EVENT_OPT_REQUIRED_CAP_GEN3 0x3002 - -/* HW Fault events */ -#define HT_EVENT_HW_EVENTS 0x4000 -#define HT_EVENT_HW_SYNCHFLOOD 0x4001 -#define HT_EVENT_HW_HTCRC 0x4002 - -/* The bbHT component (hb*) uses 0x5000 for events. - * For consistency, we avoid that range here. - */ - -/*---------------------------------------------------------------------------- - * TYPEDEFS, STRUCTURES, ENUMS - * - *---------------------------------------------------------------------------- - */ - -typedef struct { - u8 **topolist; - u8 AutoBusStart; - /* Note: This should always be the form AutoBusCurrent+N*AutoBusIncrement, also bus 253-255 are reserved */ - u8 AutoBusMax; - u8 AutoBusIncrement; - - /**---------------------------------------------------------------------------------------- - * - * BOOL - * AMD_CB_IgnoreLink(u8 Node, u8 Link) - * - * Description: - * This routine is called every time a coherent link is found and then every - * time a non-coherent link from a CPU is found. - * Any coherent or non-coherent link from a CPU can be ignored and not used - * for discovery or initialization. Useful for connection based systems. - * (Note: not called for IO device to IO Device links.) - * - * Parameters: - * @param[in] u8 node = The node on which this link is located - * @param[in] u8 link = The link about to be initialized - * @param[out] BOOL result = true to ignore this link and skip it - * false to initialize the link normally - * - * --------------------------------------------------------------------------------------- - */ - BOOL (*AMD_CB_IgnoreLink)(u8 Node, u8 Link); - - /**---------------------------------------------------------------------------------------- - * - * BOOL - * AMD_CB_OverrideBusNumbers(u8 Node, u8 Link, u8 *SecBus, u8 *SubBus) - * - * Description: - * This routine is called every time a non-coherent chain is processed. - * If a system can not use the auto Bus numbering feature for non-coherent chain bus - * assignments, this routine can provide explicit control. For each chain, provide - * the bus number range to use. - * - * Parameters: - * @param[in] u8 node = The node on which this chain is located - * @param[in] u8 link = The link on the host for this chain - * @param[out] u8 secBus = Secondary Bus number for this non-coherent chain - * @param[out] u8 *subBus = Subordinate Bus number - * @param[out] BOOL result = true this routine is supplying the bus numbers - * false use auto Bus numbering - * - * --------------------------------------------------------------------------------------- - */ - BOOL (*AMD_CB_OverrideBusNumbers)(u8 Node, u8 Link, u8 *SecBus, u8 *SubBus); - - /**---------------------------------------------------------------------------------------- - * - * BOOL - * AMD_CB_ManualBUIDSwapList(u8 Node, u8 Link, u8 **List) - * - * Description: - * This routine is called every time a non-coherent chain is processed. - * BUID assignment may be controlled explicitly on a non-coherent chain. Provide a - * swap list. The first part of the list controls the BUID assignment and the - * second part of the list provides the device to device linking. Device orientation - * can be detected automatically, or explicitly. See documentation for more details. - * - * Automatic non-coherent init assigns BUIDs starting at 1 and incrementing sequentially - * based on each device's unit count. - * - * Parameters: - * @param[in] u8 node = The node on which this chain is located - * @param[in] u8 link = The link on the host for this chain - * @param[out] u8 **list = supply a pointer to a list - * @param[out] BOOL result = true to use a manual list - * false to initialize the link automatically - * - * --------------------------------------------------------------------------------------- - */ - BOOL (*AMD_CB_ManualBUIDSwapList)(u8 Node, u8 Link, const u8 **List); - - /**---------------------------------------------------------------------------------------- - * - * void - * AMD_CB_DeviceCapOverride(u8 HostNode, u8 HostLink, u8 Depth, u8 Segment, - * u8 Bus, u8 Dev, u32 DevVenID, u8 Link, - * u8 *LinkWidthIn, u8 *LinkWidthOut, u16 *FreqCap) - * - * Description: - * This routine is called once for every link on every IO device. - * Update the width and frequency capability if needed for this device. - * This is used along with device capabilities, the limit call backs, and northbridge - * limits to compute the default settings. The components of the device's PCI config - * address are provided, so its settings can be consulted if need be. The input width - * and frequency are the reported device capabilities. - * - * Parameters: - * @param[in] u8 hostNode = The node on which this chain is located - * @param[in] u8 hostLink = The link on the host for this chain - * @param[in] u8 Depth = The depth in the I/O chain from the Host - * @param[in] u8 Segment = The Device's PCI Bus Segment number - * @param[in] u8 Bus = The Device's PCI Bus number - * @param[in] u8 Dev = The Device's PCI device Number - * @param[in] u32 DevVenID = The Device's PCI Vendor + Device ID (offset 0x00) - * @param[in] u8 Link = The Device's link number (0 or 1) - * @param[in,out] u8 *LinkWidthIn = modify to change the Link Witdh In - * @param[in,out] u8 *LinkWidthOut = modify to change the Link Witdh Out - * @param[in,out] u32 *FreqCap = modify to change the link's frequency capability - * @param[in,out] u32 *FeatureCap = modify to change the link's feature capability - * - * --------------------------------------------------------------------------------------- - */ - void (*AMD_CB_DeviceCapOverride)( - u8 HostNode, - u8 HostLink, - u8 Depth, - u8 Segment, - u8 Bus, - u8 Dev, - u32 DevVenID, - u8 Link, - u8 *LinkWidthIn, - u8 *LinkWidthOut, - u32 *FreqCap, - u32 *FeatureCap - ); - - /**---------------------------------------------------------------------------------------- - * - * void - * AMD_CB_Cpu2CpuPCBLimits(u8 NodeA, u8 LinkA, u8 NodeB, u8 LinkB, - * u8 *ABLinkWidthLimit, u8 *BALinkWidthLimit, u16 *PCBFreqCap) - * - * Description: - * For each coherent connection this routine is called once. - * Update the frequency and width if needed for this link (usually based on board - * restriction). This is used with CPU device capabilities and northbridge limits - * to compute the default settings. The input width and frequency are valid, but do - * not necessarily reflect the minimum setting that will be chosen. - * - * Parameters: - * @param[in] u8 nodeA = One node on which this link is located - * @param[in] u8 linkA = The link on this node - * @param[in] u8 nodeB = The other node on which this link is located - * @param[in] u8 linkB = The link on that node - * @param[in,out] u8 *ABLinkWidthLimit = modify to change the Link Witdh In - * @param[in,out] u8 *BALinkWidthLimit = modify to change the Link Witdh Out - * @param[in,out] u32 *PCBFreqCap = modify to change the link's frequency capability - * - * --------------------------------------------------------------------------------------- - */ - void (*AMD_CB_Cpu2CpuPCBLimits)( - u8 NodeA, - u8 LinkA, - u8 NodeB, - u8 LinkB, - u8 *ABLinkWidthLimit, - u8 *BALinkWidthLimit, - u32 *PCBFreqCap - ); - - /**---------------------------------------------------------------------------------------- - * - * void - * AMD_CB_IOPCBLimits(u8 HostNode, u8 HostLink, u8 Depth, u8 *DownstreamLinkWidthLimit, - * u8 *UpstreamLinkWidthLimit, u16 *PCBFreqCap) - * - * Description: - * For each non-coherent connection this routine is called once. - * Update the frequency and width if needed for this link (usually based on board - * restriction). This is used with device capabilities, device overrides, and northbridge limits - * to compute the default settings. The input width and frequency are valid, but do - * not necessarily reflect the minimum setting that will be chosen. - * - * Parameters: - * @param[in] u8 hostNode = The node on which this link is located - * @param[in] u8 hostLink = The link about to be initialized - * @param[in] u8 Depth = The depth in the I/O chain from the Host - * @param[in,out] u8 *DownstreamLinkWidthLimit = modify to change the Link Witdh In - * @param[in,out] u8 *UpstreamLinkWidthLimit = modify to change the Link Witdh Out - * @param[in,out] u32 *PCBFreqCap = modify to change the link's frequency capability - * - * --------------------------------------------------------------------------------------- - */ - void (*AMD_CB_IOPCBLimits)( - u8 HostNode, - u8 HostLink, - u8 Depth, - u8 *DownstreamLinkWidthLimit, - u8 *UpstreamLinkWidthLimit, - u32 *PCBFreqCap - ); - - /**---------------------------------------------------------------------------------------- - * - * BOOL - * AMD_CB_SkipRegang(u8 NodeA, u8 LinkA, u8 NodeB, u8 LinkB) - * - * Description: - * This routine is called whenever two sublinks are both connected to the same CPUs. - * Normally, unganged subsinks between the same two CPUs are reganged. - * Return true from this routine to leave the links unganged. - * - * Parameters: - * @param[in] u8 nodeA = One node on which this link is located - * @param[in] u8 linkA = The link on this node - * @param[in] u8 nodeB = The other node on which this link is located - * @param[in] u8 linkB = The link on that node - * @param[out] BOOL result = true to leave link unganged - * false to regang link automatically - * - * --------------------------------------------------------------------------------------- - */ - BOOL (*AMD_CB_SkipRegang)( - u8 NodeA, - u8 LinkA, - u8 NodeB, - u8 LinkB - ); - - /**---------------------------------------------------------------------------------------- - * - * BOOL - * AMD_CB_CustomizeTrafficDistribution() - * - * Description: - * Near the end of HT initialization, this routine is called once. - * If this routine will handle traffic distribution in a proprietary way, - * after detecting which links to distribute traffic on and configuring the system, - * return true. Return false to let the HT code detect and do traffic distribution - * This routine can also be used to simply turn this feature off, or to pre-process - * the system before normal traffic distribution. - * - * Parameters: - * @param[out] BOOL result = true skip traffic distribution - * false do normal traffic distribution - * - * --------------------------------------------------------------------------------------- - */ - BOOL (*AMD_CB_CustomizeTrafficDistribution)(void); - - - /**---------------------------------------------------------------------------------------- - * - * BOOL - * AMD_CB_CustomizeBuffers(u8 Node) - * - * Description: - * Near the end of HT initialization, this routine is called once per CPU node. - * Implement proprietary buffer tuning and return true, or return false for normal tuning. - * This routine can also be used to simply turn this feature off, or to pre-process - * the system before normal tuning. - * - * Parameters: - * @param[in] u8 node = buffer allocation may apply to this node - * @param[out] BOOL result = true skip buffer allocation on this node - * false tune buffers normally - * - * --------------------------------------------------------------------------------------- - */ - BOOL (*AMD_CB_CustomizeBuffers)(u8 node); - - /**---------------------------------------------------------------------------------------- - * - * void - * AMD_CB_OverrideDevicePort(u8 HostNode, u8 HostLink, u8 Depth, u8 *LinkWidthIn, - * u8 *LinkWidthOut, u16 *LinkFrequency) - * - * Description: - * Called once for each active link on each IO device. - * Provides an opportunity to directly control the frequency and width, - * intended for test and debug. The input frequency and width will be used - * if not overridden. - * - * Parameters: - * @param[in] u8 hostNode = The node on which this link is located - * @param[in] u8 hostLink = The link about to be initialized - * @param[in] u8 Depth = The depth in the I/O chain from the Host - * @param[in] u8 Link = the link on the device (0 or 1) - * @param[in,out] u8 *LinkWidthIn = modify to change the Link Witdh In - * @param[in,out] u8 *LinkWidthOut = modify to change the Link Witdh Out - * @param[in,out] u16 *LinkFrequency = modify to change the link's frequency capability - * - * --------------------------------------------------------------------------------------- - */ - void (*AMD_CB_OverrideDevicePort)( - u8 HostNode, - u8 HostLink, - u8 Depth, - u8 Link, - u8 *LinkWidthIn, - u8 *LinkWidthOut, - u8 *LinkFrequency - ); - - /**---------------------------------------------------------------------------------------- - * - * void - * AMD_CB_OverrideCpuPort(u8 Node, u8 Link, u8 *LinkWidthIn, u8 *LinkWidthOut, - * u16 *LinkFrequency) - * - * Description: - * Called once for each active link on each CPU. - * Provides an opportunity to directly control the frequency and width, - * intended for test and debug. The input frequency and width will be used - * if not overridden. - * - * Parameters: - * @param[in] u8 node = One node on which this link is located - * @param[in] u8 link = The link on this node - * @param[in,out] u8 *LinkWidthIn = modify to change the Link Witdh In - * @param[in,out] u8 *LinkWidthOut = modify to change the Link Witdh Out - * @param[in,out] u16 *LinkFrequency = modify to change the link's frequency capability - * - *--------------------------------------------------------------------------------------- - */ - void (*AMD_CB_OverrideCpuPort)( - u8 Node, - u8 Link, - u8 *LinkWidthIn, - u8 *LinkWidthOut, - u8 *LinkFrequency - ); - - /**---------------------------------------------------------------------------------------- - * - * void - * AMD_CB_EventNotify(u8 evtClass, u16 event, const u8 *pEventData0) - * - * Description: - * Errors, events, faults, warnings, and useful information are provided by - * calling this routine as often as necessary, once for each notification. - * See elsewhere in this file for class, event, and event data definitions. - * See the documentation for more details. - * - * Parameters: - * @param[in] u8 evtClass = What level event is this - * @param[in] u16 event = A unique ID of this event - * @param[in] u8 *pEventData0 = useful data associated with the event. - * - * --------------------------------------------------------------------------------------- - */ - void (*AMD_CB_EventNotify) ( - u8 evtClass, - u16 event, - const u8 *pEventData0 - ); - - const struct ht_link_config *ht_link_configuration; - -} AMD_HTBLOCK; - -/* - * Event Notification Structures - * These structures are passed to AMD_CB_EventNotify as *pEventData0. - */ - -/* For event HT_EVENT_HW_SYNCHFLOOD */ -typedef struct -{ - u8 eSize; - u8 node; - u8 link; -} sHtEventHWSynchFlood; - -/* For event HT_EVENT_HW_HTCRC */ -typedef struct -{ - u8 eSize; - u8 node; - u8 link; - u8 laneMask; -} sHtEventHWHtCrc; - -/* For event HT_EVENT_NCOH_BUS_MAX_EXCEED */ -typedef struct -{ - u8 eSize; - u8 node; - u8 link; - u8 bus; -} sHTEventNcohBusMaxExceed; - -/* For event HT_EVENT_NCOH_LINK_EXCEED */ -typedef struct -{ - u8 eSize; - u8 node; - u8 link; - u8 depth; - u8 maxLinks; -} sHtEventNcohLinkExceed; - -/* For event HT_EVENT_NCOH_CFG_MAP_EXCEED */ -typedef struct -{ - u8 eSize; - u8 node; - u8 link; -} sHtEventNcohCfgMapExceed; - -/* For event HT_EVENT_NCOH_BUID_EXCEED */ -typedef struct -{ - u8 eSize; - u8 node; - u8 link; - u8 depth; - u8 currentBUID; - u8 unitCount; -} sHtEventNcohBuidExceed; - -/* For event HT_EVENT_NCOH_DEVICE_FAILED */ -typedef struct -{ - u8 eSize; - u8 node; - u8 link; - u8 depth; - u8 attemptedBUID; -} sHtEventNcohDeviceFailed; - -/* For event HT_EVENT_NCOH_AUTO_DEPTH */ -typedef struct -{ - u8 eSize; - u8 node; - u8 link; - u8 depth; -} sHtEventNcohAutoDepth; - -/* For event HT_EVENT_OPT_REQUIRED_CAP_RETRY, - * HT_EVENT_OPT_REQUIRED_CAP_GEN3 - */ -typedef struct -{ - u8 eSize; - u8 node; - u8 link; - u8 depth; -} sHtEventOptRequiredCap; - -/* For event HT_EVENT_COH_NO_TOPOLOGY */ -typedef struct -{ - u8 eSize; - u8 totalNodes; -} sHtEventCohNoTopology; - -/* For event HT_EVENT_COH_LINK_EXCEED */ -typedef struct -{ - u8 eSize; - u8 node; - u8 link; - u8 targetNode; - u8 totalNodes; - u8 maxLinks; -} sHtEventCohLinkExceed; - -/* For event HT_EVENT_COH_FAMILY_FEUD */ -typedef struct -{ - u8 eSize; - u8 node; - u8 link; - u8 totalNodes; -} sHtEventCohFamilyFeud; - -/* For event HT_EVENT_COH_NODE_DISCOVERED */ -typedef struct -{ - u8 eSize; - u8 node; - u8 link; - u8 newNode; -} sHtEventCohNodeDiscovered; - -/* For event HT_EVENT_COH_MPCAP_MISMATCH */ -typedef struct -{ - u8 eSize; - u8 node; - u8 link; - u8 sysMpCap; - u8 totalNodes; -} sHtEventCohMpCapMismatch; - -/*---------------------------------------------------------------------------- - * FUNCTIONS PROTOTYPE - * - *---------------------------------------------------------------------------- - */ -void amdHtInitialize(AMD_HTBLOCK *pBlock); - - -#endif /* H3FINIT_H */ diff --git a/src/northbridge/amd/amdht/h3gtopo.h b/src/northbridge/amd/amdht/h3gtopo.h deleted file mode 100644 index e211d4c006..0000000000 --- a/src/northbridge/amd/amdht/h3gtopo.h +++ /dev/null @@ -1,355 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * - * This program is free software * you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation * version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY * without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef HTTOPO_H -#define HTTOPO_H - -#include <stddef.h> - -/*---------------------------------------------------------------------------- - * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) - * - *---------------------------------------------------------------------------- - */ - -/*----------------------------------------------------------------------------- - * DEFINITIONS AND MACROS - * - *----------------------------------------------------------------------------- - */ - -/*---------------------------------------------------------------------------- - * TYPEDEFS, STRUCTURES, ENUMS - * - *---------------------------------------------------------------------------- - */ - -/* - * 0 - */ -static u8 const amdHtTopologySingleNode[] = { - 0x01, - 0x00, 0xFF // Node 0 -}; - -/* - * 0---1 - */ -static u8 const amdHtTopologyDualNode[] = { - 0x02, - 0x02, 0xFF, 0x00, 0x11, // Node 0 - 0x00, 0x00, 0x01, 0xFF // Node 1 -}; - -/* - * 2 - * | - * | - * 0---1 - */ -static u8 const amdHtTopologyThreeLine[] = { - 0x03, - 0x06, 0xFF, 0x04, 0x11, 0x02, 0x22, // Node 0 - 0x00, 0x00, 0x01, 0xFF, 0x00, 0x00, // Node 1 - 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF // Node 2 -}; - -/* - * 2 - * |\ - * | \ - * 0---1 - */ -static u8 const amdHtTopologyTriangle[] = { - 0x03, - 0x06, 0xFF, 0x00, 0x11, 0x00, 0x22, // Node 0 - 0x00, 0x00, 0x05, 0xFF, 0x00, 0x22, // Node 1 - 0x00, 0x00, 0x00, 0x11, 0x03, 0xFF // Node 2 -}; - -/* - * 2 3 - * |\ | - * | \| - * 0---1 - */ -static u8 const amdHtTopologyFourDegenerate[] = { - 0x04, - 0x06, 0xFF, 0x00, 0x11, 0x00, 0x22, 0x00, 0x11, // Node 0 - 0x08, 0x00, 0x0D, 0xFF, 0x08, 0x22, 0x05, 0x33, // Node 1 - 0x00, 0x00, 0x00, 0x11, 0x03, 0xFF, 0x00, 0x11, // Node 2 - 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x02, 0xFF // Node 3 -}; - -/* - * 2---3 - * |\ /| - * |/ \| - * 0---1 - */ -static u8 const amdHtTopologyFourFully[] = { - 0x04, - 0x0E, 0xFF, 0x00, 0x11, 0x00, 0x22, 0x00, 0x33, // Node 0 - 0x00, 0x00, 0x0D, 0xFF, 0x00, 0x22, 0x00, 0x33, // Node 1 - 0x00, 0x00, 0x00, 0x11, 0x0B, 0xFF, 0x00, 0x33, // Node 2 - 0x00, 0x00, 0x00, 0x11, 0x00, 0x22, 0x07, 0xFF // Node 3 -}; - - -/* - * 2---3 - * |\ | - * | \| - * 0---1 - */ -static u8 const amdHtTopologyFourKite[] = { - 0x04, - 0x06, 0xFF, 0x00, 0x11, 0x00, 0x22, 0x00, 0x11, // Node 0 - 0x08, 0x00, 0x0D, 0xFF, 0x00, 0x22, 0x00, 0x33, // Node 1 - 0x00, 0x00, 0x00, 0x11, 0x0B, 0xFF, 0x01, 0x33, // Node 2 - 0x00, 0x22, 0x00, 0x11, 0x00, 0x22, 0x06, 0xFF // Node 3 -}; - - -/* - * 2 3 - * | | - * | | - * 0---1 - */ -static u8 const amdHtTopologyFourLine[] = { - 0x04, - 0x06, 0xFF, 0x04, 0x11, 0x02, 0x22, 0x04, 0x11, // Node 0 - 0x08, 0x00, 0x09, 0xFF, 0x08, 0x00, 0x01, 0x33, // Node 1 - 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0x00, 0x00, // Node 2 - 0x00, 0x11, 0x00, 0x11, 0x00, 0x11, 0x02, 0xFF // Node 3 -}; - - -/* - * 2---3 - * | | - * | | - * 0---1 - */ -static u8 const amdHtTopologyFourSquare[] = { - 0x04, - 0x06, 0xFF, 0x00, 0x11, 0x02, 0x22, 0x00, 0x22, // Node 0 - 0x00, 0x00, 0x09, 0xFF, 0x00, 0x33, 0x01, 0x33, // Node 1 - 0x08, 0x00, 0x00, 0x00, 0x09, 0xFF, 0x00, 0x33, // Node 2 - 0x00, 0x11, 0x04, 0x11, 0x00, 0x22, 0x06, 0xFF, // Node 3 -}; - - -/* - * 2---3 - * |\ - * | \ - * 0 1 - */ -static u8 const amdHtTopologyFourStar[] = { - 0x04, - 0x04, 0xFF, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, // Node 0 - 0x00, 0x22, 0x04, 0xFF, 0x00, 0x22, 0x00, 0x22, // Node 1 - 0x0A, 0x00, 0x09, 0x11, 0x0B, 0xFF, 0x03, 0x33, // Node 2 - 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x04, 0xFF, // Node 3 -}; - - -static u8 const amdHtTopologyFiveFully[] = { - 0x05, - 0x1E, 0xFF, 0x00, 0x11, 0x00, 0x22, 0x00, 0x33, 0x00, 0x44, // Node 0 - 0x00, 0x00, 0x1D, 0xFF, 0x00, 0x22, 0x00, 0x33, 0x00, 0x44, // Node 1 - 0x00, 0x00, 0x00, 0x11, 0x1B, 0xFF, 0x00, 0x33, 0x00, 0x44, // Node 2 - 0x00, 0x00, 0x00, 0x11, 0x00, 0x22, 0x17, 0xFF, 0x00, 0x44, // Node 3 - 0x00, 0x00, 0x00, 0x11, 0x00, 0x22, 0x00, 0x33, 0x0F, 0xFF // Node 4 -}; - - -/* - * - * 4 - * |\ - * | \ - * 2 3 - * | | - * 0---1 - */ -static u8 const amdHtTopologyFiveTwistedLadder[] = { - 0x05, - 0x06, 0xFF, 0x04, 0x11, 0x02, 0x22, 0x00, 0x11, 0x00, 0x22, // Node0 - 0x08, 0x00, 0x09, 0xFF, 0x08, 0x00, 0x01, 0x33, 0x00, 0x30, // Node1 - 0x10, 0x00, 0x10, 0x00, 0x11, 0xFF, 0x00, 0x40, 0x01, 0x44, // Node2 - 0x00, 0x11, 0x00, 0x11, 0x00, 0x14, 0x12, 0xFF, 0x02, 0x44, // Node3 - 0x00, 0x22, 0x00, 0x23, 0x00, 0x22, 0x04, 0x33, 0x0C, 0xFF // Node4 -}; - - -static u8 const amdHtTopologySixFully[] = { - 0x06, - 0x3E, 0xFF, 0x00, 0x11, 0x00, 0x22, 0x00, 0x33, 0x00, 0x44, 0x00, 0x55, // Node 0 - 0x00, 0x00, 0x3D, 0xFF, 0x00, 0x22, 0x00, 0x33, 0x00, 0x44, 0x00, 0x55, // Node 1 - 0x00, 0x00, 0x00, 0x11, 0x3B, 0xFF, 0x00, 0x33, 0x00, 0x44, 0x00, 0x55, // Node 2 - 0x00, 0x00, 0x00, 0x11, 0x00, 0x22, 0x37, 0xFF, 0x00, 0x44, 0x00, 0x55, // Node 3 - 0x00, 0x00, 0x00, 0x11, 0x00, 0x22, 0x00, 0x33, 0x2F, 0xFF, 0x00, 0x55, // Node 4 - 0x00, 0x00, 0x00, 0x11, 0x00, 0x22, 0x00, 0x33, 0x00, 0x44, 0x1F, 0xFF // Node 5 -}; - -/* - * - * 4 5 - * |\ /| - * |/ \| - * 2 3 - * | | - * 0---1 - */ -static u8 const amdHtTopologySixTwistedLadder[] = { - 0x06, - 0x06, 0xFF, 0x04, 0x11, 0x02, 0x22, 0x00, 0x11, 0x02, 0x22, 0x00, 0x12, // Node0 - 0x08, 0x00, 0x09, 0xFF, 0x00, 0x00, 0x01, 0x33, 0x00, 0x03, 0x01, 0x33, // Node1 - 0x30, 0x00, 0x00, 0x00, 0x31, 0xFF, 0x00, 0x54, 0x21, 0x44, 0x00, 0x55, // Node2 - 0x00, 0x11, 0x30, 0x11, 0x00, 0x45, 0x32, 0xFF, 0x00, 0x44, 0x12, 0x55, // Node3 - 0x00, 0x22, 0x00, 0x32, 0x08, 0x22, 0x00, 0x33, 0x0C, 0xFF, 0x00, 0x32, // Node4 - 0x00, 0x23, 0x00, 0x33, 0x00, 0x22, 0x04, 0x33, 0x00, 0x23, 0x0C, 0xFF // Node5 -}; - - -static u8 const amdHtTopologySevenFully[] = { - 0x07, - 0x7E, 0xFF, 0x00, 0x11, 0x00, 0x22, 0x00, 0x33, 0x00, 0x44, 0x00, 0x55, 0x00, 0x66, // Node 0 - 0x00, 0x00, 0x7D, 0xFF, 0x00, 0x22, 0x00, 0x33, 0x00, 0x44, 0x00, 0x55, 0x00, 0x66, // Node 1 - 0x00, 0x00, 0x00, 0x11, 0x7B, 0xFF, 0x00, 0x33, 0x00, 0x44, 0x00, 0x55, 0x00, 0x66, // Node 2 - 0x00, 0x00, 0x00, 0x11, 0x00, 0x22, 0x77, 0xFF, 0x00, 0x44, 0x00, 0x55, 0x00, 0x66, // Node 3 - 0x00, 0x00, 0x00, 0x11, 0x00, 0x22, 0x00, 0x33, 0x6F, 0xFF, 0x00, 0x55, 0x00, 0x66, // Node 4 - 0x00, 0x00, 0x00, 0x11, 0x00, 0x22, 0x00, 0x33, 0x00, 0x44, 0x5F, 0xFF, 0x00, 0x66, // Node 5 - 0x00, 0x00, 0x00, 0x11, 0x00, 0x22, 0x00, 0x33, 0x00, 0x44, 0x00, 0x55, 0x3F, 0xFF, // Node 6 -}; - - -/* 6 - * | - * 4 5 - * |\ /| - * |/ \| - * 2 3 - * | | - * 0---1 - */ -static u8 const amdHtTopologySevenTwistedLadder[] = { - 0x07, - 0x06, 0xFF, 0x00, 0x11, 0x02, 0x22, 0x00, 0x12, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, // Node0 - 0x00, 0x00, 0x09, 0xFF, 0x00, 0x03, 0x01, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, // Node1 - 0x30, 0x00, 0x00, 0x50, 0x31, 0xFF, 0x00, 0x54, 0x21, 0x44, 0x01, 0x55, 0x21, 0x44, // Node2 - 0x00, 0x41, 0x30, 0x11, 0x00, 0x45, 0x32, 0xFF, 0x02, 0x44, 0x12, 0x55, 0x02, 0x44, // Node3 - 0x48, 0x22, 0x40, 0x33, 0x48, 0x22, 0x40, 0x33, 0x4C, 0xFF, 0x40, 0x32, 0x0C, 0x66, // Node4 - 0x00, 0x22, 0x04, 0x33, 0x00, 0x22, 0x04, 0x33, 0x00, 0x23, 0x0C, 0xFF, 0x00, 0x23, // Node5 - 0x00, 0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0x44, 0x10, 0xFF // Node6 -}; - - -/* - * 5--4 - * /####\ - * 6######3 - * |######| - * 7######2 - * \####/ - * 0--1 - */ -static u8 const amdHtTopologyEightFully [] = { - 0x08, - 0xFE, 0xFF, 0x00, 0x11, 0x00, 0x22, 0x00, 0x33, 0x00, 0x44, 0x00, 0x55, 0x00, 0x66, 0x00, 0x77, // Node 0 - 0x00, 0x00, 0xFD, 0xFF, 0x00, 0x22, 0x00, 0x33, 0x00, 0x44, 0x00, 0x55, 0x00, 0x66, 0x00, 0x77, // Node 1 - 0x00, 0x00, 0x00, 0x11, 0xFB, 0xFF, 0x00, 0x33, 0x00, 0x44, 0x00, 0x55, 0x00, 0x66, 0x00, 0x77, // Node 2 - 0x00, 0x00, 0x00, 0x11, 0x00, 0x22, 0xF7, 0xFF, 0x00, 0x44, 0x00, 0x55, 0x00, 0x66, 0x00, 0x77, // Node 3 - 0x00, 0x00, 0x00, 0x11, 0x00, 0x22, 0x00, 0x33, 0xEF, 0xFF, 0x00, 0x55, 0x00, 0x66, 0x00, 0x77, // Node 4 - 0x00, 0x00, 0x00, 0x11, 0x00, 0x22, 0x00, 0x33, 0x00, 0x44, 0xDF, 0xFF, 0x00, 0x66, 0x00, 0x77, // Node 5 - 0x00, 0x00, 0x00, 0x11, 0x00, 0x22, 0x00, 0x33, 0x00, 0x44, 0x00, 0x55, 0xBF, 0xFF, 0x00, 0x77, // Node 6 - 0x00, 0x00, 0x00, 0x11, 0x00, 0x22, 0x00, 0x33, 0x00, 0x44, 0x00, 0x55, 0x00, 0x66, 0x7F, 0xFF // Node 7 -}; - - -/* 6---7 - * | | - * 4---5 - * | | - * 2---3 - * | | - * 0---1 - */ -static u8 const amdHtTopologyEightStraightLadder[] = { - 0x08, - 0x06, 0xFF, 0x00, 0x11, 0x02, 0x22, 0x00, 0x22, 0x02, 0x22, 0x00, 0x22, 0x02, 0x22, 0x00, 0x22, // Node0 - 0x00, 0x00, 0x09, 0xFF, 0x00, 0x33, 0x01, 0x33, 0x00, 0x33, 0x01, 0x33, 0x00, 0x33, 0x01, 0x33, // Node1 - 0x18, 0x00, 0x00, 0x00, 0x19, 0xFF, 0x00, 0x33, 0x09, 0x44, 0x00, 0x44, 0x09, 0x44, 0x00, 0x44, // Node2 - 0x00, 0x11, 0x24, 0x11, 0x00, 0x22, 0x26, 0xFF, 0x00, 0x55, 0x06, 0x55, 0x00, 0x55, 0x06, 0x55, // Node3 - 0x60, 0x22, 0x00, 0x22, 0x60, 0x22, 0x00, 0x22, 0x64, 0xFF, 0x00, 0x55, 0x24, 0x66, 0x00, 0x66, // Node4 - 0x00, 0x33, 0x90, 0x33, 0x00, 0x33, 0x90, 0x33, 0x00, 0x44, 0x98, 0xFF, 0x00, 0x77, 0x18, 0x77, // Node5 - 0x80, 0x44, 0x00, 0x44, 0x80, 0x44, 0x00, 0x44, 0x80, 0x44, 0x00, 0x44, 0x90, 0xFF, 0x00, 0x77, // Node6 - 0x00, 0x55, 0x40, 0x55, 0x00, 0x55, 0x40, 0x55, 0x00, 0x55, 0x40, 0x55, 0x00, 0x66, 0x60, 0xFF // Node7 -}; - - -/* 6---7 - * | | - * 4 5 - * |\ /| - * |/ \| - * 2 3 - * | | - * 0---1 - */ -static u8 const amdHtTopologyEightTwistedLadder[] = { - 0x08, - 0x06, 0xFF, 0x00, 0x11, 0x02, 0x22, 0x00, 0x12, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, 0x00, 0x22, // Node0 - 0x00, 0x00, 0x09, 0xFF, 0x00, 0x03, 0x01, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, 0x00, 0x33, // Node1 - 0x30, 0x00, 0x00, 0x50, 0x31, 0xFF, 0x00, 0x54, 0x21, 0x44, 0x01, 0x55, 0x21, 0x44, 0x01, 0x55, // Node2 - 0x00, 0x41, 0x30, 0x11, 0x00, 0x45, 0x32, 0xFF, 0x02, 0x44, 0x12, 0x55, 0x02, 0x44, 0x12, 0x55, // Node3 - 0x48, 0x22, 0x40, 0x33, 0x48, 0x22, 0x40, 0x33, 0x4C, 0xFF, 0x00, 0x32, 0x0C, 0x66, 0x00, 0x36, // Node4 - 0x80, 0x22, 0x84, 0x33, 0x80, 0x22, 0x84, 0x33, 0x00, 0x23, 0x8C, 0xFF, 0x00, 0x27, 0x0C, 0x77, // Node5 - 0x00, 0x44, 0x00, 0x44, 0x00, 0x44, 0x00, 0x44, 0x80, 0x44, 0x00, 0x74, 0x90, 0xFF, 0x00, 0x77, // Node6 - 0x00, 0x55, 0x00, 0x55, 0x00, 0x55, 0x00, 0x55, 0x00, 0x65, 0x40, 0x55, 0x00, 0x66, 0x60, 0xFF // Node7 -}; - -static const u8 *const amd_topo_list[] = { - amdHtTopologySingleNode, - amdHtTopologyDualNode, - amdHtTopologyThreeLine, - amdHtTopologyTriangle, - amdHtTopologyFourLine, - amdHtTopologyFourStar, - amdHtTopologyFourDegenerate, - amdHtTopologyFourSquare, - amdHtTopologyFourKite, - amdHtTopologyFourFully, - amdHtTopologyFiveFully, - amdHtTopologySixFully, - amdHtTopologySevenFully, - amdHtTopologyEightFully, - amdHtTopologyEightTwistedLadder, - amdHtTopologyEightStraightLadder, - NULL // NULL to mark end of list -}; - -/*---------------------------------------------------------------------------- - * FUNCTIONS PROTOTYPE - * - *---------------------------------------------------------------------------- - */ -void getAmdTopolist(u8 ***p); - - -#endif /* HTTOPO_H */ diff --git a/src/northbridge/amd/amdht/h3ncmn.c b/src/northbridge/amd/amdht/h3ncmn.c deleted file mode 100644 index 830e9888c9..0000000000 --- a/src/northbridge/amd/amdht/h3ncmn.c +++ /dev/null @@ -1,2549 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - - -/*---------------------------------------------------------------------------- - * MODULES USED - * - *---------------------------------------------------------------------------- - */ - -#include "h3ncmn.h" -#include "h3finit.h" -#include "h3ffeat.h" -#include "AsPsNb.h" - -#include <arch/cpu.h> -#include <device/pci.h> -#include <cpu/amd/msr.h> -#include <device/pci_def.h> -#include <northbridge/amd/amdfam10/raminit.h> -#include <northbridge/amd/amdfam10/amdfam10.h> - -/*---------------------------------------------------------------------------- - * DEFINITIONS AND MACROS - * - *---------------------------------------------------------------------------- - */ - -/* CPU Northbridge Functions */ -#define CPU_HTNB_FUNC_00 0 -#define CPU_HTNB_FUNC_04 4 -#define CPU_ADDR_FUNC_01 1 -#define CPU_NB_FUNC_03 3 -#define CPU_NB_FUNC_05 5 - -/* Function 0 registers */ -#define REG_ROUTE0_0X40 0x40 -#define REG_ROUTE1_0X44 0x44 -#define REG_NODE_ID_0X60 0x60 -#define REG_UNIT_ID_0X64 0x64 -#define REG_LINK_TRANS_CONTROL_0X68 0x68 -#define REG_LINK_INIT_CONTROL_0X6C 0x6c -#define REG_HT_CAP_BASE_0X80 0x80 -#define REG_NORTHBRIDGE_CFG_3X8C 0x8c -#define REG_HT_LINK_RETRY0_0X130 0x130 -#define REG_HT_TRAFFIC_DIST_0X164 0x164 -#define REG_HT_LINK_EXT_CONTROL0_0X170 0x170 - -#define HT_CONTROL_CLEAR_CRC (~(3 << 8)) - -/* Function 1 registers */ -#define REG_ADDR_CONFIG_MAP0_1XE0 0xE0 -#define CPU_ADDR_NUM_CONFIG_MAPS 4 - -/* Function 3 registers */ -#define REG_NB_SRI_XBAR_BUF_3X70 0x70 -#define REG_NB_MCT_XBAR_BUF_3X78 0x78 -#define REG_NB_FIFOPTR_3XDC 0xDC -#define REG_NB_CAPABILITY_3XE8 0xE8 -#define REG_NB_CPUID_3XFC 0xFC -#define REG_NB_LINK_XCS_TOKEN0_3X148 0x148 -#define REG_NB_DOWNCORE_3X190 0x190 -#define REG_NB_CAPABILITY_5X84 0x84 - -/* Function 4 registers */ - - -/*---------------------------------------------------------------------------- - * TYPEDEFS AND STRUCTURES - * - *---------------------------------------------------------------------------- - */ -/*---------------------------------------------------------------------------- - * PROTOTYPES OF LOCAL FUNCTIONS - * - *---------------------------------------------------------------------------- - */ - -/*************************************************************************** - *** FAMILY/NORTHBRIDGE SPECIFIC FUNCTIONS *** - ***************************************************************************/ - -inline uint8_t is_gt_rev_d(void) -{ - uint8_t fam15h = 0; - uint8_t rev_gte_d = 0; - uint32_t family; - uint32_t model; - - family = model = cpuid_eax(0x80000001); - model = ((model & 0xf0000) >> 12) | ((model & 0xf0) >> 4); - family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8); - - if (family >= 0x6f) - /* Family 15h or later */ - fam15h = 1; - - if ((model >= 0x8) || fam15h) - /* Revision D or later */ - rev_gte_d = 1; - - return rev_gte_d; -} - -/***************************************************************************//** - * - * SBDFO - * makeLinkBase(u8 currentNode, u8 currentLink) - * - * Description: - * Private to northbridge implementation. Return the HT Host capability base - * PCI config address for a link. - * - * Parameters: - * @param[in] node = the node this link is on - * @param[in] link = the link - * - *****************************************************************************/ -static SBDFO makeLinkBase(u8 node, u8 link) -{ - SBDFO linkBase; - - /* With rev F can not be called with a 4th link or with the sublinks */ - if (link < 4) - linkBase = MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_HTNB_FUNC_00, - REG_HT_CAP_BASE_0X80 + link*HT_HOST_CAP_SIZE); - else - linkBase = MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_HTNB_FUNC_04, - REG_HT_CAP_BASE_0X80 + (link-4)*HT_HOST_CAP_SIZE); - return linkBase; -} - -/***************************************************************************//** - * - * void - * setHtControlRegisterBits(SBDFO reg, u8 hiBit, u8 loBit, u32 *pValue) - * - * Description: - * Private to northbridge implementation. Provide a common routine for accessing the - * HT Link Control registers (84, a4, c4, e4), to enforce not clearing the - * HT CRC error bits. Replaces direct use of AmdPCIWriteBits(). - * NOTE: This routine is called for IO Devices as well as CPUs! - * - * Parameters: - * @param[in] reg = the PCI config address the control register - * @param[in] hiBit = the high bit number - * @param[in] loBit = the low bit number - * @param[in] pValue = the value to write to that bit range. Bit 0 => loBit. - * - *****************************************************************************/ -static void setHtControlRegisterBits(SBDFO reg, u8 hiBit, u8 loBit, u32 *pValue) -{ - u32 temp, mask; - - ASSERT((hiBit < 32) && (loBit < 32) && (hiBit >= loBit) && ((reg & 0x3) == 0)); - ASSERT((hiBit < 8) || (loBit > 9)); - - /* A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case */ - if ((hiBit-loBit) != 31) - mask = (((u32)1 << (hiBit-loBit+1))-1); - else - mask = (u32)0xFFFFFFFF; - - AmdPCIRead(reg, &temp); - temp &= ~(mask << loBit); - temp |= (*pValue & mask) << loBit; - temp &= (u32)HT_CONTROL_CLEAR_CRC; - AmdPCIWrite(reg, &temp); -} - -/***************************************************************************//** - * - * static void - * writeRoutingTable(u8 node, u8 target, u8 Link, cNorthBridge *nb) - * - * Description: - * 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. - * - * Parameters: - * @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 - * - *****************************************************************************/ - -static void writeRoutingTable(u8 node, u8 target, u8 link, cNorthBridge *nb) -{ -#ifndef HT_BUILD_NC_ONLY - u32 temp = (nb->selfRouteResponseMask | nb->selfRouteRequestMask) << (link + 1); - ASSERT((node < nb->maxNodes) && (target < nb->maxNodes) && (link < nb->maxLinks)); - AmdPCIWrite(MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_HTNB_FUNC_00, - REG_ROUTE0_0X40 + target*4), - &temp); -#else - STOP_HERE; -#endif -} - -/***************************************************************************//** - * - * static void - * writeNodeID(u8 node, u8 nodeID, cNorthBridge *nb) - * - * Description: - * Modifies the NodeID register on the target node - * - * Parameters: - * @param[in] node = the node that will have its NodeID altered. - * @param[in] nodeID = the new value for NodeID - * @param[in] *nb = this northbridge - * - *****************************************************************************/ - -static void writeNodeID(u8 node, u8 nodeID, cNorthBridge *nb) -{ - u32 temp; - ASSERT((node < nb->maxNodes) && (nodeID < nb->maxNodes)); - if (is_fam15h()) { - temp = 1; - AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_NB_FUNC_03, - REG_NORTHBRIDGE_CFG_3X8C), - 22, 22, &temp); - } - temp = nodeID; - AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_HTNB_FUNC_00, - REG_NODE_ID_0X60), - 2, 0, &temp); -} - -/***************************************************************************//** - * - * static void - * readDefLnk(u8 node, cNorthBridge *nb) - * - * Description: - * Read the DefLnk (the source link of the current packet) - * from node - * - * Parameters: - * @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. Since this - * code is running on the BSP, this should be the link - * pointing back towards the BSP. - * - *****************************************************************************/ - -static u8 readDefLnk(u8 node, cNorthBridge *nb) -{ - u32 deflink = 0; - SBDFO licr; - u32 temp; - - licr = MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_HTNB_FUNC_00, - REG_LINK_INIT_CONTROL_0X6C); - - ASSERT((node < nb->maxNodes)); - AmdPCIReadBits(licr, 3, 2, &deflink); - AmdPCIReadBits(licr, 8, 8, &temp); /* on rev F, this bit is reserved == 0 */ - deflink |= temp << 2; - return (u8)deflink; -} - -/***************************************************************************//** - * - * static void - * enableRoutingTables(u8 node, cNorthBridge *nb) - * - * Description: - * Turns routing tables on for a given node - * - * Parameters: - * @param[in] node = the node that will have it's routing tables enabled - * @param[in] *nb = this northbridge - * - *****************************************************************************/ - -static void enableRoutingTables(u8 node, cNorthBridge *nb) -{ - u32 temp = 0; - ASSERT((node < nb->maxNodes)); - AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_HTNB_FUNC_00, - REG_LINK_INIT_CONTROL_0X6C), - 0, 0, &temp); -} - - -/***************************************************************************//** - * - * static BOOL - * verifyLinkIsCoherent(u8 node, u8 Link, cNorthBridge *nbk) - * - * Description: - * Verify that the link is coherent, connected, and ready - * - * Parameters: - * @param[in] node = the node that will be examined - * @param[in] link = the link on that Node to examine - * @param[in] *nb = this northbridge - * @return true - The link has the following status - * linkCon = 1, Link is connected - * InitComplete = 1, Link initialization is complete - * NC = 0, Link is coherent - * UniP-cLDT = 0, Link is not Uniprocessor cLDT - * LinkConPend = 0 Link connection is not pending - * false- The link has some other status - * - *****************************************************************************/ - -static BOOL verifyLinkIsCoherent(u8 node, u8 link, cNorthBridge *nb) -{ -#ifndef HT_BUILD_NC_ONLY - - u32 linkType; - SBDFO linkBase; - - ASSERT((node < nb->maxNodes) && (link < nb->maxLinks)); - - linkBase = makeLinkBase(node, link); - - /* FN0_98/A4/C4 = LDT Type Register */ - AmdPCIRead(linkBase + HTHOST_LINK_TYPE_REG, &linkType); - - /* Verify LinkCon = 1, InitComplete = 1, NC = 0, UniP-cLDT = 0, LinkConPend = 0 */ - return (linkType & HTHOST_TYPE_MASK) == HTHOST_TYPE_COHERENT; -#else - return 0; -#endif /* HT_BUILD_NC_ONLY */ -} - -/***************************************************************************//** - * - * static bool - * readTrueLinkFailStatus(u8 node, u8 link, sMainData *pDat, cNorthBridge *nb) - * - * Description: - * Return the LinkFailed status AFTER an attempt is made to clear the bit. - * Also, call event notify if a Hardware Fault caused a synch flood on a previous boot. - * - * The table below summarizes correct responses of this routine. - * Family before after unconnected Notify? return - * 0F 0 0 0 No 0 - * 0F 1 0 0 Yes 0 - * 0F 1 1 X No 1 - * 10 0 0 0 No 0 - * 10 1 0 0 Yes 0 - * 10 1 0 3 No 1 - * - * Parameters: - * @param[in] node = the node that will be examined - * @param[in] link = the link on that node to examine - * @param[in] *pDat = access to call back routine - * @param[in] *nb = this northbridge - * @return true - the link is not connected or has hard error - * false- if the link is connected - * - *****************************************************************************/ - -static BOOL readTrueLinkFailStatus(u8 node, u8 link, sMainData *pDat, cNorthBridge *nb) -{ - u32 before, after, unconnected, crc; - SBDFO linkBase; - - ASSERT((node < nb->maxNodes) && (link < nb->maxLinks)); - - linkBase = makeLinkBase(node, link); - - /* Save the CRC status before doing anything else. - * Read, Clear, the Re-read the error bits in the Link Control Register - * FN0_84/A4/C4[4] = LinkFail bit - * and the connection status, TransOff and EndOfChain - */ - AmdPCIReadBits(linkBase + HTHOST_LINK_CONTROL_REG, 9, 8, &crc); - AmdPCIReadBits(linkBase + HTHOST_LINK_CONTROL_REG, 4, 4, &before); - setHtControlRegisterBits(linkBase + HTHOST_LINK_CONTROL_REG, 4, 4, &before); - AmdPCIReadBits(linkBase + HTHOST_LINK_CONTROL_REG, 4, 4, &after); - AmdPCIReadBits(linkBase + HTHOST_LINK_CONTROL_REG, 7, 6, &unconnected); - - if (before != after) - { - if (!unconnected) - { - if (crc != 0) - { - /* A synch flood occurred due to HT CRC */ - if (pDat->HtBlock->AMD_CB_EventNotify) - { - /* Pass the node and link on which the generic synch flood event occurred. */ - sHtEventHWHtCrc evt; - evt.eSize = sizeof(sHtEventHWHtCrc); - evt.node = node; - evt.link = link; - evt.laneMask = (uint8)crc; - - pDat->HtBlock->AMD_CB_EventNotify(HT_EVENT_CLASS_HW_FAULT, - HT_EVENT_HW_HTCRC, - (u8 *)&evt); - } - } - else - { - /* Some synch flood occurred */ - if (pDat->HtBlock->AMD_CB_EventNotify) - { - /* Pass the node and link on which the generic synch flood event occurred. */ - sHtEventHWSynchFlood evt; - evt.eSize = sizeof(sHtEventHWSynchFlood); - evt.node = node; - evt.link = link; - - pDat->HtBlock->AMD_CB_EventNotify(HT_EVENT_CLASS_HW_FAULT, - HT_EVENT_HW_SYNCHFLOOD, - (u8 *)&evt); - } - } - } - } - return ((after != 0) || unconnected); -} - - -/***************************************************************************//** - * - * static u8 - * readToken(u8 node, cNorthBridge *nb) - * - * Description: - * Read the token stored in the scratchpad register - * 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. - * - * Parameters: - * @param[in] node = the node that will be examined - * @param[in] *nb = this northbridge - * @return the Token read from the node - * - *****************************************************************************/ -static u8 readToken(u8 node, cNorthBridge *nb) -{ - u32 temp; - - ASSERT((node < nb->maxNodes)); - /* Use CpuCnt as a scratch register */ - /* Limiting use to 4 bits makes code GH to rev F compatible. */ - AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_HTNB_FUNC_00, - REG_NODE_ID_0X60), - 19, 16, &temp); - - return (u8)temp; -} - - -/***************************************************************************//** - * - * static void - * writeToken(u8 node, u8 Value, cNorthBridge *nb) - * - * Description: - * Write the token stored in the scratchpad register - * 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. - * Limiting use to 4 bits makes code GH to rev F compatible. - * - * Parameters: - * @param[in] node = the node that will be examined - * @param value - * @param[in] *nb = this northbridge - * - *****************************************************************************/ -static void writeToken(u8 node, u8 value, cNorthBridge *nb) -{ - u32 temp = value; - ASSERT((node < nb->maxNodes)); - /* Use CpuCnt as a scratch register */ - /* Limiting use to 4 bits makes code GH to rev F compatible. */ - AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_HTNB_FUNC_00, - REG_NODE_ID_0X60), - 19, 16, &temp); -} - -/***************************************************************************//** - * - * static u8 - * fam0FGetNumCoresOnNode(u8 node, cNorthBridge *nb) - * - * Description: - * Return the number of cores (1 based count) on node. - * - * Parameters: - * @param[in] node = the node that will be examined - * @param[in] *nb = this northbridge - * @return = the number of cores - * - * --------------------------------------------------------------------------------------- - */ -static u8 fam0FGetNumCoresOnNode(u8 node, cNorthBridge *nb) -{ - u32 temp; - - ASSERT((node < nb->maxNodes)); - /* Read CmpCap */ - AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_NB_FUNC_03, - REG_NB_CAPABILITY_3XE8), - 13, 12, &temp); - - /* and add one */ - return (u8)(temp+1); -} - -/***************************************************************************//** - * - * static u8 - * fam10GetNumCoresOnNode(u8 node, cNorthBridge *nb) - * - * Description: - * Return the number of cores (1 based count) on node. - * - * Parameters: - * @param[in] node = the node that will be examined - * @param[in] *nb = this northbridge - * @return = the number of cores - * - * - */ -static u8 fam10GetNumCoresOnNode(u8 node, cNorthBridge *nb) -{ - u32 temp, leveling, cores; - u8 i; - - ASSERT((node < nb->maxNodes)); - /* Read CmpCap [2][1:0] */ - AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_NB_FUNC_03, - REG_NB_CAPABILITY_3XE8), - 15, 12, &temp); - - /* bits[15,13,12] specify the cores */ - temp = ((temp & 8) >> 1) + (temp & 3); - cores = temp + 1; - - /* Support Downcoring */ - AmdPCIReadBits (MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_NB_FUNC_03, - REG_NB_DOWNCORE_3X190), - 3, 0, &leveling); - for (i = 0; i < cores; i++) - { - if (leveling & ((u32) 1 << i)) - { - temp--; - } - } - return (u8)(temp+1); -} - -/***************************************************************************//** - * - * static u8 - * fam15GetNumCoresOnNode(u8 node, cNorthBridge *nb) - * - * Description: - * Return the number of cores (1 based count) on node. - * - * Parameters: - * @param[in] node = the node that will be examined - * @param[in] *nb = this northbridge - * @return = the number of cores - * - * - */ -static u8 fam15GetNumCoresOnNode(u8 node, cNorthBridge *nb) -{ - u32 temp, leveling, cores; - u8 i; - - ASSERT((node < nb->maxNodes)); - /* Read CmpCap [7:0] */ - AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_NB_FUNC_05, - REG_NB_CAPABILITY_5X84), - 7, 0, &temp); - - /* bits[7:0] specify the cores */ - temp = temp & 0xff; - cores = temp + 1; - - /* Support Downcoring */ - AmdPCIReadBits (MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_NB_FUNC_03, - REG_NB_DOWNCORE_3X190), - 31, 0, &leveling); - for (i = 0; i < cores; i++) - { - if (leveling & ((u32) 1 << i)) - { - temp--; - } - } - return (u8)(temp+1); -} - -/***************************************************************************//** - * - * static void - * setTotalNodesAndCores(u8 node, u8 totalNodes, u8 totalCores, cNorthBridge *nb) - * - * Description: - * Write the total number of cores and nodes to the node - * - * Parameters: - * @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 - * - * --------------------------------------------------------------------------------------- - */ -static void setTotalNodesAndCores(u8 node, u8 totalNodes, u8 totalCores, cNorthBridge *nb) -{ - SBDFO nodeIDReg; - u32 temp; - - ASSERT((node < nb->maxNodes) && (totalNodes <= nb->maxNodes)); - nodeIDReg = MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_HTNB_FUNC_00, - REG_NODE_ID_0X60); - - temp = totalCores-1; - /* Rely on max number of nodes:cores for rev F and GH to make - * this code work, even though we write reserved bit 20 on rev F it will be - * zero in that case. - */ - AmdPCIWriteBits(nodeIDReg, 20, 16, &temp); - temp = totalNodes-1; - AmdPCIWriteBits(nodeIDReg, 6, 4, &temp); -} - -/***************************************************************************//** - * - * static void - * limitNodes(u8 node, cNorthBridge *nb) - * - * Description: - * Limit coherent config accesses to cpus as indicated by nodecnt. - * - * Parameters: - * @param[in] node = the node that will be examined - * @param[in] *nb = this northbridge - * - * --------------------------------------------------------------------------------------- - */ -static void limitNodes(u8 node, cNorthBridge *nb) -{ - u32 temp = 1; - ASSERT((node < nb->maxNodes)); - AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_HTNB_FUNC_00, - REG_LINK_TRANS_CONTROL_0X68), - 15, 15, &temp); -} - -/***************************************************************************//** - * - * static void - * writeFullRoutingTable(u8 node, u8 target, u8 reqLink, u8 rspLink, u32 BClinks, cNorthBridge *nb) - * - * Description: - * Write the routing table entry for node to target, using the request link, response - * link, and broadcast links provided. - * - * Parameters: - * @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] bClinks = the broadcast links - * @param[in] *nb = this northbridge - * - * --------------------------------------------------------------------------------------- - */ -static void writeFullRoutingTable(u8 node, u8 target, u8 reqLink, u8 rspLink, u32 bClinks, cNorthBridge *nb) -{ -#ifndef HT_BUILD_NC_ONLY - u32 value = 0; - - ASSERT((node < nb->maxNodes) && (target < nb->maxNodes)); - if (reqLink == ROUTETOSELF) - value |= nb->selfRouteRequestMask; - else - value |= nb->selfRouteRequestMask << (reqLink+1); - - if (rspLink == ROUTETOSELF) - value |= nb->selfRouteResponseMask; - else - value |= nb->selfRouteResponseMask << (rspLink+1); - - /* Allow us to accept a Broadcast ourselves, then set broadcasts for routes */ - value |= (u32)1 << nb->broadcastSelfBit; - value |= (u32)bClinks << (nb->broadcastSelfBit + 1); - - AmdPCIWrite(MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_HTNB_FUNC_00, - REG_ROUTE0_0X40 + target*4), &value); -#else - STOP_HERE; -#endif /* HT_BUILD_NC_ONLY */ -} - -/***************************************************************************//** - * - * static u32 - * makeKey(u8 currentNode) - * - * Description: - * Private routine to northbridge code. - * 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. - * - * Parameters: - * @param[in] node = the node - * @return = the key value - * - * --------------------------------------------------------------------------------------- - */ -static u32 makeKey(u8 node) -{ - u32 extFam, baseFam; - AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_NB_FUNC_03, - REG_NB_CPUID_3XFC), - 27, 20, &extFam); - AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_NB_FUNC_03, - REG_NB_CPUID_3XFC), - 11, 8, &baseFam); - return ((u32)(baseFam << 8) | extFam); -} - - -/***************************************************************************//** - * - * static BOOL - * isCompatible(u8 currentNode, cNorthBridge *nb) - * - * Description: - * 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. - * - * Parameters: - * @param[in] node = the node - * @param[in] *nb = this northbridge - * @return = true: the new is compatible, false: it is not - * - * --------------------------------------------------------------------------------------- - */ -static BOOL isCompatible(u8 node, cNorthBridge *nb) -{ - return (makeKey(node) == nb->compatibleKey); -} - -/***************************************************************************//** - * - * static BOOL - * fam0fIsCapable(u8 node, sMainData *pDat, cNorthBridge *nb) - * - * Description: - * Get node capability and update the minimum supported system capability. - * Return whether the current configuration exceeds the capability. - * - * Parameters: - * @param[in] node = the node - * @param[in,out] *pDat = sysMpCap (updated) and NodesDiscovered - * @param[in] *nb = this northbridge - * @return true: system is capable of current config. - * false: system is not capable of current config. - * - * --------------------------------------------------------------------------------------- - */ -static BOOL fam0fIsCapable(u8 node, sMainData *pDat, cNorthBridge *nb) -{ -#ifndef HT_BUILD_NC_ONLY - u32 temp; - u8 maxNodes; - - ASSERT(node < nb->maxNodes); - - AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_NB_FUNC_03, - REG_NB_CAPABILITY_3XE8), - 2, 1, &temp); - if (temp > 1) - { - maxNodes = 8; - } else { - if (temp == 1) - { - maxNodes = 2; - } else { - maxNodes = 1; - } - } - if (pDat->sysMpCap > maxNodes) - { - pDat->sysMpCap = maxNodes; - } - /* Note since sysMpCap is one based and NodesDiscovered is zero based, equal is false */ - return (pDat->sysMpCap > pDat->NodesDiscovered); -#else - return 1; -#endif -} - -/***************************************************************************//** - * - * static BOOL - * fam10IsCapable(u8 node, sMainData *pDat, cNorthBridge *nb) - * - * Description: - * Get node capability and update the minimum supported system capability. - * Return whether the current configuration exceeds the capability. - * - * Parameters: - * @param[in] node = the node - * @param[in,out] *pDat = sysMpCap (updated) and NodesDiscovered - * @param[in] *nb = this northbridge - * @return true: system is capable of current config. - * false: system is not capable of current config. - * - * --------------------------------------------------------------------------------------- - */ -static BOOL fam10IsCapable(u8 node, sMainData *pDat, cNorthBridge *nb) -{ -#ifndef HT_BUILD_NC_ONLY - u32 temp; - u8 maxNodes; - - ASSERT(node < nb->maxNodes); - - AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_NB_FUNC_03, - REG_NB_CAPABILITY_3XE8), - 18, 16, &temp); - - if (temp != 0) - { - maxNodes = (1 << (~temp & 0x3)); /* That is, 1, 2, 4, or 8 */ - } - else - { - maxNodes = 8; - } - - if (pDat->sysMpCap > maxNodes) - { - pDat->sysMpCap = maxNodes; - } - /* Note since sysMpCap is one based and NodesDiscovered is zero based, equal is false */ - return (pDat->sysMpCap > pDat->NodesDiscovered); -#else - return 1; -#endif -} - -/***************************************************************************//** - * - * static BOOL - * fam15IsCapable(u8 node, sMainData *pDat, cNorthBridge *nb) - * - * Description: - * Get node capability and update the minimum supported system capability. - * Return whether the current configuration exceeds the capability. - * - * Parameters: - * @param[in] node = the node - * @param[in,out] *pDat = sysMpCap (updated) and NodesDiscovered - * @param[in] *nb = this northbridge - * @return true: system is capable of current config. - * false: system is not capable of current config. - * - * --------------------------------------------------------------------------------------- - */ -static BOOL fam15IsCapable(u8 node, sMainData *pDat, cNorthBridge *nb) -{ -#ifndef HT_BUILD_NC_ONLY - u32 temp; - u8 maxNodes; - - ASSERT(node < nb->maxNodes); - - AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_NB_FUNC_03, - REG_NB_CAPABILITY_3XE8), - 18, 16, &temp); - - if (temp != 0) - { - maxNodes = (1 << (~temp & 0x3)); /* That is, 1, 2, 4, or 8 */ - } - else - { - /* Check if CPU package is dual node */ - AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_NB_FUNC_03, - REG_NB_CAPABILITY_3XE8), - 29, 29, &temp); - if (temp) - maxNodes = 4; - else - maxNodes = 8; - } - - if (pDat->sysMpCap > maxNodes) - { - pDat->sysMpCap = maxNodes; - } - /* Note since sysMpCap is one based and NodesDiscovered is zero based, equal is false */ - return (pDat->sysMpCap > pDat->NodesDiscovered); -#else - return 1; -#endif -} - -/***************************************************************************//** - * - * static void - * fam0fStopLink(u8 currentNode, u8 currentLink, cNorthBridge *nb) - * - * Description: - * Disable a cHT link on node by setting F0x[E4, C4, A4, 84][TransOff, EndOfChain]=1 - * - * Parameters: - * @param[in] node = the node this link is on - * @param[in] link = the link to stop - * @param[in] *nb = this northbridge - * - * --------------------------------------------------------------------------------------- - */ -static void fam0fStopLink(u8 node, u8 link, cNorthBridge *nb) -{ -#ifndef HT_BUILD_NC_ONLY - u32 temp; - SBDFO linkBase; - - ASSERT((node < nb->maxNodes) && (link < nb->maxLinks)); - - linkBase = makeLinkBase(node, link); - - /* Set TransOff, EndOfChain */ - temp = 3; - setHtControlRegisterBits(linkBase + HTHOST_LINK_CONTROL_REG, 7, 6, &temp); -#endif -} - -/***************************************************************************//** - * - * static void - * commonVoid() - * - * Description: - * Nothing. - * - * Parameters: - * None. - * - * --------------------------------------------------------------------------------------- - */ -static void commonVoid(void) -{ -} - -/***************************************************************************//** - * - * static BOOL - * commonReturnFalse() - * - * Description: - * Return False. - * - * Parameters: - * @return = false - * - */ -static BOOL commonReturnFalse(void) -{ - return 0; -} - -/*************************************************************************** - *** Non-coherent init code *** - *** Northbridge access routines *** - ***************************************************************************/ - -/***************************************************************************//** - * - * static u8 - * readSbLink(cNorthBridge *nb) - * - * Description: - * Return the link to the Southbridge - * - * Parameters: - * @param[in] *nb = this northbridge - * @return the link to the southbridge - * - * --------------------------------------------------------------------------------------- - */ -static u8 readSbLink(cNorthBridge *nb) -{ - u32 temp; - AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(0), - makePCIBusFromNode(0), - makePCIDeviceFromNode(0), - CPU_HTNB_FUNC_00, - REG_UNIT_ID_0X64), - 10, 8, &temp); - return (u8)temp; -} - -/***************************************************************************//** - * - * static BOOL - * verifyLinkIsNonCoherent(u8 node, u8 link, cNorthBridge *nb) - * - * Description: - * Verify that the link is non-coherent, connected, and ready - * - * Parameters: - * @param[in] node = the node that will be examined - * @param[in] link = the Link on that node to examine - * @param[in] *nb = this northbridge - * @return = true - The link has the following status - * LinkCon = 1, Link is connected - * InitComplete = 1,Link initialization is complete - * NC = 1, Link is coherent - * UniP-cLDT = 0, Link is not Uniprocessor cLDT - * LinkConPend = 0 Link connection is not pending - * false- The link has some other status - * - * --------------------------------------------------------------------------------------- - */ -static BOOL verifyLinkIsNonCoherent(u8 node, u8 link, cNorthBridge *nb) -{ - u32 linkType; - SBDFO linkBase; - - ASSERT((node < nb->maxNodes) && (link < nb->maxLinks)); - - linkBase = makeLinkBase(node, link); - - /* FN0_98/A4/C4 = LDT Type Register */ - AmdPCIRead(linkBase + HTHOST_LINK_TYPE_REG, &linkType); - - /* Verify linkCon = 1, InitComplete = 1, NC = 0, UniP-cLDT = 0, LinkConPend = 0 */ - return (linkType & HTHOST_TYPE_MASK) == HTHOST_TYPE_NONCOHERENT; -} - -/***************************************************************************//** - * - * static void - * ht3SetCFGAddrMap(u8 cfgMapIndex, u8 secBus, u8 subBus, u8 targetNode, u8 targetLink, sMainData *pDat, cNorthBridge *nb) - * - * Description: - * Configure and enable config access to a non-coherent chain for the given bus range. - * - * Parameters: - * @param[in] cfgMapIndex = 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] pDat = our global state - * @param[in] *nb = this northbridge - * - * --------------------------------------------------------------------------------------- - */ -static void ht3SetCFGAddrMap(u8 cfgMapIndex, u8 secBus, u8 subBus, u8 targetNode, u8 targetLink, sMainData *pDat, cNorthBridge *nb) -{ - u8 curNode; - SBDFO linkBase; - u32 temp; - - linkBase = makeLinkBase(targetNode, targetLink); - - ASSERT(secBus <= subBus); - temp = secBus; - AmdPCIWriteBits(linkBase + HTHOST_ISOC_REG, 15, 8, &temp); - - /* For target link, note that rev F uses bits 9:8 and only with GH is bit 10 - * set to indicate a sublink. For node, we are currently not supporting Extended - * routing tables. - */ - temp = ((u32)subBus << 24) + ((u32)secBus << 16) + ((u32)targetLink << 8) - + ((u32)targetNode << 4) + (u32)3; - for (curNode = 0; curNode < pDat->NodesDiscovered+1; curNode++) - AmdPCIWrite(MAKE_SBDFO(makePCISegmentFromNode(curNode), - makePCIBusFromNode(curNode), - makePCIDeviceFromNode(curNode), - CPU_ADDR_FUNC_01, - REG_ADDR_CONFIG_MAP0_1XE0 + 4*cfgMapIndex), - &temp); -} - -/***************************************************************************//** - * - * static void - * ht1SetCFGAddrMap(u8 cfgMapIndex, u8 secBus, u8 subBus, u8 targetNode, u8 targetLink, sMainData *pDat, cNorthBridge *nb) - * - * Description: - * Configure and enable config access to a non-coherent chain for the given bus range. - * - * Parameters: - * @param[in] cfgMapIndex = 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] pDat = our global state - * @param[in] *nb = this northbridge - * - ******************************************************************************/ -static void ht1SetCFGAddrMap(u8 cfgMapIndex, u8 secBus, u8 subBus, u8 targetNode, u8 targetLink, sMainData *pDat, cNorthBridge *nb) -{ - u8 curNode; - SBDFO linkBase; - u32 temp; - - linkBase = makeLinkBase(targetNode, targetLink); - - ASSERT(secBus <= subBus); - temp = secBus; - AmdPCIWriteBits(linkBase + HTHOST_ISOC_REG, 15, 8, &temp); - - temp = subBus; - AmdPCIWriteBits(linkBase + HTHOST_ISOC_REG, 23, 16, &temp); - - /* For target link, note that rev F uses bits 9:8 and only with GH is bit 10 - * set to indicate a sublink. For node, we are currently not supporting Extended - * routing tables. - */ - temp = ((u32)subBus << 24) + ((u32)secBus << 16) + ((u32)targetLink << 8) - + ((u32)targetNode << 4) + (u32)3; - for (curNode = 0; curNode < pDat->NodesDiscovered+1; curNode++) - AmdPCIWrite(MAKE_SBDFO(makePCISegmentFromNode(curNode), - makePCIBusFromNode(curNode), - makePCIDeviceFromNode(curNode), - CPU_ADDR_FUNC_01, - REG_ADDR_CONFIG_MAP0_1XE0 + 4*cfgMapIndex), - &temp); -} - -/*************************************************************************** - *** Link Optimization *** - ***************************************************************************/ - -/** - * static u8 - * convertBitsToWidth(u8 value, cNorthBridge *nb) - * - * Description: - * Given the bits set in the register field, return the width it represents - * - * Parameters: - * @param[in] value = The bits for the register - * @param[in] *nb = this northbridge - * @return The width - * - ******************************************************************************/ -static u8 convertBitsToWidth(u8 value, cNorthBridge *nb) -{ - switch (value) { - case 1: return 16; - case 0: return 8; - case 5: return 4; - case 4: return 2; - default: STOP_HERE; /* This is an error internal condition */ - } - return 0; // shut up GCC. -} - -/***************************************************************************//** - * - * static u8 - * convertWidthToBits(u8 value, cNorthBridge *nb) - * - * Description: - * Translate a desired width setting to the bits to set in the register field - * - * Parameters: - * @param[in] value = The width - * @param[in] *nb = this northbridge - * @return The bits for the register - * - ******************************************************************************/ -static u8 convertWidthToBits(u8 value, cNorthBridge *nb) -{ - switch (value) { - case 16: return 1; - case 8: return 0; - case 4: return 5; - case 2: return 4; - default: STOP_HERE; /* This is an internal error condition */ - } - return 0; // shut up GCC -} - -/***************************************************************************//** - * - * static u16 - * ht1NorthBridgeFreqMask(u8 NodeID, cNorthBridge *nb) - * - * Description: - * Return a mask that eliminates HT frequencies that cannot be used due to a slow - * northbridge frequency. - * - * Parameters: - * @param[in] node = Result could (later) be for a specific node - * @param[in] *nb = this northbridge - * @return Frequency mask - * - ******************************************************************************/ -static uint32_t ht1NorthBridgeFreqMask(u8 node, cNorthBridge *nb) -{ - /* only up to HT1 speeds */ - return (HT_FREQUENCY_LIMIT_HT1_ONLY); -} - -/***************************************************************************//** - * - * static u16 - * fam10NorthBridgeFreqMask(u8 NodeID, cNorthBridge *nb) - * - * Description: - * Return a mask that eliminates HT frequencies that cannot be used due to a slow - * northbridge frequency. - * - * Parameters: - * @param[in] node = Result could (later) be for a specific node - * @param[in] *nb = this northbridge - * @return = Frequency mask - * - ******************************************************************************/ -static uint32_t fam10NorthBridgeFreqMask(u8 node, cNorthBridge *nb) -{ - u8 nbCOF; - uint32_t supported; - - nbCOF = getMinNbCOF(); - /* - * nbCOF is minimum northbridge speed in hundreds of MHz. - * HT can not go faster than the minimum speed of the northbridge. - */ - if ((nbCOF >= 6) && (nbCOF < 10)) - { - /* Generation 1 HT link frequency */ - /* Convert frequency to bit and all less significant bits, - * by setting next power of 2 and subtracting 1. - */ - supported = ((uint32_t)1 << ((nbCOF >> 1) + 2)) - 1; - } - else if ((nbCOF >= 10) && (nbCOF <= 32)) - { - /* Generation 3 HT link frequency - * Assume error retry is enabled on all Gen 3 links - */ - if (is_gt_rev_d()) { - nbCOF *= 2; - if (nbCOF > 32) - nbCOF = 32; - } - - /* Convert frequency to bit and all less significant bits, - * by setting next power of 2 and subtracting 1. - */ - supported = ((uint32_t)1 << ((nbCOF >> 1) + 2)) - 1; - } - else if (nbCOF > 32) - { - supported = HT_FREQUENCY_LIMIT_3200M; - } - /* unlikely cases, but include as a defensive measure, also avoid trick above */ - else if (nbCOF == 4) - { - supported = HT_FREQUENCY_LIMIT_400M; - } - else if (nbCOF == 2) - { - supported = HT_FREQUENCY_LIMIT_200M; - } - else - { - STOP_HERE; - supported = HT_FREQUENCY_LIMIT_200M; - } - - return (fixEarlySampleFreqCapability(supported)); -} - -/***************************************************************************//** - * - * static u16 - * fam15NorthBridgeFreqMask(u8 NodeID, cNorthBridge *nb) - * - * Description: - * Return a mask that eliminates HT frequencies that cannot be used due to a slow - * northbridge frequency. - * - * Parameters: - * @param[in] node = Result could (later) be for a specific node - * @param[in] *nb = this northbridge - * @return = Frequency mask - * - ******************************************************************************/ -static uint32_t fam15NorthBridgeFreqMask(u8 node, cNorthBridge *nb) -{ - u8 nbCOF; - uint32_t supported; - - nbCOF = getMinNbCOF(); - /* - * nbCOF is minimum northbridge speed in hundreds of MHz. - * HT can not go faster than the minimum speed of the northbridge. - */ - if ((nbCOF >= 6) && (nbCOF < 10)) - { - /* Generation 1 HT link frequency */ - /* Convert frequency to bit and all less significant bits, - * by setting next power of 2 and subtracting 1. - */ - supported = ((uint32_t)1 << ((nbCOF >> 1) + 2)) - 1; - } - else if ((nbCOF >= 10) && (nbCOF <= 32)) - { - /* Generation 3 HT link frequency - * Assume error retry is enabled on all Gen 3 links - */ - nbCOF *= 2; - if (nbCOF > 32) - nbCOF = 32; - - /* Convert frequency to bit and all less significant bits, - * by setting next power of 2 and subtracting 1. - */ - supported = ((uint32_t)1 << ((nbCOF >> 1) + 2)) - 1; - } - else if (nbCOF > 32) - { - supported = HT_FREQUENCY_LIMIT_3200M; - } - /* unlikely cases, but include as a defensive measure, also avoid trick above */ - else if (nbCOF == 4) - { - supported = HT_FREQUENCY_LIMIT_400M; - } - else if (nbCOF == 2) - { - supported = HT_FREQUENCY_LIMIT_200M; - } - else - { - STOP_HERE; - supported = HT_FREQUENCY_LIMIT_200M; - } - - return (fixEarlySampleFreqCapability(supported)); -} - -/***************************************************************************//** - * - * static void - * gatherLinkData(sMainData *pDat, cNorthBridge *nb) - * - * Description: - * For all discovered links, populate the port list with the frequency and width - * capabilities. - * - * Parameters: - * @param[in,out] pDat = our global state, port list - * @param[in] *nb = this northbridge - * - ******************************************************************************/ -static void gatherLinkData(sMainData *pDat, cNorthBridge *nb) -{ - u8 i; - SBDFO linkBase; - u32 temp; - - for (i = 0; i < pDat->TotalLinks*2; i++) - { - if (pDat->PortList[i].Type == PORTLIST_TYPE_CPU) - { - linkBase = makeLinkBase(pDat->PortList[i].NodeID, pDat->PortList[i].Link); - - pDat->PortList[i].Pointer = linkBase; - - AmdPCIReadBits(linkBase + HTHOST_LINK_CONTROL_REG, 22, 20, &temp); - pDat->PortList[i].PrvWidthOutCap = convertBitsToWidth((u8)temp, pDat->nb); - - AmdPCIReadBits(linkBase + HTHOST_LINK_CONTROL_REG, 18, 16, &temp); - pDat->PortList[i].PrvWidthInCap = convertBitsToWidth((u8)temp, pDat->nb); - - AmdPCIReadBits(linkBase + HTHOST_FREQ_REV_REG, 31, 16, &temp); - pDat->PortList[i].PrvFrequencyCap = temp & 0x7FFF /* Mask off bit 15, reserved value */ - & nb->northBridgeFreqMask(pDat->PortList[i].NodeID, pDat->nb); - if (is_gt_rev_d()) { - AmdPCIReadBits(linkBase + HTHOST_FREQ_REV_REG_2, 15, 1, &temp); - temp &= 0x7; /* Mask off reserved values */ - pDat->PortList[i].PrvFrequencyCap |= (temp << 17); - } - - AmdPCIReadBits(linkBase + HTHOST_FEATURE_CAP_REG, 9, 0, &temp); - pDat->PortList[i].PrvFeatureCap = (u16)temp; - } - else - { - linkBase = pDat->PortList[i].Pointer; - if (pDat->PortList[i].Link == 1) - linkBase += HTSLAVE_LINK01_OFFSET; - - AmdPCIReadBits(linkBase + HTSLAVE_LINK_CONTROL_0_REG, 22, 20, &temp); - pDat->PortList[i].PrvWidthOutCap = convertBitsToWidth((u8)temp, pDat->nb); - - AmdPCIReadBits(linkBase + HTSLAVE_LINK_CONTROL_0_REG, 18, 16, &temp); - pDat->PortList[i].PrvWidthInCap = convertBitsToWidth((u8)temp, pDat->nb); - - AmdPCIReadBits(linkBase + HTSLAVE_FREQ_REV_0_REG, 31, 16, &temp); - pDat->PortList[i].PrvFrequencyCap = (u16)temp; - - AmdPCIReadBits(linkBase + HTSLAVE_FEATURE_CAP_REG, 7, 0, &temp); - pDat->PortList[i].PrvFeatureCap = (u16)temp; - - if (pDat->HtBlock->AMD_CB_DeviceCapOverride) - { - linkBase &= 0xFFFFF000; - AmdPCIRead(linkBase, &temp); - - pDat->HtBlock->AMD_CB_DeviceCapOverride( - pDat->PortList[i].NodeID, - pDat->PortList[i].HostLink, - pDat->PortList[i].HostDepth, - (u8)SBDFO_SEG(pDat->PortList[i].Pointer), - (u8)SBDFO_BUS(pDat->PortList[i].Pointer), - (u8)SBDFO_DEV(pDat->PortList[i].Pointer), - temp, - pDat->PortList[i].Link, - &(pDat->PortList[i].PrvWidthInCap), - &(pDat->PortList[i].PrvWidthOutCap), - &(pDat->PortList[i].PrvFrequencyCap), - &(pDat->PortList[i].PrvFeatureCap)); - } - } - } -} - -/***************************************************************************//** - * - * static void - * setLinkData(sMainData *pDat, cNorthBridge *nb) - * - * Description: - * Change the hardware state for all links according to the now optimized data in the - * port list data structure. - * - * Parameters: - * @param[in] pDat = our global state, port list - * @param[in] *nb = this northbridge - * - ******************************************************************************/ -static void setLinkData(sMainData *pDat, cNorthBridge *nb) -{ - u8 i; - SBDFO linkBase; - u32 temp, temp2, frequency_index, widthin, widthout, bits; - - for (i = 0; i < pDat->TotalLinks*2; i++) - { - - ASSERT(pDat->PortList[i&0xFE].SelWidthOut == pDat->PortList[(i&0xFE)+1].SelWidthIn); - ASSERT(pDat->PortList[i&0xFE].SelWidthIn == pDat->PortList[(i&0xFE)+1].SelWidthOut); - ASSERT(pDat->PortList[i&0xFE].SelFrequency == pDat->PortList[(i&0xFE)+1].SelFrequency); - - if (pDat->PortList[i].SelRegang) - { - ASSERT(pDat->PortList[i].Type == PORTLIST_TYPE_CPU); - ASSERT(pDat->PortList[i].Link < 4); - temp = 1; - AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(pDat->PortList[i].NodeID), - makePCIBusFromNode(pDat->PortList[i].NodeID), - makePCIDeviceFromNode(pDat->PortList[i].NodeID), - CPU_HTNB_FUNC_00, - REG_HT_LINK_EXT_CONTROL0_0X170 + 4*pDat->PortList[i].Link), - 0, 0, &temp); - } - - if (pDat->PortList[i].Type == PORTLIST_TYPE_CPU) - { - if (pDat->HtBlock->AMD_CB_OverrideCpuPort) - pDat->HtBlock->AMD_CB_OverrideCpuPort(pDat->PortList[i].NodeID, - pDat->PortList[i].Link, - &(pDat->PortList[i].SelWidthIn), - &(pDat->PortList[i].SelWidthOut), - &(pDat->PortList[i].SelFrequency)); - } - else - { - if (pDat->HtBlock->AMD_CB_OverrideDevicePort) - pDat->HtBlock->AMD_CB_OverrideDevicePort(pDat->PortList[i].NodeID, - pDat->PortList[i].HostLink, - pDat->PortList[i].HostDepth, - pDat->PortList[i].Link, - &(pDat->PortList[i].SelWidthIn), - &(pDat->PortList[i].SelWidthOut), - &(pDat->PortList[i].SelFrequency)); - } - - linkBase = pDat->PortList[i].Pointer; - if ((pDat->PortList[i].Type == PORTLIST_TYPE_IO) && (pDat->PortList[i].Link == 1)) - linkBase += HTSLAVE_LINK01_OFFSET; - - /* Some IO devices don't work properly when setting widths, so write them in a single operation, - * rather than individually. - */ - widthout = convertWidthToBits(pDat->PortList[i].SelWidthOut, pDat->nb); - ASSERT(widthout == 1 || widthout == 0 || widthout == 5 || widthout == 4); - widthin = convertWidthToBits(pDat->PortList[i].SelWidthIn, pDat->nb); - ASSERT(widthin == 1 || widthin == 0 || widthin == 5 || widthin == 4); - - temp = (widthin & 7) | ((widthout & 7) << 4); - setHtControlRegisterBits(linkBase + HTHOST_LINK_CONTROL_REG, 31, 24, &temp); - - temp = pDat->PortList[i].SelFrequency; - if (pDat->PortList[i].Type == PORTLIST_TYPE_CPU) - { - ASSERT((temp >= HT_FREQUENCY_600M && temp <= HT_FREQUENCY_3200M) - || (temp == HT_FREQUENCY_200M) || (temp == HT_FREQUENCY_400M)); - frequency_index = temp; - if (temp > 0xf) { - temp2 = (temp >> 4) & 0x1; - temp &= 0xf; - } else { - temp2 = 0x0; - } - /* NOTE - * The Family 15h BKDG Rev. 3.14 is wrong - * Freq[4] must be set before Freq[3:0], otherwise the register writes will be ignored! - */ - if (is_gt_rev_d()) - AmdPCIWriteBits(linkBase + HTHOST_FREQ_REV_REG_2, 0, 0, &temp2); - AmdPCIWriteBits(linkBase + HTHOST_FREQ_REV_REG, 11, 8, &temp); - - /* Enable isochronous flow control mode if supported by chipset */ - if (is_fam15h()) { - if (pDat->PortList[i].enable_isochronous_mode) - temp = 1; - else - temp = 0; - setHtControlRegisterBits(linkBase + HTHOST_LINK_CONTROL_REG, 12, 12, &temp); - } - - if (frequency_index > HT_FREQUENCY_1000M) /* Gen1 = 200MHz -> 1000MHz, Gen3 = 1200MHz -> 3200MHz */ - { - /* Enable for Gen3 frequencies */ - temp = 1; - } - else - { - /* Disable for Gen1 frequencies */ - temp = 0; - } - /* HT3 retry mode enable / disable */ - AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(pDat->PortList[i].NodeID), - makePCIBusFromNode(pDat->PortList[i].NodeID), - makePCIDeviceFromNode(pDat->PortList[i].NodeID), - CPU_HTNB_FUNC_00, - REG_HT_LINK_RETRY0_0X130 + 4*pDat->PortList[i].Link), - 0, 0, &temp); - - /* and Scrambling enable / disable */ - AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(pDat->PortList[i].NodeID), - makePCIBusFromNode(pDat->PortList[i].NodeID), - makePCIDeviceFromNode(pDat->PortList[i].NodeID), - CPU_HTNB_FUNC_00, - REG_HT_LINK_EXT_CONTROL0_0X170 + 4*pDat->PortList[i].Link), - 3, 3, &temp); - } - else - { - SBDFO currentPtr; - BOOL isFound; - - ASSERT(temp <= HT_FREQUENCY_3200M); - /* Write the frequency setting */ - AmdPCIWriteBits(linkBase + HTSLAVE_FREQ_REV_0_REG, 11, 8, &temp); - - /* 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 call backs - * (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; - } - - /* Enable isochronous flow control mode if supported by chipset */ - if (is_fam15h()) { - if (pDat->PortList[i].enable_isochronous_mode) - temp = 1; - else - temp = 0; - } - - /* Retry Enable */ - isFound = FALSE; - currentPtr = linkBase & (u32)0xFFFFF000; /* Set PCI Offset to 0 */ - do - { - AmdPCIFindNextCap(¤tPtr); - if (currentPtr != ILLEGAL_SBDFO) - { - AmdPCIRead(currentPtr, &temp); - /* HyperTransport Retry Capability? */ - if (IS_HT_RETRY_CAPABILITY(temp)) - { - ASSERT(pDat->PortList[i].Link < 2); - AmdPCIWriteBits(currentPtr + HTRETRY_CONTROL_REG, - pDat->PortList[i].Link*16, - pDat->PortList[i].Link*16, - &bits); - isFound = TRUE; - } - /* Some other capability, keep looking */ - } - 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) - { - if (pDat->HtBlock->AMD_CB_EventNotify) - { - sHtEventOptRequiredCap evt; - evt.eSize = sizeof(sHtEventOptRequiredCap); - evt.node = pDat->PortList[i].NodeID; - evt.link = pDat->PortList[i].HostLink; - evt.depth = pDat->PortList[i].HostDepth; - - pDat->HtBlock->AMD_CB_EventNotify(HT_EVENT_CLASS_WARNING, - HT_EVENT_OPT_REQUIRED_CAP_RETRY, - (u8 *)&evt); - } - STOP_HERE; - } - isFound = TRUE; - } - } while (!isFound); - - /* Scrambling enable */ - isFound = FALSE; - currentPtr = linkBase & (u32)0xFFFFF000; /* Set PCI Offset to 0 */ - do - { - AmdPCIFindNextCap(¤tPtr); - if (currentPtr != ILLEGAL_SBDFO) - { - AmdPCIRead(currentPtr, &temp); - /* HyperTransport Gen3 Capability? */ - if (IS_HT_GEN3_CAPABILITY(temp)) - { - ASSERT(pDat->PortList[i].Link < 2); - AmdPCIWriteBits((currentPtr + - HTGEN3_LINK_TRAINING_0_REG + - pDat->PortList[i].Link*HTGEN3_LINK01_OFFSET), - 3, 3, &bits); - isFound = TRUE; - } - /* Some other capability, keep looking */ - } - 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) - { - if (pDat->HtBlock->AMD_CB_EventNotify) - { - sHtEventOptRequiredCap evt; - evt.eSize = sizeof(sHtEventOptRequiredCap); - evt.node = pDat->PortList[i].NodeID; - evt.link = pDat->PortList[i].HostLink; - evt.depth = pDat->PortList[i].HostDepth; - - pDat->HtBlock->AMD_CB_EventNotify(HT_EVENT_CLASS_WARNING, - HT_EVENT_OPT_REQUIRED_CAP_GEN3, - (u8 *)&evt); - } - STOP_HERE; - } - isFound = TRUE; - } - } while (!isFound); - } - } -} - -/***************************************************************************//** - * - * void - * fam0fWriteHTLinkCmdBufferAlloc(u8 node, u8 link, u8 req, u8 preq, u8 rsp, u8 prb) - * - * Description: - * Set the command buffer allocations in the buffer count register for the node and link. - * The command buffer settings in the low 16 bits are the same on both - * family 10h and family 0fh northbridges. - * - * Parameters: - * @param[in] node = The node to set allocations on - * @param[in] link = the link to set allocations on - * @param[in] req = non-posted Request Command Buffers - * @param[in] preq = Posted Request Command Buffers - * @param[in] rsp = Response Command Buffers - * @param[in] prb = Probe Command Buffers - * - ******************************************************************************/ -#ifndef HT_BUILD_NC_ONLY - -static void fam0fWriteHTLinkCmdBufferAlloc(u8 node, u8 link, u8 req, u8 preq, u8 rsp, u8 prb) -{ - u32 temp; - SBDFO currentPtr; - - currentPtr = makeLinkBase(node, link); - currentPtr += HTHOST_BUFFER_COUNT_REG; - - /* non-posted Request Command Buffers */ - temp = req; - AmdPCIWriteBits(currentPtr, 3, 0, &temp); - /* Posted Request Command Buffers */ - temp = preq; - AmdPCIWriteBits(currentPtr, 7, 4, &temp); - /* Response Command Buffers */ - temp = rsp; - AmdPCIWriteBits(currentPtr, 11, 8, &temp); - /* Probe Command Buffers */ - temp = prb; - AmdPCIWriteBits(currentPtr, 15, 12, &temp); - /* LockBc */ - temp = 1; - AmdPCIWriteBits(currentPtr, 31, 31, &temp); -} -#endif /* HT_BUILD_NC_ONLY */ - -/***************************************************************************//** - * - * void - * fam0fWriteHTLinkDatBufferAlloc(u8 node, u8 link, u8 reqD, u8 preqD, u8 rspD) - * - * Description: - * Set the data buffer allocations in the buffer count register for the node and link. - * The command buffer settings in the high 16 bits are not the same on both - * family 10h and family 0fh northbridges. - * - * Parameters: - * @param[in] node = The node to set allocations on - * @param[in] link = the link to set allocations on - * @param[in] reqD = non-posted Request Data Buffers - * @param[in] preqD = Posted Request Data Buffers - * @param[in] rspD = Response Data Buffers - * - ******************************************************************************/ -#ifndef HT_BUILD_NC_ONLY - -static void fam0fWriteHTLinkDatBufferAlloc(u8 node, u8 link, u8 reqD, u8 preqD, u8 rspD) -{ - u32 temp; - SBDFO currentPtr; - - currentPtr = makeLinkBase(node, link); - currentPtr += HTHOST_BUFFER_COUNT_REG; - - /* Request Data Buffers */ - temp = reqD; - AmdPCIWriteBits(currentPtr, 18, 16, &temp); - /* Posted Request Data Buffers */ - temp = preqD; - AmdPCIWriteBits(currentPtr, 22, 20, &temp); - /* Response Data Buffers */ - temp = rspD; - AmdPCIWriteBits(currentPtr, 26, 24, &temp); -} -#endif /* HT_BUILD_NC_ONLY */ - -/***************************************************************************//** - * - * static void - * ht3WriteTrafficDistribution(u32 links01, u32 links10, cNorthBridge *nb) - * - * Description: - * Set the traffic distribution register for the links provided. - * - * Parameters: - * @param[in] links01 = coherent links from node 0 to 1 - * @param[in] links10 = coherent links from node 1 to 0 - * @param[in] nb = this northbridge - * - ******************************************************************************/ -static void ht3WriteTrafficDistribution(u32 links01, u32 links10, cNorthBridge *nb) -{ -#ifndef HT_BUILD_NC_ONLY - u32 temp; - - /* Node 0 */ - /* DstLnk */ - AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(0), - makePCIBusFromNode(0), - makePCIDeviceFromNode(0), - CPU_HTNB_FUNC_00, - REG_HT_TRAFFIC_DIST_0X164), - 23, 16, &links01); - /* DstNode = 1, cHTPrbDistEn = 1, cHTRspDistEn = 1, cHTReqDistEn = 1 */ - temp = 0x0107; - AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(0), - makePCIBusFromNode(0), - makePCIDeviceFromNode(0), - CPU_HTNB_FUNC_00, - REG_HT_TRAFFIC_DIST_0X164), - 15, 0, &temp); - - /* Node 1 */ - /* DstLnk */ - AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(1), - makePCIBusFromNode(1), - makePCIDeviceFromNode(1), - CPU_HTNB_FUNC_00, - REG_HT_TRAFFIC_DIST_0X164), - 23, 16, &links10); - /* DstNode = 0, cHTPrbDistEn = 1, cHTRspDistEn = 1, cHTReqDistEn = 1 */ - temp = 0x0007; - AmdPCIWriteBits(MAKE_SBDFO(makePCISegmentFromNode(1), - makePCIBusFromNode(1), - makePCIDeviceFromNode(1), - CPU_HTNB_FUNC_00, - REG_HT_TRAFFIC_DIST_0X164), - 15, 0, &temp); -#endif /* HT_BUILD_NC_ONLY */ -} - -/***************************************************************************//** - * - * static void - * ht1WriteTrafficDistribution(u32 links01, u32 links10, cNorthBridge *nb) - * - * Description: - * Traffic distribution is more complex in this case as the routing table must be - * adjusted to use one link for requests and the other for responses. Also, - * perform the buffer tunings on the links required for this config. - * - * Parameters: - * @param[in] links01 = coherent links from node 0 to 1 - * @param[in] links10 = coherent links from node 1 to 0 - * @param[in] nb = this northbridge - * - ******************************************************************************/ -static void ht1WriteTrafficDistribution(u32 links01, u32 links10, cNorthBridge *nb) -{ -#ifndef HT_BUILD_NC_ONLY - u32 route01, route10; - u8 req0, req1, rsp0, rsp1, nclink; - - /* - * Get the current request route for 0->1 and 1->0. This will indicate which of the links - * in links01 are connected to which links in links10. Since we have to route to distribute - * traffic, we need to know that. The link used by htinit will become the request, probe link. - * the other link will be used for responses. - */ - - /* Get the routes, and hang on to them, we will write them back updated. */ - AmdPCIRead(MAKE_SBDFO(makePCISegmentFromNode(0), - makePCIBusFromNode(0), - makePCIDeviceFromNode(0), - CPU_HTNB_FUNC_00, - REG_ROUTE1_0X44), - &route01); - AmdPCIRead(MAKE_SBDFO(makePCISegmentFromNode(1), - makePCIBusFromNode(1), - makePCIDeviceFromNode(1), - CPU_HTNB_FUNC_00, - REG_ROUTE0_0X40), - &route10); - - /* Convert the request routes to a link number. Note "0xE" is ht1 nb specific. - * Find the response link numbers. - */ - ASSERT((route01 & 0xE) && (route10 & 0xE)); /* no route! error! */ - req0 = (u8)AmdBitScanReverse((route01 & 0xE)) - 1; - req1 = (u8)AmdBitScanReverse((route10 & 0xE)) - 1; - /* Now, find the other link for the responses */ - rsp0 = (u8)AmdBitScanReverse((links01 & ~((u32)1 << req0))); - rsp1 = (u8)AmdBitScanReverse((links10 & ~((u32)1 << req1))); - - /* ht1 nb restriction, must have exactly two links */ - ASSERT(((((links01 & ~((u32)1 << req0)) & ~((u32)1 << rsp0))) == 0) - && ((((links10 & ~((u32)1 << req1)) & ~((u32)1 << rsp1))) == 0)); - - route01 = (route01 & ~0x0E00) | ((u32)0x0100<<(rsp0 + 1)); - route10 = (route10 & ~0x0E00) | ((u32)0x0100<<(rsp1 + 1)); - - AmdPCIWrite(MAKE_SBDFO(makePCISegmentFromNode(0), - makePCIBusFromNode(0), - makePCIDeviceFromNode(0), - CPU_HTNB_FUNC_00, - REG_ROUTE1_0X44), - &route01); - - AmdPCIWrite(MAKE_SBDFO(makePCISegmentFromNode(1), - makePCIBusFromNode(1), - makePCIDeviceFromNode(1), - CPU_HTNB_FUNC_00, - REG_ROUTE0_0X40), - &route10); - - /* While we otherwise do buffer tunings elsewhere, for the dual cHT DP case with - * ht1 northbridges like family 0Fh, do the tunings here where we have all the - * link and route info at hand and don't need to recalculate it. - */ - - /* Node 0, Request / Probe Link (note family F only has links < 4) */ - fam0fWriteHTLinkCmdBufferAlloc(0, req0, 6, 3, 1, 6); - fam0fWriteHTLinkDatBufferAlloc(0, req0, 4, 3, 1); - /* Node 0, Response Link (note family F only has links < 4) */ - fam0fWriteHTLinkCmdBufferAlloc(0, rsp0, 1, 0, 15, 0); - fam0fWriteHTLinkDatBufferAlloc(0, rsp0, 1, 1, 6); - /* Node 1, Request / Probe Link (note family F only has links < 4) */ - fam0fWriteHTLinkCmdBufferAlloc(1, req1, 6, 3, 1, 6); - fam0fWriteHTLinkDatBufferAlloc(1, req1, 4, 3, 1); - /* Node 1, Response Link (note family F only has links < 4) */ - fam0fWriteHTLinkCmdBufferAlloc(1, rsp1, 1, 0, 15, 0); - fam0fWriteHTLinkDatBufferAlloc(1, rsp1, 1, 1, 6); - - /* Node 0, is the third link non-coherent? */ - nclink = (u8)AmdBitScanReverse(((u8)0x07 & ~((u32)1 << req0) & ~((u32)1 << rsp0))); - if (nb->verifyLinkIsNonCoherent(0, nclink, nb)) - { - fam0fWriteHTLinkCmdBufferAlloc(0, nclink, 6, 5, 2, 0); - } - - /* Node 1, is the third link non-coherent? */ - nclink = (u8)AmdBitScanReverse(((u8)0x07 & ~((u32)1 << req1) & ~((u32)1 << rsp1))); - if (nb->verifyLinkIsNonCoherent(1, nclink, nb)) - { - fam0fWriteHTLinkCmdBufferAlloc(1, nclink, 6, 5, 2, 0); - } -#endif /* HT_BUILD_NC_ONLY */ -} - -/***************************************************************************//** - * - * static void - * fam0fBufferOptimizations(u8 node, sMainData *pDat, cNorthBridge *nb) - * - * Description: - * Buffer tunings are inherently northbridge specific. Check for specific configs - * which require adjustments and apply any standard workarounds to this node. - * - * Parameters: - * @param[in] node = the node to - * @param[in] *pDat = coherent links from node 0 to 1 - * @param[in] nb = this northbridge - * - ******************************************************************************/ -static void fam0fBufferOptimizations(u8 node, sMainData *pDat, cNorthBridge *nb) -{ -#ifndef HT_BUILD_NC_ONLY - u8 i; - u32 temp; - SBDFO currentPtr; - - ASSERT(node < nb->maxNodes); - - /* Fix the FIFO pointer register before changing speeds */ - currentPtr = MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_NB_FUNC_03, - REG_NB_FIFOPTR_3XDC); - for (i = 0; i < nb->maxLinks; i++) - { - temp = 0; - if (nb->verifyLinkIsCoherent(node, i, nb)) - { - temp = 0x26; - ASSERT(i < 3); - AmdPCIWriteBits(currentPtr, 8*i + 5, 8*i, &temp); - } - else - { - if (nb->verifyLinkIsNonCoherent(node, i, nb)) - { - temp = 0x25; - ASSERT(i < 3); - AmdPCIWriteBits(currentPtr, 8*i + 5, 8*i, &temp); - } - } - } - /* - * 8P Buffer tuning. - * Either apply the BKDG tunings or, if applicable, apply the more restrictive errata 153 - * workaround. - * If 8 nodes, Check this node for 'inner' or 'outer'. - * Tune each link based on coherent or non-coherent - */ - if (pDat->NodesDiscovered >= 6) - { - u8 j; - BOOL isOuter; - BOOL isErrata153; - - /* This is for family 0Fh, so assuming dual core max then 7 or 8 nodes are required - * to be in the situation of 14 or more cores. We checked nodes above, cross check - * that the number of cores is 14 or more. We want both 14 cores with at least 7 or 8 nodes - * not one condition alone, to apply the errata 153 workaround. Otherwise, 7 or 8 rev F - * nodes use the BKDG tuning. - */ - - isErrata153 = 0; - - AmdPCIReadBits (MAKE_SBDFO(makePCISegmentFromNode(0), - makePCIBusFromNode(0), - makePCIDeviceFromNode(0), - CPU_HTNB_FUNC_00, - REG_NODE_ID_0X60), - 19, 16, &temp); - - if (temp >= 14) - { - /* Check whether we need to do errata 153 tuning or BKDG tuning. - * Errata 153 applies to JH-1, JH-2 and older. It is fixed in JH-3 - * (and, one assumes, from there on). - */ - for (i = 0; i < (pDat->NodesDiscovered +1); i++) - { - AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(i), - makePCIBusFromNode(i), - makePCIDeviceFromNode(i), - CPU_NB_FUNC_03, - REG_NB_CPUID_3XFC), - 7, 0, &temp); - if (((u8)temp & ~0x40) < 0x13) - { - isErrata153 = 1; - break; - } - } - } - - for (i = 0; i < CPU_ADDR_NUM_CONFIG_MAPS; i++) - { - isOuter = FALSE; - /* Check for outer node by scanning the config maps on node 0 for one - * which is assigned to this node. - */ - currentPtr = MAKE_SBDFO(makePCISegmentFromNode(0), - makePCIBusFromNode(0), - makePCIDeviceFromNode(0), - CPU_ADDR_FUNC_01, - REG_ADDR_CONFIG_MAP0_1XE0 + (4 * i)); - AmdPCIReadBits (currentPtr, 1, 0, &temp); - /* Make sure this config map is valid, if it is it will be enabled for read/write */ - if (temp == 3) - { - /* It's valid, get the node (that node is an outer node) */ - AmdPCIReadBits (currentPtr, 6, 4, &temp); - /* Is the node we're working on now? */ - if (node == (u8)temp) - { - /* This is an outer node. Tune it appropriately. */ - for (j = 0; j < nb->maxLinks; j++) - { - if (isErrata153) - { - if (nb->verifyLinkIsCoherent(node, j, nb)) - { - fam0fWriteHTLinkCmdBufferAlloc(node, j, 1, 1, 6, 4); - } - else - { - if (nb->verifyLinkIsNonCoherent(node, j, nb)) - { - fam0fWriteHTLinkCmdBufferAlloc(node, j, 5, 4, 1, 0); - } - } - } - else - { - if (nb->verifyLinkIsCoherent(node, j, nb)) - { - fam0fWriteHTLinkCmdBufferAlloc(node, j, 1, 1, 8, 5); - } - } - } - /* - * SRI to XBAR Buffer Counts are correct for outer node at power on defaults. - */ - isOuter = TRUE; - break; - } - } - /* We fill config maps in ascending order, so if we didn't use this one, we're done. */ - else break; - } - if (!isOuter) - { - if (isErrata153) - { - /* Tuning for inner node coherent links */ - for (j = 0; j < nb->maxLinks; j++) - { - if (nb->verifyLinkIsCoherent(node, j, nb)) - { - fam0fWriteHTLinkCmdBufferAlloc(node, j, 2, 1, 5, 4); - } - - } - /* SRI to XBAR Buffer Count for inner nodes, zero DReq and DPReq */ - temp = 0; - AmdPCIWriteBits (MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_NB_FUNC_03, - REG_NB_SRI_XBAR_BUF_3X70), - 31, 28, &temp); - } - } - - /* - * Tune MCT to XBAR Buffer Count the same an all nodes, 2 Probes, 5 Response - */ - if (isErrata153) - { - temp = 0x25; - AmdPCIWriteBits (MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_NB_FUNC_03, - REG_NB_MCT_XBAR_BUF_3X78), - 14, 8, &temp); - } - } -#endif /* HT_BUILD_NC_ONLY */ -} - -/***************************************************************************//** - * - * static void - * fam10BufferOptimizations(u8 node, sMainData *pDat, cNorthBridge *nb) - * - * Description: - * Buffer tunings are inherently northbridge specific. Check for specific configs - * which require adjustments and apply any standard workarounds to this node. - * - * Parameters: - * @param[in] node = the node to tune - * @param[in] *pDat = global state - * @param[in] nb = this northbridge - * - ******************************************************************************/ -static void fam10BufferOptimizations(u8 node, sMainData *pDat, cNorthBridge *nb) -{ - u32 temp; - SBDFO currentPtr; - u8 i; - - ASSERT(node < nb->maxNodes); - - /* - * Link to XCS Token Count Tuning - * - * For each active link that we reganged (so this unfortunately can't go into the PCI reg - * table), we have to switch the Link to XCS Token Counts to the ganged state. - * We do this here for the non-uma case, which is to write the values that would have - * been power on defaults if the link was ganged at cold reset. - */ - for (i = 0; i < pDat->TotalLinks*2; i++) - { - if ((pDat->PortList[i].NodeID == node) && (pDat->PortList[i].Type == PORTLIST_TYPE_CPU)) - { - /* If the link is greater than 4, this is a sublink 1, so it is not reganged. */ - if (pDat->PortList[i].Link < 4) - { - currentPtr = MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_NB_FUNC_03, - REG_NB_LINK_XCS_TOKEN0_3X148 + 4*pDat->PortList[i].Link); - if (pDat->PortList[i].SelRegang) - { - /* Handle all the regang Token count adjustments */ - - /* Sublink 0: [Probe0tok] = 2 [Rsp0tok] = 2 [PReq0tok] = 2 [Req0tok] = 2 */ - temp = 0xAA; - AmdPCIWriteBits(currentPtr, 7, 0, &temp); - /* Sublink 1: [Probe1tok] = 0 [Rsp1tok] = 0 [PReq1tok] = 0 [Req1tok] = 0 */ - temp = 0; - AmdPCIWriteBits(currentPtr, 23, 16, &temp); - /* [FreeTok] = 3 */ - temp = 3; - AmdPCIWriteBits(currentPtr, 15, 14, &temp); - } - else - { - /* Read the regang bit in hardware */ - AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(pDat->PortList[i].NodeID), - makePCIBusFromNode(pDat->PortList[i].NodeID), - makePCIDeviceFromNode(pDat->PortList[i].NodeID), - CPU_HTNB_FUNC_00, - REG_HT_LINK_EXT_CONTROL0_0X170 + 4*pDat->PortList[i].Link), - 0, 0, &temp); - if (temp == 1) - { - /* handle a minor adjustment for stapped ganged links. If SelRegang is false we - * didn't do the regang, so if the bit is on then it's hardware strapped. - */ - - /* [FreeTok] = 3 */ - temp = 3; - AmdPCIWriteBits(currentPtr, 15, 14, &temp); - } - } - } - } - } -} - -/***************************************************************************//** - * - * static void - * fam15BufferOptimizations(u8 node, sMainData *pDat, cNorthBridge *nb) - * - * Description: - * Buffer tunings are inherently northbridge specific. Check for specific configs - * which require adjustments and apply any standard workarounds to this node. - * - * Parameters: - * @param[in] node = the node to tune - * @param[in] *pDat = global state - * @param[in] nb = this northbridge - * - ******************************************************************************/ -static void fam15BufferOptimizations(u8 node, sMainData *pDat, cNorthBridge *nb) -{ - /* Buffer count setup on Family 15h is currently handled in cpuSetAMDPCI */ -} - -/* - * North Bridge 'constructor'. - * - */ - -/***************************************************************************//** - * - * void - * newNorthBridge(u8 node, cNorthBridge *nb) - * - * Description: - * 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. - * - * Parameters: - * @param node - * @param[out] nb = the caller's northbridge structure to initialize. - * - ******************************************************************************/ -void newNorthBridge(u8 node, cNorthBridge *nb) -{ - u32 match; - u32 extFam, baseFam, model; - - cNorthBridge fam15 = - { -#ifdef HT_BUILD_NC_ONLY - 8, - 1, - 12, -#else - 8, - 8, - 64, -#endif /* HT_BUILD_NC_ONLY*/ - writeRoutingTable, - writeNodeID, - readDefLnk, - enableRoutingTables, - verifyLinkIsCoherent, - readTrueLinkFailStatus, - readToken, - writeToken, - fam15GetNumCoresOnNode, - setTotalNodesAndCores, - limitNodes, - writeFullRoutingTable, - isCompatible, - fam15IsCapable, - (void (*)(u8, u8, cNorthBridge*))commonVoid, - (BOOL (*)(u8, u8, sMainData*, cNorthBridge*))commonReturnFalse, - readSbLink, - verifyLinkIsNonCoherent, - ht3SetCFGAddrMap, - convertBitsToWidth, - convertWidthToBits, - fam15NorthBridgeFreqMask, - gatherLinkData, - setLinkData, - ht3WriteTrafficDistribution, - fam15BufferOptimizations, - 0x00000001, - 0x00000200, - 18, - 0x00000f06 - }; - - cNorthBridge fam10 = - { -#ifdef HT_BUILD_NC_ONLY - 8, - 1, - 12, -#else - 8, - 8, - 64, -#endif /* HT_BUILD_NC_ONLY*/ - writeRoutingTable, - writeNodeID, - readDefLnk, - enableRoutingTables, - verifyLinkIsCoherent, - readTrueLinkFailStatus, - readToken, - writeToken, - fam10GetNumCoresOnNode, - setTotalNodesAndCores, - limitNodes, - writeFullRoutingTable, - isCompatible, - fam10IsCapable, - (void (*)(u8, u8, cNorthBridge*))commonVoid, - (BOOL (*)(u8, u8, sMainData*, cNorthBridge*))commonReturnFalse, - readSbLink, - verifyLinkIsNonCoherent, - ht3SetCFGAddrMap, - convertBitsToWidth, - convertWidthToBits, - fam10NorthBridgeFreqMask, - gatherLinkData, - setLinkData, - ht3WriteTrafficDistribution, - fam10BufferOptimizations, - 0x00000001, - 0x00000200, - 18, - 0x00000f01 - }; - - cNorthBridge fam0f = - { -#ifdef HT_BUILD_NC_ONLY - 3, - 1, - 12, -#else - 3, - 8, - 32, -#endif /* HT_BUILD_NC_ONLY*/ - writeRoutingTable, - writeNodeID, - readDefLnk, - enableRoutingTables, - verifyLinkIsCoherent, - readTrueLinkFailStatus, - readToken, - writeToken, - fam0FGetNumCoresOnNode, - setTotalNodesAndCores, - limitNodes, - writeFullRoutingTable, - isCompatible, - fam0fIsCapable, - fam0fStopLink, - (BOOL (*)(u8, u8, sMainData*, cNorthBridge*))commonReturnFalse, - readSbLink, - verifyLinkIsNonCoherent, - ht1SetCFGAddrMap, - convertBitsToWidth, - convertWidthToBits, - ht1NorthBridgeFreqMask, - gatherLinkData, - setLinkData, - ht1WriteTrafficDistribution, - fam0fBufferOptimizations, - 0x00000001, - 0x00000100, - 16, - 0x00000f00 - }; - - /* Start with enough of the key to identify the northbridge interface */ - AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_NB_FUNC_03, - REG_NB_CPUID_3XFC), - 27, 20, &extFam); - AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_NB_FUNC_03, - REG_NB_CPUID_3XFC), - 11, 8, &baseFam); - AmdPCIReadBits(MAKE_SBDFO(makePCISegmentFromNode(node), - makePCIBusFromNode(node), - makePCIDeviceFromNode(node), - CPU_NB_FUNC_03, - REG_NB_CPUID_3XFC), - 7, 4, &model); - match = (u32)((baseFam << 8) | extFam); - - /* Test each in turn looking for a match. - * Initialize the struct if found. - */ - if (match == fam15.compatibleKey) - { - Amdmemcpy((void *)nb, (const void *)&fam15, (u32) sizeof(cNorthBridge)); - } - else if (match == fam10.compatibleKey) - { - Amdmemcpy((void *)nb, (const void *)&fam10, (u32) sizeof(cNorthBridge)); - } - else - { - if (match == fam0f.compatibleKey) - { - Amdmemcpy((void *)nb, (const void *)&fam0f, (u32) sizeof(cNorthBridge)); - } - else - { - STOP_HERE; - } - } - - /* Update the initial limited key to the real one, which may include other matching info */ - nb->compatibleKey = makeKey(node); -} diff --git a/src/northbridge/amd/amdht/h3ncmn.h b/src/northbridge/amd/amdht/h3ncmn.h deleted file mode 100644 index db057c0f1c..0000000000 --- a/src/northbridge/amd/amdht/h3ncmn.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef H3NCMN_H -#define H3NCMN_H - -#include <stdint.h> -#include <device/pci.h> -#include <cpu/amd/msr.h> - -#include "comlib.h" -#include "h3finit.h" -#include "h3ffeat.h" - -/* Use a macro to convert a node number to a PCI device. If some future port of - * this code needs to, this can easily be replaced by a function call: - * u8 makePCIDeviceFromNode(u8 node); - */ -#define makePCIDeviceFromNode(node) \ - ((u8)(24 + node)) - -/* Use a macro to convert a node number to a PCI bus. If some future port of - * this code needs to, this can easily be replaced by a function call: - * u8 makePCIBusFromNode(u8 node); - */ -#define makePCIBusFromNode(node) \ - ((u8)(0)) - -/* Use a macro to convert a node number to a PCI Segment. If some future port of - * this code needs to, this can easily be replaced by a function call: - * u8 makePCISegmentFromNode(u8 node); - */ -#define makePCISegmentFromNode(node) \ - ((u8)(0)) - -/* Macros to fix support issues that come up with early sample processors, which - * sometimes do things like report capabilities that are actually unsupported. - * Use the build flag, HT_BUILD_EARLY_SAMPLE_CPU_SUPPORT, to enable this support. - * - * It's not envisioned this would be replaced by an external function, but the prototype is - * u16 fixEarlySampleFreqCapability(u16 fc); - */ -#ifndef HT_BUILD_EARLY_SAMPLE_CPU_SUPPORT -#define fixEarlySampleFreqCapability(fc) \ - ((u16)fc) -#else -#define fixEarlySampleFreqCapability(fc) \ - ((u16)fc & HT_FREQUENCY_LIMIT_HT1_ONLY) -#endif - -struct cNorthBridge -{ - /* Public data, clients of northbridge can access */ - u8 maxLinks; - u8 maxNodes; - u8 maxPlatformLinks; - - /* Public Interfaces for northbridge clients, coherent init*/ - void (*writeRoutingTable)(u8 node, u8 target, u8 link, cNorthBridge *nb); - void (*writeNodeID)(u8 node, u8 nodeID, cNorthBridge *nb); - u8 (*readDefLnk)(u8 node, cNorthBridge *nb); - void (*enableRoutingTables)(u8 node, cNorthBridge *nb); - BOOL (*verifyLinkIsCoherent)(u8 node, u8 link, cNorthBridge *nb); - BOOL (*readTrueLinkFailStatus)(u8 node, u8 link, sMainData *pDat, cNorthBridge *nb); - u8 (*readToken)(u8 node, cNorthBridge *nb); - void (*writeToken)(u8 node, u8 value, cNorthBridge *nb); - u8 (*getNumCoresOnNode)(u8 node, cNorthBridge *nb); - void (*setTotalNodesAndCores)(u8 node, u8 totalNodes, u8 totalCores, cNorthBridge *nb); - void (*limitNodes)(u8 node, cNorthBridge *nb); - void (*writeFullRoutingTable)(u8 node, u8 target, u8 reqLink, u8 rspLink, u32 bClinks, cNorthBridge *nb); - BOOL (*isCompatible)(u8 node, cNorthBridge *nb); - BOOL (*isCapable)(u8 node, sMainData *pDat, cNorthBridge *nb); - void (*stopLink)(u8 node, u8 link, cNorthBridge *nb); - BOOL (*handleSpecialLinkCase)(u8 node, u8 link, sMainData *pDat, cNorthBridge *nb); - - /* Public Interfaces for northbridge clients, noncoherent init */ - u8 (*readSbLink)(cNorthBridge *nb); - BOOL (*verifyLinkIsNonCoherent)(u8 node, u8 link, cNorthBridge *nb); - void (*setCFGAddrMap)(u8 cfgMapIndex, u8 secBus, u8 subBus, u8 targetNode, u8 targetLink, sMainData *pDat, cNorthBridge *nb); - - /* Public Interfaces for northbridge clients, Optimization */ - u8 (*convertBitsToWidth)(u8 value, cNorthBridge *nb); - u8 (*convertWidthToBits)(u8 value, cNorthBridge *nb); - uint32_t (*northBridgeFreqMask)(u8 node, cNorthBridge *nb); - void (*gatherLinkData)(sMainData *pDat, cNorthBridge *nb); - void (*setLinkData)(sMainData *pDat, cNorthBridge *nb); - - /* Public Interfaces for northbridge clients, System and performance Tuning. */ - void (*writeTrafficDistribution)(u32 links01, u32 links10, cNorthBridge *nb); - void (*bufferOptimizations)(u8 node, sMainData *pDat, cNorthBridge *nb); - - /* Private Data for northbridge implementation use only */ - u32 selfRouteRequestMask; - u32 selfRouteResponseMask; - u8 broadcastSelfBit; - u32 compatibleKey; -} ; - -void newNorthBridge(u8 node, cNorthBridge *nb); -uint8_t is_gt_rev_d(void); - -#endif /* H3NCMN_H */ diff --git a/src/northbridge/amd/amdht/ht_wrapper.c b/src/northbridge/amd/amdht/ht_wrapper.c deleted file mode 100644 index 89ff46eae3..0000000000 --- a/src/northbridge/amd/amdht/ht_wrapper.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * Copyright (C) 2007-2008 Advanced Micro Devices, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <arch/cpu.h> -#include <cpu/x86/msr.h> -#include <console/console.h> -#include <device/pci_ops.h> -#include "ht_wrapper.h" - -/*---------------------------------------------------------------------------- - * TYPEDEFS, DEFINITIONS AND MACROS - * - *---------------------------------------------------------------------------- - */ - -/* Single CPU system? */ -#if (CONFIG_MAX_PHYSICAL_CPUS == 1) - /* FIXME - * This #define is used by other #included .c files - * When set, multiprocessor support is completely disabled - */ - #define HT_BUILD_NC_ONLY 1 -#endif - -/* Debugging Options */ -//#define AMD_DEBUG_ERROR_STOP 1 - -/*---------------------------------------------------------------------------- - * MODULES USED - * - *---------------------------------------------------------------------------- - */ - -#include "comlib.h" -#include "h3gtopo.h" -#include "h3finit.h" - -/*---------------------------------------------------------------------------- - * LOCAL FUNCTIONS - * - *---------------------------------------------------------------------------- - */ - -static const char * event_class_string_decodes[] = { - [HT_EVENT_CLASS_CRITICAL] = "CRITICAL", - [HT_EVENT_CLASS_ERROR] = "ERROR", - [HT_EVENT_CLASS_HW_FAULT] = "HARDWARE FAULT", - [HT_EVENT_CLASS_WARNING] = "WARNING", - [HT_EVENT_CLASS_INFO] = "INFO" -}; - -typedef struct { - uint32_t code; - const char *string; -} event_string_decode_t; - -static const event_string_decode_t event_string_decodes[] = { - { HT_EVENT_COH_EVENTS, "HT_EVENT_COH_EVENTS" }, - { HT_EVENT_COH_NO_TOPOLOGY, "HT_EVENT_COH_NO_TOPOLOGY" }, - { HT_EVENT_COH_LINK_EXCEED, "HT_EVENT_COH_LINK_EXCEED" }, - { HT_EVENT_COH_FAMILY_FEUD, "HT_EVENT_COH_FAMILY_FEUD" }, - { HT_EVENT_COH_NODE_DISCOVERED, "HT_EVENT_COH_NODE_DISCOVERED" }, - { HT_EVENT_COH_MPCAP_MISMATCH, "HT_EVENT_COH_MPCAP_MISMATCH" }, - { HT_EVENT_NCOH_EVENTS, "HT_EVENT_NCOH_EVENTS" }, - { HT_EVENT_NCOH_BUID_EXCEED, "HT_EVENT_NCOH_BUID_EXCEED" }, - { HT_EVENT_NCOH_LINK_EXCEED, "HT_EVENT_NCOH_LINK_EXCEED" }, - { HT_EVENT_NCOH_BUS_MAX_EXCEED, "HT_EVENT_NCOH_BUS_MAX_EXCEED" }, - { HT_EVENT_NCOH_CFG_MAP_EXCEED, "HT_EVENT_NCOH_CFG_MAP_EXCEED" }, - { HT_EVENT_NCOH_DEVICE_FAILED, "HT_EVENT_NCOH_DEVICE_FAILED" }, - { HT_EVENT_NCOH_AUTO_DEPTH, "HT_EVENT_NCOH_AUTO_DEPTH" }, - { HT_EVENT_OPT_EVENTS, "HT_EVENT_OPT_EVENTS" }, - { HT_EVENT_OPT_REQUIRED_CAP_RETRY, "HT_EVENT_OPT_REQUIRED_CAP_RETRY" }, - { HT_EVENT_OPT_REQUIRED_CAP_GEN3, "HT_EVENT_OPT_REQUIRED_CAP_GEN3" }, - { HT_EVENT_HW_EVENTS, "HT_EVENT_HW_EVENTS" }, - { HT_EVENT_HW_SYNCHFLOOD, "HT_EVENT_HW_SYNCHFLOOD" }, - { HT_EVENT_HW_HTCRC, "HT_EVENT_HW_HTCRC" } -}; - -static const char *event_string_decode(uint32_t event) -{ - uint32_t i; - for (i = 0; i < ARRAY_SIZE(event_string_decodes); i++) - if (event_string_decodes[i].code == event) - break; - if (i == ARRAY_SIZE(event_string_decodes)) - return "ERROR: Unmatched event code! " - "Did you forget to update event_string_decodes[]?"; - return event_string_decodes[i].string; -} - -/** - * void AMD_CB_EventNotify (u8 evtClass, u16 event, const u8 *pEventData0) - */ -static void AMD_CB_EventNotify (u8 evtClass, u16 event, const u8 *pEventData0) -{ - uint8_t i; - uint8_t log_level; - uint8_t dump_event_detail; - - printk(BIOS_DEBUG, "%s: ", __func__); - - /* Decode event */ - dump_event_detail = 1; - switch (evtClass) { - case HT_EVENT_CLASS_CRITICAL: - case HT_EVENT_CLASS_ERROR: - case HT_EVENT_CLASS_HW_FAULT: - case HT_EVENT_CLASS_WARNING: - case HT_EVENT_CLASS_INFO: - log_level = BIOS_DEBUG; - printk(log_level, "%s", event_class_string_decodes[evtClass]); - break; - default: - log_level = BIOS_DEBUG; - printk(log_level, "UNKNOWN"); - break; - } - printk(log_level, ": "); - - switch (event) { - case HT_EVENT_COH_EVENTS: - case HT_EVENT_COH_NO_TOPOLOGY: - case HT_EVENT_COH_LINK_EXCEED: - case HT_EVENT_COH_FAMILY_FEUD: - printk(log_level, "%s", event_string_decode(event)); - break; - case HT_EVENT_COH_NODE_DISCOVERED: - { - printk(log_level, "HT_EVENT_COH_NODE_DISCOVERED"); - sHtEventCohNodeDiscovered *evt = (sHtEventCohNodeDiscovered*)pEventData0; - printk(log_level, ": node %d link %d new node: %d", - evt->node, evt->link, evt->newNode); - dump_event_detail = 0; - break; - } - case HT_EVENT_COH_MPCAP_MISMATCH: - case HT_EVENT_NCOH_EVENTS: - case HT_EVENT_NCOH_BUID_EXCEED: - case HT_EVENT_NCOH_LINK_EXCEED: - case HT_EVENT_NCOH_BUS_MAX_EXCEED: - case HT_EVENT_NCOH_CFG_MAP_EXCEED: - printk(log_level, "%s", event_string_decode(event)); - break; - case HT_EVENT_NCOH_DEVICE_FAILED: - { - printk(log_level, "%s", event_string_decode(event)); - sHtEventNcohDeviceFailed *evt = (sHtEventNcohDeviceFailed*)pEventData0; - printk(log_level, ": node %d link %d depth: %d attemptedBUID: %d", - evt->node, evt->link, evt->depth, evt->attemptedBUID); - dump_event_detail = 0; - break; - } - case HT_EVENT_NCOH_AUTO_DEPTH: - { - printk(log_level, "%s", event_string_decode(event)); - sHtEventNcohAutoDepth *evt = (sHtEventNcohAutoDepth*)pEventData0; - printk(log_level, ": node %d link %d depth: %d", - evt->node, evt->link, evt->depth); - dump_event_detail = 0; - break; - } - case HT_EVENT_OPT_EVENTS: - case HT_EVENT_OPT_REQUIRED_CAP_RETRY: - case HT_EVENT_OPT_REQUIRED_CAP_GEN3: - case HT_EVENT_HW_EVENTS: - case HT_EVENT_HW_SYNCHFLOOD: - case HT_EVENT_HW_HTCRC: - printk(log_level, "%s", event_string_decode(event)); - break; - default: - printk(log_level, "HT_EVENT_UNKNOWN"); - break; - } - printk(log_level, "\n"); - - if (dump_event_detail) { - printk(BIOS_DEBUG, " event class: %02x\n event: %04x\n data: ", evtClass, event); - - for (i = 0; i < *pEventData0; i++) { - printk(BIOS_DEBUG, " %02x ", *(pEventData0 + i)); - } - printk(BIOS_DEBUG, "\n"); - } -} - -/** - * void getAmdTopolist(u8 ***p) - * - * point to the stock topo list array - * - */ -void getAmdTopolist(u8 ***p) -{ - *p = (u8 **)amd_topo_list; -} - -/** - * BOOL AMD_CB_IgnoreLink(u8 Node, u8 Link) - * Description: - * This routine is used to ignore connected yet faulty HT links, - * such as those present in a G34 processor package. - * - * Parameters: - * @param[in] node = The node on which this chain is located - * @param[in] link = The link on the host for this chain - */ -static BOOL AMD_CB_IgnoreLink (u8 node, u8 link) -{ - return 0; -} - -/** - * void amd_ht_init(struct sys_info *sysinfo) - * - * AMD HT init coreboot wrapper - * - */ -void amd_ht_init(struct sys_info *sysinfo) -{ - - if (!sysinfo) { - printk(BIOS_DEBUG, "Skipping %s\n", __func__); - return; - } - - AMD_HTBLOCK ht_wrapper = { - NULL, // u8 **topolist; - 0, // u8 AutoBusStart; - 32, // u8 AutoBusMax; - 6, // u8 AutoBusIncrement; - AMD_CB_IgnoreLink, // BOOL (*AMD_CB_IgnoreLink)(); - NULL, // BOOL (*AMD_CB_OverrideBusNumbers)(); - AMD_CB_ManualBUIDSwapList, // BOOL (*AMD_CB_ManualBUIDSwapList)(); - NULL, // void (*AMD_CB_DeviceCapOverride)(); - NULL, // void (*AMD_CB_Cpu2CpuPCBLimits)(); - NULL, // void (*AMD_CB_IOPCBLimits)(); - NULL, // BOOL (*AMD_CB_SkipRegang)(); - NULL, // BOOL (*AMD_CB_CustomizeTrafficDistribution)(); - NULL, // BOOL (*AMD_CB_CustomizeBuffers)(); - NULL, // void (*AMD_CB_OverrideDevicePort)(); - NULL, // void (*AMD_CB_OverrideCpuPort)(); - AMD_CB_EventNotify, // void (*AMD_CB_EventNotify) (); - &sysinfo->ht_link_cfg // struct ht_link_config* - }; - - printk(BIOS_DEBUG, "Enter %s\n", __func__); - amdHtInitialize(&ht_wrapper); - printk(BIOS_DEBUG, "Exit %s\n", __func__); -} - -/** - * void amd_ht_fixup(struct sys_info *sysinfo) - * - * AMD HT fixup - * - */ -void amd_ht_fixup(struct sys_info *sysinfo) { - printk(BIOS_DEBUG, "%s\n", __func__); - if (CONFIG(CPU_AMD_MODEL_10XXX)) { - uint8_t rev_gte_d = 0; - uint8_t fam15h = 0; - uint8_t dual_node = 0; - uint32_t f3xe8; - uint32_t family; - uint32_t model; - - family = model = cpuid_eax(0x80000001); - model = ((model & 0xf0000) >> 12) | ((model & 0xf0) >> 4); - family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8); - - if (family >= 0x6f) - /* Family 15h or later */ - fam15h = 1; - - if ((model >= 0x8) || fam15h) - /* Family 10h Revision D or later */ - rev_gte_d = 1; - - if (rev_gte_d) { - f3xe8 = pci_read_config32(NODE_PCI(0, 3), 0xe8); - - /* Check for dual node capability */ - if (f3xe8 & 0x20000000) - dual_node = 1; - - if (dual_node) { - /* Each G34 processor contains a defective HT link. - * See the Family 10h BKDG Rev 3.62 section 2.7.1.5 for details - * For Family 15h see the BKDG Rev. 3.14 section 2.12.1.5 for details. - */ - uint8_t node; - uint8_t node_count = get_nodes(); - uint32_t dword; - for (node = 0; node < node_count; node++) { - f3xe8 = pci_read_config32(NODE_PCI(node, 3), 0xe8); - uint8_t internal_node_number = ((f3xe8 & 0xc0000000) >> 30); - printk(BIOS_DEBUG, - "%s: node %d (internal node " - "ID %d): disabling defective " - "HT link", __func__, node, - internal_node_number); - if (internal_node_number == 0) { - uint8_t package_link_3_connected = pci_read_config32(NODE_PCI(node, 0), (fam15h)?0x98:0xd8) & 0x1; - printk(BIOS_DEBUG, " (L3 connected: %d)\n", package_link_3_connected); - if (package_link_3_connected) { - /* Set WidthIn and WidthOut to 0 */ - dword = pci_read_config32(NODE_PCI(node, 0), (fam15h)?0x84:0xc4); - dword &= ~0x77000000; - pci_write_config32(NODE_PCI(node, 0), (fam15h)?0x84:0xc4, dword); - /* Set Ganged to 1 */ - dword = pci_read_config32(NODE_PCI(node, 0), (fam15h)?0x170:0x178); - dword |= 0x00000001; - pci_write_config32(NODE_PCI(node, 0), (fam15h)?0x170:0x178, dword); - } else { - /* Set ConnDly to 1 */ - dword = pci_read_config32(NODE_PCI(node, 0), 0x16c); - dword |= 0x00000100; - pci_write_config32(NODE_PCI(node, 0), 0x16c, dword); - /* Set TransOff and EndOfChain to 1 */ - dword = pci_read_config32(NODE_PCI(node, 4), (fam15h)?0x84:0xc4); - dword |= 0x000000c0; - pci_write_config32(NODE_PCI(node, 4), (fam15h)?0x84:0xc4, dword); - } - } else if (internal_node_number == 1) { - uint8_t package_link_3_connected = pci_read_config32(NODE_PCI(node, 0), (fam15h)?0xf8:0xb8) & 0x1; - printk(BIOS_DEBUG, " (L3 connected: %d)\n", package_link_3_connected); - if (package_link_3_connected) { - /* Set WidthIn and WidthOut to 0 */ - dword = pci_read_config32(NODE_PCI(node, 0), (fam15h)?0xe4:0xa4); - dword &= ~0x77000000; - pci_write_config32(NODE_PCI(node, 0), (fam15h)?0xe4:0xa4, dword); - /* Set Ganged to 1 */ - /* WARNING - * The Family 15h BKDG states that 0x18c should be set, - * however this is in error. 0x17c is the correct control - * register (sublink 0) for these processors... - */ - dword = pci_read_config32(NODE_PCI(node, 0), (fam15h)?0x17c:0x174); - dword |= 0x00000001; - pci_write_config32(NODE_PCI(node, 0), (fam15h)?0x17c:0x174, dword); - } else { - /* Set ConnDly to 1 */ - dword = pci_read_config32(NODE_PCI(node, 0), 0x16c); - dword |= 0x00000100; - pci_write_config32(NODE_PCI(node, 0), 0x16c, dword); - /* Set TransOff and EndOfChain to 1 */ - dword = pci_read_config32(NODE_PCI(node, 4), (fam15h)?0xe4:0xa4); - dword |= 0x000000c0; - pci_write_config32(NODE_PCI(node, 4), (fam15h)?0xe4:0xa4, dword); - } - } - } - } - } - } -} - -u32 get_nodes(void) -{ - pci_devfn_t dev; - u32 nodes; - - dev = PCI_DEV(CONFIG_CBB, CONFIG_CDB, 0); - nodes = ((pci_read_config32(dev, 0x60)>>4) & 7); -#if CONFIG_MAX_PHYSICAL_CPUS > 8 - nodes += (((pci_read_config32(dev, 0x160)>>4) & 7)<<3); -#endif - nodes++; - - return nodes; -} diff --git a/src/northbridge/amd/amdht/ht_wrapper.h b/src/northbridge/amd/amdht/ht_wrapper.h deleted file mode 100644 index 629e08f4fe..0000000000 --- a/src/northbridge/amd/amdht/ht_wrapper.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef AMD_HT_WRAPPER_H -#define AMD_HT_WRAPPER_H - -#include <northbridge/amd/amdfam10/raminit.h> -#include <northbridge/amd/amdfam10/amdfam10.h> -#include <stdint.h> -#include "h3finit.h" - -void amd_ht_fixup(struct sys_info *sysinfo); -u32 get_nodes(void); -void amd_ht_init(struct sys_info *sysinfo); - -#endif diff --git a/src/northbridge/amd/amdht/porting.h b/src/northbridge/amd/amdht/porting.h deleted file mode 100644 index 9058d4d0e1..0000000000 --- a/src/northbridge/amd/amdht/porting.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef PORTING_H -#define PORTING_H - - -/* For AMD64 or 32-bit GCC */ -typedef int int32; -typedef unsigned int uint32; -typedef short int16; -typedef unsigned short uint16; -typedef char int8; -typedef unsigned char uint8; - -/* Create the Boolean type */ -#define TRUE 1 -#define FALSE 0 -typedef unsigned char BOOL; - -/* Force tight packing of structures */ -#pragma pack(1) - -#define CALLCONV - - -typedef struct _uint64 -{ - uint32 lo; - uint32 hi; -}uint64; - - -/* - * SBDFO - Segment Bus Device Function Offset - * 31:28 Segment (4-bits) - * 27:20 Bus (8-bits) - * 19:15 Device (5-bits) - * 14:12 Function(3-bits) - * 11:00 Offset (12-bits) - */ -typedef uint32 SBDFO; - -#define MAKE_SBDFO(seg,bus,dev,fun,off) ((((uint32)(seg))<<28) | (((uint32)(bus))<<20) | \ - (((uint32)(dev))<<15) | (((uint32)(fun))<<12) | ((uint32)(off))) -#define SBDFO_SEG(x) (((uint32)(x)>>28) & 0x0F) -#define SBDFO_BUS(x) (((uint32)(x)>>20) & 0xFF) -#define SBDFO_DEV(x) (((uint32)(x)>>15) & 0x1F) -#define SBDFO_FUN(x) (((uint32)(x)>>12) & 0x07) -#define SBDFO_OFF(x) (((uint32)(x)) & 0xFFF) -#define ILLEGAL_SBDFO 0xFFFFFFFF - -void CALLCONV AmdMSRRead(uint32 Address, uint64 *Value); -void CALLCONV AmdMSRWrite(uint32 Address, uint64 *Value); -void CALLCONV AmdIORead(uint8 IOSize, uint16 Address, uint32 *Value); -void CALLCONV AmdIOWrite(uint8 IOSize, uint16 Address, uint32 *Value); -void CALLCONV AmdMemRead(uint8 MemSize, uint64 *Address, uint32 *Value); -void CALLCONV AmdMemWrite(uint8 MemSize, uint64 *Address, uint32 *Value); -void CALLCONV AmdPCIRead(SBDFO loc, uint32 *Value); -void CALLCONV AmdPCIWrite(SBDFO loc, uint32 *Value); -void CALLCONV AmdCPUIDRead(uint32 Address, uint32 Regs[4]); - -#define BYTESIZE 1 -#define WORDSIZE 2 -#define DWORDSIZE 4 - -#endif /* PORTING_H */ |