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>
28 #define CacheSize CONFIG_DCACHE_RAM_SIZE
29 #define CacheBase (0xd0000 - CacheSize)
31 /* Save the BIST result. */
35 /* Check whether the processor has HT capability. */
45 * It is a HT processor. Send SIPI to the other logical processor
46 * within this processor so that the CAR related common system
47 * registers are programmed accordingly.
51 * Use some register that is common to both logical processors
52 * as semaphore. Refer Appendix B, Vol.3.
56 movl $MTRRfix64K_00000_MSR, %ecx
60 * Figure out the logical AP's APIC ID; the following logic will
61 * work only for processors with 2 threads.
62 * Refer to Vol 3. Table 7-1 for details about this logic.
64 movl $0xFEE00020, %esi
66 andl $0xFF000000, %ebx
75 bswapl %ebx /* EBX - logical AP's APIC ID. */
78 * Fill up the IPI command registers in the Local APIC mapped to
79 * default address and issue SIPI to the other logical processor
80 * within this processor die.
84 movl $0xFEE00310, %esi
87 /* SIPI vector - F900:0000 */
88 movl $0x000006F9, %eax
89 movl $0xFEE00300, %esi
99 andl $0x00001000, %eax
102 /* Wait for the Logical AP to complete initialization. */
103 LogicalAP_SIPINotdone:
104 movl $MTRRfix64K_00000_MSR, %ecx
107 jz LogicalAP_SIPINotdone
110 /* Set the default memory type and enable fixed and variable MTRRs. */
111 movl $MTRRdefType_MSR, %ecx
113 movl $0x00000c00, %eax /* Enable variable and fixed MTRRs. */
116 /* Clear all MTRRs. */
118 movl $fixed_mtrr_msr, %esi
120 clear_fixed_var_mtrr:
123 jz clear_fixed_var_mtrr_out
129 jmp clear_fixed_var_mtrr
132 .long 0x250, 0x258, 0x259
133 .long 0x268, 0x269, 0x26A
134 .long 0x26B, 0x26C, 0x26D
138 .long 0x200, 0x201, 0x202, 0x203
139 .long 0x204, 0x205, 0x206, 0x207
140 .long 0x208, 0x209, 0x20A, 0x20B
141 .long 0x20C, 0x20D, 0x20E, 0x20F
142 .long 0x000 /* NULL, end of table */
144 clear_fixed_var_mtrr_out:
147 * 0x06 is the WB IO type for a given 4k segment.
148 * segs is the number of 4k segments in the area of the particular
149 * register we want to use for CAR.
150 * reg is the register where the IO type should be stored.
152 .macro extractmask segs, reg
155 * The xorl here is superfluous because at the point of first execution
156 * of this macro, %eax and %edx are cleared. Later invocations of this
157 * macro will have a monotonically increasing segs parameter.
161 movl $0x06000000, \reg /* WB IO type */
163 movl $0x06060000, \reg /* WB IO type */
165 movl $0x06060600, \reg /* WB IO type */
167 movl $0x06060606, \reg /* WB IO type */
172 * size is the cache size in bytes we want to use for CAR.
173 * windowoffset is the 32k-aligned window into CAR size.
175 .macro simplemask carsize, windowoffset
176 .set gas_bug_workaround,(((\carsize - \windowoffset) / 0x1000) - 4)
177 extractmask gas_bug_workaround, %eax
178 .set gas_bug_workaround,(((\carsize - \windowoffset) / 0x1000))
179 extractmask gas_bug_workaround, %edx
181 * Without the gas bug workaround, the entire macro would consist
182 * only of the two lines below:
183 * extractmask (((\carsize - \windowoffset) / 0x1000) - 4), %eax
184 * extractmask (((\carsize - \windowoffset) / 0x1000)), %edx
188 #if CacheSize > 0x10000
189 #error Invalid CAR size, must be at most 64k.
191 #if CacheSize < 0x1000
192 #error Invalid CAR size, must be at least 4k. This is a processor limitation.
194 #if (CacheSize & (0x1000 - 1))
195 #error Invalid CAR size, is not a multiple of 4k. This is a processor limitation.
198 #if CacheSize > 0x8000
199 /* Enable caching for 32K-64K using fixed MTRR. */
200 movl $MTRRfix4K_C0000_MSR, %ecx
201 simplemask CacheSize, 0x8000
205 /* Enable caching for 0-32K using fixed MTRR. */
206 movl $MTRRfix4K_C8000_MSR, %ecx
207 simplemask CacheSize, 0
210 #if defined(CONFIG_XIP_ROM_SIZE) && defined(CONFIG_XIP_ROM_BASE)
212 #if defined(CONFIG_TINY_BOOTBLOCK) && CONFIG_TINY_BOOTBLOCK
213 #define REAL_XIP_ROM_BASE AUTO_XIP_ROM_BASE
215 #define REAL_XIP_ROM_BASE CONFIG_XIP_ROM_BASE
219 * Enable write base caching so we can do execute in place (XIP)
222 movl $MTRRphysBase_MSR(1), %ecx
224 movl $REAL_XIP_ROM_BASE, %eax
225 orl $MTRR_TYPE_WRBACK, %eax
228 movl $MTRRphysMask_MSR(1), %ecx
229 movl $0x0000000f, %edx
230 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | 0x800), %eax
232 #endif /* CONFIG_XIP_ROM_SIZE && CONFIG_XIP_ROM_BASE */
236 andl $0x9fffffff, %eax
239 /* Read the range with lodsl. */
240 movl $CacheBase, %esi
242 movl $(CacheSize >> 2), %ecx
245 /* Clear the range. */
246 movl $CacheBase, %edi
247 movl $(CacheSize >> 2), %ecx
252 /* Check the cache as ram. */
253 movl $CacheBase, %esi
254 movl $(CacheSize >> 2), %ecx
264 movl $CacheBase, %esi
265 // movl $(CacheSize >> 2), %ecx
279 je .xin2 /* Don't show. */
295 movl $(CacheBase + CacheSize - 4), %eax
298 /* Restore the BIST result. */
301 /* We need to set EBP? No need. */
303 pushl %eax /* BIST */
306 /* We don't need CAR for now on. */
314 movl $MTRRfix4K_C8000_MSR, %ecx
319 #if CONFIG_DCACHE_RAM_SIZE > 0x8000
320 movl $MTRRfix4K_C0000_MSR, %ecx
325 * Set the default memory type and disable fixed
326 * and enable variable MTRRs.
328 movl $MTRRdefType_MSR, %ecx
330 movl $0x00000800, %eax /* Enable variable and disable fixed MTRRs. */
335 andl $0x9fffffff, %eax
338 /* Clear boot_complete flag. */
342 cld /* Clear direction flag. */
346 movl $ROMSTAGE_STACK, %esp