1 /* SPDX-License-Identifier: GPL-2.0 */
3 * This file was modified from the coreboot version.
5 * Copyright (C) 2015-2016 Intel Corp.
9 #include <asm/msr-index.h>
12 #include <asm/processor.h>
13 #include <asm/processor-flags.h>
17 #define IS_POWER_OF_2(x) (!((x) & ((x) - 1)))
21 post_code(POST_CAR_START)
24 * Use the MTRR default type MSR as a proxy for detecting INIT#.
25 * Reset the system if any known bits are set in that MSR. That is
26 * an indication of the CPU not being properly reset.
28 check_for_clean_reset:
29 mov $MTRR_DEF_TYPE_MSR, %ecx
31 and $(MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN), %eax
34 /* perform warm reset */
35 movw $IO_PORT_RESET, %dx
36 movb $(SYS_RST | RST_CPU), %al
40 post_code(POST_CAR_SIPI)
42 /* Clear/disable fixed MTRRs */
43 mov $fixed_mtrr_list_size, %ebx
49 movzwl fixed_mtrr_list(%ebx), %ecx
53 post_code(POST_CAR_MTRR)
55 /* Figure put how many MTRRs we have, and clear them out */
56 mov $MTRR_CAP_MSR, %ecx
58 movzb %al, %ebx /* Number of variable MTRRs */
59 mov $MTRR_PHYS_BASE_MSR(0), %ecx
71 post_code(POST_CAR_UNCACHEABLE)
73 /* Configure default memory type to uncacheable (UC) */
74 mov $MTRR_DEF_TYPE_MSR, %ecx
76 /* Clear enable bits and set default type to UC */
77 and $~(MTRR_DEF_TYPE_MASK | MTRR_DEF_TYPE_EN | \
78 MTRR_DEF_TYPE_FIX_EN), %eax
82 * Configure MTRR_PHYS_MASK_HIGH for proper addressing above 4GB
83 * based on the physical address size supported for this processor
84 * This is based on read from CPUID EAX = 080000008h, EAX bits [7:0]
87 * MTRR_PHYS_MASK_HIGH = 00000000Fh For 36 bit addressing
88 * MTRR_PHYS_MASK_HIGH = 0000000FFh For 40 bit addressing
91 movl $0x80000008, %eax /* Address sizes leaf */
97 dec %esi /* esi <- MTRR_PHYS_MASK_HIGH */
99 post_code(POST_CAR_BASE_ADDRESS)
101 #if IS_POWER_OF_2(CONFIG_DCACHE_RAM_SIZE)
102 /* Configure CAR region as write-back (WB) */
103 mov $MTRR_PHYS_BASE_MSR(0), %ecx
104 mov $CONFIG_DCACHE_RAM_BASE, %eax
105 or $MTRR_TYPE_WRBACK, %eax
109 /* Configure the MTRR mask for the size region */
110 mov $MTRR_PHYS_MASK(0), %ecx
111 mov $CONFIG_DCACHE_RAM_SIZE, %eax /* size mask */
114 or $MTRR_PHYS_MASK_VALID, %eax
115 movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
117 #elif (CONFIG_DCACHE_RAM_SIZE == 768 * KiB) /* 768 KiB */
118 /* Configure CAR region as write-back (WB) */
119 mov $MTRR_PHYS_BASE_MSR(0), %ecx
120 mov $CONFIG_DCACHE_RAM_BASE, %eax
121 or $MTRR_TYPE_WRBACK, %eax
125 mov $MTRR_PHYS_MASK_MSR(0), %ecx
126 mov $(512 * KiB), %eax /* size mask */
129 or $MTRR_PHYS_MASK_VALID, %eax
130 movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
133 mov $MTRR_PHYS_BASE_MSR(1), %ecx
134 mov $(CONFIG_DCACHE_RAM_BASE + 512 * KiB), %eax
135 or $MTRR_TYPE_WRBACK, %eax
139 mov $MTRR_PHYS_MASK_MSR(1), %ecx
140 mov $(256 * KiB), %eax /* size mask */
143 or $MTRR_PHYS_MASK_VALID, %eax
144 movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
147 #error "DCACHE_RAM_SIZE is not a power of 2 and setup code is missing"
149 post_code(POST_CAR_FILL)
151 /* Enable variable MTRRs */
152 mov $MTRR_DEF_TYPE_MSR, %ecx
154 or $MTRR_DEF_TYPE_EN, %eax
159 and $~(X86_CR0_CD | X86_CR0_NW), %eax
163 #if IS_ENABLED(CONFIG_INTEL_CAR_NEM)
165 #elif IS_ENABLED(CONFIG_INTEL_CAR_CQOS)
167 #elif IS_ENABLED(CONFIG_INTEL_CAR_NEM_ENHANCED)
170 #error "No CAR mechanism selected:
175 .word MTRR_FIX_64K_00000_MSR
176 .word MTRR_FIX_16K_80000_MSR
177 .word MTRR_FIX_16K_A0000_MSR
178 .word MTRR_FIX_4K_C0000_MSR
179 .word MTRR_FIX_4K_C8000_MSR
180 .word MTRR_FIX_4K_D0000_MSR
181 .word MTRR_FIX_4K_D8000_MSR
182 .word MTRR_FIX_4K_E0000_MSR
183 .word MTRR_FIX_4K_E8000_MSR
184 .word MTRR_FIX_4K_F0000_MSR
185 .word MTRR_FIX_4K_F8000_MSR
186 fixed_mtrr_list_size = . - fixed_mtrr_list
188 #if IS_ENABLED(CONFIG_INTEL_CAR_NEM)
191 /* Disable cache eviction (setup stage) */
192 mov $MSR_EVICT_CTL, %ecx
199 /* Clear the cache memory region. This will also fill up the cache */
200 movl $CONFIG_DCACHE_RAM_BASE, %edi
201 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
209 /* Disable cache eviction (run stage) */
210 mov $MSR_EVICT_CTL, %ecx
219 #elif IS_ENABLED(CONFIG_INTEL_CAR_CQOS)
223 * Create CBM_LEN_MASK based on CBM_LEN
224 * Get CPUID.(EAX=10H, ECX=2H):EAX.CBM_LEN[bits 4:0]
237 /* Store the CBM_LEN_MASK in mm3 for later use */
241 * Disable both L1 and L2 prefetcher. For yet-to-understood reason,
242 * prefetchers slow down filling cache with rep stos in CQOS mode.
244 mov $MSR_PREFETCH_CTL, %ecx
246 or $(PREFETCH_L1_DISABLE | PREFETCH_L2_DISABLE), %eax
249 #if (CONFIG_DCACHE_RAM_SIZE == CONFIG_L2_CACHE_SIZE)
251 * If CAR size is set to full L2 size, mask is calculated as all-zeros.
252 * This is not supported by the CPU/uCode.
254 #error "CQOS CAR may not use whole L2 cache area"
257 /* Calculate how many bits to be used for CAR */
259 mov $CONFIG_DCACHE_RAM_SIZE, %eax /* dividend */
260 mov $CONFIG_CACHE_QOS_SIZE_PER_BIT, %ecx /* divisor */
261 div %ecx /* result is in eax */
262 mov %eax, %ecx /* save to ecx */
265 sub $1, %ebx /* resulting mask is is in ebx */
267 /* Set this mask for initial cache fill */
268 mov $MSR_L2_QOS_MASK(0), %ecx
273 /* Set CLOS selector to 0 */
274 mov $MSR_IA32_PQR_ASSOC, %ecx
276 and $~MSR_IA32_PQR_ASSOC_MASK, %edx /* select mask 0 */
279 /* We will need to block CAR region from evicts */
280 mov $MSR_L2_QOS_MASK(1), %ecx
282 /* Invert bits that are to be used for cache */
284 xor $~0, %eax /* invert 32 bits */
287 * Use CBM_LEN_MASK stored in mm3 to set bits based on Capacity Bit
296 /* Clear the cache memory region. This will also fill up the cache */
297 movl $CONFIG_DCACHE_RAM_BASE, %edi
298 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
306 /* Cache is populated. Use mask 1 that will block evicts */
307 mov $MSR_IA32_PQR_ASSOC, %ecx
309 and $~MSR_IA32_PQR_ASSOC_MASK, %edx /* clear index bits first */
310 or $1, %edx /* select mask 1 */
313 /* Enable prefetchers */
314 mov $MSR_PREFETCH_CTL, %ecx
316 and $~(PREFETCH_L1_DISABLE | PREFETCH_L2_DISABLE), %eax
323 #elif IS_ENABLED(CONFIG_INTEL_CAR_NEM_ENHANCED)
324 .global car_nem_enhanced
326 /* Disable cache eviction (setup stage) */
327 mov $MSR_EVICT_CTL, %ecx
333 /* Create n-way set associativity of cache */
340 and $0xe0, %al /* EAX[7:5] = Cache Level */
341 cmp $0x60, %al /* Check to see if it is LLC */
345 * Set MSR 0xC91 IA32_L3_MASK_! = 0xE/0xFE/0xFFE/0xFFFE
346 * for 4/8/16 way of LLC
350 /* Calculate n-way associativity of LLC */
354 * Maximizing RO cacheability while locking in the CAR to a
355 * single way since that particular way won't be victim candidate
357 * This has been done after programing LLC_WAY_MASK_1 MSR
358 * with desired LLC way as mentioned below.
360 * Hence create Code and Data Size as per request
361 * Code Size (RO) : Up to 16M
362 * Data Size (RW) : Up to 256K
366 * LLC Ways -> LLC_WAY_MASK_1:
372 * These MSRs contain one bit per each way of LLC
373 * - If this bit is '0' - the way is protected from eviction
374 * - If this bit is '1' - the way is not protected from eviction
378 movl $MSR_IA32_L3_MASK_1, %ecx
382 * Set MSR 0xC92 IA32_L3_MASK_2 = 0x1
384 * For SKL SOC, data size remains 256K consistently.
385 * Hence, creating 1-way associative cache for Data
387 mov $MSR_IA32_L3_MASK_2, %ecx
392 * Set MSR_IA32_PQR_ASSOC = 0x02
395 * 0: Default value, no way mask should be applied
396 * 1: Apply way mask 1 to LLC
397 * 2: Apply way mask 2 to LLC
398 * 3: Shouldn't be use in NEM Mode
400 movl $MSR_IA32_PQR_ASSOC, %ecx
405 movl $CONFIG_DCACHE_RAM_BASE, %edi
406 movl $CONFIG_DCACHE_RAM_SIZE, %ecx
412 * Set MSR_IA32_PQR_ASSOC = 0x01
413 * At this stage we apply LLC_WAY_MASK_1 to the cache.
414 * i.e. way 0 is protected from eviction.
416 movl $MSR_IA32_PQR_ASSOC, %ecx
423 * Enable No-Eviction Mode Run State by setting
424 * NO_EVICT_MODE MSR 2E0h bit [1] = '1'.
427 movl $MSR_EVICT_CTL, %ecx
437 #if CONFIG_IS_ENABLED(X86_16BIT_INIT)
439 /* These next two fields are filled in by binman */
441 ucode_base: /* Declared in microcode.h */
442 .long 0 /* microcode base */
444 ucode_size: /* Declared in microcode.h */
445 .long 0 /* microcode size */
446 .long CONFIG_SYS_MONITOR_BASE /* code region base */
447 .long CONFIG_SYS_MONITOR_LEN /* code region size */