summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/drivers/intel/fsp1_1/fsp_relocate.c28
-rw-r--r--src/drivers/intel/fsp1_1/fsp_util.h9
-rw-r--r--src/soc/intel/common/fsp_ramstage.c20
3 files changed, 40 insertions, 17 deletions
diff --git a/src/drivers/intel/fsp1_1/fsp_relocate.c b/src/drivers/intel/fsp1_1/fsp_relocate.c
index 08e1eb82f0..3e526086e2 100644
--- a/src/drivers/intel/fsp1_1/fsp_relocate.c
+++ b/src/drivers/intel/fsp1_1/fsp_relocate.c
@@ -482,15 +482,33 @@ static FSP_INFO_HEADER *fsp_relocate_in_place(void *fsp, size_t size)
return relocate_remaining_items(fsp, size, fih_offset);
}
-FSP_INFO_HEADER *fsp_relocate(void *fsp_src, size_t size)
+int fsp_relocate(struct prog *fsp_relocd, const struct region_device *fsp_src)
{
void *new_loc;
+ void *fih;
+ size_t size = region_device_sz(fsp_src);
new_loc = cbmem_add(CBMEM_ID_REFCODE, size);
+
if (new_loc == NULL) {
- printk(BIOS_ERR, "Unable to load FSP into memory.\n");
- return NULL;
+ printk(BIOS_ERR, "ERROR: Unable to load FSP into memory.\n");
+ return -1;
}
- memcpy(new_loc, fsp_src, size);
- return fsp_relocate_in_place(new_loc, size);
+
+ if (rdev_readat(fsp_src, new_loc, 0, size) != size) {
+ printk(BIOS_ERR, "ERROR: Can't read FSP's region device.\n");
+ return -1;
+ }
+
+ fih = fsp_relocate_in_place(new_loc, size);
+
+ if (fih == NULL) {
+ printk(BIOS_ERR, "ERROR: FSP relocation faiulre.\n");
+ return -1;
+ }
+
+ prog_set_area(fsp_relocd, new_loc, size);
+ prog_set_entry(fsp_relocd, fih, NULL);
+
+ return 0;
}
diff --git a/src/drivers/intel/fsp1_1/fsp_util.h b/src/drivers/intel/fsp1_1/fsp_util.h
index 618317ba69..fba91165a1 100644
--- a/src/drivers/intel/fsp1_1/fsp_util.h
+++ b/src/drivers/intel/fsp1_1/fsp_util.h
@@ -24,6 +24,8 @@
#include <types.h>
#include <arch/cpu.h>
#include <fsp_gop.h>
+#include <program_loading.h>
+#include <region.h>
/*
* The following are functions with prototypes defined in the EDK2 headers. The
@@ -63,10 +65,11 @@ void *get_next_type_guid_hob(UINT16 type, const EFI_GUID *guid,
void *get_next_resource_hob(const EFI_GUID *guid, const void *hob_start);
void *get_first_resource_hob(const EFI_GUID *guid);
/*
- * Relocate FSP entire binary into ram. Returns NULL on error. Otherwise the
- * FSP_INFO_HEADER pointer to the relocated FSP.
+ * Relocate FSP entire binary into ram. Returns < 0 on error, 0 on success.
+ * The FSP source is pointed to by region_device and the relocation information
+ * is encoded in a struct prog with its entry point set to the FSP info header.
*/
-FSP_INFO_HEADER *fsp_relocate(void *fsp_src, size_t size);
+int fsp_relocate(struct prog *fsp_relocd, const struct region_device *fsp_src);
/* Additional HOB types not included in the FSP:
* #define EFI_HOB_TYPE_HANDOFF 0x0001
diff --git a/src/soc/intel/common/fsp_ramstage.c b/src/soc/intel/common/fsp_ramstage.c
index 5ccc4eea92..1c3c38a35b 100644
--- a/src/soc/intel/common/fsp_ramstage.c
+++ b/src/soc/intel/common/fsp_ramstage.c
@@ -286,20 +286,22 @@ static void fsp_cache_save(void)
static int fsp_find_and_relocate(void)
{
- void *fih;
- void *data;
- size_t length;
+ struct prog fsp_prog = PROG_INIT(ASSET_REFCODE, "fsp.bin");
+ struct region_device fsp_rdev;
+ uint32_t type = CBFS_TYPE_FSP;
- data = cbfs_boot_map_with_leak("fsp.bin", CBFS_TYPE_FSP, &length);
-
- if (data == NULL) {
- printk(BIOS_ERR, "Couldn't find fsp.bin in CBFS.\n");
+ if (cbfs_boot_locate(&fsp_rdev, prog_name(&fsp_prog), &type)) {
+ printk(BIOS_ERR, "ERROR: Couldn't find fsp.bin in CBFS.\n");
return -1;
}
- fih = fsp_relocate(data, length);
+ if (fsp_relocate(&fsp_prog, &fsp_rdev)) {
+ printk(BIOS_ERR, "ERROR: FSP relocation failed.\n");
+ return -1;
+ }
- fsp_update_fih(fih);
+ /* FSP_INFO_HEADER is set as the program entry. */
+ fsp_update_fih(prog_entry(&fsp_prog));
return 0;
}