blob: c039abefb6c4ecb6e4cd1ce8a6a997d7c0221b5e [file] [log] [blame]
Kyösti Mälkki5fdb95e2015-01-01 17:51:51 +02001/*
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.
Kyösti Mälkki5fdb95e2015-01-01 17:51:51 +020014 */
15
16#include <stdint.h>
17#include <cpu/x86/msr.h>
18#include <cpu/x86/mtrr.h>
19#include <cpu/amd/mtrr.h>
20#include <cpu/x86/cache.h>
21#include <string.h>
Kyösti Mälkkid4955f02017-09-08 07:14:17 +030022#include <northbridge/amd/agesa/agesa_helper.h>
Kyösti Mälkki5fdb95e2015-01-01 17:51:51 +020023
24static void write_mtrr(u8 **p_nvram_pos, unsigned idx)
25{
26 msr_t msr_data;
27 msr_data = rdmsr(idx);
28
29 memcpy(*p_nvram_pos, &msr_data, sizeof(msr_data));
30 *p_nvram_pos += sizeof(msr_data);
31}
32
33void backup_mtrr(void *mtrr_store, u32 *mtrr_store_size)
34{
35 u8 *nvram_pos = mtrr_store;
36 msr_t msr_data;
37 u32 i;
38
39 /* Enable 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 /* Fixed MTRRs */
45 write_mtrr(&nvram_pos, 0x250);
46 write_mtrr(&nvram_pos, 0x258);
47 write_mtrr(&nvram_pos, 0x259);
48
49 for (i = 0x268; i < 0x270; i++)
50 write_mtrr(&nvram_pos, i);
51
52 /* Disable access to AMD RdDram and WrDram extension bits */
53 msr_data = rdmsr(SYSCFG_MSR);
54 msr_data.lo &= ~SYSCFG_MSR_MtrrFixDramModEn;
55 wrmsr(SYSCFG_MSR, msr_data);
56
57 /* Variable MTRRs */
58 for (i = 0x200; i < 0x210; i++)
59 write_mtrr(&nvram_pos, i);
60
61 /* SYSCFG_MSR */
62 write_mtrr(&nvram_pos, SYSCFG_MSR);
63 /* TOM */
64 write_mtrr(&nvram_pos, 0xC001001A);
65 /* TOM2 */
66 write_mtrr(&nvram_pos, 0xC001001D);
67
68 *mtrr_store_size = nvram_pos - (u8*) mtrr_store;
69}
70
71void restore_mtrr(void)
72{
73 volatile u32 *msrPtr = (u32 *) OemS3Saved_MTRR_Storage();
74 u32 msr;
75 msr_t msr_data;
76
77 if (!msrPtr)
78 return;
79
80 disable_cache();
81
82 /* Enable access to AMD RdDram and WrDram extension bits */
83 msr_data = rdmsr(SYSCFG_MSR);
84 msr_data.lo |= SYSCFG_MSR_MtrrFixDramModEn;
85 wrmsr(SYSCFG_MSR, msr_data);
86
87 /* Now restore the Fixed MTRRs */
88 msr_data.lo = *msrPtr;
89 msrPtr ++;
90 msr_data.hi = *msrPtr;
91 msrPtr ++;
92 wrmsr(0x250, msr_data);
93
94 msr_data.lo = *msrPtr;
95 msrPtr ++;
96 msr_data.hi = *msrPtr;
97 msrPtr ++;
98 wrmsr(0x258, msr_data);
99
100 msr_data.lo = *msrPtr;
101 msrPtr ++;
102 msr_data.hi = *msrPtr;
103 msrPtr ++;
104 wrmsr(0x259, msr_data);
105
106 for (msr = 0x268; msr <= 0x26F; msr++) {
107 msr_data.lo = *msrPtr;
108 msrPtr ++;
109 msr_data.hi = *msrPtr;
110 msrPtr ++;
111 wrmsr(msr, msr_data);
112 }
113
114 /* Disable access to AMD RdDram and WrDram extension bits */
115 msr_data = rdmsr(SYSCFG_MSR);
116 msr_data.lo &= ~SYSCFG_MSR_MtrrFixDramModEn;
117 wrmsr(SYSCFG_MSR, msr_data);
118
119 /* Restore the Variable MTRRs */
120 for (msr = 0x200; msr <= 0x20F; msr++) {
121 msr_data.lo = *msrPtr;
122 msrPtr ++;
123 msr_data.hi = *msrPtr;
124 msrPtr ++;
125 wrmsr(msr, msr_data);
126 }
127
128 /* Restore SYSCFG MTRR */
129 msr_data.lo = *msrPtr;
130 msrPtr ++;
131 msr_data.hi = *msrPtr;
132 msrPtr ++;
133 wrmsr(SYSCFG_MSR, msr_data);
134}