[coreboot-gerrit] New patch to review for coreboot: intel/skylake: coreboot Cache-as-RAM (CAR) implementation

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Fri Jan 22 22:26:04 CET 2016


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13138

-gerrit

commit dbe971d498fac3e555b6ced13c362983fef7843e
Author: Subrata Banik <subrata.banik at intel.com>
Date:   Tue Jan 19 19:19:15 2016 +0530

    intel/skylake: coreboot Cache-as-RAM (CAR) implementation
    
    Now coreboot should do BIOS CAR setup along with NEM
    mode setup.
    
    This patch also provides mechanism to use 16MB code caching
    benefit although LLC still limited to 1M/1.5M based
    on SOC LLC limit.
    Here with unlimited cache line gets replaced. Now we could use
    unlimited cache size along with well defined data size
    
    BUG=chrome-os-partner:48412
    BRANCH=glados
    TEST=Builds and Boots on FAB4 SKU2/3.
    
    Signed-off-by: Subrata Banik <subrata.banik at intel.com>
    Signed-off-by: pchandri <preetham.chandrian at intel.com>
    Signed-off-by: Dhaval Sharma <dhaval.v.sharma at intel.com>
    
    Change-Id: I96a9cf3a6e41cae9619c683dca28ad31dcaa2536
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
    Original-Commit-Id: 2ec51f15c874ad2f1f4fad52fa8deced7b27a24b
    Original-Change-Id: Id62c15799d98bc27b5e558adfa7c7b3468aa153a
    Original-Reviewed-on: https://chromium-review.googlesource.com/320855
    Original-Commit-Ready: Subrata Banik <subrata.banik at intel.com>
    Original-Tested-by: Subrata Banik <subrata.banik at intel.com>
    Original-Reviewed-by: Aaron Durbin <adurbin at chromium.org>
---
 src/drivers/intel/fsp1_1/Kconfig                 |   8 -
 src/drivers/intel/fsp1_1/after_raminit.S         |  12 +-
 src/drivers/intel/fsp1_1/cache_as_ram.inc        |  20 +-
 src/soc/intel/skylake/Kconfig                    |  10 +
 src/soc/intel/skylake/include/soc/car_setup.S    | 341 +++++++++++++++++++++++
 src/soc/intel/skylake/include/soc/car_teardown.S |  54 ++++
 src/soc/intel/skylake/romstage/romstage.c        |   9 +
 7 files changed, 437 insertions(+), 17 deletions(-)

diff --git a/src/drivers/intel/fsp1_1/Kconfig b/src/drivers/intel/fsp1_1/Kconfig
index c959e57..9b2c463 100644
--- a/src/drivers/intel/fsp1_1/Kconfig
+++ b/src/drivers/intel/fsp1_1/Kconfig
@@ -23,14 +23,6 @@ if PLATFORM_USES_FSP1_1
 
 comment "Intel FSP 1.1"
 
-config DCACHE_RAM_BASE
-	hex
-	default 0xfef00000
-
-config DCACHE_RAM_SIZE
-	hex
-	default 0x4000
-
 config HAVE_FSP_BIN
 	bool "Should the Intel FSP binary be added to the flash image"
 	help
diff --git a/src/drivers/intel/fsp1_1/after_raminit.S b/src/drivers/intel/fsp1_1/after_raminit.S
index 85a0a8c..6fd5ddd 100644
--- a/src/drivers/intel/fsp1_1/after_raminit.S
+++ b/src/drivers/intel/fsp1_1/after_raminit.S
@@ -20,7 +20,7 @@
 #include <cpu/x86/cache.h>
 #include <cpu/x86/post_code.h>
 
-.extern fih_car
+
 /*
  * This is the common entry point after DRAM has been initialized.
  */
@@ -31,6 +31,14 @@
 	/* Switch to the stack in RAM */
 	movl	%eax, %esp
 
+#if IS_ENABLED(CONFIG_SKIP_FSP_CAR)
+
+	/* SOC specific NEM */
+	#include <soc/car_teardown.S>
+
+#else
+.extern fih_car
+
 	post_code(POST_FSP_TEMP_RAM_EXIT)
 
 	/* Calculate TempRamExit entry into FSP */
@@ -56,8 +64,8 @@
 	 */
 	movb	$0xBC, %ah
 	jmp	.Lhlt
-
 1:
+#endif
 	/* Display the MTRRs */
 	call	soc_display_mtrrs
 
diff --git a/src/drivers/intel/fsp1_1/cache_as_ram.inc b/src/drivers/intel/fsp1_1/cache_as_ram.inc
index 35abdb4..e226cc5 100644
--- a/src/drivers/intel/fsp1_1/cache_as_ram.inc
+++ b/src/drivers/intel/fsp1_1/cache_as_ram.inc
@@ -33,17 +33,22 @@
 	 * mm0:  low 32-bits of TSC value
 	 * mm1:  high 32-bits of TSC value
 	 */
-
-	mov	%eax, %edi
-
+	movl	%eax, %edi
 cache_as_ram:
 	post_code(0x20)
 
+#if IS_ENABLED(CONFIG_SKIP_FSP_CAR)
+
 	/*
-	 * edi:  BIST value
-	 * mm0:  low 32-bits of TSC value
-	 * mm1:  high 32-bits of TSC value
+	 * SOC specific setup
+	 * NOTE: This has to preserve the registers
+	 * mm0, mm1 and edi.
 	 */
+	#include <soc/car_setup.S>
+
+	post_code(0x28)
+
+#endif
 
 	/*
 	 * Find the FSP binary in cbfs.
@@ -143,7 +148,7 @@ CAR_init_done:
 	rep	stosl
 
 before_romstage:
-	post_code(0x23)
+	post_code(0x2A)
 
 	/* Call cache_as_ram_main(struct cache_as_ram_params *) */
 	call	cache_as_ram_main
@@ -218,3 +223,4 @@ CAR_init_params:
 CAR_init_stack:
 	.long	CAR_init_done
 	.long	CAR_init_params
+
diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig
index 58b828f..35b2a18 100644
--- a/src/soc/intel/skylake/Kconfig
+++ b/src/soc/intel/skylake/Kconfig
@@ -176,4 +176,14 @@ config NHLT_SSM4567
 	help
 	  Include DSP firmware settings for ssm4567 smart amplifier.
 
+config DCACHE_RAM_SIZE_TOTAL
+	hex
+	default 0x40000
+
+config SKIP_FSP_CAR
+        bool "Skip cache as RAM setup in FSP"
+        default y
+        help
+          Skip Cache as RAM setup in FSP.
+
 endif
