cpu/intel/car/non-evict: Improve CAR setup

On older CPUs lacking ESRM (Enhanced Short Rep Mov) the rep stos
instructions are very slow. Since the MTRR that covers the SPI ROM
is disabled when setting up the NEM, the CPU will run with cache
disabled and is even slower.

The Sandy Bridge BWG and the Sandy Bridge UEFI reference code do not
disable the MTRR on the XiP, allowing the CPU to run at full speed
when setting up CAR. On UEFI the CAR is set up by touching each
cache-line once. It doesn't clear the CAR while doing so.

Do the same to speed up setting CAR:
- Invalidate the cache
- Enable the SPI ROM XiP MTRR
- Set CR0.CD=0
- Touch one spot in each cache-line
- Clear CAR after NEM has been set up

To ensure that the CAR MTRR area is 64-byte aligned add an ALIGN to
the linker script. All existing boards should use a 64-byte alignment
for CAR.

TEST=Booted on Lenovo X220 and measured with cbmem -t:

TODO: Test on platforms that have FSRM (Ivy Bridge and newer).

Before:
   0:1st timestamp                                     1,083 (0)
  11:start of bootblock                                93,765 (92,681)

After:
   0:1st timestamp                                     0
  11:start of bootblock                                24,027

Boots 69msec faster than before or about 4 times faster.

Change-Id: Ia8baef28fd736ef6bb02d8a100d752ac0392e1cf
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/88792
Reviewed-by: Jérémy Compostella <jeremy.compostella@intel.com>
Reviewed-by: Shuo Liu <shuo.liu@intel.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
This commit is contained in:
Patrick Rudolph 2025-08-13 15:37:41 +02:00 committed by Matt DeVillier
commit 97dbfd3098
2 changed files with 36 additions and 30 deletions

View file

@ -122,6 +122,7 @@ _car_region_end = . + CONFIG_DCACHE_RAM_SIZE - (. - _car_region_start)
}
#if ENV_BOOTBLOCK
. = ALIGN(64);
_car_mtrr_end = .;
_car_mtrr_start = _car_region_start;

View file

@ -151,21 +151,16 @@ update_microcode:
jmp update_bsp_microcode
end_microcode_update:
#endif
/* Disable caching to change MTRR's. */
/* Disable caching. */
movl %cr0, %eax
orl $CR0_CacheDisable, %eax
movl %eax, %cr0
/* Clear the mask valid to disable the MTRR */
movl $MTRR_PHYS_MASK(1), %ecx
rdmsr
andl $(~MTRR_PHYS_MASK_VALID), %eax
wrmsr
/* Enable cache. */
movl %cr0, %eax
andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
invd
/* Enable caching */
andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
movl %eax, %cr0
/* enable the 'no eviction' mode */
@ -175,36 +170,46 @@ end_microcode_update:
andl $~2, %eax
wrmsr
/* Clear the cache memory region. This will also fill up the cache. */
cld
xorl %eax, %eax
/* Fill up the cache next. */
movl $_car_mtrr_start, %edi
movl $_car_mtrr_size, %ecx
shr $2, %ecx
rep stosl
/* enable the 'no eviction run' state */
/* Number of loops. */
movl $_car_mtrr_size, %ecx
shr $6, %ecx
xorl %ebx, %ebx
mov $64, %bl
1:
/*
* BWG: *One* location in each 64-byte cache line must be written
* to set all cached values to modified state.
*
* Value of %eax doesn't matter here. CAR is zeroed later.
*
* Zeroing the whole cache here *not* work when CR0.CD = 0.
* Zeroing the whole cache here *does* work when CR0.CD = 1,
* but will be a couple of times slower (4 times on Sandy Bridge).
*/
movl %eax, (%edi)
addl %ebx, %edi
loop 1b
/* enable the 'no eviction run' state. */
movl $NoEvictMod_MSR, %ecx
rdmsr
orl $3, %eax
wrmsr
post_code(POSTCODE_SOC_DISABLE_CACHE)
/* Enable Cache-as-RAM mode by disabling cache. */
movl %cr0, %eax
orl $CR0_CacheDisable, %eax
movl %eax, %cr0
movl $MTRR_PHYS_MASK(1), %ecx
rdmsr
orl $MTRR_PHYS_MASK_VALID, %eax
or $3, %al
wrmsr
post_code(POSTCODE_SOC_ENABLE_CACHE)
/* Enable cache. */
movl %cr0, %eax
andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax
movl %eax, %cr0
/* Now that CAR is enabled clear it. */
movl $_car_mtrr_start, %edi
movl $_car_mtrr_size, %ecx
cld
xorl %eax, %eax
shr $2, %ecx
rep stosl
/* Setup the stack. */
mov $_ecar_stack, %esp