blob: 5c616c52fa6e0653dc6c34c16a0f10a80da599a8 [file] [log] [blame]
Myles Watson707fad02009-10-23 18:22:27 +00001/*
Stefan Reinauer7e61e452008-01-18 10:35:56 +00002 * This file is part of the coreboot project.
Myles Watson707fad02009-10-23 18:22:27 +00003 *
Carl-Daniel Hailfinger4d1aa0a2008-01-08 17:06:38 +00004 * 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
Myles Watson707fad02009-10-23 18:22:27 +000011 *
Carl-Daniel Hailfinger4d1aa0a2008-01-08 17:06:38 +000012 * 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.
Myles Watson707fad02009-10-23 18:22:27 +000015 *
Carl-Daniel Hailfinger4d1aa0a2008-01-08 17:06:38 +000016 * 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.
Myles Watson707fad02009-10-23 18:22:27 +000020 *
Carl-Daniel Hailfinger4d1aa0a2008-01-08 17:06:38 +000021 * 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
24 */
25
arch import user (historical)6ca76362005-07-06 17:17:25 +000026/* We will use 4K bytes only */
arch import user (historical)fb07bf42005-07-06 18:17:43 +000027/* disable HyperThreading is done by eswar*/
28/* other's is the same as AMD except remove amd specific msr */
29
Stefan Reinauer08670622009-06-30 15:17:49 +000030#define CacheSize CONFIG_DCACHE_RAM_SIZE
Myles Watson707fad02009-10-23 18:22:27 +000031#define CacheBase (0xd0000 - CacheSize)
arch import user (historical)6ca76362005-07-06 17:17:25 +000032
33#include <cpu/x86/mtrr.h>
34
35 /* Save the BIST result */
Myles Watson707fad02009-10-23 18:22:27 +000036 movl %eax, %ebp
arch import user (historical)6ca76362005-07-06 17:17:25 +000037
38CacheAsRam:
39 /* hope we can skip the double set for normal part */
Stefan Reinauer08670622009-06-30 15:17:49 +000040#if CONFIG_USE_FALLBACK_IMAGE == 1
arch import user (historical)6ca76362005-07-06 17:17:25 +000041
Myles Watson707fad02009-10-23 18:22:27 +000042 // Check whether the processor has HT capability
43 movl $01, %eax
44 cpuid
45 btl $28, %edx
46 jnc NotHtProcessor
47 bswapl %ebx
48 cmpb $01, %bh
49 jbe NotHtProcessor
arch import user (historical)fb07bf42005-07-06 18:17:43 +000050
Myles Watson707fad02009-10-23 18:22:27 +000051 // It is a HT processor; Send SIPI to the other logical processor
52 // within this processor so that the CAR related common system registers
53 // are programmed accordingly
arch import user (historical)fb07bf42005-07-06 18:17:43 +000054
Myles Watson707fad02009-10-23 18:22:27 +000055 // Use some register that is common to both logical processors
56 // as semaphore. Refer Appendix B, Vol.3
57 xorl %eax, %eax
58 xorl %edx, %edx
59 movl $0x250, %ecx
60 wrmsr
arch import user (historical)fb07bf42005-07-06 18:17:43 +000061
Myles Watson707fad02009-10-23 18:22:27 +000062 // Figure out the logical AP's APIC ID; the following logic will work
63 // only for processors with 2 threads
64 // Refer to Vol 3. Table 7-1 for details about this logic
65 movl $0xFEE00020, %esi
66 movl (%esi), %ebx
67 andl $0xFF000000, %ebx
68 bswapl %ebx
69 btl $0, %ebx
70 jnc LogicalAP0
71 andb $0xFE, %bl
72 jmp Send_SIPI
arch import user (historical)fb07bf42005-07-06 18:17:43 +000073LogicalAP0:
Myles Watson707fad02009-10-23 18:22:27 +000074 orb $0x01, %bl
arch import user (historical)fb07bf42005-07-06 18:17:43 +000075Send_SIPI:
Myles Watson707fad02009-10-23 18:22:27 +000076 bswapl %ebx // ebx - logical AP's APIC ID
arch import user (historical)fb07bf42005-07-06 18:17:43 +000077
Myles Watson707fad02009-10-23 18:22:27 +000078 // Fill up the IPI command registers in the Local APIC mapped to default address
79 // and issue SIPI to the other logical processor within this processor die.
arch import user (historical)fb07bf42005-07-06 18:17:43 +000080Retry_SIPI:
Myles Watson707fad02009-10-23 18:22:27 +000081 movl %ebx, %eax
82 movl $0xFEE00310, %esi
83 movl %eax, (%esi)
arch import user (historical)fb07bf42005-07-06 18:17:43 +000084
Myles Watson707fad02009-10-23 18:22:27 +000085 // SIPI vector - F900:0000
86 movl $0x000006F9, %eax
87 movl $0xFEE00300, %esi
88 movl %eax, (%esi)
arch import user (historical)fb07bf42005-07-06 18:17:43 +000089
Myles Watson707fad02009-10-23 18:22:27 +000090 movl $0x30, %ecx
arch import user (historical)fb07bf42005-07-06 18:17:43 +000091SIPI_Delay:
Myles Watson707fad02009-10-23 18:22:27 +000092 pause
93 decl %ecx
94 jnz SIPI_Delay
arch import user (historical)fb07bf42005-07-06 18:17:43 +000095
Myles Watson707fad02009-10-23 18:22:27 +000096 movl (%esi), %eax
97 andl $0x00001000, %eax
98 jnz Retry_SIPI
arch import user (historical)fb07bf42005-07-06 18:17:43 +000099
Myles Watson707fad02009-10-23 18:22:27 +0000100 // Wait for the Logical AP to complete initialization
arch import user (historical)fb07bf42005-07-06 18:17:43 +0000101LogicalAP_SIPINotdone:
Myles Watson707fad02009-10-23 18:22:27 +0000102 movl $0x250, %ecx
103 rdmsr
104 orl %eax, %eax
105 jz LogicalAP_SIPINotdone
arch import user (historical)fb07bf42005-07-06 18:17:43 +0000106
107NotHtProcessor:
108
109#if 1
Myles Watson707fad02009-10-23 18:22:27 +0000110 /* Set the default memory type and enable fixed and variable MTRRs */
111 movl $MTRRdefType_MSR, %ecx
112 xorl %edx, %edx
113 /* Enable Variable and Fixed MTRRs */
114 movl $0x00000c00, %eax
115 wrmsr
arch import user (historical)fb07bf42005-07-06 18:17:43 +0000116#endif
117
Myles Watson707fad02009-10-23 18:22:27 +0000118 /* Clear all MTRRs */
119 xorl %edx, %edx
120 movl $fixed_mtrr_msr, %esi
arch import user (historical)6ca76362005-07-06 17:17:25 +0000121
arch import user (historical)6ca76362005-07-06 17:17:25 +0000122clear_fixed_var_mtrr:
Myles Watson707fad02009-10-23 18:22:27 +0000123 lodsl (%esi), %eax
124 testl %eax, %eax
125 jz clear_fixed_var_mtrr_out
arch import user (historical)6ca76362005-07-06 17:17:25 +0000126
Myles Watson707fad02009-10-23 18:22:27 +0000127 movl %eax, %ecx
128 xorl %eax, %eax
129 wrmsr
arch import user (historical)6ca76362005-07-06 17:17:25 +0000130
Myles Watson707fad02009-10-23 18:22:27 +0000131 jmp clear_fixed_var_mtrr
arch import user (historical)6ca76362005-07-06 17:17:25 +0000132clear_fixed_var_mtrr_out:
133
Carl-Daniel Hailfinger4d1aa0a2008-01-08 17:06:38 +0000134/* 0x06 is the WB IO type for a given 4k segment.
135 * segs is the number of 4k segments in the area of the particular
136 * register we want to use for CAR.
137 * reg is the register where the IO type should be stored.
138 */
139.macro extractmask segs, reg
140.if \segs <= 0
141 /* The xorl here is superfluous because at the point of first execution
142 * of this macro, %eax and %edx are cleared. Later invocations of this
143 * macro will have a monotonically increasing segs parameter.
144 */
145 xorl \reg, \reg
146.elseif \segs == 1
Myles Watson707fad02009-10-23 18:22:27 +0000147 movl $0x06000000, \reg /* WB IO type */
Carl-Daniel Hailfinger4d1aa0a2008-01-08 17:06:38 +0000148.elseif \segs == 2
Myles Watson707fad02009-10-23 18:22:27 +0000149 movl $0x06060000, \reg /* WB IO type */
Carl-Daniel Hailfinger4d1aa0a2008-01-08 17:06:38 +0000150.elseif \segs == 3
Myles Watson707fad02009-10-23 18:22:27 +0000151 movl $0x06060600, \reg /* WB IO type */
Carl-Daniel Hailfinger4d1aa0a2008-01-08 17:06:38 +0000152.elseif \segs >= 4
Myles Watson707fad02009-10-23 18:22:27 +0000153 movl $0x06060606, \reg /* WB IO type */
Carl-Daniel Hailfinger4d1aa0a2008-01-08 17:06:38 +0000154.endif
155.endm
156
157/* size is the cache size in bytes we want to use for CAR.
158 * windowoffset is the 32k-aligned window into CAR size
159 */
160.macro simplemask carsize, windowoffset
Carl-Daniel Hailfinger4afb7fb2008-04-04 15:02:45 +0000161 .set gas_bug_workaround,(((\carsize - \windowoffset) / 0x1000) - 4)
162 extractmask gas_bug_workaround, %eax
163 .set gas_bug_workaround,(((\carsize - \windowoffset) / 0x1000))
164 extractmask gas_bug_workaround, %edx
165/* Without the gas bug workaround, the entire macro would consist only of the
166 * two lines below.
Carl-Daniel Hailfinger188288a2008-01-08 19:14:16 +0000167 extractmask (((\carsize - \windowoffset) / 0x1000) - 4), %eax
168 extractmask (((\carsize - \windowoffset) / 0x1000)), %edx
Carl-Daniel Hailfinger4afb7fb2008-04-04 15:02:45 +0000169 */
Carl-Daniel Hailfinger4d1aa0a2008-01-08 17:06:38 +0000170.endm
171
172#if CacheSize > 0x10000
173#error Invalid CAR size, must be at most 64k.
174#endif
175#if CacheSize < 0x1000
176#error Invalid CAR size, must be at least 4k. This is a processor limitation.
177#endif
178#if (CacheSize & (0x1000 - 1))
179#error Invalid CAR size, is not a multiple of 4k. This is a processor limitation.
180#endif
181
Myles Watson707fad02009-10-23 18:22:27 +0000182#if CacheSize > 0x8000
183 /* enable caching for 32K-64K using fixed mtrr */
184 movl $0x268, %ecx /* fix4k_c0000*/
Carl-Daniel Hailfinger4d1aa0a2008-01-08 17:06:38 +0000185 simplemask CacheSize, 0x8000
Myles Watson707fad02009-10-23 18:22:27 +0000186 wrmsr
arch import user (historical)fb07bf42005-07-06 18:17:43 +0000187#endif
188
Myles Watson707fad02009-10-23 18:22:27 +0000189 /* enable caching for 0-32K using fixed mtrr */
190 movl $0x269, %ecx /* fix4k_c8000*/
Carl-Daniel Hailfinger4d1aa0a2008-01-08 17:06:38 +0000191 simplemask CacheSize, 0
arch import user (historical)fb07bf42005-07-06 18:17:43 +0000192 wrmsr
arch import user (historical)fb07bf42005-07-06 18:17:43 +0000193
arch import user (historical)6ca76362005-07-06 17:17:25 +0000194#else
Myles Watson707fad02009-10-23 18:22:27 +0000195 /* disable cache */
196 movl %cr0, %eax
197 orl $(0x1 << 30), %eax
198 movl %eax, %cr0
arch import user (historical)6ca76362005-07-06 17:17:25 +0000199
Stefan Reinauer08670622009-06-30 15:17:49 +0000200#endif /* CONFIG_USE_FALLBACK_IMAGE == 1*/
arch import user (historical)6ca76362005-07-06 17:17:25 +0000201
Stefan Reinauer08670622009-06-30 15:17:49 +0000202#if defined(CONFIG_XIP_ROM_SIZE) && defined(CONFIG_XIP_ROM_BASE)
Myles Watson707fad02009-10-23 18:22:27 +0000203 /* enable write base caching so we can do execute in place
204 * on the flash rom.
205 */
206 movl $0x202, %ecx
207 xorl %edx, %edx
208 movl $(CONFIG_XIP_ROM_BASE | MTRR_TYPE_WRBACK), %eax
209 wrmsr
arch import user (historical)6ca76362005-07-06 17:17:25 +0000210
Myles Watson707fad02009-10-23 18:22:27 +0000211 movl $0x203, %ecx
212 movl $0x0000000f, %edx
213 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | 0x800), %eax
214 wrmsr
Stefan Reinauer08670622009-06-30 15:17:49 +0000215#endif /* CONFIG_XIP_ROM_SIZE && CONFIG_XIP_ROM_BASE */
arch import user (historical)6ca76362005-07-06 17:17:25 +0000216
Myles Watson707fad02009-10-23 18:22:27 +0000217 /* enable cache */
218 movl %cr0, %eax
219 andl $0x9fffffff, %eax
220 movl %eax, %cr0
arch import user (historical)6ca76362005-07-06 17:17:25 +0000221
Stefan Reinauer08670622009-06-30 15:17:49 +0000222#if CONFIG_USE_FALLBACK_IMAGE == 1
arch import user (historical)6ca76362005-07-06 17:17:25 +0000223
arch import user (historical)6ca76362005-07-06 17:17:25 +0000224 /* Read the range with lodsl*/
Myles Watson707fad02009-10-23 18:22:27 +0000225 movl $CacheBase, %esi
arch import user (historical)6ca76362005-07-06 17:17:25 +0000226 cld
Myles Watson707fad02009-10-23 18:22:27 +0000227 movl $(CacheSize >> 2), %ecx
228 rep lodsl
arch import user (historical)6ca76362005-07-06 17:17:25 +0000229
arch import user (historical)6ca76362005-07-06 17:17:25 +0000230 /* Clear the range */
Myles Watson707fad02009-10-23 18:22:27 +0000231 movl $CacheBase, %edi
232 movl $(CacheSize >> 2), %ecx
233 xorl %eax, %eax
234 rep stosl
arch import user (historical)6ca76362005-07-06 17:17:25 +0000235
236
arch import user (historical)fb07bf42005-07-06 18:17:43 +0000237#if 0
238 /* check the cache as ram */
Myles Watson707fad02009-10-23 18:22:27 +0000239 movl $CacheBase, %esi
240 movl $(CacheSize>>2), %ecx
241.xin1:
242 movl %esi, %eax
243 movl %eax, (%esi)
244 decl %ecx
245 je .xout1
246 add $4, %esi
247 jmp .xin1
248.xout1:
arch import user (historical)6ca76362005-07-06 17:17:25 +0000249
Myles Watson707fad02009-10-23 18:22:27 +0000250 movl $CacheBase, %esi
arch import user (historical)6ca76362005-07-06 17:17:25 +0000251// movl $(CacheSize>>2), %ecx
arch import user (historical)fb07bf42005-07-06 18:17:43 +0000252 movl $4, %ecx
253.xin1x:
Myles Watson707fad02009-10-23 18:22:27 +0000254 movl %esi, %eax
arch import user (historical)fb07bf42005-07-06 18:17:43 +0000255
Myles Watson707fad02009-10-23 18:22:27 +0000256 movl $0x4000, %edx
257 movb %ah, %al
258.testx1:
259 outb %al, $0x80
260 decl %edx
261 jnz .testx1
arch import user (historical)fb07bf42005-07-06 18:17:43 +0000262
Myles Watson707fad02009-10-23 18:22:27 +0000263 movl (%esi), %eax
264 cmpb 0xff, %al
265 je .xin2 /* dont show */
266
267 movl $0x4000, %edx
arch import user (historical)6ca76362005-07-06 17:17:25 +0000268.testx2:
Myles Watson707fad02009-10-23 18:22:27 +0000269 outb %al, $0x80
270 decl %edx
271 jnz .testx2
272
arch import user (historical)6ca76362005-07-06 17:17:25 +0000273.xin2: decl %ecx
Myles Watson707fad02009-10-23 18:22:27 +0000274 je .xout1x
275 add $4, %esi
276 jmp .xin1x
arch import user (historical)6ca76362005-07-06 17:17:25 +0000277.xout1x:
278
279#endif
Stefan Reinauer08670622009-06-30 15:17:49 +0000280#endif /*CONFIG_USE_FALLBACK_IMAGE == 1*/
arch import user (historical)6ca76362005-07-06 17:17:25 +0000281
arch import user (historical)6ca76362005-07-06 17:17:25 +0000282
Myles Watson707fad02009-10-23 18:22:27 +0000283 movl $(CacheBase + CacheSize - 4), %eax
284 movl %eax, %esp
arch import user (historical)6ca76362005-07-06 17:17:25 +0000285
286 /* Load a different set of data segments */
287#if CONFIG_USE_INIT
Myles Watson707fad02009-10-23 18:22:27 +0000288 movw $CACHE_RAM_DATA_SEG, %ax
289 movw %ax, %ds
290 movw %ax, %es
291 movw %ax, %ss
arch import user (historical)6ca76362005-07-06 17:17:25 +0000292#endif
293
294lout:
arch import user (historical)6ca76362005-07-06 17:17:25 +0000295 /* Restore the BIST result */
arch import user (historical)fb07bf42005-07-06 18:17:43 +0000296 movl %ebp, %eax
Myles Watson707fad02009-10-23 18:22:27 +0000297
arch import user (historical)6ca76362005-07-06 17:17:25 +0000298 /* We need to set ebp ? No need */
299 movl %esp, %ebp
Myles Watson707fad02009-10-23 18:22:27 +0000300 pushl %eax /* bist */
301 call amd64_main
arch import user (historical)6ca76362005-07-06 17:17:25 +0000302 /* We will not go back */
303
Myles Watson707fad02009-10-23 18:22:27 +0000304fixed_mtrr_msr:
305 .long 0x250, 0x258, 0x259
306 .long 0x268, 0x269, 0x26A
307 .long 0x26B, 0x26C, 0x26D
308 .long 0x26E, 0x26F
309var_mtrr_msr:
310 .long 0x200, 0x201, 0x202, 0x203
311 .long 0x204, 0x205, 0x206, 0x207
312 .long 0x208, 0x209, 0x20A, 0x20B
313 .long 0x20C, 0x20D, 0x20E, 0x20F
314 .long 0x000 /* NULL, end of table */
arch import user (historical)fb07bf42005-07-06 18:17:43 +0000315
Stefan Reinauer08670622009-06-30 15:17:49 +0000316#if CONFIG_USE_FALLBACK_IMAGE == 1
Myles Watson707fad02009-10-23 18:22:27 +0000317 .align 0x1000
318 .code16
arch import user (historical)fb07bf42005-07-06 18:17:43 +0000319.global LogicalAP_SIPI
320LogicalAP_SIPI:
Myles Watson707fad02009-10-23 18:22:27 +0000321 // cr0 register is shared among the logical processors;
322 // so clear CD & NW bits so that the BSP's cr0 register
323 // controls the cache behavior
324 // Note: The cache behavior is determined by "OR" result
325 // of the cr0 registers of the logical processors
arch import user (historical)fb07bf42005-07-06 18:17:43 +0000326
Myles Watson707fad02009-10-23 18:22:27 +0000327 movl %cr0, %eax
328 andl $0x9FFFFFFF, %eax
329 movl %eax, %cr0
arch import user (historical)fb07bf42005-07-06 18:17:43 +0000330
Myles Watson707fad02009-10-23 18:22:27 +0000331 finit
arch import user (historical)fb07bf42005-07-06 18:17:43 +0000332
Myles Watson707fad02009-10-23 18:22:27 +0000333 // Set the semaphore to indicate the Logical AP is done
334 // with CAR specific initialization
335 movl $0x250, %ecx
336 movl $0x06, %eax
337 xorl %edx, %edx
338 wrmsr
arch import user (historical)fb07bf42005-07-06 18:17:43 +0000339
Myles Watson707fad02009-10-23 18:22:27 +0000340 // Halt this AP
341 cli
arch import user (historical)fb07bf42005-07-06 18:17:43 +0000342Halt_LogicalAP:
Myles Watson707fad02009-10-23 18:22:27 +0000343 hlt
344 jmp Halt_LogicalAP
345 .code32
Stefan Reinauer08670622009-06-30 15:17:49 +0000346#endif /*CONFIG_USE_FALLBACK_IMAGE == 1*/
arch import user (historical)6ca76362005-07-06 17:17:25 +0000347.CacheAsRam_out: