mirror of
https://github.com/fail0verflow/switch-coreboot.git
synced 2025-05-04 01:39:18 -04:00
drivers/intel/fsp2_0: handle XIP and non-XIP for FSPM component
The previously implementation for loading the FSPM component didn't handle platforms which expects FSPM to be XIP. For the non-XIP case, romstage's address space wasn't fully being checked for overlaps. Lastly, fixup the API as the range_entry isn't needed any longer. This API change requires a apollolake to be updated as well. BUG=chrome-os-partner:52679 Change-Id: I24d0c7d123d12f15a8477e1025bf0901e2d702e7 Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: https://review.coreboot.org/15741 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh <furquan@google.com>
This commit is contained in:
parent
a413e5e455
commit
d04639b3d6
3 changed files with 89 additions and 11 deletions
|
@ -58,7 +58,7 @@ enum fsp_notify_phase {
|
||||||
|
|
||||||
|
|
||||||
/* Main FSP stages */
|
/* Main FSP stages */
|
||||||
enum fsp_status fsp_memory_init(struct range_entry *r, bool s3wake);
|
enum fsp_status fsp_memory_init(bool s3wake);
|
||||||
enum fsp_status fsp_silicon_init(struct range_entry *r);
|
enum fsp_status fsp_silicon_init(struct range_entry *r);
|
||||||
enum fsp_status fsp_notify(enum fsp_notify_phase phase);
|
enum fsp_status fsp_notify(enum fsp_notify_phase phase);
|
||||||
|
|
||||||
|
@ -74,14 +74,13 @@ void platform_fsp_silicon_init_params_cb(struct FSPS_UPD *supd);
|
||||||
* points and map 1:1 to the FSP entry points of the same name.
|
* points and map 1:1 to the FSP entry points of the same name.
|
||||||
*
|
*
|
||||||
* ### fsp_memory_init():
|
* ### fsp_memory_init():
|
||||||
* - r: memory range that the binary is allowed to be loaded into
|
|
||||||
* - s3wake: boolean indicating if the system is waking from resume
|
* - s3wake: boolean indicating if the system is waking from resume
|
||||||
*
|
*
|
||||||
* This function is responsible for loading and executing the memory
|
* This function is responsible for loading and executing the memory
|
||||||
* initialization code from the FSP-M binary. It expects this binary to reside
|
* initialization code from the FSP-M binary. It expects this binary to reside
|
||||||
* in cbfs as FSP_M_FILE.
|
* in cbfs as FSP_M_FILE.
|
||||||
*
|
*
|
||||||
* The function takes two parameters, which are described above, but does not
|
* The function takes one parameter, which is described above, but does not
|
||||||
* take in memory parameters as an argument. The memory parameters can be filled
|
* take in memory parameters as an argument. The memory parameters can be filled
|
||||||
* in with platform_fsp_memory_init_params_cb(). This is a callback symbol
|
* in with platform_fsp_memory_init_params_cb(). This is a callback symbol
|
||||||
* that fsp_memory_init() will call. The platform must provide this symbol.
|
* that fsp_memory_init() will call. The platform must provide this symbol.
|
||||||
|
|
|
@ -14,15 +14,18 @@
|
||||||
#include <arch/io.h>
|
#include <arch/io.h>
|
||||||
#include <arch/cpu.h>
|
#include <arch/cpu.h>
|
||||||
#include <arch/symbols.h>
|
#include <arch/symbols.h>
|
||||||
|
#include <cbfs.h>
|
||||||
#include <cbmem.h>
|
#include <cbmem.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <fsp/api.h>
|
#include <fsp/api.h>
|
||||||
#include <fsp/util.h>
|
#include <fsp/util.h>
|
||||||
#include <memrange.h>
|
#include <memrange.h>
|
||||||
|
#include <program_loading.h>
|
||||||
#include <reset.h>
|
#include <reset.h>
|
||||||
#include <romstage_handoff.h>
|
#include <romstage_handoff.h>
|
||||||
#include <soc/intel/common/mrc_cache.h>
|
#include <soc/intel/common/mrc_cache.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <symbols.h>
|
||||||
#include <timestamp.h>
|
#include <timestamp.h>
|
||||||
|
|
||||||
typedef asmlinkage enum fsp_status (*fsp_memory_init_fn)
|
typedef asmlinkage enum fsp_status (*fsp_memory_init_fn)
|
||||||
|
@ -153,12 +156,93 @@ static enum fsp_status do_fsp_memory_init(struct fsp_header *hdr, bool s3wake)
|
||||||
return do_fsp_post_memory_init(hob_list_ptr, s3wake);
|
return do_fsp_post_memory_init(hob_list_ptr, s3wake);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum fsp_status fsp_memory_init(struct range_entry *range, bool s3wake)
|
/* Load the binary into the memory specified by the info header. */
|
||||||
|
static enum cb_err load_fspm_mem(struct fsp_header *hdr,
|
||||||
|
const struct region_device *rdev)
|
||||||
|
{
|
||||||
|
struct memranges ranges;
|
||||||
|
struct range_entry freeranges[2];
|
||||||
|
const struct range_entry *r;
|
||||||
|
uintptr_t fspm_begin;
|
||||||
|
uintptr_t fspm_end;
|
||||||
|
|
||||||
|
if (fsp_validate_component(hdr, rdev) != CB_SUCCESS)
|
||||||
|
return CB_ERR;
|
||||||
|
|
||||||
|
fspm_begin = hdr->image_base;
|
||||||
|
fspm_end = fspm_begin + hdr->image_size;
|
||||||
|
|
||||||
|
/* Build up memory map of romstage address space including CAR. */
|
||||||
|
memranges_init_empty(&ranges, &freeranges[0], ARRAY_SIZE(freeranges));
|
||||||
|
memranges_insert(&ranges, (uintptr_t)_car_region_start,
|
||||||
|
_car_relocatable_data_end - _car_region_start, 0);
|
||||||
|
memranges_insert(&ranges, (uintptr_t)_program, _program_size, 0);
|
||||||
|
memranges_each_entry(r, &ranges) {
|
||||||
|
if (fspm_end <= range_entry_base(r))
|
||||||
|
continue;
|
||||||
|
if (fspm_begin >= range_entry_end(r))
|
||||||
|
continue;
|
||||||
|
printk(BIOS_ERR, "FSPM overlaps currently running program.\n");
|
||||||
|
return CB_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load binary into memory at provided address. */
|
||||||
|
if (rdev_readat(rdev, (void *)fspm_begin, 0, fspm_end - fspm_begin) < 0)
|
||||||
|
return CB_ERR;
|
||||||
|
|
||||||
|
return CB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle the case when FSPM is running XIP. */
|
||||||
|
static enum cb_err load_fspm_xip(struct fsp_header *hdr,
|
||||||
|
const struct region_device *rdev)
|
||||||
|
{
|
||||||
|
void *base;
|
||||||
|
|
||||||
|
if (fsp_validate_component(hdr, rdev) != CB_SUCCESS)
|
||||||
|
return CB_ERR;
|
||||||
|
|
||||||
|
base = rdev_mmap_full(rdev);
|
||||||
|
if ((uintptr_t)base != hdr->image_base) {
|
||||||
|
printk(BIOS_ERR, "FSPM XIP base does not match: %p vs %p\n",
|
||||||
|
(void *)(uintptr_t)hdr->image_base, base);
|
||||||
|
return CB_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since the component is XIP it's already in the address space. Thus,
|
||||||
|
* there's no need to rdev_munmap().
|
||||||
|
*/
|
||||||
|
return CB_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum fsp_status fsp_memory_init(bool s3wake)
|
||||||
{
|
{
|
||||||
struct fsp_header hdr;
|
struct fsp_header hdr;
|
||||||
|
enum cb_err status;
|
||||||
|
struct cbfsf file_desc;
|
||||||
|
struct region_device file_data;
|
||||||
|
const char *name = CONFIG_FSP_M_CBFS;
|
||||||
|
|
||||||
if (fsp_load_binary(&hdr, CONFIG_FSP_M_CBFS, range) != CB_SUCCESS)
|
if (cbfs_boot_locate(&file_desc, name, NULL)) {
|
||||||
|
printk(BIOS_ERR, "Could not locate %s in CBFS\n", name);
|
||||||
return FSP_NOT_FOUND;
|
return FSP_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
cbfs_file_data(&file_data, &file_desc);
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_NO_XIP_EARLY_STAGES))
|
||||||
|
status = load_fspm_mem(&hdr, &file_data);
|
||||||
|
else
|
||||||
|
status = load_fspm_xip(&hdr, &file_data);
|
||||||
|
|
||||||
|
if (status != CB_SUCCESS) {
|
||||||
|
printk(BIOS_ERR, "Loading FSPM failed.\n");
|
||||||
|
return FSP_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Signal that FSP component has been loaded. */
|
||||||
|
prog_segment_loaded(hdr.image_base, hdr.image_size, SEG_FINAL);
|
||||||
|
|
||||||
return do_fsp_memory_init(&hdr, s3wake);
|
return do_fsp_memory_init(&hdr, s3wake);
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,6 @@ ROMSTAGE_CBMEM_INIT_HOOK(migrate_power_state);
|
||||||
|
|
||||||
asmlinkage void car_stage_entry(void)
|
asmlinkage void car_stage_entry(void)
|
||||||
{
|
{
|
||||||
struct range_entry reg_car;
|
|
||||||
struct postcar_frame pcf;
|
struct postcar_frame pcf;
|
||||||
uintptr_t top_of_ram;
|
uintptr_t top_of_ram;
|
||||||
bool s3wake;
|
bool s3wake;
|
||||||
|
@ -116,11 +115,7 @@ asmlinkage void car_stage_entry(void)
|
||||||
|
|
||||||
s3wake = fill_power_state(ps) == ACPI_S3;
|
s3wake = fill_power_state(ps) == ACPI_S3;
|
||||||
|
|
||||||
/* Make sure the blob does not override our data in CAR */
|
if (fsp_memory_init(s3wake) != FSP_SUCCESS) {
|
||||||
range_entry_init(®_car, (uintptr_t)_car_relocatable_data_end,
|
|
||||||
(uintptr_t)_car_region_end, 0);
|
|
||||||
|
|
||||||
if (fsp_memory_init(®_car, s3wake) != FSP_SUCCESS) {
|
|
||||||
die("FSP memory init failed. Giving up.");
|
die("FSP memory init failed. Giving up.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue