aboutsummaryrefslogtreecommitdiff
path: root/src/cpu/amd/car/disable_cache_as_ram.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/amd/car/disable_cache_as_ram.c')
-rw-r--r--src/cpu/amd/car/disable_cache_as_ram.c89
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);
}