fsp1_1: fsp_relocate: use struct region_device and struct prog

Using struct prog and struct region_device allows for the
caller to be none-the-wiser about where FSP gets placed. It
also allows for the source location to be abstracted away
such that it doesn't require a large mapping up front to
do the relocation. Lastly, it allows for simplifying the
intel/commmon FSP support in that it can pass around a
struct prog.

BUG=chrome-os-partner:43636
BRANCH=None
TEST=Built, booted, suspended, and resumed on glados.

Original-Change-Id: I034b04ab2b7e9e01f5ee14fcc190f04b90517d30
Original-Signed-off-by: Aaron Durbin <adurbin@chroumium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/290830
Original-Tested-by: Aaron Durbin <adurbin@chromium.org>
Original-Reviewed-by: Leroy P Leahy <leroy.p.leahy@intel.com>
Original-Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
Original-Commit-Queue: Aaron Durbin <adurbin@chromium.org>

Change-Id: Ibe1f206a9541902103551afaf212418fcc90e73c
Signed-off-by: Aaron Durbin <adurbin@chroumium.org>
Reviewed-on: http://review.coreboot.org/11193
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
This commit is contained in:
Aaron Durbin 2015-08-05 10:17:33 -05:00
parent 54546c97c7
commit 22ea007891
3 changed files with 40 additions and 17 deletions

View File

@ -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); 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 *new_loc;
void *fih;
size_t size = region_device_sz(fsp_src);
new_loc = cbmem_add(CBMEM_ID_REFCODE, size); new_loc = cbmem_add(CBMEM_ID_REFCODE, size);
if (new_loc == NULL) { if (new_loc == NULL) {
printk(BIOS_ERR, "Unable to load FSP into memory.\n"); printk(BIOS_ERR, "ERROR: Unable to load FSP into memory.\n");
return NULL; 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;
} }

View File

@ -24,6 +24,8 @@
#include <types.h> #include <types.h>
#include <arch/cpu.h> #include <arch/cpu.h>
#include <fsp_gop.h> #include <fsp_gop.h>
#include <program_loading.h>
#include <region.h>
/* /*
* The following are functions with prototypes defined in the EDK2 headers. The * 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_next_resource_hob(const EFI_GUID *guid, const void *hob_start);
void *get_first_resource_hob(const EFI_GUID *guid); void *get_first_resource_hob(const EFI_GUID *guid);
/* /*
* Relocate FSP entire binary into ram. Returns NULL on error. Otherwise the * Relocate FSP entire binary into ram. Returns < 0 on error, 0 on success.
* FSP_INFO_HEADER pointer to the relocated FSP. * 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: /* Additional HOB types not included in the FSP:
* #define EFI_HOB_TYPE_HANDOFF 0x0001 * #define EFI_HOB_TYPE_HANDOFF 0x0001

View File

@ -286,20 +286,22 @@ static void fsp_cache_save(void)
static int fsp_find_and_relocate(void) static int fsp_find_and_relocate(void)
{ {
void *fih; struct prog fsp_prog = PROG_INIT(ASSET_REFCODE, "fsp.bin");
void *data; struct region_device fsp_rdev;
size_t length; uint32_t type = CBFS_TYPE_FSP;
data = cbfs_boot_map_with_leak("fsp.bin", CBFS_TYPE_FSP, &length); if (cbfs_boot_locate(&fsp_rdev, prog_name(&fsp_prog), &type)) {
printk(BIOS_ERR, "ERROR: Couldn't find fsp.bin in CBFS.\n");
if (data == NULL) {
printk(BIOS_ERR, "Couldn't find fsp.bin in CBFS.\n");
return -1; 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; return 0;
} }