blob: 49b40a8d9aa5424c531c1cdeb32b9af06504eb14 [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
Kyösti Mälkki7522a8f2020-11-20 16:47:38 +020012.section .init, "ax", @progbits
13
Patrick Rudolph2b771122020-11-30 13:52:42 +010014.code32
Subrata Banik03e971c2017-03-07 14:02:23 +053015.global bootblock_pre_c_entry
16bootblock_pre_c_entry:
17
18 post_code(0x20)
19
Arthur Heymansc4772b92019-04-14 18:38:35 +020020 movl $no_reset, %esp /* return address */
21 jmp check_mtrr /* Check if CPU properly reset */
Subrata Banik03e971c2017-03-07 14:02:23 +053022
23no_reset:
24 post_code(0x21)
25
26 /* Clear/disable fixed MTRRs */
27 mov $fixed_mtrr_list_size, %ebx
28 xor %eax, %eax
29 xor %edx, %edx
30
31clear_fixed_mtrr:
32 add $-2, %ebx
33 movzwl fixed_mtrr_list(%ebx), %ecx
34 wrmsr
35 jnz clear_fixed_mtrr
36
37 post_code(0x22)
38
39 /* Figure put how many MTRRs we have, and clear them out */
40 mov $MTRR_CAP_MSR, %ecx
41 rdmsr
42 movzb %al, %ebx /* Number of variable MTRRs */
43 mov $MTRR_PHYS_BASE(0), %ecx
44 xor %eax, %eax
45 xor %edx, %edx
46
47clear_var_mtrr:
48 wrmsr
49 inc %ecx
50 wrmsr
51 inc %ecx
52 dec %ebx
53 jnz clear_var_mtrr
54
55 post_code(0x23)
56
57 /* Configure default memory type to uncacheable (UC) */
58 mov $MTRR_DEF_TYPE_MSR, %ecx
59 rdmsr
60 /* Clear enable bits and set default type to UC. */
61 and $~(MTRR_DEF_TYPE_MASK | MTRR_DEF_TYPE_EN | \
62 MTRR_DEF_TYPE_FIX_EN), %eax
63 wrmsr
64
65 /* Configure MTRR_PHYS_MASK_HIGH for proper addressing above 4GB
66 * based on the physical address size supported for this processor
67 * This is based on read from CPUID EAX = 080000008h, EAX bits [7:0]
68 *
69 * Examples:
70 * MTRR_PHYS_MASK_HIGH = 00000000Fh For 36 bit addressing
71 * MTRR_PHYS_MASK_HIGH = 0000000FFh For 40 bit addressing
72 */
73
Elyes HAOUAS05498a22018-05-28 16:26:43 +020074 movl $0x80000008, %eax /* Address sizes leaf */
Subrata Banik03e971c2017-03-07 14:02:23 +053075 cpuid
76 sub $32, %al
77 movzx %al, %eax
78 xorl %esi, %esi
79 bts %eax, %esi
80 dec %esi /* esi <- MTRR_PHYS_MASK_HIGH */
81
82 post_code(0x24)
83
84#if ((CONFIG_DCACHE_RAM_SIZE & (CONFIG_DCACHE_RAM_SIZE - 1)) == 0)
85 /* Configure CAR region as write-back (WB) */
86 mov $MTRR_PHYS_BASE(0), %ecx
87 mov $CONFIG_DCACHE_RAM_BASE, %eax
88 or $MTRR_TYPE_WRBACK, %eax
89 xor %edx,%edx
90 wrmsr
91
92 /* Configure the MTRR mask for the size region */
93 mov $MTRR_PHYS_MASK(0), %ecx
94 mov $CONFIG_DCACHE_RAM_SIZE, %eax /* size mask */
95 dec %eax
96 not %eax
97 or $MTRR_PHYS_MASK_VALID, %eax
98 movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
99 wrmsr
100#elif (CONFIG_DCACHE_RAM_SIZE == 768 * KiB) /* 768 KiB */
101 /* Configure CAR region as write-back (WB) */
102 mov $MTRR_PHYS_BASE(0), %ecx
103 mov $CONFIG_DCACHE_RAM_BASE, %eax
104 or $MTRR_TYPE_WRBACK, %eax
105 xor %edx,%edx
106 wrmsr
107
108 mov $MTRR_PHYS_MASK(0), %ecx
109 mov $(512 * KiB), %eax /* size mask */
110 dec %eax
111 not %eax
112 or $MTRR_PHYS_MASK_VALID, %eax
113 movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
114 wrmsr
115
116 mov $MTRR_PHYS_BASE(1), %ecx
117 mov $(CONFIG_DCACHE_RAM_BASE + 512 * KiB), %eax
118 or $MTRR_TYPE_WRBACK, %eax
119 xor %edx,%edx
120 wrmsr
121
122 mov $MTRR_PHYS_MASK(1), %ecx
123 mov $(256 * KiB), %eax /* size mask */
124 dec %eax
125 not %eax
126 or $MTRR_PHYS_MASK_VALID, %eax
127 movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
128 wrmsr
129#else
130#error "DCACHE_RAM_SIZE is not a power of 2 and setup code is missing"
131#endif
132 post_code(0x25)
133
134 /* Enable variable MTRRs */
135 mov $MTRR_DEF_TYPE_MSR, %ecx
136 rdmsr
137 or $MTRR_DEF_TYPE_EN, %eax
138 wrmsr
139
140 /* Enable caching */
141 mov %cr0, %eax
142 and $~(CR0_CD | CR0_NW), %eax
143 invd
144 mov %eax, %cr0
145
Julius Wernercd49cce2019-03-05 16:53:33 -0800146#if CONFIG(INTEL_CAR_NEM)
Subrata Banik03e971c2017-03-07 14:02:23 +0530147 jmp car_nem
Julius Wernercd49cce2019-03-05 16:53:33 -0800148#elif CONFIG(INTEL_CAR_CQOS)
Subrata Banik03e971c2017-03-07 14:02:23 +0530149 jmp car_cqos
Julius Wernercd49cce2019-03-05 16:53:33 -0800150#elif CONFIG(INTEL_CAR_NEM_ENHANCED)
Subrata Banik03e971c2017-03-07 14:02:23 +0530151 jmp car_nem_enhanced
152#else
153 jmp .halt_forever /* In case nothing has selected */
154#endif
155
156.global car_init_done
157car_init_done:
158
159 post_code(0x29)
160
161 /* Setup bootblock stack */
Arthur Heymansdf9cdcf2019-11-09 06:50:20 +0100162 mov $_ecar_stack, %esp
Subrata Banik03e971c2017-03-07 14:02:23 +0530163
Aaron Durbin028e18f2017-06-23 11:14:58 -0500164 /* Need to align stack to 16 bytes at call instruction. Account for
165 the two pushes below. */
166 andl $0xfffffff0, %esp
Patrick Rudolph2b771122020-11-30 13:52:42 +0100167
168#if ENV_X86_64
169 #include <cpu/x86/64bit/entry64.inc>
170 movd %mm2, %rdi
171 shlq $32, %rdi
172 movd %mm1, %rsi
173 or %rsi, %rdi
174 movd %mm0, %rsi
175#else
Aaron Durbin028e18f2017-06-23 11:14:58 -0500176 sub $8, %esp
177
Subrata Banik5885ffe2019-11-14 11:08:51 +0530178 /* push TSC value to stack */
Subrata Banik03e971c2017-03-07 14:02:23 +0530179 movd %mm2, %eax
180 pushl %eax /* tsc[63:32] */
181 movd %mm1, %eax
Elyes HAOUAS05498a22018-05-28 16:26:43 +0200182 pushl %eax /* tsc[31:0] */
Patrick Rudolph2b771122020-11-30 13:52:42 +0100183#endif
Subrata Banik03e971c2017-03-07 14:02:23 +0530184
185before_carstage:
186 post_code(0x2A)
187
188 call bootblock_c_entry
189 /* Never reached */
190
191.halt_forever:
192 post_code(POST_DEAD_CODE)
193 hlt
194 jmp .halt_forever
195
196fixed_mtrr_list:
197 .word MTRR_FIX_64K_00000
198 .word MTRR_FIX_16K_80000
199 .word MTRR_FIX_16K_A0000
200 .word MTRR_FIX_4K_C0000
201 .word MTRR_FIX_4K_C8000
202 .word MTRR_FIX_4K_D0000
203 .word MTRR_FIX_4K_D8000
204 .word MTRR_FIX_4K_E0000
205 .word MTRR_FIX_4K_E8000
206 .word MTRR_FIX_4K_F0000
207 .word MTRR_FIX_4K_F8000
208fixed_mtrr_list_size = . - fixed_mtrr_list
209
Julius Wernercd49cce2019-03-05 16:53:33 -0800210#if CONFIG(INTEL_CAR_NEM)
Subrata Banik03e971c2017-03-07 14:02:23 +0530211.global car_nem
212car_nem:
213 /* Disable cache eviction (setup stage) */
214 mov $MSR_EVICT_CTL, %ecx
215 rdmsr
216 or $0x1, %eax
217 wrmsr
218
219 post_code(0x26)
220
221 /* Clear the cache memory region. This will also fill up the cache */
222 movl $CONFIG_DCACHE_RAM_BASE, %edi
223 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
224 shr $0x02, %ecx
225 xor %eax, %eax
226 cld
227 rep stosl
228
229 post_code(0x27)
230
231 /* Disable cache eviction (run stage) */
232 mov $MSR_EVICT_CTL, %ecx
233 rdmsr
234 or $0x2, %eax
235 wrmsr
236
237 post_code(0x28)
238
239 jmp car_init_done
240
Julius Wernercd49cce2019-03-05 16:53:33 -0800241#elif CONFIG(INTEL_CAR_CQOS)
Subrata Banik03e971c2017-03-07 14:02:23 +0530242.global car_cqos
243car_cqos:
244 /*
Naresh G Solankif329f0c2017-09-27 14:21:18 +0530245 * Create CBM_LEN_MASK based on CBM_LEN
246 * Get CPUID.(EAX=10H, ECX=2H):EAX.CBM_LEN[bits 4:0]
247 */
248 mov $0x10, %eax
249 mov $0x2, %ecx
250 cpuid
251 and $0x1F, %eax
252 add $1, %al
253
254 mov $1, %ebx
255 mov %al, %cl
256 shl %cl, %ebx
257 sub $1, %ebx
258
259 /* Store the CBM_LEN_MASK in mm3 for later use. */
260 movd %ebx, %mm3
261
262 /*
Subrata Banik03e971c2017-03-07 14:02:23 +0530263 * Disable both L1 and L2 prefetcher. For yet-to-understood reason,
264 * prefetchers slow down filling cache with rep stos in CQOS mode.
265 */
266 mov $MSR_PREFETCH_CTL, %ecx
267 rdmsr
268 or $(PREFETCH_L1_DISABLE | PREFETCH_L2_DISABLE), %eax
269 wrmsr
270
271#if (CONFIG_DCACHE_RAM_SIZE == CONFIG_L2_CACHE_SIZE)
272/*
273 * If CAR size is set to full L2 size, mask is calculated as all-zeros.
274 * This is not supported by the CPU/uCode.
275 */
276#error "CQOS CAR may not use whole L2 cache area"
277#endif
278
279 /* Calculate how many bits to be used for CAR */
280 xor %edx, %edx
281 mov $CONFIG_DCACHE_RAM_SIZE, %eax /* dividend */
282 mov $CONFIG_CACHE_QOS_SIZE_PER_BIT, %ecx /* divisor */
283 div %ecx /* result is in eax */
284 mov %eax, %ecx /* save to ecx */
285 mov $1, %ebx
286 shl %cl, %ebx
287 sub $1, %ebx /* resulting mask is is in ebx */
288
289 /* Set this mask for initial cache fill */
290 mov $MSR_L2_QOS_MASK(0), %ecx
291 rdmsr
Naresh G Solankif329f0c2017-09-27 14:21:18 +0530292 mov %ebx, %eax
Subrata Banik03e971c2017-03-07 14:02:23 +0530293 wrmsr
294
295 /* Set CLOS selector to 0 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200296 mov $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530297 rdmsr
298 and $~IA32_PQR_ASSOC_MASK, %edx /* select mask 0 */
299 wrmsr
300
301 /* We will need to block CAR region from evicts */
302 mov $MSR_L2_QOS_MASK(1), %ecx
303 rdmsr
304 /* Invert bits that are to be used for cache */
Naresh G Solankif329f0c2017-09-27 14:21:18 +0530305 mov %ebx, %eax
306 xor $~0, %eax /* invert 32 bits */
307
308 /*
309 * Use CBM_LEN_MASK stored in mm3 to set bits based on Capacity Bit
310 * Mask Length.
311 */
312 movd %mm3, %ebx
313 and %ebx, %eax
Subrata Banik03e971c2017-03-07 14:02:23 +0530314 wrmsr
315
316 post_code(0x26)
317
318 /* Clear the cache memory region. This will also fill up the cache */
319 movl $CONFIG_DCACHE_RAM_BASE, %edi
320 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
321 shr $0x02, %ecx
322 xor %eax, %eax
323 cld
324 rep stosl
325
326 post_code(0x27)
327
328 /* Cache is populated. Use mask 1 that will block evicts */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200329 mov $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530330 rdmsr
331 and $~IA32_PQR_ASSOC_MASK, %edx /* clear index bits first */
332 or $1, %edx /* select mask 1 */
333 wrmsr
334
335 /* Enable prefetchers */
336 mov $MSR_PREFETCH_CTL, %ecx
337 rdmsr
338 and $~(PREFETCH_L1_DISABLE | PREFETCH_L2_DISABLE), %eax
339 wrmsr
340
341 post_code(0x28)
342
343 jmp car_init_done
344
Julius Wernercd49cce2019-03-05 16:53:33 -0800345#elif CONFIG(INTEL_CAR_NEM_ENHANCED)
Subrata Banik03e971c2017-03-07 14:02:23 +0530346.global car_nem_enhanced
347car_nem_enhanced:
348 /* Disable cache eviction (setup stage) */
349 mov $MSR_EVICT_CTL, %ecx
350 rdmsr
351 or $0x1, %eax
352 wrmsr
353 post_code(0x26)
354
355 /* Create n-way set associativity of cache */
356 xorl %edi, %edi
357find_llc_subleaf:
358 movl %edi, %ecx
359 movl $0x04, %eax
360 cpuid
361 inc %edi
362 and $0xe0, %al /* EAX[7:5] = Cache Level */
363 cmp $0x60, %al /* Check to see if it is LLC */
364 jnz find_llc_subleaf
365
366 /*
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530367 * Calculate the total LLC size
368 * (Line_Size + 1) * (Sets + 1) * (Partitions + 1) * (Ways + 1)
369 * (EBX[11:0] + 1) * (ECX + 1) * (EBX[21:12] + 1) * EBX[31:22] + 1)
370 */
371
372 mov %ebx, %eax
373 and $0xFFF, %eax
374 inc %eax
375 inc %ecx
376 mul %ecx
377 mov %eax, %ecx
378 mov %ebx, %eax
379 shr $12, %eax
380 and $0x3FF, %eax
381 inc %eax
382 mul %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530383 shr $22, %ebx
384 inc %ebx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530385 mov %ebx, %edx
386 mul %ebx /* eax now holds total LLC size */
Subrata Banik03e971c2017-03-07 14:02:23 +0530387
388 /*
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530389 * The number of the ways that we want to protect from eviction
390 * can be calculated as RW data stack size / way size where way
391 * size is Total LLC size / Total number of LLC ways.
Subrata Banik03e971c2017-03-07 14:02:23 +0530392 */
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530393 div %ebx /* way size */
394 mov %eax, %ecx
395
Subrata Banik03e971c2017-03-07 14:02:23 +0530396 /*
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530397 * Check if way size if bigger than the cache ram size.
398 * Then we need to allocate just one way for non-eviction
399 * of RW data.
400 */
401 movl $0x01, %eax
402 cmp $CONFIG_DCACHE_RAM_SIZE, %ecx
403 jnc set_eviction_mask
404
405 /*
406 * RW data size / way size is equal to number of
407 * ways to be configured for non-eviction
408 */
409 mov $CONFIG_DCACHE_RAM_SIZE, %eax
410 div %ecx
411 mov %eax, %ecx
412 movl $0x01, %eax
413 shl %cl, %eax
414 subl $0x01, %eax
415
416set_eviction_mask:
Shreesh Chhabbi860c6842020-12-03 15:06:20 -0800417 mov %ebx, %ecx /* back up number of ways */
418 mov %eax, %ebx /* back up the non-eviction mask*/
419#if CONFIG(CAR_HAS_SF_MASKS)
420 mov %ecx, %edi /* use number of ways to prepare SF mask */
421 /*
422 * SF mask is programmed with the double number of bits than
423 * the number of ways
424 */
425 mov $0x01, %eax
426 shl %cl, %eax
427 shl %cl, %eax
428 subl $0x01, %eax /* contains SF mask */
429 /*
430 * Program MSR 0x1891 IA32_CR_SF_QOS_MASK_1 with
431 * total number of LLC ways
432 */
433 movl $IA32_CR_SF_QOS_MASK_1, %ecx
434 xorl %edx, %edx
435 wrmsr
436 mov %edi, %ecx /* restore number of ways */
437#endif
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530438 /*
Shreesh Chhabbi87c7ec72020-12-03 14:07:15 -0800439 * Program MSR 0xC91 IA32_L3_MASK_1
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530440 * This MSR contain one bit per each way of LLC
Subrata Banik03e971c2017-03-07 14:02:23 +0530441 * - If this bit is '0' - the way is protected from eviction
442 * - If this bit is '1' - the way is not protected from eviction
443 */
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530444 mov $0x1, %eax
445 shl %cl, %eax
446 subl $0x01, %eax
447 mov %eax, %ecx
448 mov %ebx, %eax
449
450 xor $~0, %eax /* invert 32 bits */
451 and %ecx, %eax
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200452 movl $IA32_L3_MASK_1, %ecx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530453 xorl %edx, %edx
454 wrmsr
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530455 /*
Shreesh Chhabbi87c7ec72020-12-03 14:07:15 -0800456 * Program MSR 0xC92 IA32_L3_MASK_2
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530457 * This MSR contain one bit per each way of LLC
458 * - If this bit is '0' - the way is protected from eviction
459 * - If this bit is '1' - the way is not protected from eviction
460 */
461 mov %ebx, %eax
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530462 movl $IA32_L3_MASK_2, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530463 xorl %edx, %edx
464 wrmsr
465 /*
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530466 * Set IA32_PQR_ASSOC
Subrata Banik03e971c2017-03-07 14:02:23 +0530467 *
468 * Possible values:
469 * 0: Default value, no way mask should be applied
470 * 1: Apply way mask 1 to LLC
471 * 2: Apply way mask 2 to LLC
472 * 3: Shouldn't be use in NEM Mode
473 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200474 movl $IA32_PQR_ASSOC, %ecx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530475 xorl %eax, %eax
Subrata Banik03e971c2017-03-07 14:02:23 +0530476 xorl %edx, %edx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530477#if CONFIG(COS_MAPPED_TO_MSB)
478 movl $0x02, %edx
479#else
480 movl $0x02, %eax
481#endif
Subrata Banik03e971c2017-03-07 14:02:23 +0530482 wrmsr
Subrata Banik03e971c2017-03-07 14:02:23 +0530483 movl $CONFIG_DCACHE_RAM_BASE, %edi
484 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
485 shr $0x02, %ecx
486 xor %eax, %eax
487 cld
488 rep stosl
489 /*
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530490 * Set IA32_PQR_ASSOC
Subrata Banik03e971c2017-03-07 14:02:23 +0530491 * At this stage we apply LLC_WAY_MASK_1 to the cache.
Subrata Banik03e971c2017-03-07 14:02:23 +0530492 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200493 movl $IA32_PQR_ASSOC, %ecx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530494 xorl %eax, %eax
Subrata Banik03e971c2017-03-07 14:02:23 +0530495 xorl %edx, %edx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530496#if CONFIG(COS_MAPPED_TO_MSB)
497 movl $0x01, %edx
498#else
499 movl $0x01, %eax
500#endif
Subrata Banik03e971c2017-03-07 14:02:23 +0530501 wrmsr
502
503 post_code(0x27)
504 /*
505 * Enable No-Eviction Mode Run State by setting
506 * NO_EVICT_MODE MSR 2E0h bit [1] = '1'.
507 */
508
509 movl $MSR_EVICT_CTL, %ecx
510 rdmsr
511 orl $0x02, %eax
512 wrmsr
513
514 post_code(0x28)
515
516 jmp car_init_done
517#endif