blob: 8812dd9bd74db423dcec43d23505f58d6476fe19 [file] [log] [blame]
Zheng Baoeb75f652010-04-23 17:32:48 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2010 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.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include "mct_d.h"
21
22static void SetMTRRrangeWB_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr);
23static void SetMTRRrange_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr, u16 MtrrType);
24
25void CPUMemTyping_D(struct MCTStatStruc *pMCTstat,
26 struct DCTStatStruc *pDCTstatA)
27{
28 /* BSP only. Set the fixed MTRRs for common legacy ranges.
29 * Set TOP_MEM and TOM2.
30 * Set some variable MTRRs with WB Uncacheable type.
31 */
32
33 u32 Bottom32bIO, Bottom40bIO, Cache32bTOP;
34 u32 val;
35 u32 addr;
36 u32 lo, hi;
37
38 /* Set temporary top of memory from Node structure data.
Zheng Bao53b52f32010-10-09 07:18:50 +000039 * Adjust temp top of memory down to accommodate 32-bit IO space.
Zheng Baoeb75f652010-04-23 17:32:48 +000040 * Bottom40bIO=top of memory, right justified 8 bits
41 * (defines dram versus IO space type)
42 * Bottom32bIO=sub 4GB top of memory, right justified 8 bits
43 * (defines dram versus IO space type)
44 * Cache32bTOP=sub 4GB top of WB cacheable memory,
45 * right justified 8 bits
46 */
47
48 val = mctGet_NVbits(NV_BottomIO);
49 if(val == 0)
50 val++;
51
52 Bottom32bIO = val << (24-8);
53
54 val = pMCTstat->SysLimit + 1;
55 if(val <= _4GB_RJ8) {
56 Bottom40bIO = 0;
57 if(Bottom32bIO >= val)
58 Bottom32bIO = val;
59 } else {
60 Bottom40bIO = val;
61 }
62
63 Cache32bTOP = Bottom32bIO;
64
65 /*======================================================================
66 Set default values for CPU registers
67 ======================================================================*/
68
69 /* NOTE : For coreboot, we don't need to set mtrr enables here because
70 they are still enable from cache_as_ram.inc */
71
72 addr = 0x250;
73 lo = 0x1E1E1E1E;
74 hi = lo;
75 _WRMSR(addr, lo, hi); /* 0 - 512K = WB Mem */
76 addr = 0x258;
77 _WRMSR(addr, lo, hi); /* 512K - 640K = WB Mem */
78
79 /*======================================================================
80 Set variable MTRR values
81 ======================================================================*/
82 /* NOTE: for coreboot change from 0x200 to 0x204: coreboot is using
83 0x200, 0x201 for [1M, CONFIG_TOP_MEM)
84 0x202, 0x203 for ROM Caching
85 */
86 addr = 0x204; /* MTRR phys base 2*/
87 /* use TOP_MEM as limit*/
88 /* Limit=TOP_MEM|TOM2*/
89 /* Base=0*/
90 printk(BIOS_DEBUG, "\t CPUMemTyping: Cache32bTOP:%x\n", Cache32bTOP);
91 SetMTRRrangeWB_D(0, &Cache32bTOP, &addr);
92 /* Base */
93 /* Limit */
94 /* MtrrAddr */
95 if(addr == -1) /* ran out of MTRRs?*/
96 pMCTstat->GStatus |= 1<<GSB_MTRRshort;
97
98 pMCTstat->Sub4GCacheTop = Cache32bTOP<<8;
99
100 /*======================================================================
101 Set TOP_MEM and TOM2 CPU registers
102 ======================================================================*/
103 addr = TOP_MEM;
104 lo = Bottom32bIO<<8;
105 hi = Bottom32bIO>>24;
106 _WRMSR(addr, lo, hi);
107 printk(BIOS_DEBUG, "\t CPUMemTyping: Bottom32bIO:%x\n", Bottom32bIO);
108 printk(BIOS_DEBUG, "\t CPUMemTyping: Bottom40bIO:%x\n", Bottom40bIO);
109 if(Bottom40bIO) {
110 hi = Bottom40bIO >> 24;
111 lo = Bottom40bIO << 8;
112 addr += 3; /* TOM2 */
113 _WRMSR(addr, lo, hi);
114 }
115 addr = 0xC0010010; /* SYS_CFG */
116 _RDMSR(addr, &lo, &hi);
117 if(Bottom40bIO) {
118 lo |= (1<<21); /* MtrrTom2En=1 */
119 lo |= (1<<22); /* Tom2ForceMemTypeWB */
120 } else {
121 lo &= ~(1<<21); /* MtrrTom2En=0 */
122 lo &= ~(1<<22); /* Tom2ForceMemTypeWB */
123 }
124 _WRMSR(addr, lo, hi);
125}
126
127static void SetMTRRrangeWB_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr)
128{
129 /*set WB type*/
130 SetMTRRrange_D(Base, pLimit, pMtrrAddr, 6);
131}
132
133static void SetMTRRrange_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr, u16 MtrrType)
134{
135 /* Program MTRRs to describe given range as given cache type.
136 * Use MTRR pairs starting with the given MTRRphys Base address,
137 * and use as many as is required up to (excluding) MSR 020C, which
138 * is reserved for OS.
139 *
140 * "Limit" in the context of this procedure is not the numerically
141 * correct limit, but rather the Last address+1, for purposes of coding
142 * efficiency and readability. Size of a region is then Limit-Base.
143 *
144 * 1. Size of each range must be a power of two
145 * 2. Each range must be naturally aligned (Base is same as size)
146 *
147 * There are two code paths: the ascending path and descending path
Zheng Bao53b52f32010-10-09 07:18:50 +0000148 * (analogous to bsf and bsr), where the next limit is a function of the
Zheng Baoeb75f652010-04-23 17:32:48 +0000149 * next set bit in a forward or backward sequence of bits (as a function
150 * of the Limit). We start with the ascending path, to ensure that
151 * regions are naturally aligned, then we switch to the descending path
152 * to maximize MTRR usage efficiency. Base=0 is a special case where we
153 * start with the descending path. Correct Mask for region is
154 * 2comp(Size-1)-1, which is 2comp(Limit-Base-1)-1
155 */
156
157 u32 curBase, curLimit, curSize;
158 u32 val, valx;
159 u32 addr;
160
161 val = curBase = Base;
162 curLimit = *pLimit;
163 addr = *pMtrrAddr;
164 while((addr >= 0x200) && (addr < 0x20C) && (val < *pLimit)) {
165 /* start with "ascending" code path */
166 /* alignment (largest block size)*/
167 valx = 1 << bsf(curBase);
168 curSize = valx;
169
170 /* largest legal limit, given current non-zero range Base*/
171 valx += curBase;
172 if((curBase == 0) || (*pLimit < valx)) {
173 /* flop direction to "descending" code path*/
174 valx = 1<<bsr(*pLimit - curBase);
175 curSize = valx;
176 valx += curBase;
177 }
178 curLimit = valx; /*eax=curBase, edx=curLimit*/
179 valx = val>>24;
180 val <<= 8;
181
182 /* now program the MTRR */
183 val |= MtrrType; /* set cache type (UC or WB)*/
184 _WRMSR(addr, val, valx); /* prog. MTRR with current region Base*/
185 val = ((~(curSize - 1))+1) - 1; /* Size-1*/ /*Mask=2comp(Size-1)-1*/
186 valx = (val >> 24) | (0xff00); /* GH have 48 bits addr */
187 val <<= 8;
188 val |= ( 1 << 11); /* set MTRR valid*/
189 addr++;
190 _WRMSR(addr, val, valx); /* prog. MTRR with current region Mask*/
191 val = curLimit;
192 curBase = val; /* next Base = current Limit (loop exit)*/
193 addr++; /* next MTRR pair addr */
194 }
195 if(val < *pLimit) {
196 *pLimit = val;
197 addr = -1;
198 }
199 *pMtrrAddr = addr;
200}
201
202void UMAMemTyping_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
203{
204/* UMA memory size may need splitting the MTRR configuration into two
205 Before training use NB_BottomIO or the physical memory size to set the MTRRs.
206 After training, add UMAMemTyping function to reconfigure the MTRRs based on
207 NV_BottomUMA (for UMA systems only).
208 This two-step process allows all memory to be cached for training
209*/
210 u32 Bottom32bIO, Cache32bTOP;
211 u32 val;
212 u32 addr;
213 u32 lo, hi;
214
215 /*======================================================================
Zheng Bao53b52f32010-10-09 07:18:50 +0000216 * Adjust temp top of memory down to accommodate UMA memory start
Zheng Baoeb75f652010-04-23 17:32:48 +0000217 *======================================================================*/
218 /* Bottom32bIO=sub 4GB top of memory, right justified 8 bits
219 * (defines dram versus IO space type)
220 * Cache32bTOP=sub 4GB top of WB cacheable memory, right justified 8 bits */
221
222 Bottom32bIO = pMCTstat->Sub4GCacheTop >> 8;
223
224 val = mctGet_NVbits(NV_BottomUMA);
225 if (val == 0)
226 val++;
227
228 val <<= (24-8);
229 if (val < Bottom32bIO) {
230 Cache32bTOP = val;
231 pMCTstat->Sub4GCacheTop = val;
232
233 /*======================================================================
234 * Clear variable MTRR values
235 *======================================================================*/
236 addr = 0x200;
237 lo = 0;
238 hi = lo;
239 while( addr < 0x20C) {
240 _WRMSR(addr, lo, hi); /* prog. MTRR with current region Mask */
241 addr++; /* next MTRR pair addr */
242 }
243
244 /*======================================================================
245 * Set variable MTRR values
246 *======================================================================*/
247 printk(BIOS_DEBUG, "\t UMAMemTyping_D: Cache32bTOP:%x\n", Cache32bTOP);
248 SetMTRRrangeWB_D(0, &Cache32bTOP, &addr);
249 if(addr == -1) /* ran out of MTRRs?*/
250 pMCTstat->GStatus |= 1<<GSB_MTRRshort;
251 }
252}