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 #include <cpu/x86/car.h>
22 #include <cpu/x86/mtrr.h>
23 #include <cpu/amd/mtrr.h>
25 #define CacheSize CONFIG_DCACHE_RAM_SIZE
26 #define CacheBase (0xd0000 - CacheSize)
28 /* Leave some space for global variable to pass to RAM stage. */
29 #define GlobalVarSize CONFIG_DCACHE_RAM_GLOBAL_VAR_SIZE
31 /* For CAR with Fam10h. */
32 #define CacheSizeAPStack 0x400 /* 1K */
34 #define MSR_MCFG_BASE 0xC0010058
35 #define MSR_FAM10 0xC001102A
37 #define jmp_if_k8(x) comisd %xmm2, %xmm1; jb x
39 #define CPUID_MASK 0x0ff00f00
40 #define CPUID_VAL_FAM10_ROTATED 0x0f000010
45 * xmm2: Fam10h comparison value
52 * For normal part %ebx already contain cpu_init_detected
61 /* Figure out the CPU family. */
65 /* Base family is bits 8..11, extended family is bits 20..27. */
66 andl $CPUID_MASK, %eax
67 /* Reorder bits for easier comparison by value. */
70 movl $CPUID_VAL_FAM10_ROTATED, %eax
74 /* Check if cpu_init_detected. */
75 movl $MTRRdefType_MSR, %ecx
78 movl %eax, %ebx /* We store the status. */
80 jmp_if_k8(CAR_FAM10_out_post_errata)
83 * For GH, CAR need to set DRAM Base/Limit registers to direct that
85 * Only BSP needed, for other nodes set during HT/memory init.
86 * So we need to check if it is BSP.
93 /* Enable RT tables on BSP. */
94 movl $0x8000c06c, %eax
102 /* Setup temporary DRAM map: [0,16M) bit 0-23. */
103 movl $0x8000c144, %eax
110 movl $0x8000c140, %eax
120 * Errata 193: Disable clean copybacks to L3 cache to allow cached ROM.
121 * Re-enable it in after RAM is initialized and before CAR is disabled.
123 movl $MSR_FAM10, %ecx
128 /* Erratum 343, RevGuide for Fam10h, Pub#41322 Rev. 3.33 */
129 movl $MSR_FAM10, %ecx
131 bts $35-32, %edx /* Set bit 35 in EDX:EAX (bit 3 in EDX). */
134 #if CONFIG_MMCONF_SUPPORT
135 /* Set MMIO config space BAR. */
136 movl $MSR_MCFG_BASE, %ecx
138 andl $(~(0xfff00000 | (0xf << 2))), %eax
139 orl $((CONFIG_MMCONF_BASE_ADDRESS & 0xfff00000)), %eax
140 orl $((8 << 2) | (1 << 0)), %eax
141 andl $(~(0x0000ffff)), %edx
142 orl $(CONFIG_MMCONF_BASE_ADDRESS >> 32), %edx
146 CAR_FAM10_out_post_errata:
148 /* Set MtrrFixDramModEn for clear fixed MTRR. */
149 enable_fixed_mtrr_dram_modify:
150 movl $SYSCFG_MSR, %ecx
152 andl $(~(SYSCFG_MSR_MtrrFixDramEn | SYSCFG_MSR_MtrrVarDramEn)), %eax
153 orl $SYSCFG_MSR_MtrrFixDramModEn, %eax
156 /* Clear all MTRRs. */
158 movl $fixed_mtrr_msr, %esi
160 clear_fixed_var_mtrr:
163 jz clear_fixed_var_mtrr_out
169 jmp clear_fixed_var_mtrr
170 clear_fixed_var_mtrr_out:
173 * 0x06 is the WB IO type for a given 4k segment.
174 * 0x1e is the MEM IO type for a given 4k segment (K10 and above).
175 * segs is the number of 4k segments in the area of the particular
176 * register we want to use for CAR.
177 * reg is the register where the IO type should be stored.
179 .macro extractmask segs, reg
182 * The xorl here is superfluous because at the point of first execution
183 * of this macro, %eax and %edx are cleared. Later invocations of this
184 * macro will have a monotonically increasing segs parameter.
191 movl $0x1e000000, \reg /* WB MEM type */
193 movl $0x1e1e0000, \reg /* WB MEM type */
195 movl $0x1e1e1e00, \reg /* WB MEM type */
197 movl $0x1e1e1e1e, \reg /* WB MEM type */
202 movl $0x06000000, \reg /* WB IO type */
204 movl $0x06060000, \reg /* WB IO type */
206 movl $0x06060600, \reg /* WB IO type */
208 movl $0x06060606, \reg /* WB IO type */
211 .endif /* if \segs <= 0 */
215 * carsize is the cache size in bytes we want to use for CAR.
216 * windowoffset is the 32k-aligned window into CAR size.
218 .macro simplemask carsize, windowoffset
219 .set gas_bug_workaround,(((\carsize - \windowoffset) / 0x1000) - 4)
220 extractmask gas_bug_workaround, %eax
221 .set gas_bug_workaround,(((\carsize - \windowoffset) / 0x1000))
222 extractmask gas_bug_workaround, %edx
224 * Without the gas bug workaround, the entire macro would consist
225 * only of the two lines below:
226 * extractmask (((\carsize - \windowoffset) / 0x1000) - 4), %eax
227 * extractmask (((\carsize - \windowoffset) / 0x1000)), %edx
231 #if CacheSize > 0x10000
232 #error Invalid CAR size, must be at most 64k.
234 #if CacheSize < 0x1000
235 #error Invalid CAR size, must be at least 4k. This is a processor limitation.
237 #if (CacheSize & (0x1000 - 1))
238 #error Invalid CAR size, is not a multiple of 4k. This is a processor limitation.
241 #if CacheSize > 0x8000
242 /* Enable caching for 32K-64K using fixed MTRR. */
243 movl $MTRRfix4K_C0000_MSR, %ecx
244 simplemask CacheSize, 0x8000
248 /* Enable caching for 0-32K using fixed MTRR. */
249 movl $MTRRfix4K_C8000_MSR, %ecx
250 simplemask CacheSize, 0
253 /* Enable memory access for first MBs using top_mem. */
256 movl $(((CONFIG_RAMTOP) + TOP_MEM_MASK) & ~TOP_MEM_MASK) , %eax
259 #if defined(CONFIG_XIP_ROM_SIZE) && defined(CONFIG_XIP_ROM_BASE)
261 #if defined(CONFIG_TINY_BOOTBLOCK) && CONFIG_TINY_BOOTBLOCK
262 #define REAL_XIP_ROM_BASE AUTO_XIP_ROM_BASE
264 #define REAL_XIP_ROM_BASE CONFIG_XIP_ROM_BASE
267 /* Enable write base caching so we can do execute in place (XIP)
270 movl $MTRRphysBase_MSR(1), %ecx
272 movl $REAL_XIP_ROM_BASE, %eax
273 orl $MTRR_TYPE_WRBACK, %eax
276 movl $MTRRphysMask_MSR(1), %ecx
277 movl $0xff, %edx /* (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1 for K8 (CONFIG_CPU_ADDR_BITS = 40) */
278 jmp_if_k8(wbcache_post_fam10_setup)
279 movl $0xffff, %edx /* (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1 for FAM10 (CONFIG_CPU_ADDR_BITS = 48) */
280 wbcache_post_fam10_setup:
281 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | 0x800), %eax
283 #endif /* CONFIG_XIP_ROM_SIZE && CONFIG_XIP_ROM_BASE */
285 /* Set the default memory type and enable fixed and variable MTRRs. */
286 movl $MTRRdefType_MSR, %ecx
288 movl $(MTRRdefTypeEn | MTRRdefTypeFixEn), %eax
291 /* Enable the MTRRs and IORRs in SYSCFG. */
292 movl $SYSCFG_MSR, %ecx
294 orl $(SYSCFG_MSR_MtrrVarDramEn | SYSCFG_MSR_MtrrFixDramEn), %eax
301 jmp_if_k8(fam10_end_part1)
303 /* So we need to check if it is BSP. */
306 bt $8, %eax /* BSP */
312 /* Read the range with lodsl. */
314 movl $CacheBase, %esi
315 movl $(CacheSize >> 2), %ecx
318 /* Clear the range. */
319 movl $CacheBase, %edi
320 movl $(CacheSize >> 2), %ecx
324 /* Set up the stack pointer. */
325 movl $(CacheBase + CacheSize - GlobalVarSize), %eax
333 * Need to set stack pointer for AP.
335 * CacheBase + (CacheSize - GlobalVarSize) / 2
336 * - (NodeID << CoreIDbits + CoreID) * CacheSizeAPStack
337 * So need to get the NodeID and CoreID at first.
338 * If NB_CFG bit 54 is set just use initial APIC ID, otherwise need
342 /* Store our init detected. */
345 /* Get the coreid bits at first. */
346 movl $0x80000008, %eax
352 /* Get the initial APIC ID. */
357 /* Get the nb cfg bit 54. */
358 movl $0xc001001f, %ecx /* NB_CFG_MSR */
360 movl %edi, %ecx /* CoreID bits */
366 /* Calculate stack pointer. */
367 movl $CacheSizeAPStack, %eax
369 movl $(CacheBase + (CacheSize - GlobalVarSize) / 2), %esp
372 /* Retrive init detected. */
383 restore_bist_result()
385 /* We need to set EBP? No need. */
387 pushl %ebx /* Init detected. */
388 pushl %eax /* BIST */
389 call cache_as_ram_main
390 /* We will not go back. */
392 post_code(0xaf) /* Should never see this POST code. */
395 .long 0x250, 0x258, 0x259
396 .long 0x268, 0x269, 0x26A
397 .long 0x26B, 0x26C, 0x26D
401 .long 0x200, 0x201, 0x202, 0x203
402 .long 0x204, 0x205, 0x206, 0x207
403 .long 0x208, 0x209, 0x20A, 0x20B
404 .long 0x20C, 0x20D, 0x20E, 0x20F
407 .long 0xC0010016, 0xC0010017, 0xC0010018, 0xC0010019
410 .long 0xC001001A, 0xC001001D
411 .long 0x000 /* NULL, end of table */
413 cache_as_ram_setup_out: