blob: 6c7ba5fffe0db07780a260e6ce645a63f7b21eda [file] [log] [blame]
Angel Pons8a3453f2020-04-02 23:48:19 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Kyösti Mälkki5fdb95e2015-01-01 17:51:51 +02002
3#include <stdint.h>
4#include <cpu/x86/msr.h>
5#include <cpu/x86/mtrr.h>
6#include <cpu/amd/mtrr.h>
7#include <cpu/x86/cache.h>
8#include <string.h>
Kyösti Mälkkid4955f02017-09-08 07:14:17 +03009#include <northbridge/amd/agesa/agesa_helper.h>
Kyösti Mälkki5fdb95e2015-01-01 17:51:51 +020010
Martin Roth38ddbfb2019-10-23 21:41:00 -060011static void write_mtrr(u8 **p_nvram_pos, unsigned int idx)
Kyösti Mälkki5fdb95e2015-01-01 17:51:51 +020012{
13 msr_t msr_data;
14 msr_data = rdmsr(idx);
15
16 memcpy(*p_nvram_pos, &msr_data, sizeof(msr_data));
17 *p_nvram_pos += sizeof(msr_data);
18}
19
20void backup_mtrr(void *mtrr_store, u32 *mtrr_store_size)
21{
22 u8 *nvram_pos = mtrr_store;
23 msr_t msr_data;
24 u32 i;
25
26 /* Enable access to AMD RdDram and WrDram extension bits */
27 msr_data = rdmsr(SYSCFG_MSR);
28 msr_data.lo |= SYSCFG_MSR_MtrrFixDramModEn;
29 wrmsr(SYSCFG_MSR, msr_data);
30
31 /* Fixed MTRRs */
Elyes HAOUASd50cf232018-10-17 20:18:17 +020032 write_mtrr(&nvram_pos, MTRR_FIX_64K_00000);
33 write_mtrr(&nvram_pos, MTRR_FIX_16K_80000);
34 write_mtrr(&nvram_pos, MTRR_FIX_16K_A0000);
Kyösti Mälkki5fdb95e2015-01-01 17:51:51 +020035
Elyes HAOUASd50cf232018-10-17 20:18:17 +020036 for (i = MTRR_FIX_4K_C0000; i <= MTRR_FIX_4K_F8000; i++)
Kyösti Mälkki5fdb95e2015-01-01 17:51:51 +020037 write_mtrr(&nvram_pos, i);
38
39 /* Disable access to AMD RdDram and WrDram extension bits */
40 msr_data = rdmsr(SYSCFG_MSR);
41 msr_data.lo &= ~SYSCFG_MSR_MtrrFixDramModEn;
42 wrmsr(SYSCFG_MSR, msr_data);
43
44 /* Variable MTRRs */
Elyes HAOUASd50cf232018-10-17 20:18:17 +020045 for (i = MTRR_PHYS_BASE(0); i < MTRR_PHYS_BASE(8); i++)
Kyösti Mälkki5fdb95e2015-01-01 17:51:51 +020046 write_mtrr(&nvram_pos, i);
47
48 /* SYSCFG_MSR */
49 write_mtrr(&nvram_pos, SYSCFG_MSR);
50 /* TOM */
Elyes HAOUAS8a643702018-10-23 17:10:27 +020051 write_mtrr(&nvram_pos, TOP_MEM);
Kyösti Mälkki5fdb95e2015-01-01 17:51:51 +020052 /* TOM2 */
Elyes HAOUAS8a643702018-10-23 17:10:27 +020053 write_mtrr(&nvram_pos, TOP_MEM2);
Kyösti Mälkki5fdb95e2015-01-01 17:51:51 +020054
55 *mtrr_store_size = nvram_pos - (u8*) mtrr_store;
56}
57
58void restore_mtrr(void)
59{
60 volatile u32 *msrPtr = (u32 *) OemS3Saved_MTRR_Storage();
61 u32 msr;
62 msr_t msr_data;
63
64 if (!msrPtr)
65 return;
66
67 disable_cache();
68
69 /* Enable access to AMD RdDram and WrDram extension bits */
70 msr_data = rdmsr(SYSCFG_MSR);
71 msr_data.lo |= SYSCFG_MSR_MtrrFixDramModEn;
72 wrmsr(SYSCFG_MSR, msr_data);
73
74 /* Now restore the Fixed MTRRs */
75 msr_data.lo = *msrPtr;
76 msrPtr ++;
77 msr_data.hi = *msrPtr;
78 msrPtr ++;
Elyes HAOUASd50cf232018-10-17 20:18:17 +020079 wrmsr(MTRR_FIX_64K_00000, msr_data);
Kyösti Mälkki5fdb95e2015-01-01 17:51:51 +020080
81 msr_data.lo = *msrPtr;
82 msrPtr ++;
83 msr_data.hi = *msrPtr;
84 msrPtr ++;
Elyes HAOUASd50cf232018-10-17 20:18:17 +020085 wrmsr(MTRR_FIX_16K_80000, msr_data);
Kyösti Mälkki5fdb95e2015-01-01 17:51:51 +020086
87 msr_data.lo = *msrPtr;
88 msrPtr ++;
89 msr_data.hi = *msrPtr;
90 msrPtr ++;
Elyes HAOUASd50cf232018-10-17 20:18:17 +020091 wrmsr(MTRR_FIX_16K_A0000, msr_data);
Kyösti Mälkki5fdb95e2015-01-01 17:51:51 +020092
Elyes HAOUASd50cf232018-10-17 20:18:17 +020093 for (msr = MTRR_FIX_4K_C0000; msr <= MTRR_FIX_4K_F8000; msr++) {
Kyösti Mälkki5fdb95e2015-01-01 17:51:51 +020094 msr_data.lo = *msrPtr;
95 msrPtr ++;
96 msr_data.hi = *msrPtr;
97 msrPtr ++;
98 wrmsr(msr, msr_data);
99 }
100
101 /* Disable access to AMD RdDram and WrDram extension bits */
102 msr_data = rdmsr(SYSCFG_MSR);
103 msr_data.lo &= ~SYSCFG_MSR_MtrrFixDramModEn;
104 wrmsr(SYSCFG_MSR, msr_data);
105
106 /* Restore the Variable MTRRs */
Elyes HAOUASd50cf232018-10-17 20:18:17 +0200107 for (msr = MTRR_PHYS_BASE(0); msr <= MTRR_PHYS_MASK(7); msr++) {
Kyösti Mälkki5fdb95e2015-01-01 17:51:51 +0200108 msr_data.lo = *msrPtr;
109 msrPtr ++;
110 msr_data.hi = *msrPtr;
111 msrPtr ++;
112 wrmsr(msr, msr_data);
113 }
114
115 /* Restore SYSCFG MTRR */
116 msr_data.lo = *msrPtr;
117 msrPtr ++;
118 msr_data.hi = *msrPtr;
119 msrPtr ++;
120 wrmsr(SYSCFG_MSR, msr_data);
121}