[coreboot-gerrit] Patch set updated for coreboot: arch/x86: Utilize additional MTRRs in postcar_frame_add_mtrr

Naresh Solanki (naresh.solanki@intel.com) gerrit at coreboot.org
Fri Sep 9 16:52:48 CEST 2016


Naresh Solanki (naresh.solanki at intel.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/16509

-gerrit

commit fe8ffa7bf33aa550cba6eb4b1cac503eeaa0739a
Author: Rizwan Qureshi <rizwan.qureshi at intel.com>
Date:   Wed Sep 7 20:18:17 2016 +0530

    arch/x86: Utilize additional MTRRs in postcar_frame_add_mtrr
    
    In the current implementation of postcar_frame_add_mtrr,
    if provided size is bigger than the base address alignment,
    the alignment is considered as size and covered by the MTRRs
    ignoring the specified size.
    In this case the callee has to make sure that the provided
    size should be smaller or equal to the base address alignment
    boundary.
    
    To simplify this, utilize additonal MTRRs to cover the entire
    size specified. We reuse the code from cpu/x86/mtrr/mtrr.c.
    
    Change-Id: Ie2e88b596f43692169c7d4440b18498a72fcba11
    Signed-off-by: Rizwan Qureshi <rizwan.qureshi at intel.com>
---
 src/arch/x86/postcar_loader.c | 59 +++++++++++++++++++++++++++----------------
 1 file changed, 37 insertions(+), 22 deletions(-)

diff --git a/src/arch/x86/postcar_loader.c b/src/arch/x86/postcar_loader.c
index b5d8db0..d9719ff 100644
--- a/src/arch/x86/postcar_loader.c
+++ b/src/arch/x86/postcar_loader.c
@@ -59,29 +59,44 @@ int postcar_frame_init(struct postcar_frame *pcf, size_t stack_size)
 void postcar_frame_add_mtrr(struct postcar_frame *pcf,
 				uintptr_t addr, size_t size, int type)
 {
-	size_t align;
-
-	if (pcf->num_var_mttrs >= pcf->max_var_mttrs) {
-		printk(BIOS_ERR, "No more variable MTRRs: %d\n",
-			pcf->max_var_mttrs);
-		return;
-	}
-
-	/* Determine address alignment by lowest bit set in address. */
-	align = addr & (addr ^ (addr - 1));
-
-	if (align < size) {
-		printk(BIOS_ERR, "Address (%lx) alignment (%zx) < size (%zx)\n",
-			addr, align, size);
-		size = align;
+	/*
+	 * Utilize additional MTRRs if the specified size is greater than the
+	 * base address alignment.
+	 */
+	while (size != 0) {
+		uint32_t addr_lsb;
+		uint32_t size_msb;
+		uint32_t mtrr_size;
+
+		if (pcf->num_var_mttrs >= pcf->max_var_mttrs) {
+			printk(BIOS_ERR, "No more variable MTRRs: %d\n",
+					pcf->max_var_mttrs);
+			return;
+		}
+
+		addr_lsb = fls(addr);
+		size_msb = fms(size);
+
+		/* All MTRR entries need to have their base aligned to the mask
+		 * size. The maximum size is calculated by a function of the
+		 * min base bit set and maximum size bit set. */
+		if (addr_lsb > size_msb)
+			mtrr_size = 1 << size_msb;
+		else
+			mtrr_size = 1 << addr_lsb;
+
+		printk(BIOS_DEBUG, "MTRR Range: Start=%lx End=%lx (Size %x)\n",
+					addr, addr + mtrr_size, mtrr_size);
+
+		stack_push(pcf, pcf->upper_mask);
+		stack_push(pcf, ~(mtrr_size - 1) | MTRR_PHYS_MASK_VALID);
+		stack_push(pcf, 0);
+		stack_push(pcf, addr | type);
+		pcf->num_var_mttrs++;
+
+		size -= mtrr_size;
+		addr += mtrr_size;
 	}
-
-	/* Push MTRR mask then base -- upper 32-bits then lower 32-bits. */
-	stack_push(pcf, pcf->upper_mask);
-	stack_push(pcf, ~(size - 1) | MTRR_PHYS_MASK_VALID);
-	stack_push(pcf, 0);
-	stack_push(pcf, addr | type);
-	pcf->num_var_mttrs++;
 }
 
 void *postcar_commit_mtrrs(struct postcar_frame *pcf)



More information about the coreboot-gerrit mailing list