diff --git a/plat/nvidia/tegra/soc/t186/drivers/include/mce.h b/plat/nvidia/tegra/soc/t186/drivers/include/mce.h index 825f81ff24a7175c9fd9b3435f268fcc6fec2ac3..606569236b9f15ac775b89df92927cd34ce8c600 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/include/mce.h +++ b/plat/nvidia/tegra/soc/t186/drivers/include/mce.h @@ -322,6 +322,7 @@ int mce_update_gsc_videomem(void); int mce_update_gsc_tzdram(void); int mce_update_gsc_tzram(void); __dead2 void mce_enter_ccplex_state(uint32_t state_idx); +void mce_verify_firmware_version(void); /* declarations for ARI/NVG handler functions */ int ari_enter_cstate(uint32_t ari_base, uint32_t state, uint32_t wake_time); diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c index d105e36e39ee6d903f59d206cb461db4dd4ca0d3..0e550f5ba3881867aa4700d10be9077a3a9157cb 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c +++ b/plat/nvidia/tegra/soc/t186/drivers/mce/mce.c @@ -447,3 +447,46 @@ __dead2 void mce_enter_ccplex_state(uint32_t state_idx) panic(); } + +/******************************************************************************* + * Handler to read the MCE firmware version and check if it is compatible + * with interface header the BL3-1 was compiled against + ******************************************************************************/ +void mce_verify_firmware_version(void) +{ + arch_mce_ops_t *ops; + uint32_t cpu_ari_base; + uint64_t version; + uint32_t major, minor; + + /* get a pointer to the CPU's arch_mce_ops_t struct */ + ops = mce_get_curr_cpu_ops(); + + /* get the CPU's ARI base address */ + cpu_ari_base = mce_get_curr_cpu_ari_base(); + + /* + * Read the MCE firmware version and extract the major and minor + * version fields + */ + version = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_VERSION, 0); + major = (uint32_t)version; + minor = (uint32_t)(version >> 32); + + INFO("MCE Version - HW=%d:%d, SW=%d:%d\n", major, minor, + TEGRA_ARI_VERSION_MAJOR, TEGRA_ARI_VERSION_MINOR); + + /* + * Verify that the MCE firmware version and the interface header + * match + */ + if (major != TEGRA_ARI_VERSION_MAJOR) { + ERROR("ARI major version mismatch\n"); + panic(); + } + + if (minor < TEGRA_ARI_VERSION_MINOR) { + ERROR("ARI minor version mismatch\n"); + panic(); + } +} diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index b37bdad6d4a2f571a5a336863c81d2654894fe9a..49f45892fd23eee624b78a22541d90a9390d1ff0 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -37,6 +37,7 @@ #include <debug.h> #include <denver.h> #include <interrupt_mgmt.h> +#include <mce.h> #include <platform.h> #include <tegra_def.h> #include <tegra_private.h> @@ -170,3 +171,11 @@ void plat_gic_setup(void) if (sizeof(tegra186_sec_irqs) > 0) tegra_fiq_handler_setup(); } + +/******************************************************************************* + * Handler for early platform setup + ******************************************************************************/ +void plat_early_platform_setup(void) +{ + mce_verify_firmware_version(); +}