blob: 9874ec47a2d7dec5188c27a8fbe0407740bc4218 [file] [log] [blame]
Marc Jones2006b382007-12-19 00:47:09 +00001/*
Stefan Reinauer7e61e452008-01-18 10:35:56 +00002 * This file is part of the coreboot project.
Carl-Daniel Hailfingerf2ecb742008-01-08 17:28:35 +00003 *
Marc Jones2006b382007-12-19 00:47:09 +00004 * Copyright (C) 2005-2007 Advanced Micro Devices, Inc.
Carl-Daniel Hailfinger1923fc42008-01-10 17:48:25 +00005 * Copyright (C) 2008 Carl-Daniel Hailfinger
Timothy Pearsona97e0072015-06-02 13:53:25 -05006 * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering
Marc Jones2006b382007-12-19 00:47:09 +00007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
Carl-Daniel Hailfingerf2ecb742008-01-08 17:28:35 +000016 */
17
arch import user (historical)6ca76362005-07-06 17:17:25 +000018#include <cpu/x86/mtrr.h>
Patrick Georgi05e740f2012-03-31 12:52:21 +020019#include <cpu/x86/cache.h>
arch import user (historical)6ca76362005-07-06 17:17:25 +000020#include <cpu/amd/mtrr.h>
Uwe Hermann42926842010-09-30 23:15:36 +000021
22#define CacheSize CONFIG_DCACHE_RAM_SIZE
23#define CacheBase (0xd0000 - CacheSize)
Timothy Pearsonb5e46552015-06-02 13:47:36 -050024#define CacheSizeBSPStack CONFIG_DCACHE_BSP_STACK_SIZE
Timothy Pearsonfb39f822015-06-02 20:25:03 -050025#define CacheSizeBSPSlush CONFIG_DCACHE_BSP_STACK_SLUSH
Uwe Hermann42926842010-09-30 23:15:36 +000026
Uwe Hermann42926842010-09-30 23:15:36 +000027/* For CAR with Fam10h. */
Timothy Pearsonb5e46552015-06-02 13:47:36 -050028#define CacheSizeAPStack CONFIG_DCACHE_AP_STACK_SIZE
Uwe Hermann42926842010-09-30 23:15:36 +000029
30#define MSR_MCFG_BASE 0xC0010058
Timothy Pearson730a0432015-10-16 13:51:51 -050031#define MSR_BU_CFG2 0xC001102A
Uwe Hermann42926842010-09-30 23:15:36 +000032
Timothy Pearsone67d2402015-10-29 01:09:55 -050033#define jmp_if_not_k8(x) comisd %xmm2, %xmm1; jae x
Uwe Hermann42926842010-09-30 23:15:36 +000034#define jmp_if_k8(x) comisd %xmm2, %xmm1; jb x
Timothy Pearson730a0432015-10-16 13:51:51 -050035#define jmp_if_not_fam15h(x) comisd %xmm3, %xmm1; jb x
36#define jmp_if_fam15h(x) comisd %xmm3, %xmm1; jae x
Uwe Hermann42926842010-09-30 23:15:36 +000037
38#define CPUID_MASK 0x0ff00f00
39#define CPUID_VAL_FAM10_ROTATED 0x0f000010
Timothy Pearson730a0432015-10-16 13:51:51 -050040#define CPUID_VAL_FAM15_ROTATED 0x0f000060
Uwe Hermann42926842010-09-30 23:15:36 +000041
Patrick Georgi08afc6d2009-02-17 12:56:58 +000042/*
Stefan Reinauer6f57b512010-07-08 16:41:05 +000043 * XMM map:
Uwe Hermann42926842010-09-30 23:15:36 +000044 * xmm1: CPU family
45 * xmm2: Fam10h comparison value
Timothy Pearson730a0432015-10-16 13:51:51 -050046 * xmm3: Fam15h comparison value
47 * xmm4: Backup EBX
48 * xmm5: Coreboot init detect
Stefan Reinauer6f57b512010-07-08 16:41:05 +000049 */
arch import user (historical)6ca76362005-07-06 17:17:25 +000050
Stefan Reinauer7b0500c2011-01-19 06:54:42 +000051 /* Save the BIST result. */
52 movl %eax, %ebp
Marc Jones2006b382007-12-19 00:47:09 +000053
Uwe Hermann42926842010-09-30 23:15:36 +000054 /*
55 * For normal part %ebx already contain cpu_init_detected
56 * from fallback call.
57 */
arch import user (historical)6ca76362005-07-06 17:17:25 +000058
Stefan Reinauer806e1462005-12-01 10:54:44 +000059cache_as_ram_setup:
Stefan Reinaueraed99202010-06-07 08:29:36 +000060 post_code(0xa0)
Yinghai Lu6f63c022005-12-14 20:08:23 +000061
Stefan Reinauer7b0500c2011-01-19 06:54:42 +000062 /* Enable SSE. */
63 movl %cr4, %eax
64 orl $(3 << 9), %eax
65 movl %eax, %cr4
Patrick Georgi08afc6d2009-02-17 12:56:58 +000066
Uwe Hermann42926842010-09-30 23:15:36 +000067 /* Figure out the CPU family. */
Timothy Pearson730a0432015-10-16 13:51:51 -050068 cvtsi2sd %ebx, %xmm4
Patrick Georgi08afc6d2009-02-17 12:56:58 +000069 movl $0x01, %eax
70 cpuid
Uwe Hermann42926842010-09-30 23:15:36 +000071 /* Base family is bits 8..11, extended family is bits 20..27. */
Patrick Georgi08afc6d2009-02-17 12:56:58 +000072 andl $CPUID_MASK, %eax
Uwe Hermann42926842010-09-30 23:15:36 +000073 /* Reorder bits for easier comparison by value. */
Patrick Georgi08afc6d2009-02-17 12:56:58 +000074 roll $0x10, %eax
75 cvtsi2sd %eax, %xmm1
76 movl $CPUID_VAL_FAM10_ROTATED, %eax
77 cvtsi2sd %eax, %xmm2
Timothy Pearson730a0432015-10-16 13:51:51 -050078 movl $CPUID_VAL_FAM15_ROTATED, %eax
79 cvtsi2sd %eax, %xmm3
80 cvtsd2si %xmm4, %ebx
Patrick Georgi08afc6d2009-02-17 12:56:58 +000081
Uwe Hermann42926842010-09-30 23:15:36 +000082 /* Check if cpu_init_detected. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070083 movl $MTRR_DEF_TYPE_MSR, %ecx
Ronald G. Minnichfb0a64b2005-11-23 21:01:08 +000084 rdmsr
Alexandru Gagniuc86091f92015-09-30 20:23:09 -070085 andl $MTRR_DEF_TYPE_EN, %eax
Uwe Hermann42926842010-09-30 23:15:36 +000086 movl %eax, %ebx /* We store the status. */
Timothy Pearson730a0432015-10-16 13:51:51 -050087 cvtsi2sd %ebx, %xmm5
Marc Jones2006b382007-12-19 00:47:09 +000088
Patrick Georgi08afc6d2009-02-17 12:56:58 +000089 jmp_if_k8(CAR_FAM10_out_post_errata)
90
Uwe Hermann42926842010-09-30 23:15:36 +000091 /*
92 * For GH, CAR need to set DRAM Base/Limit registers to direct that
93 * to node0.
94 * Only BSP needed, for other nodes set during HT/memory init.
95 * So we need to check if it is BSP.
96 */
Marc Jones8ae8c882007-12-19 01:32:08 +000097 movl $0x1b, %ecx
98 rdmsr
Uwe Hermann66d16872010-10-01 07:27:51 +000099 bt $8, %eax /* BSP */
Marc Jones8ae8c882007-12-19 01:32:08 +0000100 jnc CAR_FAM10_out
101
Uwe Hermann42926842010-09-30 23:15:36 +0000102 /* Enable RT tables on BSP. */
Marc Jones8ae8c882007-12-19 01:32:08 +0000103 movl $0x8000c06c, %eax
104 movw $0xcf8, %dx
105 outl %eax, %dx
106 addw $4, %dx
107 inl %dx, %eax
108 btr $0, %eax
109 outl %eax, %dx
110
Uwe Hermann42926842010-09-30 23:15:36 +0000111 /* Setup temporary DRAM map: [0,16M) bit 0-23. */
Marc Jones8ae8c882007-12-19 01:32:08 +0000112 movl $0x8000c144, %eax
113 movw $0xcf8, %dx
114 outl %eax, %dx
115 addw $4, %dx
116 movl $0, %eax
117 outl %eax, %dx
118
119 movl $0x8000c140, %eax
120 movw $0xcf8, %dx
121 outl %eax, %dx
122 addw $4, %dx
123 movl $3, %eax
124 outl %eax, %dx
125
126CAR_FAM10_out:
127
Timothy Pearson730a0432015-10-16 13:51:51 -0500128 jmp_if_fam15h(CAR_FAM10_errata_applied)
Uwe Hermann42926842010-09-30 23:15:36 +0000129 /*
130 * Errata 193: Disable clean copybacks to L3 cache to allow cached ROM.
131 * Re-enable it in after RAM is initialized and before CAR is disabled.
Stefan Reinauer6f57b512010-07-08 16:41:05 +0000132 */
Timothy Pearson730a0432015-10-16 13:51:51 -0500133 movl $MSR_BU_CFG2, %ecx
Marc Jones8ae8c882007-12-19 01:32:08 +0000134 rdmsr
Timothy Pearson730a0432015-10-16 13:51:51 -0500135 bts $15, %eax /* Set bit 15 in EDX:EAX (bit 15 in EAX). */
Marc Jones8ae8c882007-12-19 01:32:08 +0000136 wrmsr
Patrick Georgi08afc6d2009-02-17 12:56:58 +0000137
Marco Schmidtc263b442009-06-06 11:21:52 +0000138 /* Erratum 343, RevGuide for Fam10h, Pub#41322 Rev. 3.33 */
Timothy Pearson730a0432015-10-16 13:51:51 -0500139 movl $MSR_BU_CFG2, %ecx
Marco Schmidtc263b442009-06-06 11:21:52 +0000140 rdmsr
Uwe Hermann42926842010-09-30 23:15:36 +0000141 bts $35-32, %edx /* Set bit 35 in EDX:EAX (bit 3 in EDX). */
Marco Schmidtc263b442009-06-06 11:21:52 +0000142 wrmsr
143
Timothy Pearson730a0432015-10-16 13:51:51 -0500144CAR_FAM10_errata_applied:
145
Myles Watson2b286142010-09-13 17:46:13 +0000146#if CONFIG_MMCONF_SUPPORT
Scott Duplichanbda153b2010-10-19 21:08:11 +0000147 #if (CONFIG_MMCONF_BASE_ADDRESS > 0xFFFFFFFF)
148 #error "MMCONF_BASE_ADDRESS too big"
149 #elif (CONFIG_MMCONF_BASE_ADDRESS & 0xFFFFF)
150 #error "MMCONF_BASE_ADDRESS not 1MB aligned"
151 #endif
152 movl $0, %edx
153 movl $((CONFIG_MMCONF_BASE_ADDRESS) | (1 << 0)), %eax
154 #if (CONFIG_MMCONF_BUS_NUMBER == 1)
155 #elif (CONFIG_MMCONF_BUS_NUMBER == 2)
156 orl $(1 << 2), %eax
157 #elif (CONFIG_MMCONF_BUS_NUMBER == 4)
Patrick Georgi472efa62012-02-16 20:44:20 +0100158 orl $(2 << 2), %eax
Scott Duplichanbda153b2010-10-19 21:08:11 +0000159 #elif (CONFIG_MMCONF_BUS_NUMBER == 8)
160 orl $(3 << 2), %eax
161 #elif (CONFIG_MMCONF_BUS_NUMBER == 16)
162 orl $(4 << 2), %eax
163 #elif (CONFIG_MMCONF_BUS_NUMBER == 32)
164 orl $(5 << 2), %eax
165 #elif (CONFIG_MMCONF_BUS_NUMBER == 64)
166 orl $(6 << 2), %eax
167 #elif (CONFIG_MMCONF_BUS_NUMBER == 128)
168 orl $(7 << 2), %eax
169 #elif (CONFIG_MMCONF_BUS_NUMBER == 256)
170 orl $(8 << 2), %eax
171 #else
172 #error "bad MMCONF_BUS_NUMBER value"
173 #endif
Patrick Georgie5760af2014-03-30 18:53:12 +0200174 movl $MSR_MCFG_BASE, %ecx
Arne Georg Gleditsche7a5b762010-09-13 15:11:35 +0000175 wrmsr
176#endif
177
Patrick Georgi08afc6d2009-02-17 12:56:58 +0000178CAR_FAM10_out_post_errata:
Marc Jones8ae8c882007-12-19 01:32:08 +0000179
Timothy Pearson730a0432015-10-16 13:51:51 -0500180 /* Fam15h APIC IDs do not depend on NB config bit 54 */
181 jmp_if_not_fam15h(skip_nb54_set)
182 movl $0xc001001f, %ecx /* NB_CFG_MSR */
183 rdmsr
184 bts $(54 - 32), %edx /* Set NB config bit 54 */
185 wrmsr
186
187skip_nb54_set:
188 /* On Fam15h CPUs each compute unit's MTRRs are shared between two cores */
189 jmp_if_not_fam15h(skip_cu_check)
190
191 /* Get the initial APIC ID. */
192 movl $1, %eax
193 cpuid
194 movl %ebx, %eax
195
196 /* Restore init detect */
197 cvtsd2si %xmm5, %ebx
198
199 /* Determine if this is the second core to start in a compute unit; if so, wait for first core start, clear init detect and skip MTRR init */
200 bt $24, %eax
201 jnc skip_cu_check /* First core in the compute unit jumps to skip_cu_check */
202
203 /* Determine if this is the second core to start in a compute unit; if so, clear init detect and skip MTRR init */
204 /* Busywait until the first core sets up the MTRRs */
205check_init_detect_1:
206 /* Check if cpu_init_detected. */
207 movl $MTRR_DEF_TYPE_MSR, %ecx
208 rdmsr
209 andl $MTRR_DEF_TYPE_EN, %eax
210 cmp $0x00000000, %eax
211 je check_init_detect_1 /* First core has not yet started */
212
213check_init_detect_2:
214 movl $SYSCFG_MSR, %ecx
215 rdmsr
216 andl $(SYSCFG_MSR_MtrrFixDramEn | SYSCFG_MSR_MtrrVarDramEn), %eax
217 cmp $0x00000000, %eax
218 je check_init_detect_2 /* First core has not yet started */
219
220 /* First core has now started */
221 movl $0x00000000, %ebx /* Clear init detect flag */
222 cvtsi2sd %ebx, %xmm5
223 jmp fam10_mtrr_setup_complete
224
225skip_cu_check:
226
227 jmp_if_not_fam15h(CAR_FAM15_errata_applied)
228
229 /* Erratum 714, RevGuide for Fam15h, Pub#48063 Rev. 3.24 */
230 movl $MSR_BU_CFG2, %ecx
231 rdmsr
232 bts $8, %eax /* Set bit 8 in EDX:EAX (bit 8 in EAX). */
233 wrmsr
234
235CAR_FAM15_errata_applied:
236
Uwe Hermann42926842010-09-30 23:15:36 +0000237 /* Set MtrrFixDramModEn for clear fixed MTRR. */
arch import user (historical)6ca76362005-07-06 17:17:25 +0000238enable_fixed_mtrr_dram_modify:
239 movl $SYSCFG_MSR, %ecx
240 rdmsr
Marc Jones2006b382007-12-19 00:47:09 +0000241 andl $(~(SYSCFG_MSR_MtrrFixDramEn | SYSCFG_MSR_MtrrVarDramEn)), %eax
arch import user (historical)6ca76362005-07-06 17:17:25 +0000242 orl $SYSCFG_MSR_MtrrFixDramModEn, %eax
243 wrmsr
244
Uwe Hermann42926842010-09-30 23:15:36 +0000245 /* Clear all MTRRs. */
Marc Jones2006b382007-12-19 00:47:09 +0000246 xorl %edx, %edx
Warren Turkal4ffde942010-10-12 06:13:40 +0000247 movl $all_mtrr_msrs, %esi
Carl-Daniel Hailfingerf2ecb742008-01-08 17:28:35 +0000248
arch import user (historical)6ca76362005-07-06 17:17:25 +0000249clear_fixed_var_mtrr:
Marc Jones2006b382007-12-19 00:47:09 +0000250 lodsl (%esi), %eax
251 testl %eax, %eax
Myles Watson707fad02009-10-23 18:22:27 +0000252 jz clear_fixed_var_mtrr_out
arch import user (historical)6ca76362005-07-06 17:17:25 +0000253
Marc Jones2006b382007-12-19 00:47:09 +0000254 movl %eax, %ecx
255 xorl %eax, %eax
256 wrmsr
arch import user (historical)6ca76362005-07-06 17:17:25 +0000257
Myles Watson707fad02009-10-23 18:22:27 +0000258 jmp clear_fixed_var_mtrr
arch import user (historical)6ca76362005-07-06 17:17:25 +0000259clear_fixed_var_mtrr_out:
260
Uwe Hermann42926842010-09-30 23:15:36 +0000261/*
262 * 0x06 is the WB IO type for a given 4k segment.
Carl-Daniel Hailfinger1923fc42008-01-10 17:48:25 +0000263 * 0x1e is the MEM IO type for a given 4k segment (K10 and above).
264 * segs is the number of 4k segments in the area of the particular
Uwe Hermann42926842010-09-30 23:15:36 +0000265 * register we want to use for CAR.
Carl-Daniel Hailfinger1923fc42008-01-10 17:48:25 +0000266 * reg is the register where the IO type should be stored.
267 */
268.macro extractmask segs, reg
269.if \segs <= 0
Uwe Hermann42926842010-09-30 23:15:36 +0000270 /*
271 * The xorl here is superfluous because at the point of first execution
Carl-Daniel Hailfinger1923fc42008-01-10 17:48:25 +0000272 * of this macro, %eax and %edx are cleared. Later invocations of this
273 * macro will have a monotonically increasing segs parameter.
274 */
Uwe Hermann42926842010-09-30 23:15:36 +0000275 xorl \reg, \reg
Patrick Georgi08afc6d2009-02-17 12:56:58 +0000276.else
277 jmp_if_k8(1f)
278
279.if \segs == 1
Uwe Hermann42926842010-09-30 23:15:36 +0000280 movl $0x1e000000, \reg /* WB MEM type */
Carl-Daniel Hailfinger1923fc42008-01-10 17:48:25 +0000281.elseif \segs == 2
Uwe Hermann42926842010-09-30 23:15:36 +0000282 movl $0x1e1e0000, \reg /* WB MEM type */
Carl-Daniel Hailfinger1923fc42008-01-10 17:48:25 +0000283.elseif \segs == 3
Uwe Hermann42926842010-09-30 23:15:36 +0000284 movl $0x1e1e1e00, \reg /* WB MEM type */
Carl-Daniel Hailfinger1923fc42008-01-10 17:48:25 +0000285.elseif \segs >= 4
Uwe Hermann42926842010-09-30 23:15:36 +0000286 movl $0x1e1e1e1e, \reg /* WB MEM type */
Patrick Georgi08afc6d2009-02-17 12:56:58 +0000287.endif
288 jmp 2f
2891:
290.if \segs == 1
Uwe Hermann42926842010-09-30 23:15:36 +0000291 movl $0x06000000, \reg /* WB IO type */
Carl-Daniel Hailfinger1923fc42008-01-10 17:48:25 +0000292.elseif \segs == 2
Uwe Hermann42926842010-09-30 23:15:36 +0000293 movl $0x06060000, \reg /* WB IO type */
Carl-Daniel Hailfinger1923fc42008-01-10 17:48:25 +0000294.elseif \segs == 3
Uwe Hermann42926842010-09-30 23:15:36 +0000295 movl $0x06060600, \reg /* WB IO type */
Carl-Daniel Hailfinger1923fc42008-01-10 17:48:25 +0000296.elseif \segs >= 4
Uwe Hermann42926842010-09-30 23:15:36 +0000297 movl $0x06060606, \reg /* WB IO type */
Carl-Daniel Hailfinger1923fc42008-01-10 17:48:25 +0000298.endif
Patrick Georgi08afc6d2009-02-17 12:56:58 +00002992:
300.endif /* if \segs <= 0 */
Carl-Daniel Hailfinger1923fc42008-01-10 17:48:25 +0000301.endm
Marc Jones8ae8c882007-12-19 01:32:08 +0000302
Uwe Hermann42926842010-09-30 23:15:36 +0000303/*
Uwe Hermann66d16872010-10-01 07:27:51 +0000304 * carsize is the cache size in bytes we want to use for CAR.
Uwe Hermann42926842010-09-30 23:15:36 +0000305 * windowoffset is the 32k-aligned window into CAR size.
Carl-Daniel Hailfinger1923fc42008-01-10 17:48:25 +0000306 */
307.macro simplemask carsize, windowoffset
Stefan Reinauer4a45ec42015-07-07 00:54:05 +0200308 .set gas_bug_workaround,(((\carsize - \windowoffset) >> 12) - 4)
Carl-Daniel Hailfingered8dc582008-01-10 17:59:25 +0000309 extractmask gas_bug_workaround, %eax
Stefan Reinauer4a45ec42015-07-07 00:54:05 +0200310 .set gas_bug_workaround,(((\carsize - \windowoffset) >> 12))
Carl-Daniel Hailfingered8dc582008-01-10 17:59:25 +0000311 extractmask gas_bug_workaround, %edx
Uwe Hermann42926842010-09-30 23:15:36 +0000312 /*
313 * Without the gas bug workaround, the entire macro would consist
314 * only of the two lines below:
Stefan Reinauer4a45ec42015-07-07 00:54:05 +0200315 * extractmask (((\carsize - \windowoffset) >> 12) - 4), %eax
316 * extractmask (((\carsize - \windowoffset) >> 12)), %edx
Uwe Hermann42926842010-09-30 23:15:36 +0000317 */
Carl-Daniel Hailfinger1923fc42008-01-10 17:48:25 +0000318.endm
319
Timothy Pearsona97e0072015-06-02 13:53:25 -0500320#if IS_ENABLED(CONFIG_CPU_AMD_MODEL_10XXX)
321 #if CacheSize > 0x80000
322 #error Invalid CAR size, must be at most 128k (processor limit is 512k).
323 #endif
324#else
325 #if CacheSize > 0x10000
326 #error Invalid CAR size, must be at most 64k.
327 #endif
Carl-Daniel Hailfinger1923fc42008-01-10 17:48:25 +0000328#endif
329#if CacheSize < 0x1000
330#error Invalid CAR size, must be at least 4k. This is a processor limitation.
331#endif
332#if (CacheSize & (0x1000 - 1))
333#error Invalid CAR size, is not a multiple of 4k. This is a processor limitation.
Yinghai Lud4b278c2006-10-04 20:46:15 +0000334#endif
arch import user (historical)6ca76362005-07-06 17:17:25 +0000335
Myles Watson707fad02009-10-23 18:22:27 +0000336#if CacheSize > 0x8000
Uwe Hermann42926842010-09-30 23:15:36 +0000337 /* Enable caching for 32K-64K using fixed MTRR. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700338 movl $MTRR_FIX_4K_C0000, %ecx
Carl-Daniel Hailfinger1923fc42008-01-10 17:48:25 +0000339 simplemask CacheSize, 0x8000
Myles Watson707fad02009-10-23 18:22:27 +0000340 wrmsr
Yinghai Lud4b278c2006-10-04 20:46:15 +0000341#endif
342
Timothy Pearsona97e0072015-06-02 13:53:25 -0500343#if CacheSize > 0x10000
344 /* Enable caching for 64K-96K using fixed MTRR. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700345 movl $MTRR_FIX_4K_D0000, %ecx
Timothy Pearsona97e0072015-06-02 13:53:25 -0500346 simplemask CacheSize, 0x10000
347 wrmsr
348#endif
349
350#if CacheSize > 0x18000
351 /* Enable caching for 96K-128K using fixed MTRR. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700352 movl $MTRR_FIX_4K_D8000, %ecx
Timothy Pearsona97e0072015-06-02 13:53:25 -0500353 simplemask CacheSize, 0x18000
354 wrmsr
355#endif
356
Uwe Hermann42926842010-09-30 23:15:36 +0000357 /* Enable caching for 0-32K using fixed MTRR. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700358 movl $MTRR_FIX_4K_C8000, %ecx
Carl-Daniel Hailfinger1923fc42008-01-10 17:48:25 +0000359 simplemask CacheSize, 0
arch import user (historical)6ca76362005-07-06 17:17:25 +0000360 wrmsr
Yinghai Lu6f63c022005-12-14 20:08:23 +0000361
Uwe Hermann42926842010-09-30 23:15:36 +0000362 /* Enable memory access for first MBs using top_mem. */
Marc Jones2006b382007-12-19 00:47:09 +0000363 movl $TOP_MEM, %ecx
364 xorl %edx, %edx
Myles Watson0f61a4f2009-10-16 16:32:57 +0000365 movl $(((CONFIG_RAMTOP) + TOP_MEM_MASK) & ~TOP_MEM_MASK) , %eax
Marc Jones2006b382007-12-19 00:47:09 +0000366 wrmsr
Yinghai Lu6f63c022005-12-14 20:08:23 +0000367
Patrick Georgi784544b2011-10-31 17:07:52 +0100368#if CONFIG_XIP_ROM_SIZE
Rudolf Marek95c50c62010-01-05 17:35:44 +0000369
Uwe Hermann42926842010-09-30 23:15:36 +0000370 /* Enable write base caching so we can do execute in place (XIP)
371 * on the flash ROM.
Uwe Hermann1d36d6d2010-09-30 21:22:40 +0000372 */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700373 movl $MTRR_PHYS_BASE(1), %ecx
Uwe Hermann1d36d6d2010-09-30 21:22:40 +0000374 xorl %edx, %edx
Uwe Hermann36455aa2010-10-02 20:51:29 +0000375 /*
Patrick Georgi1da10462011-10-28 20:28:03 +0200376 * IMPORTANT: The following calculation _must_ be done at runtime. See
Uwe Hermann36455aa2010-10-02 20:51:29 +0000377 * http://www.coreboot.org/pipermail/coreboot/2010-October/060855.html
378 */
Rudolf Marek9438da32011-10-30 18:06:58 +0100379 movl $copy_and_run, %eax
Patrick Georgi1da10462011-10-28 20:28:03 +0200380 andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
381 orl $MTRR_TYPE_WRBACK, %eax
Marc Jones2006b382007-12-19 00:47:09 +0000382 wrmsr
arch import user (historical)6ca76362005-07-06 17:17:25 +0000383
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700384 movl $MTRR_PHYS_MASK(1), %ecx
Stefan Reinauer08670622009-06-30 15:17:49 +0000385 movl $0xff, %edx /* (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1 for K8 (CONFIG_CPU_ADDR_BITS = 40) */
Patrick Georgi08afc6d2009-02-17 12:56:58 +0000386 jmp_if_k8(wbcache_post_fam10_setup)
Stefan Reinauer08670622009-06-30 15:17:49 +0000387 movl $0xffff, %edx /* (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1 for FAM10 (CONFIG_CPU_ADDR_BITS = 48) */
Patrick Georgi08afc6d2009-02-17 12:56:58 +0000388wbcache_post_fam10_setup:
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700389 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
Marc Jones2006b382007-12-19 00:47:09 +0000390 wrmsr
Patrick Georgi784544b2011-10-31 17:07:52 +0100391#endif /* CONFIG_XIP_ROM_SIZE */
arch import user (historical)6ca76362005-07-06 17:17:25 +0000392
Uwe Hermann42926842010-09-30 23:15:36 +0000393 /* Set the default memory type and enable fixed and variable MTRRs. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700394 movl $MTRR_DEF_TYPE_MSR, %ecx
Marc Jones2006b382007-12-19 00:47:09 +0000395 xorl %edx, %edx
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700396 movl $(MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN), %eax
Marc Jones2006b382007-12-19 00:47:09 +0000397 wrmsr
398
Uwe Hermann42926842010-09-30 23:15:36 +0000399 /* Enable the MTRRs and IORRs in SYSCFG. */
Marc Jones2006b382007-12-19 00:47:09 +0000400 movl $SYSCFG_MSR, %ecx
401 rdmsr
Myles Watson707fad02009-10-23 18:22:27 +0000402 orl $(SYSCFG_MSR_MtrrVarDramEn | SYSCFG_MSR_MtrrFixDramEn), %eax
Marc Jones2006b382007-12-19 00:47:09 +0000403 wrmsr
Marc Jones2006b382007-12-19 00:47:09 +0000404
Timothy Pearson730a0432015-10-16 13:51:51 -0500405fam10_mtrr_setup_complete:
Stefan Reinaueraed99202010-06-07 08:29:36 +0000406 post_code(0xa1)
Carl-Daniel Hailfingerf2ecb742008-01-08 17:28:35 +0000407
Timothy Pearson730a0432015-10-16 13:51:51 -0500408 /* Disable conversion of INVD to WBINVD (INVDWBINVD = 0) */
409 mov $0xc0010015, %ecx
410 rdmsr
411 btr $4, %eax
412 wrmsr
413
414jmp_if_not_fam15h(fam15_car_msr_setup_complete)
415 /* Disable streaming store (DisSS = 1) */
416 mov $0xc0011020, %ecx
417 rdmsr
418 bts $28, %eax
419 wrmsr
420
421 /* Disable speculative ITLB reloads (DisSpecTlbRld = 1) */
422 mov $0xc0011021, %ecx
423 rdmsr
424 bts $9, %eax
425 wrmsr
426
427 /* Disable speculative DTLB reloads (DisSpecTlbRld = 1) and set DisHwPf = 1 */
428 mov $0xc0011022, %ecx
429 rdmsr
430 bts $4, %eax
431 bts $13, %eax
432 wrmsr
433
434 /* Disable CR0 combining (CombineCr0Cd = 0) */
435 mov $0xc001102b, %ecx
436 rdmsr
437 btr $49-32, %edx
438 wrmsr
439fam15_car_msr_setup_complete:
440
Stefan Reinauer7b0500c2011-01-19 06:54:42 +0000441 /* Enable cache. */
442 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200443 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
Stefan Reinauer7b0500c2011-01-19 06:54:42 +0000444 movl %eax, %cr0
Marc Jones2006b382007-12-19 00:47:09 +0000445
Timothy Pearsone67d2402015-10-29 01:09:55 -0500446 jmp_if_not_k8(CAR_skip_k8_errata_part1)
447
448 /* Set DisFillP on BSP. */
449 movl $0x8000c068, %eax
450 movw $0xcf8, %dx
451 outl %eax, %dx
452 addw $4, %dx
453 inl %dx, %eax
454 bts $10, %eax
455 outl %eax, %dx
456
457CAR_skip_k8_errata_part1:
458
Patrick Georgi08afc6d2009-02-17 12:56:58 +0000459 jmp_if_k8(fam10_end_part1)
460
Uwe Hermann42926842010-09-30 23:15:36 +0000461 /* So we need to check if it is BSP. */
Marc Jones8ae8c882007-12-19 01:32:08 +0000462 movl $0x1b, %ecx
463 rdmsr
Uwe Hermann66d16872010-10-01 07:27:51 +0000464 bt $8, %eax /* BSP */
Marc Jones8ae8c882007-12-19 01:32:08 +0000465 jnc CAR_FAM10_ap
Patrick Georgi08afc6d2009-02-17 12:56:58 +0000466fam10_end_part1:
Carl-Daniel Hailfingerf2ecb742008-01-08 17:28:35 +0000467
Stefan Reinaueraed99202010-06-07 08:29:36 +0000468 post_code(0xa2)
Marc Jones8ae8c882007-12-19 01:32:08 +0000469
Uwe Hermann42926842010-09-30 23:15:36 +0000470 /* Read the range with lodsl. */
Yinghai Lu6f63c022005-12-14 20:08:23 +0000471 cld
Marc Jones2006b382007-12-19 00:47:09 +0000472 movl $CacheBase, %esi
473 movl $(CacheSize >> 2), %ecx
Myles Watson707fad02009-10-23 18:22:27 +0000474 rep lodsl
475
Uwe Hermann42926842010-09-30 23:15:36 +0000476 /* Clear the range. */
Marc Jones2006b382007-12-19 00:47:09 +0000477 movl $CacheBase, %edi
478 movl $(CacheSize >> 2), %ecx
479 xorl %eax, %eax
Myles Watson707fad02009-10-23 18:22:27 +0000480 rep stosl
arch import user (historical)6ca76362005-07-06 17:17:25 +0000481
Timothy Pearsone67d2402015-10-29 01:09:55 -0500482 jmp_if_not_k8(CAR_skip_k8_errata_part2)
483
484 /* Clear DisFillP on BSP. */
485 movl $0x8000c068, %eax
486 movw $0xcf8, %dx
487 outl %eax, %dx
488 addw $4, %dx
489 inl %dx, %eax
490 btr $10, %eax
491 outl %eax, %dx
492
493CAR_skip_k8_errata_part2:
494
Uwe Hermann42926842010-09-30 23:15:36 +0000495 /* Set up the stack pointer. */
Patrick Georgibbc880e2012-11-20 18:20:56 +0100496 movl $(CacheBase + CacheSize), %eax
Marc Jones2006b382007-12-19 00:47:09 +0000497 movl %eax, %esp
Carl-Daniel Hailfingerf2ecb742008-01-08 17:28:35 +0000498
Stefan Reinaueraed99202010-06-07 08:29:36 +0000499 post_code(0xa3)
Marc Jones8ae8c882007-12-19 01:32:08 +0000500
Marc Jones8ae8c882007-12-19 01:32:08 +0000501 jmp CAR_FAM10_ap_out
502CAR_FAM10_ap:
Uwe Hermann42926842010-09-30 23:15:36 +0000503 /*
504 * Need to set stack pointer for AP.
505 * It will be from:
Timothy Pearsonfb39f822015-06-02 20:25:03 -0500506 * CacheBase + (CacheSize - (CacheSizeBSPStack + CacheSizeBSPSlush))
Uwe Hermann42926842010-09-30 23:15:36 +0000507 * - (NodeID << CoreIDbits + CoreID) * CacheSizeAPStack
Timothy Pearsonfb39f822015-06-02 20:25:03 -0500508 * The spacing between the BSP stack and the top of the AP
509 * stacks is purposefully set larger (an extra CacheSizeBSPSlush
510 * worth of unused space) than necessary to aid debugging when
511 * additional stack variables are added by future developers.
512 * The extra space will allow BSP overruns to be caught by
513 * the warning logic and easily fixed instead of crashing the
514 * system with no obvious clues of what went wrong.
515 *
516 * So, need to get the NodeID and CoreID at first.
Uwe Hermann42926842010-09-30 23:15:36 +0000517 * If NB_CFG bit 54 is set just use initial APIC ID, otherwise need
518 * to reverse it.
519 */
Marc Jones8ae8c882007-12-19 01:32:08 +0000520
Uwe Hermann42926842010-09-30 23:15:36 +0000521 /* Get the coreid bits at first. */
Marc Jones8ae8c882007-12-19 01:32:08 +0000522 movl $0x80000008, %eax
523 cpuid
524 shrl $12, %ecx
525 andl $0x0f, %ecx
526 movl %ecx, %edi
527
Uwe Hermann42926842010-09-30 23:15:36 +0000528 /* Get the initial APIC ID. */
Marc Jones8ae8c882007-12-19 01:32:08 +0000529 movl $1, %eax
530 cpuid
531 shrl $24, %ebx
532
Uwe Hermann42926842010-09-30 23:15:36 +0000533 /* Get the nb cfg bit 54. */
534 movl $0xc001001f, %ecx /* NB_CFG_MSR */
Marc Jones8ae8c882007-12-19 01:32:08 +0000535 rdmsr
Uwe Hermann42926842010-09-30 23:15:36 +0000536 movl %edi, %ecx /* CoreID bits */
Uwe Hermann66d16872010-10-01 07:27:51 +0000537 bt $(54 - 32), %edx
Marc Jones8ae8c882007-12-19 01:32:08 +0000538 jc roll_cfg
Timothy Pearson730a0432015-10-16 13:51:51 -0500539
540 /* Fam10h NB config bit 54 was not set */
Marc Jones8ae8c882007-12-19 01:32:08 +0000541 rolb %cl, %bl
542roll_cfg:
Carl-Daniel Hailfingerf2ecb742008-01-08 17:28:35 +0000543
Uwe Hermann42926842010-09-30 23:15:36 +0000544 /* Calculate stack pointer. */
Marc Jones8ae8c882007-12-19 01:32:08 +0000545 movl $CacheSizeAPStack, %eax
546 mull %ebx
Timothy Pearsonfb39f822015-06-02 20:25:03 -0500547 movl $(CacheBase + (CacheSize - (CacheSizeBSPStack + CacheSizeBSPSlush))), %esp
Marc Jones8ae8c882007-12-19 01:32:08 +0000548 subl %eax, %esp
549
Timothy Pearson730a0432015-10-16 13:51:51 -0500550 /* Restore init detect */
551 cvtsd2si %xmm5, %ebx
Marc Jones8ae8c882007-12-19 01:32:08 +0000552
Stefan Reinaueraed99202010-06-07 08:29:36 +0000553 post_code(0xa4)
Marc Jones8ae8c882007-12-19 01:32:08 +0000554
555CAR_FAM10_ap_out:
Marc Jones8ae8c882007-12-19 01:32:08 +0000556
Stefan Reinaueraed99202010-06-07 08:29:36 +0000557 post_code(0xa5)
arch import user (historical)6ca76362005-07-06 17:17:25 +0000558
Stefan Reinauer7b0500c2011-01-19 06:54:42 +0000559 /* Disable SSE. */
560 movl %cr4, %eax
561 andl $~(3 << 9), %eax
562 movl %eax, %cr4
Patrick Georgi08afc6d2009-02-17 12:56:58 +0000563
Timothy Pearson730a0432015-10-16 13:51:51 -0500564 post_code(0xa6)
565
Stefan Reinauer7b0500c2011-01-19 06:54:42 +0000566 /* Restore the BIST result. */
567 movl %ebp, %eax
Carl-Daniel Hailfingerf2ecb742008-01-08 17:28:35 +0000568
Uwe Hermann42926842010-09-30 23:15:36 +0000569 /* We need to set EBP? No need. */
arch import user (historical)6ca76362005-07-06 17:17:25 +0000570 movl %esp, %ebp
Uwe Hermann42926842010-09-30 23:15:36 +0000571 pushl %ebx /* Init detected. */
572 pushl %eax /* BIST */
Timothy Pearson730a0432015-10-16 13:51:51 -0500573
574 post_code(0xa7)
575
Marc Jones2006b382007-12-19 00:47:09 +0000576 call cache_as_ram_main
Vladimir Serbinenkoa6c29fe2013-11-26 17:49:29 +0100577
Uwe Hermann42926842010-09-30 23:15:36 +0000578 /* We will not go back. */
arch import user (historical)6ca76362005-07-06 17:17:25 +0000579
Uwe Hermann42926842010-09-30 23:15:36 +0000580 post_code(0xaf) /* Should never see this POST code. */
Marc Jones8ae8c882007-12-19 01:32:08 +0000581
Vladimir Serbinenkoa6c29fe2013-11-26 17:49:29 +0100582 .globl cache_as_ram_switch_stack
583
584cache_as_ram_switch_stack:
585 /* Return address. */
586 popl %eax
Kyösti Mälkkiabc083e2013-12-29 12:07:54 +0200587 /* New stack. */
Vladimir Serbinenkoa6c29fe2013-11-26 17:49:29 +0100588 popl %eax
Kyösti Mälkkiabc083e2013-12-29 12:07:54 +0200589 movl %eax, %esp
Vladimir Serbinenkoa6c29fe2013-11-26 17:49:29 +0100590 call cache_as_ram_new_stack
591
Warren Turkal4ffde942010-10-12 06:13:40 +0000592all_mtrr_msrs:
593 /* fixed MTRR MSRs */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700594 .long MTRR_FIX_64K_00000
595 .long MTRR_FIX_16K_80000
596 .long MTRR_FIX_16K_A0000
597 .long MTRR_FIX_4K_C0000
598 .long MTRR_FIX_4K_C8000
599 .long MTRR_FIX_4K_D0000
600 .long MTRR_FIX_4K_D8000
601 .long MTRR_FIX_4K_E0000
602 .long MTRR_FIX_4K_E8000
603 .long MTRR_FIX_4K_F0000
604 .long MTRR_FIX_4K_F8000
Uwe Hermann42926842010-09-30 23:15:36 +0000605
Warren Turkal4ffde942010-10-12 06:13:40 +0000606 /* var MTRR MSRs */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700607 .long MTRR_PHYS_BASE(0)
608 .long MTRR_PHYS_MASK(0)
609 .long MTRR_PHYS_BASE(1)
610 .long MTRR_PHYS_MASK(1)
611 .long MTRR_PHYS_BASE(2)
612 .long MTRR_PHYS_MASK(2)
613 .long MTRR_PHYS_BASE(3)
614 .long MTRR_PHYS_MASK(3)
615 .long MTRR_PHYS_BASE(4)
616 .long MTRR_PHYS_MASK(4)
617 .long MTRR_PHYS_BASE(5)
618 .long MTRR_PHYS_MASK(5)
619 .long MTRR_PHYS_BASE(6)
620 .long MTRR_PHYS_MASK(6)
621 .long MTRR_PHYS_BASE(7)
622 .long MTRR_PHYS_MASK(7)
Uwe Hermann42926842010-09-30 23:15:36 +0000623
Warren Turkal4ffde942010-10-12 06:13:40 +0000624 /* Variable IORR MTRR MSRs */
625 .long IORRBase_MSR(0)
626 .long IORRMask_MSR(0)
627 .long IORRBase_MSR(1)
628 .long IORRMask_MSR(1)
Uwe Hermann42926842010-09-30 23:15:36 +0000629
Warren Turkal4ffde942010-10-12 06:13:40 +0000630 /* Top of memory MTRR MSRs */
Kyösti Mälkki0127c6c2015-03-05 14:35:04 +0200631 .long TOP_MEM
632 .long TOP_MEM2
Warren Turkal4ffde942010-10-12 06:13:40 +0000633
Marc Jones2006b382007-12-19 00:47:09 +0000634 .long 0x000 /* NULL, end of table */
635
Stefan Reinauer806e1462005-12-01 10:54:44 +0000636cache_as_ram_setup_out: