soc/intel/common/cache_as_ram.S: Add macro to find a free MTRR

This adds a macro to find an available MTRR(s) to set up CAR.
This added complexity is not required on bootpaths without bootguard
but with bootguard MTRR's have already been set up by the ACM so
we need to figure out at runtime which ones are available.

Change-Id: I7d5442c75464cfb2b3611c63a472c8ee521c014d
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/37190
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-by: Patrick Rudolph <siro@das-labor.org>
This commit is contained in:
Arthur Heymans 2019-11-25 09:45:40 +01:00 committed by Patrick Georgi
parent cebf1e8c46
commit 64c9c6d54c
1 changed files with 44 additions and 6 deletions

View File

@ -12,6 +12,35 @@
.section .init, "ax", @progbits .section .init, "ax", @progbits
.code32 .code32
/*
* macro: find_free_mtrr
* Clobbers: %eax, %ebx, %ecx, %edx.
* Returns:
* %ebx contains the number of freely available MTRR's.
* It should be checked against 0.
* %ecx holds the MTRR_BASE of the free MTRR.
*/
.macro find_free_mtrr
/* Figure out how many MTRRs we have */
mov $MTRR_CAP_MSR, %ecx
rdmsr
movzb %al, %ebx /* Number of variable MTRRs */
/* Find a free variable MTRR */
movl $MTRR_PHYS_MASK(0), %ecx
1:
rdmsr
test $MTRR_PHYS_MASK_VALID, %eax
jz 2f
addl $2, %ecx
dec %ebx
jnz 1b
2:
/* %ecx needs to hold the MTRR_BASE */
decl %ecx
.endm
.global bootblock_pre_c_entry .global bootblock_pre_c_entry
bootblock_pre_c_entry: bootblock_pre_c_entry:
@ -82,15 +111,18 @@ clear_var_mtrr:
post_code(0x24) post_code(0x24)
#if ((CONFIG_DCACHE_RAM_SIZE & (CONFIG_DCACHE_RAM_SIZE - 1)) == 0) #if ((CONFIG_DCACHE_RAM_SIZE & (CONFIG_DCACHE_RAM_SIZE - 1)) == 0)
find_free_mtrr
test %ebx, %ebx
jz .halt_forever
/* Configure CAR region as write-back (WB) */ /* Configure CAR region as write-back (WB) */
mov $MTRR_PHYS_BASE(0), %ecx
mov $CONFIG_DCACHE_RAM_BASE, %eax mov $CONFIG_DCACHE_RAM_BASE, %eax
or $MTRR_TYPE_WRBACK, %eax or $MTRR_TYPE_WRBACK, %eax
xor %edx,%edx xor %edx,%edx
wrmsr wrmsr
/* Configure the MTRR mask for the size region */ /* Configure the MTRR mask for the size region */
mov $MTRR_PHYS_MASK(0), %ecx inc %ecx
mov $CONFIG_DCACHE_RAM_SIZE, %eax /* size mask */ mov $CONFIG_DCACHE_RAM_SIZE, %eax /* size mask */
dec %eax dec %eax
not %eax not %eax
@ -98,14 +130,17 @@ clear_var_mtrr:
movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */ movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
wrmsr wrmsr
#elif (CONFIG_DCACHE_RAM_SIZE == 768 * KiB) /* 768 KiB */ #elif (CONFIG_DCACHE_RAM_SIZE == 768 * KiB) /* 768 KiB */
find_free_mtrr
test %ebx, %ebx
jz .halt_forever
/* Configure CAR region as write-back (WB) */ /* Configure CAR region as write-back (WB) */
mov $MTRR_PHYS_BASE(0), %ecx
mov $CONFIG_DCACHE_RAM_BASE, %eax mov $CONFIG_DCACHE_RAM_BASE, %eax
or $MTRR_TYPE_WRBACK, %eax or $MTRR_TYPE_WRBACK, %eax
xor %edx,%edx xor %edx,%edx
wrmsr wrmsr
mov $MTRR_PHYS_MASK(0), %ecx incl %ecx
mov $(512 * KiB), %eax /* size mask */ mov $(512 * KiB), %eax /* size mask */
dec %eax dec %eax
not %eax not %eax
@ -113,13 +148,16 @@ clear_var_mtrr:
movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */ movl %esi, %edx /* edx <- MTRR_PHYS_MASK_HIGH */
wrmsr wrmsr
mov $MTRR_PHYS_BASE(1), %ecx find_free_mtrr
test %ebx, %ebx
jz .halt_forever
1:
mov $(CONFIG_DCACHE_RAM_BASE + 512 * KiB), %eax mov $(CONFIG_DCACHE_RAM_BASE + 512 * KiB), %eax
or $MTRR_TYPE_WRBACK, %eax or $MTRR_TYPE_WRBACK, %eax
xor %edx,%edx xor %edx,%edx
wrmsr wrmsr
mov $MTRR_PHYS_MASK(1), %ecx incl %ecx
mov $(256 * KiB), %eax /* size mask */ mov $(256 * KiB), %eax /* size mask */
dec %eax dec %eax
not %eax not %eax