blob: d5f5081c3c69228ab4461f1adaf986b9e7fedbe7 [file] [log] [blame]
Subrata Banik03e971c2017-03-07 14:02:23 +05301/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2015-2016 Intel Corp.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <commonlib/helpers.h>
18#include <cpu/x86/cache.h>
19#include <cpu/x86/cr.h>
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +020020#include <cpu/x86/msr.h>
Subrata Banik03e971c2017-03-07 14:02:23 +053021#include <cpu/x86/mtrr.h>
22#include <cpu/x86/post_code.h>
23#include <rules.h>
24#include <intelblocks/msr.h>
25
26.global bootblock_pre_c_entry
27bootblock_pre_c_entry:
28
29 post_code(0x20)
30
Arthur Heymansc4772b92019-04-14 18:38:35 +020031 movl $no_reset, %esp /* return address */
32 jmp check_mtrr /* Check if CPU properly reset */
Subrata Banik03e971c2017-03-07 14:02:23 +053033
34no_reset:
35 post_code(0x21)
36
37 /* Clear/disable fixed MTRRs */
38 mov $fixed_mtrr_list_size, %ebx
39 xor %eax, %eax
40 xor %edx, %edx
41
42clear_fixed_mtrr:
43 add $-2, %ebx
44 movzwl fixed_mtrr_list(%ebx), %ecx
45 wrmsr
46 jnz clear_fixed_mtrr
47
48 post_code(0x22)
49
50 /* Figure put how many MTRRs we have, and clear them out */
51 mov $MTRR_CAP_MSR, %ecx
52 rdmsr
53 movzb %al, %ebx /* Number of variable MTRRs */
54 mov $MTRR_PHYS_BASE(0), %ecx
55 xor %eax, %eax
56 xor %edx, %edx
57
58clear_var_mtrr:
59 wrmsr
60 inc %ecx
61 wrmsr
62 inc %ecx
63 dec %ebx
64 jnz clear_var_mtrr
65
66 post_code(0x23)
67
68 /* Configure default memory type to uncacheable (UC) */
69 mov $MTRR_DEF_TYPE_MSR, %ecx
70 rdmsr
71 /* Clear enable bits and set default type to UC. */
72 and $~(MTRR_DEF_TYPE_MASK | MTRR_DEF_TYPE_EN | \
73 MTRR_DEF_TYPE_FIX_EN), %eax
74 wrmsr
75
76 /* Configure MTRR_PHYS_MASK_HIGH for proper addressing above 4GB
77 * based on the physical address size supported for this processor
78 * This is based on read from CPUID EAX = 080000008h, EAX bits [7:0]
79 *
80 * Examples:
81 * MTRR_PHYS_MASK_HIGH = 00000000Fh For 36 bit addressing
82 * MTRR_PHYS_MASK_HIGH = 0000000FFh For 40 bit addressing
83 */
84
Elyes HAOUAS05498a22018-05-28 16:26:43 +020085 movl $0x80000008, %eax /* Address sizes leaf */
Subrata Banik03e971c2017-03-07 14:02:23 +053086 cpuid
87 sub $32, %al
88 movzx %al, %eax
89 xorl %esi, %esi
90 bts %eax, %esi
91 dec %esi /* esi <- MTRR_PHYS_MASK_HIGH */
92
93 post_code(0x24)
94
95#if ((CONFIG_DCACHE_RAM_SIZE & (CONFIG_DCACHE_RAM_SIZE - 1)) == 0)
96 /* Configure CAR region as write-back (WB) */
97 mov $MTRR_PHYS_BASE(0), %ecx
98 mov $CONFIG_DCACHE_RAM_BASE, %eax
99 or $MTRR_TYPE_WRBACK, %eax
100 xor %edx,%edx
101 wrmsr
102
103 /* Configure the MTRR mask for the size region */
104 mov $MTRR_PHYS_MASK(0), %ecx
105 mov $CONFIG_DCACHE_RAM_SIZE, %eax /* size mask */
106 dec %eax
107 not %eax
108 or $MTRR_PHYS_MASK_VALID, %eax
109 movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
110 wrmsr
111#elif (CONFIG_DCACHE_RAM_SIZE == 768 * KiB) /* 768 KiB */
112 /* Configure CAR region as write-back (WB) */
113 mov $MTRR_PHYS_BASE(0), %ecx
114 mov $CONFIG_DCACHE_RAM_BASE, %eax
115 or $MTRR_TYPE_WRBACK, %eax
116 xor %edx,%edx
117 wrmsr
118
119 mov $MTRR_PHYS_MASK(0), %ecx
120 mov $(512 * 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
127 mov $MTRR_PHYS_BASE(1), %ecx
128 mov $(CONFIG_DCACHE_RAM_BASE + 512 * KiB), %eax
129 or $MTRR_TYPE_WRBACK, %eax
130 xor %edx,%edx
131 wrmsr
132
133 mov $MTRR_PHYS_MASK(1), %ecx
134 mov $(256 * KiB), %eax /* size mask */
135 dec %eax
136 not %eax
137 or $MTRR_PHYS_MASK_VALID, %eax
138 movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
139 wrmsr
140#else
141#error "DCACHE_RAM_SIZE is not a power of 2 and setup code is missing"
142#endif
143 post_code(0x25)
144
145 /* Enable variable MTRRs */
146 mov $MTRR_DEF_TYPE_MSR, %ecx
147 rdmsr
148 or $MTRR_DEF_TYPE_EN, %eax
149 wrmsr
150
151 /* Enable caching */
152 mov %cr0, %eax
153 and $~(CR0_CD | CR0_NW), %eax
154 invd
155 mov %eax, %cr0
156
Julius Wernercd49cce2019-03-05 16:53:33 -0800157#if CONFIG(INTEL_CAR_NEM)
Subrata Banik03e971c2017-03-07 14:02:23 +0530158 jmp car_nem
Julius Wernercd49cce2019-03-05 16:53:33 -0800159#elif CONFIG(INTEL_CAR_CQOS)
Subrata Banik03e971c2017-03-07 14:02:23 +0530160 jmp car_cqos
Julius Wernercd49cce2019-03-05 16:53:33 -0800161#elif CONFIG(INTEL_CAR_NEM_ENHANCED)
Subrata Banik03e971c2017-03-07 14:02:23 +0530162 jmp car_nem_enhanced
163#else
164 jmp .halt_forever /* In case nothing has selected */
165#endif
166
167.global car_init_done
168car_init_done:
169
170 post_code(0x29)
171
172 /* Setup bootblock stack */
173 mov $_car_stack_end, %esp
174
Aaron Durbin028e18f2017-06-23 11:14:58 -0500175 /* Need to align stack to 16 bytes at call instruction. Account for
176 the two pushes below. */
177 andl $0xfffffff0, %esp
178 sub $8, %esp
179
Subrata Banik03e971c2017-03-07 14:02:23 +0530180 /*push TSC value to stack*/
181 movd %mm2, %eax
182 pushl %eax /* tsc[63:32] */
183 movd %mm1, %eax
Elyes HAOUAS05498a22018-05-28 16:26:43 +0200184 pushl %eax /* tsc[31:0] */
Subrata Banik03e971c2017-03-07 14:02:23 +0530185
186before_carstage:
187 post_code(0x2A)
188
189 call bootblock_c_entry
190 /* Never reached */
191
192.halt_forever:
193 post_code(POST_DEAD_CODE)
194 hlt
195 jmp .halt_forever
196
197fixed_mtrr_list:
198 .word MTRR_FIX_64K_00000
199 .word MTRR_FIX_16K_80000
200 .word MTRR_FIX_16K_A0000
201 .word MTRR_FIX_4K_C0000
202 .word MTRR_FIX_4K_C8000
203 .word MTRR_FIX_4K_D0000
204 .word MTRR_FIX_4K_D8000
205 .word MTRR_FIX_4K_E0000
206 .word MTRR_FIX_4K_E8000
207 .word MTRR_FIX_4K_F0000
208 .word MTRR_FIX_4K_F8000
209fixed_mtrr_list_size = . - fixed_mtrr_list
210
Julius Wernercd49cce2019-03-05 16:53:33 -0800211#if CONFIG(INTEL_CAR_NEM)
Subrata Banik03e971c2017-03-07 14:02:23 +0530212.global car_nem
213car_nem:
214 /* Disable cache eviction (setup stage) */
215 mov $MSR_EVICT_CTL, %ecx
216 rdmsr
217 or $0x1, %eax
218 wrmsr
219
220 post_code(0x26)
221
222 /* Clear the cache memory region. This will also fill up the cache */
223 movl $CONFIG_DCACHE_RAM_BASE, %edi
224 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
225 shr $0x02, %ecx
226 xor %eax, %eax
227 cld
228 rep stosl
229
230 post_code(0x27)
231
232 /* Disable cache eviction (run stage) */
233 mov $MSR_EVICT_CTL, %ecx
234 rdmsr
235 or $0x2, %eax
236 wrmsr
237
238 post_code(0x28)
239
240 jmp car_init_done
241
Julius Wernercd49cce2019-03-05 16:53:33 -0800242#elif CONFIG(INTEL_CAR_CQOS)
Subrata Banik03e971c2017-03-07 14:02:23 +0530243.global car_cqos
244car_cqos:
245 /*
Naresh G Solankif329f0c2017-09-27 14:21:18 +0530246 * Create CBM_LEN_MASK based on CBM_LEN
247 * Get CPUID.(EAX=10H, ECX=2H):EAX.CBM_LEN[bits 4:0]
248 */
249 mov $0x10, %eax
250 mov $0x2, %ecx
251 cpuid
252 and $0x1F, %eax
253 add $1, %al
254
255 mov $1, %ebx
256 mov %al, %cl
257 shl %cl, %ebx
258 sub $1, %ebx
259
260 /* Store the CBM_LEN_MASK in mm3 for later use. */
261 movd %ebx, %mm3
262
263 /*
Subrata Banik03e971c2017-03-07 14:02:23 +0530264 * Disable both L1 and L2 prefetcher. For yet-to-understood reason,
265 * prefetchers slow down filling cache with rep stos in CQOS mode.
266 */
267 mov $MSR_PREFETCH_CTL, %ecx
268 rdmsr
269 or $(PREFETCH_L1_DISABLE | PREFETCH_L2_DISABLE), %eax
270 wrmsr
271
272#if (CONFIG_DCACHE_RAM_SIZE == CONFIG_L2_CACHE_SIZE)
273/*
274 * If CAR size is set to full L2 size, mask is calculated as all-zeros.
275 * This is not supported by the CPU/uCode.
276 */
277#error "CQOS CAR may not use whole L2 cache area"
278#endif
279
280 /* Calculate how many bits to be used for CAR */
281 xor %edx, %edx
282 mov $CONFIG_DCACHE_RAM_SIZE, %eax /* dividend */
283 mov $CONFIG_CACHE_QOS_SIZE_PER_BIT, %ecx /* divisor */
284 div %ecx /* result is in eax */
285 mov %eax, %ecx /* save to ecx */
286 mov $1, %ebx
287 shl %cl, %ebx
288 sub $1, %ebx /* resulting mask is is in ebx */
289
290 /* Set this mask for initial cache fill */
291 mov $MSR_L2_QOS_MASK(0), %ecx
292 rdmsr
Naresh G Solankif329f0c2017-09-27 14:21:18 +0530293 mov %ebx, %eax
Subrata Banik03e971c2017-03-07 14:02:23 +0530294 wrmsr
295
296 /* Set CLOS selector to 0 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200297 mov $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530298 rdmsr
299 and $~IA32_PQR_ASSOC_MASK, %edx /* select mask 0 */
300 wrmsr
301
302 /* We will need to block CAR region from evicts */
303 mov $MSR_L2_QOS_MASK(1), %ecx
304 rdmsr
305 /* Invert bits that are to be used for cache */
Naresh G Solankif329f0c2017-09-27 14:21:18 +0530306 mov %ebx, %eax
307 xor $~0, %eax /* invert 32 bits */
308
309 /*
310 * Use CBM_LEN_MASK stored in mm3 to set bits based on Capacity Bit
311 * Mask Length.
312 */
313 movd %mm3, %ebx
314 and %ebx, %eax
Subrata Banik03e971c2017-03-07 14:02:23 +0530315 wrmsr
316
317 post_code(0x26)
318
319 /* Clear the cache memory region. This will also fill up the cache */
320 movl $CONFIG_DCACHE_RAM_BASE, %edi
321 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
322 shr $0x02, %ecx
323 xor %eax, %eax
324 cld
325 rep stosl
326
327 post_code(0x27)
328
329 /* Cache is populated. Use mask 1 that will block evicts */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200330 mov $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530331 rdmsr
332 and $~IA32_PQR_ASSOC_MASK, %edx /* clear index bits first */
333 or $1, %edx /* select mask 1 */
334 wrmsr
335
336 /* Enable prefetchers */
337 mov $MSR_PREFETCH_CTL, %ecx
338 rdmsr
339 and $~(PREFETCH_L1_DISABLE | PREFETCH_L2_DISABLE), %eax
340 wrmsr
341
342 post_code(0x28)
343
344 jmp car_init_done
345
Julius Wernercd49cce2019-03-05 16:53:33 -0800346#elif CONFIG(INTEL_CAR_NEM_ENHANCED)
Subrata Banik03e971c2017-03-07 14:02:23 +0530347.global car_nem_enhanced
348car_nem_enhanced:
349 /* Disable cache eviction (setup stage) */
350 mov $MSR_EVICT_CTL, %ecx
351 rdmsr
352 or $0x1, %eax
353 wrmsr
354 post_code(0x26)
355
356 /* Create n-way set associativity of cache */
357 xorl %edi, %edi
358find_llc_subleaf:
359 movl %edi, %ecx
360 movl $0x04, %eax
361 cpuid
362 inc %edi
363 and $0xe0, %al /* EAX[7:5] = Cache Level */
364 cmp $0x60, %al /* Check to see if it is LLC */
365 jnz find_llc_subleaf
366
367 /*
Subrata Banik8adaffc2019-08-10 21:43:12 +0530368 * Set MSR 0xC91 IA32_L3_MASK_1 = 0xE/0xFE/0xFFE/0xFFFE
Subrata Banik03e971c2017-03-07 14:02:23 +0530369 * for 4/8/16 way of LLC
370 */
371 shr $22, %ebx
372 inc %ebx
373 /* Calculate n-way associativity of LLC */
374 mov %bl, %cl
375
376 /*
377 * Maximizing RO cacheability while locking in the CAR to a
378 * single way since that particular way won't be victim candidate
379 * for evictions.
Jonathan Neuschäfer5268b762018-02-12 12:24:25 +0100380 * This has been done after programming LLC_WAY_MASK_1 MSR
Subrata Banik03e971c2017-03-07 14:02:23 +0530381 * with desired LLC way as mentioned below.
382 *
383 * Hence create Code and Data Size as per request
384 * Code Size (RO) : Up to 16M
385 * Data Size (RW) : Up to 256K
386 */
387 movl $0x01, %eax
388 /*
389 * LLC Ways -> LLC_WAY_MASK_1:
390 * 4: 0x000E
391 * 8: 0x00FE
392 * 12: 0x0FFE
393 * 16: 0xFFFE
394 *
395 * These MSRs contain one bit per each way of LLC
396 * - If this bit is '0' - the way is protected from eviction
397 * - If this bit is '1' - the way is not protected from eviction
398 */
399 shl %cl, %eax
400 subl $0x02, %eax
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200401 movl $IA32_L3_MASK_1, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530402 xorl %edx, %edx
403 wrmsr
404 /*
405 * Set MSR 0xC92 IA32_L3_MASK_2 = 0x1
406 *
407 * For SKL SOC, data size remains 256K consistently.
408 * Hence, creating 1-way associative cache for Data
409 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200410 mov $IA32_L3_MASK_2, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530411 mov $0x01, %eax
412 xorl %edx, %edx
413 wrmsr
414 /*
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200415 * Set IA32_PQR_ASSOC = 0x02
Subrata Banik03e971c2017-03-07 14:02:23 +0530416 *
417 * Possible values:
418 * 0: Default value, no way mask should be applied
419 * 1: Apply way mask 1 to LLC
420 * 2: Apply way mask 2 to LLC
421 * 3: Shouldn't be use in NEM Mode
422 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200423 movl $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530424 movl $0x02, %eax
425 xorl %edx, %edx
426 wrmsr
427
428 movl $CONFIG_DCACHE_RAM_BASE, %edi
429 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
430 shr $0x02, %ecx
431 xor %eax, %eax
432 cld
433 rep stosl
434 /*
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200435 * Set IA32_PQR_ASSOC = 0x01
Subrata Banik03e971c2017-03-07 14:02:23 +0530436 * At this stage we apply LLC_WAY_MASK_1 to the cache.
437 * i.e. way 0 is protected from eviction.
438 */
Elyes HAOUAS419bfbc2018-10-01 08:47:51 +0200439 movl $IA32_PQR_ASSOC, %ecx
Subrata Banik03e971c2017-03-07 14:02:23 +0530440 movl $0x01, %eax
441 xorl %edx, %edx
442 wrmsr
443
444 post_code(0x27)
445 /*
446 * Enable No-Eviction Mode Run State by setting
447 * NO_EVICT_MODE MSR 2E0h bit [1] = '1'.
448 */
449
450 movl $MSR_EVICT_CTL, %ecx
451 rdmsr
452 orl $0x02, %eax
453 wrmsr
454
455 post_code(0x28)
456
457 jmp car_init_done
458#endif