2 * This file is part of the coreboot project.
4 * Copyright (C) 2000, 2007 Ronald G. Minnich <rminnich@gmail.com>
5 * Copyright (C) 2005 Eswar Nallusamy, LANL
6 * Copyright (C) 2005 Tyan (written by Yinghai Lu for Tyan)
7 * Copyright (C) 2007-2010 coresystems GmbH
8 * Copyright (C) 2007 Carl-Daniel Hailfinger
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; version 2 of the License.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
20 #include <cpu/x86/mtrr.h>
21 #include <cpu/x86/cache.h>
22 #include <cpu/x86/lapic_def.h>
23 #include <cpu/x86/post_code.h>
25 #define CacheSize CONFIG_DCACHE_RAM_SIZE
26 #define CacheBase (0xd0000 - CacheSize)
28 /* Save the BIST result. */
32 /* Check whether the processor has HT capability. */
42 * It is a HT processor. Send SIPI to the other logical processor
43 * within this processor so that the CAR related common system
44 * registers are programmed accordingly.
48 * Use some register that is common to both logical processors
49 * as semaphore. Refer Appendix B, Vol.3.
53 movl $MTRR_FIX_64K_00000, %ecx
57 * Figure out the logical AP's APIC ID; the following logic will
58 * work only for processors with 2 threads.
59 * Refer to Vol 3. Table 7-1 for details about this logic.
61 movl $0xFEE00020, %esi
63 andl $0xFF000000, %ebx
72 bswapl %ebx /* EBX - logical AP's APIC ID. */
75 * Fill up the IPI command registers in the Local APIC mapped to
76 * default address and issue SIPI to the other logical processor
77 * within this processor die.
81 movl $0xFEE00310, %esi
84 /* SIPI vector - F900:0000 */
85 movl $0x000006F9, %eax
86 movl $0xFEE00300, %esi
96 andl $0x00001000, %eax
99 /* Wait for the Logical AP to complete initialization. */
100 LogicalAP_SIPINotdone:
101 movl $MTRR_FIX_64K_00000, %ecx
104 jz LogicalAP_SIPINotdone
107 /* Set the default memory type and enable fixed and variable MTRRs. */
108 movl $MTRR_DEF_TYPE_MSR, %ecx
110 movl $(MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN), %eax
113 /* Clear all MTRRs. */
115 movl $all_mtrr_msrs, %esi
117 clear_fixed_var_mtrr:
120 jz clear_fixed_var_mtrr_out
126 jmp clear_fixed_var_mtrr
129 /* fixed MTRR MSRs */
130 .long MTRR_FIX_64K_00000
131 .long MTRR_FIX_16K_80000
132 .long MTRR_FIX_16K_A0000
133 .long MTRR_FIX_4K_C0000
134 .long MTRR_FIX_4K_C8000
135 .long MTRR_FIX_4K_D0000
136 .long MTRR_FIX_4K_D8000
137 .long MTRR_FIX_4K_E0000
138 .long MTRR_FIX_4K_E8000
139 .long MTRR_FIX_4K_F0000
140 .long MTRR_FIX_4K_F8000
143 .long MTRR_PHYS_BASE(0)
144 .long MTRR_PHYS_MASK(0)
145 .long MTRR_PHYS_BASE(1)
146 .long MTRR_PHYS_MASK(1)
147 .long MTRR_PHYS_BASE(2)
148 .long MTRR_PHYS_MASK(2)
149 .long MTRR_PHYS_BASE(3)
150 .long MTRR_PHYS_MASK(3)
151 .long MTRR_PHYS_BASE(4)
152 .long MTRR_PHYS_MASK(4)
153 .long MTRR_PHYS_BASE(5)
154 .long MTRR_PHYS_MASK(5)
155 .long MTRR_PHYS_BASE(6)
156 .long MTRR_PHYS_MASK(6)
157 .long MTRR_PHYS_BASE(7)
158 .long MTRR_PHYS_MASK(7)
160 .long 0x000 /* NULL, end of table */
162 clear_fixed_var_mtrr_out:
165 * 0x06 is the WB IO type for a given 4k segment.
166 * segs is the number of 4k segments in the area of the particular
167 * register we want to use for CAR.
168 * reg is the register where the IO type should be stored.
170 .macro extractmask segs, reg
173 * The xorl here is superfluous because at the point of first execution
174 * of this macro, %eax and %edx are cleared. Later invocations of this
175 * macro will have a monotonically increasing segs parameter.
179 movl $0x06000000, \reg /* WB IO type */
181 movl $0x06060000, \reg /* WB IO type */
183 movl $0x06060600, \reg /* WB IO type */
185 movl $0x06060606, \reg /* WB IO type */
190 * carsize is the cache size in bytes we want to use for CAR.
191 * windowoffset is the 32k-aligned window into CAR size.
193 .macro simplemask carsize, windowoffset
194 .set gas_bug_workaround,(((\carsize - \windowoffset) >> 12) - 4)
195 extractmask gas_bug_workaround, %eax
196 .set gas_bug_workaround,(((\carsize - \windowoffset) >> 12))
197 extractmask gas_bug_workaround, %edx
199 * Without the gas bug workaround, the entire macro would consist
200 * only of the two lines below:
201 * extractmask (((\carsize - \windowoffset) >> 12) - 4), %eax
202 * extractmask (((\carsize - \windowoffset) >> 12)), %edx
206 #if CacheSize > 0x10000
207 #error Invalid CAR size, must be at most 64k.
209 #if CacheSize < 0x1000
210 #error Invalid CAR size, must be at least 4k. This is a processor limitation.
212 #if (CacheSize & (0x1000 - 1))
213 #error Invalid CAR size, is not a multiple of 4k. This is a processor limitation.
216 #if CacheSize > 0x8000
217 /* Enable caching for 32K-64K using fixed MTRR. */
218 movl $MTRR_FIX_4K_C0000, %ecx
219 simplemask CacheSize, 0x8000
223 /* Enable caching for 0-32K using fixed MTRR. */
224 movl $MTRR_FIX_4K_C8000, %ecx
225 simplemask CacheSize, 0
228 #if CONFIG_XIP_ROM_SIZE
231 * Enable write base caching so we can do execute in place (XIP)
234 movl $MTRR_PHYS_BASE(1), %ecx
237 * IMPORTANT: The following calculation _must_ be done at runtime. See
238 * http://www.coreboot.org/pipermail/coreboot/2010-October/060855.html
240 movl $copy_and_run, %eax
241 andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
242 orl $MTRR_TYPE_WRBACK, %eax
245 movl $MTRR_PHYS_MASK(1), %ecx
246 movl $0x0000000f, %edx
247 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
249 #endif /* CONFIG_XIP_ROM_SIZE */
253 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
256 /* Read the range with lodsl. */
257 movl $CacheBase, %esi
259 movl $(CacheSize >> 2), %ecx
262 /* Clear the range. */
263 movl $CacheBase, %edi
264 movl $(CacheSize >> 2), %ecx
269 /* Check the cache as ram. */
270 movl $CacheBase, %esi
271 movl $(CacheSize >> 2), %ecx
281 movl $CacheBase, %esi
282 // movl $(CacheSize >> 2), %ecx
296 je .xin2 /* Don't show. */
312 movl $(CacheBase + CacheSize - 4), %eax
315 /* Restore the BIST result. */
318 /* We need to set EBP? No need. */
320 pushl %eax /* BIST */
323 /* We don't need CAR from now on. */
327 orl $CR0_CacheDisable, %eax
331 movl $MTRR_FIX_4K_C8000, %ecx
336 #if CONFIG_DCACHE_RAM_SIZE > 0x8000
337 movl $MTRR_FIX_4K_C0000, %ecx
342 * Set the default memory type and disable fixed
343 * and enable variable MTRRs.
345 movl $MTRR_DEF_TYPE_MSR, %ecx
347 movl $MTRR_DEF_TYPE_EN, %eax /* Enable variable and disable fixed MTRRs. */
352 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
356 post_code(POST_PREPARE_RAMSTAGE)
357 cld /* Clear direction flag. */
359 movl $CONFIG_RAMTOP, %esp
364 post_code(POST_DEAD_CODE)