[coreboot-gerrit] Change in coreboot[master]: soc/intel/common/block: Add cache as ram init and teardown code

Martin Roth (Code Review) gerrit at coreboot.org
Tue Mar 28 16:38:45 CEST 2017


Martin Roth has submitted this change and it was merged. ( https://review.coreboot.org/18381 )

Change subject: soc/intel/common/block: Add cache as ram init and teardown code
......................................................................


soc/intel/common/block: Add cache as ram init and teardown code

Create sample model for common car init and teardown programming.

TEST=Booted Reef, KCRD/EVE, GLKRVP with CAR_CQOS, CAR_NEM_ENHANCED
and CAR_NEM configs till post code 0x2a.

Change-Id: Iffd0c3e3ca81a3d283d5f1da115222a222e6b157
Signed-off-by: Subrata Banik <subrata.banik at intel.com>
Reviewed-on: https://review.coreboot.org/18381
Tested-by: build bot (Jenkins)
Reviewed-by: Martin Roth <martinroth at google.com>
---
M src/drivers/intel/fsp1_1/after_raminit.S
A src/soc/intel/common/block/cpu/Kconfig
A src/soc/intel/common/block/cpu/Makefile.inc
A src/soc/intel/common/block/cpu/car/cache_as_ram.S
A src/soc/intel/common/block/cpu/car/exit_car.S
M src/soc/intel/skylake/Kconfig
M src/soc/intel/skylake/Makefile.inc
D src/soc/intel/skylake/bootblock/cache_as_ram.S
D src/soc/intel/skylake/include/soc/car_teardown.S
M src/soc/intel/skylake/romstage/car_stage_fsp20.S
10 files changed, 601 insertions(+), 341 deletions(-)

Approvals:
  build bot (Jenkins): Verified
  Martin Roth: Looks good to me, approved



diff --git a/src/drivers/intel/fsp1_1/after_raminit.S b/src/drivers/intel/fsp1_1/after_raminit.S
index 3a4116a..cd56ea8 100644
--- a/src/drivers/intel/fsp1_1/after_raminit.S
+++ b/src/drivers/intel/fsp1_1/after_raminit.S
@@ -32,8 +32,8 @@
 
 #if IS_ENABLED(CONFIG_SKIP_FSP_CAR)
 
-	/* SOC specific NEM */
-	#include <soc/car_teardown.S>
+	/* chipset_teardown_car() is expected to disable cache-as-ram. */
+	call	chipset_teardown_car
 
 #else
 .extern fih_car
diff --git a/src/soc/intel/common/block/cpu/Kconfig b/src/soc/intel/common/block/cpu/Kconfig
new file mode 100644
index 0000000..7b78c53
--- /dev/null
+++ b/src/soc/intel/common/block/cpu/Kconfig
@@ -0,0 +1,32 @@
+config SOC_INTEL_COMMON_BLOCK_CAR
+	bool
+	default n
+	help
+	  This option allows you to select how cache-as-ram (CAR) is set up.
+
+config INTEL_CAR_NEM
+	bool
+	default n
+	help
+	  Traditionally, CAR is set up by using Non-Evict mode. This method
+	  does not allow CAR and cache to co-exist, because cache fills are
+	  blocked in NEM.
+
+config INTEL_CAR_CQOS
+	bool
+	default n
+	help
+	  Cache Quality of Service allows more fine-grained control of cache
+	  usage. As result, it is possible to set up a portion of L2 cache for
+	  CAR and use the remainder for actual caching.
+
+config INTEL_CAR_NEM_ENHANCED
+	bool
+	default n
+	help
+	  A current limitation of NEM (Non-Evict mode) is that code and data sizes
+	  are derived from the requirement to not write out any modified cache line.
+	  With NEM, if there is no physical memory behind the cached area,
+	  the modified data will be lost and NEM results will be inconsistent.
+	  ENHANCED NEM guarantees that modified data is always
+	  kept in cache while clean data is replaced.
diff --git a/src/soc/intel/common/block/cpu/Makefile.inc b/src/soc/intel/common/block/cpu/Makefile.inc
new file mode 100644
index 0000000..abdff2f
--- /dev/null
+++ b/src/soc/intel/common/block/cpu/Makefile.inc
@@ -0,0 +1,3 @@
+bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CAR) += car/cache_as_ram.S
+postcar-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CAR) += car/exit_car.S
+romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CAR) += car/exit_car.S
diff --git a/src/soc/intel/common/block/cpu/car/cache_as_ram.S b/src/soc/intel/common/block/cpu/car/cache_as_ram.S
new file mode 100644
index 0000000..79c5c77
--- /dev/null
+++ b/src/soc/intel/common/block/cpu/car/cache_as_ram.S
@@ -0,0 +1,440 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015-2016 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <commonlib/helpers.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/cr.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/post_code.h>
+#include <rules.h>
+#include <intelblocks/msr.h>
+
+.global bootblock_pre_c_entry
+bootblock_pre_c_entry:
+
+	post_code(0x20)
+
+	/*
+	 * Use the MTRR default type MSR as a proxy for detecting INIT#.
+	 * Reset the system if any known bits are set in that MSR. That is
+	 * an indication of the CPU not being properly reset.
+	 */
+check_for_clean_reset:
+	mov	$MTRR_DEF_TYPE_MSR, %ecx
+	rdmsr
+	and	$(MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN), %eax
+	cmp	$0, %eax
+	jz	no_reset
+	/* perform warm reset */
+	movw	$0xcf9, %dx
+	movb	$0x06, %al
+	outb	%al, %dx
+
+no_reset:
+	post_code(0x21)
+
+	/* Clear/disable fixed MTRRs */
+	mov	$fixed_mtrr_list_size, %ebx
+	xor	%eax, %eax
+	xor	%edx, %edx
+
+clear_fixed_mtrr:
+	add	$-2, %ebx
+	movzwl	fixed_mtrr_list(%ebx), %ecx
+	wrmsr
+	jnz	clear_fixed_mtrr
+
+	post_code(0x22)
+
+	/* Figure put how many MTRRs we have, and clear them out */
+	mov	$MTRR_CAP_MSR, %ecx
+	rdmsr
+	movzb	%al, %ebx		/* Number of variable MTRRs */
+	mov	$MTRR_PHYS_BASE(0), %ecx
+	xor	%eax, %eax
+	xor	%edx, %edx
+
+clear_var_mtrr:
+	wrmsr
+	inc	%ecx
+	wrmsr
+	inc	%ecx
+	dec	%ebx
+	jnz	clear_var_mtrr
+
+	post_code(0x23)
+
+	/* Configure default memory type to uncacheable (UC) */
+	mov	$MTRR_DEF_TYPE_MSR, %ecx
+	rdmsr
+	/* Clear enable bits and set default type to UC. */
+	and	$~(MTRR_DEF_TYPE_MASK | MTRR_DEF_TYPE_EN | \
+		 MTRR_DEF_TYPE_FIX_EN), %eax
+	wrmsr
+
+	/* Configure MTRR_PHYS_MASK_HIGH for proper addressing above 4GB
+	 * based on the physical address size supported for this processor
+	 * This is based on read from CPUID EAX = 080000008h, EAX bits [7:0]
+	 *
+	 * Examples:
+	 *  MTRR_PHYS_MASK_HIGH = 00000000Fh  For 36 bit addressing
+	 *  MTRR_PHYS_MASK_HIGH = 0000000FFh  For 40 bit addressing
+	 */
+
+	movl	$0x80000008, %eax 	/* Address sizes leaf */
+	cpuid
+	sub	$32, %al
+	movzx	%al, %eax
+	xorl	%esi, %esi
+	bts	%eax, %esi
+	dec	%esi			/* esi <- MTRR_PHYS_MASK_HIGH */
+
+	post_code(0x24)
+
+#if ((CONFIG_DCACHE_RAM_SIZE & (CONFIG_DCACHE_RAM_SIZE - 1)) == 0)
+	/* Configure CAR region as write-back (WB) */
+	mov	$MTRR_PHYS_BASE(0), %ecx
+	mov	$CONFIG_DCACHE_RAM_BASE, %eax
+	or	$MTRR_TYPE_WRBACK, %eax
+	xor	%edx,%edx
+	wrmsr
+
+	/* Configure the MTRR mask for the size region */
+	mov	$MTRR_PHYS_MASK(0), %ecx
+	mov	$CONFIG_DCACHE_RAM_SIZE, %eax	/* size mask */
+	dec	%eax
+	not	%eax
+	or	$MTRR_PHYS_MASK_VALID, %eax
+	movl	%esi, %edx	/* edx <- MTRR_PHYS_MASK_HIGH */
+	wrmsr
+#elif (CONFIG_DCACHE_RAM_SIZE == 768 * KiB) /* 768 KiB */
+	/* Configure CAR region as write-back (WB) */
+	mov	$MTRR_PHYS_BASE(0), %ecx
+	mov	$CONFIG_DCACHE_RAM_BASE, %eax
+	or	$MTRR_TYPE_WRBACK, %eax
+	xor	%edx,%edx
+	wrmsr
+
+	mov	$MTRR_PHYS_MASK(0), %ecx
+	mov	$(512 * KiB), %eax	/* size mask */
+	dec	%eax
+	not	%eax
+	or	$MTRR_PHYS_MASK_VALID, %eax
+	movl	%esi, %edx	/* edx <- MTRR_PHYS_MASK_HIGH */
+	wrmsr
+
+	mov	$MTRR_PHYS_BASE(1), %ecx
+	mov	$(CONFIG_DCACHE_RAM_BASE + 512 * KiB), %eax
+	or	$MTRR_TYPE_WRBACK, %eax
+	xor	%edx,%edx
+	wrmsr
+
+	mov	$MTRR_PHYS_MASK(1), %ecx
+	mov	$(256 * KiB), %eax	/* size mask */
+	dec	%eax
+	not	%eax
+	or	$MTRR_PHYS_MASK_VALID, %eax
+	movl	%esi, %edx	/* edx <- MTRR_PHYS_MASK_HIGH */
+	wrmsr
+#else
+#error "DCACHE_RAM_SIZE is not a power of 2 and setup code is missing"
+#endif
+	post_code(0x25)
+
+	/* Enable variable MTRRs */
+	mov	$MTRR_DEF_TYPE_MSR, %ecx
+	rdmsr
+	or	$MTRR_DEF_TYPE_EN, %eax
+	wrmsr
+
+	/* Enable caching */
+	mov	%cr0, %eax
+	and	$~(CR0_CD | CR0_NW), %eax
+	invd
+	mov	%eax, %cr0
+
+#if IS_ENABLED(CONFIG_INTEL_CAR_NEM)
+	jmp car_nem
+#elif IS_ENABLED(CONFIG_INTEL_CAR_CQOS)
+	jmp car_cqos
+#elif IS_ENABLED(CONFIG_INTEL_CAR_NEM_ENHANCED)
+	jmp car_nem_enhanced
+#else
+	jmp	.halt_forever /* In case nothing has selected */
+#endif
+
+.global car_init_done
+car_init_done:
+
+	post_code(0x29)
+
+	/* Setup bootblock stack */
+	mov	$_car_stack_end, %esp
+
+	/*push TSC value to stack*/
+	movd	%mm2, %eax
+	pushl	%eax	/* tsc[63:32] */
+	movd	%mm1, %eax
+	pushl	%eax 	/* tsc[31:0] */
+
+before_carstage:
+	post_code(0x2A)
+
+	call	bootblock_c_entry
+	/* Never reached */
+
+.halt_forever:
+	post_code(POST_DEAD_CODE)
+	hlt
+	jmp	.halt_forever
+
+fixed_mtrr_list:
+	.word	MTRR_FIX_64K_00000
+	.word	MTRR_FIX_16K_80000
+	.word	MTRR_FIX_16K_A0000
+	.word	MTRR_FIX_4K_C0000
+	.word	MTRR_FIX_4K_C8000
+	.word	MTRR_FIX_4K_D0000
+	.word	MTRR_FIX_4K_D8000
+	.word	MTRR_FIX_4K_E0000
+	.word	MTRR_FIX_4K_E8000
+	.word	MTRR_FIX_4K_F0000
+	.word	MTRR_FIX_4K_F8000
+fixed_mtrr_list_size = . - fixed_mtrr_list
+
+#if IS_ENABLED(CONFIG_INTEL_CAR_NEM)
+.global car_nem
+car_nem:
+	/* Disable cache eviction (setup stage) */
+	mov	$MSR_EVICT_CTL, %ecx
+	rdmsr
+	or	$0x1, %eax
+	wrmsr
+
+	post_code(0x26)
+
+	/* Clear the cache memory region. This will also fill up the cache */
+	movl	$CONFIG_DCACHE_RAM_BASE, %edi
+	movl	$CONFIG_DCACHE_RAM_SIZE, %ecx
+	shr	$0x02, %ecx
+	xor	%eax, %eax
+	cld
+	rep	stosl
+
+	post_code(0x27)
+
+	/* Disable cache eviction (run stage) */
+	mov	$MSR_EVICT_CTL, %ecx
+	rdmsr
+	or	$0x2, %eax
+	wrmsr
+
+	post_code(0x28)
+
+	jmp car_init_done
+
+#elif IS_ENABLED(CONFIG_INTEL_CAR_CQOS)
+.global car_cqos
+car_cqos:
+	/*
+	 * Disable both L1 and L2 prefetcher. For yet-to-understood reason,
+	 * prefetchers slow down filling cache with rep stos in CQOS mode.
+	 */
+	mov	$MSR_PREFETCH_CTL, %ecx
+	rdmsr
+	or	$(PREFETCH_L1_DISABLE | PREFETCH_L2_DISABLE), %eax
+	wrmsr
+
+#if (CONFIG_DCACHE_RAM_SIZE == CONFIG_L2_CACHE_SIZE)
+/*
+ * If CAR size is set to full L2 size, mask is calculated as all-zeros.
+ * This is not supported by the CPU/uCode.
+ */
+#error "CQOS CAR may not use whole L2 cache area"
+#endif
+
+	/* Calculate how many bits to be used for CAR */
+	xor	%edx, %edx
+	mov	$CONFIG_DCACHE_RAM_SIZE, %eax	/* dividend */
+	mov	$CONFIG_CACHE_QOS_SIZE_PER_BIT, %ecx	/* divisor */
+	div	%ecx		/* result is in eax */
+	mov	%eax, %ecx	/* save to ecx */
+	mov	$1, %ebx
+	shl	%cl, %ebx
+	sub	$1, %ebx	/* resulting mask is is in ebx */
+
+	/* Set this mask for initial cache fill */
+	mov	$MSR_L2_QOS_MASK(0), %ecx
+	rdmsr
+	mov	%bl, %al
+	wrmsr
+
+	/* Set CLOS selector to 0 */
+	mov	$MSR_IA32_PQR_ASSOC, %ecx
+	rdmsr
+	and	$~IA32_PQR_ASSOC_MASK, %edx	/* select mask 0 */
+	wrmsr
+
+	/* We will need to block CAR region from evicts */
+	mov	$MSR_L2_QOS_MASK(1), %ecx
+	rdmsr
+	/* Invert bits that are to be used for cache */
+	mov	%bl, %al
+	xor	$~0, %al			/* invert 8 bits */
+	wrmsr
+
+	post_code(0x26)
+
+	/* Clear the cache memory region. This will also fill up the cache */
+	movl	$CONFIG_DCACHE_RAM_BASE, %edi
+	movl	$CONFIG_DCACHE_RAM_SIZE, %ecx
+	shr	$0x02, %ecx
+	xor	%eax, %eax
+	cld
+	rep	stosl
+
+	post_code(0x27)
+
+	/* Cache is populated. Use mask 1 that will block evicts */
+	mov	$MSR_IA32_PQR_ASSOC, %ecx
+	rdmsr
+	and	$~IA32_PQR_ASSOC_MASK, %edx	/* clear index bits first */
+	or	$1, %edx			/* select mask 1 */
+	wrmsr
+
+	/* Enable prefetchers */
+	mov	$MSR_PREFETCH_CTL, %ecx
+	rdmsr
+	and	$~(PREFETCH_L1_DISABLE | PREFETCH_L2_DISABLE), %eax
+	wrmsr
+
+	post_code(0x28)
+
+	jmp car_init_done
+
+#elif IS_ENABLED(CONFIG_INTEL_CAR_NEM_ENHANCED)
+.global car_nem_enhanced
+car_nem_enhanced:
+	/* Disable cache eviction (setup stage) */
+	mov	$MSR_EVICT_CTL, %ecx
+	rdmsr
+	or	$0x1, %eax
+	wrmsr
+	post_code(0x26)
+
+	/* Create n-way set associativity of cache */
+	xorl	%edi, %edi
+find_llc_subleaf:
+	movl	%edi, %ecx
+	movl	$0x04, %eax
+	cpuid
+	inc	%edi
+	and	$0xe0, %al	/* EAX[7:5] = Cache Level */
+	cmp	$0x60, %al	/* Check to see if it is LLC */
+	jnz	find_llc_subleaf
+
+	/*
+	 * Set MSR 0xC91 IA32_L3_MASK_! = 0xE/0xFE/0xFFE/0xFFFE
+	 * for 4/8/16 way of LLC
+	*/
+	shr	$22, %ebx
+	inc	%ebx
+	/* Calculate n-way associativity of LLC */
+	mov	%bl, %cl
+
+	/*
+	 * Maximizing RO cacheability while locking in the CAR to a
+	 * single way since that particular way won't be victim candidate
+	 * for evictions.
+	 * This has been done after programing LLC_WAY_MASK_1 MSR
+	 * with desired LLC way as mentioned below.
+	 *
+	 * Hence create Code and Data Size as per request
+	 * Code Size (RO) : Up to 16M
+	 * Data Size (RW) : Up to 256K
+	 */
+	movl	$0x01, %eax
+	/*
+	 * LLC Ways -> LLC_WAY_MASK_1:
+	 *  4: 0x000E
+	 *  8: 0x00FE
+	 * 12: 0x0FFE
+	 * 16: 0xFFFE
+	 *
+	 * These MSRs contain one bit per each way of LLC
+	 * - If this bit is '0' - the way is protected from eviction
+	 * - If this bit is '1' - the way is not protected from eviction
+	 */
+	shl	%cl, %eax
+	subl	$0x02, %eax
+	movl	$MSR_IA32_L3_MASK_1, %ecx
+	xorl	%edx, %edx
+	wrmsr
+	/*
+	 * Set MSR 0xC92 IA32_L3_MASK_2 = 0x1
+	 *
+	 * For SKL SOC, data size remains 256K consistently.
+	 * Hence, creating 1-way associative cache for Data
+	*/
+	mov	$MSR_IA32_L3_MASK_2, %ecx
+	mov	$0x01, %eax
+	xorl	%edx, %edx
+	wrmsr
+	/*
+	 * Set MSR_IA32_PQR_ASSOC = 0x02
+	 *
+	 * Possible values:
+	 * 0: Default value, no way mask should be applied
+	 * 1: Apply way mask 1 to LLC
+	 * 2: Apply way mask 2 to LLC
+	 * 3: Shouldn't be use in NEM Mode
+	 */
+	movl	$MSR_IA32_PQR_ASSOC, %ecx
+	movl	$0x02, %eax
+	xorl	%edx, %edx
+	wrmsr
+
+	movl	$CONFIG_DCACHE_RAM_BASE, %edi
+	movl	$CONFIG_DCACHE_RAM_SIZE, %ecx
+	shr	$0x02, %ecx
+	xor	%eax, %eax
+	cld
+	rep	stosl
+	/*
+	 * Set MSR_IA32_PQR_ASSOC = 0x01
+	 * At this stage we apply LLC_WAY_MASK_1 to the cache.
+	 * i.e. way 0 is protected from eviction.
+	*/
+	movl	$MSR_IA32_PQR_ASSOC, %ecx
+	movl	$0x01, %eax
+	xorl	%edx, %edx
+	wrmsr
+
+	post_code(0x27)
+	/*
+	 * Enable No-Eviction Mode Run State by setting
+	 * NO_EVICT_MODE MSR 2E0h bit [1] = '1'.
+	 */
+
+	movl	$MSR_EVICT_CTL, %ecx
+	rdmsr
+	orl	$0x02, %eax
+	wrmsr
+
+	post_code(0x28)
+
+	jmp car_init_done
+#endif
diff --git a/src/soc/intel/common/block/cpu/car/exit_car.S b/src/soc/intel/common/block/cpu/car/exit_car.S
new file mode 100644
index 0000000..15e7f17
--- /dev/null
+++ b/src/soc/intel/common/block/cpu/car/exit_car.S
@@ -0,0 +1,96 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2017 Intel Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/cr.h>
+#include <intelblocks/msr.h>
+
+.text
+.global chipset_teardown_car
+chipset_teardown_car:
+
+	/*
+	 * Retrieve return address from stack as it will get trashed below if
+	 * execution is utilizing the cache-as-ram stack.
+	 */
+	pop	%ebx
+
+	/* Disable MTRRs. */
+	mov	$(MTRR_DEF_TYPE_MSR), %ecx
+	rdmsr
+	and	$(~(MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN)), %eax
+	wrmsr
+
+#if IS_ENABLED(CONFIG_INTEL_CAR_NEM)
+.global car_nem_teardown
+car_nem_teardown:
+
+	/* invalidate cache contents. */
+	invd
+
+	/* Knock down bit 1 then bit 0 of NEM control not combining steps. */
+	mov	$(MSR_EVICT_CTL), %ecx
+	rdmsr
+	and	$(~(1 << 1)), %eax
+	wrmsr
+	and	$(~(1 << 0)), %eax
+	wrmsr
+
+#elif IS_ENABLED(CONFIG_INTEL_CAR_CQOS)
+.global car_cqos_teardown
+car_cqos_teardown:
+
+	/* Go back to all-evicting mode, set both masks to all-1s */
+	mov	$MSR_L2_QOS_MASK(0), %ecx
+	rdmsr
+	mov	$~0, %al
+	wrmsr
+
+	mov	$MSR_L2_QOS_MASK(1), %ecx
+	rdmsr
+	mov	$~0, %al
+	wrmsr
+
+	/* Reset CLOS selector to 0 */
+	mov	$MSR_IA32_PQR_ASSOC, %ecx
+	rdmsr
+	and	$~IA32_PQR_ASSOC_MASK, %edx
+	wrmsr
+
+#elif IS_ENABLED(CONFIG_INTEL_CAR_NEM_ENHANCED)
+.global car_nem_enhanced_teardown
+car_nem_enhanced_teardown:
+
+	/* invalidate cache contents. */
+	invd
+
+	/* Knock down bit 1 then bit 0 of NEM control not combining steps. */
+	mov	$(MSR_EVICT_CTL), %ecx
+	rdmsr
+	and	$(~(1 << 1)), %eax
+	wrmsr
+	and	$(~(1 << 0)), %eax
+	wrmsr
+
+	/* Reset CLOS selector to 0 */
+	mov	$MSR_IA32_PQR_ASSOC, %ecx
+	rdmsr
+	and	$~IA32_PQR_ASSOC_MASK, %edx
+	wrmsr
+#endif
+
+	/* Return to caller. */
+	jmp	*%ebx
diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig
index a56d044..ebdcbe3 100644
--- a/src/soc/intel/skylake/Kconfig
+++ b/src/soc/intel/skylake/Kconfig
@@ -255,6 +255,32 @@
 	help
 	  Include DSP firmware settings for max98927 amplifier.
 
