[coreboot-gerrit] New patch to review for coreboot: drivers/intel/fsp1_1: prepare relocation code for sharing

Patrick Georgi (pgeorgi@google.com) gerrit at coreboot.org
Tue Sep 15 19:40:15 CET 2015


Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11663

-gerrit

commit cfea5f208deb009d3c05be18a6902078fafddfcf
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Thu Sep 10 21:19:25 2015 -0500

    drivers/intel/fsp1_1: prepare relocation code for sharing
    
    In order to integrate fsp 1.1 relocation with cbfstool one
    needs to be able to supply the address to relocate the FSP
    image. Therefore, allow this by returning offset for return
    values. Note that exposed API has not changed.
    
    BUG=chrome-os-partner:44827
    BRANCH=None
    TEST=Built and booted glados. Confirmed relocation values matched.
    
    Change-Id: I650a08ffb9caf7e0438a988cae9bec56dd31753c
    Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
    Original-Commit-Id: 53870b0df809418e9a09e7d380ad2399a09fb4fb
    Original-Change-Id: Ic2ec63681ed4e652e2624b40e132f95d1e5a0887
    Original-Signed-off-by: Aaron Durbin <adurbin at chromium.org>
    Original-Reviewed-on: https://chromium-review.googlesource.com/298831
    Original-Reviewed-by: Duncan Laurie <dlaurie at chromium.org>
    Original-Reviewed-by: Leroy P Leahy <leroy.p.leahy at intel.com>
---
 src/drivers/intel/fsp1_1/fsp_relocate.c | 60 +++++++++++++++++++++------------
 1 file changed, 38 insertions(+), 22 deletions(-)

diff --git a/src/drivers/intel/fsp1_1/fsp_relocate.c b/src/drivers/intel/fsp1_1/fsp_relocate.c
index 2cc2560..351fcc8 100644
--- a/src/drivers/intel/fsp1_1/fsp_relocate.c
+++ b/src/drivers/intel/fsp1_1/fsp_relocate.c
@@ -82,7 +82,7 @@ static size_t reloc_offset(uint16_t reloc_entry)
 	return reloc_entry & ((1 << 12) - 1);
 }
 
-static int te_relocate_in_place(void *te, size_t size)
+static int te_relocate(uintptr_t new_addr, void *te, size_t size)
 {
 	EFI_TE_IMAGE_HEADER *teih;
 	EFI_IMAGE_DATA_DIRECTORY *relocd;
@@ -115,11 +115,11 @@ static int te_relocate_in_place(void *te, size_t size)
 	te_base = te;
 	te_base -= fixup_offset;
 
-	adj = (uintptr_t)te - (teih->ImageBase + fixup_offset);
+	adj = new_addr - (teih->ImageBase + fixup_offset);
 
 	printk(FSP_DBG_LVL, "TE Image %p -> %p adjust value: %x\n",
 		(void *)(uintptr_t)(teih->ImageBase + fixup_offset),
-		te, adj);
+		(void *)new_addr, adj);
 
 	/* Adjust ImageBase for consistency. */
 	teih->ImageBase = (uint32_t)(teih->ImageBase + adj);
@@ -266,7 +266,8 @@ static int relocate_patch_table(void *fsp, size_t size, size_t offset,
 	return 0;
 }
 
-static void *relocate_remaining_items(void *fsp, size_t size, size_t fih_offset)
+static ssize_t relocate_remaining_items(void *fsp, size_t size,
+					uintptr_t new_addr, size_t fih_offset)
 {
 	EFI_FFS_FILE_HEADER *ffsfh;
 	EFI_COMMON_SECTION_HEADER *csh;
@@ -278,7 +279,7 @@ static void *relocate_remaining_items(void *fsp, size_t size, size_t fih_offset)
 
 	if (fih_offset == 0) {
 		printk(BIOS_ERR, "FSP_INFO_HEADER offset is 0.\n");
-		return NULL;
+		return -1;
 	}
 
 	/* FSP_INFO_HEADER at first file in FV within first RAW section. */
@@ -290,22 +291,22 @@ static void *relocate_remaining_items(void *fsp, size_t size, size_t fih_offset)
 
 	if (memcmp(&ffsfh->Name, &fih_guid, sizeof(fih_guid))) {
 		printk(BIOS_ERR, "Bad FIH GUID.\n");
-		return NULL;
+		return -1;
 	}
 
 	if (csh->Type != EFI_SECTION_RAW) {
 		printk(BIOS_ERR, "FIH file should have raw section: %x\n",
 			csh->Type);
-		return NULL;
+		return -1;
 	}
 
 	if (fih->Signature != FSP_SIG) {
 		printk(BIOS_ERR, "Unexpected FIH signature: %08x\n",
 			fih->Signature);
-		return NULL;
+		return -1;
 	}
 
-	adjustment = (intptr_t)fsp - fih->ImageBase;
+	adjustment = (intptr_t)new_addr - fih->ImageBase;
 
 	/* Update ImageBase to reflect FSP's new home. */
 	fih->ImageBase += adjustment;
@@ -330,18 +331,18 @@ static void *relocate_remaining_items(void *fsp, size_t size, size_t fih_offset)
 
 		if (relocate_patch_table(fsp, size, offset, adjustment)) {
 			printk(BIOS_ERR, "FSPP relocation failed.\n");
-			return NULL;
+			return -1;
 		}
 
-		return fih;
+		return fih_offset;
 	}
 
 	printk(BIOS_ERR, "Could not find the FSP patch table.\n");
-	return NULL;
+	return -1;
 }
 
-static ssize_t relocate_fvh(void *fsp, size_t fsp_size, size_t fvh_offset,
-				size_t *fih_offset)
+static ssize_t relocate_fvh(uintptr_t new_addr, void *fsp, size_t fsp_size,
+				size_t fvh_offset, size_t *fih_offset)
 {
 	EFI_FIRMWARE_VOLUME_HEADER *fvh;
 	EFI_FFS_FILE_HEADER *ffsfh;
@@ -431,14 +432,24 @@ static ssize_t relocate_fvh(void *fsp, size_t fsp_size, size_t fvh_offset,
 				return -1;
 			}
 
+			/*
+			 * The entire FSP 1.1 image can be thought of as one
+			 * program with a single link address even though there
+			 * are multiple TEs linked separately. The reason is
+			 * that each TE is linked for XIP. So in order to
+			 * relocate the TE properly we need to form the
+			 * relocated address based on the TE offset within
+			 * FSP proper.
+			 */
 			if (csh->Type == EFI_SECTION_TE) {
 				void *te;
 				size_t te_offset = offset + data_offset;
+				uintptr_t te_addr = new_addr + te_offset;
 
 				printk(FSP_DBG_LVL, "TE image at offset %zx\n",
 					te_offset);
 				te = relative_offset(fsp, te_offset);
-				te_relocate_in_place(te, data_size);
+				te_relocate(te_addr, te, data_size);
 			}
 
 			offset += data_size + data_offset;
@@ -451,7 +462,7 @@ static ssize_t relocate_fvh(void *fsp, size_t fsp_size, size_t fvh_offset,
 	return fvh->FvLength;
 }
 
-static FSP_INFO_HEADER *fsp_relocate_in_place(void *fsp, size_t size)
+static ssize_t fsp1_1_relocate(uintptr_t new_addr, void *fsp, size_t size)
 {
 	size_t offset;
 	size_t fih_offset;
@@ -464,27 +475,30 @@ static FSP_INFO_HEADER *fsp_relocate_in_place(void *fsp, size_t size)
 		/* Relocate each FV within the FSP region. The FSP_INFO_HEADER
 		 * should only be located in the first FV. */
 		if (offset == 0)
-			nparsed = relocate_fvh(fsp, size, offset, &fih_offset);
+			nparsed = relocate_fvh(new_addr, fsp, size, offset,
+						&fih_offset);
 		else
-			nparsed = relocate_fvh(fsp, size, offset, NULL);
+			nparsed = relocate_fvh(new_addr, fsp, size, offset,
+						NULL);
 
 		/* FV should be larger than 0 or failed to parse. */
 		if (nparsed <= 0) {
 			printk(BIOS_ERR, "FV @ offset %zx relocation failed\n",
 				offset);
-			return NULL;
+			return -1;
 		}
 
 		offset += nparsed;
 	}
 
-	return relocate_remaining_items(fsp, size, fih_offset);
+	return relocate_remaining_items(fsp, size, new_addr, fih_offset);
 }
 
 int fsp_relocate(struct prog *fsp_relocd, const struct region_device *fsp_src)
 {
 	void *new_loc;
 	void *fih;
+	ssize_t fih_offset;
 	size_t size = region_device_sz(fsp_src);
 
 	new_loc = cbmem_add(CBMEM_ID_REFCODE, size);
@@ -499,13 +513,15 @@ int fsp_relocate(struct prog *fsp_relocd, const struct region_device *fsp_src)
 		return -1;
 	}
 
-	fih = fsp_relocate_in_place(new_loc, size);
+	fih_offset = fsp1_1_relocate((uintptr_t)new_loc, new_loc, size);
 
-	if (fih == NULL) {
+	if (fih_offset <= 0) {
 		printk(BIOS_ERR, "ERROR: FSP relocation faiulre.\n");
 		return -1;
 	}
 
+	fih = relative_offset(new_loc, fih_offset);
+
 	prog_set_area(fsp_relocd, new_loc, size);
 	prog_set_entry(fsp_relocd, fih, NULL);
 



More information about the coreboot-gerrit mailing list