diff --git a/src/soc/intel/skylake/include/soc/car_setup.S b/src/soc/intel/skylake/include/soc/car_setup.S
new file mode 100644
index 0000000..c94d817
--- /dev/null
+++ b/src/soc/intel/skylake/include/soc/car_setup.S
@@ -0,0 +1,341 @@
+/*
+ * 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.
+ *
+ */
+
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/post_code.h>
+
+/*
+ * MTRR definitions
+ */
+.equ		IA32_MTRR_CAP,			0x00fe
+.equ		MTRR_PHYS_MASK_VALID,		0x0800
+
+.equ		NO_EVICT_MODE,			0x02e0
+
+.equ		IA32_PQR_ASSOC,			0x0c8f
+.equ		IA32_L3_MASK_1,			0x0c91
+.equ		IA32_L3_MASK_2,			0x0c92
+.equ		CACHE_INIT_VALUE,		0
+
+/*
+ * See BWG - chapter "Determining Cacheable Code Region Base Addresses and Ranges".
+ *
+ */
+
+	movl	%edi, %ebp		/* Put BIST value in a safe place */
+	/*
+	 * Ensure that all variable-range MTRR valid flags are clear and
+	 * IA32_MTRR_DEF_TYPE MSR E flag is clear.  Note: This is the default state
+	 * after hardware reset.
+	 *
+	 * Initialize all fixed-range and variable-range MTRR register fields to 0.
+	 */
+	mov	$(MtrrByteCountFixed), %ebx		/* EBX = size of  Fixed MTRRs */
+
+	xorl	%eax, %eax			/* Clear the low dword to write */
+	xorl	%edx, %edx			/* Clear the high dword to write */
+	xorl	%ecx, %ecx
+	/* Clearing Fixed Range MTRRs */
+clear_mtrr_fixed:
+	addl	$(-2), %ebx			/* need to check it */
+	movw	(MtrrInitTable)(%ebx), %cx	/* cx <- address of mtrr to zero */
+	wrmsr
+	jnz	clear_mtrr_fixed			/* loop through the whole table */
+
+	post_code(0x21)
+
+	/* Clearing Variable Range MTRRs */
+	movl	$MTRRcap_MSR, %ecx
+	rdmsr
+	movzx	%al, %ebx
+	clr	%eax
+	clr	%edx
+	movl	$MTRRphysBase_MSR(0), %ecx
+clear_var_mtrr:
+	wrmsr
+	inc	%ecx
+	wrmsr
+	inc	%ecx
+	dec	%ebx
+	jnz	clear_var_mtrr
+
+	post_code(0x22)
+
+	/*
+	 * Configure the default memory type to un-cacheable (UC) in the
+	 * IA32_MTRR_DEF_TYPE MSR.
+	 */
+
+	movl	$MTRRdefType_MSR, %ecx		/* Load the MTRR default type index */
+	rdmsr
+	andl	$0xFFFFF300, %eax		/* Clear the enable bits and def type UC. */
+	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 */
+
+	/*
+	 *   Configure the DataStack region as write-back (WB) cacheable memory type
+	 *   using the variable range MTRRs.
+	 *
+	 *
+	 * Set the base address of the DataStack cache range
+	 */
+
+	movl	$CONFIG_DCACHE_RAM_BASE, %eax
+	orl	$MTRR_TYPE_WRBACK, %eax	/* Load the write-back cache value */
+	xorl	%edx, %edx			/* clear upper dword */
+	movl	$MTRRphysBase_MSR(0), %ecx		/* Load the MTRR index */
+	wrmsr					/* the value in MTRR_PHYS_BASE_0 */
+
+	/*
+	 * Set the mask for the DataStack cache range
+	 * Compute MTRR mask value:  Mask = NOT (Size - 1)
+	 */
+	movl	$CONFIG_DCACHE_RAM_SIZE_TOTAL, %eax
+	dec	%eax
+	not	%eax
+	orl	$MTRR_PHYS_MASK_VALID, %eax	/* turn on the Valid flag */
+	movl	%esi, %edx			/* edx <- MTRR_PHYS_MASK_HIGH */
+	inc	%ecx
+	wrmsr					/* the value in MTRR_PHYS_MASK_0 */
+
+	post_code(0x23)
+
+	/*
+	 * Enable the MTRRs by setting the IA32_MTRR_DEF_TYPE MSR E flag.
+	 */
+	movl	$MTRRdefType_MSR, %ecx               /* Load the MTRR default type index */
+	rdmsr
+	orl	$MTRRdefTypeEn, %eax             /* Enable variable range MTRRs */
+	wrmsr
+
+	post_code(0x24)
+
+	/*
+	 *   Enable the logical processor's (BSP) cache: execute INVD and set
+	 *   CR0.CD = 0, CR0.NW = 0.
+	 */
+	movl	%cr0, %eax
+	and	$(~(CR0_CD + CR0_NW)), %eax
+	invd
+	movl	%eax, %cr0
+
+	/*
+	 *   Enable No-Eviction Mode Setup State by setting
+	 *   NO_EVICT_MODE  MSR 2E0h bit [0] = '1'.
+	 */
+	movl	$NO_EVICT_MODE, %ecx
+	rdmsr
+	orl	$0x01, %eax
+	wrmsr
+
+	/* 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 created 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
+	 *
+	 * +----------------+-------+----------------------------------+
+	 * | IA32_PQR_ASSOC | 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_TOTAL, %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
+
+	/*
+	 * Enable No-Eviction Mode Run State by setting
+	 * NO_EVICT_MODE MSR 2E0h bit [1] = '1'.
+	 */
+
+	movl	$NO_EVICT_MODE, %ecx
+	rdmsr
+	orl	$0x02, %eax
+	wrmsr
+
+	post_code(0x25)
+	/*
+	 *   Configure the BIOS code region as write-protected (WP) cacheable
+	 *   memory type using a single variable range MTRR.
+	 *
+	 *   Ensure region to cache meets MTRR requirements for
+	 *   size and alignment.
+	 */
+	movl	$(0xFFFFFFFF - CONFIG_ROM_SIZE + 1), %edi	/* Code region base */
+	movl	$CONFIG_ROM_SIZE, %eax				/* Code region size */
+	cmpl	$0, %edi
+	jz	InvalidParameter
+	cmpl	$0, %eax
+	jz	InvalidParameter
+	jmp	CheckPass
+
+InvalidParameter:
+	movl	$0x80000002, %eax	/* RETURN_INVALID_PARAMETER */
+	jmp	.Lhlt
+
+CheckPass:
+
+	post_code(0x26)
+
+	/*
+	 * Program base register
+	 */
+	xorl	%edx, %edx			/* clear upper dword */
+	movl	$MTRRphysBase_MSR(1), %ecx	/* setup variable mtrr */
+	movl	%edi, %eax
+	orl	$MTRR_TYPE_WRPROT, %eax	/* set type to write protect */
+	wrmsr
+
+	movl	$CONFIG_ROM_SIZE, %eax
+
+	/*
+	 * Compute MTRR mask value:  Mask = NOT (Size - 1)
+	 */
+	dec	%eax	/* eax - size to cache less one byte */
+	not	%eax	/* eax contains low 32 bits of mask */
+	or	$MTRR_PHYS_MASK_VALID, %eax
+	/*
+	 * Program mask register
+	 */
+	movl	$MTRRphysMask_MSR(1) , %ecx	/* setup variable mtrr */
+	movl	%esi, %edx	/* edx <- MTRR_PHYS_MASK_HIGH */
+	wrmsr
+
+	post_code(0x27)
+
+	/*
+	 * edi:  BIST value
+	 * mm0:  low 32-bits of TSC value
+	 * mm1:  high 32-bits of TSC value
+	 */
+	movl	%ebp, %edi		/* Restore BIST value */
+
+	.section	.rodata
+
+MtrrInitTable:
+	.word      MTRRdefType_MSR
+	.word      MTRRfix64K_00000_MSR
+	.word      MTRRfix16K_80000_MSR
+	.word      MTRRfix16K_A0000_MSR
+	.word      MTRRfix4K_C0000_MSR
+	.word      MTRRfix4K_C8000_MSR
+	.word      MTRRfix4K_D0000_MSR
+	.word      MTRRfix4K_D8000_MSR
+	.word      MTRRfix4K_E0000_MSR
+	.word      MTRRfix4K_E8000_MSR
+	.word      MTRRfix4K_F0000_MSR
+	.word      MTRRfix4K_F8000_MSR
+
+.equ MtrrByteCountFixed,  (.-MtrrInitTable)
+
+	.previous
diff --git a/src/soc/intel/skylake/include/soc/car_teardown.S b/src/soc/intel/skylake/include/soc/car_teardown.S
new file mode 100644
index 0000000..f520841
--- /dev/null
+++ b/src/soc/intel/skylake/include/soc/car_teardown.S
@@ -0,0 +1,54 @@
+/*
+ * 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	$MTRRdefType_MSR, %ecx
+	rdmsr
+	andl	$(~MTRRdefTypeEn), %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/romstage.c b/src/soc/intel/skylake/romstage/romstage.c
index b872d39..f99f05d 100644
--- a/src/soc/intel/skylake/romstage/romstage.c
+++ b/src/soc/intel/skylake/romstage/romstage.c
@@ -96,6 +96,10 @@ void soc_memory_init_params(struct romstage_params *params,
 		upd->SaGv = config->SaGv;
 	upd->RMT = config->Rmt;
 	upd->DdrFreqLimit = config->DdrFreqLimit;
+	if (IS_ENABLED(CONFIG_SKIP_FSP_CAR)) {
+		upd->FspCarBase = CONFIG_DCACHE_RAM_BASE;
+		upd->FspCarSize = CONFIG_DCACHE_RAM_SIZE_TOTAL;
+	}
 }
 
 void soc_display_memory_init_params(const MEMORY_INIT_UPD *old,
@@ -232,6 +236,11 @@ void soc_display_memory_init_params(const MEMORY_INIT_UPD *old,
 		new->ApertureSize);
 	fsp_display_upd_value("SaGv", 1, old->SaGv, new->SaGv);
 	fsp_display_upd_value("RMT", 1, old->RMT, new->RMT);
+	fsp_display_upd_value("FspCarBase", 1, old->FspCarBase,
+		new->FspCarBase);
+	fsp_display_upd_value("FspCarSize", 1, old->FspCarSize,
+		new->FspCarSize);
+
 }
 
 /* SOC initialization after RAM is enabled. */



More information about the coreboot-gerrit mailing list