+choice
+	prompt "Cache-as-ram implementation"
+	default CAR_NEM_ENHANCED
+	help
+	  This option allows you to select how cache-as-ram (CAR) is set up.
+
+config CAR_NEM_ENHANCED
+	bool "Enhanced Non-evict mode"
+	select SOC_INTEL_COMMON_BLOCK_CAR
+	select INTEL_CAR_NEM_ENHANCED
+	help
+	  A current limitation of NEM (Non-Evict mode) is that code and data sizes
+	  are derived from the requirement to not write out any modified cache line.
+	  With NEM, if there is no physical memory behind the cached area,
+	  the modified data will be lost and NEM results will be inconsistent.
+	  ENHANCED NEM guarantees that modified data is always
+	  kept in cache while clean data is replaced.
+
+config USE_SKYLAKE_FSP_CAR
+	bool "Use FSP CAR"
+	select FSP_CAR
+	help
+	  Use FSP APIs to initialize & tear Down the Cache-As-Ram.
+
+endchoice
+
 config SKIP_FSP_CAR
 	bool "Skip cache as RAM setup in FSP"
 	default y
diff --git a/src/soc/intel/skylake/Makefile.inc b/src/soc/intel/skylake/Makefile.inc
index 1d5d89f..49f818d 100644
--- a/src/soc/intel/skylake/Makefile.inc
+++ b/src/soc/intel/skylake/Makefile.inc
@@ -10,7 +10,6 @@
 subdirs-y += ../../../cpu/x86/tsc
 
 bootblock-y += bootblock/bootblock.c
