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.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #include <cpu/x86/stack.h>
25 #include <cpu/x86/mtrr.h>
26 #include <cpu/x86/lapic_def.h>
27 #include <cpu/x86/post_code.h>
29 #define CacheSize CONFIG_DCACHE_RAM_SIZE
30 #define CacheBase (0xd0000 - CacheSize)
32 /* Save the BIST result. */
36 /* Check whether the processor has HT capability. */
46 * It is a HT processor. Send SIPI to the other logical processor
47 * within this processor so that the CAR related common system
48 * registers are programmed accordingly.
52 * Use some register that is common to both logical processors
53 * as semaphore. Refer Appendix B, Vol.3.
57 movl $MTRRfix64K_00000_MSR, %ecx
61 * Figure out the logical AP's APIC ID; the following logic will
62 * work only for processors with 2 threads.
63 * Refer to Vol 3. Table 7-1 for details about this logic.
65 movl $0xFEE00020, %esi
67 andl $0xFF000000, %ebx
76 bswapl %ebx /* EBX - logical AP's APIC ID. */
79 * Fill up the IPI command registers in the Local APIC mapped to
80 * default address and issue SIPI to the other logical processor
81 * within this processor die.
85 movl $0xFEE00310, %esi
88 /* SIPI vector - F900:0000 */
89 movl $0x000006F9, %eax
90 movl $0xFEE00300, %esi
100 andl $0x00001000, %eax
103 /* Wait for the Logical AP to complete initialization. */
104 LogicalAP_SIPINotdone:
105 movl $MTRRfix64K_00000_MSR, %ecx
108 jz LogicalAP_SIPINotdone
111 /* Set the default memory type and enable fixed and variable MTRRs. */
112 movl $MTRRdefType_MSR, %ecx
114 movl $(MTRRdefTypeEn | MTRRdefTypeFixEn), %eax
117 /* Clear all MTRRs. */
119 movl $all_mtrr_msrs, %esi
121 clear_fixed_var_mtrr:
124 jz clear_fixed_var_mtrr_out
130 jmp clear_fixed_var_mtrr
133 /* fixed MTRR MSRs */
134 .long MTRRfix64K_00000_MSR
135 .long MTRRfix16K_80000_MSR
136 .long MTRRfix16K_A0000_MSR
137 .long MTRRfix4K_C0000_MSR
138 .long MTRRfix4K_C8000_MSR
139 .long MTRRfix4K_D0000_MSR
140 .long MTRRfix4K_D8000_MSR
141 .long MTRRfix4K_E0000_MSR
142 .long MTRRfix4K_E8000_MSR
143 .long MTRRfix4K_F0000_MSR
144 .long MTRRfix4K_F8000_MSR
147 .long MTRRphysBase_MSR(0)
148 .long MTRRphysMask_MSR(0)
149 .long MTRRphysBase_MSR(1)
150 .long MTRRphysMask_MSR(1)
151 .long MTRRphysBase_MSR(2)
152 .long MTRRphysMask_MSR(2)
153 .long MTRRphysBase_MSR(3)
154 .long MTRRphysMask_MSR(3)
155 .long MTRRphysBase_MSR(4)
156 .long MTRRphysMask_MSR(4)
157 .long MTRRphysBase_MSR(5)
158 .long MTRRphysMask_MSR(5)
159 .long MTRRphysBase_MSR(6)
160 .long MTRRphysMask_MSR(6)
161 .long MTRRphysBase_MSR(7)
162 .long MTRRphysMask_MSR(7)
164 .long 0x000 /* NULL, end of table */
166 clear_fixed_var_mtrr_out:
169 * 0x06 is the WB IO type for a given 4k segment.
170 * segs is the number of 4k segments in the area of the particular
171 * register we want to use for CAR.
172 * reg is the register where the IO type should be stored.
174 .macro extractmask segs, reg
177 * The xorl here is superfluous because at the point of first execution
178 * of this macro, %eax and %edx are cleared. Later invocations of this
179 * macro will have a monotonically increasing segs parameter.
183 movl $0x06000000, \reg /* WB IO type */
185 movl $0x06060000, \reg /* WB IO type */
187 movl $0x06060600, \reg /* WB IO type */
189 movl $0x06060606, \reg /* WB IO type */
194 * carsize is the cache size in bytes we want to use for CAR.
195 * windowoffset is the 32k-aligned window into CAR size.
197 .macro simplemask carsize, windowoffset
198 .set gas_bug_workaround,(((\carsize - \windowoffset) / 0x1000) - 4)
199 extractmask gas_bug_workaround, %eax
200 .set gas_bug_workaround,(((\carsize - \windowoffset) / 0x1000))
201 extractmask gas_bug_workaround, %edx
203 * Without the gas bug workaround, the entire macro would consist
204 * only of the two lines below:
205 * extractmask (((\carsize - \windowoffset) / 0x1000) - 4), %eax
206 * extractmask (((\carsize - \windowoffset) / 0x1000)), %edx
210 #if CacheSize > 0x10000
211 #error Invalid CAR size, must be at most 64k.
213 #if CacheSize < 0x1000
214 #error Invalid CAR size, must be at least 4k. This is a processor limitation.
216 #if (CacheSize & (0x1000 - 1))
217 #error Invalid CAR size, is not a multiple of 4k. This is a processor limitation.
220 #if CacheSize > 0x8000
221 /* Enable caching for 32K-64K using fixed MTRR. */
222 movl $MTRRfix4K_C0000_MSR, %ecx
223 simplemask CacheSize, 0x8000
227 /* Enable caching for 0-32K using fixed MTRR. */
228 movl $MTRRfix4K_C8000_MSR, %ecx
229 simplemask CacheSize, 0
232 #if defined(CONFIG_XIP_ROM_SIZE) && defined(CONFIG_XIP_ROM_BASE)
234 #if defined(CONFIG_TINY_BOOTBLOCK) && CONFIG_TINY_BOOTBLOCK
235 #define REAL_XIP_ROM_BASE AUTO_XIP_ROM_BASE
237 #define REAL_XIP_ROM_BASE CONFIG_XIP_ROM_BASE
241 * Enable write base caching so we can do execute in place (XIP)
244 movl $MTRRphysBase_MSR(1), %ecx
247 * IMPORTANT: The two lines below can _not_ be written like this:
248 * movl $(REAL_XIP_ROM_BASE | MTRR_TYPE_WRBACK), %eax
249 * http://www.coreboot.org/pipermail/coreboot/2010-October/060855.html
251 movl $REAL_XIP_ROM_BASE, %eax
252 orl $MTRR_TYPE_WRBACK, %eax
255 movl $MTRRphysMask_MSR(1), %ecx
256 movl $0x0000000f, %edx
257 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRRphysMaskValid), %eax
259 #endif /* CONFIG_XIP_ROM_SIZE && CONFIG_XIP_ROM_BASE */
263 andl $(~((1 << 30) | (1 << 29))), %eax
266 /* Read the range with lodsl. */
267 movl $CacheBase, %esi
269 movl $(CacheSize >> 2), %ecx
272 /* Clear the range. */
273 movl $CacheBase, %edi
274 movl $(CacheSize >> 2), %ecx
279 /* Check the cache as ram. */
280 movl $CacheBase, %esi
281 movl $(CacheSize >> 2), %ecx
291 movl $CacheBase, %esi
292 // movl $(CacheSize >> 2), %ecx
306 je .xin2 /* Don't show. */
322 movl $(CacheBase + CacheSize - 4), %eax
325 /* Restore the BIST result. */
328 /* We need to set EBP? No need. */
330 pushl %eax /* BIST */
333 /* We don't need CAR from now on. */
341 movl $MTRRfix4K_C8000_MSR, %ecx
346 #if CONFIG_DCACHE_RAM_SIZE > 0x8000
347 movl $MTRRfix4K_C0000_MSR, %ecx
352 * Set the default memory type and disable fixed
353 * and enable variable MTRRs.
355 movl $MTRRdefType_MSR, %ecx
357 movl $MTRRdefTypeEn, %eax /* Enable variable and disable fixed MTRRs. */
362 andl $(~((1 << 30) | (1 << 29))), %eax
365 /* Clear boot_complete flag. */
368 post_code(POST_PREPARE_RAMSTAGE)
369 cld /* Clear direction flag. */
373 movl $ROMSTAGE_STACK, %esp
379 post_code(POST_DEAD_CODE)