cpu/amd: Add initial AMD Family 15h support
TEST: Booted ASUS KGPE-D16 with single Opteron 6380 * Unbuffered DDR3 DIMMs tested and working * Suspend to RAM (S3) tested and working Change-Id: Idffd2ce36ce183fbfa087e5ba69a9148f084b45e Signed-off-by: Timothy Pearson <tpearson@raptorengineeringinc.com> Reviewed-on: http://review.coreboot.org/11966 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
committed by
Martin Roth
parent
d150006c4a
commit
730a043fb6
@@ -28,19 +28,24 @@
|
||||
#define CacheSizeAPStack CONFIG_DCACHE_AP_STACK_SIZE
|
||||
|
||||
#define MSR_MCFG_BASE 0xC0010058
|
||||
#define MSR_FAM10 0xC001102A
|
||||
#define MSR_BU_CFG2 0xC001102A
|
||||
|
||||
#define jmp_if_not_k8(x) comisd %xmm2, %xmm1; jae x
|
||||
#define jmp_if_k8(x) comisd %xmm2, %xmm1; jb x
|
||||
#define jmp_if_not_fam15h(x) comisd %xmm3, %xmm1; jb x
|
||||
#define jmp_if_fam15h(x) comisd %xmm3, %xmm1; jae x
|
||||
|
||||
#define CPUID_MASK 0x0ff00f00
|
||||
#define CPUID_VAL_FAM10_ROTATED 0x0f000010
|
||||
#define CPUID_VAL_FAM15_ROTATED 0x0f000060
|
||||
|
||||
/*
|
||||
* XMM map:
|
||||
* xmm1: CPU family
|
||||
* xmm2: Fam10h comparison value
|
||||
* xmm3: Backup EBX
|
||||
* xmm3: Fam15h comparison value
|
||||
* xmm4: Backup EBX
|
||||
* xmm5: Coreboot init detect
|
||||
*/
|
||||
|
||||
/* Save the BIST result. */
|
||||
@@ -60,7 +65,7 @@ cache_as_ram_setup:
|
||||
movl %eax, %cr4
|
||||
|
||||
/* Figure out the CPU family. */
|
||||
cvtsi2sd %ebx, %xmm3
|
||||
cvtsi2sd %ebx, %xmm4
|
||||
movl $0x01, %eax
|
||||
cpuid
|
||||
/* Base family is bits 8..11, extended family is bits 20..27. */
|
||||
@@ -70,13 +75,16 @@ cache_as_ram_setup:
|
||||
cvtsi2sd %eax, %xmm1
|
||||
movl $CPUID_VAL_FAM10_ROTATED, %eax
|
||||
cvtsi2sd %eax, %xmm2
|
||||
cvtsd2si %xmm3, %ebx
|
||||
movl $CPUID_VAL_FAM15_ROTATED, %eax
|
||||
cvtsi2sd %eax, %xmm3
|
||||
cvtsd2si %xmm4, %ebx
|
||||
|
||||
/* Check if cpu_init_detected. */
|
||||
movl $MTRR_DEF_TYPE_MSR, %ecx
|
||||
rdmsr
|
||||
andl $MTRR_DEF_TYPE_EN, %eax
|
||||
movl %eax, %ebx /* We store the status. */
|
||||
cvtsi2sd %ebx, %xmm5
|
||||
|
||||
jmp_if_k8(CAR_FAM10_out_post_errata)
|
||||
|
||||
@@ -117,21 +125,24 @@ cache_as_ram_setup:
|
||||
|
||||
CAR_FAM10_out:
|
||||
|
||||
jmp_if_fam15h(CAR_FAM10_errata_applied)
|
||||
/*
|
||||
* Errata 193: Disable clean copybacks to L3 cache to allow cached ROM.
|
||||
* Re-enable it in after RAM is initialized and before CAR is disabled.
|
||||
*/
|
||||
movl $MSR_FAM10, %ecx
|
||||
movl $MSR_BU_CFG2, %ecx
|
||||
rdmsr
|
||||
bts $15, %eax
|
||||
bts $15, %eax /* Set bit 15 in EDX:EAX (bit 15 in EAX). */
|
||||
wrmsr
|
||||
|
||||
/* Erratum 343, RevGuide for Fam10h, Pub#41322 Rev. 3.33 */
|
||||
movl $MSR_FAM10, %ecx
|
||||
movl $MSR_BU_CFG2, %ecx
|
||||
rdmsr
|
||||
bts $35-32, %edx /* Set bit 35 in EDX:EAX (bit 3 in EDX). */
|
||||
wrmsr
|
||||
|
||||
CAR_FAM10_errata_applied:
|
||||
|
||||
#if CONFIG_MMCONF_SUPPORT
|
||||
#if (CONFIG_MMCONF_BASE_ADDRESS > 0xFFFFFFFF)
|
||||
#error "MMCONF_BASE_ADDRESS too big"
|
||||
@@ -166,6 +177,63 @@ CAR_FAM10_out:
|
||||
|
||||
CAR_FAM10_out_post_errata:
|
||||
|
||||
/* Fam15h APIC IDs do not depend on NB config bit 54 */
|
||||
jmp_if_not_fam15h(skip_nb54_set)
|
||||
movl $0xc001001f, %ecx /* NB_CFG_MSR */
|
||||
rdmsr
|
||||
bts $(54 - 32), %edx /* Set NB config bit 54 */
|
||||
wrmsr
|
||||
|
||||
skip_nb54_set:
|
||||
/* On Fam15h CPUs each compute unit's MTRRs are shared between two cores */
|
||||
jmp_if_not_fam15h(skip_cu_check)
|
||||
|
||||
/* Get the initial APIC ID. */
|
||||
movl $1, %eax
|
||||
cpuid
|
||||
movl %ebx, %eax
|
||||
|
||||
/* Restore init detect */
|
||||
cvtsd2si %xmm5, %ebx
|
||||
|
||||
/* Determine if this is the second core to start in a compute unit; if so, wait for first core start, clear init detect and skip MTRR init */
|
||||
bt $24, %eax
|
||||
jnc skip_cu_check /* First core in the compute unit jumps to skip_cu_check */
|
||||
|
||||
/* Determine if this is the second core to start in a compute unit; if so, clear init detect and skip MTRR init */
|
||||
/* Busywait until the first core sets up the MTRRs */
|
||||
check_init_detect_1:
|
||||
/* Check if cpu_init_detected. */
|
||||
movl $MTRR_DEF_TYPE_MSR, %ecx
|
||||
rdmsr
|
||||
andl $MTRR_DEF_TYPE_EN, %eax
|
||||
cmp $0x00000000, %eax
|
||||
je check_init_detect_1 /* First core has not yet started */
|
||||
|
||||
check_init_detect_2:
|
||||
movl $SYSCFG_MSR, %ecx
|
||||
rdmsr
|
||||
andl $(SYSCFG_MSR_MtrrFixDramEn | SYSCFG_MSR_MtrrVarDramEn), %eax
|
||||
cmp $0x00000000, %eax
|
||||
je check_init_detect_2 /* First core has not yet started */
|
||||
|
||||
/* First core has now started */
|
||||
movl $0x00000000, %ebx /* Clear init detect flag */
|
||||
cvtsi2sd %ebx, %xmm5
|
||||
jmp fam10_mtrr_setup_complete
|
||||
|
||||
skip_cu_check:
|
||||
|
||||
jmp_if_not_fam15h(CAR_FAM15_errata_applied)
|
||||
|
||||
/* Erratum 714, RevGuide for Fam15h, Pub#48063 Rev. 3.24 */
|
||||
movl $MSR_BU_CFG2, %ecx
|
||||
rdmsr
|
||||
bts $8, %eax /* Set bit 8 in EDX:EAX (bit 8 in EAX). */
|
||||
wrmsr
|
||||
|
||||
CAR_FAM15_errata_applied:
|
||||
|
||||
/* Set MtrrFixDramModEn for clear fixed MTRR. */
|
||||
enable_fixed_mtrr_dram_modify:
|
||||
movl $SYSCFG_MSR, %ecx
|
||||
@@ -334,8 +402,42 @@ wbcache_post_fam10_setup:
|
||||
orl $(SYSCFG_MSR_MtrrVarDramEn | SYSCFG_MSR_MtrrFixDramEn), %eax
|
||||
wrmsr
|
||||
|
||||
fam10_mtrr_setup_complete:
|
||||
post_code(0xa1)
|
||||
|
||||
/* Disable conversion of INVD to WBINVD (INVDWBINVD = 0) */
|
||||
mov $0xc0010015, %ecx
|
||||
rdmsr
|
||||
btr $4, %eax
|
||||
wrmsr
|
||||
|
||||
jmp_if_not_fam15h(fam15_car_msr_setup_complete)
|
||||
/* Disable streaming store (DisSS = 1) */
|
||||
mov $0xc0011020, %ecx
|
||||
rdmsr
|
||||
bts $28, %eax
|
||||
wrmsr
|
||||
|
||||
/* Disable speculative ITLB reloads (DisSpecTlbRld = 1) */
|
||||
mov $0xc0011021, %ecx
|
||||
rdmsr
|
||||
bts $9, %eax
|
||||
wrmsr
|
||||
|
||||
/* Disable speculative DTLB reloads (DisSpecTlbRld = 1) and set DisHwPf = 1 */
|
||||
mov $0xc0011022, %ecx
|
||||
rdmsr
|
||||
bts $4, %eax
|
||||
bts $13, %eax
|
||||
wrmsr
|
||||
|
||||
/* Disable CR0 combining (CombineCr0Cd = 0) */
|
||||
mov $0xc001102b, %ecx
|
||||
rdmsr
|
||||
btr $49-32, %edx
|
||||
wrmsr
|
||||
fam15_car_msr_setup_complete:
|
||||
|
||||
/* Enable cache. */
|
||||
movl %cr0, %eax
|
||||
andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
|
||||
@@ -416,9 +518,6 @@ CAR_FAM10_ap:
|
||||
* to reverse it.
|
||||
*/
|
||||
|
||||
/* Store our init detected. */
|
||||
movl %ebx, %esi
|
||||
|
||||
/* Get the coreid bits at first. */
|
||||
movl $0x80000008, %eax
|
||||
cpuid
|
||||
@@ -437,6 +536,8 @@ CAR_FAM10_ap:
|
||||
movl %edi, %ecx /* CoreID bits */
|
||||
bt $(54 - 32), %edx
|
||||
jc roll_cfg
|
||||
|
||||
/* Fam10h NB config bit 54 was not set */
|
||||
rolb %cl, %bl
|
||||
roll_cfg:
|
||||
|
||||
@@ -446,8 +547,8 @@ roll_cfg:
|
||||
movl $(CacheBase + (CacheSize - (CacheSizeBSPStack + CacheSizeBSPSlush))), %esp
|
||||
subl %eax, %esp
|
||||
|
||||
/* Retrive init detected. */
|
||||
movl %esi, %ebx
|
||||
/* Restore init detect */
|
||||
cvtsd2si %xmm5, %ebx
|
||||
|
||||
post_code(0xa4)
|
||||
|
||||
@@ -460,6 +561,8 @@ CAR_FAM10_ap_out:
|
||||
andl $~(3 << 9), %eax
|
||||
movl %eax, %cr4
|
||||
|
||||
post_code(0xa6)
|
||||
|
||||
/* Restore the BIST result. */
|
||||
movl %ebp, %eax
|
||||
|
||||
@@ -467,6 +570,9 @@ CAR_FAM10_ap_out:
|
||||
movl %esp, %ebp
|
||||
pushl %ebx /* Init detected. */
|
||||
pushl %eax /* BIST */
|
||||
|
||||
post_code(0xa7)
|
||||
|
||||
call cache_as_ram_main
|
||||
|
||||
/* We will not go back. */
|
||||
|
@@ -15,46 +15,95 @@
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* be warned, this file will be used other cores and core 0 / node 0
|
||||
* WARNING: this file will be used by both any AP cores and core 0 / node 0
|
||||
*/
|
||||
|
||||
#include <cpu/x86/cache.h>
|
||||
|
||||
static inline __attribute__((always_inline)) void disable_cache_as_ram(void)
|
||||
static inline __attribute__((always_inline)) uint32_t amd_fam1x_cpu_family(void)
|
||||
{
|
||||
uint32_t family;
|
||||
|
||||
family = cpuid_eax(0x80000001);
|
||||
family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
|
||||
|
||||
return family;
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) void disable_cache_as_ram(uint8_t skip_sharedc_config)
|
||||
{
|
||||
msr_t msr;
|
||||
uint32_t family;
|
||||
|
||||
/* disable cache */
|
||||
write_cr0(read_cr0() | CR0_CacheDisable);
|
||||
if (!skip_sharedc_config) {
|
||||
/* disable cache */
|
||||
write_cr0(read_cr0() | CR0_CacheDisable);
|
||||
|
||||
msr.lo = 0;
|
||||
msr.hi = 0;
|
||||
wrmsr(MTRR_FIX_4K_C8000, msr);
|
||||
msr.lo = 0;
|
||||
msr.hi = 0;
|
||||
wrmsr(MTRR_FIX_4K_C8000, msr);
|
||||
#if CONFIG_DCACHE_RAM_SIZE > 0x8000
|
||||
wrmsr(MTRR_FIX_4K_C0000, msr);
|
||||
wrmsr(MTRR_FIX_4K_C0000, msr);
|
||||
#endif
|
||||
#if CONFIG_DCACHE_RAM_SIZE > 0x10000
|
||||
wrmsr(MTRR_FIX_4K_D0000, msr);
|
||||
wrmsr(MTRR_FIX_4K_D0000, msr);
|
||||
#endif
|
||||
#if CONFIG_DCACHE_RAM_SIZE > 0x18000
|
||||
wrmsr(MTRR_FIX_4K_D8000, msr);
|
||||
wrmsr(MTRR_FIX_4K_D8000, msr);
|
||||
#endif
|
||||
/* disable fixed mtrr from now on, it will be enabled by ramstage again*/
|
||||
/* disable fixed mtrr from now on, it will be enabled by ramstage again */
|
||||
msr = rdmsr(SYSCFG_MSR);
|
||||
msr.lo &= ~(SYSCFG_MSR_MtrrFixDramEn | SYSCFG_MSR_MtrrFixDramModEn);
|
||||
wrmsr(SYSCFG_MSR, msr);
|
||||
|
||||
msr = rdmsr(SYSCFG_MSR);
|
||||
msr.lo &= ~(SYSCFG_MSR_MtrrFixDramEn | SYSCFG_MSR_MtrrFixDramModEn);
|
||||
wrmsr(SYSCFG_MSR, msr);
|
||||
/* Set the default memory type and disable fixed and enable variable MTRRs */
|
||||
msr.hi = 0;
|
||||
msr.lo = (1 << 11);
|
||||
|
||||
/* Set the default memory type and disable fixed and enable variable MTRRs */
|
||||
msr.hi = 0;
|
||||
msr.lo = (1 << 11);
|
||||
wrmsr(MTRR_DEF_TYPE_MSR, msr);
|
||||
|
||||
wrmsr(MTRR_DEF_TYPE_MSR, msr);
|
||||
enable_cache();
|
||||
}
|
||||
|
||||
enable_cache();
|
||||
/* INVDWBINVD = 1 */
|
||||
msr = rdmsr(0xc0010015);
|
||||
msr.lo |= (0x1 << 4);
|
||||
wrmsr(0xc0010015, msr);
|
||||
|
||||
family = amd_fam1x_cpu_family();
|
||||
|
||||
#if IS_ENABLED(CPU_AMD_MODEL_10XXX)
|
||||
if (family >= 0x6f) {
|
||||
/* Family 15h or later */
|
||||
|
||||
/* DisSS = 0 */
|
||||
msr = rdmsr(0xc0011020);
|
||||
msr.lo &= ~(0x1 << 28);
|
||||
wrmsr(0xc0011020, msr);
|
||||
|
||||
if (!skip_sharedc_config) {
|
||||
/* DisSpecTlbRld = 0 */
|
||||
msr = rdmsr(0xc0011021);
|
||||
msr.lo &= ~(0x1 << 9);
|
||||
wrmsr(0xc0011021, msr);
|
||||
|
||||
/* Erratum 714: SpecNbReqDis = 0 */
|
||||
msr = rdmsr(BU_CFG2_MSR);
|
||||
msr.lo &= ~(0x1 << 8);
|
||||
wrmsr(BU_CFG2_MSR, msr);
|
||||
}
|
||||
|
||||
/* DisSpecTlbRld = 0 */
|
||||
/* DisHwPf = 0 */
|
||||
msr = rdmsr(0xc0011022);
|
||||
msr.lo &= ~(0x1 << 4);
|
||||
msr.lo &= ~(0x1 << 13);
|
||||
wrmsr(0xc0011022, msr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void disable_cache_as_ram_bsp(void)
|
||||
{
|
||||
disable_cache_as_ram();
|
||||
disable_cache_as_ram(0);
|
||||
}
|
||||
|
@@ -84,18 +84,19 @@ static void prepare_ramstage_region(void *resume_backup_memory)
|
||||
static void vErrata343(void)
|
||||
{
|
||||
#ifdef BU_CFG2_MSR
|
||||
msr_t msr;
|
||||
unsigned int uiMask = 0xFFFFFFF7;
|
||||
msr_t msr;
|
||||
unsigned int uiMask = 0xFFFFFFF7;
|
||||
|
||||
msr = rdmsr(BU_CFG2_MSR);
|
||||
msr.hi &= uiMask; // set bit 35 to 0
|
||||
wrmsr(BU_CFG2_MSR, msr);
|
||||
msr = rdmsr(BU_CFG2_MSR);
|
||||
msr.hi &= uiMask; // IcDisSpecTlbWr (bit 35) = 0
|
||||
wrmsr(BU_CFG2_MSR, msr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void post_cache_as_ram(void)
|
||||
{
|
||||
void *resume_backup_memory = NULL;
|
||||
uint32_t family = amd_fam1x_cpu_family();
|
||||
|
||||
struct romstage_handoff *handoff;
|
||||
handoff = romstage_handoff_find_or_add();
|
||||
@@ -112,7 +113,10 @@ void post_cache_as_ram(void)
|
||||
prepare_romstage_ramstack(resume_backup_memory);
|
||||
|
||||
/* from here don't store more data in CAR */
|
||||
vErrata343();
|
||||
if (family < 0x6f) {
|
||||
/* Family 10h or earlier */
|
||||
vErrata343();
|
||||
}
|
||||
|
||||
size_t car_size = car_data_size();
|
||||
void *migrated_car = (void *)(CONFIG_RAMTOP - car_size);
|
||||
|
@@ -2,6 +2,7 @@
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 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
|
||||
@@ -21,41 +22,65 @@
|
||||
*/
|
||||
static const struct {
|
||||
u32 msr;
|
||||
u32 revision;
|
||||
uint64_t revision;
|
||||
u32 platform;
|
||||
u32 data_lo;
|
||||
u32 data_hi;
|
||||
u32 mask_lo;
|
||||
u32 mask_hi;
|
||||
} fam10_msr_default[] = {
|
||||
{ TOP_MEM2, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
{ TOP_MEM2, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
0x00000000, 0x00000000,
|
||||
0xFFFFFFFF, 0xFFFFFFFF },
|
||||
|
||||
{ SYSCFG, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
{ SYSCFG, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
3 << 21, 0x00000000,
|
||||
3 << 21, 0x00000000 }, /* [MtrrTom2En]=1,[TOM2EnWB] = 1*/
|
||||
|
||||
{ HWCR, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
1 << 4, 0x00000000,
|
||||
1 << 4, 0x00000000 }, /* [INVD_WBINVD]=1 */
|
||||
{ MC1_CTL_MASK, AMD_OR_B2, AMD_PTYPE_ALL,
|
||||
1 << 18, 0x00000000,
|
||||
1 << 18, 0x00000000 }, /* Erratum 586: [DEIBP]=1 */
|
||||
|
||||
{ MC4_CTL_MASK, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
{ MC1_CTL_MASK, AMD_OR_B2, AMD_PTYPE_ALL,
|
||||
1 << 15, 0x00000000,
|
||||
1 << 15, 0x00000000 }, /* Erratum 593: [BSRP]=1 */
|
||||
|
||||
{ MC1_CTL_MASK, AMD_OR_C0, AMD_PTYPE_ALL,
|
||||
1 << 15, 0x00000000,
|
||||
1 << 15, 0x00000000 }, /* Erratum 739: [BSRP]=1 */
|
||||
|
||||
{ 0xc0011000, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
1 << 16, 0x00000000,
|
||||
1 << 16, 0x00000000 }, /* Erratum 608: [bit 16]=1 */
|
||||
|
||||
{ 0xc0011000, AMD_OR_C0, AMD_PTYPE_ALL,
|
||||
1 << 15, 0x00000000,
|
||||
1 << 15, 0x00000000 }, /* Erratum 727: [bit 15]=1 */
|
||||
|
||||
{ MC4_CTL_MASK, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
0xF << 19, 0x00000000,
|
||||
0xF << 19, 0x00000000 }, /* [RtryHt[0..3]]=1 */
|
||||
|
||||
{ MC4_CTL_MASK, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
1 << 10, 0x00000000,
|
||||
1 << 10, 0x00000000 }, /* [GartTblWkEn]=1 */
|
||||
|
||||
{ DC_CFG, AMD_FAM10_ALL, AMD_PTYPE_SVR,
|
||||
0x00000000, 0x00000004,
|
||||
0x00000000, 0x0000000C }, /* [REQ_CTR] = 1 for Server */
|
||||
0x00000000, 0x0000000C }, /* Family 10h: [REQ_CTR] = 1 for Server */
|
||||
|
||||
{ DC_CFG, AMD_DR_Bx, AMD_PTYPE_SVR,
|
||||
0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000C00 }, /* Erratum 326 */
|
||||
|
||||
{ NB_CFG, AMD_FAM10_ALL, AMD_PTYPE_DC | AMD_PTYPE_MC,
|
||||
{ NB_CFG, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_DC | AMD_PTYPE_MC,
|
||||
0x00000000, 1 << 22,
|
||||
0x00000000, 1 << 22 }, /* [ApicInitIDLo]=1 */
|
||||
|
||||
{ NB_CFG, AMD_FAM15_ALL, AMD_PTYPE_DC | AMD_PTYPE_MC,
|
||||
1 << 23, 0x00000000,
|
||||
1 << 23, 0x00000000 }, /* Erratum 663: [bit 23]=1 */
|
||||
|
||||
{ BU_CFG2, AMD_DR_Bx, AMD_PTYPE_ALL,
|
||||
1 << 29, 0x00000000,
|
||||
1 << 29, 0x00000000 }, /* For Bx Smash1GPages=1 */
|
||||
@@ -68,6 +93,14 @@ static const struct {
|
||||
0 << 1, 0x00000000,
|
||||
1 << 1, 0x00000000 }, /* IDX_MATCH_ALL=0 */
|
||||
|
||||
{ IC_CFG, AMD_OR_C0, AMD_PTYPE_ALL,
|
||||
0x00000000, 1 << (39-32),
|
||||
0x00000000, 1 << (39-32)}, /* C0 or above [DisLoopPredictor]=1 */
|
||||
|
||||
{ IC_CFG, AMD_OR_C0, AMD_PTYPE_ALL,
|
||||
0xf << 1, 0x00000000,
|
||||
0xf << 1, 0x00000000}, /* C0 or above [DisIcWayFilter]=0xf */
|
||||
|
||||
{ BU_CFG, AMD_DR_LT_B3, AMD_PTYPE_ALL,
|
||||
1 << 21, 0x00000000,
|
||||
1 << 21, 0x00000000 }, /* Erratum #254 DR B1 BU_CFG[21]=1 */
|
||||
@@ -76,19 +109,51 @@ static const struct {
|
||||
1 << 23, 0x00000000,
|
||||
1 << 23, 0x00000000 }, /* Erratum #309 BU_CFG[23]=1 */
|
||||
|
||||
{ BU_CFG, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0 << 10, 0x00000000,
|
||||
1 << 10, 0x00000000 }, /* [DcacheAgressivePriority]=0 */
|
||||
|
||||
/* CPUID_EXT_FEATURES */
|
||||
{ CPUIDFEATURES, AMD_FAM10_ALL, AMD_PTYPE_DC | AMD_PTYPE_MC,
|
||||
{ CPUIDFEATURES, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_DC | AMD_PTYPE_MC,
|
||||
1 << 28, 0x00000000,
|
||||
1 << 28, 0x00000000 }, /* [HyperThreadFeatEn]=1 */
|
||||
|
||||
{ CPUIDFEATURES, AMD_FAM10_ALL, AMD_PTYPE_DC,
|
||||
{ CPUIDFEATURES, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_DC,
|
||||
0x00000000, 1 << (33-32),
|
||||
0x00000000, 1 << (33-32) }, /* [ExtendedFeatEn]=1 */
|
||||
|
||||
{ DE_CFG, AMD_OR_B2, AMD_PTYPE_ALL,
|
||||
1 << 10, 0x00000000,
|
||||
1 << 10, 0x00000000 }, /* Bx [ResyncPredSingleDispDis]=1 */
|
||||
|
||||
{ BU_CFG2, AMD_DRBH_Cx, AMD_PTYPE_ALL,
|
||||
0x00000000, 1 << (35-32),
|
||||
0x00000000, 1 << (35-32) }, /* Erratum 343 (set to 0 after CAR, in post_cache_as_ram()/model_10xxx_init() ) */
|
||||
|
||||
{ BU_CFG3, AMD_OR_B2, AMD_PTYPE_ALL,
|
||||
0x00000000, 1 << (42-32),
|
||||
0x00000000, 1 << (42-32)}, /* Bx [PwcDisableWalkerSharing]=1 */
|
||||
|
||||
{ BU_CFG3, AMD_OR_C0, AMD_PTYPE_ALL,
|
||||
1 << 22, 0x00000000,
|
||||
1 << 22, 0x00000000}, /* C0 or above [PfcDoubleStride]=1 */
|
||||
|
||||
{ EX_CFG, AMD_OR_C0, AMD_PTYPE_ALL,
|
||||
0x00000000, 1 << (54-32),
|
||||
0x00000000, 1 << (54-32)}, /* C0 or above [LateSbzResync]=1 */
|
||||
|
||||
{ LS_CFG2, AMD_OR_C0, AMD_PTYPE_ALL,
|
||||
1 << 23, 0x00000000,
|
||||
1 << 23, 0x00000000}, /* C0 or above [DisScbThreshold]=1 */
|
||||
|
||||
{ LS_CFG2, AMD_OR_C0, AMD_PTYPE_ALL,
|
||||
1 << 14, 0x00000000,
|
||||
1 << 14, 0x00000000}, /* C0 or above [ForceSmcCheckFlowStDis]=1 */
|
||||
|
||||
{ LS_CFG2, AMD_OR_C0, AMD_PTYPE_ALL,
|
||||
1 << 12, 0x00000000,
|
||||
1 << 12, 0x00000000}, /* C0 or above [ForceBusLockDis]=1 */
|
||||
|
||||
{ OSVW_ID_Length, AMD_DR_Bx | AMD_DR_Cx | AMD_DR_Dx, AMD_PTYPE_ALL,
|
||||
0x00000004, 0x00000000,
|
||||
0x00000004, 0x00000000}, /* B0 or Above, OSVW_ID_Length is 0004h */
|
||||
@@ -101,9 +166,45 @@ static const struct {
|
||||
0x00000000, 1 << (50-32),
|
||||
0x00000000, 1 << (50-32)}, /* D0 or Above, RdMmExtCfgQwEn*/
|
||||
|
||||
{ BU_CFG2, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x00000000, 0x0 << (36-32),
|
||||
0x00000000, 0x3 << (36-32)}, /* [ThrottleNbInterface]=0 */
|
||||
|
||||
{ BU_CFG2, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
1 << 10, 0x00000000,
|
||||
1 << 10, 0x00000000}, /* [VicResyncChkEn]=1 */
|
||||
|
||||
{ BU_CFG2, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
1 << 11, 0x00000000,
|
||||
1 << 11, 0x00000000}, /* Erratum 503: [bit 11]=1 */
|
||||
|
||||
{ CPU_ID_EXT_FEATURES_MSR, AMD_DR_Dx, AMD_PTYPE_ALL,
|
||||
0x00000000, 1 << (51 - 32),
|
||||
0x00000000, 1 << (51 - 32)}, /* G34_PKG | C32_PKG | S1G4_PKG | ASB2_PKG */
|
||||
|
||||
{ CPU_ID_EXT_FEATURES_MSR, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x00000000, 1 << (56 - 32),
|
||||
0x00000000, 1 << (56 - 32)}, /* [PerfCtrExtNB]=1 */
|
||||
|
||||
{ CPU_ID_EXT_FEATURES_MSR, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x00000000, 1 << (55 - 32),
|
||||
0x00000000, 1 << (55 - 32)}, /* [PerfCtrExtCore]=1 */
|
||||
|
||||
{ IBS_OP_DATA3, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0 << 16, 0x00000000,
|
||||
1 << 16, 0x00000000}, /* [IbsDcMabHit]=0 */
|
||||
|
||||
{ MC4_MISC0, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x00000000, 0x1 << (52-32),
|
||||
0x00000000, 0xf << (52-32)}, /* [LvtOffset]=1 */
|
||||
|
||||
{ MC4_MISC1, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x00000000, 0x1 << (52-32),
|
||||
0x00000000, 0xf << (52-32)}, /* [LvtOffset]=1 */
|
||||
|
||||
{ MC4_MISC2, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x00000000, 0x1 << (52-32),
|
||||
0x00000000, 0xf << (52-32)}, /* [LvtOffset]=1 */
|
||||
};
|
||||
|
||||
|
||||
@@ -113,37 +214,46 @@ static const struct {
|
||||
static const struct {
|
||||
u8 function;
|
||||
u16 offset;
|
||||
u32 revision;
|
||||
uint64_t revision;
|
||||
u32 platform;
|
||||
u32 data;
|
||||
u32 mask;
|
||||
} fam10_pci_default[] = {
|
||||
|
||||
/* Function 0 - HT Config */
|
||||
{ 0, 0x68, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
0x000e0000, 0x000e0000 }, /* [19:17] for 8bit APIC config */
|
||||
|
||||
{ 0, 0x68, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
0x004E4800, 0x006E6800 }, /* [19:17] for 8bit APIC config,
|
||||
[14:13] BufPriRel = 2h [11] RspPassPW set,
|
||||
[22:21] DsNpReqLmt = 10b */
|
||||
{ 0, 0x68, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
0x00400000, 0x00600000 }, /* [22:21] DsNpReqLmt = 10b */
|
||||
|
||||
{ 0, 0x68, AMD_FAM10_LT_D, AMD_PTYPE_ALL,
|
||||
0x00004000, 0x00006000 }, /* [14:13] BufRelPri = 2h */
|
||||
|
||||
{ 0, 0x68, (AMD_FAM10_REV_D | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
0x00002000, 0x00006000 }, /* [14:13] BufRelPri = 1h */
|
||||
|
||||
{ 0, 0x68, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
0x00000800, 0x00000800 }, /* [11] RspPassPW = 1 */
|
||||
|
||||
/* Errata 281 Workaround */
|
||||
{ 0, 0x68, (AMD_DR_B0 | AMD_DR_B1),
|
||||
AMD_PTYPE_SVR, 0x00200000, 0x00600000 }, /* [22:21] DsNpReqLmt0 = 01b */
|
||||
|
||||
{ 0, 0x84, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
{ 0, 0x84, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
0x00002000, 0x00002000 }, /* [13] LdtStopTriEn = 1 */
|
||||
|
||||
{ 0, 0xA4, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
{ 0, 0xA4, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
0x00002000, 0x00002000 }, /* [13] LdtStopTriEn = 1 */
|
||||
|
||||
{ 0, 0xC4, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
{ 0, 0xC4, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
0x00002000, 0x00002000 }, /* [13] LdtStopTriEn = 1 */
|
||||
|
||||
{ 0, 0xE4, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
{ 0, 0xE4, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
0x00002000, 0x00002000 }, /* [13] LdtStopTriEn = 1 */
|
||||
|
||||
/* Link Global Retry Control Register */
|
||||
{ 0, 0x150, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
{ 0, 0x150, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
0x00073900, 0x00073F00 },
|
||||
|
||||
/* Errata 351
|
||||
@@ -168,13 +278,39 @@ static const struct {
|
||||
0x00000000, 0x00000100 },
|
||||
{ 0, 0x18C, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
0x00000000, 0x00000100 },
|
||||
{ 0, 0x170, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
0x00000000, 0x00000100 },
|
||||
|
||||
/* Link Global Extended Control Register */
|
||||
{ 0, 0x16C, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
0x00000014, 0x0000003F }, /* [15:13] ForceFullT0 = 0b,
|
||||
* Set T0Time 14h per BKDG */
|
||||
* Set T0Time 14h per BKDG */
|
||||
|
||||
{ 0, 0x170, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x00000100, 0x00000100 },
|
||||
{ 0, 0x174, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x00000100, 0x00000100 },
|
||||
{ 0, 0x178, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x00000100, 0x00000100 },
|
||||
{ 0, 0x17C, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x00000100, 0x00000100 },
|
||||
{ 0, 0x180, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x00000100, 0x00000100 },
|
||||
{ 0, 0x184, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x00000100, 0x00000100 },
|
||||
{ 0, 0x188, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x00000100, 0x00000100 },
|
||||
{ 0, 0x18C, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x00000100, 0x00000100 },
|
||||
|
||||
/* Link Global Extended Control Register */
|
||||
{ 0, 0x16C, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x00000014, 0x0000003F }, /* [15:13] ForceFullT0 = 111b,
|
||||
* Set T0Time 26h per BKDG */
|
||||
|
||||
{ 0, 0x16C, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x7 << 13, 0x7 << 13 }, /* [15:13] ForceFullT0 = 7h */
|
||||
|
||||
{ 0, 0x16C, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x26, 0x3f }, /* [5:0] T0Time = 26h */
|
||||
|
||||
|
||||
/* Function 1 - Map Init */
|
||||
@@ -201,10 +337,10 @@ static const struct {
|
||||
/* Function 2 - DRAM Controller */
|
||||
|
||||
/* Function 3 - Misc. Control */
|
||||
{ 3, 0x40, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
{ 3, 0x40, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
0x00000100, 0x00000100 }, /* [8] MstrAbrtEn */
|
||||
|
||||
{ 3, 0x44, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
{ 3, 0x44, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
0x4A30005C, 0x4A30005C }, /* [30] SyncOnDramAdrParErrEn = 1,
|
||||
[27] NbMcaToMstCpuEn = 1,
|
||||
[25] DisPciCfgCpuErrRsp = 1,
|
||||
@@ -216,8 +352,12 @@ static const struct {
|
||||
[2] SyncOnUcEccEn = 1 */
|
||||
|
||||
/* XBAR buffer settings */
|
||||
{ 3, 0x6C, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
0x00018052, 0x700780F7 },
|
||||
{ 3, 0x6c, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
0x00018052, 0x700780f7 },
|
||||
|
||||
/* XBAR buffer settings */
|
||||
{ 3, 0x6c, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x10010052, 0x700700f7 },
|
||||
|
||||
/* Errata 281 Workaround */
|
||||
{ 3, 0x6C, ( AMD_DR_B0 | AMD_DR_B1),
|
||||
@@ -229,12 +369,18 @@ static const struct {
|
||||
{ 3, 0x70, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
0x00041153, 0x777777F7 },
|
||||
|
||||
{ 3, 0x70, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x10171155, 0x777777f7 },
|
||||
|
||||
{ 3, 0x70, AMD_FAM10_ALL, AMD_PTYPE_UMA,
|
||||
0x61221151, 0x777777F7 },
|
||||
|
||||
{ 3, 0x74, AMD_FAM10_ALL, AMD_PTYPE_UMA,
|
||||
0x00080101, 0x000F7777 },
|
||||
|
||||
{ 3, 0x74, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x00172111, 0x77ff7777 },
|
||||
|
||||
{ 3, 0x7C, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
0x00090914, 0x707FFF1F },
|
||||
|
||||
@@ -242,12 +388,18 @@ static const struct {
|
||||
{ 3, 0x7C, ( AMD_DR_B0 | AMD_DR_B1),
|
||||
AMD_PTYPE_SVR, 0x00144514, 0x707FFF1F },
|
||||
|
||||
{ 3, 0x7C, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x040d0f16, 0x07ffff1f },
|
||||
|
||||
{ 3, 0x7C, AMD_FAM10_ALL, AMD_PTYPE_UMA,
|
||||
0x00070814, 0x007FFF1F },
|
||||
|
||||
{ 3, 0x140, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
0x00800756, 0x00F3FFFF },
|
||||
|
||||
{ 3, 0x140, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x00a11755, 0x00f3ffff },
|
||||
|
||||
{ 3, 0x140, AMD_FAM10_ALL, AMD_PTYPE_UMA,
|
||||
0x00C37756, 0x00F3FFFF },
|
||||
|
||||
@@ -259,6 +411,9 @@ static const struct {
|
||||
AMD_PTYPE_SVR, 0x00000001, 0x0000000F },
|
||||
/* [3:0] RspTok = 0001b */
|
||||
|
||||
{ 3, 0x144, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x00000028, 0x000000ff },
|
||||
|
||||
{ 3, 0x148, AMD_FAM10_ALL, AMD_PTYPE_UMA,
|
||||
0x8000052A, 0xD5FFFFFF },
|
||||
|
||||
@@ -266,41 +421,53 @@ static const struct {
|
||||
{ 3, 0x80, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
0xE6002200, 0xFFFFFFFF },
|
||||
|
||||
/* ACPI Power State Control Reg1 */
|
||||
{ 3, 0x80, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0xe20be200, 0xefefef00 },
|
||||
|
||||
/* ACPI Power State Control Reg2 */
|
||||
{ 3, 0x84, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
0xA0E641E6, 0xFFFFFFFF },
|
||||
|
||||
/* ACPI Power State Control Reg2 */
|
||||
{ 3, 0x84, AMD_FAM15_ALL, AMD_PTYPE_ALL,
|
||||
0x01e200e2, 0xefef00ef },
|
||||
|
||||
{ 3, 0xA0, AMD_FAM10_ALL, AMD_PTYPE_MOB | AMD_PTYPE_DSK,
|
||||
0x00000080, 0x00000080 }, /* [7] PSIVidEnable */
|
||||
|
||||
{ 3, 0xA0, AMD_DR_Bx, AMD_PTYPE_ALL,
|
||||
0x00002800, 0x000003800 }, /* [13:11] PllLockTime = 5 */
|
||||
|
||||
{ 3, 0xA0, (AMD_FAM10_ALL & ~(AMD_DR_Bx)), AMD_PTYPE_ALL,
|
||||
{ 3, 0xA0, ((AMD_FAM10_ALL | AMD_FAM15_ALL) & ~(AMD_DR_Bx)), AMD_PTYPE_ALL,
|
||||
0x00000800, 0x000003800 }, /* [13:11] PllLockTime = 1 */
|
||||
|
||||
/* Reported Temp Control Register */
|
||||
{ 3, 0xA4, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
{ 3, 0xA4, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
0x00000080, 0x00000080 }, /* [7] TempSlewDnEn = 1 */
|
||||
|
||||
/* Clock Power/Timing Control 0 Register */
|
||||
{ 3, 0xD4, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
{ 3, 0xD4, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
0xC0000F00, 0xF0000F00 }, /* [31] NbClkDivApplyAll = 1,
|
||||
[30:28] NbClkDiv = 100b,[11:8] ClkRampHystSel = 1111b */
|
||||
|
||||
/* Clock Power/Timing Control 1 Register */
|
||||
{ 3, 0xD8, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
0x03000010, 0x0F000070 }, /* [6:4] VSRampTime = 1,
|
||||
* [27:24] ReConDel = 3 */
|
||||
|
||||
/* Clock Power/Timing Control 1 Register */
|
||||
{ 3, 0xD8, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
0x03000016, 0x0F000077 }, /* [6:4] VSRampTime = 1,
|
||||
[2:0] VSSlamTime = 6, [27:24] ReConDel = 3 */
|
||||
0x00000006, 0x00000007 }, /* [2:0] VSSlamTime = 6 */
|
||||
|
||||
|
||||
/* Clock Power/Timing Control 2 Register */
|
||||
{ 3, 0xDC, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
{ 3, 0xDC, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
0x00005000, 0x00007000 }, /* [14:12] NbsynPtrAdj = 5 */
|
||||
|
||||
|
||||
/* Extended NB MCA Config Register */
|
||||
{ 3, 0x180, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
{ 3, 0x180, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
0x007003E2, 0x007003E2 }, /* [22:20] = SyncFloodOn_Err = 7,
|
||||
[9] SyncOnUncNbAryEn = 1 ,
|
||||
[8] SyncOnProtEn = 1,
|
||||
@@ -315,12 +482,17 @@ static const struct {
|
||||
0x00400000, 0x00400000 },
|
||||
|
||||
/* L3 Control Register */
|
||||
{ 3, 0x1B8, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
{ 3, 0x1b8, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
0x00001000, 0x00001000 }, /* [12] = L3PrivReplEn */
|
||||
|
||||
/* IBS Control Register */
|
||||
{ 3, 0x1CC, AMD_FAM10_ALL, AMD_PTYPE_ALL,
|
||||
{ 3, 0x1cc, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL,
|
||||
0x00000100, 0x00000100 }, /* [8] = LvtOffsetVal */
|
||||
|
||||
/* Erratum 619 - Family 15h Bx
|
||||
* System software should set F5x88[14] to 1b. */
|
||||
{ 5, 0x88, AMD_OR_B2, AMD_PTYPE_ALL,
|
||||
1 << 14, 1 << 14 },
|
||||
};
|
||||
|
||||
|
||||
@@ -329,7 +501,7 @@ static const struct {
|
||||
*/
|
||||
static const struct {
|
||||
u16 htreg; /* HT Phy Register index */
|
||||
u32 revision;
|
||||
uint64_t revision;
|
||||
u32 platform;
|
||||
u32 linktype;
|
||||
u32 data;
|
||||
@@ -438,38 +610,38 @@ static const struct {
|
||||
{ 0x530A, AMD_DR_ALL, AMD_PTYPE_ALL, HTPHY_LINKTYPE_ALL,
|
||||
0x00004400, 0x00006400 }, /* HT_PHY_DLL_REG */
|
||||
|
||||
{ 0xCF, AMD_FAM10_ALL, AMD_PTYPE_ALL, HTPHY_LINKTYPE_HT3,
|
||||
{ 0xCF, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL, HTPHY_LINKTYPE_HT3,
|
||||
0x00000000, 0x000000FF }, /* Provide clear setting for logical
|
||||
completeness */
|
||||
|
||||
{ 0xDF, AMD_FAM10_ALL, AMD_PTYPE_ALL, HTPHY_LINKTYPE_HT3,
|
||||
{ 0xDF, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL, HTPHY_LINKTYPE_HT3,
|
||||
0x00000000, 0x000000FF }, /* Provide clear setting for logical
|
||||
completeness */
|
||||
|
||||
{ 0xCF, AMD_FAM10_ALL, AMD_PTYPE_ALL, HTPHY_LINKTYPE_HT1,
|
||||
{ 0xCF, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL, HTPHY_LINKTYPE_HT1,
|
||||
0x0000006D, 0x000000FF }, /* HT_PHY_HT1_FIFO_PTR_OPT_VALUE */
|
||||
|
||||
{ 0xDF, AMD_FAM10_ALL, AMD_PTYPE_ALL, HTPHY_LINKTYPE_HT1,
|
||||
{ 0xDF, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL, HTPHY_LINKTYPE_HT1,
|
||||
0x0000006D, 0x000000FF }, /* HT_PHY_HT1_FIFO_PTR_OPT_VALUE */
|
||||
|
||||
/* Link Phy Receiver Loop Filter Registers */
|
||||
{ 0xD1, AMD_FAM10_ALL, AMD_PTYPE_ALL, HTPHY_LINKTYPE_HT3,
|
||||
{ 0xD1, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL, HTPHY_LINKTYPE_HT3,
|
||||
0x08040000, 0x3FFFC000 }, /* [29:22] LfcMax = 20h,
|
||||
[21:14] LfcMin = 10h */
|
||||
|
||||
{ 0xC1, AMD_FAM10_ALL, AMD_PTYPE_ALL, HTPHY_LINKTYPE_HT3,
|
||||
{ 0xC1, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL, HTPHY_LINKTYPE_HT3,
|
||||
0x08040000, 0x3FFFC000 }, /* [29:22] LfcMax = 20h,
|
||||
[21:14] LfcMin = 10h */
|
||||
|
||||
{ 0xD1, AMD_FAM10_ALL, AMD_PTYPE_ALL, HTPHY_LINKTYPE_HT1,
|
||||
{ 0xD1, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL, HTPHY_LINKTYPE_HT1,
|
||||
0x04020000, 0x3FFFC000 }, /* [29:22] LfcMax = 10h,
|
||||
[21:14] LfcMin = 08h */
|
||||
|
||||
{ 0xC1, AMD_FAM10_ALL, AMD_PTYPE_ALL, HTPHY_LINKTYPE_HT1,
|
||||
{ 0xC1, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL, HTPHY_LINKTYPE_HT1,
|
||||
0x04020000, 0x3FFFC000 }, /* [29:22] LfcMax = 10h,
|
||||
[21:14] LfcMin = 08h */
|
||||
|
||||
{ 0xC0, AMD_FAM10_ALL, AMD_PTYPE_ALL, HTPHY_LINKTYPE_ALL,
|
||||
{ 0xC0, (AMD_FAM10_ALL | AMD_FAM15_ALL), AMD_PTYPE_ALL, HTPHY_LINKTYPE_ALL,
|
||||
0x40040000, 0xe01F0000 }, /* [31:29] RttCtl = 02h,
|
||||
[20:16] RttIndex = 04h */
|
||||
};
|
||||
|
@@ -2,6 +2,7 @@
|
||||
* 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
|
||||
@@ -39,7 +40,7 @@ Fam10 Bios and Kernel Development Guide #31116, rev 3.48, April 22, 2010
|
||||
|
||||
3.- 2.4.2.7 dualPlaneOnly(dev)
|
||||
|
||||
4.- 2.4.2.8 applyBoostFIDOffset(dev)
|
||||
4.- 2.4.2.8 applyBoostFIDOffset(dev, nodeid)
|
||||
|
||||
5.- enableNbPState1(dev)
|
||||
|
||||
@@ -138,25 +139,33 @@ static void enable_fid_change(u8 fid)
|
||||
}
|
||||
}
|
||||
|
||||
static void applyBoostFIDOffset( device_t dev ) {
|
||||
// BKDG 2.4.2.8
|
||||
// revision E only, but E is apparently not supported yet, therefore untested
|
||||
if ((cpuid_edx(0x80000007) & CPB_MASK)
|
||||
&& ((cpuid_ecx(0x80000008) & NC_MASK) ==5) ) {
|
||||
u32 core = get_node_core_id_x().coreid;
|
||||
u32 asymetricBoostThisCore = ((pci_read_config32(dev, 0x10C) >> (core*2))) & 3;
|
||||
msr_t msr = rdmsr(PS_REG_BASE);
|
||||
u32 cpuFid = msr.lo & PS_CPU_FID_MASK;
|
||||
cpuFid = cpuFid + asymetricBoostThisCore;
|
||||
msr.lo &= ~PS_CPU_FID_MASK;
|
||||
msr.lo |= cpuFid ;
|
||||
wrmsr(PS_REG_BASE , msr);
|
||||
|
||||
}
|
||||
static void applyBoostFIDOffset(device_t dev, uint32_t nodeid) {
|
||||
// BKDG 2.4.2.8
|
||||
// Fam10h revision E only, but E is apparently not supported yet, therefore untested
|
||||
if ((cpuid_edx(0x80000007) & CPB_MASK)
|
||||
&& ((cpuid_ecx(0x80000008) & NC_MASK) == 5) ) {
|
||||
u32 core = get_node_core_id_x().coreid;
|
||||
u32 asymetricBoostThisCore = ((pci_read_config32(dev, 0x10C) >> (core*2))) & 3;
|
||||
msr_t msr = rdmsr(PS_REG_BASE);
|
||||
u32 cpuFid = msr.lo & PS_CPU_FID_MASK;
|
||||
cpuFid = cpuFid + asymetricBoostThisCore;
|
||||
msr.lo &= ~PS_CPU_FID_MASK;
|
||||
msr.lo |= cpuFid ;
|
||||
wrmsr(PS_REG_BASE , msr);
|
||||
} else if (is_fam15h()) {
|
||||
uint32_t dword = pci_read_config32(NODE_PCI(nodeid, 4), 0x15c);
|
||||
uint8_t boost_count = (dword >> 2) & 0x7;
|
||||
if (boost_count > 0) {
|
||||
/* Enable boost */
|
||||
dword &= ~0x3;
|
||||
dword |= 0x1;
|
||||
pci_write_config32(NODE_PCI(nodeid, 4), 0x15c, dword);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void enableNbPState1( device_t dev ) {
|
||||
u32 cpuRev = mctGetLogicalCPUID(0xFF);
|
||||
uint64_t cpuRev = mctGetLogicalCPUID(0xFF);
|
||||
if (cpuRev & AMD_FAM10_C3) {
|
||||
u32 nbPState = (pci_read_config32(dev, 0x1F0) & NB_PSTATE_MASK);
|
||||
if ( nbPState){
|
||||
@@ -198,7 +207,7 @@ static u8 setPStateMaxVal( device_t dev ) {
|
||||
static void dualPlaneOnly( device_t dev ) {
|
||||
// BKDG 2.4.2.7
|
||||
|
||||
u32 cpuRev = mctGetLogicalCPUID(0xFF);
|
||||
uint64_t cpuRev = mctGetLogicalCPUID(0xFF);
|
||||
if ((mctGetProcessorPackageType() == AMD_PKGTYPE_AM3_2r2)
|
||||
&& (cpuRev & AMD_DR_Cx)) { // should be rev C or rev E but there's no constant for E
|
||||
if ( (pci_read_config32(dev, 0x1FC) & DUAL_PLANE_ONLY_MASK)
|
||||
@@ -278,12 +287,16 @@ static void recalculateVsSlamTimeSettingOnCorePre(device_t dev)
|
||||
*/
|
||||
|
||||
/* Determine if this is a PVI or SVI system */
|
||||
dtemp = pci_read_config32(dev, 0xA0);
|
||||
|
||||
if (dtemp & PVI_MODE)
|
||||
pviModeFlag = 1;
|
||||
else
|
||||
if (is_fam15h()) {
|
||||
pviModeFlag = 0;
|
||||
} else {
|
||||
dtemp = pci_read_config32(dev, 0xa0);
|
||||
|
||||
if (dtemp & PVI_MODE)
|
||||
pviModeFlag = 1;
|
||||
else
|
||||
pviModeFlag = 0;
|
||||
}
|
||||
|
||||
/* Get P0's voltage */
|
||||
/* MSRC001_00[68:64] are not programmed yet when called from
|
||||
@@ -510,59 +523,67 @@ static void config_nb_syn_ptr_adj(device_t dev, u32 cpuRev) {
|
||||
}
|
||||
|
||||
static void config_acpi_pwr_state_ctrl_regs(device_t dev, u32 cpuRev, u8 procPkg) {
|
||||
/* step 1, chapter 2.4.2.6 of AMD Fam 10 BKDG #31116 Rev 3.48 22.4.2010 */
|
||||
u32 dword;
|
||||
u32 c1= 1;
|
||||
if (cpuRev & (AMD_DR_Bx)) {
|
||||
// will coreboot ever enable cache scrubbing ?
|
||||
// if it does, will it be enough to check the current state
|
||||
// or should we configure for what we'll set up later ?
|
||||
dword = pci_read_config32(dev, 0x58);
|
||||
u32 scrubbingCache = dword &
|
||||
( (0x1F << 16) // DCacheScrub
|
||||
| (0x1F << 8) ); // L2Scrub
|
||||
if (scrubbingCache) {
|
||||
c1 = 0x80;
|
||||
} else {
|
||||
c1 = 0xA0;
|
||||
}
|
||||
} else { // rev C or later
|
||||
// same doubt as cache scrubbing: ok to check current state ?
|
||||
dword = pci_read_config32(dev, 0xDC);
|
||||
u32 cacheFlushOnHalt = dword & (7 << 16);
|
||||
if (!cacheFlushOnHalt) {
|
||||
c1 = 0x80;
|
||||
}
|
||||
}
|
||||
dword = (c1 << 24) | (0xE641E6);
|
||||
pci_write_config32(dev, 0x84, dword);
|
||||
if (is_fam15h()) {
|
||||
/* Family 15h BKDG Rev. 3.14 D18F3x80 recommended settings */
|
||||
pci_write_config32(dev, 0x80, 0xe20be281);
|
||||
|
||||
/* Family 15h BKDG Rev. 3.14 D18F3x84 recommended settings */
|
||||
pci_write_config32(dev, 0x84, 0x01e200e2);
|
||||
} else {
|
||||
/* step 1, chapter 2.4.2.6 of AMD Fam 10 BKDG #31116 Rev 3.48 22.4.2010 */
|
||||
u32 dword;
|
||||
u32 c1= 1;
|
||||
if (cpuRev & (AMD_DR_Bx)) {
|
||||
// will coreboot ever enable cache scrubbing ?
|
||||
// if it does, will it be enough to check the current state
|
||||
// or should we configure for what we'll set up later ?
|
||||
dword = pci_read_config32(dev, 0x58);
|
||||
u32 scrubbingCache = dword &
|
||||
( (0x1F << 16) // DCacheScrub
|
||||
| (0x1F << 8) ); // L2Scrub
|
||||
if (scrubbingCache) {
|
||||
c1 = 0x80;
|
||||
} else {
|
||||
c1 = 0xA0;
|
||||
}
|
||||
} else { // rev C or later
|
||||
// same doubt as cache scrubbing: ok to check current state ?
|
||||
dword = pci_read_config32(dev, 0xDC);
|
||||
u32 cacheFlushOnHalt = dword & (7 << 16);
|
||||
if (!cacheFlushOnHalt) {
|
||||
c1 = 0x80;
|
||||
}
|
||||
}
|
||||
dword = (c1 << 24) | (0xE641E6);
|
||||
pci_write_config32(dev, 0x84, dword);
|
||||
|
||||
/* FIXME: BKDG Table 100 says if the link is at a Gen1
|
||||
frequency and the chipset does not support a 10us minimum LDTSTOP
|
||||
assertion time, then { If ASB2 && SVI then smaf001 = F6h else
|
||||
smaf001=87h. } else ... I hardly know what it means or how to check
|
||||
it from here, so I bluntly assume it is false and code here the else,
|
||||
which is easier */
|
||||
/* FIXME: BKDG Table 100 says if the link is at a Gen1
|
||||
* frequency and the chipset does not support a 10us minimum LDTSTOP
|
||||
* assertion time, then { If ASB2 && SVI then smaf001 = F6h else
|
||||
* smaf001=87h. } else ... I hardly know what it means or how to check
|
||||
* it from here, so I bluntly assume it is false and code here the else,
|
||||
* which is easier
|
||||
*/
|
||||
|
||||
u32 smaf001 = 0xE6;
|
||||
if (cpuRev & AMD_DR_Bx ) {
|
||||
smaf001 = 0xA6;
|
||||
} else {
|
||||
#if CONFIG_SVI_HIGH_FREQ
|
||||
if (cpuRev & (AMD_RB_C3 | AMD_DA_C3)) {
|
||||
smaf001 = 0xF6;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
u32 fidvidChange = 0;
|
||||
if (((cpuRev & AMD_DA_Cx) && (procPkg & AMD_PKGTYPE_S1gX))
|
||||
|| (cpuRev & AMD_RB_C3) ) {
|
||||
fidvidChange=0x0B;
|
||||
}
|
||||
dword = (0xE6 << 24) | (fidvidChange << 16)
|
||||
| (smaf001 << 8) | 0x81;
|
||||
pci_write_config32(dev, 0x80, dword);
|
||||
u32 smaf001 = 0xE6;
|
||||
if (cpuRev & AMD_DR_Bx ) {
|
||||
smaf001 = 0xA6;
|
||||
} else {
|
||||
#if CONFIG_SVI_HIGH_FREQ
|
||||
if (cpuRev & (AMD_RB_C3 | AMD_DA_C3)) {
|
||||
smaf001 = 0xF6;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
u32 fidvidChange = 0;
|
||||
if (((cpuRev & AMD_DA_Cx) && (procPkg & AMD_PKGTYPE_S1gX))
|
||||
|| (cpuRev & AMD_RB_C3) ) {
|
||||
fidvidChange=0x0B;
|
||||
}
|
||||
dword = (0xE6 << 24) | (fidvidChange << 16)
|
||||
| (smaf001 << 8) | 0x81;
|
||||
pci_write_config32(dev, 0x80, dword);
|
||||
}
|
||||
}
|
||||
|
||||
static void prep_fid_change(void)
|
||||
@@ -579,7 +600,7 @@ static void prep_fid_change(void)
|
||||
for (i = 0; i < nodes; i++) {
|
||||
printk(BIOS_DEBUG, "Prep FID/VID Node:%02x\n", i);
|
||||
dev = NODE_PCI(i, 3);
|
||||
u32 cpuRev = mctGetLogicalCPUID(0xFF) ;
|
||||
uint64_t cpuRev = mctGetLogicalCPUID(0xFF) ;
|
||||
u8 procPkg = mctGetProcessorPackageType();
|
||||
|
||||
setVSRamp(dev);
|
||||
@@ -607,7 +628,7 @@ static void prep_fid_change(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void waitCurrentPstate(u32 target_pstate){
|
||||
static void waitCurrentPstate(u32 target_pstate) {
|
||||
msr_t initial_msr = rdmsr(TSC_MSR);
|
||||
msr_t pstate_msr = rdmsr(CUR_PSTATE_MSR);
|
||||
msr_t tsc_msr;
|
||||
@@ -640,7 +661,7 @@ static void waitCurrentPstate(u32 target_pstate){
|
||||
|
||||
if (pstate_msr.lo != target_pstate) {
|
||||
msr_t limit_msr = rdmsr(0xc0010061);
|
||||
printk(BIOS_ERR, "*** Time out waiting for P-state %01x. Current P-state %01x P-state current limit MSRC001_0061=%02x\n", target_pstate, pstate_msr.lo, limit_msr.lo);
|
||||
printk(BIOS_ERR, "*** Time out waiting for P-state %01x. Current P-state %01x P-state current limit MSRC001_0061=%08x %08x\n", target_pstate, pstate_msr.lo, limit_msr.hi, limit_msr.lo);
|
||||
|
||||
do { // should we just go on instead ?
|
||||
pstate_msr = rdmsr(CUR_PSTATE_MSR);
|
||||
@@ -650,6 +671,7 @@ static void waitCurrentPstate(u32 target_pstate){
|
||||
|
||||
static void set_pstate(u32 nonBoostedPState) {
|
||||
msr_t msr;
|
||||
uint8_t skip_wait;
|
||||
|
||||
// Transition P0 for calling core.
|
||||
msr = rdmsr(0xC0010062);
|
||||
@@ -657,13 +679,22 @@ static void set_pstate(u32 nonBoostedPState) {
|
||||
msr.lo = nonBoostedPState;
|
||||
wrmsr(0xC0010062, msr);
|
||||
|
||||
/* Wait for P0 to set. */
|
||||
waitCurrentPstate(nonBoostedPState);
|
||||
if (is_fam15h()) {
|
||||
/* Do not wait for the first (even) set of cores to transition on Family 15h systems */
|
||||
if ((cpuid_ebx(0x00000001) & 0x01000000))
|
||||
skip_wait = 0;
|
||||
else
|
||||
skip_wait = 1;
|
||||
} else {
|
||||
skip_wait = 0;
|
||||
}
|
||||
|
||||
if (!skip_wait) {
|
||||
/* Wait for core to transition to P0 */
|
||||
waitCurrentPstate(nonBoostedPState);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void UpdateSinglePlaneNbVid(void)
|
||||
{
|
||||
u32 nbVid, cpuVid;
|
||||
@@ -752,11 +783,14 @@ static u32 needs_NB_COF_VID_update(void)
|
||||
u8 nodes;
|
||||
u8 i;
|
||||
|
||||
if (is_fam15h())
|
||||
return 0;
|
||||
|
||||
/* If any node has nb_cof_vid_update set all nodes need an update. */
|
||||
nodes = get_nodes();
|
||||
nb_cof_vid_update = 0;
|
||||
for (i = 0; i < nodes; i++) {
|
||||
u32 cpuRev = mctGetLogicalCPUID(i) ;
|
||||
uint64_t cpuRev = mctGetLogicalCPUID(i);
|
||||
u32 nbCofVidUpdateDefined = (cpuRev & (AMD_FAM10_LT_D));
|
||||
if (nbCofVidUpdateDefined
|
||||
&& (pci_read_config32(NODE_PCI(i, 3), 0x1FC)
|
||||
@@ -780,9 +814,11 @@ static u32 init_fidvid_core(u32 nodeid, u32 coreid)
|
||||
/* Steps 1-6 of BIOS NB COF and VID Configuration
|
||||
* for SVI and Single-Plane PVI Systems. BKDG 2.4.2.9 #31116 rev 3.48
|
||||
*/
|
||||
|
||||
dev = NODE_PCI(nodeid, 3);
|
||||
pvimode = pci_read_config32(dev, PW_CTL_MISC) & PVI_MODE;
|
||||
if (is_fam15h())
|
||||
pvimode = 0;
|
||||
else
|
||||
pvimode = pci_read_config32(dev, PW_CTL_MISC) & PVI_MODE;
|
||||
reg1fc = pci_read_config32(dev, 0x1FC);
|
||||
|
||||
if (nb_cof_vid_update) {
|
||||
@@ -794,7 +830,7 @@ static u32 init_fidvid_core(u32 nodeid, u32 coreid)
|
||||
fid_max = fid_max + ((reg1fc & DUAL_PLANE_NB_FID_OFF_MASK ) >> DUAL_PLANE_NB_FID_SHIFT );
|
||||
}
|
||||
/* write newNbVid to P-state Reg's NbVid always if NbVidUpdatedAll=1 */
|
||||
fixPsNbVidBeforeWR(vid_max, coreid,dev,pvimode);
|
||||
fixPsNbVidBeforeWR(vid_max, coreid, dev, pvimode);
|
||||
|
||||
/* fid setup is handled by the BSP at the end. */
|
||||
|
||||
@@ -814,7 +850,7 @@ static void init_fidvid_ap(u32 apicid, u32 nodeid, u32 coreid)
|
||||
|
||||
printk(BIOS_DEBUG, "FIDVID on AP: %02x\n", apicid);
|
||||
|
||||
send = init_fidvid_core(nodeid,coreid);
|
||||
send = init_fidvid_core(nodeid, coreid);
|
||||
send |= (apicid << 24); // ap apicid
|
||||
|
||||
// Send signal to BSP about this AP max fid
|
||||
@@ -856,7 +892,8 @@ static void init_fidvid_bsp_stage1(u32 ap_apicid, void *gp)
|
||||
while (--loop > 0) {
|
||||
if (lapic_remote_read(ap_apicid, LAPIC_MSG_REG, &readback) != 0)
|
||||
continue;
|
||||
if ((readback & 0x3f) == F10_APSTATE_RESET) {
|
||||
if (((readback & 0x3f) == F10_APSTATE_RESET)
|
||||
|| (is_fam15h() && ((readback & 0x3f) == F10_APSTATE_ASLEEP))) {
|
||||
timeout = 0;
|
||||
break; /* target ap is in stage 1 */
|
||||
}
|
||||
@@ -944,7 +981,10 @@ static void init_fidvid_stage2(u32 apicid, u32 nodeid)
|
||||
/* If any node has nb_cof_vid_update set all nodes need an update. */
|
||||
|
||||
dev = NODE_PCI(nodeid, 3);
|
||||
pvimode = (pci_read_config32(dev, 0xA0) >> 8) & 1;
|
||||
if (is_fam15h())
|
||||
pvimode = 0;
|
||||
else
|
||||
pvimode = (pci_read_config32(dev, 0xA0) >> 8) & 1;
|
||||
reg1fc = pci_read_config32(dev, 0x1FC);
|
||||
nbvid = (reg1fc >> 7) & 0x7F;
|
||||
NbVidUpdateAll = (reg1fc >> 1) & 1;
|
||||
@@ -965,15 +1005,17 @@ static void init_fidvid_stage2(u32 apicid, u32 nodeid)
|
||||
pci_write_config32(dev, 0xA0, dtemp);
|
||||
|
||||
dualPlaneOnly(dev);
|
||||
applyBoostFIDOffset(dev);
|
||||
applyBoostFIDOffset(dev, nodeid);
|
||||
enableNbPState1(dev);
|
||||
|
||||
finalPstateChange();
|
||||
|
||||
/* Set TSC to tick at the P0 ndfid rate */
|
||||
msr = rdmsr(HWCR);
|
||||
msr.lo |= 1 << 24;
|
||||
wrmsr(HWCR, msr);
|
||||
if (!is_fam15h()) {
|
||||
/* Set TSC to tick at the P0 ndfid rate */
|
||||
msr = rdmsr(HWCR);
|
||||
msr.lo |= 1 << 24;
|
||||
wrmsr(HWCR, msr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1007,8 +1049,7 @@ static int init_fidvid_bsp(u32 bsp_apicid, u32 nodes)
|
||||
/* Steps 1-6 of BIOS NB COF and VID Configuration
|
||||
* for SVI and Single-Plane PVI Systems.
|
||||
*/
|
||||
|
||||
fv.common_fid = init_fidvid_core(0,0);
|
||||
fv.common_fid = init_fidvid_core(0, 0);
|
||||
|
||||
print_debug_fv("BSP fid = ", fv.common_fid);
|
||||
|
||||
|
@@ -26,9 +26,12 @@
|
||||
#include <northbridge/amd/amdfam10/raminit_amdmct.c>
|
||||
#include <reset.h>
|
||||
|
||||
#if IS_ENABLED(CONFIG_SET_FIDVID)
|
||||
static void prep_fid_change(void);
|
||||
static void init_fidvid_stage2(u32 apicid, u32 nodeid);
|
||||
void cpuSetAMDMSR(void);
|
||||
#endif
|
||||
|
||||
void cpuSetAMDMSR(uint8_t node_id);
|
||||
|
||||
#if CONFIG_PCI_IO_CFG_EXT
|
||||
static void set_EnableCf8ExtCfg(void)
|
||||
@@ -47,43 +50,38 @@ static void set_EnableCf8ExtCfg(void) { }
|
||||
|
||||
typedef void (*process_ap_t) (u32 apicid, void *gp);
|
||||
|
||||
//core_range = 0 : all cores
|
||||
//core range = 1 : core 0 only
|
||||
//core range = 2 : cores other than core0
|
||||
uint32_t get_boot_apic_id(uint8_t node, uint32_t core) {
|
||||
uint32_t ap_apicid;
|
||||
|
||||
static void for_each_ap(u32 bsp_apicid, u32 core_range, process_ap_t process_ap,
|
||||
void *gp)
|
||||
{
|
||||
// here assume the OS don't change our apicid
|
||||
u32 ap_apicid;
|
||||
uint32_t nb_cfg_54;
|
||||
uint32_t siblings;
|
||||
uint32_t cores_found;
|
||||
|
||||
u32 nodes;
|
||||
u32 siblings;
|
||||
u32 disable_siblings;
|
||||
u32 cores_found;
|
||||
u32 nb_cfg_54;
|
||||
int i, j;
|
||||
u32 ApicIdCoreIdSize;
|
||||
uint8_t fam15h = 0;
|
||||
uint8_t rev_gte_d = 0;
|
||||
uint8_t dual_node = 0;
|
||||
uint32_t f3xe8;
|
||||
uint32_t family;
|
||||
uint32_t model;
|
||||
|
||||
/* get_nodes define in ht_wrapper.c */
|
||||
nodes = get_nodes();
|
||||
|
||||
if (!CONFIG_LOGICAL_CPUS ||
|
||||
read_option(multi_core, 0) != 0) { // 0 means multi core
|
||||
disable_siblings = 1;
|
||||
} else {
|
||||
disable_siblings = 0;
|
||||
}
|
||||
uint32_t ApicIdCoreIdSize;
|
||||
|
||||
/* Assume that all node are same stepping, otherwise we can use use
|
||||
nb_cfg_54 from bsp for all nodes */
|
||||
nb_cfg_54 = read_nb_cfg_54();
|
||||
f3xe8 = pci_read_config32(NODE_PCI(0, 3), 0xe8);
|
||||
|
||||
if (cpuid_eax(0x80000001) >= 0x8)
|
||||
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;
|
||||
nb_cfg_54 = 1;
|
||||
}
|
||||
|
||||
if ((model >= 0x8) || fam15h)
|
||||
/* Revision D or later */
|
||||
rev_gte_d = 1;
|
||||
|
||||
@@ -99,10 +97,63 @@ static void for_each_ap(u32 bsp_apicid, u32 core_range, process_ap_t process_ap,
|
||||
siblings = 3; //quad core
|
||||
}
|
||||
|
||||
cores_found = get_core_num_in_bsp(node);
|
||||
if (siblings > cores_found)
|
||||
siblings = cores_found;
|
||||
|
||||
if (dual_node) {
|
||||
ap_apicid = 0;
|
||||
if (fam15h) {
|
||||
ap_apicid |= ((node >> 1) & 0x3) << 5; /* Node ID */
|
||||
ap_apicid |= ((node & 0x1) * (siblings + 1)) + core; /* Core ID */
|
||||
} else {
|
||||
if (nb_cfg_54) {
|
||||
ap_apicid |= ((node >> 1) & 0x3) << 4; /* Node ID */
|
||||
ap_apicid |= ((node & 0x1) * (siblings + 1)) + core; /* Core ID */
|
||||
} else {
|
||||
ap_apicid |= node & 0x3; /* Node ID */
|
||||
ap_apicid |= (((node & 0x1) * (siblings + 1)) + core) << 4; /* Core ID */
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (fam15h) {
|
||||
ap_apicid = (node * (siblings + 1)) + core;
|
||||
} else {
|
||||
ap_apicid = node * (nb_cfg_54 ? (siblings + 1) : 1) +
|
||||
core * (nb_cfg_54 ? 1 : 64);
|
||||
}
|
||||
}
|
||||
|
||||
return ap_apicid;
|
||||
}
|
||||
|
||||
//core_range = 0 : all cores
|
||||
//core range = 1 : core 0 only
|
||||
//core range = 2 : cores other than core0
|
||||
|
||||
static void for_each_ap(u32 bsp_apicid, u32 core_range, process_ap_t process_ap,
|
||||
void *gp)
|
||||
{
|
||||
// here assume the OS don't change our apicid
|
||||
u32 ap_apicid;
|
||||
|
||||
u32 nodes;
|
||||
u32 disable_siblings;
|
||||
u32 cores_found;
|
||||
int i, j;
|
||||
|
||||
/* get_nodes define in ht_wrapper.c */
|
||||
nodes = get_nodes();
|
||||
|
||||
if (!CONFIG_LOGICAL_CPUS ||
|
||||
read_option(multi_core, 0) != 0) { // 0 means multi core
|
||||
disable_siblings = 1;
|
||||
} else {
|
||||
disable_siblings = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < nodes; i++) {
|
||||
cores_found = get_core_num_in_bsp(i);
|
||||
if (siblings > cores_found)
|
||||
siblings = cores_found;
|
||||
|
||||
u32 jstart, jend;
|
||||
|
||||
@@ -119,21 +170,7 @@ static void for_each_ap(u32 bsp_apicid, u32 core_range, process_ap_t process_ap,
|
||||
}
|
||||
|
||||
for (j = jstart; j <= jend; j++) {
|
||||
if (dual_node) {
|
||||
ap_apicid = 0;
|
||||
if (nb_cfg_54) {
|
||||
ap_apicid |= ((i >> 1) & 0x3) << 4; /* Node ID */
|
||||
ap_apicid |= ((i & 0x1) * (siblings + 1)) + j; /* Core ID */
|
||||
} else {
|
||||
ap_apicid |= i & 0x3; /* Node ID */
|
||||
ap_apicid |= (((i & 0x1) * (siblings + 1)) + j) << 4; /* Core ID */
|
||||
}
|
||||
} else {
|
||||
ap_apicid =
|
||||
i * (nb_cfg_54 ? (siblings + 1) : 1) +
|
||||
j * (nb_cfg_54 ? 1 : 64);
|
||||
}
|
||||
|
||||
ap_apicid = get_boot_apic_id(i, j);
|
||||
|
||||
#if CONFIG_ENABLE_APIC_EXT_ID && (CONFIG_APIC_ID_OFFSET > 0)
|
||||
#if !CONFIG_LIFT_BSP_APIC_ID
|
||||
@@ -193,7 +230,7 @@ void print_apicid_nodeid_coreid(u32 apicid, struct node_core_id id,
|
||||
apicid, id.nodeid, id.coreid);
|
||||
}
|
||||
|
||||
static u32 wait_cpu_state(u32 apicid, u32 state)
|
||||
uint32_t wait_cpu_state(uint32_t apicid, uint32_t state, uint32_t state2)
|
||||
{
|
||||
u32 readback = 0;
|
||||
u32 timeout = 1;
|
||||
@@ -201,7 +238,7 @@ static u32 wait_cpu_state(u32 apicid, u32 state)
|
||||
while (--loop > 0) {
|
||||
if (lapic_remote_read(apicid, LAPIC_MSG_REG, &readback) != 0)
|
||||
continue;
|
||||
if ((readback & 0x3f) == state || (readback & 0x3f) == F10_APSTATE_RESET) {
|
||||
if ((readback & 0x3f) == state || (readback & 0x3f) == state2 || (readback & 0x3f) == F10_APSTATE_RESET) {
|
||||
timeout = 0;
|
||||
break; //target cpu is in stage started
|
||||
}
|
||||
@@ -218,7 +255,7 @@ static u32 wait_cpu_state(u32 apicid, u32 state)
|
||||
static void wait_ap_started(u32 ap_apicid, void *gp)
|
||||
{
|
||||
u32 timeout;
|
||||
timeout = wait_cpu_state(ap_apicid, F10_APSTATE_STARTED);
|
||||
timeout = wait_cpu_state(ap_apicid, F10_APSTATE_STARTED, F10_APSTATE_ASLEEP);
|
||||
printk(BIOS_DEBUG, "* AP %02x", ap_apicid);
|
||||
if (timeout) {
|
||||
printk(BIOS_DEBUG, " timed out:%08x\n", timeout);
|
||||
@@ -254,16 +291,27 @@ static void enable_apic_ext_id(u32 node)
|
||||
pci_write_config32(NODE_HT(node), 0x68, val);
|
||||
}
|
||||
|
||||
static void STOP_CAR_AND_CPU(void)
|
||||
static void STOP_CAR_AND_CPU(uint8_t skip_sharedc_config, uint32_t apicid)
|
||||
{
|
||||
msr_t msr;
|
||||
uint32_t family;
|
||||
|
||||
/* Disable L2 IC to L3 connection (Only for CAR) */
|
||||
msr = rdmsr(BU_CFG2);
|
||||
msr.lo &= ~(1 << ClLinesToNbDis);
|
||||
wrmsr(BU_CFG2, msr);
|
||||
family = amd_fam1x_cpu_family(); // inline
|
||||
|
||||
if (family < 0x6f) {
|
||||
/* Family 10h or earlier */
|
||||
|
||||
/* Disable L2 IC to L3 connection (Only for CAR) */
|
||||
msr = rdmsr(BU_CFG2);
|
||||
msr.lo &= ~(1 << ClLinesToNbDis);
|
||||
wrmsr(BU_CFG2, msr);
|
||||
}
|
||||
|
||||
disable_cache_as_ram(skip_sharedc_config); // inline
|
||||
|
||||
/* Mark the core as sleeping */
|
||||
lapic_write(LAPIC_MSG_REG, (apicid << 24) | F10_APSTATE_ASLEEP);
|
||||
|
||||
disable_cache_as_ram(); // inline
|
||||
/* stop all cores except node0/core0 the bsp .... */
|
||||
stop_this_cpu();
|
||||
}
|
||||
@@ -272,6 +320,7 @@ static u32 init_cpus(u32 cpu_init_detectedx, struct sys_info *sysinfo)
|
||||
{
|
||||
u32 bsp_apicid = 0;
|
||||
u32 apicid;
|
||||
uint8_t set_mtrrs;
|
||||
struct node_core_id id;
|
||||
|
||||
/* Please refer to the calculations and explaination in cache_as_ram.inc before modifying these values */
|
||||
@@ -358,7 +407,7 @@ static u32 init_cpus(u32 cpu_init_detectedx, struct sys_info *sysinfo)
|
||||
*/
|
||||
update_microcode(cpuid_eax(1));
|
||||
|
||||
cpuSetAMDMSR();
|
||||
cpuSetAMDMSR(id.nodeid);
|
||||
|
||||
#if CONFIG_SET_FIDVID
|
||||
#if CONFIG_LOGICAL_CPUS && CONFIG_SET_FIDVID_CORE0_ONLY
|
||||
@@ -381,10 +430,29 @@ static u32 init_cpus(u32 cpu_init_detectedx, struct sys_info *sysinfo)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* AP is ready, configure MTRRs and go to sleep */
|
||||
set_var_mtrr(0, 0x00000000, CONFIG_RAMTOP, MTRR_TYPE_WRBACK);
|
||||
if (is_fam15h()) {
|
||||
/* core 1 on node 0 is special; to avoid corrupting the
|
||||
* BSP do not alter MTRRs on that core */
|
||||
if (apicid == 1)
|
||||
set_mtrrs = 0;
|
||||
else
|
||||
set_mtrrs = !!(apicid & 0x1);
|
||||
} else {
|
||||
set_mtrrs = 1;
|
||||
}
|
||||
|
||||
STOP_CAR_AND_CPU();
|
||||
/* AP is ready, configure MTRRs and go to sleep */
|
||||
if (set_mtrrs)
|
||||
set_var_mtrr(0, 0x00000000, CONFIG_RAMTOP, MTRR_TYPE_WRBACK);
|
||||
|
||||
printk(BIOS_DEBUG, "Disabling CAR on AP %02x\n", apicid);
|
||||
if (is_fam15h()) {
|
||||
/* Only modify the MSRs on the odd cores (the last cores to finish booting) */
|
||||
STOP_CAR_AND_CPU(!set_mtrrs, apicid);
|
||||
} else {
|
||||
/* Modify MSRs on all cores */
|
||||
STOP_CAR_AND_CPU(0, apicid);
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG,
|
||||
"\nAP %02x should be halted but you are reading this....\n",
|
||||
@@ -492,7 +560,7 @@ static void setup_remote_node(u8 node)
|
||||
}
|
||||
#endif /* CONFIG_MAX_PHYSICAL_CPUS > 1 */
|
||||
|
||||
static void AMD_Errata281(u8 node, u32 revision, u32 platform)
|
||||
static void AMD_Errata281(u8 node, uint64_t revision, u32 platform)
|
||||
{
|
||||
/* Workaround for Transaction Scheduling Conflict in
|
||||
* Northbridge Cross Bar. Implement XCS Token adjustment
|
||||
@@ -790,7 +858,7 @@ static void AMD_SetHtPhyRegister(u8 node, u8 link, u8 entry)
|
||||
} while (!(val & HTPHY_IS_COMPLETE_MASK));
|
||||
}
|
||||
|
||||
void cpuSetAMDMSR(void)
|
||||
void cpuSetAMDMSR(uint8_t node_id)
|
||||
{
|
||||
/* This routine loads the CPU with default settings in fam10_msr_default
|
||||
* table . It must be run after Cache-As-RAM has been enabled, and
|
||||
@@ -800,7 +868,8 @@ void cpuSetAMDMSR(void)
|
||||
*/
|
||||
msr_t msr;
|
||||
u8 i;
|
||||
u32 revision, platform;
|
||||
u32 platform;
|
||||
uint64_t revision;
|
||||
|
||||
printk(BIOS_DEBUG, "cpuSetAMDMSR ");
|
||||
|
||||
@@ -820,6 +889,49 @@ void cpuSetAMDMSR(void)
|
||||
}
|
||||
AMD_Errata298();
|
||||
|
||||
if (revision & AMD_FAM15_ALL) {
|
||||
uint32_t f5x80;
|
||||
uint8_t enabled;
|
||||
uint8_t compute_unit_count = 0;
|
||||
f5x80 = pci_read_config32(NODE_PCI(node_id, 5), 0x80);
|
||||
enabled = f5x80 & 0xf;
|
||||
if (enabled == 0x1)
|
||||
compute_unit_count = 1;
|
||||
if (enabled == 0x3)
|
||||
compute_unit_count = 2;
|
||||
if (enabled == 0x7)
|
||||
compute_unit_count = 3;
|
||||
if (enabled == 0xf)
|
||||
compute_unit_count = 4;
|
||||
msr = rdmsr(BU_CFG2);
|
||||
msr.lo &= ~(0x3 << 6); /* ThrottleNbInterface[1:0] */
|
||||
msr.lo |= (((compute_unit_count - 1) & 0x3) << 6);
|
||||
wrmsr(BU_CFG2, msr);
|
||||
}
|
||||
|
||||
/* Revision C0 and above */
|
||||
if (revision & AMD_OR_C0) {
|
||||
uint32_t f3x1fc = pci_read_config32(NODE_PCI(node_id, 3), 0x1fc);
|
||||
msr = rdmsr(FP_CFG);
|
||||
msr.hi &= ~(0x7 << (42-32)); /* DiDtCfg4 */
|
||||
msr.hi |= (((f3x1fc >> 17) & 0x7) << (42-32));
|
||||
msr.hi &= ~(0x1 << (41-32)); /* DiDtCfg5 */
|
||||
msr.hi |= (((f3x1fc >> 22) & 0x1) << (41-32));
|
||||
msr.hi &= ~(0x1 << (40-32)); /* DiDtCfg3 */
|
||||
msr.hi |= (((f3x1fc >> 16) & 0x1) << (40-32));
|
||||
msr.hi &= ~(0x7 << (32-32)); /* DiDtCfg1 (1) */
|
||||
msr.hi |= (((f3x1fc >> 11) & 0x7) << (32-32));
|
||||
msr.lo &= ~(0x1f << 27); /* DiDtCfg1 (2) */
|
||||
msr.lo |= (((f3x1fc >> 6) & 0x1f) << 27);
|
||||
msr.lo &= ~(0x3 << 25); /* DiDtCfg2 */
|
||||
msr.lo |= (((f3x1fc >> 14) & 0x3) << 25);
|
||||
msr.lo &= ~(0x1f << 18); /* DiDtCfg0 */
|
||||
msr.lo |= (((f3x1fc >> 1) & 0x1f) << 18);
|
||||
msr.lo &= ~(0x1 << 16); /* DiDtMode */
|
||||
msr.lo |= ((f3x1fc & 0x1) << 16);
|
||||
wrmsr(FP_CFG, msr);
|
||||
}
|
||||
|
||||
printk(BIOS_DEBUG, " done\n");
|
||||
}
|
||||
|
||||
@@ -831,9 +943,10 @@ static void cpuSetAMDPCI(u8 node)
|
||||
* that it is run for the first core on each node
|
||||
*/
|
||||
u8 i, j;
|
||||
u32 revision, platform;
|
||||
u32 platform;
|
||||
u32 val;
|
||||
u8 offset;
|
||||
uint64_t revision;
|
||||
|
||||
printk(BIOS_DEBUG, "cpuSetAMDPCI %02d", node);
|
||||
|
||||
@@ -895,6 +1008,7 @@ static void cpuSetAMDPCI(u8 node)
|
||||
}
|
||||
|
||||
#ifdef UNUSED_CODE
|
||||
/* Clearing the MCA registers is apparently handled in the ramstage CPU Function 3 driver */
|
||||
static void cpuInitializeMCA(void)
|
||||
{
|
||||
/* Clears Machine Check Architecture (MCA) registers, which power on
|
||||
|
@@ -35,6 +35,23 @@
|
||||
|
||||
#define MCI_STATUS 0x401
|
||||
|
||||
static inline uint8_t is_fam15h(void)
|
||||
{
|
||||
uint8_t fam15h = 0;
|
||||
uint32_t family;
|
||||
|
||||
family = cpuid_eax(0x80000001);
|
||||
family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
|
||||
|
||||
if (family >= 0x6f)
|
||||
/* Family 15h or later */
|
||||
fam15h = 1;
|
||||
|
||||
return fam15h;
|
||||
}
|
||||
|
||||
static volatile uint8_t fam15h_startup_flags[MAX_NODES_SUPPORTED][MAX_CORES_SUPPORTED] = {{ 0 }};
|
||||
|
||||
static void model_10xxx_init(device_t dev)
|
||||
{
|
||||
u8 i;
|
||||
@@ -43,13 +60,44 @@ static void model_10xxx_init(device_t dev)
|
||||
#if CONFIG_LOGICAL_CPUS
|
||||
u32 siblings;
|
||||
#endif
|
||||
uint8_t delay_start;
|
||||
|
||||
id = get_node_core_id(read_nb_cfg_54()); /* nb_cfg_54 can not be set */
|
||||
printk(BIOS_DEBUG, "nodeid = %02d, coreid = %02d\n", id.nodeid, id.coreid);
|
||||
|
||||
if (is_fam15h())
|
||||
delay_start = !!(id.coreid & 0x1);
|
||||
else
|
||||
delay_start = 0;
|
||||
|
||||
/* Turn on caching if we haven't already */
|
||||
x86_enable_cache();
|
||||
amd_setup_mtrrs();
|
||||
|
||||
if (!delay_start) {
|
||||
/* Initialize all variable MTRRs except the first pair.
|
||||
* This prevents Linux from having to correct an inconsistent
|
||||
* MTRR setup, which would crash Family 15h CPUs due to the
|
||||
* compute unit structure sharing MTRR MSRs between AP cores.
|
||||
*/
|
||||
msr.hi = 0x00000000;
|
||||
msr.lo = 0x00000000;
|
||||
|
||||
disable_cache();
|
||||
|
||||
for (i = 0x2; i < 0x10; i++) {
|
||||
wrmsr(0x00000200 | i, msr);
|
||||
}
|
||||
|
||||
enable_cache();
|
||||
|
||||
/* Set up other MTRRs */
|
||||
amd_setup_mtrrs();
|
||||
} else {
|
||||
while (!fam15h_startup_flags[id.nodeid][id.coreid - 1]) {
|
||||
/* Wait for CU first core startup */
|
||||
}
|
||||
}
|
||||
|
||||
x86_mtrr_check();
|
||||
|
||||
disable_cache();
|
||||
@@ -84,17 +132,24 @@ static void model_10xxx_init(device_t dev)
|
||||
printk(BIOS_DEBUG, "siblings = %02d, ", siblings);
|
||||
#endif
|
||||
|
||||
/* DisableCf8ExtCfg */
|
||||
/* Disable Cf8ExtCfg */
|
||||
msr = rdmsr(NB_CFG_MSR);
|
||||
msr.hi &= ~(1 << (46 - 32));
|
||||
wrmsr(NB_CFG_MSR, msr);
|
||||
|
||||
msr = rdmsr(BU_CFG2_MSR);
|
||||
/* Clear ClLinesToNbDis */
|
||||
msr.lo &= ~(1 << 15);
|
||||
/* Clear bit 35 as per Erratum 343 */
|
||||
msr.hi &= ~(1 << (35-32));
|
||||
wrmsr(BU_CFG2_MSR, msr);
|
||||
if (is_fam15h()) {
|
||||
msr = rdmsr(BU_CFG3_MSR);
|
||||
/* Set CombineCr0Cd */
|
||||
msr.hi |= (1 << (49-32));
|
||||
wrmsr(BU_CFG3_MSR, msr);
|
||||
} else {
|
||||
msr = rdmsr(BU_CFG2_MSR);
|
||||
/* Clear ClLinesToNbDis */
|
||||
msr.lo &= ~(1 << 15);
|
||||
/* Clear bit 35 as per Erratum 343 */
|
||||
msr.hi &= ~(1 << (35-32));
|
||||
wrmsr(BU_CFG2_MSR, msr);
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) {
|
||||
printk(BIOS_DEBUG, "Initializing SMM ASeg memory\n");
|
||||
@@ -127,6 +182,7 @@ static void model_10xxx_init(device_t dev)
|
||||
msr.lo |= (1 << 0);
|
||||
wrmsr(HWCR_MSR, msr);
|
||||
|
||||
fam15h_startup_flags[id.nodeid][id.coreid] = 1;
|
||||
}
|
||||
|
||||
static struct device_operations cpu_dev_ops = {
|
||||
@@ -143,15 +199,17 @@ static struct cpu_device_id cpu_table[] = {
|
||||
{ X86_VENDOR_AMD, 0x100f22 },
|
||||
{ X86_VENDOR_AMD, 0x100f23 },
|
||||
{ X86_VENDOR_AMD, 0x100f40 }, /* RB-C0 */
|
||||
{ X86_VENDOR_AMD, 0x100F42 }, /* RB-C2 */
|
||||
{ X86_VENDOR_AMD, 0x100F43 }, /* RB-C3 */
|
||||
{ X86_VENDOR_AMD, 0x100F52 }, /* BL-C2 */
|
||||
{ X86_VENDOR_AMD, 0x100F62 }, /* DA-C2 */
|
||||
{ X86_VENDOR_AMD, 0x100F63 }, /* DA-C3 */
|
||||
{ X86_VENDOR_AMD, 0x100F80 }, /* HY-D0 */
|
||||
{ X86_VENDOR_AMD, 0x100F81 }, /* HY-D1 */
|
||||
{ X86_VENDOR_AMD, 0x100F91 }, /* HY-D1 */
|
||||
{ X86_VENDOR_AMD, 0x100FA0 }, /* PH-E0 */
|
||||
{ X86_VENDOR_AMD, 0x100f42 }, /* RB-C2 */
|
||||
{ X86_VENDOR_AMD, 0x100f43 }, /* RB-C3 */
|
||||
{ X86_VENDOR_AMD, 0x100f52 }, /* BL-C2 */
|
||||
{ X86_VENDOR_AMD, 0x100f62 }, /* DA-C2 */
|
||||
{ X86_VENDOR_AMD, 0x100f63 }, /* DA-C3 */
|
||||
{ X86_VENDOR_AMD, 0x100f80 }, /* HY-D0 */
|
||||
{ X86_VENDOR_AMD, 0x100f81 }, /* HY-D1 */
|
||||
{ X86_VENDOR_AMD, 0x100f91 }, /* HY-D1 */
|
||||
{ X86_VENDOR_AMD, 0x100fa0 }, /* PH-E0 */
|
||||
{ X86_VENDOR_AMD, 0x600f12 }, /* OR-B2 */
|
||||
{ X86_VENDOR_AMD, 0x600f20 }, /* OR-C0 */
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
|
@@ -70,8 +70,7 @@ static void write_pstates_for_core(u8 pstate_num, u16 *pstate_feq, u32 *pstate_p
|
||||
/* Revision C or greater single-link processor */
|
||||
cpuid1 = cpuid(0x80000008);
|
||||
acpigen_write_PSD_package(0, (cpuid1.ecx & 0xff) + 1, SW_ALL);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
/* Find the local APIC ID for the specified core ID */
|
||||
struct device* cpu;
|
||||
int cpu_index = 0;
|
||||
@@ -95,7 +94,9 @@ static void write_pstates_for_core(u8 pstate_num, u16 *pstate_feq, u32 *pstate_p
|
||||
}
|
||||
|
||||
/*
|
||||
* For details of this algorithm, please refer to the BDKG 3.62 page 69
|
||||
* For details of this algorithm, please refer to:
|
||||
* Family 10h BDKG 3.62 page 69
|
||||
* Family 15h BDKG 3.14 page 74
|
||||
*
|
||||
* WARNING: The core count algorithm below assumes that all processors
|
||||
* are identical, with the same number of active cores. While the BKDG
|
||||
@@ -145,6 +146,13 @@ void amd_generate_powernow(u32 pcontrol_blk, u8 plen, u8 onlyBSP)
|
||||
uint8_t node_count;
|
||||
uint8_t cores_per_node;
|
||||
uint8_t total_core_count;
|
||||
uint8_t fam15h;
|
||||
uint8_t fam10h_rev_e = 0;
|
||||
|
||||
/* Detect Revision E processors via method used in fidvid.c */
|
||||
if ((cpuid_edx(0x80000007) & CPB_MASK)
|
||||
&& ((cpuid_ecx(0x80000008) & NC_MASK) == 5))
|
||||
fam10h_rev_e = 1;
|
||||
|
||||
/*
|
||||
* Based on the CPU socket type,cmp_cap and pwr_lmt , get the power limit.
|
||||
@@ -152,11 +160,17 @@ void amd_generate_powernow(u32 pcontrol_blk, u8 plen, u8 onlyBSP)
|
||||
* cmp_cap : 0x0 SingleCore ; 0x1 DualCore ; 0x2 TripleCore ; 0x3 QuadCore ; 0x4 QuintupleCore ; 0x5 HexCore
|
||||
*/
|
||||
printk(BIOS_INFO, "Pstates algorithm ...\n");
|
||||
fam15h = !!(mctGetLogicalCPUID(0) & AMD_FAM15_ALL);
|
||||
/* Get number of cores */
|
||||
dtemp = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 3)), 0xE8);
|
||||
cmp_cap = (dtemp & 0x3000) >> 12;
|
||||
if (mctGetLogicalCPUID(0) & AMD_FAM10_REV_D) /* revision D */
|
||||
cmp_cap |= (dtemp & 0x8000) >> 13;
|
||||
if (fam15h) {
|
||||
cmp_cap = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 5)), 0x84) & 0xff;
|
||||
} else {
|
||||
dtemp = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 3)), 0xe8);
|
||||
cmp_cap = (dtemp & 0x3000) >> 12;
|
||||
if (mctGetLogicalCPUID(0) & (AMD_FAM10_REV_D | AMD_FAM15_ALL)) /* revision D or higher */
|
||||
cmp_cap |= (dtemp & 0x8000) >> 13;
|
||||
}
|
||||
|
||||
/* Get number of nodes */
|
||||
dtemp = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 0)), 0x60);
|
||||
node_count = ((dtemp & 0x70) >> 4) + 1;
|
||||
@@ -165,6 +179,14 @@ void amd_generate_powernow(u32 pcontrol_blk, u8 plen, u8 onlyBSP)
|
||||
/* Compute total number of cores installed in system */
|
||||
total_core_count = cores_per_node * node_count;
|
||||
|
||||
/* Get number of boost states */
|
||||
uint8_t boost_count = 0;
|
||||
dtemp = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x18, 4)), 0x15c);
|
||||
if (fam10h_rev_e)
|
||||
boost_count = (dtemp >> 2) & 0x1;
|
||||
else if (mctGetLogicalCPUID(0) & AMD_FAM15_ALL)
|
||||
boost_count = (dtemp >> 2) & 0x7;
|
||||
|
||||
Pstate_num = 0;
|
||||
|
||||
/* See if the CPUID(0x80000007) returned EDX[7]==1b */
|
||||
@@ -201,7 +223,7 @@ void amd_generate_powernow(u32 pcontrol_blk, u8 plen, u8 onlyBSP)
|
||||
|
||||
/* Get PSmax's index */
|
||||
msr = rdmsr(0xC0010061);
|
||||
Pstate_max = (uint8_t) ((msr.lo >> PS_MAX_VAL_SHFT) & BIT_MASK_3);
|
||||
Pstate_max = (uint8_t) ((msr.lo >> PS_MAX_VAL_SHFT) & ((fam15h)?BIT_MASK_7:BIT_MASK_3));
|
||||
|
||||
/* Determine if all enabled Pstates have the same fidvid */
|
||||
uint8_t i;
|
||||
@@ -215,10 +237,14 @@ void amd_generate_powernow(u32 pcontrol_blk, u8 plen, u8 onlyBSP)
|
||||
}
|
||||
}
|
||||
|
||||
/* Family 15h uses slightly different PSmax numbering */
|
||||
if (fam15h)
|
||||
Pstate_max++;
|
||||
|
||||
/* Populate tables with all Pstate information */
|
||||
for (Pstate_num = 0; Pstate_num < Pstate_max; Pstate_num++) {
|
||||
/* Get power state information */
|
||||
msr = rdmsr(0xC0010064 + Pstate_num);
|
||||
msr = rdmsr(0xC0010064 + Pstate_num + boost_count);
|
||||
cpufid = (msr.lo & 0x3f);
|
||||
cpudid = (msr.lo & 0x1c0) >> 6;
|
||||
cpuvid = (msr.lo & 0xfe00) >> 9;
|
||||
@@ -228,12 +254,10 @@ void amd_generate_powernow(u32 pcontrol_blk, u8 plen, u8 onlyBSP)
|
||||
if (pviModeFlag) {
|
||||
if (cpuvid >= 0x20) {
|
||||
core_voltage = 7625 - (((cpuvid - 0x20) * 10000) / 80);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
core_voltage = 15500 - ((cpuvid * 10000) / 40);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
cpuvid = cpuvid & 0x7f;
|
||||
if (cpuvid >= 0x7c)
|
||||
core_voltage = 0;
|
||||
|
@@ -29,6 +29,10 @@
|
||||
#include <cpu/amd/mtrr.h>
|
||||
#include <cpu/cpu.h>
|
||||
#include <cpu/amd/model_10xxx_rev.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pnp.h>
|
||||
#include <device/pci_ops.h>
|
||||
|
||||
/* The maximum length of CPU names is 48 bytes, including the final NULL byte.
|
||||
* If you change these names your BIOS will _NOT_ pass the AMD validation and
|
||||
@@ -208,105 +212,139 @@ static int strcpymax(char *dst, const char *src, int buflen)
|
||||
return i;
|
||||
}
|
||||
|
||||
#define NAME_STRING_MAXLEN 48
|
||||
|
||||
int init_processor_name(void)
|
||||
{
|
||||
/* variable names taken from fam10 revision guide for clarity */
|
||||
u32 BrandId; /* CPUID Fn8000_0001_EBX */
|
||||
u8 String1; /* BrandID[14:11] */
|
||||
u8 String2; /* BrandID[3:0] */
|
||||
u8 Model; /* BrandID[10:4] */
|
||||
u8 Pg; /* BrandID[15] */
|
||||
u8 PkgTyp; /* BrandID[31:28] */
|
||||
u8 NC; /* CPUID Fn8000_0008_ECX */
|
||||
const char *processor_name_string = unknown;
|
||||
char program_string[48];
|
||||
u32 *p_program_string = (u32 *)program_string;
|
||||
msr_t msr;
|
||||
int i, j = 0, str2_checkNC = 1;
|
||||
const struct str_s *str, *str2;
|
||||
ssize_t i;
|
||||
char program_string[NAME_STRING_MAXLEN];
|
||||
u32 *p_program_string = (u32 *)program_string;
|
||||
uint8_t fam15h = 0;
|
||||
uint32_t family;
|
||||
|
||||
family = cpuid_eax(0x80000001);
|
||||
family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
|
||||
|
||||
/* Find out which CPU brand it is */
|
||||
BrandId = cpuid_ebx(0x80000001);
|
||||
String1 = (u8)((BrandId >> 11) & 0x0F);
|
||||
String2 = (u8)((BrandId >> 0) & 0x0F);
|
||||
Model = (u8)((BrandId >> 4) & 0x7F);
|
||||
Pg = (u8)((BrandId >> 15) & 0x01);
|
||||
PkgTyp = (u8)((BrandId >> 28) & 0x0F);
|
||||
NC = (u8)(cpuid_ecx(0x80000008) & 0xFF);
|
||||
if (family >= 0x6f)
|
||||
/* Family 15h or later */
|
||||
fam15h = 1;
|
||||
|
||||
/* null the string */
|
||||
memset(program_string, 0, sizeof(program_string));
|
||||
|
||||
if (!Model) {
|
||||
processor_name_string = Pg ? thermal : sample;
|
||||
goto done;
|
||||
}
|
||||
if (fam15h) {
|
||||
/* Family 15h or later */
|
||||
uint32_t dword;
|
||||
device_t cpu_fn5_dev = dev_find_slot(0, PCI_DEVFN(0x18, 5));
|
||||
pci_write_config32(cpu_fn5_dev, 0x194, 0);
|
||||
dword = pci_read_config32(cpu_fn5_dev, 0x198);
|
||||
if (dword == 0) {
|
||||
strcpymax(program_string, sample, sizeof(program_string));
|
||||
} else {
|
||||
/* Assemble the string from PCI configuration register contents */
|
||||
for (i = 0; i < 12; i++) {
|
||||
pci_write_config32(cpu_fn5_dev, 0x194, i);
|
||||
p_program_string[i] = pci_read_config32(cpu_fn5_dev, 0x198);
|
||||
}
|
||||
|
||||
switch (PkgTyp) {
|
||||
case 0: /* F1207 */
|
||||
str = String1_socket_F;
|
||||
str2 = String2_socket_F;
|
||||
str2_checkNC = 0;
|
||||
break;
|
||||
case 1: /* AM2 */
|
||||
str = String1_socket_AM2;
|
||||
str2 = String2_socket_AM2;
|
||||
break;
|
||||
case 3: /* G34 */
|
||||
str = String1_socket_G34;
|
||||
str2 = String2_socket_G34;
|
||||
str2_checkNC = 0;
|
||||
break;
|
||||
case 5: /* C32 */
|
||||
str = String1_socket_C32;
|
||||
str2 = String2_socket_C32;
|
||||
break;
|
||||
default:
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* String1 */
|
||||
for (i = 0; str[i].value; i++) {
|
||||
if ((str[i].Pg == Pg) &&
|
||||
(str[i].NC == NC) &&
|
||||
(str[i].String == String1)) {
|
||||
processor_name_string = str[i].value;
|
||||
break;
|
||||
/* Correctly place the null terminator */
|
||||
for (i = (NAME_STRING_MAXLEN - 2); i > 0; i--) {
|
||||
if (program_string[i] != 0x20)
|
||||
break;
|
||||
}
|
||||
program_string[i + 1] = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* variable names taken from fam10 revision guide for clarity */
|
||||
u32 BrandId; /* CPUID Fn8000_0001_EBX */
|
||||
u8 String1; /* BrandID[14:11] */
|
||||
u8 String2; /* BrandID[3:0] */
|
||||
u8 Model; /* BrandID[10:4] */
|
||||
u8 Pg; /* BrandID[15] */
|
||||
u8 PkgTyp; /* BrandID[31:28] */
|
||||
u8 NC; /* CPUID Fn8000_0008_ECX */
|
||||
const char *processor_name_string = unknown;
|
||||
int j = 0, str2_checkNC = 1;
|
||||
const struct str_s *str, *str2;
|
||||
|
||||
if (!str[i].value)
|
||||
goto done;
|
||||
/* Find out which CPU brand it is */
|
||||
BrandId = cpuid_ebx(0x80000001);
|
||||
String1 = (u8)((BrandId >> 11) & 0x0F);
|
||||
String2 = (u8)((BrandId >> 0) & 0x0F);
|
||||
Model = (u8)((BrandId >> 4) & 0x7F);
|
||||
Pg = (u8)((BrandId >> 15) & 0x01);
|
||||
PkgTyp = (u8)((BrandId >> 28) & 0x0F);
|
||||
NC = (u8)(cpuid_ecx(0x80000008) & 0xFF);
|
||||
|
||||
j = strcpymax(program_string, processor_name_string,
|
||||
sizeof(program_string));
|
||||
|
||||
/* Translate Model from 01-99 to ASCII and put it on the end.
|
||||
* Numbers less than 10 should include a leading zero, e.g., 09.*/
|
||||
if (Model < 100 && j < sizeof(program_string) - 2) {
|
||||
program_string[j++] = (Model / 10) + '0';
|
||||
program_string[j++] = (Model % 10) + '0';
|
||||
}
|
||||
|
||||
processor_name_string = unknown2;
|
||||
|
||||
/* String 2 */
|
||||
for(i = 0; str2[i].value; i++) {
|
||||
if ((str2[i].Pg == Pg) &&
|
||||
((str2[i].NC == NC) || !str2_checkNC) &&
|
||||
(str2[i].String == String2)) {
|
||||
processor_name_string = str2[i].value;
|
||||
break;
|
||||
if (!Model) {
|
||||
processor_name_string = Pg ? thermal : sample;
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch (PkgTyp) {
|
||||
case 0: /* F1207 */
|
||||
str = String1_socket_F;
|
||||
str2 = String2_socket_F;
|
||||
str2_checkNC = 0;
|
||||
break;
|
||||
case 1: /* AM2 */
|
||||
str = String1_socket_AM2;
|
||||
str2 = String2_socket_AM2;
|
||||
break;
|
||||
case 3: /* G34 */
|
||||
str = String1_socket_G34;
|
||||
str2 = String2_socket_G34;
|
||||
str2_checkNC = 0;
|
||||
break;
|
||||
case 5: /* C32 */
|
||||
str = String1_socket_C32;
|
||||
str2 = String2_socket_C32;
|
||||
break;
|
||||
default:
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* String1 */
|
||||
for (i = 0; str[i].value; i++) {
|
||||
if ((str[i].Pg == Pg) &&
|
||||
(str[i].NC == NC) &&
|
||||
(str[i].String == String1)) {
|
||||
processor_name_string = str[i].value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!str[i].value)
|
||||
goto done;
|
||||
|
||||
j = strcpymax(program_string, processor_name_string,
|
||||
sizeof(program_string));
|
||||
|
||||
/* Translate Model from 01-99 to ASCII and put it on the end.
|
||||
* Numbers less than 10 should include a leading zero, e.g., 09.*/
|
||||
if (Model < 100 && j < sizeof(program_string) - 2) {
|
||||
program_string[j++] = (Model / 10) + '0';
|
||||
program_string[j++] = (Model % 10) + '0';
|
||||
}
|
||||
|
||||
processor_name_string = unknown2;
|
||||
|
||||
/* String 2 */
|
||||
for(i = 0; str2[i].value; i++) {
|
||||
if ((str2[i].Pg == Pg) &&
|
||||
((str2[i].NC == NC) || !str2_checkNC) &&
|
||||
(str2[i].String == String2)) {
|
||||
processor_name_string = str2[i].value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
strcpymax(&program_string[j], processor_name_string,
|
||||
sizeof(program_string) - j);
|
||||
}
|
||||
|
||||
|
||||
done:
|
||||
strcpymax(&program_string[j], processor_name_string,
|
||||
sizeof(program_string) - j);
|
||||
|
||||
printk(BIOS_DEBUG, "CPU model: %s\n", program_string);
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
|
@@ -24,6 +24,7 @@ struct id_mapping {
|
||||
|
||||
static u16 get_equivalent_processor_rev_id(u32 orig_id) {
|
||||
static const struct id_mapping id_mapping_table[] = {
|
||||
/* Family 10h */
|
||||
{ 0x100f00, 0x1000 },
|
||||
{ 0x100f01, 0x1000 },
|
||||
{ 0x100f02, 0x1000 },
|
||||
@@ -38,8 +39,13 @@ static u16 get_equivalent_processor_rev_id(u32 orig_id) {
|
||||
{ 0x100f62, 0x1062 }, /* DA-C2 */
|
||||
{ 0x100f63, 0x1043 }, /* DA-C3 */
|
||||
{ 0x100f81, 0x1081 }, /* HY-D1 */
|
||||
{ 0x100f91, 0x1081 }, /* HY-D1 */
|
||||
{ 0x100fa0, 0x10A0 }, /* PH-E0 */
|
||||
|
||||
/* Family 15h */
|
||||
{ 0x600f12, 0x6012 }, /* OR-B2 */
|
||||
{ 0x600f20, 0x6020 }, /* OR-C0 */
|
||||
|
||||
/* Array terminator */
|
||||
{ 0xffffff, 0x0000 },
|
||||
};
|
||||
|
@@ -199,7 +199,7 @@ static void enable_apic_ext_id(u32 node)
|
||||
|
||||
static void STOP_CAR_AND_CPU(void)
|
||||
{
|
||||
disable_cache_as_ram(); // inline
|
||||
disable_cache_as_ram(0); // inline
|
||||
/* stop all cores except node0/core0 the bsp .... */
|
||||
stop_this_cpu();
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@
|
||||
* 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
|
||||
@@ -22,16 +23,41 @@
|
||||
|
||||
#include "cpu/amd/quadcore/quadcore_id.c"
|
||||
|
||||
/* get_boot_apic_id and wait_cpu_state located in init_cpus.c */
|
||||
uint32_t get_boot_apic_id(uint8_t node, uint32_t core);
|
||||
uint32_t wait_cpu_state(uint32_t apicid, uint32_t state, uint32_t state2);
|
||||
|
||||
static inline uint8_t is_fam15h(void)
|
||||
{
|
||||
uint8_t fam15h = 0;
|
||||
uint32_t family;
|
||||
|
||||
family = cpuid_eax(0x80000001);
|
||||
family = ((family & 0xf00000) >> 16) | ((family & 0xf00) >> 8);
|
||||
|
||||
if (family >= 0x6f)
|
||||
/* Family 15h or later */
|
||||
fam15h = 1;
|
||||
|
||||
return fam15h;
|
||||
}
|
||||
|
||||
static u32 get_core_num_in_bsp(u32 nodeid)
|
||||
{
|
||||
u32 dword;
|
||||
dword = pci_read_config32(NODE_PCI(nodeid, 3), 0xe8);
|
||||
dword >>= 12;
|
||||
/* Bit 15 is CmpCap[2] since Revision D. */
|
||||
if ((cpuid_ecx(0x80000008) & 0xff) > 3)
|
||||
dword = ((dword & 8) >> 1) | (dword & 3);
|
||||
else
|
||||
dword &= 3;
|
||||
if (is_fam15h()) {
|
||||
/* Family 15h moved CmpCap to F5x84 [7:0] */
|
||||
dword = pci_read_config32(NODE_PCI(nodeid, 5), 0x84);
|
||||
dword &= 0xff;
|
||||
} else {
|
||||
dword = pci_read_config32(NODE_PCI(nodeid, 3), 0xe8);
|
||||
dword >>= 12;
|
||||
/* Bit 15 is CmpCap[2] since Revision D. */
|
||||
if ((cpuid_ecx(0x80000008) & 0xff) > 3)
|
||||
dword = ((dword & 8) >> 1) | (dword & 3);
|
||||
else
|
||||
dword &= 3;
|
||||
}
|
||||
return dword;
|
||||
}
|
||||
|
||||
@@ -46,28 +72,68 @@ static u8 set_apicid_cpuid_lo(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void real_start_other_core(u32 nodeid, u32 cores)
|
||||
static void real_start_other_core(uint32_t nodeid, uint32_t cores)
|
||||
{
|
||||
u32 dword, i;
|
||||
ssize_t i;
|
||||
uint32_t dword;
|
||||
|
||||
printk(BIOS_DEBUG, "Start other core - nodeid: %02x cores: %02x\n", nodeid, cores);
|
||||
|
||||
/* set PCI_DEV(0, 0x18+nodeid, 3), 0x44 bit 27 to redirect all MC4
|
||||
accesses and error logging to core0 */
|
||||
dword = pci_read_config32(NODE_PCI(nodeid, 3), 0x44);
|
||||
dword |= 1 << 27; // NbMcaToMstCpuEn bit
|
||||
dword |= 1 << 30; /* SyncFloodOnDramAdrParErr=1 */
|
||||
dword |= 1 << 27; /* NbMcaToMstCpuEn=1 */
|
||||
dword |= 1 << 21; /* SyncFloodOnAnyUcErr=1 */
|
||||
dword |= 1 << 20; /* SyncFloodOnWDT=1 */
|
||||
dword |= 1 << 2; /* SyncFloodOnDramUcEcc=1 */
|
||||
pci_write_config32(NODE_PCI(nodeid, 3), 0x44, dword);
|
||||
// set PCI_DEV(0, 0x18+nodeid, 0), 0x68 bit 5 to start core1
|
||||
dword = pci_read_config32(NODE_PCI(nodeid, 0), 0x68);
|
||||
dword |= 1 << 5;
|
||||
pci_write_config32(NODE_PCI(nodeid, 0), 0x68, dword);
|
||||
if (is_fam15h()) {
|
||||
uint32_t core_activation_flags = 0;
|
||||
uint32_t active_cores = 0;
|
||||
|
||||
if(cores > 1) {
|
||||
dword = pci_read_config32(NODE_PCI(nodeid, 0), 0x168);
|
||||
for (i = 0; i < cores - 1; i++) {
|
||||
dword |= 1 << i;
|
||||
/* Set PCI_DEV(0, 0x18+nodeid, 0), 0x1dc bits 7:1 to start cores */
|
||||
dword = pci_read_config32(NODE_PCI(nodeid, 0), 0x1dc);
|
||||
for (i = 1; i < cores + 1; i++) {
|
||||
core_activation_flags |= 1 << i;
|
||||
}
|
||||
|
||||
/* Start the first core of each compute unit */
|
||||
active_cores |= core_activation_flags & 0x55;
|
||||
pci_write_config32(NODE_PCI(nodeid, 0), 0x1dc, dword | active_cores);
|
||||
|
||||
/* Each core shares a single set of MTRR registers with
|
||||
* another core in the same compute unit, therefore, it
|
||||
* is important that one core in each CU starts in advance
|
||||
* of the other in order to avoid one core stomping all over
|
||||
* the other core's settings.
|
||||
*/
|
||||
|
||||
/* Wait for the first core of each compute unit to start... */
|
||||
uint32_t timeout;
|
||||
for (i = 1; i < cores + 1; i++) {
|
||||
if (!(i & 0x1)) {
|
||||
uint32_t ap_apicid = get_boot_apic_id(nodeid, i);
|
||||
timeout = wait_cpu_state(ap_apicid, F10_APSTATE_ASLEEP, F10_APSTATE_ASLEEP);
|
||||
}
|
||||
}
|
||||
|
||||
/* Start the second core of each compute unit */
|
||||
active_cores |= core_activation_flags & 0xaa;
|
||||
pci_write_config32(NODE_PCI(nodeid, 0), 0x1dc, dword | active_cores);
|
||||
} else {
|
||||
// set PCI_DEV(0, 0x18+nodeid, 0), 0x68 bit 5 to start core1
|
||||
dword = pci_read_config32(NODE_PCI(nodeid, 0), 0x68);
|
||||
dword |= 1 << 5;
|
||||
pci_write_config32(NODE_PCI(nodeid, 0), 0x68, dword);
|
||||
|
||||
if (cores > 1) {
|
||||
dword = pci_read_config32(NODE_PCI(nodeid, 0), 0x168);
|
||||
for (i = 0; i < cores - 1; i++) {
|
||||
dword |= 1 << i;
|
||||
}
|
||||
pci_write_config32(NODE_PCI(nodeid, 0), 0x168, dword);
|
||||
}
|
||||
pci_write_config32(NODE_PCI(nodeid, 0), 0x168, dword);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,10 +153,9 @@ static void start_other_cores(void)
|
||||
|
||||
for (nodeid = 0; nodeid < nodes; nodeid++) {
|
||||
u32 cores = get_core_num_in_bsp(nodeid);
|
||||
printk(BIOS_DEBUG, "init node: %02x cores: %02x \n", nodeid, cores);
|
||||
printk(BIOS_DEBUG, "init node: %02x cores: %02x pass 1 \n", nodeid, cores);
|
||||
if (cores > 0) {
|
||||
real_start_other_core(nodeid, cores);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -39,9 +39,12 @@ struct node_core_id get_node_core_id(u32 nb_cfg_54)
|
||||
{
|
||||
struct node_core_id id;
|
||||
uint8_t apicid;
|
||||
uint8_t fam15h = 0;
|
||||
uint8_t rev_gte_d = 0;
|
||||
uint8_t dual_node = 0;
|
||||
uint32_t f3xe8;
|
||||
uint32_t family;
|
||||
uint32_t model;
|
||||
|
||||
#ifdef __PRE_RAM__
|
||||
f3xe8 = pci_read_config32(NODE_PCI(0, 3), 0xe8);
|
||||
@@ -49,7 +52,17 @@ struct node_core_id get_node_core_id(u32 nb_cfg_54)
|
||||
f3xe8 = pci_read_config32(get_node_pci(0, 3), 0xe8);
|
||||
#endif
|
||||
|
||||
if (cpuid_eax(0x80000001) >= 0x8)
|
||||
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;
|
||||
nb_cfg_54 = 1;
|
||||
}
|
||||
|
||||
if ((model >= 0x8) || fam15h)
|
||||
/* Revision D or later */
|
||||
rev_gte_d = 1;
|
||||
|
||||
@@ -63,7 +76,13 @@ struct node_core_id get_node_core_id(u32 nb_cfg_54)
|
||||
*/
|
||||
apicid = (cpuid_ebx(1) >> 24) & 0xff;
|
||||
if( nb_cfg_54) {
|
||||
if (rev_gte_d && dual_node) {
|
||||
if (fam15h && dual_node) {
|
||||
id.coreid = apicid & 0x1f;
|
||||
id.nodeid = (apicid & 0x60) >> 5;
|
||||
} else if (fam15h && !dual_node) {
|
||||
id.coreid = apicid & 0xf;
|
||||
id.nodeid = (apicid & 0x70) >> 4;
|
||||
} else if (rev_gte_d && dual_node) {
|
||||
id.coreid = apicid & 0xf;
|
||||
id.nodeid = (apicid & 0x30) >> 4;
|
||||
} else if (rev_gte_d && !dual_node) {
|
||||
@@ -86,7 +105,25 @@ struct node_core_id get_node_core_id(u32 nb_cfg_54)
|
||||
}
|
||||
}
|
||||
|
||||
if (rev_gte_d && dual_node) {
|
||||
if (fam15h && dual_node) {
|
||||
/* Coreboot expects each separate processor die to be on a different nodeid.
|
||||
* Since the code above returns nodeid 0 even on internal node 1 some fixup is needed...
|
||||
*/
|
||||
uint32_t f5x84;
|
||||
uint8_t core_count;
|
||||
|
||||
#ifdef __PRE_RAM__
|
||||
f5x84 = pci_read_config32(NODE_PCI(0, 5), 0x84);
|
||||
#else
|
||||
f5x84 = pci_read_config32(get_node_pci(0, 5), 0x84);
|
||||
#endif
|
||||
core_count = (f5x84 & 0xff) + 1;
|
||||
id.nodeid = id.nodeid * 2;
|
||||
if (id.coreid >= core_count) {
|
||||
id.nodeid += 1;
|
||||
id.coreid = id.coreid - core_count;
|
||||
}
|
||||
} else if (rev_gte_d && dual_node) {
|
||||
/* Coreboot expects each separate processor die to be on a different nodeid.
|
||||
* Since the code above returns nodeid 0 even on internal node 1 some fixup is needed...
|
||||
*/
|
||||
|
Reference in New Issue
Block a user