2 * This file is part of the coreboot project.
4 * Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com>
5 * Copyright (C) 2005 Tyan (written by Yinghai Lu for Tyan)
6 * Copyright (C) 2007-2008 coresystems GmbH
7 * Copyright (C) 2012 Kyösti Mälkki <kyosti.malkki@gmail.com>
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.
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.
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
23 #include <cpu/x86/stack.h>
24 #include <cpu/x86/mtrr.h>
25 #include <cpu/x86/post_code.h>
26 #include <cpu/x86/lapic_def.h>
28 /* Macro to access Local APIC registers at default base. */
29 #define LAPIC(x) $(LAPIC_DEFAULT_BASE | LAPIC_ ## x)
30 #define START_IPI_VECTOR ((CONFIG_AP_SIPI_VECTOR >> 12) & 0xff)
32 /* Base address to cache all of Flash ROM, just below 4GB. */
33 #define CACHE_ROM_BASE ((1<<22 - CONFIG_CACHE_ROM_SIZE>>10)<<10)
35 #define CACHE_AS_RAM_SIZE CONFIG_DCACHE_RAM_SIZE
36 #define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
38 /* Save the BIST result. */
44 movl $LAPIC_BASE_MSR, %ecx
46 andl $LAPIC_BASE_MSR_BOOTSTRAP_PROCESSOR, %eax
49 /* Zero out all fixed range and variable range MTRRs.
50 * For hyper-threaded CPUs these are shared.
52 movl $mtrr_table, %esi
53 movl $((mtrr_table_end - mtrr_table) / 2), %edi
66 /* Configure the default memory type to uncacheable. */
67 movl $MTRRdefType_MSR, %ecx
69 andl $(~0x00000cff), %eax
74 /* Determine CPU_ADDR_BITS and load PHYSMASK high
77 movl $0x80000000, %eax
79 cmpl $0x80000008, %eax
81 movl $0x80000008, %eax
92 andl $(1<<6 | 1<<17), %edx /* PAE or PSE36 */
96 /* Preload high word of address mask (in %edx) for Variable
97 * MTRRs 0 and 1 and enable local apic at default base.
101 movl $MTRRphysMask_MSR(0), %ecx
103 movl $MTRRphysMask_MSR(1), %ecx
105 movl $LAPIC_BASE_MSR, %ecx
110 andl $(~LAPIC_BASE_MSR_ADDR_MASK), %eax
111 orl $(LAPIC_DEFAULT_BASE | LAPIC_BASE_MSR_ENABLE), %eax
118 /* Send INIT IPI to all excluding ourself. */
119 movl LAPIC(ICR), %edi
120 movl $(LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | LAPIC_DM_INIT), %eax
127 andl $LAPIC_ICR_BUSY, %ecx
132 /* For a hyper-threading processor, cache must not be disabled
133 * on an AP on the same physical package with the BSP.
153 /* Send Start IPI to all excluding ourself. */
154 movl LAPIC(ICR), %edi
155 movl $(LAPIC_DEST_ALLBUT | LAPIC_DM_STARTUP | START_IPI_VECTOR), %eax
162 andl $LAPIC_ICR_BUSY, %ecx
173 /* Wait for sibling CPU to start. */
174 1: movl $(MTRRphysBase_MSR(0)), %ecx
189 /* Do not disable cache (so BSP can enable it). */
191 andl $(~((1 << 30) | (1 << 29))), %eax
196 /* MTRR registers are shared between HT siblings. */
197 movl $(MTRRphysBase_MSR(0)), %ecx
215 /* Set Cache-as-RAM base address. */
216 movl $(MTRRphysBase_MSR(0)), %ecx
217 movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
221 /* Set Cache-as-RAM mask. */
222 movl $(MTRRphysMask_MSR(0)), %ecx
224 movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRRphysMaskValid), %eax
228 movl $MTRRdefType_MSR, %ecx
230 orl $MTRRdefTypeEn, %eax
235 /* Enable L2 cache Write-Back (WBINVD and FLUSH#).
237 * MSR is set when DisplayFamily_DisplayModel is one of:
238 * 06_0x, 06_17, 06_1C
240 * Description says this bit enables use of WBINVD and FLUSH#.
241 * Should this be set only after the system bus and/or memory
242 * controller can successfully handle write cycles?
245 #define EAX_FAMILY(a) (a << 8) /* for family <= 0fH */
246 #define EAX_MODEL(a) (((a & 0xf0) << 12) | ((a & 0xf) << 4))
251 andl $EAX_FAMILY(0x0f), %eax
252 cmpl $EAX_FAMILY(0x06), %eax
255 andl $EAX_MODEL(0xff), %eax
256 cmpl $EAX_MODEL(0x17), %eax
258 cmpl $EAX_MODEL(0x1c), %eax
260 andl $EAX_MODEL(0xf0), %eax
261 cmpl $EAX_MODEL(0x00), %eax
272 /* Enable cache (CR0.CD = 0, CR0.NW = 0). */
274 andl $(~((1 << 30) | (1 << 29))), %eax
278 /* Clear the cache memory reagion. */
281 movl $CACHE_AS_RAM_BASE, %edi
282 movl $(CACHE_AS_RAM_SIZE / 4), %ecx
285 /* Enable Cache-as-RAM mode by disabling cache. */
292 #if CONFIG_XIP_ROM_SIZE
293 /* Enable cache for our code in Flash because we do XIP here */
294 movl $MTRRphysBase_MSR(1), %ecx
297 * IMPORTANT: The following calculation _must_ be done at runtime. See
298 * http://www.coreboot.org/pipermail/coreboot/2010-October/060855.html
300 movl $copy_and_run, %eax
301 andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
302 orl $MTRR_TYPE_WRBACK, %eax
305 movl $MTRRphysMask_MSR(1), %ecx
307 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRRphysMaskValid), %eax
309 #endif /* CONFIG_XIP_ROM_SIZE */
313 andl $(~((1 << 30) | (1 << 29))), %eax
318 /* Set up the stack pointer. */
320 /* Leave some space for the struct ehci_debug_info. */
321 movl $(CACHE_AS_RAM_BASE + CACHE_AS_RAM_SIZE - 4 - 128), %esp
323 movl $(CACHE_AS_RAM_BASE + CACHE_AS_RAM_SIZE - 4), %esp
326 /* Restore the BIST result. */
333 /* Call romstage.c main function. */
347 movl $MTRRdefType_MSR, %ecx
349 andl $(~MTRRdefTypeEn), %eax
360 andl $~((1 << 30) | (1 << 29)), %eax
372 /* Enable Write Back and Speculative Reads for low RAM. */
373 movl $MTRRphysBase_MSR(0), %ecx
374 movl $(0x00000000 | MTRR_TYPE_WRBACK), %eax
377 movl $MTRRphysMask_MSR(0), %ecx
379 movl $(~(CONFIG_RAMTOP - 1) | MTRRphysMaskValid), %eax
382 /* Enable caching and Speculative Reads for Flash ROM device. */
383 movl $MTRRphysBase_MSR(1), %ecx
384 movl $(CACHE_ROM_BASE | MTRR_TYPE_WRPROT), %eax
387 movl $MTRRphysMask_MSR(1), %ecx
389 movl $(~(CONFIG_CACHE_ROM_SIZE - 1) | MTRRphysMaskValid), %eax
394 /* And enable cache again after setting MTRRs. */
396 andl $~((1 << 30) | (1 << 29)), %eax
402 movl $MTRRdefType_MSR, %ecx
404 orl $MTRRdefTypeEn, %eax
409 /* Invalidate the cache again. */
414 /* Clear boot_complete flag. */
417 post_code(POST_PREPARE_RAMSTAGE)
418 cld /* Clear direction flag. */
422 movl $ROMSTAGE_STACK, %esp
428 post_code(POST_DEAD_CODE)
434 .word 0x250, 0x258, 0x259
435 .word 0x268, 0x269, 0x26A
436 .word 0x26B, 0x26C, 0x26D
439 .word 0x200, 0x201, 0x202, 0x203
440 .word 0x204, 0x205, 0x206, 0x207
441 .word 0x208, 0x209, 0x20A, 0x20B
442 .word 0x20C, 0x20D, 0x20E, 0x20F