blob: 69ed17496844233a0a10c4a193d03f59bb87974c [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 /*
Subrata Banik8adaffc2019-08-10 21:43:12 +0530354 * Set MSR 0xC91 IA32_L3_MASK_1 = 0xE/0xFE/0xFFE/0xFFFE
Subrata Banik03e971c2017-03-07 14:02:23 +0530355 * for 4/8/16 way of LLC
356 */
357 shr $22, %ebx
358 inc %ebx
359 /* Calculate n-way associativity of LLC */
360 mov %bl, %cl
361
362 /*
363 * Maximizing RO cacheability while locking in the CAR to a
364 * single way since that particular way won't be victim candidate
365 * for evictions.
Jonathan Neuschäfer5268b762018-02-12 12:24:25 +0100366 * This has been done after programming LLC_WAY_MASK_1 MSR
Subrata Banik03e971c2017-03-07 14:02:23 +0530367 * with desired LLC way as mentioned below.
368 *
369 * Hence create Code and Data Size as per request
370 * Code Size (RO) : Up to 16M
371 * Data Size (RW) : Up to 256K
372 */
373 movl $0x01, %eax
374 /*
375 * LLC Ways -> LLC_WAY_MASK_1:
376 * 4: 0x000E
377 * 8: 0x00FE
378 * 12: 0x0FFE
379 * 16: 0xFFFE
380 *
381 * These MSRs contain one bit per each way of LLC
382 * - If this bit is '0' - the way is protected from eviction
383 * - If this bit is '1' - the way is not protected from eviction
384 */
385 shl %cl, %eax
386 subl $0x02, %eax
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200387 movl $IA32_L3_MASK_1, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530388 xorl %edx, %edx
389 wrmsr
390 /*
391 * Set MSR 0xC92 IA32_L3_MASK_2 = 0x1
392 *
393 * For SKL SOC, data size remains 256K consistently.
394 * Hence, creating 1-way associative cache for Data
395 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200396 mov $IA32_L3_MASK_2, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530397 mov $0x01, %eax
398 xorl %edx, %edx
399 wrmsr
400 /*
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200401 * Set IA32_PQR_ASSOC = 0x02
Subrata Banik03e971c2017-03-07 14:02:23 +0530402 *
403 * Possible values:
404 * 0: Default value, no way mask should be applied
405 * 1: Apply way mask 1 to LLC
406 * 2: Apply way mask 2 to LLC
407 * 3: Shouldn't be use in NEM Mode
408 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200409 movl $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530410 movl $0x02, %eax
411 xorl %edx, %edx
412 wrmsr
413
414 movl $CONFIG_DCACHE_RAM_BASE, %edi
415 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
416 shr $0x02, %ecx
417 xor %eax, %eax
418 cld
419 rep stosl
420 /*
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200421 * Set IA32_PQR_ASSOC = 0x01
Subrata Banik03e971c2017-03-07 14:02:23 +0530422 * At this stage we apply LLC_WAY_MASK_1 to the cache.
423 * i.e. way 0 is protected from eviction.
424 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200425 movl $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530426 movl $0x01, %eax
427 xorl %edx, %edx
428 wrmsr
429
430 post_code(0x27)
431 /*
432 * Enable No-Eviction Mode Run State by setting
433 * NO_EVICT_MODE MSR 2E0h bit [1] = '1'.
434 */
435
436 movl $MSR_EVICT_CTL, %ecx
437 rdmsr
438 orl $0x02, %eax
439 wrmsr
440
441 post_code(0x28)
442
443 jmp car_init_done
444#endif