tree: drop last paragraph of GPL copyright header
[coreboot.git] / src / northbridge / amd / amdmct / mct / mctmtr_d.c
blob06c642a8654e776cc625a9a7a557a0ec4b632ad8
1 /*
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.
17 #include "mct_d.h"
18 #include <cpu/amd/mtrr.h>
20 static void SetMTRRrangeWB_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr);
21 static void SetMTRRrange_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr, u16 MtrrType);
23 void CPUMemTyping_D(struct MCTStatStruc *pMCTstat,
24 struct DCTStatStruc *pDCTstatA)
26 /* BSP only. Set the fixed MTRRs for common legacy ranges.
27 * Set TOP_MEM and TOM2.
28 * Set some variable MTRRs with WB Uncacheable type.
31 u32 Bottom32bIO, Bottom40bIO, Cache32bTOP;
32 u32 val;
33 u32 addr;
34 u32 lo, hi;
36 /* Set temporary top of memory from Node structure data.
37 * Adjust temp top of memory down to accommodate 32-bit IO space.
38 * Bottom40bIO=top of memory, right justified 8 bits
39 * (defines dram versus IO space type)
40 * Bottom32bIO=sub 4GB top of memory, right justified 8 bits
41 * (defines dram versus IO space type)
42 * Cache32bTOP=sub 4GB top of WB cacheable memory,
43 * right justified 8 bits
46 val = mctGet_NVbits(NV_BottomIO);
47 if(val == 0)
48 val++;
50 Bottom32bIO = val << (24-8);
52 val = pMCTstat->SysLimit + 1;
53 if(val <= _4GB_RJ8) {
54 Bottom40bIO = 0;
55 if(Bottom32bIO >= val)
56 Bottom32bIO = val;
57 } else {
58 Bottom40bIO = val;
61 Cache32bTOP = Bottom32bIO;
63 /*======================================================================
64 Set default values for CPU registers
65 ======================================================================*/
67 /* NOTE : For coreboot, we don't need to set mtrr enables here because
68 they are still enable from cache_as_ram.inc */
70 addr = 0x250;
71 lo = 0x1E1E1E1E;
72 hi = lo;
73 _WRMSR(addr, lo, hi); /* 0 - 512K = WB Mem */
74 addr = 0x258;
75 _WRMSR(addr, lo, hi); /* 512K - 640K = WB Mem */
77 /*======================================================================
78 Set variable MTRR values
79 ======================================================================*/
80 /* NOTE: for coreboot change from 0x200 to 0x204: coreboot is using
81 0x200, 0x201 for [1M, CONFIG_TOP_MEM)
82 0x202, 0x203 for ROM Caching
84 addr = 0x204; /* MTRR phys base 2*/
85 /* use TOP_MEM as limit*/
86 /* Limit=TOP_MEM|TOM2*/
87 /* Base=0*/
88 print_tx("\t CPUMemTyping: Cache32bTOP:", Cache32bTOP);
89 SetMTRRrangeWB_D(0, &Cache32bTOP, &addr);
90 /* Base */
91 /* Limit */
92 /* MtrrAddr */
93 if(addr == -1) /* ran out of MTRRs?*/
94 pMCTstat->GStatus |= 1<<GSB_MTRRshort;
96 pMCTstat->Sub4GCacheTop = Cache32bTOP<<8;
98 /*======================================================================
99 Set TOP_MEM and TOM2 CPU registers
100 ======================================================================*/
101 addr = TOP_MEM;
102 lo = Bottom32bIO<<8;
103 hi = Bottom32bIO>>24;
104 _WRMSR(addr, lo, hi);
105 print_tx("\t CPUMemTyping: Bottom32bIO:", Bottom32bIO);
106 print_tx("\t CPUMemTyping: Bottom40bIO:", Bottom40bIO);
107 if(Bottom40bIO) {
108 hi = Bottom40bIO >> 24;
109 lo = Bottom40bIO << 8;
110 if (mctSetNodeBoundary_D())
111 lo &= 0xC0000000;
112 addr += 3; /* TOM2 */
113 _WRMSR(addr, lo, hi);
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 */
124 _WRMSR(addr, lo, hi);
128 static void SetMTRRrangeWB_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr)
130 /*set WB type*/
131 SetMTRRrange_D(Base, pLimit, pMtrrAddr, 6);
135 static void SetMTRRrange_D(u32 Base, u32 *pLimit, u32 *pMtrrAddr, u16 MtrrType)
137 /* Program MTRRs to describe given range as given cache type.
138 * Use MTRR pairs starting with the given MTRRphys Base address,
139 * and use as many as is required up to (excluding) MSR 020C, which
140 * is reserved for OS.
142 * "Limit" in the context of this procedure is not the numerically
143 * correct limit, but rather the Last address+1, for purposes of coding
144 * efficiency and readability. Size of a region is then Limit-Base.
146 * 1. Size of each range must be a power of two
147 * 2. Each range must be naturally aligned (Base is same as size)
149 * There are two code paths: the ascending path and descending path
150 * (analogous to bsf and bsr), where the next limit is a function of the
151 * next set bit in a forward or backward sequence of bits (as a function
152 * of the Limit). We start with the ascending path, to ensure that
153 * regions are naturally aligned, then we switch to the descending path
154 * to maximize MTRR usage efficiency. Base=0 is a special case where we
155 * start with the descending path. Correct Mask for region is
156 * 2comp(Size-1)-1, which is 2comp(Limit-Base-1)-1
159 u32 curBase, curLimit, curSize;
160 u32 val, valx;
161 u32 addr;
163 val = curBase = Base;
164 curLimit = *pLimit;
165 addr = *pMtrrAddr;
166 while((addr >= 0x200) && (addr < 0x20C) && (val < *pLimit)) {
167 /* start with "ascending" code path */
168 /* alignment (largest block size)*/
169 valx = 1 << bsf(curBase);
170 curSize = valx;
172 /* largest legal limit, given current non-zero range Base*/
173 valx += curBase;
174 if((curBase == 0) || (*pLimit < valx)) {
175 /* flop direction to "descending" code path*/
176 valx = 1<<bsr(*pLimit - curBase);
177 curSize = valx;
178 valx += curBase;
180 curLimit = valx; /*eax=curBase, edx=curLimit*/
181 valx = val>>24;
182 val <<= 8;
184 /* now program the MTRR */
185 val |= MtrrType; /* set cache type (UC or WB)*/
186 _WRMSR(addr, val, valx); /* prog. MTRR with current region Base*/
187 val = ((~(curSize - 1))+1) - 1; /* Size-1*/ /*Mask=2comp(Size-1)-1*/
188 valx = (val >> 24) | (0xff00); /* GH have 48 bits addr */
189 val <<= 8;
190 val |= ( 1 << 11); /* set MTRR valid*/
191 addr++;
192 _WRMSR(addr, val, valx); /* prog. MTRR with current region Mask*/
193 val = curLimit;
194 curBase = val; /* next Base = current Limit (loop exit)*/
195 addr++; /* next MTRR pair addr */
197 if(val < *pLimit) {
198 *pLimit = val;
199 addr = -1;
201 *pMtrrAddr = addr;
204 void UMAMemTyping_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
206 /* UMA memory size may need splitting the MTRR configuration into two
207 Before training use NB_BottomIO or the physical memory size to set the MTRRs.
208 After training, add UMAMemTyping function to reconfigure the MTRRs based on
209 NV_BottomUMA (for UMA systems only).
210 This two-step process allows all memory to be cached for training
212 u32 Bottom32bIO, Cache32bTOP;
213 u32 val;
214 u32 addr;
215 u32 lo, hi;
217 /*======================================================================
218 * Adjust temp top of memory down to accommodate UMA memory start
219 *======================================================================*/
220 /* Bottom32bIO=sub 4GB top of memory, right justified 8 bits
221 * (defines dram versus IO space type)
222 * Cache32bTOP=sub 4GB top of WB cacheable memory, right justified 8 bits */
224 Bottom32bIO = pMCTstat->Sub4GCacheTop >> 8;
226 val = mctGet_NVbits(NV_BottomUMA);
227 if (val == 0)
228 val++;
230 val <<= (24-8);
231 if (val < Bottom32bIO) {
232 Cache32bTOP = val;
233 pMCTstat->Sub4GCacheTop = val;
235 /*======================================================================
236 * Clear variable MTRR values
237 *======================================================================*/
238 addr = 0x200;
239 lo = 0;
240 hi = lo;
241 while( addr < 0x20C) {
242 _WRMSR(addr, lo, hi); /* prog. MTRR with current region Mask */
243 addr++; /* next MTRR pair addr */
246 /*======================================================================
247 * Set variable MTRR values
248 *======================================================================*/
249 print_tx("\t UMAMemTyping_D: Cache32bTOP:", Cache32bTOP);
250 SetMTRRrangeWB_D(0, &Cache32bTOP, &addr);
251 if(addr == -1) /* ran out of MTRRs?*/
252 pMCTstat->GStatus |= 1<<GSB_MTRRshort;