diff options
author | Andrey Petrov <andrey.petrov@intel.com> | 2016-06-27 13:39:34 -0700 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2016-08-28 18:38:48 +0200 |
commit | 3f4aece4e07b15a5a2d191873da04b88c8e87049 (patch) | |
tree | 95656eb37744843a4e9586c625451b55a5e17251 /src/soc/intel/apollolake/bootblock/cache_as_ram.S | |
parent | 7f72c9b30ec543fc5d485dca5f15790d2c4b03f3 (diff) |
soc/intel/apollolake: Add CQOS CAR implementation
Add new option to set up Cache-As-RAM by using CQOS, Cache Quality of
Service. CQOS allows setting ways of cache in no-fill mode, while keeping
other ways in regular evicting mode. This effectively allows using CAR
and cache simultaneously.
BUG=chrome-os-partner:51959
TEST=switch from NEM to CQOS and back, boot
Change-Id: Ic7f9899918f94a5788b02a4fbd2f5d5ba9aaf91d
Signed-off-by: Andrey Petrov <andrey.petrov@intel.com>
Reviewed-on: https://review.coreboot.org/15455
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/soc/intel/apollolake/bootblock/cache_as_ram.S')
-rw-r--r-- | src/soc/intel/apollolake/bootblock/cache_as_ram.S | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/soc/intel/apollolake/bootblock/cache_as_ram.S b/src/soc/intel/apollolake/bootblock/cache_as_ram.S index e8fae28b5b..65dd4c83f9 100644 --- a/src/soc/intel/apollolake/bootblock/cache_as_ram.S +++ b/src/soc/intel/apollolake/bootblock/cache_as_ram.S @@ -124,12 +124,61 @@ clear_var_mtrr: 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 */ @@ -140,11 +189,26 @@ clear_var_mtrr: 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) |