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.
19 #include <cpu/x86/mtrr.h>
20 #include <cpu/x86/cache.h>
21 #include <cpu/x86/post_code.h>
22 #include <cpu/x86/lapic_def.h>
24 /* Macro to access Local APIC registers at default base. */
25 #define LAPIC(x) $(LAPIC_DEFAULT_BASE | LAPIC_ ## x)
26 #define START_IPI_VECTOR ((CONFIG_AP_SIPI_VECTOR >> 12) & 0xff)
28 #define CACHE_AS_RAM_SIZE CONFIG_DCACHE_RAM_SIZE
29 #define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
31 /* Save the BIST result. */
37 movl $LAPIC_BASE_MSR, %ecx
39 andl $LAPIC_BASE_MSR_BOOTSTRAP_PROCESSOR, %eax
42 /* Zero out all fixed range and variable range MTRRs.
43 * For hyper-threaded CPUs these are shared.
45 movl $mtrr_table, %esi
46 movl $((mtrr_table_end - mtrr_table) >> 1), %edi
59 /* Configure the default memory type to uncacheable. */
60 movl $MTRR_DEF_TYPE_MSR, %ecx
62 andl $(~0x00000cff), %eax
67 /* Determine CPU_ADDR_BITS and load PHYSMASK high
70 movl $0x80000000, %eax
72 cmpl $0x80000008, %eax
74 movl $0x80000008, %eax
85 andl $(1<<6 | 1<<17), %edx /* PAE or PSE36 */
89 /* Preload high word of address mask (in %edx) for Variable
90 * MTRRs 0 and 1 and enable local apic at default base.
94 movl $MTRR_PHYS_MASK(0), %ecx
96 movl $MTRR_PHYS_MASK(1), %ecx
98 movl $LAPIC_BASE_MSR, %ecx
103 andl $(~LAPIC_BASE_MSR_ADDR_MASK), %eax
104 orl $(LAPIC_DEFAULT_BASE | LAPIC_BASE_MSR_ENABLE), %eax
111 /* Send INIT IPI to all excluding ourself. */
112 movl LAPIC(ICR), %edi
113 movl $(LAPIC_DEST_ALLBUT | LAPIC_INT_ASSERT | LAPIC_DM_INIT), %eax
120 andl $LAPIC_ICR_BUSY, %ecx
132 jbe sipi_complete /* only one LAPIC ID in package */
150 jbe sipi_complete /* only LAPIC ID of a core */
152 /* For a hyper-threading processor, cache must not be disabled
153 * on an AP on the same physical package with the BSP.
166 /* Send Start IPI to all excluding ourself. */
167 movl LAPIC(ICR), %edi
168 movl $(LAPIC_DEST_ALLBUT | LAPIC_DM_STARTUP | START_IPI_VECTOR), %eax
175 andl $LAPIC_ICR_BUSY, %ecx
186 /* Wait for sibling CPU to start. */
187 1: movl $(MTRR_PHYS_BASE(0)), %ecx
202 /* Do not disable cache (so BSP can enable it). */
204 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
209 /* MTRR registers are shared between HT siblings. */
210 movl $(MTRR_PHYS_BASE(0)), %ecx
228 /* Set Cache-as-RAM base address. */
229 movl $(MTRR_PHYS_BASE(0)), %ecx
230 movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
234 /* Set Cache-as-RAM mask. */
235 movl $(MTRR_PHYS_MASK(0)), %ecx
237 movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
241 movl $MTRR_DEF_TYPE_MSR, %ecx
243 orl $MTRR_DEF_TYPE_EN, %eax
248 /* Enable L2 cache Write-Back (WBINVD and FLUSH#).
250 * MSR is set when DisplayFamily_DisplayModel is one of:
251 * 06_0x, 06_17, 06_1C
253 * Description says this bit enables use of WBINVD and FLUSH#.
254 * Should this be set only after the system bus and/or memory
255 * controller can successfully handle write cycles?
258 #define EAX_FAMILY(a) (a << 8) /* for family <= 0fH */
259 #define EAX_MODEL(a) (((a & 0xf0) << 12) | ((a & 0xf) << 4))
264 andl $EAX_FAMILY(0x0f), %eax
265 cmpl $EAX_FAMILY(0x06), %eax
268 andl $EAX_MODEL(0xff), %eax
269 cmpl $EAX_MODEL(0x17), %eax
271 cmpl $EAX_MODEL(0x1c), %eax
273 andl $EAX_MODEL(0xf0), %eax
274 cmpl $EAX_MODEL(0x00), %eax
285 /* Enable cache (CR0.CD = 0, CR0.NW = 0). */
287 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
291 /* Clear the cache memory reagion. */
294 movl $CACHE_AS_RAM_BASE, %edi
295 movl $(CACHE_AS_RAM_SIZE >> 2), %ecx
298 /* Enable Cache-as-RAM mode by disabling cache. */
300 orl $CR0_CacheDisable, %eax
305 #if CONFIG_XIP_ROM_SIZE
306 /* Enable cache for our code in Flash because we do XIP here */
307 movl $MTRR_PHYS_BASE(1), %ecx
310 * IMPORTANT: The following calculation _must_ be done at runtime. See
311 * http://www.coreboot.org/pipermail/coreboot/2010-October/060855.html
313 movl $copy_and_run, %eax
314 andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
315 orl $MTRR_TYPE_WRBACK, %eax
318 movl $MTRR_PHYS_MASK(1), %ecx
320 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
322 #endif /* CONFIG_XIP_ROM_SIZE */
326 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
331 /* Set up the stack pointer. */
332 movl $(CACHE_AS_RAM_BASE + CACHE_AS_RAM_SIZE - 4), %esp
334 /* Restore the BIST result. */
341 /* Call romstage.c main function. */
349 orl $CR0_CacheDisable, %eax
355 movl $MTRR_DEF_TYPE_MSR, %ecx
357 andl $(~MTRR_DEF_TYPE_EN), %eax
368 andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
375 orl $CR0_CacheDisable, %eax
380 /* Enable Write Back and Speculative Reads for low RAM. */
381 movl $MTRR_PHYS_BASE(0), %ecx
382 movl $(0x00000000 | MTRR_TYPE_WRBACK), %eax
385 movl $MTRR_PHYS_MASK(0), %ecx
387 movl $(~(CONFIG_RAMTOP - 1) | MTRR_PHYS_MASK_VALID), %eax
391 /* Enable caching and Speculative Reads for Flash ROM device. */
392 movl $MTRR_PHYS_BASE(1), %ecx
393 movl $(CACHE_ROM_BASE | MTRR_TYPE_WRPROT), %eax
396 movl $MTRR_PHYS_MASK(1), %ecx
398 movl $(~(CACHE_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
404 /* And enable cache again after setting MTRRs. */
406 andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
412 movl $MTRR_DEF_TYPE_MSR, %ecx
414 orl $MTRR_DEF_TYPE_EN, %eax
419 /* Invalidate the cache again. */
425 post_code(POST_PREPARE_RAMSTAGE)
426 cld /* Clear direction flag. */
428 movl $CONFIG_RAMTOP, %esp
433 post_code(POST_DEAD_CODE)
439 .word 0x250, 0x258, 0x259
440 .word 0x268, 0x269, 0x26A
441 .word 0x26B, 0x26C, 0x26D
444 .word 0x200, 0x201, 0x202, 0x203
445 .word 0x204, 0x205, 0x206, 0x207
446 .word 0x208, 0x209, 0x20A, 0x20B
447 .word 0x20C, 0x20D, 0x20E, 0x20F