blob: 17b8dc063ce3d244384466097b5cf8e13c13e8d5 [file] [log] [blame]
Subrata Banik03e971c2017-03-07 14:02:23 +05301/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2015-2016 Intel Corp.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <commonlib/helpers.h>
18#include <cpu/x86/cache.h>
19#include <cpu/x86/cr.h>
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +020020#include <cpu/x86/msr.h>
Subrata Banik03e971c2017-03-07 14:02:23 +053021#include <cpu/x86/mtrr.h>
22#include <cpu/x86/post_code.h>
23#include <rules.h>
24#include <intelblocks/msr.h>
25
26.global bootblock_pre_c_entry
27bootblock_pre_c_entry:
28
29 post_code(0x20)
30
31 /*
32 * Use the MTRR default type MSR as a proxy for detecting INIT#.
33 * Reset the system if any known bits are set in that MSR. That is
34 * an indication of the CPU not being properly reset.
35 */
36check_for_clean_reset:
37 mov $MTRR_DEF_TYPE_MSR, %ecx
38 rdmsr
39 and $(MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN), %eax
40 cmp $0, %eax
41 jz no_reset
42 /* perform warm reset */
43 movw $0xcf9, %dx
44 movb $0x06, %al
45 outb %al, %dx
46
47no_reset:
48 post_code(0x21)
49
50 /* Clear/disable fixed MTRRs */
51 mov $fixed_mtrr_list_size, %ebx
52 xor %eax, %eax
53 xor %edx, %edx
54
55clear_fixed_mtrr:
56 add $-2, %ebx
57 movzwl fixed_mtrr_list(%ebx), %ecx
58 wrmsr
59 jnz clear_fixed_mtrr
60
61 post_code(0x22)
62
63 /* Figure put how many MTRRs we have, and clear them out */
64 mov $MTRR_CAP_MSR, %ecx
65 rdmsr
66 movzb %al, %ebx /* Number of variable MTRRs */
67 mov $MTRR_PHYS_BASE(0), %ecx
68 xor %eax, %eax
69 xor %edx, %edx
70
71clear_var_mtrr:
72 wrmsr
73 inc %ecx
74 wrmsr
75 inc %ecx
76 dec %ebx
77 jnz clear_var_mtrr
78
79 post_code(0x23)
80
81 /* Configure default memory type to uncacheable (UC) */
82 mov $MTRR_DEF_TYPE_MSR, %ecx
83 rdmsr
84 /* Clear enable bits and set default type to UC. */
85 and $~(MTRR_DEF_TYPE_MASK | MTRR_DEF_TYPE_EN | \
86 MTRR_DEF_TYPE_FIX_EN), %eax
87 wrmsr
88
89 /* Configure MTRR_PHYS_MASK_HIGH for proper addressing above 4GB
90 * based on the physical address size supported for this processor
91 * This is based on read from CPUID EAX = 080000008h, EAX bits [7:0]
92 *
93 * Examples:
94 * MTRR_PHYS_MASK_HIGH = 00000000Fh For 36 bit addressing
95 * MTRR_PHYS_MASK_HIGH = 0000000FFh For 40 bit addressing
96 */
97
Elyes HAOUAS05498a22018-05-28 16:26:43 +020098 movl $0x80000008, %eax /* Address sizes leaf */
Subrata Banik03e971c2017-03-07 14:02:23 +053099 cpuid
100 sub $32, %al
101 movzx %al, %eax
102 xorl %esi, %esi
103 bts %eax, %esi
104 dec %esi /* esi <- MTRR_PHYS_MASK_HIGH */
105
106 post_code(0x24)
107
108#if ((CONFIG_DCACHE_RAM_SIZE & (CONFIG_DCACHE_RAM_SIZE - 1)) == 0)
109 /* Configure CAR region as write-back (WB) */
110 mov $MTRR_PHYS_BASE(0), %ecx
111 mov $CONFIG_DCACHE_RAM_BASE, %eax
112 or $MTRR_TYPE_WRBACK, %eax
113 xor %edx,%edx
114 wrmsr
115
116 /* Configure the MTRR mask for the size region */
117 mov $MTRR_PHYS_MASK(0), %ecx
118 mov $CONFIG_DCACHE_RAM_SIZE, %eax /* size mask */
119 dec %eax
120 not %eax
121 or $MTRR_PHYS_MASK_VALID, %eax
122 movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
123 wrmsr
124#elif (CONFIG_DCACHE_RAM_SIZE == 768 * KiB) /* 768 KiB */
125 /* Configure CAR region as write-back (WB) */
126 mov $MTRR_PHYS_BASE(0), %ecx
127 mov $CONFIG_DCACHE_RAM_BASE, %eax
128 or $MTRR_TYPE_WRBACK, %eax
129 xor %edx,%edx
130 wrmsr
131
132 mov $MTRR_PHYS_MASK(0), %ecx
133 mov $(512 * KiB), %eax /* size mask */
134 dec %eax
135 not %eax
136 or $MTRR_PHYS_MASK_VALID, %eax
137 movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
138 wrmsr
139
140 mov $MTRR_PHYS_BASE(1), %ecx
141 mov $(CONFIG_DCACHE_RAM_BASE + 512 * KiB), %eax
142 or $MTRR_TYPE_WRBACK, %eax
143 xor %edx,%edx
144 wrmsr
145
146 mov $MTRR_PHYS_MASK(1), %ecx
147 mov $(256 * KiB), %eax /* size mask */
148 dec %eax
149 not %eax
150 or $MTRR_PHYS_MASK_VALID, %eax
151 movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
152 wrmsr
153#else
154#error "DCACHE_RAM_SIZE is not a power of 2 and setup code is missing"
155#endif
156 post_code(0x25)
157
158 /* Enable variable MTRRs */
159 mov $MTRR_DEF_TYPE_MSR, %ecx
160 rdmsr
161 or $MTRR_DEF_TYPE_EN, %eax
162 wrmsr
163
164 /* Enable caching */
165 mov %cr0, %eax
166 and $~(CR0_CD | CR0_NW), %eax
167 invd
168 mov %eax, %cr0
169
170#if IS_ENABLED(CONFIG_INTEL_CAR_NEM)
171 jmp car_nem
172#elif IS_ENABLED(CONFIG_INTEL_CAR_CQOS)
173 jmp car_cqos
174#elif IS_ENABLED(CONFIG_INTEL_CAR_NEM_ENHANCED)
175 jmp car_nem_enhanced
176#else
177 jmp .halt_forever /* In case nothing has selected */
178#endif
179
180.global car_init_done
181car_init_done:
182
183 post_code(0x29)
184
185 /* Setup bootblock stack */
186 mov $_car_stack_end, %esp
187
Aaron Durbin028e18f2017-06-23 11:14:58 -0500188 /* Need to align stack to 16 bytes at call instruction. Account for
189 the two pushes below. */
190 andl $0xfffffff0, %esp
191 sub $8, %esp
192
Subrata Banik03e971c2017-03-07 14:02:23 +0530193 /*push TSC value to stack*/
194 movd %mm2, %eax
195 pushl %eax /* tsc[63:32] */
196 movd %mm1, %eax
Elyes HAOUAS05498a22018-05-28 16:26:43 +0200197 pushl %eax /* tsc[31:0] */
Subrata Banik03e971c2017-03-07 14:02:23 +0530198
199before_carstage:
200 post_code(0x2A)
201
202 call bootblock_c_entry
203 /* Never reached */
204
205.halt_forever:
206 post_code(POST_DEAD_CODE)
207 hlt
208 jmp .halt_forever
209
210fixed_mtrr_list:
211 .word MTRR_FIX_64K_00000
212 .word MTRR_FIX_16K_80000
213 .word MTRR_FIX_16K_A0000
214 .word MTRR_FIX_4K_C0000
215 .word MTRR_FIX_4K_C8000
216 .word MTRR_FIX_4K_D0000
217 .word MTRR_FIX_4K_D8000
218 .word MTRR_FIX_4K_E0000
219 .word MTRR_FIX_4K_E8000
220 .word MTRR_FIX_4K_F0000
221 .word MTRR_FIX_4K_F8000
222fixed_mtrr_list_size = . - fixed_mtrr_list
223
224#if IS_ENABLED(CONFIG_INTEL_CAR_NEM)
225.global car_nem
226car_nem:
227 /* Disable cache eviction (setup stage) */
228 mov $MSR_EVICT_CTL, %ecx
229 rdmsr
230 or $0x1, %eax
231 wrmsr
232
233 post_code(0x26)
234
235 /* Clear the cache memory region. This will also fill up the cache */
236 movl $CONFIG_DCACHE_RAM_BASE, %edi
237 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
238 shr $0x02, %ecx
239 xor %eax, %eax
240 cld
241 rep stosl
242
243 post_code(0x27)
244
245 /* Disable cache eviction (run stage) */
246 mov $MSR_EVICT_CTL, %ecx
247 rdmsr
248 or $0x2, %eax
249 wrmsr
250
251 post_code(0x28)
252
253 jmp car_init_done
254
255#elif IS_ENABLED(CONFIG_INTEL_CAR_CQOS)
256.global car_cqos
257car_cqos:
258 /*
Naresh G Solankif329f0c2017-09-27 14:21:18 +0530259 * Create CBM_LEN_MASK based on CBM_LEN
260 * Get CPUID.(EAX=10H, ECX=2H):EAX.CBM_LEN[bits 4:0]
261 */
262 mov $0x10, %eax
263 mov $0x2, %ecx
264 cpuid
265 and $0x1F, %eax
266 add $1, %al
267
268 mov $1, %ebx
269 mov %al, %cl
270 shl %cl, %ebx
271 sub $1, %ebx
272
273 /* Store the CBM_LEN_MASK in mm3 for later use. */
274 movd %ebx, %mm3
275
276 /*
Subrata Banik03e971c2017-03-07 14:02:23 +0530277 * Disable both L1 and L2 prefetcher. For yet-to-understood reason,
278 * prefetchers slow down filling cache with rep stos in CQOS mode.
279 */
280 mov $MSR_PREFETCH_CTL, %ecx
281 rdmsr
282 or $(PREFETCH_L1_DISABLE | PREFETCH_L2_DISABLE), %eax
283 wrmsr
284
285#if (CONFIG_DCACHE_RAM_SIZE == CONFIG_L2_CACHE_SIZE)
286/*
287 * If CAR size is set to full L2 size, mask is calculated as all-zeros.
288 * This is not supported by the CPU/uCode.
289 */
290#error "CQOS CAR may not use whole L2 cache area"
291#endif
292
293 /* Calculate how many bits to be used for CAR */
294 xor %edx, %edx
295 mov $CONFIG_DCACHE_RAM_SIZE, %eax /* dividend */
296 mov $CONFIG_CACHE_QOS_SIZE_PER_BIT, %ecx /* divisor */
297 div %ecx /* result is in eax */
298 mov %eax, %ecx /* save to ecx */
299 mov $1, %ebx
300 shl %cl, %ebx
301 sub $1, %ebx /* resulting mask is is in ebx */
302
303 /* Set this mask for initial cache fill */
304 mov $MSR_L2_QOS_MASK(0), %ecx
305 rdmsr
Naresh G Solankif329f0c2017-09-27 14:21:18 +0530306 mov %ebx, %eax
Subrata Banik03e971c2017-03-07 14:02:23 +0530307 wrmsr
308
309 /* Set CLOS selector to 0 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200310 mov $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530311 rdmsr
312 and $~IA32_PQR_ASSOC_MASK, %edx /* select mask 0 */
313 wrmsr
314
315 /* We will need to block CAR region from evicts */
316 mov $MSR_L2_QOS_MASK(1), %ecx
317 rdmsr
318 /* Invert bits that are to be used for cache */
Naresh G Solankif329f0c2017-09-27 14:21:18 +0530319 mov %ebx, %eax
320 xor $~0, %eax /* invert 32 bits */
321
322 /*
323 * Use CBM_LEN_MASK stored in mm3 to set bits based on Capacity Bit
324 * Mask Length.
325 */
326 movd %mm3, %ebx
327 and %ebx, %eax
Subrata Banik03e971c2017-03-07 14:02:23 +0530328 wrmsr
329
330 post_code(0x26)
331
332 /* Clear the cache memory region. This will also fill up the cache */
333 movl $CONFIG_DCACHE_RAM_BASE, %edi
334 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
335 shr $0x02, %ecx
336 xor %eax, %eax
337 cld
338 rep stosl
339
340 post_code(0x27)
341
342 /* Cache is populated. Use mask 1 that will block evicts */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200343 mov $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530344 rdmsr
345 and $~IA32_PQR_ASSOC_MASK, %edx /* clear index bits first */
346 or $1, %edx /* select mask 1 */
347 wrmsr
348
349 /* Enable prefetchers */
350 mov $MSR_PREFETCH_CTL, %ecx
351 rdmsr
352 and $~(PREFETCH_L1_DISABLE | PREFETCH_L2_DISABLE), %eax
353 wrmsr
354
355 post_code(0x28)
356
357 jmp car_init_done
358
359#elif IS_ENABLED(CONFIG_INTEL_CAR_NEM_ENHANCED)
360.global car_nem_enhanced
361car_nem_enhanced:
362 /* Disable cache eviction (setup stage) */
363 mov $MSR_EVICT_CTL, %ecx
364 rdmsr
365 or $0x1, %eax
366 wrmsr
367 post_code(0x26)
368
369 /* Create n-way set associativity of cache */
370 xorl %edi, %edi
371find_llc_subleaf:
372 movl %edi, %ecx
373 movl $0x04, %eax
374 cpuid
375 inc %edi
376 and $0xe0, %al /* EAX[7:5] = Cache Level */
377 cmp $0x60, %al /* Check to see if it is LLC */
378 jnz find_llc_subleaf
379
380 /*
381 * Set MSR 0xC91 IA32_L3_MASK_! = 0xE/0xFE/0xFFE/0xFFFE
382 * for 4/8/16 way of LLC
383 */
384 shr $22, %ebx
385 inc %ebx
386 /* Calculate n-way associativity of LLC */
387 mov %bl, %cl
388
389 /*
390 * Maximizing RO cacheability while locking in the CAR to a
391 * single way since that particular way won't be victim candidate
392 * for evictions.
Jonathan Neuschäfer5268b762018-02-12 12:24:25 +0100393 * This has been done after programming LLC_WAY_MASK_1 MSR
Subrata Banik03e971c2017-03-07 14:02:23 +0530394 * with desired LLC way as mentioned below.
395 *
396 * Hence create Code and Data Size as per request
397 * Code Size (RO) : Up to 16M
398 * Data Size (RW) : Up to 256K
399 */
400 movl $0x01, %eax
401 /*
402 * LLC Ways -> LLC_WAY_MASK_1:
403 * 4: 0x000E
404 * 8: 0x00FE
405 * 12: 0x0FFE
406 * 16: 0xFFFE
407 *
408 * These MSRs contain one bit per each way of LLC
409 * - If this bit is '0' - the way is protected from eviction
410 * - If this bit is '1' - the way is not protected from eviction
411 */
412 shl %cl, %eax
413 subl $0x02, %eax
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200414 movl $IA32_L3_MASK_1, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530415 xorl %edx, %edx
416 wrmsr
417 /*
418 * Set MSR 0xC92 IA32_L3_MASK_2 = 0x1
419 *
420 * For SKL SOC, data size remains 256K consistently.
421 * Hence, creating 1-way associative cache for Data
422 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200423 mov $IA32_L3_MASK_2, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530424 mov $0x01, %eax
425 xorl %edx, %edx
426 wrmsr
427 /*
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200428 * Set IA32_PQR_ASSOC = 0x02
Subrata Banik03e971c2017-03-07 14:02:23 +0530429 *
430 * Possible values:
431 * 0: Default value, no way mask should be applied
432 * 1: Apply way mask 1 to LLC
433 * 2: Apply way mask 2 to LLC
434 * 3: Shouldn't be use in NEM Mode
435 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200436 movl $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530437 movl $0x02, %eax
438 xorl %edx, %edx
439 wrmsr
440
441 movl $CONFIG_DCACHE_RAM_BASE, %edi
442 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
443 shr $0x02, %ecx
444 xor %eax, %eax
445 cld
446 rep stosl
447 /*
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200448 * Set IA32_PQR_ASSOC = 0x01
Subrata Banik03e971c2017-03-07 14:02:23 +0530449 * At this stage we apply LLC_WAY_MASK_1 to the cache.
450 * i.e. way 0 is protected from eviction.
451 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200452 movl $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530453 movl $0x01, %eax
454 xorl %edx, %edx
455 wrmsr
456
457 post_code(0x27)
458 /*
459 * Enable No-Eviction Mode Run State by setting
460 * NO_EVICT_MODE MSR 2E0h bit [1] = '1'.
461 */
462
463 movl $MSR_EVICT_CTL, %ecx
464 rdmsr
465 orl $0x02, %eax
466 wrmsr
467
468 post_code(0x28)
469
470 jmp car_init_done
471#endif