drivers/intel/fsp2_0: Add FSP 2.2 specific support
• Based on FSP EAS v2.1 – Backward compatibility is retained. • Add multi-phase silicon initialization to increase the modularity of the FspSiliconInit() API. • Add FspMultiPhaseSiInit() API • FSP_INFO_HEADER changes o Added FspMultiPhaseSiInitEntryOffset • Add FSPS_ARCH_UPD o Added EnableMultiPhaseSiliconInit, bootloaders designed for FSP 2.0/2.1 can disable the FspMultiPhaseSiInit() API and continue to use FspSiliconInit() without change. FSP 2.2 Specification: https://www.intel.com/content/www/us/en/intelligent-systems/intel-firmware-support-package/intel-fsp-overview.html Change-Id: If7177a267f3a9b4cbb60a639f1c737b9a3341913 Signed-off-by: Subrata Banik <subrata.banik@intel.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/41728 Reviewed-by: Srinidhi N Kaushik <srinidhi.n.kaushik@intel.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
f7841d03e2
commit
33d9c4ad7e
|
@ -115,6 +115,8 @@ enum timestamp_id {
|
|||
TS_FSP_AFTER_FINALIZE = 959,
|
||||
TS_FSP_BEFORE_END_OF_FIRMWARE = 960,
|
||||
TS_FSP_AFTER_END_OF_FIRMWARE = 961,
|
||||
TS_FSP_MULTI_PHASE_SI_INIT_START = 962,
|
||||
TS_FSP_MULTI_PHASE_SI_INIT_END = 963,
|
||||
|
||||
/* 1000+ reserved for payloads (1000-1200: ChromeOS depthcharge) */
|
||||
|
||||
|
|
|
@ -18,6 +18,19 @@ config PLATFORM_USES_FSP2_1
|
|||
1. Remove FSP stack switch and use the same stack with boot firmware
|
||||
2. FSP should support external PPI interface pulled in via FSP_PEIM_TO_PEIM_INTERFACE
|
||||
|
||||
config PLATFORM_USES_FSP2_2
|
||||
bool
|
||||
default n
|
||||
select PLATFORM_USES_FSP2_1
|
||||
help
|
||||
Include FSP 2.2 wrappers and functionality.
|
||||
Features added into FSP 2.2 specification that impact coreboot are:
|
||||
1. Added multi-phase silicon initialization to increase the modularity of the
|
||||
FspSiliconInit() API
|
||||
2. FSP_INFO_HEADER changes to add FspMultiPhaseSiInitEntryOffset
|
||||
3. Added EnableMultiPhaseSiliconInit, bootloaders designed for FSP2.0/2.1 can disable
|
||||
the FspMultiPhaseSiInit() API and continue to use FspSiliconInit() without change.
|
||||
|
||||
if PLATFORM_USES_FSP2_0
|
||||
|
||||
config HAVE_INTEL_FSP_REPO
|
||||
|
|
|
@ -40,6 +40,9 @@ void fsp_print_header_info(const struct fsp_header *hdr)
|
|||
if ((hdr->component_attribute >> 12) == FSP_HDR_ATTRIB_FSPS) {
|
||||
printk(BIOS_SPEW, "\tSilicon init offset 0x%zx\n",
|
||||
hdr->silicon_init_entry_offset);
|
||||
if (CONFIG(PLATFORM_USES_FSP2_2))
|
||||
printk(BIOS_SPEW, "\tMultiPhaseSiInit offset 0x%zx\n",
|
||||
hdr->multi_phase_si_init_entry_offset);
|
||||
printk(BIOS_SPEW, "\tNotify phase offset 0x%zx\n",
|
||||
hdr->notify_phase_entry_offset);
|
||||
}
|
||||
|
|
|
@ -47,7 +47,10 @@ void fsps_load(bool s3wake);
|
|||
/* Callbacks for updating stage-specific parameters */
|
||||
void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version);
|
||||
void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd);
|
||||
|
||||
/* Callbacks for SoC/Mainboard specific overrides */
|
||||
void platform_fsp_multi_phase_init_cb(uint32_t phase_index);
|
||||
/* Check if SoC sets EnableMultiPhaseSiliconInit UPD */
|
||||
int soc_fsp_multi_phase_init_is_enable(void);
|
||||
/*
|
||||
* The following functions are used when FSP_PLATFORM_MEMORY_SETTINGS_VERSION
|
||||
* is employed allowing the mainboard and SoC to supply their own version
|
||||
|
|
|
@ -6,7 +6,11 @@
|
|||
#include <types.h>
|
||||
|
||||
#define FSP_HDR_OFFSET 0x94
|
||||
#if CONFIG(PLATFORM_USES_FSP2_2)
|
||||
#define FSP_HDR_LEN 0x4c
|
||||
#else
|
||||
#define FSP_HDR_LEN 0x48
|
||||
#endif
|
||||
#define FSP_HDR_SIGNATURE "FSPH"
|
||||
#define FSP_HDR_ATTRIB_FSPT 1
|
||||
#define FSP_HDR_ATTRIB_FSPM 2
|
||||
|
@ -26,6 +30,7 @@ struct fsp_header {
|
|||
size_t notify_phase_entry_offset;
|
||||
size_t memory_init_entry_offset;
|
||||
size_t silicon_init_entry_offset;
|
||||
size_t multi_phase_si_init_entry_offset;
|
||||
char image_id[sizeof(uint64_t) + 1];
|
||||
uint8_t revision;
|
||||
};
|
||||
|
|
|
@ -54,4 +54,22 @@ struct FSPM_ARCH_UPD {
|
|||
uint8_t Reserved1[8];
|
||||
} __packed;
|
||||
|
||||
struct FSPS_ARCH_UPD {
|
||||
///
|
||||
/// Revision of the structure. For FSP v2.2 value is 1.
|
||||
///
|
||||
uint8_t Revision;
|
||||
uint8_t Reserved[3];
|
||||
///
|
||||
/// Length of the structure in bytes. The current value for this field is 32
|
||||
///
|
||||
uint32_t Length;
|
||||
uint8_t Reserved1[4];
|
||||
///
|
||||
/// To enable multi-phase silicon initialization the bootloader must set non-zero value
|
||||
///
|
||||
uint8_t EnableMultiPhaseSiliconInit;
|
||||
uint8_t Reserved2[19];
|
||||
} __packed;
|
||||
|
||||
#endif /* _FSP2_0_UPD_H_ */
|
||||
|
|
|
@ -21,6 +21,17 @@ struct fsp_notify_params {
|
|||
enum fsp_notify_phase phase;
|
||||
};
|
||||
|
||||
enum fsp_multi_phase_action {
|
||||
GET_NUMBER_OF_PHASES = 0,
|
||||
EXECUTE_PHASE = 1
|
||||
};
|
||||
|
||||
struct fsp_multi_phase_params {
|
||||
enum fsp_multi_phase_action multi_phase_action;
|
||||
uint32_t phase_index;
|
||||
void *multi_phase_param_ptr;
|
||||
};
|
||||
|
||||
struct hob_resource {
|
||||
uint8_t owner_guid[16];
|
||||
uint32_t type;
|
||||
|
@ -115,6 +126,7 @@ typedef asmlinkage uint32_t (*temp_ram_exit_fn)(void *param);
|
|||
typedef asmlinkage uint32_t (*fsp_memory_init_fn)
|
||||
(void *raminit_upd, void **hob_list);
|
||||
typedef asmlinkage uint32_t (*fsp_silicon_init_fn)(void *silicon_upd);
|
||||
typedef asmlinkage uint32_t (*fsp_multi_phase_si_init_fn)(struct fsp_multi_phase_params *);
|
||||
typedef asmlinkage uint32_t (*fsp_notify_fn)(struct fsp_notify_params *);
|
||||
#include <fsp/debug.h>
|
||||
|
||||
|
|
|
@ -16,13 +16,74 @@
|
|||
|
||||
struct fsp_header fsps_hdr;
|
||||
|
||||
struct fsp_multi_phase_get_number_of_phases_params {
|
||||
uint32_t number_of_phases;
|
||||
uint32_t phases_executed;
|
||||
};
|
||||
|
||||
/* Callbacks for SoC/Mainboard specific overrides */
|
||||
void __weak platform_fsp_multi_phase_init_cb(uint32_t phase_index)
|
||||
{
|
||||
/* Leave for the SoC/Mainboard to implement if necessary. */
|
||||
}
|
||||
|
||||
int __weak soc_fsp_multi_phase_init_is_enable(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* FSP Specification < 2.2 has only 1 stage like FspSiliconInit. FSP specification >= 2.2
|
||||
* has multiple stages as below.
|
||||
*/
|
||||
enum fsp_silicon_init_phases {
|
||||
FSP_SILICON_INIT_API,
|
||||
FSP_MULTI_PHASE_SI_INIT_GET_NUMBER_OF_PHASES_API,
|
||||
FSP_MULTI_PHASE_SI_INIT_EXECUTE_PHASE_API
|
||||
};
|
||||
|
||||
static void fsps_return_value_handler(enum fsp_silicon_init_phases phases, uint32_t status)
|
||||
{
|
||||
uint8_t postcode;
|
||||
|
||||
/* Handle any reset request returned by FSP-S APIs */
|
||||
fsp_handle_reset(status);
|
||||
|
||||
if (status == FSP_SUCCESS)
|
||||
return;
|
||||
/* Handle all other errors returned by FSP-S APIs */
|
||||
/* Assume video failure if attempted to initialize graphics */
|
||||
if (CONFIG(RUN_FSP_GOP) && vbt_get())
|
||||
postcode = POST_VIDEO_FAILURE;
|
||||
else
|
||||
postcode = POST_HW_INIT_FAILURE; /* else generic */
|
||||
|
||||
switch (phases) {
|
||||
case FSP_SILICON_INIT_API:
|
||||
die_with_post_code(postcode, "FspSiliconInit returned with error 0x%08x\n",
|
||||
status);
|
||||
break;
|
||||
case FSP_MULTI_PHASE_SI_INIT_GET_NUMBER_OF_PHASES_API:
|
||||
printk(BIOS_SPEW, "FspMultiPhaseSiInit NumberOfPhases returned 0x%08x\n",
|
||||
status);
|
||||
break;
|
||||
case FSP_MULTI_PHASE_SI_INIT_EXECUTE_PHASE_API:
|
||||
printk(BIOS_SPEW, "FspMultiPhaseSiInit ExecutePhase returned 0x%08x\n",
|
||||
status);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void do_silicon_init(struct fsp_header *hdr)
|
||||
{
|
||||
FSPS_UPD *upd, *supd;
|
||||
fsp_silicon_init_fn silicon_init;
|
||||
uint32_t status;
|
||||
uint8_t postcode;
|
||||
const struct cbmem_entry *logo_entry = NULL;
|
||||
fsp_multi_phase_si_init_fn multi_phase_si_init;
|
||||
struct fsp_multi_phase_params multi_phase_params;
|
||||
struct fsp_multi_phase_get_number_of_phases_params multi_phase_get_number;
|
||||
|
||||
supd = (FSPS_UPD *) (hdr->cfg_region_offset + hdr->image_base);
|
||||
|
||||
|
@ -64,20 +125,49 @@ static void do_silicon_init(struct fsp_header *hdr)
|
|||
cbmem_entry_remove(logo_entry);
|
||||
|
||||
fsp_debug_after_silicon_init(status);
|
||||
fsps_return_value_handler(FSP_SILICON_INIT_API, status);
|
||||
|
||||
/* Handle any errors returned by FspSiliconInit */
|
||||
fsp_handle_reset(status);
|
||||
if (status != FSP_SUCCESS) {
|
||||
/* Assume video failure if attempted to initialize graphics */
|
||||
if (CONFIG(RUN_FSP_GOP) && vbt_get())
|
||||
postcode = POST_VIDEO_FAILURE;
|
||||
else
|
||||
postcode = POST_HW_INIT_FAILURE; /* else generic */
|
||||
if (!CONFIG(PLATFORM_USES_FSP2_2))
|
||||
return;
|
||||
|
||||
printk(BIOS_SPEW, "FspSiliconInit returned 0x%08x\n", status);
|
||||
die_with_post_code(postcode,
|
||||
"FspSiliconInit returned an error!\n");
|
||||
/* Check if SoC user would like to call Multi Phase Init */
|
||||
if (!soc_fsp_multi_phase_init_is_enable())
|
||||
return;
|
||||
|
||||
/* Call MultiPhaseSiInit */
|
||||
multi_phase_si_init = (void *) (hdr->image_base +
|
||||
hdr->multi_phase_si_init_entry_offset);
|
||||
|
||||
/* Implementing multi_phase_si_init() is optional as per FSP 2.2 spec */
|
||||
if (multi_phase_si_init == NULL)
|
||||
return;
|
||||
|
||||
post_code(POST_FSP_MULTI_PHASE_SI_INIT_ENTRY);
|
||||
timestamp_add_now(TS_FSP_MULTI_PHASE_SI_INIT_START);
|
||||
/* Get NumberOfPhases Value */
|
||||
multi_phase_params.multi_phase_action = GET_NUMBER_OF_PHASES;
|
||||
multi_phase_params.phase_index = 0;
|
||||
multi_phase_params.multi_phase_param_ptr = &multi_phase_get_number;
|
||||
status = multi_phase_si_init(&multi_phase_params);
|
||||
fsps_return_value_handler(FSP_MULTI_PHASE_SI_INIT_GET_NUMBER_OF_PHASES_API, status);
|
||||
|
||||
/* Execute Multi Phase Execution */
|
||||
for (int i = 1; i <= multi_phase_get_number.number_of_phases; i++) {
|
||||
printk(BIOS_SPEW, "Executing Phase %d of FspMultiPhaseSiInit\n", i);
|
||||
/*
|
||||
* Give SoC/mainboard a chance to perform any operation before
|
||||
* Multi Phase Execution
|
||||
*/
|
||||
platform_fsp_multi_phase_init_cb(i);
|
||||
|
||||
multi_phase_params.multi_phase_action = EXECUTE_PHASE;
|
||||
multi_phase_params.phase_index = i;
|
||||
multi_phase_params.multi_phase_param_ptr = NULL;
|
||||
status = multi_phase_si_init(&multi_phase_params);
|
||||
fsps_return_value_handler(FSP_MULTI_PHASE_SI_INIT_EXECUTE_PHASE_API, status);
|
||||
}
|
||||
timestamp_add_now(TS_FSP_MULTI_PHASE_SI_INIT_END);
|
||||
post_code(POST_FSP_MULTI_PHASE_SI_INIT_EXIT);
|
||||
}
|
||||
|
||||
static int fsps_get_dest(const struct fsp_load_descriptor *fspld, void **dest,
|
||||
|
|
|
@ -49,6 +49,8 @@ enum cb_err fsp_identify(struct fsp_header *hdr, const void *fsp_blob)
|
|||
hdr->notify_phase_entry_offset = read32(raw_hdr + 56);
|
||||
hdr->memory_init_entry_offset = read32(raw_hdr + 60);
|
||||
hdr->silicon_init_entry_offset = read32(raw_hdr + 68);
|
||||
if (CONFIG(PLATFORM_USES_FSP2_2))
|
||||
hdr->multi_phase_si_init_entry_offset = read32(raw_hdr + 72);
|
||||
|
||||
return CB_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -288,6 +288,20 @@
|
|||
*/
|
||||
#define POST_FSP_SILICON_EXIT 0x99
|
||||
|
||||
/**
|
||||
* \brief Before calling FSP Multiphase SiliconInit
|
||||
*
|
||||
* Going to call into FSP binary for Multiple phase SI Init
|
||||
*/
|
||||
#define POST_FSP_MULTI_PHASE_SI_INIT_ENTRY 0xa0
|
||||
|
||||
/**
|
||||
* \brief After calling FSP Multiphase SiliconInit
|
||||
*
|
||||
* FSP binary returned from Multiple phase SI Init
|
||||
*/
|
||||
#define POST_FSP_MULTI_PHASE_SI_INIT_EXIT 0xa1
|
||||
|
||||
/**
|
||||
* \brief Entry into elf boot
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue