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) 2007 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 /* We will use 4K bytes only */
27 /* disable HyperThreading is done by eswar*/
28 /* other's is the same as AMD except remove amd specific msr */
30 #define CacheSize CONFIG_DCACHE_RAM_SIZE
31 #define CacheBase (0xd0000 - CacheSize)
33 #include <cpu/x86/stack.h>
34 #include <cpu/x86/mtrr.h>
36 /* Save the BIST result */
40 // Check whether the processor has HT capability
49 // It is a HT processor; Send SIPI to the other logical processor
50 // within this processor so that the CAR related common system registers
51 // are programmed accordingly
53 // Use some register that is common to both logical processors
54 // as semaphore. Refer Appendix B, Vol.3
60 // Figure out the logical AP's APIC ID; the following logic will work
61 // only for processors with 2 threads
62 // Refer to Vol 3. Table 7-1 for details about this logic
63 movl $0xFEE00020, %esi
65 andl $0xFF000000, %ebx
74 bswapl %ebx // ebx - logical AP's APIC ID
76 // Fill up the IPI command registers in the Local APIC mapped to default address
77 // and issue SIPI to the other logical processor within this processor die.
80 movl $0xFEE00310, %esi
83 // SIPI vector - F900:0000
84 movl $0x000006F9, %eax
85 movl $0xFEE00300, %esi
95 andl $0x00001000, %eax
98 // Wait for the Logical AP to complete initialization
99 LogicalAP_SIPINotdone:
103 jz LogicalAP_SIPINotdone
108 /* Set the default memory type and enable fixed and variable MTRRs */
109 movl $MTRRdefType_MSR, %ecx
111 /* Enable Variable and Fixed MTRRs */
112 movl $0x00000c00, %eax
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
137 .long 0x200, 0x201, 0x202, 0x203
138 .long 0x204, 0x205, 0x206, 0x207
139 .long 0x208, 0x209, 0x20A, 0x20B
140 .long 0x20C, 0x20D, 0x20E, 0x20F
141 .long 0x000 /* NULL, end of table */
143 clear_fixed_var_mtrr_out:
145 /* 0x06 is the WB IO type for a given 4k segment.
146 * segs is the number of 4k segments in the area of the particular
147 * register we want to use for CAR.
148 * reg is the register where the IO type should be stored.
150 .macro extractmask segs, reg
152 /* The xorl here is superfluous because at the point of first execution
153 * of this macro, %eax and %edx are cleared. Later invocations of this
154 * macro will have a monotonically increasing segs parameter.
158 movl $0x06000000, \reg /* WB IO type */
160 movl $0x06060000, \reg /* WB IO type */
162 movl $0x06060600, \reg /* WB IO type */
164 movl $0x06060606, \reg /* WB IO type */
168 /* size is the cache size in bytes we want to use for CAR.
169 * windowoffset is the 32k-aligned window into CAR size
171 .macro simplemask carsize, windowoffset
172 .set gas_bug_workaround,(((\carsize - \windowoffset) / 0x1000) - 4)
173 extractmask gas_bug_workaround, %eax
174 .set gas_bug_workaround,(((\carsize - \windowoffset) / 0x1000))
175 extractmask gas_bug_workaround, %edx
176 /* Without the gas bug workaround, the entire macro would consist only of the
178 extractmask (((\carsize - \windowoffset) / 0x1000) - 4), %eax
179 extractmask (((\carsize - \windowoffset) / 0x1000)), %edx
183 #if CacheSize > 0x10000
184 #error Invalid CAR size, must be at most 64k.
186 #if CacheSize < 0x1000
187 #error Invalid CAR size, must be at least 4k. This is a processor limitation.
189 #if (CacheSize & (0x1000 - 1))
190 #error Invalid CAR size, is not a multiple of 4k. This is a processor limitation.
193 #if CacheSize > 0x8000
194 /* enable caching for 32K-64K using fixed mtrr */
195 movl $0x268, %ecx /* fix4k_c0000*/
196 simplemask CacheSize, 0x8000
200 /* enable caching for 0-32K using fixed mtrr */
201 movl $0x269, %ecx /* fix4k_c8000*/
202 simplemask CacheSize, 0
205 #if defined(CONFIG_XIP_ROM_SIZE) && defined(CONFIG_XIP_ROM_BASE)
206 #if defined(CONFIG_TINY_BOOTBLOCK) && CONFIG_TINY_BOOTBLOCK
207 #define REAL_XIP_ROM_BASE AUTO_XIP_ROM_BASE
209 #define REAL_XIP_ROM_BASE CONFIG_XIP_ROM_BASE
211 /* enable write base caching so we can do execute in place
216 movl $REAL_XIP_ROM_BASE, %eax
217 orl $MTRR_TYPE_WRBACK, %eax
221 movl $0x0000000f, %edx
222 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | 0x800), %eax
224 #endif /* CONFIG_XIP_ROM_SIZE && CONFIG_XIP_ROM_BASE */
228 andl $0x9fffffff, %eax
231 /* Read the range with lodsl*/
232 movl $CacheBase, %esi
234 movl $(CacheSize >> 2), %ecx
237 /* Clear the range */
238 movl $CacheBase, %edi
239 movl $(CacheSize >> 2), %ecx
245 /* check the cache as ram */
246 movl $CacheBase, %esi
247 movl $(CacheSize>>2), %ecx
257 movl $CacheBase, %esi
258 // movl $(CacheSize>>2), %ecx
272 je .xin2 /* dont show */
288 movl $(CacheBase + CacheSize - 4), %eax
291 /* Load a different set of data segments */
293 movw $CACHE_RAM_DATA_SEG, %ax
300 /* Restore the BIST result */
303 /* We need to set ebp ? No need */
305 pushl %eax /* bist */
309 FIXME : backup stack in CACHE_AS_RAM into mmx and sse and after we get STACK up, we restore that.
310 It is only needed if we want to go back
313 /* We don't need cache as ram for now on */
320 movl $0x269, %ecx /* fix4k_c8000*/
325 #if CONFIG_DCACHE_RAM_SIZE > 0x8000
326 movl $0x268, %ecx /* fix4k_c0000*/
330 /* Set the default memory type and disable fixed and enable variable MTRRs */
332 // movl $MTRRdefType_MSR, %ecx
334 /* Enable Variable and Disable Fixed MTRRs */
335 movl $0x00000800, %eax
338 #if defined(CLEAR_FIRST_1M_RAM)
339 /* enable caching for first 1M using variable mtrr */
343 // movl $(0 | MTRR_TYPE_WRCOMB), %eax
347 movl $0x0000000f, %edx /* AMD 40 bit 0xff*/
348 movl $((~(( 0 + 0x100000) - 1)) | 0x800), %eax
354 andl $0x9fffffff,%eax
357 #if defined(CLEAR_FIRST_1M_RAM)
358 /* clear the first 1M */
361 movl $(0x100000>>2), %ecx
370 /* enable caching for first 1M using variable mtrr */
374 // movl $(0 | MTRR_TYPE_WRBACK), %eax
378 movl $0x0000000f, %edx /* AMD 40 bit 0xff*/
379 movl $((~(( 0 + 0x100000) - 1)) | 0x800), %eax
384 andl $0x9fffffff,%eax
388 /* FIXME: I hope we don't need to change esp and ebp value here, so we
389 * can restore value from mmx sse back But the problem is the range is
390 * some io related, So don't go back
394 /* clear boot_complete flag */
398 cld /* clear direction flag */
402 movl $ROMSTAGE_STACK, %esp