-bootblock-y += bootblock/cache_as_ram.S
 bootblock-y += bootblock/cpu.c
 bootblock-y += bootblock/i2c.c
 bootblock-y += bootblock/pch.c
diff --git a/src/soc/intel/skylake/bootblock/cache_as_ram.S b/src/soc/intel/skylake/bootblock/cache_as_ram.S
deleted file mode 100644
index 04abba6..0000000
--- a/src/soc/intel/skylake/bootblock/cache_as_ram.S
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2015-2016 Intel Corp.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <cpu/x86/cache.h>
-#include <cpu/x86/cr.h>
-#include <cpu/x86/mtrr.h>
-#include <cpu/x86/post_code.h>
-#include <rules.h>
-
-#define IA32_PQR_ASSOC 0x0c8f
-#define IA32_L3_MASK_1 0x0c91
-#define IA32_L3_MASK_2 0x0c92
-#define CACHE_INIT_VALUE 0
-#define MSR_EVICT_CTL 0x2e0
-
-.global bootblock_pre_c_entry
-bootblock_pre_c_entry:
-
-	post_code(0x20)
-
-	/*
-	 * Use the MTRR default type MSR as a proxy for detecting INIT#.
-	 * Reset the system if any known bits are set in that MSR. That is
-	 * an indication of the CPU not being properly reset.
-	 */
-check_for_clean_reset:
-	mov	$MTRR_DEF_TYPE_MSR, %ecx
-	rdmsr
-	and	$(MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN), %eax
-	cmp	$0, %eax
-	jz	no_reset
-	/* perform soft reset */
-	movw	$0xcf9, %dx
-	movb	$0x06, %al
-	outb	%al, %dx
-
-no_reset:
-	post_code(0x21)
-
-	/* Clear/disable fixed MTRRs */
-	mov	$fixed_mtrr_list_size, %ebx
-	xor	%eax, %eax
-	xor	%edx, %edx
-clear_fixed_mtrr:
-	add	$-2, %ebx
-	movzwl	fixed_mtrr_list(%ebx), %ecx
-	wrmsr
-	jnz	clear_fixed_mtrr
-
-	post_code(0x22)
-
-	/* Figure put how many MTRRs we have, and clear them out */
-	mov	$MTRR_CAP_MSR, %ecx
-	rdmsr
-	movzb	%al, %ebx		/* Number of variable MTRRs */
-	mov	$MTRR_PHYS_BASE(0), %ecx
-	xor	%eax, %eax
-	xor	%edx, %edx
-
-clear_var_mtrr:
-	wrmsr
-	inc	%ecx
-	wrmsr
-	inc	%ecx
-	dec	%ebx
-	jnz	clear_var_mtrr
-
-	post_code(0x23)
-
-	/* Configure default memory type to uncacheable (UC) */
-	mov	$MTRR_DEF_TYPE_MSR, %ecx
-	rdmsr
-	/* Clear enable bits and set default type to UC. */
-	and	$~(MTRR_DEF_TYPE_MASK | MTRR_DEF_TYPE_EN | \
-		 MTRR_DEF_TYPE_FIX_EN), %eax
-	wrmsr
-
-	/* Configure MTRR_PHYS_MASK_HIGH for proper addressing above 4GB
-	 * based on the physical address size supported for this processor
-	 * This is based on read from CPUID EAX = 080000008h, EAX bits [7:0]
-	 *
-	 * Examples:
-	 *  MTRR_PHYS_MASK_HIGH = 00000000Fh  For 36 bit addressing
-	 *  MTRR_PHYS_MASK_HIGH = 0000000FFh  For 40 bit addressing
-	 */
-
-	movl	$0x80000008, %eax 	/* Address sizes leaf */
-	cpuid
-	sub	$32, %al
-	movzx	%al, %eax
-	xorl	%esi, %esi
-	bts	%eax, %esi
-	dec	%esi			/* esi <- MTRR_PHYS_MASK_HIGH */
-
-	post_code(0x24)
-
-	/* Configure CAR region as write-back (WB) */
-	mov	$MTRR_PHYS_BASE(0), %ecx
-	mov	$CONFIG_DCACHE_RAM_BASE, %eax
-	or	$MTRR_TYPE_WRBACK, %eax
-	xor	%edx,%edx
-	wrmsr
-
-	/* Configure the MTRR mask for the size region */
-	mov	$MTRR_PHYS_MASK(0), %ecx
-	mov	$CONFIG_DCACHE_RAM_SIZE, %eax	/* size mask */
-	dec	%eax
-	not	%eax
-	or	$MTRR_PHYS_MASK_VALID, %eax
-	wrmsr
-
-	post_code(0x25)
-
-	/* Enable variable MTRRs */
-	mov	$MTRR_DEF_TYPE_MSR, %ecx
-	rdmsr
-	or	$MTRR_DEF_TYPE_EN, %eax
-	wrmsr
-
-	/* Enable caching */
-	mov	%cr0, %eax
-	and	$~(CR0_CD | CR0_NW), %eax
-	invd
-	mov	%eax, %cr0
-
-	/* Disable cache eviction (setup stage) */
-	mov	$MSR_EVICT_CTL, %ecx
-	rdmsr
-	or	$0x1, %eax
-	wrmsr
-	post_code(0x26)
-
-	/* Create n-way set associativity of cache */
-	xorl	%edi, %edi
-find_llc_subleaf:
-	movl	%edi, %ecx
-	movl	$0x04, %eax
-	cpuid
-	inc	%edi
-	and	$0xe0, %al	/* EAX[7:5] = Cache Level */
-	cmp	$0x60, %al	/* Check to see if it is LLC */
-	jnz	find_llc_subleaf
-
-	/*
-	 * Set MSR 0xC91 IA32_L3_MASK_! = 0xE/0xFE/0xFFE/0xFFFE
-	 * for 4/8/16 way of LLC
-	*/
-	shr	$22, %ebx
-	inc	%ebx
-	/* Calculate n-way associativity of LLC */
-	mov	%bl, %cl
-
-	/*
-	 * Maximizing RO cacheability while locking in the CAR to a
-	 * single way since that particular way won't be victim candidate
-	 * for evictions.
-	 * This has been done after programing LLC_WAY_MASK_1 MSR
-	 * with desired LLC way as mentioned below.
-	 *
-	 * Hence create Code and Data Size as per request
-	 * Code Size (RO) : Up to 16M
-	 * Data Size (RW) : Up to 256K
-	 */
-	movl	$0x01, %eax
-	/*
-	 * LLC Ways -> LLC_WAY_MASK_1:
-	 *  4: 0x000E
-	 *  8: 0x00FE
-	 * 12: 0x0FFE
-	 * 16: 0xFFFE
-	 *
-	 * These MSRs contain one bit per each way of LLC
-	 * - If this bit is '0' - the way is protected from eviction
-	 * - If this bit is '1' - the way is not protected from eviction
-	 */
-	shl	%cl, %eax
-	subl	$0x02, %eax
-	movl	$IA32_L3_MASK_1, %ecx
-	xorl	%edx, %edx
-	wrmsr
-	/*
-	 * Set MSR 0xC92 IA32_L3_MASK_2 = 0x1
-	 *
-	 * For SKL SOC, data size remains 256K consistently.
-	 * Hence, creating 1-way associative cache for Data
-	*/
-	mov	$IA32_L3_MASK_2, %ecx
-	mov	$0x01, %eax
-	xorl	%edx, %edx
-	wrmsr
-	/*
-	 * Set IA32_PQR_ASSOC = 0x02
-	 *
-	 * Possible values:
-	 * 0: Default value, no way mask should be applied
-	 * 1: Apply way mask 1 to LLC
-	 * 2: Apply way mask 2 to LLC
-	 * 3: Shouldn't be use in NEM Mode
-	 */
-	movl	$IA32_PQR_ASSOC, %ecx
-	movl	$0x02, %eax
-	xorl	%edx, %edx
-	wrmsr
-
-	movl	$CONFIG_DCACHE_RAM_BASE, %edi
-	movl	$CONFIG_DCACHE_RAM_SIZE, %ecx
-	shr	$0x02, %ecx
-	movl	$CACHE_INIT_VALUE, %eax
-	cld
-	rep	stosl
-	/*
-	 * Set IA32_PQR_ASSOC = 0x01
-	 * At this stage we apply LLC_WAY_MASK_1 to the cache.
-	 * i.e. way 0 is protected from eviction.
-	*/
-	movl	$IA32_PQR_ASSOC, %ecx
-	movl	$0x01, %eax
-	xorl	%edx, %edx
-	wrmsr
-
-	post_code(0x27)
-	/*
-	 * Enable No-Eviction Mode Run State by setting
-	 * NO_EVICT_MODE MSR 2E0h bit [1] = '1'.
-	 */
-
-	movl	$MSR_EVICT_CTL, %ecx
-	rdmsr
-	orl	$0x02, %eax
-	wrmsr
-
-car_init_done:
-
-	post_code(0x28)
-
-	/* Setup bootblock stack */
-	mov	$_car_stack_end, %esp
-
-	post_code(0x29)
-
-	/*push TSC value to stack*/
-	movd	%mm2, %eax
-	pushl	%eax	/* tsc[63:32] */
-	movd	%mm1, %eax
-	pushl	%eax 	/* tsc[31:0] */
-
-before_carstage:
-	post_code(0x2A)
-
-	call	bootblock_c_entry
-	/* Never reached */
-
-.halt_forever:
-	post_code(POST_DEAD_CODE)
-	hlt
-	jmp	.halt_forever
-
-fixed_mtrr_list:
-	.word	MTRR_FIX_64K_00000
-	.word	MTRR_FIX_16K_80000
-	.word	MTRR_FIX_16K_A0000
-	.word	MTRR_FIX_4K_C0000
-	.word	MTRR_FIX_4K_C8000
-	.word	MTRR_FIX_4K_D0000
-	.word	MTRR_FIX_4K_D8000
-	.word	MTRR_FIX_4K_E0000
-	.word	MTRR_FIX_4K_E8000
-	.word	MTRR_FIX_4K_F0000
-	.word	MTRR_FIX_4K_F8000
-fixed_mtrr_list_size = . - fixed_mtrr_list
diff --git a/src/soc/intel/skylake/include/soc/car_teardown.S b/src/soc/intel/skylake/include/soc/car_teardown.S
deleted file mode 100644
index 315b3c1..0000000
--- a/src/soc/intel/skylake/include/soc/car_teardown.S
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
- * Copyright (C) 2016 Intel Corp.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-.equ		IA32_PQR_ASSOC,			0x0c8f
-
-	/* Disable MTRR by clearing the IA32_MTRR_DEF_TYPE MSR E flag. */
-	movl	$MTRR_DEF_TYPE_MSR, %ecx
-	rdmsr
-	andl	$(~MTRR_DEF_TYPE_EN), %eax
-	wrmsr
-
-	/* Invalidate Cache */
-	invd
-
-	/*
-	 * Disable No-Eviction Mode Run State by clearing
-	 * NO_EVICT_MODE MSR 2E0h bit [1] = 0
-	 */
-	movl	$0x000002E0, %ecx
-	rdmsr
-	andl	$~(0x2), %eax
-	wrmsr
-
-	/*
-	 * Disable No-Eviction Mode Setup State by clearing
-	 * NO_EVICT_MODE MSR 2E0h bit [0] = 0
-	 */
-	rdmsr
-	andl	$~(0x1), %eax
-	wrmsr
-
-	/*
-	 * Set IA32_PQR_ASSOC = 0x00
-	 * This step guarantees that no protected way remain in LLC cache,
-	 * all the ways are open for the evictions.
-	 */
-	movl	$IA32_PQR_ASSOC, %ecx
-	movl	$0x00, %eax
-	xorl	%edx, %edx
-	wrmsr
diff --git a/src/soc/intel/skylake/romstage/car_stage_fsp20.S b/src/soc/intel/skylake/romstage/car_stage_fsp20.S
index c6401fa..5ef8bd6 100644
--- a/src/soc/intel/skylake/romstage/car_stage_fsp20.S
+++ b/src/soc/intel/skylake/romstage/car_stage_fsp20.S
@@ -37,7 +37,8 @@
 	/* Switch to the stack in RAM */
 	movl	%eax, %esp
 
