diff options
Diffstat (limited to 'resources/libreboot/patch/coreboot/33fb4cf0ffb01be8bcb6b488872c87eb50e7d77f/grub/kgpe-d16/0090-northbridge-amd-amdfam10-Add-probe-filter-support.patch')
-rw-r--r-- | resources/libreboot/patch/coreboot/33fb4cf0ffb01be8bcb6b488872c87eb50e7d77f/grub/kgpe-d16/0090-northbridge-amd-amdfam10-Add-probe-filter-support.patch | 282 |
1 files changed, 282 insertions, 0 deletions
diff --git a/resources/libreboot/patch/coreboot/33fb4cf0ffb01be8bcb6b488872c87eb50e7d77f/grub/kgpe-d16/0090-northbridge-amd-amdfam10-Add-probe-filter-support.patch b/resources/libreboot/patch/coreboot/33fb4cf0ffb01be8bcb6b488872c87eb50e7d77f/grub/kgpe-d16/0090-northbridge-amd-amdfam10-Add-probe-filter-support.patch new file mode 100644 index 0000000..1a684e2 --- /dev/null +++ b/resources/libreboot/patch/coreboot/33fb4cf0ffb01be8bcb6b488872c87eb50e7d77f/grub/kgpe-d16/0090-northbridge-amd-amdfam10-Add-probe-filter-support.patch @@ -0,0 +1,282 @@ +From 7aca5c828dde51868dcf4c46ba19f5dc34aaf7d3 Mon Sep 17 00:00:00 2001 +From: Timothy Pearson <tpearson@raptorengineeringinc.com> +Date: Sun, 2 Aug 2015 21:06:39 -0500 +Subject: [PATCH 090/143] northbridge/amd/amdfam10: Add probe filter support + +Change-Id: I00a27a828260be8685ae622cfa5a4995add95a8e +Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> +--- + src/cpu/amd/family_10h-family_15h/init_cpus.c | 13 ++ + .../amd/family_10h-family_15h/model_10xxx_init.c | 22 +++ + src/northbridge/amd/amdfam10/northbridge.c | 144 +++++++++++++++++++- + src/northbridge/amd/amdht/h3ncmn.c | 22 +++ + 4 files changed, 200 insertions(+), 1 deletion(-) + +diff --git a/src/cpu/amd/family_10h-family_15h/init_cpus.c b/src/cpu/amd/family_10h-family_15h/init_cpus.c +index 4e5098e..7d303e0 100644 +--- a/src/cpu/amd/family_10h-family_15h/init_cpus.c ++++ b/src/cpu/amd/family_10h-family_15h/init_cpus.c +@@ -445,6 +445,19 @@ static u32 init_cpus(u32 cpu_init_detectedx, struct sys_info *sysinfo) + + cpuSetAMDMSR(id.nodeid); + ++ /* Set up probe filter support */ ++ if (is_gt_rev_d()) { ++ uint8_t node_count; ++ node_count = (pci_read_config32(NODE_PCI(id.nodeid, 0), 0x60) >> 4) & 0x7; ++ node_count++; ++ ++ if (node_count > 1) { ++ msr_t msr = rdmsr(BU_CFG2_MSR); ++ msr.hi |= 1 << (42 - 32); ++ wrmsr(BU_CFG2_MSR, msr); ++ } ++ } ++ + #if CONFIG_SET_FIDVID + #if CONFIG_LOGICAL_CPUS && CONFIG_SET_FIDVID_CORE0_ONLY + // Run on all AP for proper FID/VID setup. +diff --git a/src/cpu/amd/family_10h-family_15h/model_10xxx_init.c b/src/cpu/amd/family_10h-family_15h/model_10xxx_init.c +index 8a61f13..5c590b8 100644 +--- a/src/cpu/amd/family_10h-family_15h/model_10xxx_init.c ++++ b/src/cpu/amd/family_10h-family_15h/model_10xxx_init.c +@@ -54,6 +54,28 @@ static inline uint8_t is_fam15h(void) + return fam15h; + } + ++static 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; ++} ++ + static volatile uint8_t fam15h_startup_flags[MAX_NODES_SUPPORTED][MAX_CORES_SUPPORTED] = {{ 0 }}; + + static void model_10xxx_init(device_t dev) +diff --git a/src/northbridge/amd/amdfam10/northbridge.c b/src/northbridge/amd/amdfam10/northbridge.c +index 52b5ffb..808cd3a 100644 +--- a/src/northbridge/amd/amdfam10/northbridge.c ++++ b/src/northbridge/amd/amdfam10/northbridge.c +@@ -30,10 +30,13 @@ + #include <lib.h> + #include <smbios.h> + #include <cpu/cpu.h> ++#include <delay.h> + + #include <cpu/x86/lapic.h> ++#include <cpu/x86/cache.h> + #include <cpu/amd/mtrr.h> + #include <cpu/amd/amdfam10_sysconf.h> ++#include <cpu/amd/model_10xxx_msr.h> + #include <cpu/amd/family_10h-family_15h/ram_calc.h> + + #if CONFIG_LOGICAL_CPUS +@@ -1527,7 +1530,7 @@ static void cpu_bus_scan(device_t dev) + if(i>=32) { + busn--; + devn-=32; +- pbus = pci_domain->link_list->next); ++ pbus = pci_domain->link_list->next; + } + #endif + +@@ -1647,8 +1650,147 @@ static void cpu_bus_scan(device_t dev) + } + } + ++static void detect_and_enable_probe_filter(device_t dev) ++{ ++ uint32_t dword; ++ ++ uint8_t fam15h = 0; ++ uint8_t rev_gte_d = 0; ++ uint8_t dual_node = 0; ++ unsigned nb_cfg_54; ++ uint32_t f3xe8; ++ uint32_t family; ++ uint32_t model; ++ ++ family = model = cpuid_eax(0x80000001); ++ model = ((model & 0xf0000) >> 12) | ((model & 0xf0) >> 4); ++ ++ if (is_fam15h()) { ++ /* Family 15h or later */ ++ fam15h = 1; ++ nb_cfg_54 = 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; ++ ++ if (rev_gte_d && (sysconf.nodes > 1)) { ++ /* Enable the probe filter */ ++ uint8_t i; ++ uint8_t pfmode = 0x0; ++ ++ uint32_t f3x58[MAX_NODES_SUPPORTED]; ++ uint32_t f3x5c[MAX_NODES_SUPPORTED]; ++ ++ printk(BIOS_DEBUG, "Enabling probe filter\n"); ++ ++ /* Disable L3 and DRAM scrubbers and configure system for probe filter support */ ++ for (i = 0; i < sysconf.nodes; i++) { ++ device_t f2x_dev = dev_find_slot(0, PCI_DEVFN(0x18 + i, 2)); ++ device_t f3x_dev = dev_find_slot(0, PCI_DEVFN(0x18 + i, 3)); ++ ++ f3x58[i] = pci_read_config32(f3x_dev, 0x58); ++ f3x5c[i] = pci_read_config32(f3x_dev, 0x5c); ++ pci_write_config32(f3x_dev, 0x58, f3x58[i] & ~((0x1f << 24) | 0x1f)); ++ pci_write_config32(f3x_dev, 0x5c, f3x5c[i] & ~0x1); ++ ++ dword = pci_read_config32(f2x_dev, 0x1b0); ++ dword &= ~(0x7 << 8); /* CohPrefPrbLmt = 0x0 */ ++ pci_write_config32(f2x_dev, 0x1b0, dword); ++ ++ msr_t msr = rdmsr_amd(BU_CFG2_MSR); ++ msr.hi |= 1 << (42 - 32); ++ wrmsr_amd(BU_CFG2_MSR, msr); ++ ++ if (is_fam15h()) { ++ uint8_t subcache_size = 0x0; ++ uint8_t pref_so_repl = 0x0; ++ uint32_t f3x1c4 = pci_read_config32(f3x_dev, 0x1c4); ++ if ((f3x1c4 & 0xffff) == 0xcccc) { ++ subcache_size = 0x1; ++ pref_so_repl = 0x2; ++ pfmode = 0x3; ++ } else { ++ pfmode = 0x2; ++ } ++ ++ dword = pci_read_config32(f3x_dev, 0x1d4); ++ dword |= 0x1 << 29; /* PFLoIndexHashEn = 0x1 */ ++ dword &= ~(0x3 << 20); /* PFPreferredSORepl = pref_so_repl */ ++ dword |= (pref_so_repl & 0x3) << 20; ++ dword |= 0x1 << 17; /* PFWayHashEn = 0x1 */ ++ dword |= 0xf << 12; /* PFSubCacheEn = 0xf */ ++ dword &= ~(0x3 << 10); /* PFSubCacheSize3 = subcache_size */ ++ dword |= (subcache_size & 0x3) << 10; ++ dword &= ~(0x3 << 8); /* PFSubCacheSize2 = subcache_size */ ++ dword |= (subcache_size & 0x3) << 8; ++ dword &= ~(0x3 << 6); /* PFSubCacheSize1 = subcache_size */ ++ dword |= (subcache_size & 0x3) << 6; ++ dword &= ~(0x3 << 4); /* PFSubCacheSize0 = subcache_size */ ++ dword |= (subcache_size & 0x3) << 4; ++ dword &= ~(0x3 << 2); /* PFWayNum = 0x2 */ ++ dword |= 0x2 << 2; ++ pci_write_config32(f3x_dev, 0x1d4, dword); ++ } else { ++ pfmode = 0x2; ++ ++ dword = pci_read_config32(f3x_dev, 0x1d4); ++ dword |= 0x1 << 29; /* PFLoIndexHashEn = 0x1 */ ++ dword &= ~(0x3 << 20); /* PFPreferredSORepl = 0x2 */ ++ dword |= 0x2 << 20; ++ dword |= 0xf << 12; /* PFSubCacheEn = 0xf */ ++ dword &= ~(0x3 << 10); /* PFSubCacheSize3 = 0x0 */ ++ dword &= ~(0x3 << 8); /* PFSubCacheSize2 = 0x0 */ ++ dword &= ~(0x3 << 6); /* PFSubCacheSize1 = 0x0 */ ++ dword &= ~(0x3 << 4); /* PFSubCacheSize0 = 0x0 */ ++ dword &= ~(0x3 << 2); /* PFWayNum = 0x2 */ ++ dword |= 0x2 << 2; ++ pci_write_config32(f3x_dev, 0x1d4, dword); ++ } ++ } ++ ++ udelay(40); ++ ++ disable_cache(); ++ asm("wbinvd"); ++ for (i = 0; i < sysconf.nodes; i++) { ++ device_t f3x_dev = dev_find_slot(0, PCI_DEVFN(0x18 + i, 3)); ++ ++ dword = pci_read_config32(f3x_dev, 0x1c4); ++ dword |= (0x1 << 31); /* L3TagInit = 1 */ ++ pci_write_config32(f3x_dev, 0x1c4, dword); ++ do { ++ } while (pci_read_config32(f3x_dev, 0x1c4) & (0x1 << 31)); ++ ++ dword = pci_read_config32(f3x_dev, 0x1d4); ++ dword &= ~0x3; /* PFMode = pfmode */ ++ dword |= pfmode & 0x3; ++ pci_write_config32(f3x_dev, 0x1d4, dword); ++ do { ++ } while (!(pci_read_config32(f3x_dev, 0x1d4) & (0x1 << 19))); ++ } ++ enable_cache(); ++ ++ /* Reenable L3 and DRAM scrubbers */ ++ for (i = 0; i < sysconf.nodes; i++) { ++ device_t f3x_dev = dev_find_slot(0, PCI_DEVFN(0x18 + i, 3)); ++ ++ pci_write_config32(f3x_dev, 0x58, f3x58[i]); ++ pci_write_config32(f3x_dev, 0x5c, f3x5c[i]); ++ } ++ ++ } ++} ++ + static void cpu_bus_init(device_t dev) + { ++ detect_and_enable_probe_filter(dev); + initialize_cpus(dev->link_list); + #if CONFIG_AMD_SB_CIMX + sb_After_Pci_Init(); +diff --git a/src/northbridge/amd/amdht/h3ncmn.c b/src/northbridge/amd/amdht/h3ncmn.c +index 1026d0e..a27ee5b 100644 +--- a/src/northbridge/amd/amdht/h3ncmn.c ++++ b/src/northbridge/amd/amdht/h3ncmn.c +@@ -107,6 +107,28 @@ static inline uint8_t is_fam15h(void) + return fam15h; + } + ++static 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 +-- +1.7.9.5 + |