blob: 5f6b6de07cda6728f4e7d4b9af2d7f02f25b176a [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>
Arthur Heymans481c52d2019-11-08 17:05:04 +01004#include <cpu/intel/msr.h>
Subrata Banik03e971c2017-03-07 14:02:23 +05305#include <cpu/x86/cache.h>
6#include <cpu/x86/cr.h>
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +02007#include <cpu/x86/msr.h>
Subrata Banik03e971c2017-03-07 14:02:23 +05308#include <cpu/x86/mtrr.h>
9#include <cpu/x86/post_code.h>
Subrata Banik03e971c2017-03-07 14:02:23 +053010#include <intelblocks/msr.h>
Martin Roth8c974502022-11-20 17:56:44 -070011#include <intelblocks/post_codes.h>
Subrata Banik03e971c2017-03-07 14:02:23 +053012
Kyösti Mälkki7522a8f2020-11-20 16:47:38 +020013.section .init, "ax", @progbits
14
Patrick Rudolph2b771122020-11-30 13:52:42 +010015.code32
Arthur Heymans64c9c6d2019-11-25 09:45:40 +010016
17/*
18 * macro: find_free_mtrr
19 * Clobbers: %eax, %ebx, %ecx, %edx.
20 * Returns:
21 * %ebx contains the number of freely available MTRR's.
22 * It should be checked against 0.
23 * %ecx holds the MTRR_BASE of the free MTRR.
24 */
25.macro find_free_mtrr
26 /* Figure out how many MTRRs we have */
27 mov $MTRR_CAP_MSR, %ecx
28 rdmsr
29 movzb %al, %ebx /* Number of variable MTRRs */
30
31 /* Find a free variable MTRR */
32 movl $MTRR_PHYS_MASK(0), %ecx
331:
34 rdmsr
35 test $MTRR_PHYS_MASK_VALID, %eax
36 jz 2f
37 addl $2, %ecx
38 dec %ebx
39 jnz 1b
402:
41 /* %ecx needs to hold the MTRR_BASE */
42 decl %ecx
43.endm
44
Arthur Heymans99a48bc2019-11-25 09:56:20 +010045/*
46 * macro: clear_car
47 * Clears the region between CONFIG_DCACHE_RAM_BASE and
48 * CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE to populate
49 * cachelines.
50 * Clobbers %eax, %ecx, %edi.
51 */
52.macro clear_car
53 /* Clear the cache memory region. This will also fill up the cache */
54 movl $CONFIG_DCACHE_RAM_BASE, %edi
55 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
56 shr $0x02, %ecx
57 xor %eax, %eax
58 cld
59 rep stosl
60.endm
61
Arthur Heymanscd96fed52021-06-23 10:48:28 +020062/*
63 * macro: is_bootguard_nem
64 * Checks if the Bootguard ACM has enabled non eviction mode
65 * Clobbers %eax, %ecx, %edx
66 * Returns %eax and sets/unsets zero flag
67 */
68.macro is_bootguard_nem
Arthur Heymans6da7fa22021-06-23 10:52:01 +020069#if CONFIG(SOC_INTEL_NO_BOOTGUARD_MSR)
70 xorl %eax, %eax
71#else
Arthur Heymanscd96fed52021-06-23 10:48:28 +020072 movl $MSR_BOOT_GUARD_SACM_INFO, %ecx
73 rdmsr
74 andl $B_BOOT_GUARD_SACM_INFO_NEM_ENABLED, %eax
Arthur Heymans6da7fa22021-06-23 10:52:01 +020075#endif
Arthur Heymanscd96fed52021-06-23 10:48:28 +020076.endm
77
Subrata Banik03e971c2017-03-07 14:02:23 +053078.global bootblock_pre_c_entry
79bootblock_pre_c_entry:
80
Martin Roth8c974502022-11-20 17:56:44 -070081 post_code(POST_BOOTBLOCK_PRE_C_ENTRY)
Subrata Banik03e971c2017-03-07 14:02:23 +053082
Arthur Heymans481c52d2019-11-08 17:05:04 +010083/* Bootguard sets up its own CAR and needs separate handling */
84check_boot_guard:
Arthur Heymanscd96fed52021-06-23 10:48:28 +020085 is_bootguard_nem
Arthur Heymans481c52d2019-11-08 17:05:04 +010086 jz no_bootguard
87
88 /* Disable PBE timer */
89 movl $MSR_BC_PBEC, %ecx
90 movl $B_STOP_PBET, %eax
91 xorl %edx, %edx
92 wrmsr
93
94 jmp setup_car_mtrr
95
96no_bootguard:
Arthur Heymansc4772b92019-04-14 18:38:35 +020097 movl $no_reset, %esp /* return address */
98 jmp check_mtrr /* Check if CPU properly reset */
Subrata Banik03e971c2017-03-07 14:02:23 +053099
100no_reset:
Martin Roth8c974502022-11-20 17:56:44 -0700101 post_code(POST_SOC_NO_RESET)
Subrata Banik03e971c2017-03-07 14:02:23 +0530102
103 /* Clear/disable fixed MTRRs */
Arthur Heymans2834d982022-11-08 15:06:42 +0100104 mov $fixed_mtrr_list, %ebx
Subrata Banik03e971c2017-03-07 14:02:23 +0530105 xor %eax, %eax
106 xor %edx, %edx
107
108clear_fixed_mtrr:
Arthur Heymans2834d982022-11-08 15:06:42 +0100109 movzwl (%ebx), %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530110 wrmsr
Arthur Heymans2834d982022-11-08 15:06:42 +0100111 add $2, %ebx
112 cmp $fixed_mtrr_list_end, %ebx
113 jl clear_fixed_mtrr
Subrata Banik03e971c2017-03-07 14:02:23 +0530114
Martin Roth8c974502022-11-20 17:56:44 -0700115 post_code(POST_SOC_CLEAR_FIXED_MTRRS)
Subrata Banik03e971c2017-03-07 14:02:23 +0530116
Arthur Heymansc57d3032021-06-16 09:56:26 +0200117 /* Figure out how many MTRRs we have, and clear them out */
Subrata Banik03e971c2017-03-07 14:02:23 +0530118 mov $MTRR_CAP_MSR, %ecx
119 rdmsr
120 movzb %al, %ebx /* Number of variable MTRRs */
121 mov $MTRR_PHYS_BASE(0), %ecx
122 xor %eax, %eax
123 xor %edx, %edx
124
125clear_var_mtrr:
126 wrmsr
127 inc %ecx
128 wrmsr
129 inc %ecx
130 dec %ebx
131 jnz clear_var_mtrr
132
Martin Roth8c974502022-11-20 17:56:44 -0700133 post_code(POST_SOC_CLEAR_VAR_MTRRS)
Subrata Banik03e971c2017-03-07 14:02:23 +0530134
135 /* Configure default memory type to uncacheable (UC) */
136 mov $MTRR_DEF_TYPE_MSR, %ecx
137 rdmsr
138 /* Clear enable bits and set default type to UC. */
139 and $~(MTRR_DEF_TYPE_MASK | MTRR_DEF_TYPE_EN | \
140 MTRR_DEF_TYPE_FIX_EN), %eax
141 wrmsr
142
Arthur Heymans481c52d2019-11-08 17:05:04 +0100143setup_car_mtrr:
Subrata Banik03e971c2017-03-07 14:02:23 +0530144 /* Configure MTRR_PHYS_MASK_HIGH for proper addressing above 4GB
145 * based on the physical address size supported for this processor
146 * This is based on read from CPUID EAX = 080000008h, EAX bits [7:0]
147 *
148 * Examples:
149 * MTRR_PHYS_MASK_HIGH = 00000000Fh For 36 bit addressing
150 * MTRR_PHYS_MASK_HIGH = 0000000FFh For 40 bit addressing
151 */
152
Elyes HAOUAS05498a22018-05-28 16:26:43 +0200153 movl $0x80000008, %eax /* Address sizes leaf */
Subrata Banik03e971c2017-03-07 14:02:23 +0530154 cpuid
155 sub $32, %al
156 movzx %al, %eax
157 xorl %esi, %esi
158 bts %eax, %esi
159 dec %esi /* esi <- MTRR_PHYS_MASK_HIGH */
160
Martin Roth8c974502022-11-20 17:56:44 -0700161 post_code(POST_SOC_SET_UP_CAR_MTRRS)
Subrata Banik03e971c2017-03-07 14:02:23 +0530162
163#if ((CONFIG_DCACHE_RAM_SIZE & (CONFIG_DCACHE_RAM_SIZE - 1)) == 0)
Arthur Heymans64c9c6d2019-11-25 09:45:40 +0100164 find_free_mtrr
165 test %ebx, %ebx
166 jz .halt_forever
167
Subrata Banik03e971c2017-03-07 14:02:23 +0530168 /* Configure CAR region as write-back (WB) */
Subrata Banik03e971c2017-03-07 14:02:23 +0530169 mov $CONFIG_DCACHE_RAM_BASE, %eax
170 or $MTRR_TYPE_WRBACK, %eax
171 xor %edx,%edx
172 wrmsr
173
174 /* Configure the MTRR mask for the size region */
Arthur Heymans64c9c6d2019-11-25 09:45:40 +0100175 inc %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530176 mov $CONFIG_DCACHE_RAM_SIZE, %eax /* size mask */
177 dec %eax
178 not %eax
179 or $MTRR_PHYS_MASK_VALID, %eax
180 movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
181 wrmsr
182#elif (CONFIG_DCACHE_RAM_SIZE == 768 * KiB) /* 768 KiB */
Arthur Heymans64c9c6d2019-11-25 09:45:40 +0100183 find_free_mtrr
184 test %ebx, %ebx
185 jz .halt_forever
186
Subrata Banik03e971c2017-03-07 14:02:23 +0530187 /* Configure CAR region as write-back (WB) */
Subrata Banik03e971c2017-03-07 14:02:23 +0530188 mov $CONFIG_DCACHE_RAM_BASE, %eax
189 or $MTRR_TYPE_WRBACK, %eax
190 xor %edx,%edx
191 wrmsr
192
Arthur Heymans64c9c6d2019-11-25 09:45:40 +0100193 incl %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530194 mov $(512 * KiB), %eax /* size mask */
195 dec %eax
196 not %eax
197 or $MTRR_PHYS_MASK_VALID, %eax
198 movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
199 wrmsr
200
Arthur Heymans64c9c6d2019-11-25 09:45:40 +0100201 find_free_mtrr
202 test %ebx, %ebx
203 jz .halt_forever
2041:
Subrata Banik03e971c2017-03-07 14:02:23 +0530205 mov $(CONFIG_DCACHE_RAM_BASE + 512 * KiB), %eax
206 or $MTRR_TYPE_WRBACK, %eax
207 xor %edx,%edx
208 wrmsr
209
Arthur Heymans64c9c6d2019-11-25 09:45:40 +0100210 incl %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530211 mov $(256 * KiB), %eax /* size mask */
212 dec %eax
213 not %eax
214 or $MTRR_PHYS_MASK_VALID, %eax
215 movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
216 wrmsr
217#else
218#error "DCACHE_RAM_SIZE is not a power of 2 and setup code is missing"
219#endif
Martin Roth8c974502022-11-20 17:56:44 -0700220 post_code(POST_SOC_BOOTGUARD_SETUP)
Subrata Banik03e971c2017-03-07 14:02:23 +0530221
Arthur Heymanscd96fed52021-06-23 10:48:28 +0200222 is_bootguard_nem
Arthur Heymans481c52d2019-11-08 17:05:04 +0100223 jz no_bootguard_car_continue
224
Arthur Heymans5cb24d42021-06-23 13:17:33 +0200225 /*
226 * With Bootguard some RO caching of the flash is already set up by
227 * the ACM. It looks like in such a setup 'clear_car' will not properly fill
228 * the cachelines. Fill all the CAR cachelines explicitly using sfence.
229 * This assumes 64 bytes cachelines.
230 */
231 movl $CONFIG_DCACHE_RAM_BASE, %edi
232 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
233 shr $0x06, %ecx
234 xor %eax, %eax
235
2361:
237 movl %eax, (%edi)
238 sfence
239 add $64, %edi
240 loop 1b
241
Arthur Heymans481c52d2019-11-08 17:05:04 +0100242 clear_car
243
244 jmp car_init_done
245
246no_bootguard_car_continue:
Subrata Banik03e971c2017-03-07 14:02:23 +0530247 /* Enable variable MTRRs */
248 mov $MTRR_DEF_TYPE_MSR, %ecx
249 rdmsr
250 or $MTRR_DEF_TYPE_EN, %eax
251 wrmsr
252
253 /* Enable caching */
254 mov %cr0, %eax
255 and $~(CR0_CD | CR0_NW), %eax
256 invd
257 mov %eax, %cr0
258
Julius Wernercd49cce2019-03-05 16:53:33 -0800259#if CONFIG(INTEL_CAR_NEM)
Subrata Banik03e971c2017-03-07 14:02:23 +0530260 jmp car_nem
Julius Wernercd49cce2019-03-05 16:53:33 -0800261#elif CONFIG(INTEL_CAR_CQOS)
Subrata Banik03e971c2017-03-07 14:02:23 +0530262 jmp car_cqos
Julius Wernercd49cce2019-03-05 16:53:33 -0800263#elif CONFIG(INTEL_CAR_NEM_ENHANCED)
Subrata Banik03e971c2017-03-07 14:02:23 +0530264 jmp car_nem_enhanced
265#else
266 jmp .halt_forever /* In case nothing has selected */
267#endif
268
269.global car_init_done
270car_init_done:
271
Martin Roth8c974502022-11-20 17:56:44 -0700272 post_code(POST_SOC_CAR_INIT_DONE)
Subrata Banik03e971c2017-03-07 14:02:23 +0530273
274 /* Setup bootblock stack */
Arthur Heymansdf9cdcf2019-11-09 06:50:20 +0100275 mov $_ecar_stack, %esp
Subrata Banik03e971c2017-03-07 14:02:23 +0530276
Aaron Durbin028e18f2017-06-23 11:14:58 -0500277 /* Need to align stack to 16 bytes at call instruction. Account for
278 the two pushes below. */
279 andl $0xfffffff0, %esp
Patrick Rudolph2b771122020-11-30 13:52:42 +0100280
281#if ENV_X86_64
282 #include <cpu/x86/64bit/entry64.inc>
283 movd %mm2, %rdi
284 shlq $32, %rdi
285 movd %mm1, %rsi
286 or %rsi, %rdi
287 movd %mm0, %rsi
288#else
Aaron Durbin028e18f2017-06-23 11:14:58 -0500289 sub $8, %esp
290
Subrata Banik5885ffe2019-11-14 11:08:51 +0530291 /* push TSC value to stack */
Subrata Banik03e971c2017-03-07 14:02:23 +0530292 movd %mm2, %eax
293 pushl %eax /* tsc[63:32] */
294 movd %mm1, %eax
Elyes HAOUAS05498a22018-05-28 16:26:43 +0200295 pushl %eax /* tsc[31:0] */
Patrick Rudolph2b771122020-11-30 13:52:42 +0100296#endif
Subrata Banik03e971c2017-03-07 14:02:23 +0530297
298before_carstage:
Martin Roth8c974502022-11-20 17:56:44 -0700299 post_code(POST_SOC_BEFORE_CARSTAGE)
Subrata Banik03e971c2017-03-07 14:02:23 +0530300
301 call bootblock_c_entry
302 /* Never reached */
303
304.halt_forever:
lilacious40cb3fe2023-06-21 23:24:14 +0200305 post_code(POSTCODE_DEAD_CODE)
Subrata Banik03e971c2017-03-07 14:02:23 +0530306 hlt
307 jmp .halt_forever
308
309fixed_mtrr_list:
310 .word MTRR_FIX_64K_00000
311 .word MTRR_FIX_16K_80000
312 .word MTRR_FIX_16K_A0000
313 .word MTRR_FIX_4K_C0000
314 .word MTRR_FIX_4K_C8000
315 .word MTRR_FIX_4K_D0000
316 .word MTRR_FIX_4K_D8000
317 .word MTRR_FIX_4K_E0000
318 .word MTRR_FIX_4K_E8000
319 .word MTRR_FIX_4K_F0000
320 .word MTRR_FIX_4K_F8000
Arthur Heymans2834d982022-11-08 15:06:42 +0100321fixed_mtrr_list_end:
Subrata Banik03e971c2017-03-07 14:02:23 +0530322
Julius Wernercd49cce2019-03-05 16:53:33 -0800323#if CONFIG(INTEL_CAR_NEM)
Subrata Banik03e971c2017-03-07 14:02:23 +0530324.global car_nem
325car_nem:
326 /* Disable cache eviction (setup stage) */
327 mov $MSR_EVICT_CTL, %ecx
328 rdmsr
329 or $0x1, %eax
330 wrmsr
331
Martin Roth8c974502022-11-20 17:56:44 -0700332 post_code(POST_SOC_CLEARING_CAR)
Subrata Banik03e971c2017-03-07 14:02:23 +0530333
Arthur Heymans99a48bc2019-11-25 09:56:20 +0100334 clear_car
Subrata Banik03e971c2017-03-07 14:02:23 +0530335
Martin Roth8c974502022-11-20 17:56:44 -0700336 post_code(POST_SOC_DISABLE_CACHE_EVICT)
Subrata Banik03e971c2017-03-07 14:02:23 +0530337
338 /* Disable cache eviction (run stage) */
339 mov $MSR_EVICT_CTL, %ecx
340 rdmsr
341 or $0x2, %eax
342 wrmsr
343
Subrata Banik03e971c2017-03-07 14:02:23 +0530344 jmp car_init_done
345
Julius Wernercd49cce2019-03-05 16:53:33 -0800346#elif CONFIG(INTEL_CAR_CQOS)
Subrata Banik03e971c2017-03-07 14:02:23 +0530347.global car_cqos
348car_cqos:
349 /*
Naresh G Solankif329f0c2017-09-27 14:21:18 +0530350 * Create CBM_LEN_MASK based on CBM_LEN
351 * Get CPUID.(EAX=10H, ECX=2H):EAX.CBM_LEN[bits 4:0]
352 */
353 mov $0x10, %eax
354 mov $0x2, %ecx
355 cpuid
356 and $0x1F, %eax
357 add $1, %al
358
359 mov $1, %ebx
360 mov %al, %cl
361 shl %cl, %ebx
362 sub $1, %ebx
363
364 /* Store the CBM_LEN_MASK in mm3 for later use. */
365 movd %ebx, %mm3
366
367 /*
Subrata Banik03e971c2017-03-07 14:02:23 +0530368 * Disable both L1 and L2 prefetcher. For yet-to-understood reason,
369 * prefetchers slow down filling cache with rep stos in CQOS mode.
370 */
371 mov $MSR_PREFETCH_CTL, %ecx
372 rdmsr
373 or $(PREFETCH_L1_DISABLE | PREFETCH_L2_DISABLE), %eax
374 wrmsr
375
376#if (CONFIG_DCACHE_RAM_SIZE == CONFIG_L2_CACHE_SIZE)
377/*
378 * If CAR size is set to full L2 size, mask is calculated as all-zeros.
379 * This is not supported by the CPU/uCode.
380 */
381#error "CQOS CAR may not use whole L2 cache area"
382#endif
383
384 /* Calculate how many bits to be used for CAR */
385 xor %edx, %edx
386 mov $CONFIG_DCACHE_RAM_SIZE, %eax /* dividend */
387 mov $CONFIG_CACHE_QOS_SIZE_PER_BIT, %ecx /* divisor */
388 div %ecx /* result is in eax */
389 mov %eax, %ecx /* save to ecx */
390 mov $1, %ebx
391 shl %cl, %ebx
Elyes Haouas3b3bb7c2023-02-08 12:49:33 +0100392 sub $1, %ebx /* resulting mask is in ebx */
Subrata Banik03e971c2017-03-07 14:02:23 +0530393
394 /* Set this mask for initial cache fill */
395 mov $MSR_L2_QOS_MASK(0), %ecx
396 rdmsr
Naresh G Solankif329f0c2017-09-27 14:21:18 +0530397 mov %ebx, %eax
Subrata Banik03e971c2017-03-07 14:02:23 +0530398 wrmsr
399
400 /* Set CLOS selector to 0 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200401 mov $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530402 rdmsr
403 and $~IA32_PQR_ASSOC_MASK, %edx /* select mask 0 */
404 wrmsr
405
406 /* We will need to block CAR region from evicts */
407 mov $MSR_L2_QOS_MASK(1), %ecx
408 rdmsr
409 /* Invert bits that are to be used for cache */
Naresh G Solankif329f0c2017-09-27 14:21:18 +0530410 mov %ebx, %eax
411 xor $~0, %eax /* invert 32 bits */
412
413 /*
414 * Use CBM_LEN_MASK stored in mm3 to set bits based on Capacity Bit
415 * Mask Length.
416 */
417 movd %mm3, %ebx
418 and %ebx, %eax
Subrata Banik03e971c2017-03-07 14:02:23 +0530419 wrmsr
420
Martin Roth8c974502022-11-20 17:56:44 -0700421 post_code(POST_SOC_CLEARING_CAR)
Subrata Banik03e971c2017-03-07 14:02:23 +0530422
Arthur Heymans99a48bc2019-11-25 09:56:20 +0100423 clear_car
Subrata Banik03e971c2017-03-07 14:02:23 +0530424
Martin Roth8c974502022-11-20 17:56:44 -0700425 post_code(POST_SOC_DISABLE_CACHE_EVICT)
Subrata Banik03e971c2017-03-07 14:02:23 +0530426
427 /* Cache is populated. Use mask 1 that will block evicts */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200428 mov $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530429 rdmsr
430 and $~IA32_PQR_ASSOC_MASK, %edx /* clear index bits first */
431 or $1, %edx /* select mask 1 */
432 wrmsr
433
434 /* Enable prefetchers */
435 mov $MSR_PREFETCH_CTL, %ecx
436 rdmsr
437 and $~(PREFETCH_L1_DISABLE | PREFETCH_L2_DISABLE), %eax
438 wrmsr
439
Subrata Banik03e971c2017-03-07 14:02:23 +0530440 jmp car_init_done
441
Julius Wernercd49cce2019-03-05 16:53:33 -0800442#elif CONFIG(INTEL_CAR_NEM_ENHANCED)
Subrata Banik03e971c2017-03-07 14:02:23 +0530443.global car_nem_enhanced
444car_nem_enhanced:
445 /* Disable cache eviction (setup stage) */
446 mov $MSR_EVICT_CTL, %ecx
447 rdmsr
448 or $0x1, %eax
449 wrmsr
Martin Roth8c974502022-11-20 17:56:44 -0700450 post_code(POST_SOC_CAR_NEM_ENHANCED)
Subrata Banik03e971c2017-03-07 14:02:23 +0530451
452 /* Create n-way set associativity of cache */
453 xorl %edi, %edi
454find_llc_subleaf:
455 movl %edi, %ecx
456 movl $0x04, %eax
457 cpuid
458 inc %edi
459 and $0xe0, %al /* EAX[7:5] = Cache Level */
460 cmp $0x60, %al /* Check to see if it is LLC */
461 jnz find_llc_subleaf
462
463 /*
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530464 * Calculate the total LLC size
465 * (Line_Size + 1) * (Sets + 1) * (Partitions + 1) * (Ways + 1)
466 * (EBX[11:0] + 1) * (ECX + 1) * (EBX[21:12] + 1) * EBX[31:22] + 1)
467 */
468
469 mov %ebx, %eax
470 and $0xFFF, %eax
471 inc %eax
472 inc %ecx
473 mul %ecx
474 mov %eax, %ecx
475 mov %ebx, %eax
476 shr $12, %eax
477 and $0x3FF, %eax
478 inc %eax
479 mul %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530480 shr $22, %ebx
481 inc %ebx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530482 mov %ebx, %edx
483 mul %ebx /* eax now holds total LLC size */
Subrata Banik03e971c2017-03-07 14:02:23 +0530484
485 /*
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530486 * The number of the ways that we want to protect from eviction
487 * can be calculated as RW data stack size / way size where way
488 * size is Total LLC size / Total number of LLC ways.
Subrata Banik03e971c2017-03-07 14:02:23 +0530489 */
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530490 div %ebx /* way size */
491 mov %eax, %ecx
492
Subrata Banik03e971c2017-03-07 14:02:23 +0530493 /*
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530494 * Check if way size if bigger than the cache ram size.
495 * Then we need to allocate just one way for non-eviction
496 * of RW data.
497 */
Subrata Banik06039022021-03-09 14:40:39 +0530498 movl $0x01, %eax
Subrata Banik16ab9bd2021-07-30 17:01:11 +0530499 mov %eax, %edx /* back up data_ways in edx */
Subrata Banik06039022021-03-09 14:40:39 +0530500 cmp $CONFIG_DCACHE_RAM_SIZE, %ecx
501 jnc set_eviction_mask
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530502
503 /*
504 * RW data size / way size is equal to number of
505 * ways to be configured for non-eviction
506 */
Subrata Banik06039022021-03-09 14:40:39 +0530507 mov $CONFIG_DCACHE_RAM_SIZE, %eax
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530508 div %ecx
Subrata Banik16ab9bd2021-07-30 17:01:11 +0530509 mov %eax, %edx /* back up data_ways in edx */
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530510 mov %eax, %ecx
511 movl $0x01, %eax
512 shl %cl, %eax
513 subl $0x01, %eax
514
515set_eviction_mask:
Subrata Banik1b12d782021-07-08 12:50:42 +0530516 mov %ebx, %edi /* back up number of ways */
Subrata Banik39b53d92021-07-23 14:57:50 +0530517 mov %eax, %esi /* back up the non-eviction mask */
Shreesh Chhabbi860c6842020-12-03 15:06:20 -0800518#if CONFIG(CAR_HAS_SF_MASKS)
Subrata Banik16ab9bd2021-07-30 17:01:11 +0530519 mov %edx, %eax /* restore data_ways in eax */
520 /*
521 * Calculate SF masks 2:
522 * 1. if CONFIG_SF_MASK_2WAYS_PER_BIT: data_ways = data_ways / 2
523 * 2. Program MSR 0x1892 Non-Eviction Mask #2
524 * IA32_CR_SF_QOS_MASK_2 = ((1 << data_ways) - 1)
525 */
526#if CONFIG(SF_MASK_2WAYS_PER_BIT)
527 cmp $0x01, %eax /* Skip Step 1 if data_ways = 1 */
528 jz program_sf2
529 movl $0x01, %ecx /* Step 1 */
530 shr %cl, %eax
531#endif
532 /* Step 2 */
533 mov %eax, %ecx
534 movl $0x01, %eax
535 shl %cl, %eax
536 subl $0x01, %eax
537program_sf2:
Subrata Banikbaf922c2021-07-30 17:24:38 +0530538 mov %eax, %ebx /* back up IA32_CR_SF_QOS_MASK_2 in ebx */
Subrata Banik16ab9bd2021-07-30 17:01:11 +0530539 xorl %edx, %edx
540 mov $IA32_CR_SF_QOS_MASK_2, %ecx
541 wrmsr
542
Shreesh Chhabbi860c6842020-12-03 15:06:20 -0800543 /*
Subrata Banikbaf922c2021-07-30 17:24:38 +0530544 * Calculate the SF Mask 1:
Martin Roth26f97f92021-10-01 14:53:22 -0600545 * 1. Calculate SFWayCnt = IA32_SF_QOS_INFO & Bit [5:0]
Subrata Banikbaf922c2021-07-30 17:24:38 +0530546 * 2. if CONFIG_SF_MASK_2WAYS_PER_BIT: SFWayCnt = SFWayCnt / 2
547 * 3. Set SF_MASK_1 = ((1 << SFWayCnt) - 1) - IA32_CR_SF_QOS_MASK_2
Shreesh Chhabbi860c6842020-12-03 15:06:20 -0800548 */
Subrata Banikbaf922c2021-07-30 17:24:38 +0530549 mov $IA32_SF_QOS_INFO, %ecx
550 rdmsr
551 and $IA32_SF_WAY_COUNT_MASK, %eax /* Step 1 */
552#if CONFIG(SF_MASK_2WAYS_PER_BIT)
553 /* Assumption: skip checking SFWayCnt = 1 i.e. 1 way LLC (which is not practical) */
554 movl $0x01, %ecx /* Step 2 */
555 shr %cl, %eax
556#endif
557 /* Step 3 */
558 mov %eax, %ecx
559 movl $0x01, %eax
Shreesh Chhabbi860c6842020-12-03 15:06:20 -0800560 shl %cl, %eax
Subrata Banikbaf922c2021-07-30 17:24:38 +0530561 subl $0x01, %eax
562 sub %ebx, %eax
Shreesh Chhabbi860c6842020-12-03 15:06:20 -0800563 xorl %edx, %edx
Subrata Banikbaf922c2021-07-30 17:24:38 +0530564 movl $IA32_CR_SF_QOS_MASK_1, %ecx
Shreesh Chhabbi860c6842020-12-03 15:06:20 -0800565 wrmsr
Shreesh Chhabbi860c6842020-12-03 15:06:20 -0800566#endif
Subrata Banik0e2510f2021-07-30 17:36:56 +0530567#if CONFIG(CAR_HAS_L3_PROTECTED_WAYS)
568 /* Set MSR 0xC85 L3_Protected_ways = ((1 << data ways) - 1) */
569 mov %esi, %eax
570 xorl %edx, %edx
571 mov $IA32_L3_PROTECTED_WAYS, %ecx
572 wrmsr
573#endif
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530574 /*
Shreesh Chhabbi87c7ec72020-12-03 14:07:15 -0800575 * Program MSR 0xC91 IA32_L3_MASK_1
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530576 * This MSR contain one bit per each way of LLC
Subrata Banik03e971c2017-03-07 14:02:23 +0530577 * - If this bit is '0' - the way is protected from eviction
578 * - If this bit is '1' - the way is not protected from eviction
579 */
Subrata Banik06039022021-03-09 14:40:39 +0530580 mov $0x1, %eax
Subrata Banik1b12d782021-07-08 12:50:42 +0530581 mov %edi, %ecx
Subrata Banik06039022021-03-09 14:40:39 +0530582 shl %cl, %eax
583 subl $0x01, %eax
584 mov %eax, %ecx
Subrata Banik1b12d782021-07-08 12:50:42 +0530585 mov %esi, %eax
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530586
587 xor $~0, %eax /* invert 32 bits */
588 and %ecx, %eax
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200589 movl $IA32_L3_MASK_1, %ecx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530590 xorl %edx, %edx
591 wrmsr
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530592 /*
Shreesh Chhabbi87c7ec72020-12-03 14:07:15 -0800593 * Program MSR 0xC92 IA32_L3_MASK_2
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530594 * This MSR contain one bit per each way of LLC
595 * - If this bit is '0' - the way is protected from eviction
596 * - If this bit is '1' - the way is not protected from eviction
597 */
Subrata Banik1b12d782021-07-08 12:50:42 +0530598 mov %esi, %eax
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530599 movl $IA32_L3_MASK_2, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530600 xorl %edx, %edx
601 wrmsr
602 /*
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530603 * Set IA32_PQR_ASSOC
Subrata Banik03e971c2017-03-07 14:02:23 +0530604 *
605 * Possible values:
606 * 0: Default value, no way mask should be applied
607 * 1: Apply way mask 1 to LLC
608 * 2: Apply way mask 2 to LLC
609 * 3: Shouldn't be use in NEM Mode
610 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200611 movl $IA32_PQR_ASSOC, %ecx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530612 xorl %eax, %eax
Subrata Banik03e971c2017-03-07 14:02:23 +0530613 xorl %edx, %edx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530614#if CONFIG(COS_MAPPED_TO_MSB)
615 movl $0x02, %edx
616#else
617 movl $0x02, %eax
618#endif
Subrata Banik03e971c2017-03-07 14:02:23 +0530619 wrmsr
Arthur Heymans99a48bc2019-11-25 09:56:20 +0100620
621 clear_car
622
Subrata Banik03e971c2017-03-07 14:02:23 +0530623 /*
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530624 * Set IA32_PQR_ASSOC
Subrata Banik03e971c2017-03-07 14:02:23 +0530625 * At this stage we apply LLC_WAY_MASK_1 to the cache.
Subrata Banik03e971c2017-03-07 14:02:23 +0530626 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200627 movl $IA32_PQR_ASSOC, %ecx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530628 xorl %eax, %eax
Subrata Banik03e971c2017-03-07 14:02:23 +0530629 xorl %edx, %edx
Aamir Bohrac1d227d2020-07-16 09:03:06 +0530630#if CONFIG(COS_MAPPED_TO_MSB)
631 movl $0x01, %edx
632#else
633 movl $0x01, %eax
634#endif
Subrata Banik03e971c2017-03-07 14:02:23 +0530635 wrmsr
636
Martin Roth8c974502022-11-20 17:56:44 -0700637 post_code(POST_SOC_DISABLE_CACHE_EVICT)
Subrata Banik03e971c2017-03-07 14:02:23 +0530638 /*
639 * Enable No-Eviction Mode Run State by setting
640 * NO_EVICT_MODE MSR 2E0h bit [1] = '1'.
641 */
642
643 movl $MSR_EVICT_CTL, %ecx
644 rdmsr
645 orl $0x02, %eax
646 wrmsr
647
Subrata Banik03e971c2017-03-07 14:02:23 +0530648 jmp car_init_done
649#endif