diff options
Diffstat (limited to 'src/cpu/amd/car/disable_cache_as_ram.c')
-rw-r--r-- | src/cpu/amd/car/disable_cache_as_ram.c | 89 |
1 files changed, 69 insertions, 20 deletions
diff --git a/src/cpu/amd/car/disable_cache_as_ram.c b/src/cpu/amd/car/disable_cache_as_ram.c index ae295d33ee..e8d5af8047 100644 --- a/src/cpu/amd/car/disable_cache_as_ram.c +++ b/src/cpu/amd/car/disable_cache_as_ram.c @@ -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); + + /* Set the default memory type and disable fixed and enable variable MTRRs */ + msr.hi = 0; + msr.lo = (1 << 11); - msr = rdmsr(SYSCFG_MSR); - msr.lo &= ~(SYSCFG_MSR_MtrrFixDramEn | SYSCFG_MSR_MtrrFixDramModEn); - wrmsr(SYSCFG_MSR, msr); + wrmsr(MTRR_DEF_TYPE_MSR, msr); - /* Set the default memory type and disable fixed and enable variable MTRRs */ - msr.hi = 0; - msr.lo = (1 << 11); + enable_cache(); + } - wrmsr(MTRR_DEF_TYPE_MSR, msr); + /* INVDWBINVD = 1 */ + msr = rdmsr(0xc0010015); + msr.lo |= (0x1 << 4); + wrmsr(0xc0010015, msr); - enable_cache(); + 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); } |