-	#include <soc/car_teardown.S>
+	/* chipset_teardown_car() is expected to disable cache-as-ram. */
+	call	chipset_teardown_car
 
 	/* Display the MTRRs */
 	call	soc_display_mtrrs

-- 
To view, visit https://review.coreboot.org/18381
To unsubscribe, visit https://review.coreboot.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Iffd0c3e3ca81a3d283d5f1da115222a222e6b157
Gerrit-PatchSet: 40
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Owner: Aamir Bohra <aamir.bohra at intel.com>
Gerrit-Reviewer: Aaron Durbin <adurbin at chromium.org>
Gerrit-Reviewer: Balaji Manigandan <balaji.manigandan at intel.com>
Gerrit-Reviewer: Barnali Sarkar <barnali.sarkar at intel.com>
Gerrit-Reviewer: Hannah Williams <hannah.williams at intel.com>
Gerrit-Reviewer: Martin Roth <martinroth at google.com>
Gerrit-Reviewer: Paul Menzel <paulepanter at users.sourceforge.net>
Gerrit-Reviewer: Rizwan Qureshi <rizwan.qureshi at intel.com>
Gerrit-Reviewer: Subrata Banik <subrata.banik at intel.com>
Gerrit-Reviewer: build bot (Jenkins)
Gerrit-Reviewer: dhaval v sharma <dhaval.v.sharma at intel.com>



More information about the coreboot-gerrit mailing list