blob: 5af1fc65c13f64a5195b4726fe4c5bf774df91f2 [file] [log] [blame]
Angel Pons0612b272020-04-05 15:46:56 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Subrata Banik03e971c2017-03-07 14:02:23 +05302
3#include <commonlib/helpers.h>
4#include <cpu/x86/cache.h>
5#include <cpu/x86/cr.h>
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +02006#include <cpu/x86/msr.h>
Subrata Banik03e971c2017-03-07 14:02:23 +05307#include <cpu/x86/mtrr.h>
8#include <cpu/x86/post_code.h>
9#include <rules.h>
10#include <intelblocks/msr.h>
11
12.global bootblock_pre_c_entry
13bootblock_pre_c_entry:
14
15 post_code(0x20)
16
Arthur Heymansc4772b92019-04-14 18:38:35 +020017 movl $no_reset, %esp /* return address */
18 jmp check_mtrr /* Check if CPU properly reset */
Subrata Banik03e971c2017-03-07 14:02:23 +053019
20no_reset:
21 post_code(0x21)
22
23 /* Clear/disable fixed MTRRs */
24 mov $fixed_mtrr_list_size, %ebx
25 xor %eax, %eax
26 xor %edx, %edx
27
28clear_fixed_mtrr:
29 add $-2, %ebx
30 movzwl fixed_mtrr_list(%ebx), %ecx
31 wrmsr
32 jnz clear_fixed_mtrr
33
34 post_code(0x22)
35
36 /* Figure put how many MTRRs we have, and clear them out */
37 mov $MTRR_CAP_MSR, %ecx
38 rdmsr
39 movzb %al, %ebx /* Number of variable MTRRs */
40 mov $MTRR_PHYS_BASE(0), %ecx
41 xor %eax, %eax
42 xor %edx, %edx
43
44clear_var_mtrr:
45 wrmsr
46 inc %ecx
47 wrmsr
48 inc %ecx
49 dec %ebx
50 jnz clear_var_mtrr
51
52 post_code(0x23)
53
54 /* Configure default memory type to uncacheable (UC) */
55 mov $MTRR_DEF_TYPE_MSR, %ecx
56 rdmsr
57 /* Clear enable bits and set default type to UC. */
58 and $~(MTRR_DEF_TYPE_MASK | MTRR_DEF_TYPE_EN | \
59 MTRR_DEF_TYPE_FIX_EN), %eax
60 wrmsr
61
62 /* Configure MTRR_PHYS_MASK_HIGH for proper addressing above 4GB
63 * based on the physical address size supported for this processor
64 * This is based on read from CPUID EAX = 080000008h, EAX bits [7:0]
65 *
66 * Examples:
67 * MTRR_PHYS_MASK_HIGH = 00000000Fh For 36 bit addressing
68 * MTRR_PHYS_MASK_HIGH = 0000000FFh For 40 bit addressing
69 */
70
Elyes HAOUAS05498a22018-05-28 16:26:43 +020071 movl $0x80000008, %eax /* Address sizes leaf */
Subrata Banik03e971c2017-03-07 14:02:23 +053072 cpuid
73 sub $32, %al
74 movzx %al, %eax
75 xorl %esi, %esi
76 bts %eax, %esi
77 dec %esi /* esi <- MTRR_PHYS_MASK_HIGH */
78
79 post_code(0x24)
80
81#if ((CONFIG_DCACHE_RAM_SIZE & (CONFIG_DCACHE_RAM_SIZE - 1)) == 0)
82 /* Configure CAR region as write-back (WB) */
83 mov $MTRR_PHYS_BASE(0), %ecx
84 mov $CONFIG_DCACHE_RAM_BASE, %eax
85 or $MTRR_TYPE_WRBACK, %eax
86 xor %edx,%edx
87 wrmsr
88
89 /* Configure the MTRR mask for the size region */
90 mov $MTRR_PHYS_MASK(0), %ecx
91 mov $CONFIG_DCACHE_RAM_SIZE, %eax /* size mask */
92 dec %eax
93 not %eax
94 or $MTRR_PHYS_MASK_VALID, %eax
95 movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
96 wrmsr
97#elif (CONFIG_DCACHE_RAM_SIZE == 768 * KiB) /* 768 KiB */
98 /* Configure CAR region as write-back (WB) */
99 mov $MTRR_PHYS_BASE(0), %ecx
100 mov $CONFIG_DCACHE_RAM_BASE, %eax
101 or $MTRR_TYPE_WRBACK, %eax
102 xor %edx,%edx
103 wrmsr
104
105 mov $MTRR_PHYS_MASK(0), %ecx
106 mov $(512 * KiB), %eax /* size mask */
107 dec %eax
108 not %eax
109 or $MTRR_PHYS_MASK_VALID, %eax
110 movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
111 wrmsr
112
113 mov $MTRR_PHYS_BASE(1), %ecx
114 mov $(CONFIG_DCACHE_RAM_BASE + 512 * KiB), %eax
115 or $MTRR_TYPE_WRBACK, %eax
116 xor %edx,%edx
117 wrmsr
118
119 mov $MTRR_PHYS_MASK(1), %ecx
120 mov $(256 * KiB), %eax /* size mask */
121 dec %eax
122 not %eax
123 or $MTRR_PHYS_MASK_VALID, %eax
124 movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
125 wrmsr
126#else
127#error "DCACHE_RAM_SIZE is not a power of 2 and setup code is missing"
128#endif
129 post_code(0x25)
130
131 /* Enable variable MTRRs */
132 mov $MTRR_DEF_TYPE_MSR, %ecx
133 rdmsr
134 or $MTRR_DEF_TYPE_EN, %eax
135 wrmsr
136
137 /* Enable caching */
138 mov %cr0, %eax
139 and $~(CR0_CD | CR0_NW), %eax
140 invd
141 mov %eax, %cr0
142
Julius Wernercd49cce2019-03-05 16:53:33 -0800143#if CONFIG(INTEL_CAR_NEM)
Subrata Banik03e971c2017-03-07 14:02:23 +0530144 jmp car_nem
Julius Wernercd49cce2019-03-05 16:53:33 -0800145#elif CONFIG(INTEL_CAR_CQOS)
Subrata Banik03e971c2017-03-07 14:02:23 +0530146 jmp car_cqos
Julius Wernercd49cce2019-03-05 16:53:33 -0800147#elif CONFIG(INTEL_CAR_NEM_ENHANCED)
Subrata Banik03e971c2017-03-07 14:02:23 +0530148 jmp car_nem_enhanced
149#else
150 jmp .halt_forever /* In case nothing has selected */
151#endif
152
153.global car_init_done
154car_init_done:
155
156 post_code(0x29)
157
158 /* Setup bootblock stack */
Arthur Heymansdf9cdcf2019-11-09 06:50:20 +0100159 mov $_ecar_stack, %esp
Subrata Banik03e971c2017-03-07 14:02:23 +0530160
Aaron Durbin028e18f2017-06-23 11:14:58 -0500161 /* Need to align stack to 16 bytes at call instruction. Account for
162 the two pushes below. */
163 andl $0xfffffff0, %esp
164 sub $8, %esp
165
Subrata Banik5885ffe2019-11-14 11:08:51 +0530166 /* push TSC value to stack */
Subrata Banik03e971c2017-03-07 14:02:23 +0530167 movd %mm2, %eax
168 pushl %eax /* tsc[63:32] */
169 movd %mm1, %eax
Elyes HAOUAS05498a22018-05-28 16:26:43 +0200170 pushl %eax /* tsc[31:0] */
Subrata Banik03e971c2017-03-07 14:02:23 +0530171
172before_carstage:
173 post_code(0x2A)
174
175 call bootblock_c_entry
176 /* Never reached */
177
178.halt_forever:
179 post_code(POST_DEAD_CODE)
180 hlt
181 jmp .halt_forever
182
183fixed_mtrr_list:
184 .word MTRR_FIX_64K_00000
185 .word MTRR_FIX_16K_80000
186 .word MTRR_FIX_16K_A0000
187 .word MTRR_FIX_4K_C0000
188 .word MTRR_FIX_4K_C8000
189 .word MTRR_FIX_4K_D0000
190 .word MTRR_FIX_4K_D8000
191 .word MTRR_FIX_4K_E0000
192 .word MTRR_FIX_4K_E8000
193 .word MTRR_FIX_4K_F0000
194 .word MTRR_FIX_4K_F8000
195fixed_mtrr_list_size = . - fixed_mtrr_list
196
Julius Wernercd49cce2019-03-05 16:53:33 -0800197#if CONFIG(INTEL_CAR_NEM)
Subrata Banik03e971c2017-03-07 14:02:23 +0530198.global car_nem
199car_nem:
200 /* Disable cache eviction (setup stage) */
201 mov $MSR_EVICT_CTL, %ecx
202 rdmsr
203 or $0x1, %eax
204 wrmsr
205
206 post_code(0x26)
207
208 /* Clear the cache memory region. This will also fill up the cache */
209 movl $CONFIG_DCACHE_RAM_BASE, %edi
210 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
211 shr $0x02, %ecx
212 xor %eax, %eax
213 cld
214 rep stosl
215
216 post_code(0x27)
217
218 /* Disable cache eviction (run stage) */
219 mov $MSR_EVICT_CTL, %ecx
220 rdmsr
221 or $0x2, %eax
222 wrmsr
223
224 post_code(0x28)
225
226 jmp car_init_done
227
Julius Wernercd49cce2019-03-05 16:53:33 -0800228#elif CONFIG(INTEL_CAR_CQOS)
Subrata Banik03e971c2017-03-07 14:02:23 +0530229.global car_cqos
230car_cqos:
231 /*
Naresh G Solankif329f0c2017-09-27 14:21:18 +0530232 * Create CBM_LEN_MASK based on CBM_LEN
233 * Get CPUID.(EAX=10H, ECX=2H):EAX.CBM_LEN[bits 4:0]
234 */
235 mov $0x10, %eax
236 mov $0x2, %ecx
237 cpuid
238 and $0x1F, %eax
239 add $1, %al
240
241 mov $1, %ebx
242 mov %al, %cl
243 shl %cl, %ebx
244 sub $1, %ebx
245
246 /* Store the CBM_LEN_MASK in mm3 for later use. */
247 movd %ebx, %mm3
248
249 /*
Subrata Banik03e971c2017-03-07 14:02:23 +0530250 * Disable both L1 and L2 prefetcher. For yet-to-understood reason,
251 * prefetchers slow down filling cache with rep stos in CQOS mode.
252 */
253 mov $MSR_PREFETCH_CTL, %ecx
254 rdmsr
255 or $(PREFETCH_L1_DISABLE | PREFETCH_L2_DISABLE), %eax
256 wrmsr
257
258#if (CONFIG_DCACHE_RAM_SIZE == CONFIG_L2_CACHE_SIZE)
259/*
260 * If CAR size is set to full L2 size, mask is calculated as all-zeros.
261 * This is not supported by the CPU/uCode.
262 */
263#error "CQOS CAR may not use whole L2 cache area"
264#endif
265
266 /* Calculate how many bits to be used for CAR */
267 xor %edx, %edx
268 mov $CONFIG_DCACHE_RAM_SIZE, %eax /* dividend */
269 mov $CONFIG_CACHE_QOS_SIZE_PER_BIT, %ecx /* divisor */
270 div %ecx /* result is in eax */
271 mov %eax, %ecx /* save to ecx */
272 mov $1, %ebx
273 shl %cl, %ebx
274 sub $1, %ebx /* resulting mask is is in ebx */
275
276 /* Set this mask for initial cache fill */
277 mov $MSR_L2_QOS_MASK(0), %ecx
278 rdmsr
Naresh G Solankif329f0c2017-09-27 14:21:18 +0530279 mov %ebx, %eax
Subrata Banik03e971c2017-03-07 14:02:23 +0530280 wrmsr
281
282 /* Set CLOS selector to 0 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200283 mov $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530284 rdmsr
285 and $~IA32_PQR_ASSOC_MASK, %edx /* select mask 0 */
286 wrmsr
287
288 /* We will need to block CAR region from evicts */
289 mov $MSR_L2_QOS_MASK(1), %ecx
290 rdmsr
291 /* Invert bits that are to be used for cache */
Naresh G Solankif329f0c2017-09-27 14:21:18 +0530292 mov %ebx, %eax
293 xor $~0, %eax /* invert 32 bits */
294
295 /*
296 * Use CBM_LEN_MASK stored in mm3 to set bits based on Capacity Bit
297 * Mask Length.
298 */
299 movd %mm3, %ebx
300 and %ebx, %eax
Subrata Banik03e971c2017-03-07 14:02:23 +0530301 wrmsr
302
303 post_code(0x26)
304
305 /* Clear the cache memory region. This will also fill up the cache */
306 movl $CONFIG_DCACHE_RAM_BASE, %edi
307 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
308 shr $0x02, %ecx
309 xor %eax, %eax
310 cld
311 rep stosl
312
313 post_code(0x27)
314
315 /* Cache is populated. Use mask 1 that will block evicts */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200316 mov $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530317 rdmsr
318 and $~IA32_PQR_ASSOC_MASK, %edx /* clear index bits first */
319 or $1, %edx /* select mask 1 */
320 wrmsr
321
322 /* Enable prefetchers */
323 mov $MSR_PREFETCH_CTL, %ecx
324 rdmsr
325 and $~(PREFETCH_L1_DISABLE | PREFETCH_L2_DISABLE), %eax
326 wrmsr
327
328 post_code(0x28)
329
330 jmp car_init_done
331
Julius Wernercd49cce2019-03-05 16:53:33 -0800332#elif CONFIG(INTEL_CAR_NEM_ENHANCED)
Subrata Banik03e971c2017-03-07 14:02:23 +0530333.global car_nem_enhanced
334car_nem_enhanced:
335 /* Disable cache eviction (setup stage) */
336 mov $MSR_EVICT_CTL, %ecx
337 rdmsr
338 or $0x1, %eax
339 wrmsr
340 post_code(0x26)
341
342 /* Create n-way set associativity of cache */
343 xorl %edi, %edi
344find_llc_subleaf:
345 movl %edi, %ecx
346 movl $0x04, %eax
347 cpuid
348 inc %edi
349 and $0xe0, %al /* EAX[7:5] = Cache Level */
350 cmp $0x60, %al /* Check to see if it is LLC */
351 jnz find_llc_subleaf
352
353 /*
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530354 * Calculate the total LLC size
355 * (Line_Size + 1) * (Sets + 1) * (Partitions + 1) * (Ways + 1)
356 * (EBX[11:0] + 1) * (ECX + 1) * (EBX[21:12] + 1) * EBX[31:22] + 1)
357 */
358
359 mov %ebx, %eax
360 and $0xFFF, %eax
361 inc %eax
362 inc %ecx
363 mul %ecx
364 mov %eax, %ecx
365 mov %ebx, %eax
366 shr $12, %eax
367 and $0x3FF, %eax
368 inc %eax
369 mul %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530370 shr $22, %ebx
371 inc %ebx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530372 mov %ebx, %edx
373 mul %ebx /* eax now holds total LLC size */
Subrata Banik03e971c2017-03-07 14:02:23 +0530374
375 /*
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530376 * The number of the ways that we want to protect from eviction
377 * can be calculated as RW data stack size / way size where way
378 * size is Total LLC size / Total number of LLC ways.
Subrata Banik03e971c2017-03-07 14:02:23 +0530379 */
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530380 div %ebx /* way size */
381 mov %eax, %ecx
382
Subrata Banik03e971c2017-03-07 14:02:23 +0530383 /*
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530384 * Check if way size if bigger than the cache ram size.
385 * Then we need to allocate just one way for non-eviction
386 * of RW data.
387 */
388 movl $0x01, %eax
389 cmp $CONFIG_DCACHE_RAM_SIZE, %ecx
390 jnc set_eviction_mask
391
392 /*
393 * RW data size / way size is equal to number of
394 * ways to be configured for non-eviction
395 */
396 mov $CONFIG_DCACHE_RAM_SIZE, %eax
397 div %ecx
398 mov %eax, %ecx
399 movl $0x01, %eax
400 shl %cl, %eax
401 subl $0x01, %eax
402
403set_eviction_mask:
404 mov %ebx, %ecx /* back up the number of ways */
405 mov %eax, %ebx /* back up the non-eviction mask*/
406 /*
407 * Set MSR 0xC91 IA32_L3_MASK_1 or MSR 0x1891 IA32_CR_SF_QOS_MASK_1
408 * This MSR contain one bit per each way of LLC
Subrata Banik03e971c2017-03-07 14:02:23 +0530409 * - 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 */
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530412 mov $0x1, %eax
413 shl %cl, %eax
414 subl $0x01, %eax
415 mov %eax, %ecx
416 mov %ebx, %eax
417
418 xor $~0, %eax /* invert 32 bits */
419 and %ecx, %eax
420#if CONFIG(USE_CAR_NEM_ENHANCED_V1)
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200421 movl $IA32_L3_MASK_1, %ecx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530422#elif CONFIG(USE_CAR_NEM_ENHANCED_V2)
423 movl $IA32_CR_SF_QOS_MASK_1, %ecx
424#endif
425 xorl %edx, %edx
426 wrmsr
427
428 /*
429 * Set MSR 0xC92 IA32_L3_MASK_1 or MSR 0x1892 IA32_CR_SF_QOS_MASK_2
430 * This MSR contain one bit per each way of LLC
431 * - If this bit is '0' - the way is protected from eviction
432 * - If this bit is '1' - the way is not protected from eviction
433 */
434 mov %ebx, %eax
435#if CONFIG(USE_CAR_NEM_ENHANCED_V1)
436 movl $IA32_L3_MASK_2, %ecx
437#elif CONFIG(USE_CAR_NEM_ENHANCED_V2)
438 movl $IA32_CR_SF_QOS_MASK_2, %ecx
439#endif
Subrata Banik03e971c2017-03-07 14:02:23 +0530440 xorl %edx, %edx
441 wrmsr
442 /*
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530443 * Set IA32_PQR_ASSOC
Subrata Banik03e971c2017-03-07 14:02:23 +0530444 *
445 * Possible values:
446 * 0: Default value, no way mask should be applied
447 * 1: Apply way mask 1 to LLC
448 * 2: Apply way mask 2 to LLC
449 * 3: Shouldn't be use in NEM Mode
450 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200451 movl $IA32_PQR_ASSOC, %ecx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530452 xorl %eax, %eax
Subrata Banik03e971c2017-03-07 14:02:23 +0530453 xorl %edx, %edx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530454#if CONFIG(COS_MAPPED_TO_MSB)
455 movl $0x02, %edx
456#else
457 movl $0x02, %eax
458#endif
Subrata Banik03e971c2017-03-07 14:02:23 +0530459 wrmsr
460
461 movl $CONFIG_DCACHE_RAM_BASE, %edi
462 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
463 shr $0x02, %ecx
464 xor %eax, %eax
465 cld
466 rep stosl
467 /*
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530468 * Set IA32_PQR_ASSOC
Subrata Banik03e971c2017-03-07 14:02:23 +0530469 * At this stage we apply LLC_WAY_MASK_1 to the cache.
Subrata Banik03e971c2017-03-07 14:02:23 +0530470 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200471 movl $IA32_PQR_ASSOC, %ecx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530472 xorl %eax, %eax
Subrata Banik03e971c2017-03-07 14:02:23 +0530473 xorl %edx, %edx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530474#if CONFIG(COS_MAPPED_TO_MSB)
475 movl $0x01, %edx
476#else
477 movl $0x01, %eax
478#endif
Subrata Banik03e971c2017-03-07 14:02:23 +0530479 wrmsr
480
481 post_code(0x27)
482 /*
483 * Enable No-Eviction Mode Run State by setting
484 * NO_EVICT_MODE MSR 2E0h bit [1] = '1'.
485 */
486
487 movl $MSR_EVICT_CTL, %ecx
488 rdmsr
489 orl $0x02, %eax
490 wrmsr
491
492 post_code(0x28)
493
494 jmp car_init_done
495#endif