summaryrefslogtreecommitdiff
path: root/src/drivers/intel/fsp2_0/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers/intel/fsp2_0/util.c')
-rw-r--r--src/drivers/intel/fsp2_0/util.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/drivers/intel/fsp2_0/util.c b/src/drivers/intel/fsp2_0/util.c
index 4050862849..3b7516ab06 100644
--- a/src/drivers/intel/fsp2_0/util.c
+++ b/src/drivers/intel/fsp2_0/util.c
@@ -1,9 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <device/mmio.h>
+#include <cbfs.h>
#include <cf9_reset.h>
+#include <commonlib/bsd/compression.h>
+#include <commonlib/fsp.h>
#include <console/console.h>
#include <fsp/util.h>
+#include <lib.h>
#include <string.h>
#include <types.h>
@@ -114,3 +118,68 @@ void fsp_handle_reset(uint32_t status)
break;
}
}
+
+static void *fsp_get_dest_and_load(struct fsp_load_descriptor *fspld, size_t size,
+ const struct region_device *source_rdev,
+ uint32_t compression_algo)
+{
+ void *dest;
+
+ if (fspld->get_destination(fspld, &dest, size, source_rdev) < 0) {
+ printk(BIOS_ERR, "FSP Destination not obtained.\n");
+ return NULL;
+ }
+
+ if (cbfs_load_and_decompress(source_rdev, 0, region_device_sz(source_rdev),
+ dest, size, compression_algo) != size) {
+ printk(BIOS_ERR, "Failed to load FSP component.\n");
+ return NULL;
+ }
+
+ if (fsp_component_relocate((uintptr_t)dest, dest, size) < 0) {
+ printk(BIOS_ERR, "Unable to relocate FSP component!\n");
+ return NULL;
+ }
+
+ return dest;
+}
+
+/* Load the FSP component described by fsp_load_descriptor from cbfs. The FSP
+ * header object will be validated and filled in on successful load. */
+enum cb_err fsp_load_component(struct fsp_load_descriptor *fspld, struct fsp_header *hdr)
+{
+ struct cbfsf file_desc;
+ uint32_t compression_algo;
+ size_t output_size;
+ void *dest;
+ struct region_device source_rdev;
+ struct prog *fsp_prog = &fspld->fsp_prog;
+
+ if (fspld->get_destination == NULL)
+ return CB_ERR;
+
+ if (cbfs_boot_locate(&file_desc, prog_name(fsp_prog), &fsp_prog->cbfs_type) < 0)
+ return CB_ERR;
+
+ if (cbfsf_decompression_info(&file_desc, &compression_algo, &output_size) < 0)
+ return CB_ERR;
+
+ cbfs_file_data(&source_rdev, &file_desc);
+
+ dest = fsp_get_dest_and_load(fspld, output_size, &source_rdev, compression_algo);
+
+ if (dest == NULL)
+ return CB_ERR;
+
+ prog_set_area(fsp_prog, dest, output_size);
+
+ if (fsp_validate_component(hdr, prog_rdev(fsp_prog)) != CB_SUCCESS) {
+ printk(BIOS_ERR, "Invalid FSP header after load!\n");
+ return CB_ERR;
+ }
+
+ /* Signal that FSP component has been loaded. */
+ prog_segment_loaded(hdr->image_base, hdr->image_size, SEG_FINAL);
+
+ return CB_SUCCESS;
+}