blob: 4e0f391d33712927e279c2b04493185ac1e7172d [file] [log] [blame]
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +02001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com>
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +02005 * Copyright (C) 2005 Tyan (written by Yinghai Lu for Tyan)
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +02006 * Copyright (C) 2007-2008 coresystems GmbH
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +02007 * Copyright (C) 2012 Kyösti Mälkki <kyosti.malkki@gmail.com>
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +02008 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; version 2 of the License.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include <cpu/x86/stack.h>
24#include <cpu/x86/mtrr.h>
Patrick Georgi05e740f2012-03-31 12:52:21 +020025#include <cpu/x86/cache.h>
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +020026#include <cpu/x86/post_code.h>
Kyösti Mälkkif9d1a422012-02-28 01:45:44 +020027#include <cpu/x86/lapic_def.h>
28
29/* Macro to access Local APIC registers at default base. */
30#define LAPIC(x) $(LAPIC_DEFAULT_BASE | LAPIC_ ## x)
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +020031#define START_IPI_VECTOR ((CONFIG_AP_SIPI_VECTOR >> 12) & 0xff)
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +020032
Kyösti Mälkki325b92f2012-02-28 00:24:15 +020033/* Base address to cache all of Flash ROM, just below 4GB. */
34#define CACHE_ROM_BASE ((1<<22 - CONFIG_CACHE_ROM_SIZE>>10)<<10)
35
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +020036#define CACHE_AS_RAM_SIZE CONFIG_DCACHE_RAM_SIZE
37#define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
38
39 /* Save the BIST result. */
40 movl %eax, %ebp
41
42cache_as_ram:
43 post_code(0x20)
44
Kyösti Mälkkia860c682012-02-28 02:06:45 +020045 movl $LAPIC_BASE_MSR, %ecx
46 rdmsr
47 andl $LAPIC_BASE_MSR_BOOTSTRAP_PROCESSOR, %eax
48 jz ap_init
49
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +020050 /* Zero out all fixed range and variable range MTRRs.
Kyösti Mälkkia860c682012-02-28 02:06:45 +020051 * For hyper-threaded CPUs these are shared.
52 */
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +020053 movl $mtrr_table, %esi
54 movl $((mtrr_table_end - mtrr_table) / 2), %edi
55 xorl %eax, %eax
56 xorl %edx, %edx
57clear_mtrrs:
58 movw (%esi), %bx
59 movzx %bx, %ecx
60 wrmsr
61 add $2, %esi
62 dec %edi
63 jnz clear_mtrrs
64
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +020065 post_code(0x21)
66
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +020067 /* Configure the default memory type to uncacheable. */
68 movl $MTRRdefType_MSR, %ecx
69 rdmsr
70 andl $(~0x00000cff), %eax
71 wrmsr
72
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +020073 post_code(0x22)
74
Kyösti Mälkkia860c682012-02-28 02:06:45 +020075 /* Determine CPU_ADDR_BITS and load PHYSMASK high
76 * word to %edx.
77 */
78 movl $0x80000000, %eax
79 cpuid
80 cmpl $0x80000008, %eax
81 jc addrsize_no_MSR
82 movl $0x80000008, %eax
83 cpuid
84 movb %al, %cl
85 sub $32, %cl
86 movl $1, %edx
87 shl %cl, %edx
88 subl $1, %edx
89 jmp addrsize_set_high
90addrsize_no_MSR:
91 movl $1, %eax
92 cpuid
93 andl $(1<<6 | 1<<17), %edx /* PAE or PSE36 */
94 jz addrsize_set_high
95 movl $0x0f, %edx
96
97 /* Preload high word of address mask (in %edx) for Variable
98 * MTRRs 0 and 1 and enable local apic at default base.
99 */
100addrsize_set_high:
101 xorl %eax, %eax
102 movl $MTRRphysMask_MSR(0), %ecx
103 wrmsr
104 movl $MTRRphysMask_MSR(1), %ecx
105 wrmsr
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +0200106 movl $LAPIC_BASE_MSR, %ecx
Kyösti Mälkkia860c682012-02-28 02:06:45 +0200107 not %edx
108 movl %edx, %ebx
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +0200109 rdmsr
Kyösti Mälkkia860c682012-02-28 02:06:45 +0200110 andl %ebx, %edx
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +0200111 andl $(~LAPIC_BASE_MSR_ADDR_MASK), %eax
112 orl $(LAPIC_DEFAULT_BASE | LAPIC_BASE_MSR_ENABLE), %eax
113 wrmsr
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +0200114
115bsp_init:
116
117 post_code(0x23)
118
119 /* Send INIT IPI to all excluding ourself. */
120 movl LAPIC(ICR), %edi
121 movl $(LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | LAPIC_DM_INIT), %eax
1221: movl %eax, (%edi)
123 movl $0x30, %ecx
1242: pause
125 dec %ecx
126 jnz 2b
127 movl (%edi), %ecx
128 andl $LAPIC_ICR_BUSY, %ecx
129 jnz 1b
130
131 post_code(0x24)
Patrick Georgi819c7d42012-03-31 13:08:12 +0200132
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +0200133 /* For a hyper-threading processor, cache must not be disabled
134 * on an AP on the same physical package with the BSP.
135 */
136 movl $01, %eax
137 cpuid
138 btl $28, %edx
139 jnc sipi_complete
140 bswapl %ebx
141 cmpb $01, %bh
142 jbe sipi_complete
143
144hyper_threading_cpu:
145
146 /* delay 10 ms */
147 movl $10000, %ecx
1481: inb $0x80, %al
149 dec %ecx
150 jnz 1b
151
152 post_code(0x25)
153
154 /* Send Start IPI to all excluding ourself. */
155 movl LAPIC(ICR), %edi
156 movl $(LAPIC_DEST_ALLBUT | LAPIC_DM_STARTUP | START_IPI_VECTOR), %eax
1571: movl %eax, (%edi)
158 movl $0x30, %ecx
1592: pause
160 dec %ecx
161 jnz 2b
162 movl (%edi), %ecx
163 andl $LAPIC_ICR_BUSY, %ecx
164 jnz 1b
165
166 /* delay 250 us */
167 movl $250, %ecx
1681: inb $0x80, %al
169 dec %ecx
170 jnz 1b
171
172 post_code(0x26)
173
174 /* Wait for sibling CPU to start. */
1751: movl $(MTRRphysBase_MSR(0)), %ecx
176 rdmsr
177 andl %eax, %eax
178 jnz sipi_complete
179
180 movl $0x30, %ecx
1812: pause
182 dec %ecx
183 jnz 2b
184 jmp 1b
185
186
187ap_init:
188 post_code(0x27)
189
190 /* Do not disable cache (so BSP can enable it). */
191 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200192 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +0200193 movl %eax, %cr0
194
195 post_code(0x28)
196
197 /* MTRR registers are shared between HT siblings. */
198 movl $(MTRRphysBase_MSR(0)), %ecx
199 movl $(1<<12), %eax
200 xorl %edx, %edx
201 wrmsr
202
203 post_code(0x29)
204
205ap_halt:
206 cli
2071: hlt
208 jnz 1b
209
210
211
212sipi_complete:
213
214 post_code(0x2a)
215
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200216 /* Set Cache-as-RAM base address. */
217 movl $(MTRRphysBase_MSR(0)), %ecx
218 movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
219 xorl %edx, %edx
220 wrmsr
221
222 /* Set Cache-as-RAM mask. */
223 movl $(MTRRphysMask_MSR(0)), %ecx
Kyösti Mälkkia860c682012-02-28 02:06:45 +0200224 rdmsr
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200225 movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRRphysMaskValid), %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200226 wrmsr
227
228 /* Enable MTRR. */
229 movl $MTRRdefType_MSR, %ecx
230 rdmsr
231 orl $MTRRdefTypeEn, %eax
232 wrmsr
233
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +0200234 post_code(0x2b)
235
Kyösti Mälkki05d6ffb2012-02-16 23:12:04 +0200236 /* Enable L2 cache Write-Back (WBINVD and FLUSH#).
237 *
238 * MSR is set when DisplayFamily_DisplayModel is one of:
239 * 06_0x, 06_17, 06_1C
240 *
241 * Description says this bit enables use of WBINVD and FLUSH#.
242 * Should this be set only after the system bus and/or memory
243 * controller can successfully handle write cycles?
244 */
245
246#define EAX_FAMILY(a) (a << 8) /* for family <= 0fH */
247#define EAX_MODEL(a) (((a & 0xf0) << 12) | ((a & 0xf) << 4))
248
249 movl $1, %eax
250 cpuid
251 movl %eax, %ebx
252 andl $EAX_FAMILY(0x0f), %eax
253 cmpl $EAX_FAMILY(0x06), %eax
254 jne no_msr_11e
255 movl %ebx, %eax
256 andl $EAX_MODEL(0xff), %eax
257 cmpl $EAX_MODEL(0x17), %eax
258 je has_msr_11e
259 cmpl $EAX_MODEL(0x1c), %eax
260 je has_msr_11e
261 andl $EAX_MODEL(0xf0), %eax
262 cmpl $EAX_MODEL(0x00), %eax
263 jne no_msr_11e
264has_msr_11e:
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200265 movl $0x11e, %ecx
266 rdmsr
267 orl $(1 << 8), %eax
268 wrmsr
Kyösti Mälkki05d6ffb2012-02-16 23:12:04 +0200269no_msr_11e:
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200270
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +0200271 post_code(0x2c)
272
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200273 /* Enable cache (CR0.CD = 0, CR0.NW = 0). */
Kyösti Mälkkif9d1a422012-02-28 01:45:44 +0200274 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200275 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200276 invd
277 movl %eax, %cr0
278
279 /* Clear the cache memory reagion. */
Kyösti Mälkkif9d1a422012-02-28 01:45:44 +0200280 cld
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200281 xorl %eax, %eax
Kyösti Mälkkif9d1a422012-02-28 01:45:44 +0200282 movl $CACHE_AS_RAM_BASE, %edi
283 movl $(CACHE_AS_RAM_SIZE / 4), %ecx
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200284 rep stosl
285
286 /* Enable Cache-as-RAM mode by disabling cache. */
287 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200288 orl $CR0_CacheDisable, %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200289 movl %eax, %cr0
290
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +0200291 post_code(0x2d)
292
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200293#if CONFIG_XIP_ROM_SIZE
294 /* Enable cache for our code in Flash because we do XIP here */
295 movl $MTRRphysBase_MSR(1), %ecx
296 xorl %edx, %edx
297 /*
298 * IMPORTANT: The following calculation _must_ be done at runtime. See
299 * http://www.coreboot.org/pipermail/coreboot/2010-October/060855.html
300 */
301 movl $copy_and_run, %eax
302 andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
303 orl $MTRR_TYPE_WRBACK, %eax
304 wrmsr
305
306 movl $MTRRphysMask_MSR(1), %ecx
Kyösti Mälkkia860c682012-02-28 02:06:45 +0200307 rdmsr
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200308 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRRphysMaskValid), %eax
309 wrmsr
310#endif /* CONFIG_XIP_ROM_SIZE */
311
312 /* Enable cache. */
313 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200314 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200315 movl %eax, %cr0
316
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +0200317 post_code(0x2e)
318
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200319 /* Set up the stack pointer. */
320#if CONFIG_USBDEBUG
321 /* Leave some space for the struct ehci_debug_info. */
Kyösti Mälkkif9d1a422012-02-28 01:45:44 +0200322 movl $(CACHE_AS_RAM_BASE + CACHE_AS_RAM_SIZE - 4 - 128), %esp
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200323#else
Kyösti Mälkkif9d1a422012-02-28 01:45:44 +0200324 movl $(CACHE_AS_RAM_BASE + CACHE_AS_RAM_SIZE - 4), %esp
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200325#endif
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200326
327 /* Restore the BIST result. */
328 movl %ebp, %eax
329 movl %esp, %ebp
330 pushl %eax
331
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +0200332 post_code(0x2f)
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200333
334 /* Call romstage.c main function. */
335 call main
Kyösti Mälkkif9d1a422012-02-28 01:45:44 +0200336 addl $4, %esp
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200337
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200338 post_code(0x30)
339
340 /* Disable cache. */
341 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200342 orl $CR0_CacheDisable, %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200343 movl %eax, %cr0
344
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +0200345 post_code(0x34)
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200346
347 /* Disable MTRR. */
348 movl $MTRRdefType_MSR, %ecx
349 rdmsr
350 andl $(~MTRRdefTypeEn), %eax
351 wrmsr
352
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +0200353 post_code(0x35)
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200354
355 invd
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200356
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +0200357 post_code(0x36)
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200358
359 /* Enable cache. */
360 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200361 andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200362 movl %eax, %cr0
363
Kyösti Mälkki0078ceb2012-02-28 02:02:27 +0200364 post_code(0x37)
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200365
366 /* Disable cache. */
367 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200368 orl $CR0_CacheDisable, %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200369 movl %eax, %cr0
370
371 post_code(0x38)
372
Kyösti Mälkkif9d1a422012-02-28 01:45:44 +0200373 /* Enable Write Back and Speculative Reads for low RAM. */
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200374 movl $MTRRphysBase_MSR(0), %ecx
375 movl $(0x00000000 | MTRR_TYPE_WRBACK), %eax
376 xorl %edx, %edx
377 wrmsr
378 movl $MTRRphysMask_MSR(0), %ecx
Kyösti Mälkkia860c682012-02-28 02:06:45 +0200379 rdmsr
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200380 movl $(~(CONFIG_RAMTOP - 1) | MTRRphysMaskValid), %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200381 wrmsr
382
Kyösti Mälkki325b92f2012-02-28 00:24:15 +0200383 /* Enable caching and Speculative Reads for Flash ROM device. */
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200384 movl $MTRRphysBase_MSR(1), %ecx
Kyösti Mälkki325b92f2012-02-28 00:24:15 +0200385 movl $(CACHE_ROM_BASE | MTRR_TYPE_WRPROT), %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200386 xorl %edx, %edx
387 wrmsr
388 movl $MTRRphysMask_MSR(1), %ecx
Kyösti Mälkkia860c682012-02-28 02:06:45 +0200389 rdmsr
Kyösti Mälkki325b92f2012-02-28 00:24:15 +0200390 movl $(~(CONFIG_CACHE_ROM_SIZE - 1) | MTRRphysMaskValid), %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200391 wrmsr
392
393 post_code(0x39)
394
395 /* And enable cache again after setting MTRRs. */
396 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200397 andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
Kyösti Mälkki5a660ca2012-02-28 00:15:30 +0200398 movl %eax, %cr0
399
400 post_code(0x3a)
401
402 /* Enable MTRR. */
403 movl $MTRRdefType_MSR, %ecx
404 rdmsr
405 orl $MTRRdefTypeEn, %eax
406 wrmsr
407
408 post_code(0x3b)
409
410 /* Invalidate the cache again. */
411 invd
412
413 post_code(0x3c)
414
415 /* Clear boot_complete flag. */
416 xorl %ebp, %ebp
417__main:
418 post_code(POST_PREPARE_RAMSTAGE)
419 cld /* Clear direction flag. */
420
421 movl %ebp, %esi
422
423 movl $ROMSTAGE_STACK, %esp
424 movl %esp, %ebp
425 pushl %esi
426 call copy_and_run
427
428.Lhlt:
429 post_code(POST_DEAD_CODE)
430 hlt
431 jmp .Lhlt
432
433mtrr_table:
434 /* Fixed MTRRs */
435 .word 0x250, 0x258, 0x259
436 .word 0x268, 0x269, 0x26A
437 .word 0x26B, 0x26C, 0x26D
438 .word 0x26E, 0x26F
439 /* Variable MTRRs */
440 .word 0x200, 0x201, 0x202, 0x203
441 .word 0x204, 0x205, 0x206, 0x207
442 .word 0x208, 0x209, 0x20A, 0x20B
443 .word 0x20C, 0x20D, 0x20E, 0x20F
444mtrr_table_end:
445