Patrick Georgi (pgeorgi@google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13138
-gerrit
commit 60df61c98bc36ff38944fd34a01f3c8e52ace3ab Author: Subrata Banik subrata.banik@intel.com Date: Tue Jan 19 19:19:15 2016 +0530
intel/skylake: Implement native Cache-as-RAM (CAR)
Now coreboot should do BIOS CAR setup along with NEM mode setup.
This patch also provides a 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
[pg: updated to current upstream #defines]
BUG=chrome-os-partner:48412 BRANCH=glados TEST=Builds and Boots on FAB4 SKU2/3.
Signed-off-by: Subrata Banik subrata.banik@intel.com Signed-off-by: pchandri preetham.chandrian@intel.com Signed-off-by: Dhaval Sharma dhaval.v.sharma@intel.com
Change-Id: I96a9cf3a6e41cae9619c683dca28ad31dcaa2536 Signed-off-by: Patrick Georgi pgeorgi@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@intel.com Original-Tested-by: Subrata Banik subrata.banik@intel.com Original-Reviewed-by: Aaron Durbin adurbin@chromium.org --- src/drivers/intel/fsp1_1/Kconfig | 8 - src/drivers/intel/fsp1_1/after_raminit.S | 11 +- src/drivers/intel/fsp1_1/cache_as_ram.inc | 19 +- src/soc/intel/skylake/Kconfig | 10 + src/soc/intel/skylake/include/soc/car_setup.S | 334 +++++++++++++++++++++++ src/soc/intel/skylake/include/soc/car_teardown.S | 54 ++++ src/soc/intel/skylake/romstage/romstage.c | 8 + 7 files changed, 427 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..eb99157 100644 --- a/src/drivers/intel/fsp1_1/after_raminit.S +++ b/src/drivers/intel/fsp1_1/after_raminit.S @@ -20,7 +20,6 @@ #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 +30,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 +63,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..6e7e50b 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 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..4b881a1 --- /dev/null +++ b/src/soc/intel/skylake/include/soc/car_setup.S @@ -0,0 +1,334 @@ +/* + * 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 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 $MTRR_CAP_MSR, %ecx + rdmsr + movzx %al, %ebx + clr %eax + clr %edx + movl $MTRR_PHYS_BASE(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 $MTRR_DEF_TYPE_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 $MTRR_PHYS_BASE(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 $MTRR_DEF_TYPE_MSR, %ecx /* Load the MTRR default type index */ + rdmsr + orl $MTRR_DEF_TYPE_EN, %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 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_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 $MTRR_PHYS_BASE(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 $MTRR_PHYS_MASK(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 MTRR_DEF_TYPE_MSR + .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 + +.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..315b3c1 --- /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 $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/romstage.c b/src/soc/intel/skylake/romstage/romstage.c index b872d39..9b95f72 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,10 @@ 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. */