blob: 8b35e5227cae509f6e167b47d08fef186f65fdec [file] [log] [blame]
Angel Pons0612b272020-04-05 15:46:56 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Subrata Banik03e971c2017-03-07 14:02:23 +05303
4#include <commonlib/helpers.h>
5#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>
10#include <rules.h>
11#include <intelblocks/msr.h>
12
13.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
165 sub $8, %esp
166
Subrata Banik5885ffe2019-11-14 11:08:51 +0530167 /* push TSC value to stack */
Subrata Banik03e971c2017-03-07 14:02:23 +0530168 movd %mm2, %eax
169 pushl %eax /* tsc[63:32] */
170 movd %mm1, %eax
Elyes HAOUAS05498a22018-05-28 16:26:43 +0200171 pushl %eax /* tsc[31:0] */
Subrata Banik03e971c2017-03-07 14:02:23 +0530172
173before_carstage:
174 post_code(0x2A)
175
176 call bootblock_c_entry
177 /* Never reached */
178
179.halt_forever:
180 post_code(POST_DEAD_CODE)
181 hlt
182 jmp .halt_forever
183
184fixed_mtrr_list:
185 .word MTRR_FIX_64K_00000
186 .word MTRR_FIX_16K_80000
187 .word MTRR_FIX_16K_A0000
188 .word MTRR_FIX_4K_C0000
189 .word MTRR_FIX_4K_C8000
190 .word MTRR_FIX_4K_D0000
191 .word MTRR_FIX_4K_D8000
192 .word MTRR_FIX_4K_E0000
193 .word MTRR_FIX_4K_E8000
194 .word MTRR_FIX_4K_F0000
195 .word MTRR_FIX_4K_F8000
196fixed_mtrr_list_size = . - fixed_mtrr_list
197
Julius Wernercd49cce2019-03-05 16:53:33 -0800198#if CONFIG(INTEL_CAR_NEM)
Subrata Banik03e971c2017-03-07 14:02:23 +0530199.global car_nem
200car_nem:
201 /* Disable cache eviction (setup stage) */
202 mov $MSR_EVICT_CTL, %ecx
203 rdmsr
204 or $0x1, %eax
205 wrmsr
206
207 post_code(0x26)
208
209 /* Clear the cache memory region. This will also fill up the cache */
210 movl $CONFIG_DCACHE_RAM_BASE, %edi
211 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
212 shr $0x02, %ecx
213 xor %eax, %eax
214 cld
215 rep stosl
216
217 post_code(0x27)
218
219 /* Disable cache eviction (run stage) */
220 mov $MSR_EVICT_CTL, %ecx
221 rdmsr
222 or $0x2, %eax
223 wrmsr
224
225 post_code(0x28)
226
227 jmp car_init_done
228
Julius Wernercd49cce2019-03-05 16:53:33 -0800229#elif CONFIG(INTEL_CAR_CQOS)
Subrata Banik03e971c2017-03-07 14:02:23 +0530230.global car_cqos
231car_cqos:
232 /*
Naresh G Solankif329f0c2017-09-27 14:21:18 +0530233 * Create CBM_LEN_MASK based on CBM_LEN
234 * Get CPUID.(EAX=10H, ECX=2H):EAX.CBM_LEN[bits 4:0]
235 */
236 mov $0x10, %eax
237 mov $0x2, %ecx
238 cpuid
239 and $0x1F, %eax
240 add $1, %al
241
242 mov $1, %ebx
243 mov %al, %cl
244 shl %cl, %ebx
245 sub $1, %ebx
246
247 /* Store the CBM_LEN_MASK in mm3 for later use. */
248 movd %ebx, %mm3
249
250 /*
Subrata Banik03e971c2017-03-07 14:02:23 +0530251 * Disable both L1 and L2 prefetcher. For yet-to-understood reason,
252 * prefetchers slow down filling cache with rep stos in CQOS mode.
253 */
254 mov $MSR_PREFETCH_CTL, %ecx
255 rdmsr
256 or $(PREFETCH_L1_DISABLE | PREFETCH_L2_DISABLE), %eax
257 wrmsr
258
259#if (CONFIG_DCACHE_RAM_SIZE == CONFIG_L2_CACHE_SIZE)
260/*
261 * If CAR size is set to full L2 size, mask is calculated as all-zeros.
262 * This is not supported by the CPU/uCode.
263 */
264#error "CQOS CAR may not use whole L2 cache area"
265#endif
266
267 /* Calculate how many bits to be used for CAR */
268 xor %edx, %edx
269 mov $CONFIG_DCACHE_RAM_SIZE, %eax /* dividend */
270 mov $CONFIG_CACHE_QOS_SIZE_PER_BIT, %ecx /* divisor */
271 div %ecx /* result is in eax */
272 mov %eax, %ecx /* save to ecx */
273 mov $1, %ebx
274 shl %cl, %ebx
275 sub $1, %ebx /* resulting mask is is in ebx */
276
277 /* Set this mask for initial cache fill */
278 mov $MSR_L2_QOS_MASK(0), %ecx
279 rdmsr
Naresh G Solankif329f0c2017-09-27 14:21:18 +0530280 mov %ebx, %eax
Subrata Banik03e971c2017-03-07 14:02:23 +0530281 wrmsr
282
283 /* Set CLOS selector to 0 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200284 mov $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530285 rdmsr
286 and $~IA32_PQR_ASSOC_MASK, %edx /* select mask 0 */
287 wrmsr
288
289 /* We will need to block CAR region from evicts */
290 mov $MSR_L2_QOS_MASK(1), %ecx
291 rdmsr
292 /* Invert bits that are to be used for cache */
Naresh G Solankif329f0c2017-09-27 14:21:18 +0530293 mov %ebx, %eax
294 xor $~0, %eax /* invert 32 bits */
295
296 /*
297 * Use CBM_LEN_MASK stored in mm3 to set bits based on Capacity Bit
298 * Mask Length.
299 */
300 movd %mm3, %ebx
301 and %ebx, %eax
Subrata Banik03e971c2017-03-07 14:02:23 +0530302 wrmsr
303
304 post_code(0x26)
305
306 /* Clear the cache memory region. This will also fill up the cache */
307 movl $CONFIG_DCACHE_RAM_BASE, %edi
308 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
309 shr $0x02, %ecx
310 xor %eax, %eax
311 cld
312 rep stosl
313
314 post_code(0x27)
315
316 /* Cache is populated. Use mask 1 that will block evicts */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200317 mov $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530318 rdmsr
319 and $~IA32_PQR_ASSOC_MASK, %edx /* clear index bits first */
320 or $1, %edx /* select mask 1 */
321 wrmsr
322
323 /* Enable prefetchers */
324 mov $MSR_PREFETCH_CTL, %ecx
325 rdmsr
326 and $~(PREFETCH_L1_DISABLE | PREFETCH_L2_DISABLE), %eax
327 wrmsr
328
329 post_code(0x28)
330
331 jmp car_init_done
332
Julius Wernercd49cce2019-03-05 16:53:33 -0800333#elif CONFIG(INTEL_CAR_NEM_ENHANCED)
Subrata Banik03e971c2017-03-07 14:02:23 +0530334.global car_nem_enhanced
335car_nem_enhanced:
336 /* Disable cache eviction (setup stage) */
337 mov $MSR_EVICT_CTL, %ecx
338 rdmsr
339 or $0x1, %eax
340 wrmsr
341 post_code(0x26)
342
343 /* Create n-way set associativity of cache */
344 xorl %edi, %edi
345find_llc_subleaf:
346 movl %edi, %ecx
347 movl $0x04, %eax
348 cpuid
349 inc %edi
350 and $0xe0, %al /* EAX[7:5] = Cache Level */
351 cmp $0x60, %al /* Check to see if it is LLC */
352 jnz find_llc_subleaf
353
354 /*
Subrata Banik8adaffc2019-08-10 21:43:12 +0530355 * Set MSR 0xC91 IA32_L3_MASK_1 = 0xE/0xFE/0xFFE/0xFFFE
Subrata Banik03e971c2017-03-07 14:02:23 +0530356 * for 4/8/16 way of LLC
357 */
358 shr $22, %ebx
359 inc %ebx
360 /* Calculate n-way associativity of LLC */
361 mov %bl, %cl
362
363 /*
364 * Maximizing RO cacheability while locking in the CAR to a
365 * single way since that particular way won't be victim candidate
366 * for evictions.
Jonathan Neuschäfer5268b762018-02-12 12:24:25 +0100367 * This has been done after programming LLC_WAY_MASK_1 MSR
Subrata Banik03e971c2017-03-07 14:02:23 +0530368 * with desired LLC way as mentioned below.
369 *
370 * Hence create Code and Data Size as per request
371 * Code Size (RO) : Up to 16M
372 * Data Size (RW) : Up to 256K
373 */
374 movl $0x01, %eax
375 /*
376 * LLC Ways -> LLC_WAY_MASK_1:
377 * 4: 0x000E
378 * 8: 0x00FE
379 * 12: 0x0FFE
380 * 16: 0xFFFE
381 *
382 * These MSRs contain one bit per each way of LLC
383 * - If this bit is '0' - the way is protected from eviction
384 * - If this bit is '1' - the way is not protected from eviction
385 */
386 shl %cl, %eax
387 subl $0x02, %eax
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200388 movl $IA32_L3_MASK_1, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530389 xorl %edx, %edx
390 wrmsr
391 /*
392 * Set MSR 0xC92 IA32_L3_MASK_2 = 0x1
393 *
394 * For SKL SOC, data size remains 256K consistently.
395 * Hence, creating 1-way associative cache for Data
396 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200397 mov $IA32_L3_MASK_2, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530398 mov $0x01, %eax
399 xorl %edx, %edx
400 wrmsr
401 /*
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200402 * Set IA32_PQR_ASSOC = 0x02
Subrata Banik03e971c2017-03-07 14:02:23 +0530403 *
404 * Possible values:
405 * 0: Default value, no way mask should be applied
406 * 1: Apply way mask 1 to LLC
407 * 2: Apply way mask 2 to LLC
408 * 3: Shouldn't be use in NEM Mode
409 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200410 movl $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530411 movl $0x02, %eax
412 xorl %edx, %edx
413 wrmsr
414
415 movl $CONFIG_DCACHE_RAM_BASE, %edi
416 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
417 shr $0x02, %ecx
418 xor %eax, %eax
419 cld
420 rep stosl
421 /*
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200422 * Set IA32_PQR_ASSOC = 0x01
Subrata Banik03e971c2017-03-07 14:02:23 +0530423 * At this stage we apply LLC_WAY_MASK_1 to the cache.
424 * i.e. way 0 is protected from eviction.
425 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200426 movl $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530427 movl $0x01, %eax
428 xorl %edx, %edx
429 wrmsr
430
431 post_code(0x27)
432 /*
433 * Enable No-Eviction Mode Run State by setting
434 * NO_EVICT_MODE MSR 2E0h bit [1] = '1'.
435 */
436
437 movl $MSR_EVICT_CTL, %ecx
438 rdmsr
439 orl $0x02, %eax
440 wrmsr
441
442 post_code(0x28)
443
444 jmp car_init_done
445#endif