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> Reviewed-on: https://review.coreboot.org/13138 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth <martinroth@google.com>
This commit is contained in:
parent
dcc3ecc940
commit
fbdc719414
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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. */
|
||||
|
|
Loading…
Reference in New Issue