feat(intel): implementation of SiPSVC-V3 protocol framework
- Develop SiPSVC-V3 framework to support async/yielding SMC calls.
- Add support for multi clients with multiple jobs running together.
- Add support for SDM doorbell interrupt handling.
- Keep the framework backward compatible with V1 clients.
- Enable the framework on all the platform Agilex7, Agilex5, N5X,
and Stratix10.
Change-Id: I9eb61c48be89867b4227e084493bfcf67cbe7924
Signed-off-by: Girisha Dengi <girisha.dengi@intel.com>
Signed-off-by: Sieu Mun Tang <sieu.mun.tang@altera.com>
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index e27af21..f965b7d 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2019-2023, Intel Corporation. All rights reserved.
- * Copyright (c) 2024, Altera Corporation. All rights reserved.
+ * Copyright (c) 2024-2025, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -23,20 +23,22 @@
#define MBOX_TEST_BIT BIT(31)
/* Mailbox Shared Memory Register Map */
-#define MBOX_CIN 0x00
-#define MBOX_ROUT 0x04
-#define MBOX_URG 0x08
-#define MBOX_INT 0x0C
-#define MBOX_COUT 0x20
-#define MBOX_RIN 0x24
-#define MBOX_STATUS 0x2C
-#define MBOX_CMD_BUFFER 0x40
-#define MBOX_RESP_BUFFER 0xC0
+#define MBOX_CIN 0x00 /* Command valid offset, to SDM */
+#define MBOX_ROUT 0x04 /* Response output offset, to SDM */
+#define MBOX_URG 0x08 /* Urgent command, to SDM */
+#define MBOX_INT 0x0C /* Interrupt enables, to SDM */
+/* 0x10 - 0x1F, Reserved */
-/* Mailbox SDM doorbell */
-#define MBOX_DOORBELL_TO_SDM 0x400
-#define MBOX_DOORBELL_FROM_SDM 0x480
+#define MBOX_COUT 0x20 /* Command free offset, from SDM */
+#define MBOX_RIN 0x24 /* Response valid offset, from SDM */
+#define MBOX_STATUS 0x2C /* Mailbox status from SDM to client */
+/* 0x30 - 0x3F, Reserved */
+#define MBOX_CMD_BUFFER 0x40 /* Circular buffer, cmds to SDM */
+#define MBOX_RESP_BUFFER 0xC0 /* Circular buffer, resp from SDM */
+
+#define MBOX_DOORBELL_TO_SDM 0x400 /* Doorbell from HPS to SDM */
+#define MBOX_DOORBELL_FROM_SDM 0x480 /* Doorbell from SDM to HPS */
/* Mailbox commands */
@@ -61,12 +63,15 @@
#define MBOX_HWMON_READVOLT 0x18
#define MBOX_HWMON_READTEMP 0x19
-
/* QSPI Commands */
#define MBOX_CMD_QSPI_OPEN 0x32
#define MBOX_CMD_QSPI_CLOSE 0x33
#define MBOX_CMD_QSPI_SET_CS 0x34
+#define MBOX_CMD_QSPI_ERASE 0x38
+#define MBOX_CMD_QSPI_WRITE 0x39
+#define MBOX_CMD_QSPI_READ 0x3A
#define MBOX_CMD_QSPI_DIRECT 0x3B
+#define MBOX_CMD_QSPI_GET_DEV_INFO 0x74
/* SEU Commands */
#define MBOX_CMD_SEU_ERR_READ 0x3C
@@ -94,12 +99,14 @@
#define MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY 0x87
#define MBOX_FCS_ECDSA_GET_PUBKEY 0x88
#define MBOX_FCS_ECDH_REQUEST 0x89
+#define MBOX_FCS_HKDF_REQUEST 0x8B
#define MBOX_FCS_OPEN_CS_SESSION 0xA0
#define MBOX_FCS_CLOSE_CS_SESSION 0xA1
#define MBOX_FCS_IMPORT_CS_KEY 0xA5
#define MBOX_FCS_EXPORT_CS_KEY 0xA6
#define MBOX_FCS_REMOVE_CS_KEY 0xA7
#define MBOX_FCS_GET_CS_KEY_INFO 0xA8
+#define MBOX_FCS_CREATE_CS_KEY 0xA9
/* PSG SIGMA Commands */
#define MBOX_PSG_SIGMA_TEARDOWN 0xD5
@@ -111,7 +118,9 @@
#define MBOX_GET_MEASUREMENT 0x183
/* Miscellaneous commands */
+#define MBOX_CMD_MCTP_MSG 0x194
#define MBOX_GET_ROM_PATCH_SHA384 0x1B0
+#define MBOX_CMD_GET_DEVICEID 0x500
/* Mailbox Definitions */
@@ -120,6 +129,18 @@
#define CMD_CASUAL 0
#define CMD_URGENT 1
+/* Mailbox command flags and related macros */
+#define MBOX_CMD_FLAG_DIRECT BIT(0)
+#define MBOX_CMD_FLAG_INDIRECT BIT(1)
+#define MBOX_CMD_FLAG_CASUAL BIT(2)
+#define MBOX_CMD_FLAG_URGENT BIT(3)
+
+#define MBOX_CMD_FLAG_CASUAL_INDIRECT (MBOX_CMD_FLAG_CASUAL | \
+ MBOX_CMD_FLAG_INDIRECT)
+
+#define IS_CMD_SET(cmd, _type) ((((cmd) & MBOX_CMD_FLAG_##_type) != 0) ? \
+ 1 : 0)
+
#define MBOX_WORD_BYTE 4U
#define MBOX_RESP_BUFFER_SIZE 16
#define MBOX_CMD_BUFFER_SIZE 32
@@ -171,22 +192,25 @@
+ MBOX_WORD_BYTE * (ptr))
/* Mailbox interrupt flags and masks */
-#define MBOX_INT_FLAG_COE 0x1
-#define MBOX_INT_FLAG_RIE 0x2
-#define MBOX_INT_FLAG_UAE 0x100
-#define MBOX_COE_BIT(INTERRUPT) ((INTERRUPT) & 0x3)
-#define MBOX_UAE_BIT(INTERRUPT) (((INTERRUPT) & (1<<8)))
+#define MBOX_INT_FLAG_COE BIT(0) /* COUT update interrupt enable */
+#define MBOX_INT_FLAG_RIE BIT(1) /* RIN update interrupt enable */
+#define MBOX_INT_FLAG_UAE BIT(8) /* Urgent ACK interrupt enable */
+
+#define MBOX_COE_BIT(INTERRUPT) ((INTERRUPT) & MBOX_INT_FLAG_COE)
+#define MBOX_RIE_BIT(INTERRUPT) ((INTERRUPT) & MBOX_INT_FLAG_RIE)
+#define MBOX_UAE_BIT(INTERRUPT) ((INTERRUPT) & MBOX_INT_FLAG_UAE)
/* Mailbox response and status */
#define MBOX_RESP_ERR(BUFFER) ((BUFFER) & 0x000007ff)
#define MBOX_RESP_LEN(BUFFER) (((BUFFER) & 0x007ff000) >> 12)
#define MBOX_RESP_CLIENT_ID(BUFFER) (((BUFFER) & 0xf0000000) >> 28)
#define MBOX_RESP_JOB_ID(BUFFER) (((BUFFER) & 0x0f000000) >> 24)
+#define MBOX_RESP_TRANSACTION_ID(BUFFER) (((BUFFER) & 0xff000000) >> 24)
#define MBOX_STATUS_UA_MASK (1<<8)
/* Mailbox command and response */
#define MBOX_CLIENT_ID_CMD(CLIENT_ID) ((CLIENT_ID) << 28)
-#define MBOX_JOB_ID_CMD(JOB_ID) (JOB_ID<<24)
+#define MBOX_JOB_ID_CMD(JOB_ID) (JOB_ID << 24)
#define MBOX_CMD_LEN_CMD(CMD_LEN) ((CMD_LEN) << 12)
#define MBOX_INDIRECT(val) ((val) << 11)
#define MBOX_CMD_MASK(header) ((header) & 0x7ff)
@@ -204,6 +228,17 @@
#define CONFIG_STATUS_FW_VER_OFFSET 1
#define CONFIG_STATUS_FW_VER_MASK 0x00FFFFFF
+/* QSPI mailbox command macros */
+#define MBOX_QSPI_SET_CS_OFFSET (28)
+#define MBOX_QSPI_SET_CS_MODE_OFFSET (27)
+#define MBOX_QSPI_SET_CS_CA_OFFSET (26)
+#define MBOX_QSPI_ERASE_SIZE_GRAN (0x400)
+
+#define MBOX_4K_ALIGNED_MASK (0xFFF)
+#define MBOX_IS_4K_ALIGNED(x) ((x) & MBOX_4K_ALIGNED_MASK)
+#define MBOX_IS_WORD_ALIGNED(x) (!((x) & 0x3))
+#define MBOX_QSPI_RW_MAX_WORDS (0x1000)
+
/* Data structure */
typedef struct mailbox_payload {
@@ -264,4 +299,107 @@
int mailbox_send_fpga_config_comp(void);
+#if SIP_SVC_V3
+#define MBOX_CLIENT_ID_SHIFT (28)
+#define MBOX_JOB_ID_SHIFT (24)
+#define MBOX_CMD_LEN_SHIFT (12)
+#define MBOX_INDIRECT_SHIFT (11)
+
+#define MBOX_FRAME_CMD_HEADER(client_id, job_id, args_len, indirect, cmd)\
+ ((client_id << MBOX_CLIENT_ID_SHIFT) | \
+ (job_id << MBOX_JOB_ID_SHIFT) | \
+ (args_len << MBOX_CMD_LEN_SHIFT) | \
+ (indirect << MBOX_CMD_LEN_SHIFT) | \
+ cmd)
+
+#define FLAG_SDM_RESPONSE_IS_VALID BIT(0)
+#define FLAG_SDM_RESPONSE_IS_USED BIT(1)
+#define FLAG_SDM_RESPONSE_IS_IN_PROGRESS BIT(2)
+#define FLAG_SDM_RESPONSE_IS_POLL_ON_INTR BIT(3)
+
+/*
+ * TODO: Re-visit this queue size based on the system load.
+ * 4 bits for client ID and 4 bits for job ID, total 8 bits and we can have up to
+ * 256 transactions. We can tune this based on our system load at any given time
+ */
+#define MBOX_SVC_CMD_QUEUE_SIZE (32)
+#define MBOX_SVC_RESP_QUEUE_SIZE (32)
+#define MBOX_SVC_MAX_JOB_ID (16)
+#define MBOX_SVC_CMD_ARG_SIZE (2)
+#define MBOX_SVC_CMD_IS_USED BIT(0)
+#define MBOX_SVC_CMD_CB_ARGS_SIZE (4)
+#define MBOX_SVC_MAX_CLIENTS (16)
+#define MBOX_SVC_MAX_RESP_DATA_SIZE (32)
+#define MBOX_SVC_SMC_RET_MAX_SIZE (8)
+
+/* Client ID(4bits) + Job ID(4bits) = Transcation ID(TID - 8bits, 256 combinations) */
+#define MBOX_MAX_TIDS (256)
+/* Each transcation ID bitmap holds 64bits */
+#define MBOX_TID_BITMAP_SIZE (sizeof(uint64_t) * 8)
+/* Number of transcation ID bitmaps required to hold 256 combinations */
+#define MBOX_MAX_TIDS_BITMAP (MBOX_MAX_TIDS / MBOX_TID_BITMAP_SIZE)
+
+/* SDM Response State (SRS) enums */
+typedef enum sdm_resp_state {
+ SRS_WAIT_FOR_RESP = 0x00U,
+ SRS_WAIT_FOR_HEADER,
+ SRS_WAIT_FOR_ARGUMENTS,
+ SRS_SYNC_ERROR
+} sdm_resp_state_t;
+
+/* SDM response data structure */
+typedef struct sdm_response {
+ bool is_poll_intr;
+ uint8_t client_id;
+ uint8_t job_id;
+ uint16_t resp_len;
+ uint16_t err_code;
+ uint32_t flags;
+ uint32_t header;
+ uint16_t rcvd_resp_len;
+ uint32_t resp_data[MBOX_SVC_MAX_RESP_DATA_SIZE];
+} sdm_response_t;
+
+/* SDM client callback template */
+typedef uint8_t (*sdm_command_callback)(void *resp, void *cmd,
+ uint32_t *ret_args);
+
+/* SDM command data structure */
+typedef struct sdm_command {
+ uint8_t client_id;
+ uint8_t job_id;
+ uint32_t flags;
+ sdm_command_callback cb;
+ uint32_t *cb_args;
+ uint8_t cb_args_len;
+} sdm_command_t;
+
+/* Get the transcation ID from client ID and job ID. */
+#define MBOX_GET_TRANS_ID(cid, jib) (((cid) << 4) | (jib))
+
+/* Mailbox service data structure */
+typedef struct mailbox_service {
+ sdm_resp_state_t resp_state;
+ sdm_resp_state_t next_resp_state;
+ uint32_t flags;
+ int curr_di;
+ uint64_t received_bitmap[MBOX_MAX_TIDS_BITMAP];
+ uint64_t interrupt_bitmap[MBOX_MAX_TIDS_BITMAP];
+ sdm_command_t cmd_queue[MBOX_SVC_CMD_QUEUE_SIZE];
+ sdm_response_t resp_queue[MBOX_SVC_RESP_QUEUE_SIZE];
+} mailbox_service_t;
+
+int mailbox_send_cmd_async_v3(uint8_t client_id, uint8_t job_id, uint32_t cmd,
+ uint32_t *args, uint32_t args_len, uint8_t cmd_flag,
+ sdm_command_callback cb, uint32_t *cb_args,
+ uint32_t cb_args_len);
+
+int mailbox_response_poll_v3(uint8_t client_id, uint8_t job_id, uint32_t *ret_args,
+ uint32_t *ret_args_size);
+
+int mailbox_response_poll_on_intr_v3(uint8_t *client_id, uint8_t *job_id,
+ uint64_t *bitmap);
+
+#endif /* #if SIP_SVC_V3 */
+
#endif /* SOCFPGA_MBOX_H */