blob: 26b20dcfd47927faa12aa0e5c61fb1feda9b064a [file] [log] [blame]
zbao2c08f6a2012-07-02 15:32:58 +08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2012 Advanced Micro Devices, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
zbao2c08f6a2012-07-02 15:32:58 +080014 */
15
16#include <console/console.h>
17#include <cpu/x86/msr.h>
Elyes HAOUAS400ce552018-10-12 10:54:30 +020018#include <cpu/amd/msr.h>
19#include <cpu/x86/mtrr.h>
zbao2c08f6a2012-07-02 15:32:58 +080020#include <cpu/amd/mtrr.h>
Elyes HAOUAS400ce552018-10-12 10:54:30 +020021#include <cpu/x86/smm.h>
zbao2c08f6a2012-07-02 15:32:58 +080022#include <device/device.h>
zbao2c08f6a2012-07-02 15:32:58 +080023#include <string.h>
zbao2c08f6a2012-07-02 15:32:58 +080024#include <cpu/x86/pae.h>
zbao2c08f6a2012-07-02 15:32:58 +080025#include <cpu/x86/lapic.h>
zbao2c08f6a2012-07-02 15:32:58 +080026#include <cpu/cpu.h>
27#include <cpu/x86/cache.h>
zbao2c08f6a2012-07-02 15:32:58 +080028#include <arch/acpi.h>
Kyösti Mälkkid4955f02017-09-08 07:14:17 +030029#include <northbridge/amd/agesa/agesa_helper.h>
zbao2c08f6a2012-07-02 15:32:58 +080030
Elyes HAOUASd2d8a312018-02-08 13:38:21 +010031static void model_15_init(struct device *dev)
zbao2c08f6a2012-07-02 15:32:58 +080032{
33 printk(BIOS_DEBUG, "Model 15 Init.\n");
34
35 u8 i;
36 msr_t msr;
Marshall Dawsonbd4a3f82018-08-07 07:27:57 -060037 int num_banks;
zbao2c08f6a2012-07-02 15:32:58 +080038 int msrno;
Alexandru Gagniuc53072d82014-04-12 21:57:18 -050039 unsigned int cpu_idx;
Julius Wernercd49cce2019-03-05 16:53:33 -080040#if CONFIG(LOGICAL_CPUS)
zbao2c08f6a2012-07-02 15:32:58 +080041 u32 siblings;
42#endif
43
44 //x86_enable_cache();
45 //amd_setup_mtrrs();
46 //x86_mtrr_check();
Elyes HAOUAS12d65f82018-01-28 22:35:47 +010047 disable_cache();
zbao2c08f6a2012-07-02 15:32:58 +080048 /* Enable access to AMD RdDram and WrDram extension bits */
49 msr = rdmsr(SYSCFG_MSR);
50 msr.lo |= SYSCFG_MSR_MtrrFixDramModEn;
51 msr.lo &= ~SYSCFG_MSR_MtrrFixDramEn;
52 wrmsr(SYSCFG_MSR, msr);
53
54 // BSP: make a0000-bffff UC, c0000-fffff WB, same as OntarioApMtrrSettingsList for APs
55 msr.lo = msr.hi = 0;
Elyes HAOUASd50cf232018-10-17 20:18:17 +020056 wrmsr(MTRR_FIX_16K_A0000, msr);
zbao2c08f6a2012-07-02 15:32:58 +080057 msr.lo = msr.hi = 0x1e1e1e1e;
Elyes HAOUASd50cf232018-10-17 20:18:17 +020058 wrmsr(MTRR_FIX_64K_00000, msr);
59 wrmsr(MTRR_FIX_16K_80000, msr);
60 for (msrno = MTRR_FIX_4K_C0000; msrno <= MTRR_FIX_4K_F8000; msrno++)
61 wrmsr(msrno, msr);
zbao2c08f6a2012-07-02 15:32:58 +080062
63 msr = rdmsr(SYSCFG_MSR);
64 msr.lo &= ~SYSCFG_MSR_MtrrFixDramModEn;
65 msr.lo |= SYSCFG_MSR_MtrrFixDramEn;
66 wrmsr(SYSCFG_MSR, msr);
67
Kyösti Mälkki9107e532014-06-19 20:52:39 +030068 if (acpi_is_wakeup())
zbao2c08f6a2012-07-02 15:32:58 +080069 restore_mtrr();
zbao2c08f6a2012-07-02 15:32:58 +080070
71 x86_mtrr_check();
72 x86_enable_cache();
73
74 /* zero the machine check error status registers */
Elyes HAOUAS400ce552018-10-12 10:54:30 +020075 msr = rdmsr(IA32_MCG_CAP);
Marshall Dawsonbd4a3f82018-08-07 07:27:57 -060076 num_banks = msr.lo & MCA_BANKS_MASK;
zbao2c08f6a2012-07-02 15:32:58 +080077 msr.lo = 0;
78 msr.hi = 0;
Marshall Dawsonbd4a3f82018-08-07 07:27:57 -060079 for (i = 0; i < num_banks; i++)
Elyes HAOUAS400ce552018-10-12 10:54:30 +020080 wrmsr(IA32_MC0_STATUS + (i * 4), msr);
zbao2c08f6a2012-07-02 15:32:58 +080081
Elyes HAOUASd6e96862016-08-21 10:12:15 +020082 /* Enable the local CPU APICs */
zbao2c08f6a2012-07-02 15:32:58 +080083 setup_lapic();
84
Julius Wernercd49cce2019-03-05 16:53:33 -080085#if CONFIG(LOGICAL_CPUS)
zbao2c08f6a2012-07-02 15:32:58 +080086 siblings = cpuid_ecx(0x80000008) & 0xff;
87
88 if (siblings > 0) {
89 msr = rdmsr_amd(CPU_ID_FEATURES_MSR);
90 msr.lo |= 1 << 28;
91 wrmsr_amd(CPU_ID_FEATURES_MSR, msr);
92
93 msr = rdmsr_amd(CPU_ID_EXT_FEATURES_MSR);
94 msr.hi |= 1 << (33 - 32);
95 wrmsr_amd(CPU_ID_EXT_FEATURES_MSR, msr);
96 }
97 printk(BIOS_DEBUG, "siblings = %02d, ", siblings);
98#endif
99
100 /* DisableCf8ExtCfg */
101 msr = rdmsr(NB_CFG_MSR);
102 msr.hi &= ~(1 << (46 - 32));
103 wrmsr(NB_CFG_MSR, msr);
104
Julius Wernercd49cce2019-03-05 16:53:33 -0800105 if (CONFIG(HAVE_SMI_HANDLER)) {
Alexandru Gagniuc53072d82014-04-12 21:57:18 -0500106 cpu_idx = cpu_info()->index;
107 printk(BIOS_INFO, "Initializing SMM for CPU %u\n", cpu_idx);
108
109 /* Set SMM base address for this CPU */
Elyes HAOUAS400ce552018-10-12 10:54:30 +0200110 msr = rdmsr(SMM_BASE_MSR);
Alexandru Gagniuc53072d82014-04-12 21:57:18 -0500111 msr.lo = SMM_BASE - (cpu_idx * 0x400);
Elyes HAOUAS400ce552018-10-12 10:54:30 +0200112 wrmsr(SMM_BASE_MSR, msr);
Alexandru Gagniuc53072d82014-04-12 21:57:18 -0500113
114 /* Enable the SMM memory window */
Elyes HAOUAS400ce552018-10-12 10:54:30 +0200115 msr = rdmsr(SMM_MASK_MSR);
Alexandru Gagniuc53072d82014-04-12 21:57:18 -0500116 msr.lo |= (1 << 0); /* Enable ASEG SMRAM Range */
Elyes HAOUAS400ce552018-10-12 10:54:30 +0200117 wrmsr(SMM_MASK_MSR, msr);
Alexandru Gagniuc53072d82014-04-12 21:57:18 -0500118 }
zbao2c08f6a2012-07-02 15:32:58 +0800119
120 /* Write protect SMM space with SMMLOCK. */
121 msr = rdmsr(HWCR_MSR);
122 msr.lo |= (1 << 0);
123 wrmsr(HWCR_MSR, msr);
124}
125
126static struct device_operations cpu_dev_ops = {
127 .init = model_15_init,
128};
129
Jonathan Neuschäfer8f06ce32017-11-20 01:56:44 +0100130static const struct cpu_device_id cpu_table[] = {
Paul Menzel22f32c72017-02-27 01:26:42 +0100131 { X86_VENDOR_AMD, 0x610f00 }, /* TN-A0 */
132 { X86_VENDOR_AMD, 0x610f31 }, /* RL-A1 (Richland) */
zbao2c08f6a2012-07-02 15:32:58 +0800133 { 0, 0 },
134};
135
136static const struct cpu_driver model_15 __cpu_driver = {
137 .ops = &cpu_dev_ops,
138 .id_table = cpu_table,
139};