Subrata Banik (subrata.banik@intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/18381
-gerrit
commit 284fe908e789400004a91643f4c1e9b1b6e393a2 Author: Subrata Banik subrata.banik@intel.com Date: Wed Feb 22 16:39:53 2017 +0530
soc/intel/common/block: Add cache as ram common code
Create sample model for common cache as ram programming.
TEST=Booted till post code 0x2a and ensure to have CAR done by reading MSR.
Change-Id: Iffd0c3e3ca81a3d283d5f1da115222a222e6b157 Signed-off-by: Subrata Banik subrata.banik@intel.com --- src/soc/intel/apollolake/Kconfig | 22 +- src/soc/intel/apollolake/Makefile.inc | 7 +- src/soc/intel/apollolake/bootblock/cache_as_ram.S | 251 ---------------- src/soc/intel/apollolake/include/soc/cpu.h | 7 - src/soc/intel/common/block/cpu/Kconfig | 61 ++++ src/soc/intel/common/block/cpu/Makefile.inc | 2 + src/soc/intel/common/block/cpu/car/cache_as_ram.S | 177 ++++++++++++ src/soc/intel/common/block/cpu/car/car_big_core.S | 161 +++++++++++ .../intel/common/block/cpu/car/car_small_core.S | 103 +++++++ src/soc/intel/glk/Kconfig | 1 + src/soc/intel/skylake/Kconfig | 1 + src/soc/intel/skylake/Makefile.inc | 1 - src/soc/intel/skylake/bootblock/cache_as_ram.S | 320 --------------------- 13 files changed, 508 insertions(+), 606 deletions(-)
diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig index 7cd00e0..4ff64d2 100644 --- a/src/soc/intel/apollolake/Kconfig +++ b/src/soc/intel/apollolake/Kconfig @@ -47,6 +47,7 @@ config CPU_SPECIFIC_OPTIONS select RELOCATABLE_RAMSTAGE # Build fails if this is not selected select RTC select SMM_TSEG + select SOC_INTEL_CAR_SMALL_CORE select SOC_INTEL_COMMON select SOC_INTEL_COMMON_ACPI select SOC_INTEL_COMMON_BLOCK @@ -252,27 +253,6 @@ config NHLT_DA7219 default n help Include DSP firmware settings for headset codec. -choice - prompt "Cache-as-ram implementation" - default CAR_CQOS - help - This option allows you to select how cache-as-ram (CAR) is set up. - -config CAR_NEM - bool "Non-evict mode" - 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 - block in NEM mode. - -config CAR_CQOS - bool "Cache Quality of Service" - help - Cache Quality of Service allows more fine-grained control of cache - usage. As result, it is possible to set up portion of L2 cache for - CAR and use remainder for actual caching. - -endchoice
config SPI_FLASH_INCLUDE_ALL_DRIVERS bool diff --git a/src/soc/intel/apollolake/Makefile.inc b/src/soc/intel/apollolake/Makefile.inc index 5e1cf73..eb6f832 100644 --- a/src/soc/intel/apollolake/Makefile.inc +++ b/src/soc/intel/apollolake/Makefile.inc @@ -21,12 +21,7 @@ bootblock-y += pmutil.c bootblock-y += spi.c bootblock-y += tsc_freq.c bootblock-$(CONFIG_SOC_UART_DEBUG) += uart_early.c - -ifeq ($(CONFIG_FSP_CAR),y) -bootblock-y += bootblock/cache_as_ram_fsp.S -else -bootblock-y += bootblock/cache_as_ram.S -endif +bootblock-$(CONFIG_FSP_CAR) += bootblock/cache_as_ram_fsp.S
romstage-y += car.c romstage-$(CONFIG_PLATFORM_USES_FSP2_0) += romstage.c diff --git a/src/soc/intel/apollolake/bootblock/cache_as_ram.S b/src/soc/intel/apollolake/bootblock/cache_as_ram.S deleted file mode 100644 index 65dd4c8..0000000 --- a/src/soc/intel/apollolake/bootblock/cache_as_ram.S +++ /dev/null @@ -1,251 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2015-2016 Intel Corp. - * (Written by Andrey Petrov andrey.petrov@intel.com for Intel Corp.) - * (Written by Alexandru Gagniuc alexandrux.gagniuc@intel.com for 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; either version 2 of the License, or - * (at your option) any later version. - * - * 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 <device/pci_def.h> -#include <commonlib/helpers.h> -#include <cpu/x86/mtrr.h> -#include <cpu/x86/cache.h> -#include <cpu/x86/cr.h> -#include <cpu/x86/post_code.h> -#include <soc/cpu.h> - -.global bootblock_pre_c_entry -bootblock_pre_c_entry: - -.global cache_as_ram -cache_as_ram: - 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 - - 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 - 1), %eax /* size mask */ - or $MTRR_PHYS_MASK_VALID, %eax - wrmsr -#elif (CONFIG_DCACHE_RAM_SIZE == 768 * KiB) /* 768 KiB */ - 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 - 1), %eax /* size mask */ - or $MTRR_PHYS_MASK_VALID, %eax - 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 - 1), %eax /* size mask */ - or $MTRR_PHYS_MASK_VALID, %eax - 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_CAR_NEM) - /* Disable cache eviction (setup stage) */ - mov $MSR_EVICT_CTL, %ecx - rdmsr - or $0x1, %eax - wrmsr -#else - /* - * 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 -#endif - -#if IS_ENABLED(CONFIG_CAR_CQOS) -#if (CONFIG_DCACHE_RAM_SIZE == 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 $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 -#endif - post_code(0x26) - - /* Clear the cache memory region. This will also fill up the cache */ - mov $CONFIG_DCACHE_RAM_BASE, %edi - mov $(CONFIG_DCACHE_RAM_SIZE >> 2), %ecx - xor %eax, %eax - rep stos %eax, %es:(%edi) - - post_code(0x27) - -#if IS_ENABLED(CONFIG_CAR_NEM) - /* Disable cache eviction (run stage) */ - mov $MSR_EVICT_CTL, %ecx - rdmsr - or $0x2, %eax - wrmsr -#else - /* 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 -#endif - - post_code(0x28) - -car_init_done: - - /* Setup bootblock stack */ - mov $_car_stack_end, %esp - -before_carstage: - post_code(0x2b) - - /* Restore the timestamp from bootblock_crt0.S (mm2:mm1) */ - movd %mm2, %eax - push %eax - movd %mm1, %eax - push %eax - - /* We can call into C functions now */ - 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/apollolake/include/soc/cpu.h b/src/soc/intel/apollolake/include/soc/cpu.h index 5ae49e8..5fa5bea 100644 --- a/src/soc/intel/apollolake/include/soc/cpu.h +++ b/src/soc/intel/apollolake/include/soc/cpu.h @@ -32,13 +32,6 @@ void enable_untrusted_mode(void); #define CPUID_APOLLOLAKE_A0 0x506c8 #define CPUID_APOLLOLAKE_B0 0x506c9
-/* - * Each bit in QOS mask controls this many bytes. This is calculated as: - * (CACHE_WAYS / CACHE_BITS_PER_MASK) * CACHE_LINE_SIZE * CACHE_SETS - */ -#define CACHE_QOS_SIZE_PER_BIT (128 * KiB) -#define L2_CACHE_SIZE 0x100000 - #define BASE_CLOCK_MHZ 100
/* Common Timer Copy (CTC) frequency - 19.2MHz. */ diff --git a/src/soc/intel/common/block/cpu/Kconfig b/src/soc/intel/common/block/cpu/Kconfig new file mode 100644 index 0000000..b1e9ae6 --- /dev/null +++ b/src/soc/intel/common/block/cpu/Kconfig @@ -0,0 +1,61 @@ +config SOC_INTEL_COMMON_CAR + bool + depends on !FSP_CAR + default n if (!SOC_INTEL_CAR_SMALL_CORE && !SOC_INTEL_CAR_BIG_CORE) + default CAR_CQOS if (!SOC_INTEL_CAR_BIG_CORE) + default CAR_NEM_ENHANCED if (!SOC_INTEL_CAR_SMALL_CORE) + help + This option allows you to select how cache-as-ram (CAR) is set up. + +config CAR_NEM + bool + default y + 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 + block in NEM mode. + +config CAR_CQOS + bool + default y + help + Cache Quality of Service allows more fine-grained control of cache + usage. As result, it is possible to set up portion of L2 cache for + CAR and use remainder for actual caching. + +config CAR_NEM_ENHANCED + bool + default y + help + Current limitation NEM mode is that code and data size is derive + from the need not to spill out any modified line: as in NEM mode + there is no memory behind, the modified data will be lost and NEM + results will be inconsistent, hence NEM ENHANCED mode ensure to + have, some “magic” way to guarantee that modified data is always + kept in cache while clean data is replaced. + +config SOC_INTEL_CAR_SMALL_CORE + bool + default n + help + Intel Processor CAR support on small core + +config SOC_INTEL_CAR_BIG_CORE + bool + default n + help + Intel Processor CAR support on big core + +# +# Each bit in QOS mask controls this many bytes. This is calculated as: +# (CACHE_WAYS / CACHE_BITS_PER_MASK) * CACHE_LINE_SIZE * CACHE_SETS +# + +config CACHE_QOS_SIZE_PER_BIT + int + default 128000 + +config L2_CACHE_SIZE + hex + default 0x100000 + 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..1997641 --- /dev/null +++ b/src/soc/intel/common/block/cpu/Makefile.inc @@ -0,0 +1,2 @@ +bootblock-$(CONFIG_SOC_INTEL_COMMON_CAR) += car/cache_as_ram.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..6b5a089 --- /dev/null +++ b/src/soc/intel/common/block/cpu/car/cache_as_ram.S @@ -0,0 +1,177 @@ +/* + * 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> +#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 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 + +#if IS_ENABLED(CONFIG_SOC_INTEL_CAR_SMALL_CORE) + #include "car_small_core.S" +#elif IS_ENABLED(CONFIG_SOC_INTEL_CAR_BIG_CORE) + #include "car_big_core.S" +#endif + +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 diff --git a/src/soc/intel/common/block/cpu/car/car_big_core.S b/src/soc/intel/common/block/cpu/car/car_big_core.S new file mode 100644 index 0000000..5dabbb9 --- /dev/null +++ b/src/soc/intel/common/block/cpu/car/car_big_core.S @@ -0,0 +1,161 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 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. + * + */ + + /* 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 + + /* + * 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(0x27) + /* + * 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 .halt_forever + cmpl $0, %eax + jz .halt_forever + + post_code(0x28) + /* + * 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 + diff --git a/src/soc/intel/common/block/cpu/car/car_small_core.S b/src/soc/intel/common/block/cpu/car/car_small_core.S new file mode 100644 index 0000000..9779db3 --- /dev/null +++ b/src/soc/intel/common/block/cpu/car/car_small_core.S @@ -0,0 +1,103 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 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. + * + */ + +#if IS_ENABLED(CONFIG_CAR_NEM) + /* Disable cache eviction (setup stage) */ + mov $MSR_EVICT_CTL, %ecx + rdmsr + or $0x1, %eax + wrmsr +#else + /* + * 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 +#endif + +#if IS_ENABLED(CONFIG_CAR_CQOS) +#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 +#endif + post_code(0x26) + + /* Clear the cache memory region. This will also fill up the cache */ + mov $CONFIG_DCACHE_RAM_BASE, %edi + mov $(CONFIG_DCACHE_RAM_SIZE >> 2), %ecx + xor %eax, %eax + rep stos %eax, %es:(%edi) + + post_code(0x27) + +#if IS_ENABLED(CONFIG_CAR_NEM) + /* Disable cache eviction (run stage) */ + mov $MSR_EVICT_CTL, %ecx + rdmsr + or $0x2, %eax + wrmsr +#else + /* 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 +#endif + + post_code(0x28) diff --git a/src/soc/intel/glk/Kconfig b/src/soc/intel/glk/Kconfig index ee31abb..e29be64 100644 --- a/src/soc/intel/glk/Kconfig +++ b/src/soc/intel/glk/Kconfig @@ -47,6 +47,7 @@ config CPU_SPECIFIC_OPTIONS select RELOCATABLE_RAMSTAGE # Build fails if this is not selected select RTC select SMM_TSEG + select SOC_INTEL_CAR_SMALL_CORE select SOC_INTEL_COMMON select SOC_INTEL_COMMON_ACPI select SOC_INTEL_COMMON_ACPI_WAKE_SOURCE diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig index c1b585f..7618fd3 100644 --- a/src/soc/intel/skylake/Kconfig +++ b/src/soc/intel/skylake/Kconfig @@ -46,6 +46,7 @@ config CPU_SPECIFIC_OPTIONS select RELOCATABLE_MODULES select RELOCATABLE_RAMSTAGE select RTC + select SOC_INTEL_CAR_BIG_CORE select SOC_INTEL_COMMON select SOC_INTEL_COMMON_ACPI_WAKE_SOURCE select SOC_INTEL_COMMON_BLOCK diff --git a/src/soc/intel/skylake/Makefile.inc b/src/soc/intel/skylake/Makefile.inc index 2a6b152..181e17b 100644 --- a/src/soc/intel/skylake/Makefile.inc +++ b/src/soc/intel/skylake/Makefile.inc @@ -10,7 +10,6 @@ subdirs-y += ../../../cpu/x86/smm 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 3f8f0f0..0000000 --- a/src/soc/intel/skylake/bootblock/cache_as_ram.S +++ /dev/null @@ -1,320 +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 - - /* - * 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(0x27) - /* - * 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 .halt_forever - cmpl $0, %eax - jz .halt_forever - - post_code(0x28) - /* - * 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 - -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