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
7 * (Written by Yinghai Lu <yhlu@tyan.com> for Tyan)
8 * Copyright (C) 2007 coresystems GmbH
9 * (Written by Stefan Reinauer <stepan@coresystems.de> for coresystems GmbH)
10 * Copyright (C) 2008 Carl-Daniel Hailfinger
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; version 2 of the License.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 /* Init code - Switch CPU to protected mode and enable Cache-as-Ram (CAR). */
28 #include <arch/intel.h>
30 #define ROM_CODE_SEG 0x08
31 #define ROM_DATA_SEG 0x10
33 #define CACHE_RAM_CODE_SEG 0x18
34 #define CACHE_RAM_DATA_SEG 0x20
36 /* When we come here we are in protected mode. We expand the stack
37 * and copy the data segment from ROM to the memory.
39 * After that, we call the chipset bootstrap routine that
40 * does what is left of the chipset initialization.
42 * NOTE: Aligned to 4 so that we are sure that the prefetch
43 * cache will be reloaded.
47 .globl protected_stage0
50 ljmp $ROM_CODE_SEG, $__protected_stage0
52 .globl __protected_stage0
54 /* Save the BIST result. */
57 intel_chip_post_macro(0x01)
59 movw $ROM_DATA_SEG, %ax
66 /* Restore the BIST value to %eax. */
71 /* disable HyperThreading is done by eswar
72 * the other is very similar to the AMD CAR, except remove amd specific msr
75 #define CacheSize CONFIG_DCACHE_RAM_SIZE
76 #define CacheBase CONFIG_DCACHE_RAM_BASE
78 #include <cpu/x86/mtrr.h>
80 /* Save the BIST result */
84 /* Check whether the processor has HT capability */
93 /* It is a HT processor; Send SIPI to the other logical processor
94 * within this processor so that the CAR related common system
95 * registers are programmed accordingly
98 /* Use some register that is common to both logical processors
99 * as semaphore. Refer Appendix B, Vol.3
107 /* Figure out the logical AP's APIC ID; the following logic will work
108 * only for processors with 2 threads.
110 * Refer to Vol 3. Table 7-1 for details about this logic
112 movl $0xFEE00020, %esi
114 andl $0xFF000000, %ebx
123 bswapl %ebx /* ebx - logical AP's APIC ID */
125 /* Fill up the IPI command registers in the Local APIC mapped to
126 * default address and issue SIPI to the other logical processor
127 * within this processor die.
132 movl $0xFEE00310, %esi
135 /* SIPI vector - F900:0000 */
136 movl $0x000006F9, %eax
137 movl $0xFEE00300, %esi
147 andl $0x00001000, %eax
150 /* Wait for the Logical AP to complete initialization */
151 LogicalAPSIPINotdone:
155 jz LogicalAPSIPINotdone
160 /* Set the default memory type and enable fixed and variable MTRRs */
161 movl $MTRRdefType_MSR, %ecx
163 /* Enable Variable and Fixed MTRRs */
164 movl $0x00000c00, %eax
167 /* Clear all MTRRs */
169 movl $fixed_mtrr_msr, %esi
171 clear_fixed_var_mtrr:
174 jz clear_fixed_var_mtrr_out
180 jmp clear_fixed_var_mtrr
181 clear_fixed_var_mtrr_out:
183 /* 0x06 is the WB IO type for a given 4k segment.
184 * segs is the number of 4k segments in the area of the particular
185 * register we want to use for CAR.
186 * reg is the register where the IO type should be stored.
188 .macro extractmask segs, reg
190 /* The xorl here is superfluous because at the point of first execution
191 * of this macro, %eax and %edx are cleared. Later invocations of this
192 * macro will have a monotonically increasing segs parameter.
196 movl $0x06000000, \reg /* WB IO type */
198 movl $0x06060000, \reg /* WB IO type */
200 movl $0x06060600, \reg /* WB IO type */
202 movl $0x06060606, \reg /* WB IO type */
206 /* size is the cache size in bytes we want to use for CAR.
207 * windowoffset is the 32k-aligned window into CAR size
209 .macro simplemask carsize, windowoffset
210 /* DO NOT CHANGE THE FORMATTING of the two lines below! Whitespace is
211 * interpreted as an argument delimiter by some versions of GNU as. */
212 extractmask (((\carsize-\windowoffset)/0x1000)-4), %eax
213 extractmask (((\carsize-\windowoffset)/0x1000)), %edx
216 #if CacheSize > 0x10000
217 #error Invalid CAR size, must be at most 64k.
219 #if CacheSize < 0x1000
220 #error Invalid CAR size, must be at least 4k. This is a processor limitation.
222 #if (CacheSize & (0x1000 - 1))
223 #error Invalid CAR size, is not a multiple of 4k. This is a processor limitation.
226 #if CacheSize > 0x8000
227 /* enable caching for 32K-64K using fixed mtrr */
228 movl $0x268, %ecx /* fix4k_c0000*/
229 simplemask CacheSize, 0x8000
233 /* enable caching for 0-32K using fixed mtrr */
234 movl $0x269, %ecx /* fix4k_c8000*/
235 simplemask CacheSize, 0
238 #if defined(CONFIG_XIP_ROM_SIZE) && defined(CONFIG_XIP_ROM_BASE)
239 #if defined(CONFIG_TINY_BOOTBLOCK) && CONFIG_TINY_BOOTBLOCK
240 #define REAL_XIP_ROM_BASE AUTO_XIP_ROM_BASE
242 #define REAL_XIP_ROM_BASE CONFIG_XIP_ROM_BASE
244 /* enable write base caching so we can do execute in place
249 movl $REAL_XIP_ROM_BASE, %eax
250 orl $MTRR_TYPE_WRBACK, %eax
254 movl $0x0000000f, %edx
255 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | 0x800), %eax
257 #endif /* CONFIG_XIP_ROM_SIZE && CONFIG_XIP_ROM_BASE */
261 andl $0x9fffffff,%eax
264 /* Read the range with lodsl*/
265 movl $CacheBase, %esi
267 movl $(CacheSize>>2), %ecx
270 /* Clear the range */
271 movl $CacheBase, %edi
272 movl $(CacheSize>>2), %ecx
277 /* TODO: make this a config variable */
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 /* dont show */
322 movl $(CacheBase+CacheSize-4), %eax
325 /* Load a different set of data segments */
326 movw $CACHE_RAM_DATA_SEG, %ax
332 /* Store zero for the pointer to the global variables. */
335 /* Restore the BIST result. */
338 /* We need to set ebp? No need. */
341 /* Third parameter: cpu #: 0 == BSP all other are APs.
342 * 0 until SMP support is added.
345 /* Second parameter: init_detected */
346 /* Store zero for the unused init_detected parameter. */
348 /* First parameter: bist */
351 /* We will not go back. */
354 .long 0x250, 0x258, 0x259
355 .long 0x268, 0x269, 0x26A
356 .long 0x26B, 0x26C, 0x26D
359 .long 0x200, 0x201, 0x202, 0x203
360 .long 0x204, 0x205, 0x206, 0x207
361 .long 0x208, 0x209, 0x20A, 0x20B
362 .long 0x20C, 0x20D, 0x20E, 0x20F
363 .long 0x000 /* NULL, end of table */