2 * This file is part of the coreboot project.
4 * Copyright (C) 2005-2007 Advanced Micro Devices, Inc.
5 * Copyright (C) 2008 Carl-Daniel Hailfinger
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #define CacheSize CONFIG_DCACHE_RAM_SIZE
22 #define CacheBase (0xd0000 - CacheSize)
24 /* leave some space for global variable to pass to RAM stage */
25 #define GlobalVarSize CONFIG_DCACHE_RAM_GLOBAL_VAR_SIZE
27 /* for CAR with FAM10 */
28 #define CacheSizeAPStack 0x400 /* 1K */
30 #define MSR_MCFG_BASE 0xC0010058
31 #define MSR_FAM10 0xC001102A
33 #define jmp_if_k8(x) comisd %xmm2, %xmm1; jb x
35 #define CPUID_MASK 0x0ff00f00
36 #define CPUID_VAL_FAM10_ROTATED 0x0f000010
38 #include <cpu/x86/mtrr.h>
39 #include <cpu/amd/mtrr.h>
43 * xmm2: fam10 comparison value
47 /* Save the BIST result */
50 /* for normal part %ebx already contain cpu_init_detected from fallback call */
60 /* figure out cpu family */
64 /* base family is bits 8..11, extended family is bits 20..27 */
65 andl $CPUID_MASK, %eax
66 /* reorder bits for easier comparison by value */
69 movl $CPUID_VAL_FAM10_ROTATED, %eax
73 /* check if cpu_init_detected */
74 movl $MTRRdefType_MSR, %ecx
77 movl %eax, %ebx /* We store the status */
79 jmp_if_k8(CAR_FAM10_out_post_errata)
81 /* for GH, CAR need to set DRAM Base/Limit Registers to direct that to node0 */
83 /* Only BSP needed, for other nodes set during HT/memory init. */
84 /* So we need to check if it is BSP */
90 /* Enable RT tables on BSP */
91 movl $0x8000c06c, %eax
99 /* Setup temporary DRAM map: [0,16M) bit 0-23 */
100 movl $0x8000c144, %eax
107 movl $0x8000c140, %eax
116 /* Errata 193: Disable clean copybacks to L3 cache to allow cached ROM.
117 * Re-enable it in after RAM is initialized and before CAR is disabled
119 movl $MSR_FAM10, %ecx
124 /* Erratum 343, RevGuide for Fam10h, Pub#41322 Rev. 3.33 */
126 /* read-address has to be stored in the ecx register */
127 movl $MSR_FAM10, %ecx
129 /* execute special read command for msr-register. Result is then in the EDX:EAX-registers (MSBs in EDX) */
132 /* Set bit 35 to 1 in EAX */
135 /* write back the modified register EDX:EAX to the MSR specified in ECX */
138 /* Erratum 343 end */
140 #if CONFIG_MMCONF_SUPPORT
141 /* Set MMIO Config space BAR */
142 movl $MSR_MCFG_BASE, %ecx
145 andl $(~(0xfff00000 | (0xf << 2))), %eax
146 orl $((CONFIG_MMCONF_BASE_ADDRESS & 0xfff00000) | (8 << 2) | (1 << 0)), %eax
147 andl $(~(0x0000ffff)), %edx
148 orl $(CONFIG_MMCONF_BASE_ADDRESS >> 32), %edx
153 CAR_FAM10_out_post_errata:
155 /* Set MtrrFixDramModEn for clear fixed mtrr */
156 enable_fixed_mtrr_dram_modify:
157 movl $SYSCFG_MSR, %ecx
159 andl $(~(SYSCFG_MSR_MtrrFixDramEn | SYSCFG_MSR_MtrrVarDramEn)), %eax
160 orl $SYSCFG_MSR_MtrrFixDramModEn, %eax
163 /* Clear all MTRRs */
165 movl $fixed_mtrr_msr, %esi
167 clear_fixed_var_mtrr:
170 jz clear_fixed_var_mtrr_out
176 jmp clear_fixed_var_mtrr
177 clear_fixed_var_mtrr_out:
179 /* 0x06 is the WB IO type for a given 4k segment.
180 * 0x1e is the MEM IO type for a given 4k segment (K10 and above).
181 * segs is the number of 4k segments in the area of the particular
182 * register we want to use for CAR.
183 * reg is the register where the IO type should be stored.
185 .macro extractmask segs, reg
187 /* The xorl here is superfluous because at the point of first execution
188 * of this macro, %eax and %edx are cleared. Later invocations of this
189 * macro will have a monotonically increasing segs parameter.
196 movl $0x1e000000, \reg /* WB MEM type */
198 movl $0x1e1e0000, \reg /* WB MEM type */
200 movl $0x1e1e1e00, \reg /* WB MEM type */
202 movl $0x1e1e1e1e, \reg /* WB MEM type */
207 movl $0x06000000, \reg /* WB IO type */
209 movl $0x06060000, \reg /* WB IO type */
211 movl $0x06060600, \reg /* WB IO type */
213 movl $0x06060606, \reg /* WB IO type */
216 .endif /* if \segs <= 0 */
219 /* size is the cache size in bytes we want to use for CAR.
220 * windowoffset is the 32k-aligned window into CAR size
222 .macro simplemask carsize, windowoffset
223 .set gas_bug_workaround,(((\carsize - \windowoffset) / 0x1000) - 4)
224 extractmask gas_bug_workaround, %eax
225 .set gas_bug_workaround,(((\carsize - \windowoffset) / 0x1000))
226 extractmask gas_bug_workaround, %edx
227 /* Without the gas bug workaround, the entire macro would consist only of the
229 extractmask (((\carsize - \windowoffset) / 0x1000) - 4), %eax
230 extractmask (((\carsize - \windowoffset) / 0x1000)), %edx
234 #if CacheSize > 0x10000
235 #error Invalid CAR size, must be at most 64k.
237 #if CacheSize < 0x1000
238 #error Invalid CAR size, must be at least 4k. This is a processor limitation.
240 #if (CacheSize & (0x1000 - 1))
241 #error Invalid CAR size, is not a multiple of 4k. This is a processor limitation.
244 #if CacheSize > 0x8000
245 /* enable caching for 32K-64K using fixed mtrr */
246 movl $0x268, %ecx /* fix4k_c0000*/
247 simplemask CacheSize, 0x8000
251 /* enable caching for 0-32K using fixed mtrr */
252 movl $0x269, %ecx /* fix4k_c8000*/
253 simplemask CacheSize, 0
256 /* enable memory access for first MBs using top_mem */
259 movl $(((CONFIG_RAMTOP) + TOP_MEM_MASK) & ~TOP_MEM_MASK) , %eax
262 #if defined(CONFIG_XIP_ROM_SIZE) && defined(CONFIG_XIP_ROM_BASE)
263 /* enable write base caching so we can do execute in place
269 #if defined(CONFIG_TINY_BOOTBLOCK) && CONFIG_TINY_BOOTBLOCK
270 #define REAL_XIP_ROM_BASE AUTO_XIP_ROM_BASE
272 #define REAL_XIP_ROM_BASE CONFIG_XIP_ROM_BASE
274 movl $REAL_XIP_ROM_BASE, %eax
275 orl $MTRR_TYPE_WRBACK, %eax
279 movl $0xff, %edx /* (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1 for K8 (CONFIG_CPU_ADDR_BITS = 40) */
280 jmp_if_k8(wbcache_post_fam10_setup)
281 movl $0xffff, %edx /* (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1 for FAM10 (CONFIG_CPU_ADDR_BITS = 48) */
282 wbcache_post_fam10_setup:
283 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | 0x800), %eax
285 #endif /* CONFIG_XIP_ROM_SIZE && CONFIG_XIP_ROM_BASE */
287 /* Set the default memory type and enable fixed and variable MTRRs */
288 movl $MTRRdefType_MSR, %ecx
290 /* Enable Variable and Fixed MTRRs */
291 movl $0x00000c00, %eax
294 /* Enable the MTRRs and IORRs in SYSCFG */
295 movl $SYSCFG_MSR, %ecx
297 orl $(SYSCFG_MSR_MtrrVarDramEn | SYSCFG_MSR_MtrrFixDramEn), %eax
304 andl $0x9fffffff, %eax
307 jmp_if_k8(fam10_end_part1)
309 /* So we need to check if it is BSP */
318 /* Read the range with lodsl*/
320 movl $CacheBase, %esi
321 movl $(CacheSize >> 2), %ecx
324 /* Clear the range */
325 movl $CacheBase, %edi
326 movl $(CacheSize >> 2), %ecx
330 /* set up the stack pointer */
331 movl $(CacheBase + CacheSize - GlobalVarSize), %eax
338 /* need to set stack pointer for AP */
339 /* it will be from CacheBase + (CacheSize - GlobalVarSize)/2 - (NodeID<<CoreIDbits + CoreID) * CacheSizeAPStack*/
340 /* So need to get the NodeID and CoreID at first */
341 /* If NB_CFG bit 54 is set just use initial apicid, otherwise need to reverse it */
343 /* store our init detected */
346 /* get the coreid bits at first */
347 movl $0x80000008, %eax
353 /* get the initial apic id */
358 /* get the nb cfg bit 54 */
359 movl $0xc001001f, %ecx /* NB_CFG_MSR */
361 movl %edi, %ecx /* CoreID bits */
367 /* calculate stack pointer */
368 movl $CacheSizeAPStack, %eax
370 movl $(CacheBase + (CacheSize - GlobalVarSize)/2), %esp
373 /* retrive init detected */
387 /* Restore the BIST result */
390 /* We need to set ebp ? No need */
392 pushl %ebx /* init detected */
393 pushl %eax /* bist */
394 call cache_as_ram_main
395 /* We will not go back */
397 post_code(0xaf) /* Should never see this postcode */
400 .long 0x250, 0x258, 0x259
401 .long 0x268, 0x269, 0x26A
402 .long 0x26B, 0x26C, 0x26D
405 .long 0x200, 0x201, 0x202, 0x203
406 .long 0x204, 0x205, 0x206, 0x207
407 .long 0x208, 0x209, 0x20A, 0x20B
408 .long 0x20C, 0x20D, 0x20E, 0x20F
410 .long 0xC0010016, 0xC0010017, 0xC0010018, 0xC0010019
412 .long 0xC001001A, 0xC001001D
413 .long 0x000 /* NULL, end of table */
415 cache_as_ram_setup_out: