From e1f97d9c520819297c2b0f9c019a2cbcd9706375 Mon Sep 17 00:00:00 2001 From: Hadi Asyrafi Date: Tue, 17 Dec 2019 19:22:17 +0800 Subject: [PATCH] intel: Extend SiP service to support mailbox's RSU Introduce support for RSU that can be initiated through SMC calls. Added features as below: - RSU status - RSU update - RSU HPS notify - RSU get sub-partition Signed-off-by: Hadi Asyrafi Change-Id: I78d5a07688e43da99f03d77dfd45ffb4a78f2e4c --- plat/intel/soc/agilex/bl31_plat_setup.c | 3 + .../soc/common/include/socfpga_mailbox.h | 35 ++++++++--- plat/intel/soc/common/soc/socfpga_mailbox.c | 49 +++++++++++++++ plat/intel/soc/common/socfpga_psci.c | 7 ++- plat/intel/soc/common/socfpga_sip_svc.c | 63 +++++++++++++++++++ plat/intel/soc/stratix10/bl31_plat_setup.c | 3 + 6 files changed, 152 insertions(+), 8 deletions(-) diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c index 13099b40f..4b1144095 100644 --- a/plat/intel/soc/agilex/bl31_plat_setup.c +++ b/plat/intel/soc/agilex/bl31_plat_setup.c @@ -14,6 +14,7 @@ #include #include +#include "socfpga_mailbox.h" #include "socfpga_private.h" static entry_point_info_t bl32_image_ep_info; @@ -107,6 +108,8 @@ void bl31_platform_setup(void) /* Signal secondary CPUs to jump to BL31 (BL2 = U-boot SPL) */ mmio_write_64(PLAT_CPU_RELEASE_ADDR, (uint64_t)plat_secondary_cpus_bl31_entry); + + mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL); } const mmap_region_t plat_agilex_mmap[] = { diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index c4b9e5967..38f46963a 100644 --- a/plat/intel/soc/common/include/socfpga_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -73,6 +73,29 @@ /* Mailbox REBOOT commands */ #define MBOX_CMD_REBOOT_HPS 71 +/* Mailbox RSU commands */ +#define MBOX_GET_SUBPARTITION_TABLE 90 +#define MBOX_RSU_STATUS 91 +#define MBOX_RSU_UPDATE 92 + +/* Mailbox RSU macros */ +#define RSU_VERSION_ACMF BIT(8) +#define RSU_VERSION_ACMF_MASK 0xff00 + +/* HPS stage notify command */ +#define MBOX_HPS_STAGE_NOTIFY 93 + +/* Execution states for HPS_STAGE_NOTIFY */ +#define HPS_EXECUTION_STATE_FSBL 0 +#define HPS_EXECUTION_STATE_SSBL 1 +#define HPS_EXECUTION_STATE_OS 2 + +/* Mailbox reconfiguration commands */ +#define MBOX_CONFIG_STATUS 4 +#define MBOX_RECONFIG 6 +#define MBOX_RECONFIG_DATA 8 +#define MBOX_RECONFIG_STATUS 9 + /* Generic error handling */ #define MBOX_TIMEOUT -2047 #define MBOX_NO_RESPONSE -2 @@ -98,13 +121,6 @@ #define MBOX_CFGSTAT_STATE_ERROR_BOOT_INFO 0xf0000007 #define MBOX_CFGSTAT_STATE_ERROR_QSPI_ERROR 0xf0000008 -/* Mailbox reconfiguration commands */ -#define MBOX_CONFIG_STATUS 4 -#define MBOX_RECONFIG 6 -#define MBOX_RECONFIG_DATA 8 -#define MBOX_RECONFIG_STATUS 9 - - void mailbox_set_int(int interrupt_input); int mailbox_init(void); void mailbox_set_qspi_close(void); @@ -122,4 +138,9 @@ void mailbox_clear_response(void); uint32_t intel_mailbox_get_config_status(uint32_t cmd); int intel_mailbox_is_fpga_not_ready(void); +int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len); +int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len); +int mailbox_rsu_update(uint32_t *flash_offset); +int mailbox_hps_stage_notify(uint32_t execution_stage); + #endif /* SOCFPGA_MBOX_H */ diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index 8d7c1d663..673c2d56e 100644 --- a/plat/intel/soc/common/soc/socfpga_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -267,6 +267,55 @@ void mailbox_reset_cold(void) mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0, 0, 0, NULL, 0); } +int mailbox_rsu_get_spt_offset(uint32_t *resp_buf, uint32_t resp_buf_len) +{ + return mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_SUBPARTITION_TABLE, + NULL, 0, 0, (uint32_t *)resp_buf, + resp_buf_len); +} + +struct rsu_status_info { + uint64_t current_image; + uint64_t fail_image; + uint32_t state; + uint32_t version; + uint32_t error_location; + uint32_t error_details; + uint32_t retry_counter; +}; + +int mailbox_rsu_status(uint32_t *resp_buf, uint32_t resp_buf_len) +{ + int ret; + struct rsu_status_info *info = (struct rsu_status_info *)resp_buf; + + info->retry_counter = ~0; + + ret = mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_STATUS, NULL, 0, 0, + (uint32_t *)resp_buf, resp_buf_len); + + if (ret < 0) + return ret; + + if (info->retry_counter != ~0) + if (!(info->version & RSU_VERSION_ACMF_MASK)) + info->version |= RSU_VERSION_ACMF; + + return ret; +} + +int mailbox_rsu_update(uint32_t *flash_offset) +{ + return mailbox_send_cmd(MBOX_JOB_ID, MBOX_RSU_UPDATE, + (uint32_t *)flash_offset, 2, 0, NULL, 0); +} + +int mailbox_hps_stage_notify(uint32_t execution_stage) +{ + return mailbox_send_cmd(MBOX_JOB_ID, MBOX_HPS_STAGE_NOTIFY, + &execution_stage, 1, 0, NULL, 0); +} + int mailbox_init(void) { int status = 0; diff --git a/plat/intel/soc/common/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c index d8a6c1980..d27ab9f96 100644 --- a/plat/intel/soc/common/socfpga_psci.c +++ b/plat/intel/soc/common/socfpga_psci.c @@ -130,9 +130,14 @@ static void __dead2 socfpga_system_off(void) panic(); } +extern uint64_t intel_rsu_update_address; + static void __dead2 socfpga_system_reset(void) { - mailbox_reset_cold(); + if (intel_rsu_update_address) + mailbox_rsu_update((uint32_t *)&intel_rsu_update_address); + else + mailbox_reset_cold(); while (1) wfi(); diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c index 41dae9e76..620126ea7 100644 --- a/plat/intel/soc/common/socfpga_sip_svc.c +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -365,6 +365,41 @@ uint32_t intel_secure_reg_update(uint64_t reg_addr, uint32_t mask, return INTEL_SIP_SMC_STATUS_ERROR; } +/* Intel Remote System Update (RSU) services */ +uint64_t intel_rsu_update_address; + +static uint32_t intel_rsu_status(uint64_t *respbuf, uint32_t respbuf_sz) +{ + if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) + return INTEL_SIP_SMC_STATUS_ERROR; + + return INTEL_SIP_SMC_STATUS_OK; +} + +static uint32_t intel_rsu_update(uint64_t update_address) +{ + intel_rsu_update_address = update_address; + return INTEL_SIP_SMC_STATUS_OK; +} + +static uint32_t intel_rsu_notify(uint64_t execution_stage) +{ + if (mailbox_hps_stage_notify((uint32_t)execution_stage) < 0) + return INTEL_SIP_SMC_STATUS_ERROR; + + return INTEL_SIP_SMC_STATUS_OK; +} + +static uint32_t intel_rsu_retry_counter(uint32_t *respbuf, uint32_t respbuf_sz, + uint32_t *ret_stat) +{ + if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) + return INTEL_SIP_SMC_STATUS_ERROR; + + *ret_stat = respbuf[8]; + return INTEL_SIP_SMC_STATUS_OK; +} + /* * This function is responsible for handling all SiP calls from the NS world */ @@ -381,6 +416,7 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, uint32_t val = 0; uint32_t status = INTEL_SIP_SMC_STATUS_OK; uint32_t completed_addr[3]; + uint64_t rsu_respbuf[9]; uint32_t count = 0; switch (smc_fid) { @@ -446,6 +482,33 @@ uintptr_t sip_smc_handler(uint32_t smc_fid, (uint32_t)x3, &val); SMC_RET3(handle, status, val, x1); + case INTEL_SIP_SMC_RSU_STATUS: + status = intel_rsu_status(rsu_respbuf, + ARRAY_SIZE(rsu_respbuf)); + if (status) { + SMC_RET1(handle, status); + } else { + SMC_RET4(handle, rsu_respbuf[0], rsu_respbuf[1], + rsu_respbuf[2], rsu_respbuf[3]); + } + + case INTEL_SIP_SMC_RSU_UPDATE: + status = intel_rsu_update(x1); + SMC_RET1(handle, status); + + case INTEL_SIP_SMC_RSU_NOTIFY: + status = intel_rsu_notify(x1); + SMC_RET1(handle, status); + + case INTEL_SIP_SMC_RSU_RETRY_COUNTER: + status = intel_rsu_retry_counter((uint32_t *)rsu_respbuf, + ARRAY_SIZE(rsu_respbuf), &val); + if (status) { + SMC_RET1(handle, status); + } else { + SMC_RET2(handle, status, val); + } + default: return socfpga_sip_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags); diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c index 29f57c467..4c3123815 100644 --- a/plat/intel/soc/stratix10/bl31_plat_setup.c +++ b/plat/intel/soc/stratix10/bl31_plat_setup.c @@ -16,6 +16,7 @@ #include #include +#include "socfpga_mailbox.h" #include "socfpga_private.h" #include "socfpga_reset_manager.h" #include "socfpga_system_manager.h" @@ -115,6 +116,8 @@ void bl31_platform_setup(void) /* Signal secondary CPUs to jump to BL31 (BL2 = U-boot SPL) */ mmio_write_64(PLAT_CPU_RELEASE_ADDR, (uint64_t)plat_secondary_cpus_bl31_entry); + + mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL); } const mmap_region_t plat_stratix10_mmap[] = {