2 * This file is part of the coreboot project.
4 * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
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.
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.
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
22 #include <cpu/amd/mtrr.h>
24 static void SetMTRRrangeWB_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr);
25 static void SetMTRRrange_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr, u16 MtrrType);
27 void CPUMemTyping_D(struct MCTStatStruc *pMCTstat,
28 struct DCTStatStruc *pDCTstatA)
30 /* BSP only. Set the fixed MTRRs for common legacy ranges.
31 * Set TOP_MEM and TOM2.
32 * Set some variable MTRRs with WB Uncacheable type.
35 u32 Bottom32bIO, Bottom40bIO, Cache32bTOP;
40 /* Set temporary top of memory from Node structure data.
41 * Adjust temp top of memory down to accommodate 32-bit IO space.
42 * Bottom40bIO=top of memory, right justified 8 bits
43 * (defines dram versus IO space type)
44 * Bottom32bIO=sub 4GB top of memory, right justified 8 bits
45 * (defines dram versus IO space type)
46 * Cache32bTOP=sub 4GB top of WB cacheable memory,
47 * right justified 8 bits
50 val = mctGet_NVbits(NV_BottomIO);
54 Bottom32bIO = val << (24-8);
56 val = pMCTstat->SysLimit + 1;
59 if(Bottom32bIO >= val)
65 Cache32bTOP = Bottom32bIO;
67 /*======================================================================
68 Set default values for CPU registers
69 ======================================================================*/
71 /* NOTE : For coreboot, we don't need to set mtrr enables here because
72 they are still enable from cache_as_ram.inc */
77 _WRMSR(addr, lo, hi); /* 0 - 512K = WB Mem */
79 _WRMSR(addr, lo, hi); /* 512K - 640K = WB Mem */
81 /*======================================================================
82 Set variable MTRR values
83 ======================================================================*/
84 /* NOTE: for coreboot change from 0x200 to 0x204: coreboot is using
85 0x200, 0x201 for [1M, CONFIG_TOP_MEM)
86 0x202, 0x203 for ROM Caching
88 addr = 0x204; /* MTRR phys base 2*/
89 /* use TOP_MEM as limit*/
90 /* Limit=TOP_MEM|TOM2*/
92 print_tx("\t CPUMemTyping: Cache32bTOP:", Cache32bTOP);
93 SetMTRRrangeWB_D(0, &Cache32bTOP, &addr);
97 if(addr == -1) /* ran out of MTRRs?*/
98 pMCTstat->GStatus |= 1<<GSB_MTRRshort;
100 pMCTstat->Sub4GCacheTop = Cache32bTOP<<8;
102 /*======================================================================
103 Set TOP_MEM and TOM2 CPU registers
104 ======================================================================*/
107 hi = Bottom32bIO>>24;
108 _WRMSR(addr, lo, hi);
109 print_tx("\t CPUMemTyping: Bottom32bIO:", Bottom32bIO);
110 print_tx("\t CPUMemTyping: Bottom40bIO:", Bottom40bIO);
112 hi = Bottom40bIO >> 24;
113 lo = Bottom40bIO << 8;
114 if (mctSetNodeBoundary_D())
116 addr += 3; /* TOM2 */
117 _WRMSR(addr, lo, hi);
119 addr = 0xC0010010; /* SYS_CFG */
120 _RDMSR(addr, &lo, &hi);
122 lo |= (1<<21); /* MtrrTom2En=1 */
123 lo |= (1<<22); /* Tom2ForceMemTypeWB */
125 lo &= ~(1<<21); /* MtrrTom2En=0 */
126 lo &= ~(1<<22); /* Tom2ForceMemTypeWB */
128 _WRMSR(addr, lo, hi);
132 static void SetMTRRrangeWB_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr)
135 SetMTRRrange_D(Base, pLimit, pMtrrAddr, 6);
139 static void SetMTRRrange_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr, u16 MtrrType)
141 /* Program MTRRs to describe given range as given cache type.
142 * Use MTRR pairs starting with the given MTRRphys Base address,
143 * and use as many as is required up to (excluding) MSR 020C, which
144 * is reserved for OS.
146 * "Limit" in the context of this procedure is not the numerically
147 * correct limit, but rather the Last address+1, for purposes of coding
148 * efficiency and readability. Size of a region is then Limit-Base.
150 * 1. Size of each range must be a power of two
151 * 2. Each range must be naturally aligned (Base is same as size)
153 * There are two code paths: the ascending path and descending path
154 * (analogous to bsf and bsr), where the next limit is a function of the
155 * next set bit in a forward or backward sequence of bits (as a function
156 * of the Limit). We start with the ascending path, to ensure that
157 * regions are naturally aligned, then we switch to the descending path
158 * to maximize MTRR usage efficiency. Base=0 is a special case where we
159 * start with the descending path. Correct Mask for region is
160 * 2comp(Size-1)-1, which is 2comp(Limit-Base-1)-1
163 u32 curBase, curLimit, curSize;
167 val = curBase = Base;
170 while((addr >= 0x200) && (addr < 0x20C) && (val < *pLimit)) {
171 /* start with "ascending" code path */
172 /* alignment (largest block size)*/
173 valx = 1 << bsf(curBase);
176 /* largest legal limit, given current non-zero range Base*/
178 if((curBase == 0) || (*pLimit < valx)) {
179 /* flop direction to "descending" code path*/
180 valx = 1<<bsr(*pLimit - curBase);
184 curLimit = valx; /*eax=curBase, edx=curLimit*/
188 /* now program the MTRR */
189 val |= MtrrType; /* set cache type (UC or WB)*/
190 _WRMSR(addr, val, valx); /* prog. MTRR with current region Base*/
191 val = ((~(curSize - 1))+1) - 1; /* Size-1*/ /*Mask=2comp(Size-1)-1*/
192 valx = (val >> 24) | (0xff00); /* GH have 48 bits addr */
194 val |= ( 1 << 11); /* set MTRR valid*/
196 _WRMSR(addr, val, valx); /* prog. MTRR with current region Mask*/
198 curBase = val; /* next Base = current Limit (loop exit)*/
199 addr++; /* next MTRR pair addr */
208 void UMAMemTyping_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
210 /* UMA memory size may need splitting the MTRR configuration into two
211 Before training use NB_BottomIO or the physical memory size to set the MTRRs.
212 After training, add UMAMemTyping function to reconfigure the MTRRs based on
213 NV_BottomUMA (for UMA systems only).
214 This two-step process allows all memory to be cached for training
216 u32 Bottom32bIO, Cache32bTOP;
221 /*======================================================================
222 * Adjust temp top of memory down to accommodate UMA memory start
223 *======================================================================*/
224 /* Bottom32bIO=sub 4GB top of memory, right justified 8 bits
225 * (defines dram versus IO space type)
226 * Cache32bTOP=sub 4GB top of WB cacheable memory, right justified 8 bits */
228 Bottom32bIO = pMCTstat->Sub4GCacheTop >> 8;
230 val = mctGet_NVbits(NV_BottomUMA);
235 if (val < Bottom32bIO) {
237 pMCTstat->Sub4GCacheTop = val;
239 /*======================================================================
240 * Clear variable MTRR values
241 *======================================================================*/
245 while( addr < 0x20C) {
246 _WRMSR(addr, lo, hi); /* prog. MTRR with current region Mask */
247 addr++; /* next MTRR pair addr */
250 /*======================================================================
251 * Set variable MTRR values
252 *======================================================================*/
253 print_tx("\t UMAMemTyping_D: Cache32bTOP:", Cache32bTOP);
254 SetMTRRrangeWB_D(0, &Cache32bTOP, &addr);
255 if(addr == -1) /* ran out of MTRRs?*/
256 pMCTstat->GStatus |= 1<<GSB_MTRRshort;