blob: b60e797b2f8734eed71296d5c22779111c11e750 [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
Patrick Rudolph2b771122020-11-30 13:52:42 +010012.code32
Subrata Banik03e971c2017-03-07 14:02:23 +053013.global bootblock_pre_c_entry
14bootblock_pre_c_entry:
15
16 post_code(0x20)
17
Arthur Heymansc4772b92019-04-14 18:38:35 +020018 movl $no_reset, %esp /* return address */
19 jmp check_mtrr /* Check if CPU properly reset */
Subrata Banik03e971c2017-03-07 14:02:23 +053020
21no_reset:
22 post_code(0x21)
23
24 /* Clear/disable fixed MTRRs */
25 mov $fixed_mtrr_list_size, %ebx
26 xor %eax, %eax
27 xor %edx, %edx
28
29clear_fixed_mtrr:
30 add $-2, %ebx
31 movzwl fixed_mtrr_list(%ebx), %ecx
32 wrmsr
33 jnz clear_fixed_mtrr
34
35 post_code(0x22)
36
37 /* Figure put how many MTRRs we have, and clear them out */
38 mov $MTRR_CAP_MSR, %ecx
39 rdmsr
40 movzb %al, %ebx /* Number of variable MTRRs */
41 mov $MTRR_PHYS_BASE(0), %ecx
42 xor %eax, %eax
43 xor %edx, %edx
44
45clear_var_mtrr:
46 wrmsr
47 inc %ecx
48 wrmsr
49 inc %ecx
50 dec %ebx
51 jnz clear_var_mtrr
52
53 post_code(0x23)
54
55 /* Configure default memory type to uncacheable (UC) */
56 mov $MTRR_DEF_TYPE_MSR, %ecx
57 rdmsr
58 /* Clear enable bits and set default type to UC. */
59 and $~(MTRR_DEF_TYPE_MASK | MTRR_DEF_TYPE_EN | \
60 MTRR_DEF_TYPE_FIX_EN), %eax
61 wrmsr
62
63 /* Configure MTRR_PHYS_MASK_HIGH for proper addressing above 4GB
64 * based on the physical address size supported for this processor
65 * This is based on read from CPUID EAX = 080000008h, EAX bits [7:0]
66 *
67 * Examples:
68 * MTRR_PHYS_MASK_HIGH = 00000000Fh For 36 bit addressing
69 * MTRR_PHYS_MASK_HIGH = 0000000FFh For 40 bit addressing
70 */
71
Elyes HAOUAS05498a22018-05-28 16:26:43 +020072 movl $0x80000008, %eax /* Address sizes leaf */
Subrata Banik03e971c2017-03-07 14:02:23 +053073 cpuid
74 sub $32, %al
75 movzx %al, %eax
76 xorl %esi, %esi
77 bts %eax, %esi
78 dec %esi /* esi <- MTRR_PHYS_MASK_HIGH */
79
80 post_code(0x24)
81
82#if ((CONFIG_DCACHE_RAM_SIZE & (CONFIG_DCACHE_RAM_SIZE - 1)) == 0)
83 /* Configure CAR region as write-back (WB) */
84 mov $MTRR_PHYS_BASE(0), %ecx
85 mov $CONFIG_DCACHE_RAM_BASE, %eax
86 or $MTRR_TYPE_WRBACK, %eax
87 xor %edx,%edx
88 wrmsr
89
90 /* Configure the MTRR mask for the size region */
91 mov $MTRR_PHYS_MASK(0), %ecx
92 mov $CONFIG_DCACHE_RAM_SIZE, %eax /* size mask */
93 dec %eax
94 not %eax
95 or $MTRR_PHYS_MASK_VALID, %eax
96 movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
97 wrmsr
98#elif (CONFIG_DCACHE_RAM_SIZE == 768 * KiB) /* 768 KiB */
99 /* Configure CAR region as write-back (WB) */
100 mov $MTRR_PHYS_BASE(0), %ecx
101 mov $CONFIG_DCACHE_RAM_BASE, %eax
102 or $MTRR_TYPE_WRBACK, %eax
103 xor %edx,%edx
104 wrmsr
105
106 mov $MTRR_PHYS_MASK(0), %ecx
107 mov $(512 * KiB), %eax /* size mask */
108 dec %eax
109 not %eax
110 or $MTRR_PHYS_MASK_VALID, %eax
111 movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
112 wrmsr
113
114 mov $MTRR_PHYS_BASE(1), %ecx
115 mov $(CONFIG_DCACHE_RAM_BASE + 512 * KiB), %eax
116 or $MTRR_TYPE_WRBACK, %eax
117 xor %edx,%edx
118 wrmsr
119
120 mov $MTRR_PHYS_MASK(1), %ecx
121 mov $(256 * KiB), %eax /* size mask */
122 dec %eax
123 not %eax
124 or $MTRR_PHYS_MASK_VALID, %eax
125 movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
126 wrmsr
127#else
128#error "DCACHE_RAM_SIZE is not a power of 2 and setup code is missing"
129#endif
130 post_code(0x25)
131
132 /* Enable variable MTRRs */
133 mov $MTRR_DEF_TYPE_MSR, %ecx
134 rdmsr
135 or $MTRR_DEF_TYPE_EN, %eax
136 wrmsr
137
138 /* Enable caching */
139 mov %cr0, %eax
140 and $~(CR0_CD | CR0_NW), %eax
141 invd
142 mov %eax, %cr0
143
Julius Wernercd49cce2019-03-05 16:53:33 -0800144#if CONFIG(INTEL_CAR_NEM)
Subrata Banik03e971c2017-03-07 14:02:23 +0530145 jmp car_nem
Julius Wernercd49cce2019-03-05 16:53:33 -0800146#elif CONFIG(INTEL_CAR_CQOS)
Subrata Banik03e971c2017-03-07 14:02:23 +0530147 jmp car_cqos
Julius Wernercd49cce2019-03-05 16:53:33 -0800148#elif CONFIG(INTEL_CAR_NEM_ENHANCED)
Subrata Banik03e971c2017-03-07 14:02:23 +0530149 jmp car_nem_enhanced
150#else
151 jmp .halt_forever /* In case nothing has selected */
152#endif
153
154.global car_init_done
155car_init_done:
156
157 post_code(0x29)
158
159 /* Setup bootblock stack */
Arthur Heymansdf9cdcf2019-11-09 06:50:20 +0100160 mov $_ecar_stack, %esp
Subrata Banik03e971c2017-03-07 14:02:23 +0530161
Aaron Durbin028e18f2017-06-23 11:14:58 -0500162 /* Need to align stack to 16 bytes at call instruction. Account for
163 the two pushes below. */
164 andl $0xfffffff0, %esp
Patrick Rudolph2b771122020-11-30 13:52:42 +0100165
166#if ENV_X86_64
167 #include <cpu/x86/64bit/entry64.inc>
168 movd %mm2, %rdi
169 shlq $32, %rdi
170 movd %mm1, %rsi
171 or %rsi, %rdi
172 movd %mm0, %rsi
173#else
Aaron Durbin028e18f2017-06-23 11:14:58 -0500174 sub $8, %esp
175
Subrata Banik5885ffe2019-11-14 11:08:51 +0530176 /* push TSC value to stack */
Subrata Banik03e971c2017-03-07 14:02:23 +0530177 movd %mm2, %eax
178 pushl %eax /* tsc[63:32] */
179 movd %mm1, %eax
Elyes HAOUAS05498a22018-05-28 16:26:43 +0200180 pushl %eax /* tsc[31:0] */
Patrick Rudolph2b771122020-11-30 13:52:42 +0100181#endif
Subrata Banik03e971c2017-03-07 14:02:23 +0530182
183before_carstage:
184 post_code(0x2A)
185
186 call bootblock_c_entry
187 /* Never reached */
188
189.halt_forever:
190 post_code(POST_DEAD_CODE)
191 hlt
192 jmp .halt_forever
193
194fixed_mtrr_list:
195 .word MTRR_FIX_64K_00000
196 .word MTRR_FIX_16K_80000
197 .word MTRR_FIX_16K_A0000
198 .word MTRR_FIX_4K_C0000
199 .word MTRR_FIX_4K_C8000
200 .word MTRR_FIX_4K_D0000
201 .word MTRR_FIX_4K_D8000
202 .word MTRR_FIX_4K_E0000
203 .word MTRR_FIX_4K_E8000
204 .word MTRR_FIX_4K_F0000
205 .word MTRR_FIX_4K_F8000
206fixed_mtrr_list_size = . - fixed_mtrr_list
207
Julius Wernercd49cce2019-03-05 16:53:33 -0800208#if CONFIG(INTEL_CAR_NEM)
Subrata Banik03e971c2017-03-07 14:02:23 +0530209.global car_nem
210car_nem:
211 /* Disable cache eviction (setup stage) */
212 mov $MSR_EVICT_CTL, %ecx
213 rdmsr
214 or $0x1, %eax
215 wrmsr
216
217 post_code(0x26)
218
219 /* Clear the cache memory region. This will also fill up the cache */
220 movl $CONFIG_DCACHE_RAM_BASE, %edi
221 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
222 shr $0x02, %ecx
223 xor %eax, %eax
224 cld
225 rep stosl
226
227 post_code(0x27)
228
229 /* Disable cache eviction (run stage) */
230 mov $MSR_EVICT_CTL, %ecx
231 rdmsr
232 or $0x2, %eax
233 wrmsr
234
235 post_code(0x28)
236
237 jmp car_init_done
238
Julius Wernercd49cce2019-03-05 16:53:33 -0800239#elif CONFIG(INTEL_CAR_CQOS)
Subrata Banik03e971c2017-03-07 14:02:23 +0530240.global car_cqos
241car_cqos:
242 /*
Naresh G Solankif329f0c2017-09-27 14:21:18 +0530243 * Create CBM_LEN_MASK based on CBM_LEN
244 * Get CPUID.(EAX=10H, ECX=2H):EAX.CBM_LEN[bits 4:0]
245 */
246 mov $0x10, %eax
247 mov $0x2, %ecx
248 cpuid
249 and $0x1F, %eax
250 add $1, %al
251
252 mov $1, %ebx
253 mov %al, %cl
254 shl %cl, %ebx
255 sub $1, %ebx
256
257 /* Store the CBM_LEN_MASK in mm3 for later use. */
258 movd %ebx, %mm3
259
260 /*
Subrata Banik03e971c2017-03-07 14:02:23 +0530261 * Disable both L1 and L2 prefetcher. For yet-to-understood reason,
262 * prefetchers slow down filling cache with rep stos in CQOS mode.
263 */
264 mov $MSR_PREFETCH_CTL, %ecx
265 rdmsr
266 or $(PREFETCH_L1_DISABLE | PREFETCH_L2_DISABLE), %eax
267 wrmsr
268
269#if (CONFIG_DCACHE_RAM_SIZE == CONFIG_L2_CACHE_SIZE)
270/*
271 * If CAR size is set to full L2 size, mask is calculated as all-zeros.
272 * This is not supported by the CPU/uCode.
273 */
274#error "CQOS CAR may not use whole L2 cache area"
275#endif
276
277 /* Calculate how many bits to be used for CAR */
278 xor %edx, %edx
279 mov $CONFIG_DCACHE_RAM_SIZE, %eax /* dividend */
280 mov $CONFIG_CACHE_QOS_SIZE_PER_BIT, %ecx /* divisor */
281 div %ecx /* result is in eax */
282 mov %eax, %ecx /* save to ecx */
283 mov $1, %ebx
284 shl %cl, %ebx
285 sub $1, %ebx /* resulting mask is is in ebx */
286
287 /* Set this mask for initial cache fill */
288 mov $MSR_L2_QOS_MASK(0), %ecx
289 rdmsr
Naresh G Solankif329f0c2017-09-27 14:21:18 +0530290 mov %ebx, %eax
Subrata Banik03e971c2017-03-07 14:02:23 +0530291 wrmsr
292
293 /* Set CLOS selector to 0 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200294 mov $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530295 rdmsr
296 and $~IA32_PQR_ASSOC_MASK, %edx /* select mask 0 */
297 wrmsr
298
299 /* We will need to block CAR region from evicts */
300 mov $MSR_L2_QOS_MASK(1), %ecx
301 rdmsr
302 /* Invert bits that are to be used for cache */
Naresh G Solankif329f0c2017-09-27 14:21:18 +0530303 mov %ebx, %eax
304 xor $~0, %eax /* invert 32 bits */
305
306 /*
307 * Use CBM_LEN_MASK stored in mm3 to set bits based on Capacity Bit
308 * Mask Length.
309 */
310 movd %mm3, %ebx
311 and %ebx, %eax
Subrata Banik03e971c2017-03-07 14:02:23 +0530312 wrmsr
313
314 post_code(0x26)
315
316 /* Clear the cache memory region. This will also fill up the cache */
317 movl $CONFIG_DCACHE_RAM_BASE, %edi
318 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
319 shr $0x02, %ecx
320 xor %eax, %eax
321 cld
322 rep stosl
323
324 post_code(0x27)
325
326 /* Cache is populated. Use mask 1 that will block evicts */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200327 mov $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530328 rdmsr
329 and $~IA32_PQR_ASSOC_MASK, %edx /* clear index bits first */
330 or $1, %edx /* select mask 1 */
331 wrmsr
332
333 /* Enable prefetchers */
334 mov $MSR_PREFETCH_CTL, %ecx
335 rdmsr
336 and $~(PREFETCH_L1_DISABLE | PREFETCH_L2_DISABLE), %eax
337 wrmsr
338
339 post_code(0x28)
340
341 jmp car_init_done
342
Julius Wernercd49cce2019-03-05 16:53:33 -0800343#elif CONFIG(INTEL_CAR_NEM_ENHANCED)
Subrata Banik03e971c2017-03-07 14:02:23 +0530344.global car_nem_enhanced
345car_nem_enhanced:
346 /* Disable cache eviction (setup stage) */
347 mov $MSR_EVICT_CTL, %ecx
348 rdmsr
349 or $0x1, %eax
350 wrmsr
351 post_code(0x26)
352
353 /* Create n-way set associativity of cache */
354 xorl %edi, %edi
355find_llc_subleaf:
356 movl %edi, %ecx
357 movl $0x04, %eax
358 cpuid
359 inc %edi
360 and $0xe0, %al /* EAX[7:5] = Cache Level */
361 cmp $0x60, %al /* Check to see if it is LLC */
362 jnz find_llc_subleaf
363
364 /*
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530365 * Calculate the total LLC size
366 * (Line_Size + 1) * (Sets + 1) * (Partitions + 1) * (Ways + 1)
367 * (EBX[11:0] + 1) * (ECX + 1) * (EBX[21:12] + 1) * EBX[31:22] + 1)
368 */
369
370 mov %ebx, %eax
371 and $0xFFF, %eax
372 inc %eax
373 inc %ecx
374 mul %ecx
375 mov %eax, %ecx
376 mov %ebx, %eax
377 shr $12, %eax
378 and $0x3FF, %eax
379 inc %eax
380 mul %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530381 shr $22, %ebx
382 inc %ebx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530383 mov %ebx, %edx
384 mul %ebx /* eax now holds total LLC size */
Subrata Banik03e971c2017-03-07 14:02:23 +0530385
386 /*
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530387 * The number of the ways that we want to protect from eviction
388 * can be calculated as RW data stack size / way size where way
389 * size is Total LLC size / Total number of LLC ways.
Subrata Banik03e971c2017-03-07 14:02:23 +0530390 */
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530391 div %ebx /* way size */
392 mov %eax, %ecx
393
Subrata Banik03e971c2017-03-07 14:02:23 +0530394 /*
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530395 * Check if way size if bigger than the cache ram size.
396 * Then we need to allocate just one way for non-eviction
397 * of RW data.
398 */
399 movl $0x01, %eax
400 cmp $CONFIG_DCACHE_RAM_SIZE, %ecx
401 jnc set_eviction_mask
402
403 /*
404 * RW data size / way size is equal to number of
405 * ways to be configured for non-eviction
406 */
407 mov $CONFIG_DCACHE_RAM_SIZE, %eax
408 div %ecx
409 mov %eax, %ecx
410 movl $0x01, %eax
411 shl %cl, %eax
412 subl $0x01, %eax
413
414set_eviction_mask:
415 mov %ebx, %ecx /* back up the number of ways */
Subrata Banik89b296c2020-12-06 22:54:10 +0530416 mov %eax, %ebx /* back up the non-eviction mask */
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530417 /*
Shreesh Chhabbi87c7ec72020-12-03 14:07:15 -0800418 * Program MSR 0xC91 IA32_L3_MASK_1
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530419 * This MSR contain one bit per each way of LLC
Subrata Banik03e971c2017-03-07 14:02:23 +0530420 * - If this bit is '0' - the way is protected from eviction
421 * - If this bit is '1' - the way is not protected from eviction
422 */
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530423 mov $0x1, %eax
424 shl %cl, %eax
425 subl $0x01, %eax
426 mov %eax, %ecx
427 mov %ebx, %eax
428
429 xor $~0, %eax /* invert 32 bits */
430 and %ecx, %eax
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200431 movl $IA32_L3_MASK_1, %ecx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530432 xorl %edx, %edx
433 wrmsr
434
435 /*
Shreesh Chhabbi87c7ec72020-12-03 14:07:15 -0800436 * Program MSR 0xC92 IA32_L3_MASK_2
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530437 * This MSR contain one bit per each way of LLC
438 * - If this bit is '0' - the way is protected from eviction
439 * - If this bit is '1' - the way is not protected from eviction
440 */
441 mov %ebx, %eax
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530442 movl $IA32_L3_MASK_2, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530443 xorl %edx, %edx
444 wrmsr
445 /*
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530446 * Set IA32_PQR_ASSOC
Subrata Banik03e971c2017-03-07 14:02:23 +0530447 *
448 * Possible values:
449 * 0: Default value, no way mask should be applied
450 * 1: Apply way mask 1 to LLC
451 * 2: Apply way mask 2 to LLC
452 * 3: Shouldn't be use in NEM Mode
453 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200454 movl $IA32_PQR_ASSOC, %ecx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530455 xorl %eax, %eax
Subrata Banik03e971c2017-03-07 14:02:23 +0530456 xorl %edx, %edx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530457#if CONFIG(COS_MAPPED_TO_MSB)
458 movl $0x02, %edx
459#else
460 movl $0x02, %eax
461#endif
Subrata Banik03e971c2017-03-07 14:02:23 +0530462 wrmsr
463
464 movl $CONFIG_DCACHE_RAM_BASE, %edi
465 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
466 shr $0x02, %ecx
467 xor %eax, %eax
468 cld
469 rep stosl
470 /*
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530471 * Set IA32_PQR_ASSOC
Subrata Banik03e971c2017-03-07 14:02:23 +0530472 * At this stage we apply LLC_WAY_MASK_1 to the cache.
Subrata Banik03e971c2017-03-07 14:02:23 +0530473 */
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 $0x01, %edx
479#else
480 movl $0x01, %eax
481#endif
Subrata Banik03e971c2017-03-07 14:02:23 +0530482 wrmsr
483
484 post_code(0x27)
485 /*
486 * Enable No-Eviction Mode Run State by setting
487 * NO_EVICT_MODE MSR 2E0h bit [1] = '1'.
488 */
489
490 movl $MSR_EVICT_CTL, %ecx
491 rdmsr
492 orl $0x02, %eax
493 wrmsr
494
495 post_code(0x28)
496
497 jmp car_init_done
498#endif