
From: Richard Gong richard.gong@intel.com
Add Remote System Update (RSU) related mailbox support. This includes RSU_STATUS which reports status of bitstream loaded by Configuration Management Firmware (CMF), RSU_UPDATE which will invokes CMF to load new bitstream, GET_SUBPARTITION_TABLE which will query CMF on the start address of sub-partition table, HPS_STAGE_NOTIFY which notifies firmware the stage of HPS code execution and related functions to support Secure Monitor Call (SMC).
Signed-off-by: Ley Foon Tan ley.foon.tan@intel.com Signed-off-by: Chin Liang See chin.liang.see@intel.com Signed-off-by: Radu Bacrau radu.bacrau@intel.com Signed-off-by: Richard Gong richard.gong@intel.com --- arch/arm/mach-socfpga/include/mach/mailbox_s10.h | 36 ++++++++--- arch/arm/mach-socfpga/mailbox_s10.c | 79 ++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 10 deletions(-)
diff --git a/arch/arm/mach-socfpga/include/mach/mailbox_s10.h b/arch/arm/mach-socfpga/include/mach/mailbox_s10.h index ae728a5..979fd06 100644 --- a/arch/arm/mach-socfpga/include/mach/mailbox_s10.h +++ b/arch/arm/mach-socfpga/include/mach/mailbox_s10.h @@ -77,16 +77,20 @@ enum ALT_SDM_MBOX_RESP_CODE { };
/* Mailbox command list */ -#define MBOX_RESTART 2 -#define MBOX_CONFIG_STATUS 4 -#define MBOX_RECONFIG 6 -#define MBOX_RECONFIG_MSEL 7 -#define MBOX_RECONFIG_DATA 8 -#define MBOX_RECONFIG_STATUS 9 -#define MBOX_QSPI_OPEN 50 -#define MBOX_QSPI_CLOSE 51 -#define MBOX_QSPI_DIRECT 59 -#define MBOX_REBOOT_HPS 71 +#define MBOX_RESTART 2 +#define MBOX_CONFIG_STATUS 4 +#define MBOX_RECONFIG 6 +#define MBOX_RECONFIG_MSEL 7 +#define MBOX_RECONFIG_DATA 8 +#define MBOX_RECONFIG_STATUS 9 +#define MBOX_QSPI_OPEN 50 +#define MBOX_QSPI_CLOSE 51 +#define MBOX_QSPI_DIRECT 59 +#define MBOX_REBOOT_HPS 71 +#define MBOX_GET_SUBPARTITION_TABLE 90 +#define MBOX_RSU_STATUS 91 +#define MBOX_RSU_UPDATE 92 +#define MBOX_HPS_STAGE_NOTIFY 93
/* Mailbox registers */ #define MBOX_CIN 0 /* command valid offset */ @@ -130,6 +134,11 @@ enum ALT_SDM_MBOX_RESP_CODE { #define RCF_SOFTFUNC_STATUS_SEU_ERROR BIT(3) #define RCF_PIN_STATUS_NSTATUS BIT(31)
+/* Defines for HPS_STAGE_NOTIFY */ +#define HPS_EXECUTION_STATE_FSBL 0 +#define HPS_EXECUTION_STATE_SSBL 1 +#define HPS_EXECUTION_STATE_OS 2 + int mbox_send_cmd(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg, u8 urgent, u32 *resp_buf_len, u32 *resp_buf); int mbox_send_cmd_psci(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg, @@ -146,6 +155,13 @@ int mbox_qspi_open(void); #endif
int mbox_reset_cold(void); +int mbox_rsu_get_spt_offset(u32 *resp_buf, u32 resp_buf_len); +int mbox_rsu_status(u32 *resp_buf, u32 resp_buf_len); +int mbox_rsu_status_psci(u32 *resp_buf, u32 resp_buf_len); +int mbox_rsu_update(u32 *flash_offset); +int mbox_rsu_update_psci(u32 *flash_offset); +int mbox_hps_stage_notify(u32 execution_stage); +int mbox_hps_stage_notify_psci(u32 execution_stage); int mbox_get_fpga_config_status(u32 cmd); int mbox_get_fpga_config_status_psci(u32 cmd); #endif /* _MAILBOX_S10_H_ */ diff --git a/arch/arm/mach-socfpga/mailbox_s10.c b/arch/arm/mach-socfpga/mailbox_s10.c index 4498ab5..f7c0f1b 100644 --- a/arch/arm/mach-socfpga/mailbox_s10.c +++ b/arch/arm/mach-socfpga/mailbox_s10.c @@ -9,6 +9,7 @@ #include <asm/io.h> #include <asm/arch/mailbox_s10.h> #include <asm/arch/system_manager.h> +#include <intel/rsu.h> #include <asm/secure.h>
DECLARE_GLOBAL_DATA_PTR; @@ -342,6 +343,72 @@ int mbox_reset_cold(void) return 0; }
+int mbox_rsu_get_spt_offset(u32 *resp_buf, u32 resp_buf_len) +{ + return mbox_send_cmd(MBOX_ID_UBOOT, MBOX_GET_SUBPARTITION_TABLE, + MBOX_CMD_DIRECT, 0, NULL, 0, (u32 *)&resp_buf_len, + (u32 *)resp_buf); +} + +int mbox_rsu_status(u32 *resp_buf, u32 resp_buf_len) +{ + int ret; + struct rsu_status_info *info = (struct rsu_status_info *)resp_buf; + + info->retry_counter = -1; + + ret = mbox_send_cmd(MBOX_ID_UBOOT, MBOX_RSU_STATUS, MBOX_CMD_DIRECT, 0, + NULL, 0, (u32 *)&resp_buf_len, (u32 *)resp_buf); + + if (ret) + return ret; + + if (info->retry_counter != -1) + if (!RSU_VERSION_ACMF_VERSION(info->version)) + info->version |= FIELD_PREP(RSU_VERSION_ACMF_MASK, 1); + + return ret; +} + +int __secure mbox_rsu_status_psci(u32 *resp_buf, u32 resp_buf_len) +{ + int ret; + struct rsu_status_info *info = (struct rsu_status_info *)resp_buf; + int adjust = (resp_buf_len >= 9); + + if (adjust) + info->retry_counter = -1; + + ret = mbox_send_cmd_psci(MBOX_ID_UBOOT, MBOX_RSU_STATUS, + MBOX_CMD_DIRECT, 0, NULL, 0, + (u32 *)&resp_buf_len, (u32 *)resp_buf); + + if (ret) + return ret; + + if (!adjust) + return ret; + + if (info->retry_counter != -1) + if (!RSU_VERSION_ACMF_VERSION(info->version)) + info->version |= FIELD_PREP(RSU_VERSION_ACMF_MASK, 1); + + return ret; +} + +int mbox_rsu_update(u32 *flash_offset) +{ + return mbox_send_cmd(MBOX_ID_UBOOT, MBOX_RSU_UPDATE, MBOX_CMD_DIRECT, 2, + (u32 *)flash_offset, 0, 0, NULL); +} + +int __secure mbox_rsu_update_psci(u32 *flash_offset) +{ + return mbox_send_cmd_psci(MBOX_ID_UBOOT, MBOX_RSU_UPDATE, + MBOX_CMD_DIRECT, 2, (u32 *)flash_offset, + 0, 0, NULL); +} + /* Accepted commands: CONFIG_STATUS or RECONFIG_STATUS */ static __always_inline int mbox_get_fpga_config_status_common(u32 cmd) { @@ -380,6 +447,12 @@ static __always_inline int mbox_get_fpga_config_status_common(u32 cmd) return MBOX_CFGSTAT_STATE_CONFIG; }
+int __secure mbox_hps_stage_notify_psci(u32 execution_stage) +{ + return mbox_send_cmd_psci(MBOX_ID_UBOOT, MBOX_HPS_STAGE_NOTIFY, + MBOX_CMD_DIRECT, 1, &execution_stage, 0, 0, NULL); +} + int mbox_get_fpga_config_status(u32 cmd) { return mbox_get_fpga_config_status_common(cmd); @@ -405,6 +478,12 @@ int __secure mbox_send_cmd_psci(u8 id, u32 cmd, u8 is_indirect, u32 len, resp_buf_len, resp_buf); }
+int mbox_hps_stage_notify(u32 execution_stage) +{ + return mbox_send_cmd(MBOX_ID_UBOOT, MBOX_HPS_STAGE_NOTIFY, + MBOX_CMD_DIRECT, 1, &execution_stage, 0, 0, NULL); +} + int mbox_send_cmd_only(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg) { return mbox_send_cmd_only_common(id, cmd, is_indirect, len, arg);