blob: 53056038b7f43b4ce1d895682c7321bf4963645e [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
Timothy Pearson1f780992015-06-01 23:58:59 -050023#define CacheBase CONFIG_DCACHE_RAM_BASE
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
Timothy Pearson38508a02015-06-25 15:07:34 -0500362 jmp_if_fam15h(fam15_skip_dram_mtrr_setup)
363
Uwe Hermann42926842010-09-30 23:15:36 +0000364 /* Enable memory access for first MBs using top_mem. */
Marc Jones2006b382007-12-19 00:47:09 +0000365 movl $TOP_MEM, %ecx
366 xorl %edx, %edx
Myles Watson0f61a4f2009-10-16 16:32:57 +0000367 movl $(((CONFIG_RAMTOP) + TOP_MEM_MASK) & ~TOP_MEM_MASK) , %eax
Marc Jones2006b382007-12-19 00:47:09 +0000368 wrmsr
Yinghai Lu6f63c022005-12-14 20:08:23 +0000369
Timothy Pearson38508a02015-06-25 15:07:34 -0500370fam15_skip_dram_mtrr_setup:
371
Patrick Georgi784544b2011-10-31 17:07:52 +0100372#if CONFIG_XIP_ROM_SIZE
Rudolf Marek95c50c62010-01-05 17:35:44 +0000373
Uwe Hermann42926842010-09-30 23:15:36 +0000374 /* Enable write base caching so we can do execute in place (XIP)
375 * on the flash ROM.
Uwe Hermann1d36d6d2010-09-30 21:22:40 +0000376 */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700377 movl $MTRR_PHYS_BASE(1), %ecx
Uwe Hermann1d36d6d2010-09-30 21:22:40 +0000378 xorl %edx, %edx
Uwe Hermann36455aa2010-10-02 20:51:29 +0000379 /*
Patrick Georgi1da10462011-10-28 20:28:03 +0200380 * IMPORTANT: The following calculation _must_ be done at runtime. See
Uwe Hermann36455aa2010-10-02 20:51:29 +0000381 * http://www.coreboot.org/pipermail/coreboot/2010-October/060855.html
382 */
Rudolf Marek9438da32011-10-30 18:06:58 +0100383 movl $copy_and_run, %eax
Patrick Georgi1da10462011-10-28 20:28:03 +0200384 andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
385 orl $MTRR_TYPE_WRBACK, %eax
Marc Jones2006b382007-12-19 00:47:09 +0000386 wrmsr
arch import user (historical)6ca76362005-07-06 17:17:25 +0000387
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700388 movl $MTRR_PHYS_MASK(1), %ecx
Stefan Reinauer08670622009-06-30 15:17:49 +0000389 movl $0xff, %edx /* (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1 for K8 (CONFIG_CPU_ADDR_BITS = 40) */
Patrick Georgi08afc6d2009-02-17 12:56:58 +0000390 jmp_if_k8(wbcache_post_fam10_setup)
Stefan Reinauer08670622009-06-30 15:17:49 +0000391 movl $0xffff, %edx /* (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1 for FAM10 (CONFIG_CPU_ADDR_BITS = 48) */
Patrick Georgi08afc6d2009-02-17 12:56:58 +0000392wbcache_post_fam10_setup:
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700393 movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
Marc Jones2006b382007-12-19 00:47:09 +0000394 wrmsr
Patrick Georgi784544b2011-10-31 17:07:52 +0100395#endif /* CONFIG_XIP_ROM_SIZE */
arch import user (historical)6ca76362005-07-06 17:17:25 +0000396
Uwe Hermann42926842010-09-30 23:15:36 +0000397 /* Set the default memory type and enable fixed and variable MTRRs. */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700398 movl $MTRR_DEF_TYPE_MSR, %ecx
Marc Jones2006b382007-12-19 00:47:09 +0000399 xorl %edx, %edx
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700400 movl $(MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN), %eax
Marc Jones2006b382007-12-19 00:47:09 +0000401 wrmsr
402
Uwe Hermann42926842010-09-30 23:15:36 +0000403 /* Enable the MTRRs and IORRs in SYSCFG. */
Marc Jones2006b382007-12-19 00:47:09 +0000404 movl $SYSCFG_MSR, %ecx
405 rdmsr
Myles Watson707fad02009-10-23 18:22:27 +0000406 orl $(SYSCFG_MSR_MtrrVarDramEn | SYSCFG_MSR_MtrrFixDramEn), %eax
Marc Jones2006b382007-12-19 00:47:09 +0000407 wrmsr
Marc Jones2006b382007-12-19 00:47:09 +0000408
Timothy Pearson730a0432015-10-16 13:51:51 -0500409fam10_mtrr_setup_complete:
Stefan Reinaueraed99202010-06-07 08:29:36 +0000410 post_code(0xa1)
Carl-Daniel Hailfingerf2ecb742008-01-08 17:28:35 +0000411
Timothy Pearson730a0432015-10-16 13:51:51 -0500412 /* Disable conversion of INVD to WBINVD (INVDWBINVD = 0) */
413 mov $0xc0010015, %ecx
414 rdmsr
415 btr $4, %eax
416 wrmsr
417
418jmp_if_not_fam15h(fam15_car_msr_setup_complete)
419 /* Disable streaming store (DisSS = 1) */
420 mov $0xc0011020, %ecx
421 rdmsr
422 bts $28, %eax
423 wrmsr
424
425 /* Disable speculative ITLB reloads (DisSpecTlbRld = 1) */
426 mov $0xc0011021, %ecx
427 rdmsr
428 bts $9, %eax
429 wrmsr
430
431 /* Disable speculative DTLB reloads (DisSpecTlbRld = 1) and set DisHwPf = 1 */
432 mov $0xc0011022, %ecx
433 rdmsr
434 bts $4, %eax
435 bts $13, %eax
436 wrmsr
437
438 /* Disable CR0 combining (CombineCr0Cd = 0) */
439 mov $0xc001102b, %ecx
440 rdmsr
441 btr $49-32, %edx
442 wrmsr
443fam15_car_msr_setup_complete:
444
Stefan Reinauer7b0500c2011-01-19 06:54:42 +0000445 /* Enable cache. */
446 movl %cr0, %eax
Patrick Georgi05e740f2012-03-31 12:52:21 +0200447 andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
Stefan Reinauer7b0500c2011-01-19 06:54:42 +0000448 movl %eax, %cr0
Marc Jones2006b382007-12-19 00:47:09 +0000449
Timothy Pearsone67d2402015-10-29 01:09:55 -0500450 jmp_if_not_k8(CAR_skip_k8_errata_part1)
451
452 /* Set DisFillP on BSP. */
453 movl $0x8000c068, %eax
454 movw $0xcf8, %dx
455 outl %eax, %dx
456 addw $4, %dx
457 inl %dx, %eax
458 bts $10, %eax
459 outl %eax, %dx
460
461CAR_skip_k8_errata_part1:
462
Patrick Georgi08afc6d2009-02-17 12:56:58 +0000463 jmp_if_k8(fam10_end_part1)
464
Uwe Hermann42926842010-09-30 23:15:36 +0000465 /* So we need to check if it is BSP. */
Marc Jones8ae8c882007-12-19 01:32:08 +0000466 movl $0x1b, %ecx
467 rdmsr
Uwe Hermann66d16872010-10-01 07:27:51 +0000468 bt $8, %eax /* BSP */
Marc Jones8ae8c882007-12-19 01:32:08 +0000469 jnc CAR_FAM10_ap
Patrick Georgi08afc6d2009-02-17 12:56:58 +0000470fam10_end_part1:
Carl-Daniel Hailfingerf2ecb742008-01-08 17:28:35 +0000471
Stefan Reinaueraed99202010-06-07 08:29:36 +0000472 post_code(0xa2)
Marc Jones8ae8c882007-12-19 01:32:08 +0000473
Uwe Hermann42926842010-09-30 23:15:36 +0000474 /* Read the range with lodsl. */
Yinghai Lu6f63c022005-12-14 20:08:23 +0000475 cld
Marc Jones2006b382007-12-19 00:47:09 +0000476 movl $CacheBase, %esi
477 movl $(CacheSize >> 2), %ecx
Myles Watson707fad02009-10-23 18:22:27 +0000478 rep lodsl
479
Uwe Hermann42926842010-09-30 23:15:36 +0000480 /* Clear the range. */
Marc Jones2006b382007-12-19 00:47:09 +0000481 movl $CacheBase, %edi
482 movl $(CacheSize >> 2), %ecx
483 xorl %eax, %eax
Myles Watson707fad02009-10-23 18:22:27 +0000484 rep stosl
arch import user (historical)6ca76362005-07-06 17:17:25 +0000485
Timothy Pearsone67d2402015-10-29 01:09:55 -0500486 jmp_if_not_k8(CAR_skip_k8_errata_part2)
487
488 /* Clear DisFillP on BSP. */
489 movl $0x8000c068, %eax
490 movw $0xcf8, %dx
491 outl %eax, %dx
492 addw $4, %dx
493 inl %dx, %eax
494 btr $10, %eax
495 outl %eax, %dx
496
497CAR_skip_k8_errata_part2:
498
Uwe Hermann42926842010-09-30 23:15:36 +0000499 /* Set up the stack pointer. */
Patrick Georgibbc880e2012-11-20 18:20:56 +0100500 movl $(CacheBase + CacheSize), %eax
Marc Jones2006b382007-12-19 00:47:09 +0000501 movl %eax, %esp
Carl-Daniel Hailfingerf2ecb742008-01-08 17:28:35 +0000502
Timothy Pearson1f780992015-06-01 23:58:59 -0500503 /* Poison the lower stack boundary */
504 movl $((CacheBase + CacheSize) - CacheSizeBSPStack), %eax
505 movl $0xdeadbeef, (%eax)
506
Stefan Reinaueraed99202010-06-07 08:29:36 +0000507 post_code(0xa3)
Marc Jones8ae8c882007-12-19 01:32:08 +0000508
Marc Jones8ae8c882007-12-19 01:32:08 +0000509 jmp CAR_FAM10_ap_out
510CAR_FAM10_ap:
Uwe Hermann42926842010-09-30 23:15:36 +0000511 /*
512 * Need to set stack pointer for AP.
513 * It will be from:
Timothy Pearsonfb39f822015-06-02 20:25:03 -0500514 * CacheBase + (CacheSize - (CacheSizeBSPStack + CacheSizeBSPSlush))
Uwe Hermann42926842010-09-30 23:15:36 +0000515 * - (NodeID << CoreIDbits + CoreID) * CacheSizeAPStack
Timothy Pearsonfb39f822015-06-02 20:25:03 -0500516 * The spacing between the BSP stack and the top of the AP
517 * stacks is purposefully set larger (an extra CacheSizeBSPSlush
518 * worth of unused space) than necessary to aid debugging when
519 * additional stack variables are added by future developers.
520 * The extra space will allow BSP overruns to be caught by
521 * the warning logic and easily fixed instead of crashing the
522 * system with no obvious clues of what went wrong.
523 *
524 * So, need to get the NodeID and CoreID at first.
Uwe Hermann42926842010-09-30 23:15:36 +0000525 * If NB_CFG bit 54 is set just use initial APIC ID, otherwise need
526 * to reverse it.
527 */
Marc Jones8ae8c882007-12-19 01:32:08 +0000528
Uwe Hermann42926842010-09-30 23:15:36 +0000529 /* Get the coreid bits at first. */
Marc Jones8ae8c882007-12-19 01:32:08 +0000530 movl $0x80000008, %eax
531 cpuid
532 shrl $12, %ecx
533 andl $0x0f, %ecx
534 movl %ecx, %edi
535
Uwe Hermann42926842010-09-30 23:15:36 +0000536 /* Get the initial APIC ID. */
Marc Jones8ae8c882007-12-19 01:32:08 +0000537 movl $1, %eax
538 cpuid
539 shrl $24, %ebx
540
Uwe Hermann42926842010-09-30 23:15:36 +0000541 /* Get the nb cfg bit 54. */
542 movl $0xc001001f, %ecx /* NB_CFG_MSR */
Marc Jones8ae8c882007-12-19 01:32:08 +0000543 rdmsr
Uwe Hermann42926842010-09-30 23:15:36 +0000544 movl %edi, %ecx /* CoreID bits */
Uwe Hermann66d16872010-10-01 07:27:51 +0000545 bt $(54 - 32), %edx
Marc Jones8ae8c882007-12-19 01:32:08 +0000546 jc roll_cfg
Timothy Pearson730a0432015-10-16 13:51:51 -0500547
548 /* Fam10h NB config bit 54 was not set */
Marc Jones8ae8c882007-12-19 01:32:08 +0000549 rolb %cl, %bl
550roll_cfg:
Timothy Pearson0122afb2015-07-30 14:07:15 -0500551 jmp_if_not_fam15h(ap_apicid_ready)
552 cmp $0x5, %ecx
553 jne ap_apicid_ready
Carl-Daniel Hailfingerf2ecb742008-01-08 17:28:35 +0000554
Timothy Pearson0122afb2015-07-30 14:07:15 -0500555 /* This is a multi-node CPU
556 * Adjust the maximum APIC ID to a more reasonable value
557 * given that no 32-core Family 15h processors exist
558 */
559 movl %ebx, %ecx
560 and $0x0f, %ecx /* Get lower 4 bits of CPU number */
561 and $0x60, %ebx /* Get node ID */
562 shrl $0x1, %ebx /* Shift node ID part of APIC ID down by 1 */
563 or %ecx, %ebx /* Recombine node ID and CPU number */
564
565ap_apicid_ready:
566
567 /* Calculate stack pointer using adjusted APIC ID stored in ebx */
Marc Jones8ae8c882007-12-19 01:32:08 +0000568 movl $CacheSizeAPStack, %eax
569 mull %ebx
Timothy Pearsonfb39f822015-06-02 20:25:03 -0500570 movl $(CacheBase + (CacheSize - (CacheSizeBSPStack + CacheSizeBSPSlush))), %esp
Marc Jones8ae8c882007-12-19 01:32:08 +0000571 subl %eax, %esp
572
Timothy Pearson730a0432015-10-16 13:51:51 -0500573 /* Restore init detect */
574 cvtsd2si %xmm5, %ebx
Marc Jones8ae8c882007-12-19 01:32:08 +0000575
Stefan Reinaueraed99202010-06-07 08:29:36 +0000576 post_code(0xa4)
Marc Jones8ae8c882007-12-19 01:32:08 +0000577
578CAR_FAM10_ap_out:
Marc Jones8ae8c882007-12-19 01:32:08 +0000579
Stefan Reinaueraed99202010-06-07 08:29:36 +0000580 post_code(0xa5)
arch import user (historical)6ca76362005-07-06 17:17:25 +0000581
Stefan Reinauer7b0500c2011-01-19 06:54:42 +0000582 /* Disable SSE. */
583 movl %cr4, %eax
584 andl $~(3 << 9), %eax
585 movl %eax, %cr4
Patrick Georgi08afc6d2009-02-17 12:56:58 +0000586
Timothy Pearson730a0432015-10-16 13:51:51 -0500587 post_code(0xa6)
588
Stefan Reinauer7b0500c2011-01-19 06:54:42 +0000589 /* Restore the BIST result. */
590 movl %ebp, %eax
Carl-Daniel Hailfingerf2ecb742008-01-08 17:28:35 +0000591
Uwe Hermann42926842010-09-30 23:15:36 +0000592 /* We need to set EBP? No need. */
arch import user (historical)6ca76362005-07-06 17:17:25 +0000593 movl %esp, %ebp
Uwe Hermann42926842010-09-30 23:15:36 +0000594 pushl %ebx /* Init detected. */
595 pushl %eax /* BIST */
Timothy Pearson730a0432015-10-16 13:51:51 -0500596
597 post_code(0xa7)
598
Marc Jones2006b382007-12-19 00:47:09 +0000599 call cache_as_ram_main
Vladimir Serbinenkoa6c29fe2013-11-26 17:49:29 +0100600
Uwe Hermann42926842010-09-30 23:15:36 +0000601 /* We will not go back. */
arch import user (historical)6ca76362005-07-06 17:17:25 +0000602
Uwe Hermann42926842010-09-30 23:15:36 +0000603 post_code(0xaf) /* Should never see this POST code. */
Marc Jones8ae8c882007-12-19 01:32:08 +0000604
Vladimir Serbinenkoa6c29fe2013-11-26 17:49:29 +0100605 .globl cache_as_ram_switch_stack
606
607cache_as_ram_switch_stack:
608 /* Return address. */
609 popl %eax
Kyösti Mälkkiabc083e2013-12-29 12:07:54 +0200610 /* New stack. */
Vladimir Serbinenkoa6c29fe2013-11-26 17:49:29 +0100611 popl %eax
Kyösti Mälkkiabc083e2013-12-29 12:07:54 +0200612 movl %eax, %esp
Vladimir Serbinenkoa6c29fe2013-11-26 17:49:29 +0100613 call cache_as_ram_new_stack
614
Warren Turkal4ffde942010-10-12 06:13:40 +0000615all_mtrr_msrs:
616 /* fixed MTRR MSRs */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700617 .long MTRR_FIX_64K_00000
618 .long MTRR_FIX_16K_80000
619 .long MTRR_FIX_16K_A0000
620 .long MTRR_FIX_4K_C0000
621 .long MTRR_FIX_4K_C8000
622 .long MTRR_FIX_4K_D0000
623 .long MTRR_FIX_4K_D8000
624 .long MTRR_FIX_4K_E0000
625 .long MTRR_FIX_4K_E8000
626 .long MTRR_FIX_4K_F0000
627 .long MTRR_FIX_4K_F8000
Uwe Hermann42926842010-09-30 23:15:36 +0000628
Warren Turkal4ffde942010-10-12 06:13:40 +0000629 /* var MTRR MSRs */
Alexandru Gagniuc86091f92015-09-30 20:23:09 -0700630 .long MTRR_PHYS_BASE(0)
631 .long MTRR_PHYS_MASK(0)
632 .long MTRR_PHYS_BASE(1)
633 .long MTRR_PHYS_MASK(1)
634 .long MTRR_PHYS_BASE(2)
635 .long MTRR_PHYS_MASK(2)
636 .long MTRR_PHYS_BASE(3)
637 .long MTRR_PHYS_MASK(3)
638 .long MTRR_PHYS_BASE(4)
639 .long MTRR_PHYS_MASK(4)
640 .long MTRR_PHYS_BASE(5)
641 .long MTRR_PHYS_MASK(5)
642 .long MTRR_PHYS_BASE(6)
643 .long MTRR_PHYS_MASK(6)
644 .long MTRR_PHYS_BASE(7)
645 .long MTRR_PHYS_MASK(7)
Uwe Hermann42926842010-09-30 23:15:36 +0000646
Warren Turkal4ffde942010-10-12 06:13:40 +0000647 /* Variable IORR MTRR MSRs */
648 .long IORRBase_MSR(0)
649 .long IORRMask_MSR(0)
650 .long IORRBase_MSR(1)
651 .long IORRMask_MSR(1)
Uwe Hermann42926842010-09-30 23:15:36 +0000652
Warren Turkal4ffde942010-10-12 06:13:40 +0000653 /* Top of memory MTRR MSRs */
Kyösti Mälkki0127c6c2015-03-05 14:35:04 +0200654 .long TOP_MEM
655 .long TOP_MEM2
Warren Turkal4ffde942010-10-12 06:13:40 +0000656
Marc Jones2006b382007-12-19 00:47:09 +0000657 .long 0x000 /* NULL, end of table */
658
Stefan Reinauer806e1462005-12-01 10:54:44 +0000659cache_as_ram_setup_out: