Merge changes I1dfb95aa,I9eb61c48 into integration

* changes:
  feat(intel): support FCS commands with SiPSVC V3 framework
  feat(intel): implementation of SiPSVC-V3 protocol framework
This commit is contained in:
Yann Gautier 2025-03-31 19:16:19 +02:00 committed by TrustedFirmware Code Review
commit e86efe4b14
11 changed files with 2709 additions and 199 deletions

View file

@ -1,7 +1,7 @@
/*
* Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2019-2022, 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
*/
@ -175,6 +175,16 @@ void bl31_platform_setup(void)
mmio_write_64(PLAT_CPU_RELEASE_ADDR,
(uint64_t)plat_secondary_cpus_bl31_entry);
#if SIP_SVC_V3
/*
* Re-initialize the mailbox to include V3 specific routines.
* In V3, this re-initialize is required because prior to BL31, U-Boot
* SPL has its own mailbox settings and this initialization will
* override to those settings as required by the V3 framework.
*/
mailbox_init();
#endif
mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
}

View file

@ -177,6 +177,17 @@ void bl31_platform_setup(void)
gicv3_distif_init();
gicv3_rdistif_init(plat_my_core_pos());
gicv3_cpuif_enable(plat_my_core_pos());
#if SIP_SVC_V3
/*
* Re-initialize the mailbox to include V3 specific routines.
* In V3, this re-initialize is required because prior to BL31, U-Boot
* SPL has its own mailbox settings and this initialization will
* override to those settings as required by the V3 framework.
*/
mailbox_init();
#endif
mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
}

View file

@ -1,7 +1,7 @@
/*
* Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
* 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
*/
@ -207,6 +207,9 @@
#define MAX_IO_DEVICES 4
#define MAX_IO_BLOCK_DEVICES 2
/* Define this, to support the SiPSVC V3 implementation. */
#define SIP_SVC_V3 1
#ifndef __ASSEMBLER__
struct socfpga_bl31_params {
param_header_t h;

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
* Copyright (c) 2025, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -88,12 +89,22 @@
#define FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE 52U
#define FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE 29U
#define FCS_CRYPTO_ECB_BUFFER_SIZE 12U
#define FCS_CRYPTO_CBC_CTR_BUFFER_SIZE 28U
#define FCS_CRYPTO_BLOCK_MODE_MASK 0x07
#define FCS_CRYPTO_ECB_MODE 0x00
#define FCS_CRYPTO_CBC_MODE 0x01
#define FCS_CRYPTO_CTR_MODE 0x02
#define FCS_CRYPTO_ECB_BUFFER_SIZE 12U
#define FCS_CRYPTO_CBC_CTR_BUFFER_SIZE 28U
#define FCS_CRYPTO_BLOCK_MODE_MASK 0x07
#define FCS_CRYPTO_ECB_MODE 0x00
#define FCS_CRYPTO_CBC_MODE 0x01
#define FCS_CRYPTO_CTR_MODE 0x02
#define FCS_CRYPTO_GCM_MODE 0x03
#define FCS_CRYPTO_GCM_GHASH_MODE 0x04
#define FCS_HKDF_REQUEST_DATA_SIZE 512U
#define FCS_HKDF_KEY_OBJ_MAX_SIZE 352U
#define FCS_HKDF_KEY_DATA_SIZE 168U
#define FCS_HKDF_STEP0_1_KEY_OBJ_SIZE_BITS 384U
#define FCS_HKDF_STEP2_KEY_OBJ_SIZE_BITS 256U
#define FCS_HKDF_INPUT_BLOCK_SIZE 80U
#define FCS_HKDF_SHA2_384_KEY_DATA_SIZE 48U
/* FCS Payload Structure */
typedef struct fcs_rng_payload_t {
@ -183,10 +194,12 @@ uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size,
uint32_t *mbox_error);
int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id,
uint32_t size, uint32_t *send_id);
uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size,
uint32_t intel_fcs_send_cert(uint32_t smc_fid, uint32_t trans_id,
uint64_t addr, uint64_t size,
uint32_t *send_id);
uint32_t intel_fcs_get_provision_data(uint32_t *send_id);
uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type,
uint32_t intel_fcs_cntr_set_preauth(uint32_t smc_fid, uint32_t trans_id,
uint8_t counter_type,
int32_t counter_value,
uint32_t test_bit,
uint32_t *mbox_error);
@ -198,14 +211,18 @@ uint32_t intel_fcs_decryption(uint32_t src_addr, uint32_t src_size,
uint32_t dst_addr, uint32_t dst_size,
uint32_t *send_id);
int intel_fcs_encryption_ext(uint32_t session_id, uint32_t context_id,
int intel_fcs_encryption_ext(uint32_t smc_fid, uint32_t trans_id,
uint32_t session_id, uint32_t context_id,
uint32_t src_addr, uint32_t src_size,
uint32_t dst_addr, uint32_t *dst_size,
uint32_t *mbox_error);
int intel_fcs_decryption_ext(uint32_t sesion_id, uint32_t context_id,
uint32_t *mbox_error, uint32_t smmu_src_addr,
uint32_t smmu_dst_addr);
int intel_fcs_decryption_ext(uint32_t smc_fid, uint32_t trans_id,
uint32_t sesion_id, uint32_t context_id,
uint32_t src_addr, uint32_t src_size,
uint32_t dst_addr, uint32_t *dst_size,
uint32_t *mbox_error);
uint32_t *mbox_error, uint64_t owner_id,
uint32_t smmu_src_addr, uint32_t smmu_dst_addr);
int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error);
int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error);
@ -218,9 +235,10 @@ int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size,
uint32_t intel_fcs_get_rom_patch_sha384(uint64_t addr, uint64_t *ret_size,
uint32_t *mbox_error);
int intel_fcs_create_cert_on_reload(uint32_t cert_request,
uint32_t *mbox_error);
int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr,
int intel_fcs_create_cert_on_reload(uint32_t smc_fid, uint32_t trans_id,
uint32_t cert_request, uint32_t *mbox_error);
int intel_fcs_get_attestation_cert(uint32_t smc_fid, uint32_t trans_id,
uint32_t cert_request, uint64_t dst_addr,
uint32_t *dst_size, uint32_t *mbox_error);
int intel_fcs_open_crypto_service_session(uint32_t *session_id,
@ -242,10 +260,12 @@ int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id,
int intel_fcs_get_digest_init(uint32_t session_id, uint32_t context_id,
uint32_t key_id, uint32_t param_size,
uint64_t param_data, uint32_t *mbox_error);
int intel_fcs_get_digest_update_finalize(uint32_t session_id, uint32_t context_id,
int intel_fcs_get_digest_update_finalize(uint32_t smc_fid, uint32_t trans_id,
uint32_t session_id, uint32_t context_id,
uint32_t src_addr, uint32_t src_size,
uint64_t dst_addr, uint32_t *dst_size,
uint8_t is_finalised, uint32_t *mbox_error);
uint8_t is_finalised, uint32_t *mbox_error,
uint32_t smmu_src_addr);
int intel_fcs_get_digest_smmu_update_finalize(uint32_t session_id, uint32_t context_id,
uint32_t src_addr, uint32_t src_size,
uint64_t dst_addr, uint32_t *dst_size,
@ -255,11 +275,12 @@ int intel_fcs_get_digest_smmu_update_finalize(uint32_t session_id, uint32_t cont
int intel_fcs_mac_verify_init(uint32_t session_id, uint32_t context_id,
uint32_t key_id, uint32_t param_size,
uint64_t param_data, uint32_t *mbox_error);
int intel_fcs_mac_verify_update_finalize(uint32_t session_id, uint32_t context_id,
int intel_fcs_mac_verify_update_finalize(uint32_t smc_fid, uint32_t trans_id,
uint32_t session_id, uint32_t context_id,
uint32_t src_addr, uint32_t src_size,
uint64_t dst_addr, uint32_t *dst_size,
uint32_t data_size, uint8_t is_finalised,
uint32_t *mbox_error);
uint32_t *mbox_error, uint64_t smmu_src_addr);
int intel_fcs_mac_verify_smmu_update_finalize(uint32_t session_id, uint32_t context_id,
uint32_t src_addr, uint32_t src_size,
uint64_t dst_addr, uint32_t *dst_size,
@ -269,7 +290,8 @@ int intel_fcs_mac_verify_smmu_update_finalize(uint32_t session_id, uint32_t cont
int intel_fcs_ecdsa_hash_sign_init(uint32_t session_id, uint32_t context_id,
uint32_t key_id, uint32_t param_size,
uint64_t param_data, uint32_t *mbox_error);
int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id,
int intel_fcs_ecdsa_hash_sign_finalize(uint32_t smc_fid, uint32_t trans_id,
uint32_t session_id, uint32_t context_id,
uint32_t src_addr, uint32_t src_size,
uint64_t dst_addr, uint32_t *dst_size,
uint32_t *mbox_error);
@ -277,7 +299,8 @@ int intel_fcs_ecdsa_hash_sign_finalize(uint32_t session_id, uint32_t context_id,
int intel_fcs_ecdsa_hash_sig_verify_init(uint32_t session_id, uint32_t context_id,
uint32_t key_id, uint32_t param_size,
uint64_t param_data, uint32_t *mbox_error);
int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t session_id, uint32_t context_id,
int intel_fcs_ecdsa_hash_sig_verify_finalize(uint32_t smc_fid, uint32_t trans_id,
uint32_t session_id, uint32_t context_id,
uint32_t src_addr, uint32_t src_size,
uint64_t dst_addr, uint32_t *dst_size,
uint32_t *mbox_error);
@ -286,11 +309,12 @@ int intel_fcs_ecdsa_sha2_data_sign_init(uint32_t session_id,
uint32_t context_id, uint32_t key_id,
uint32_t param_size, uint64_t param_data,
uint32_t *mbox_error);
int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t session_id,
uint32_t context_id, uint32_t src_addr,
uint32_t src_size, uint64_t dst_addr,
uint32_t *dst_size, uint8_t is_finalised,
uint32_t *mbox_error);
int intel_fcs_ecdsa_sha2_data_sign_update_finalize(uint32_t smc_fid, uint32_t trans_id,
uint32_t session_id, uint32_t context_id,
uint32_t src_addr, uint32_t src_size,
uint64_t dst_addr, uint32_t *dst_size,
uint8_t is_finalised, uint32_t *mbox_error,
uint64_t smmu_src_addr);
int intel_fcs_ecdsa_sha2_data_sign_smmu_update_finalize(uint32_t session_id,
uint32_t context_id, uint32_t src_addr,
uint32_t src_size, uint64_t dst_addr,
@ -301,11 +325,12 @@ int intel_fcs_ecdsa_sha2_data_sig_verify_init(uint32_t session_id,
uint32_t context_id, uint32_t key_id,
uint32_t param_size, uint64_t param_data,
uint32_t *mbox_error);
int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t session_id,
uint32_t context_id, uint32_t src_addr,
uint32_t src_size, uint64_t dst_addr,
uint32_t *dst_size, uint32_t data_size,
uint8_t is_finalised, uint32_t *mbox_error);
int intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(uint32_t smc_fid, uint32_t trans_id,
uint32_t session_id, uint32_t context_id,
uint32_t src_addr, uint32_t src_size,
uint64_t dst_addr, uint32_t *dst_size,
uint32_t data_size, uint8_t is_finalised,
uint32_t *mbox_error, uint64_t smmu_src_addr);
int intel_fcs_ecdsa_sha2_data_sig_verify_smmu_update_finalize(uint32_t session_id,
uint32_t context_id, uint32_t src_addr,
uint32_t src_size, uint64_t dst_addr,
@ -316,14 +341,16 @@ int intel_fcs_ecdsa_sha2_data_sig_verify_smmu_update_finalize(uint32_t session_i
int intel_fcs_ecdsa_get_pubkey_init(uint32_t session_id, uint32_t context_id,
uint32_t key_id, uint32_t param_size,
uint64_t param_data, uint32_t *mbox_error);
int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id,
int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t smc_fid, uint32_t trans_id,
uint32_t session_id, uint32_t context_id,
uint64_t dst_addr, uint32_t *dst_size,
uint32_t *mbox_error);
int intel_fcs_ecdh_request_init(uint32_t session_id, uint32_t context_id,
uint32_t key_id, uint32_t param_size,
uint64_t param_data, uint32_t *mbox_error);
int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id,
int intel_fcs_ecdh_request_finalize(uint32_t smc_fid, uint32_t trans_id,
uint32_t session_id, uint32_t context_id,
uint32_t src_addr, uint32_t src_size,
uint64_t dst_addr, uint32_t *dst_size,
uint32_t *mbox_error);
@ -331,10 +358,16 @@ int intel_fcs_ecdh_request_finalize(uint32_t session_id, uint32_t context_id,
int intel_fcs_aes_crypt_init(uint32_t session_id, uint32_t context_id,
uint32_t key_id, uint64_t param_addr,
uint32_t param_size, uint32_t *mbox_error);
int intel_fcs_aes_crypt_update_finalize(uint32_t session_id,
uint32_t context_id, uint64_t src_addr,
uint32_t src_size, uint64_t dst_addr,
uint32_t dst_size, uint8_t is_finalised,
uint32_t *send_id);
int intel_fcs_aes_crypt_update_finalize(uint32_t smc_fid, uint32_t trans_id,
uint32_t session_id, uint32_t context_id,
uint64_t src_addr, uint32_t src_size,
uint64_t dst_addr, uint32_t dst_size,
uint32_t aad_size, uint8_t is_finalised,
uint32_t *send_id, uint64_t smmu_src_addr,
uint64_t smmu_dst_addr);
int intel_fcs_hkdf_request(uint32_t smc_fid, uint32_t trans_id,
uint32_t session_id, uint32_t step_type,
uint32_t mac_mode, uint32_t src_addr,
uint32_t key_uid, uint32_t op_key_size);
#endif /* SOCFPGA_FCS_H */

View file

@ -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_safe_inject_seu_err(uint32_t *arg, unsigned int len);
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 */

View file

@ -26,6 +26,10 @@
#define INTEL_SIP_SMC_CMD_V2_RANGE_BEGIN 0x400
#define INTEL_SIP_SMC_CMD_V2_RANGE_END 0x4FF
/* SiP V3 command code range */
#define INTEL_SIP_SMC_CMD_V3_RANGE_BEGIN 0x00C8
#define INTEL_SIP_SMC_CMD_V3_RANGE_END 0x01F4
/* SiP V2 protocol header */
#define INTEL_SIP_SMC_HEADER_JOB_ID_MASK 0xF
#define INTEL_SIP_SMC_HEADER_JOB_ID_OFFSET 0U
@ -189,11 +193,11 @@
/*
* Increase if there is any backward compatibility impact
*/
#define SIP_SVC_VERSION_MAJOR 2
#define SIP_SVC_VERSION_MAJOR 3
/*
* Increase if there is new SMC function ID being added
*/
#define SIP_SVC_VERSION_MINOR 2
#define SIP_SVC_VERSION_MINOR 1
/* Structure Definitions */
@ -243,4 +247,103 @@ uintptr_t sip_smc_handler_v2(uint32_t smc_fid,
void *handle,
u_register_t flags);
#if SIP_SVC_V3
#define SMC_RET_ARGS_ONE (1)
#define SMC_RET_ARGS_TWO (2)
#define SMC_RET_ARGS_THREE (3)
#define SMC_RET_ARGS_FOUR (4)
#define SMC_RET_ARGS_FIVE (5)
#define SMC_RET_ARGS_SIX (6)
/*
* SiP SVC Version3 SMC Functions IDs
*/
/* Generic response POLL commands */
#define ALTERA_SIP_SMC_ASYNC_RESP_POLL (0x420000C8)
#define ALTERA_SIP_SMC_ASYNC_RESP_POLL_ON_INTR (0x420000C9)
/* QSPI related commands */
#define ALTERA_SIP_SMC_ASYNC_QSPI_OPEN (0x420000CC)
#define ALTERA_SIP_SMC_ASYNC_QSPI_CLOSE (0x420000CD)
#define ALTERA_SIP_SMC_ASYNC_QSPI_SET_CS (0x420000CE)
#define ALTERA_SIP_SMC_ASYNC_QSPI_ERASE (0x420000CF)
#define ALTERA_SIP_SMC_ASYNC_QSPI_WRITE (0x420000D0)
#define ALTERA_SIP_SMC_ASYNC_QSPI_READ (0x420000D1)
#define ALTERA_SIP_SMC_ASYNC_GET_DEVICE_IDENTITY (0x420000D2)
#define ALTERA_SIP_SMC_ASYNC_GET_IDCODE (0x420000D3)
#define ALTERA_SIP_SMC_ASYNC_QSPI_GET_DEV_INFO (0x420000D4)
#define ALTERA_SIP_SMC_ASYNC_HWMON_READTEMP (0x420000E8)
#define ALTERA_SIP_SMC_ASYNC_HWMON_READVOLT (0x420000E9)
/* FCS crypto service VAB/SDOS commands */
#define ALTERA_SIP_SMC_ASYNC_FCS_RANDOM_NUMBER (0x4200012C)
#define ALTERA_SIP_SMC_ASYNC_FCS_RANDOM_NUMBER_EXT (0x4200012D)
#define ALTERA_SIP_SMC_ASYNC_FCS_CRYPTION (0x4200012E)
#define ALTERA_SIP_SMC_ASYNC_FCS_CRYPTION_EXT (0x4200012F)
#define ALTERA_SIP_SMC_ASYNC_FCS_SERVICE_REQUEST (0x42000130)
#define ALTERA_SIP_SMC_ASYNC_FCS_SEND_CERTIFICATE (0x42000131)
#define ALTERA_SIP_SMC_ASYNC_FCS_GET_PROVISION_DATA (0x42000132)
#define ALTERA_SIP_SMC_ASYNC_FCS_CNTR_SET_PREAUTH (0x42000133)
#define ALTERA_SIP_SMC_ASYNC_FCS_PSGSIGMA_TEARDOWN (0x42000134)
#define ALTERA_SIP_SMC_ASYNC_FCS_CHIP_ID (0x42000135)
#define ALTERA_SIP_SMC_ASYNC_FCS_ATTESTATION_SUBKEY (0x42000136)
#define ALTERA_SIP_SMC_ASYNC_FCS_ATTESTATION_MEASUREMENTS (0x42000137)
#define ALTERA_SIP_SMC_ASYNC_FCS_GET_ATTESTATION_CERT (0x42000138)
#define ALTERA_SIP_SMC_ASYNC_FCS_CREATE_CERT_ON_RELOAD (0x42000139)
/* FCS crypto service session management commands */
#define ALTERA_SIP_SMC_ASYNC_FCS_OPEN_CS_SESSION (0x4200013A)
#define ALTERA_SIP_SMC_ASYNC_FCS_CLOSE_CS_SESSION (0x4200013B)
/* FCS crypto service key management commands */
#define ALTERA_SIP_SMC_ASYNC_FCS_IMPORT_CS_KEY (0x4200013C)
#define ALTERA_SIP_SMC_ASYNC_FCS_EXPORT_CS_KEY (0x4200013D)
#define ALTERA_SIP_SMC_ASYNC_FCS_REMOVE_CS_KEY (0x4200013E)
#define ALTERA_SIP_SMC_ASYNC_FCS_GET_CS_KEY_INFO (0x4200013F)
#define ALTERA_SIP_SMC_ASYNC_FCS_CREATE_CS_KEY (0x42000167)
/* FCS crypto service primitive commands */
#define ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_INIT (0x42000140)
#define ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_UPDATE (0x42000141)
#define ALTERA_SIP_SMC_ASYNC_FCS_AES_CRYPT_FINALIZE (0x42000142)
#define ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_INIT (0x42000143)
#define ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_UPDATE (0x42000144)
#define ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_FINALIZE (0x42000145)
#define ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_SMMU_UPDATE (0x42000146)
#define ALTERA_SIP_SMC_ASYNC_FCS_GET_DIGEST_SMMU_FINALIZE (0x42000147)
#define ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_INIT (0x42000148)
#define ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_UPDATE (0x42000149)
#define ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_FINALIZE (0x4200014A)
#define ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_SMMU_UPDATE (0x4200014B)
#define ALTERA_SIP_SMC_ASYNC_FCS_MAC_VERIFY_SMMU_FINALIZE (0x4200014C)
#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIGN_INIT (0x4200014D)
#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIGN_FINALIZE (0x4200014E)
#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_INIT (0x4200014F)
#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_UPDATE (0x42000150)
#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE (0x42000151)
#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_SMMU_UPDATE (0x42000152)
#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIGN_SMMU_FINALIZE (0x42000153)
#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIG_VERIFY_INIT (0x42000154)
#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_HASH_SIG_VERIFY_FINALIZE (0x42000155)
#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_INIT (0x42000156)
#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_UPDATE (0x42000157)
#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_FINALIZE (0x42000158)
#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_SMMU_UPDATE (0x42000159)
#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_SMMU_FINALIZE (0x4200015A)
#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_GET_PUBKEY_INIT (0x42000160)
#define ALTERA_SIP_SMC_ASYNC_FCS_ECDSA_GET_PUBKEY_FINALIZE (0x42000161)
#define ALTERA_SIP_SMC_ASYNC_FCS_ECDH_REQUEST_INIT (0x42000162)
#define ALTERA_SIP_SMC_ASYNC_FCS_ECDH_REQUEST_FINALIZE (0x42000163)
#define ALTERA_SIP_SMC_ASYNC_FCS_SDM_REMAPPER_CONFIG (0x42000164)
#define ALTERA_SIP_SMC_ASYNC_MCTP_MSG (0x42000165)
#define ALTERA_SIP_SMC_ASYNC_FCS_HKDF_REQUEST (0x42000166)
#define ALTERA_SIP_SMC_ASYNC_FCS_CREATE_CS_KEY (0x42000167)
#define GET_CLIENT_ID(x) (((x) & 0xF0) >> 4)
#define GET_JOB_ID(x) ((x) & 0x0F)
#endif /* SIP_SVC_V3 */
#endif /* SOCFPGA_SIP_SVC_H */

File diff suppressed because it is too large Load diff

View file

@ -1,11 +1,12 @@
/*
* Copyright (c) 2020-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
*/
#include <lib/mmio.h>
#include <lib/spinlock.h>
#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <platform_def.h>
@ -15,6 +16,34 @@
#include "socfpga_sip_svc.h"
#include "socfpga_system_manager.h"
#if SIP_SVC_V3
/* Function prototypes */
void mailbox_init_v3(void);
static int mailbox_response_handler_fsm(void);
static inline void mailbox_free_cmd_desc(sdm_command_t *cmd_desc);
static sdm_response_t *mailbox_get_resp_desc(uint8_t client_id, uint8_t job_id,
uint8_t *index);
static sdm_command_t *mailbox_get_cmd_desc(uint8_t client_id, uint8_t job_id);
static inline void mailbox_free_resp_desc(uint8_t index);
static sdm_command_t *mailbox_get_free_cmd_desc(void);
static sdm_response_t *mailbox_get_resp_desc_cid(uint8_t client_id,
uint8_t *index);
static int mailbox_read_response_v3(uint8_t client_id, uint8_t *job_id,
uint32_t *header, uint32_t *resp,
uint32_t *resp_len,
uint8_t ignore_client_id);
static int mailbox_poll_response_v3(uint8_t client_id, uint8_t job_id,
uint32_t *resp, unsigned int *resp_len,
uint32_t urgent);
static spinlock_t mbox_db_lock; /* Mailbox service data base lock */
static spinlock_t mbox_write_lock; /* Hardware mailbox FIFO write lock */
static spinlock_t mbox_read_lock; /* Hardware mailbox FIFO read lock */
static mailbox_service_t mbox_svc; /* Mailbox service data base */
static uint8_t async_v1_job_id;
#endif /* #if SIP_SVC_V3 */
static mailbox_payload_t mailbox_resp_payload;
static mailbox_container_t mailbox_resp_ctr = {0, 0, &mailbox_resp_payload};
@ -34,13 +63,13 @@ static bool is_mailbox_cmdbuf_empty(uint32_t cin)
static int wait_for_mailbox_cmdbuf_empty(uint32_t cin)
{
unsigned int timeout = 200U;
unsigned int timeout = 20000U;
do {
if (is_mailbox_cmdbuf_empty(cin)) {
break;
}
mdelay(10U);
udelay(50U);
} while (--timeout != 0U);
if (timeout == 0U) {
@ -54,7 +83,9 @@ static int write_mailbox_cmd_buffer(uint32_t *cin, uint32_t cout,
uint32_t data,
bool *is_doorbell_triggered)
{
unsigned int timeout = 100U;
unsigned int timeout = 20000U;
VERBOSE("MBOX: 0x%x\n", data);
do {
if (is_mailbox_cmdbuf_full(*cin)) {
@ -63,7 +94,7 @@ static int write_mailbox_cmd_buffer(uint32_t *cin, uint32_t cout,
MBOX_DOORBELL_TO_SDM, 1U);
*is_doorbell_triggered = true;
}
mdelay(10U);
udelay(50U);
} else {
mmio_write_32(MBOX_ENTRY_TO_ADDR(CMD, (*cin)++), data);
*cin %= MBOX_CMD_BUFFER_SIZE;
@ -84,6 +115,11 @@ static int write_mailbox_cmd_buffer(uint32_t *cin, uint32_t cout,
return MBOX_RET_OK;
}
/*
* Function description: Write the command header, and its payload one by one
* into the mailbox command buffer. Along with this, check for mailbox buffer
* full condition and trigger doorbell to SDM if the command buffer is full.
*/
static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args,
unsigned int len)
{
@ -92,15 +128,21 @@ static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args,
int ret;
bool is_doorbell_triggered = false;
#if SIP_SVC_V3
spin_lock(&mbox_write_lock);
#endif
cmd_free_offset = mmio_read_32(MBOX_OFFSET + MBOX_CIN);
sdm_read_offset = mmio_read_32(MBOX_OFFSET + MBOX_COUT);
/* Write the command header here */
ret = write_mailbox_cmd_buffer(&cmd_free_offset, sdm_read_offset,
header_cmd, &is_doorbell_triggered);
if (ret != 0) {
goto restart_mailbox;
}
/* Write the payload here w.r.to args and its len - one by one. */
for (i = 0U; i < len; i++) {
is_doorbell_triggered = false;
ret = write_mailbox_cmd_buffer(&cmd_free_offset,
@ -113,6 +155,9 @@ static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args,
mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U);
#if SIP_SVC_V3
spin_unlock(&mbox_write_lock);
#endif
return MBOX_RET_OK;
restart_mailbox:
@ -129,12 +174,21 @@ restart_mailbox:
}
}
#if SIP_SVC_V3
spin_unlock(&mbox_write_lock);
#endif
return MBOX_TIMEOUT;
}
int mailbox_read_response(unsigned int *job_id, uint32_t *response,
unsigned int *resp_len)
{
#if SIP_SVC_V3
return mailbox_read_response_v3(MBOX_ATF_CLIENT_ID,
(uint8_t *)job_id, NULL,
response, resp_len,
0);
#else
uint32_t rin;
uint32_t rout;
uint32_t resp_data;
@ -174,13 +228,23 @@ int mailbox_read_response(unsigned int *job_id, uint32_t *response,
return MBOX_RET_OK;
}
return MBOX_NO_RESPONSE;
#endif
}
int mailbox_read_response_async(unsigned int *job_id, uint32_t *header,
uint32_t *response, unsigned int *resp_len,
uint8_t ignore_client_id)
{
#if SIP_SVC_V3
/* Just to avoid the build warning */
(void)mailbox_resp_ctr;
return mailbox_read_response_v3(MBOX_ATF_CLIENT_ID,
(uint8_t *)job_id, header,
response, resp_len,
ignore_client_id);
#else
uint32_t rin;
uint32_t rout;
uint32_t resp_data;
@ -220,7 +284,6 @@ int mailbox_read_response_async(unsigned int *job_id, uint32_t *header,
return MBOX_WRONG_ID;
}
}
*job_id = MBOX_RESP_JOB_ID(resp_data);
ret_resp_len = MBOX_RESP_LEN(resp_data);
mailbox_resp_ctr.payload->header = resp_data;
@ -272,11 +335,16 @@ int mailbox_read_response_async(unsigned int *job_id, uint32_t *header,
*resp_len = 0;
return (mailbox_resp_ctr.flag & MBOX_PAYLOAD_FLAG_BUSY) ? MBOX_BUSY : MBOX_NO_RESPONSE;
#endif
}
int mailbox_poll_response(uint32_t job_id, uint32_t urgent, uint32_t *response,
unsigned int *resp_len)
unsigned int *resp_len)
{
#if SIP_SVC_V3
return mailbox_poll_response_v3(MBOX_ATF_CLIENT_ID, (uint8_t)job_id,
response, resp_len, urgent);
#else
unsigned int timeout = 40U;
unsigned int sdm_loop = 255U;
unsigned int ret_resp_len;
@ -285,7 +353,6 @@ int mailbox_poll_response(uint32_t job_id, uint32_t urgent, uint32_t *response,
uint32_t resp_data;
while (sdm_loop != 0U) {
do {
if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM)
== 1U) {
@ -310,7 +377,7 @@ int mailbox_poll_response(uint32_t job_id, uint32_t urgent, uint32_t *response,
}
mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
INFO("Error: Mailbox did not get UA");
ERROR("MBOX: Mailbox did not get UA");
return MBOX_RET_ERROR;
}
@ -324,13 +391,21 @@ int mailbox_poll_response(uint32_t job_id, uint32_t urgent, uint32_t *response,
rout %= MBOX_RESP_BUFFER_SIZE;
mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID
|| MBOX_RESP_JOB_ID(resp_data) != job_id) {
if ((MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID) ||
(MBOX_RESP_JOB_ID(resp_data) != job_id)) {
continue;
}
/* Get the return response len from the response header. */
ret_resp_len = MBOX_RESP_LEN(resp_data);
/* Print the response header. */
VERBOSE("MBOX: RespHdr: cid %d, jid %d, len %d, err_code 0x%x\n",
MBOX_RESP_CLIENT_ID(resp_data),
MBOX_RESP_JOB_ID(resp_data),
MBOX_RESP_LEN(resp_data),
MBOX_RESP_ERR(resp_data));
if (iterate_resp(ret_resp_len, response, resp_len)
!= MBOX_RET_OK) {
return MBOX_TIMEOUT;
@ -349,6 +424,7 @@ int mailbox_poll_response(uint32_t job_id, uint32_t urgent, uint32_t *response,
INFO("Timed out waiting for SDM\n");
return MBOX_TIMEOUT;
#endif
}
int iterate_resp(uint32_t mbox_resp_len, uint32_t *resp_buf,
@ -366,8 +442,7 @@ int iterate_resp(uint32_t mbox_resp_len, uint32_t *resp_buf,
if ((resp_buf != NULL) && (resp_len != NULL)
&& (*resp_len != 0U)) {
*(resp_buf + total_resp_len)
= resp_data;
*(resp_buf + total_resp_len) = resp_data;
*resp_len = *resp_len - 1;
total_resp_len++;
}
@ -417,6 +492,9 @@ int mailbox_send_cmd_async(uint32_t *job_id, uint32_t cmd, uint32_t *args,
return status;
}
#if SIP_SVC_V3
async_v1_job_id = (uint8_t)*job_id;
#endif
*job_id = (*job_id + 1U) % MBOX_MAX_IND_JOB_ID;
return MBOX_RET_OK;
@ -433,9 +511,7 @@ int mailbox_send_cmd(uint32_t job_id, uint32_t cmd, uint32_t *args,
MBOX_STATUS_UA_MASK;
mmio_write_32(MBOX_OFFSET + MBOX_URG, cmd);
mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U);
}
else {
} else {
status = fill_mailbox_circular_buffer(
MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) |
MBOX_JOB_ID_CMD(job_id) |
@ -460,12 +536,12 @@ void mailbox_clear_response(void)
void mailbox_set_int(uint32_t interrupt)
{
mmio_write_32(MBOX_OFFSET+MBOX_INT, MBOX_COE_BIT(interrupt) |
mmio_write_32(MBOX_OFFSET+MBOX_INT,
MBOX_COE_BIT(interrupt) |
MBOX_RIE_BIT(interrupt) |
MBOX_UAE_BIT(interrupt));
}
void mailbox_set_qspi_open(void)
{
mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE);
@ -606,6 +682,7 @@ int mailbox_init(void)
mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE |
MBOX_INT_FLAG_UAE);
mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
@ -616,8 +693,16 @@ int mailbox_init(void)
return status;
}
#if SIP_SVC_V3
/* Initialize the mailbox version3 implementation, and in V3 we
* are interested in only RIE interrupt
*/
mailbox_init_v3();
mailbox_set_int(MBOX_INT_FLAG_RIE);
#else
mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE |
MBOX_INT_FLAG_UAE);
#endif
return MBOX_RET_OK;
}
@ -730,3 +815,693 @@ int mailbox_safe_inject_seu_err(uint32_t *arg, unsigned int len)
return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_SAFE_INJECT_SEU_ERR, arg, len,
CMD_CASUAL, NULL, NULL);
}
#if SIP_SVC_V3
static int mailbox_fill_cmd_desc(uint8_t client_id, uint8_t job_id,
uint32_t *resp_buff)
{
sdm_command_t *cmd_desc = NULL;
/* Get a free command descriptor */
cmd_desc = mailbox_get_free_cmd_desc();
if (cmd_desc == NULL) {
return MBOX_BUFFER_FULL;
}
/* Record all the given values for the command. */
cmd_desc->client_id = client_id;
cmd_desc->job_id = job_id;
cmd_desc->cb = NULL;
cmd_desc->cb_args = resp_buff;
cmd_desc->cb_args_len = 0U;
return MBOX_RET_OK;
}
/* Returns the command descriptor based on the client and job ID. */
static sdm_command_t *mailbox_get_cmd_desc(uint8_t client_id, uint8_t job_id)
{
spin_lock(&mbox_db_lock);
for (uint32_t count = 0; count < MBOX_SVC_CMD_QUEUE_SIZE; count++) {
if ((mbox_svc.cmd_queue[count].client_id == client_id) &&
(mbox_svc.cmd_queue[count].job_id == job_id) &&
(mbox_svc.cmd_queue[count].flags & MBOX_SVC_CMD_IS_USED)) {
spin_unlock(&mbox_db_lock);
return &(mbox_svc.cmd_queue[count]);
}
}
spin_unlock(&mbox_db_lock);
VERBOSE("MBOX: Command descriptor not found for cid %d, jid %d\n",
client_id, job_id);
return NULL;
}
/* Returns the response descriptor based on only client ID. */
static sdm_response_t *mailbox_get_resp_desc_cid(uint8_t client_id, uint8_t *index)
{
spin_lock(&mbox_db_lock);
for (uint32_t count = 0; count < MBOX_SVC_RESP_QUEUE_SIZE; count++) {
if ((mbox_svc.resp_queue[count].client_id == client_id) &&
(mbox_svc.resp_queue[count].flags & FLAG_SDM_RESPONSE_IS_VALID)) {
*index = count;
/*
* Once we get the valid response descriptor, get the
* job ID and mark up the bitmaps.
*/
uint8_t job_id = mbox_svc.resp_queue[count].job_id;
uint8_t transaction_id = MBOX_GET_TRANS_ID(client_id, job_id);
mbox_svc.received_bitmap[transaction_id / MBOX_TID_BITMAP_SIZE] &=
~(1ULL << (transaction_id % MBOX_TID_BITMAP_SIZE));
mbox_svc.interrupt_bitmap[transaction_id / MBOX_TID_BITMAP_SIZE] &=
~(1ULL << (transaction_id % MBOX_TID_BITMAP_SIZE));
spin_unlock(&mbox_db_lock);
return &(mbox_svc.resp_queue[count]);
}
}
spin_unlock(&mbox_db_lock);
VERBOSE("MBOX: Response descriptor not found for cid %d\n", client_id);
return NULL;
}
/* Returns the response descriptor based on the client and job ID. */
static sdm_response_t *mailbox_get_resp_desc(uint8_t client_id, uint8_t job_id, uint8_t *index)
{
spin_lock(&mbox_db_lock);
/*
* Let's first check whether we have a response bitmap set for the given
* client ID and job ID.
*/
uint8_t transaction_id = MBOX_GET_TRANS_ID(client_id, job_id);
if ((mbox_svc.received_bitmap[transaction_id / MBOX_TID_BITMAP_SIZE] &
(1ULL << (transaction_id % MBOX_TID_BITMAP_SIZE))) == 0) {
spin_unlock(&mbox_db_lock);
VERBOSE("MBOX: Response bitmap not set for cid %d, jid %d, bitmap 0x%16lx\n",
client_id, job_id, mbox_svc.received_bitmap[transaction_id / 64]);
return NULL;
}
for (uint32_t count = 0; count < MBOX_SVC_RESP_QUEUE_SIZE; count++) {
if (mbox_svc.resp_queue[count].flags & FLAG_SDM_RESPONSE_IS_VALID) {
if ((mbox_svc.resp_queue[count].client_id == client_id) &&
(mbox_svc.resp_queue[count].job_id == job_id)) {
*index = count;
mbox_svc.received_bitmap[transaction_id / MBOX_TID_BITMAP_SIZE] &=
~(1ULL << (transaction_id % MBOX_TID_BITMAP_SIZE));
mbox_svc.interrupt_bitmap[transaction_id / MBOX_TID_BITMAP_SIZE] &=
~(1ULL << (transaction_id % MBOX_TID_BITMAP_SIZE));
spin_unlock(&mbox_db_lock);
return &(mbox_svc.resp_queue[count]);
}
}
}
spin_unlock(&mbox_db_lock);
VERBOSE("MBOX: Response descriptor not found for cid %d, jid %d\n",
client_id, job_id);
return NULL;
}
static int32_t mailbox_get_free_resp_desc(void)
{
spin_lock(&mbox_db_lock);
static uint32_t free_index = MBOX_SVC_RESP_QUEUE_SIZE - 1;
uint32_t count = 0U, try = 0U;
for (try = 0; try < MBOX_SVC_RESP_QUEUE_SIZE; try++) {
free_index = (free_index + 1) % MBOX_SVC_RESP_QUEUE_SIZE;
if ((mbox_svc.resp_queue[free_index].flags &
FLAG_SDM_RESPONSE_IS_USED) != 0U) {
count = free_index;
spin_unlock(&mbox_db_lock);
return count;
}
}
/* No free descriptors are available */
spin_unlock(&mbox_db_lock);
VERBOSE("MBOX: No free response descriptors are available\n");
return MBOX_BUFFER_FULL;
}
static sdm_command_t *mailbox_get_free_cmd_desc(void)
{
spin_lock(&mbox_db_lock);
static uint32_t free_index;
/* Rollover the command queue free index */
if (free_index == (MBOX_SVC_CMD_QUEUE_SIZE - 1)) {
free_index = 0U;
}
for (; free_index < MBOX_SVC_CMD_QUEUE_SIZE; free_index++) {
if ((mbox_svc.cmd_queue[free_index].flags &
MBOX_SVC_CMD_IS_USED) != 0U) {
mbox_svc.cmd_queue[free_index].flags |= MBOX_SVC_CMD_IS_USED;
spin_unlock(&mbox_db_lock);
return &(mbox_svc.cmd_queue[free_index]);
}
}
/* No free command descriptors are available */
spin_unlock(&mbox_db_lock);
VERBOSE("MBOX: No free command descriptors available\n");
return NULL;
}
static inline void mailbox_free_cmd_desc(sdm_command_t *cmd_desc)
{
if (cmd_desc == NULL) {
return;
}
spin_lock(&mbox_db_lock);
memset((void *)cmd_desc, 0, sizeof(sdm_command_t));
spin_unlock(&mbox_db_lock);
}
static inline void mailbox_free_resp_desc(uint8_t index)
{
if (index >= MBOX_SVC_RESP_QUEUE_SIZE) {
return;
}
spin_lock(&mbox_db_lock);
memset((void *)&mbox_svc.resp_queue[index], 0, sizeof(sdm_response_t));
spin_unlock(&mbox_db_lock);
}
/*
* This function serves the V1 _sync_read and _async_read functionality, and it
* is introduced as part of V3 framework to keep backward compatible with V1
* clients.
*/
static int mailbox_read_response_v3(uint8_t client_id, uint8_t *job_id,
uint32_t *header, uint32_t *resp,
uint32_t *resp_len,
uint8_t ignore_client_id)
{
uint8_t di = 0U;
int status = MBOX_RET_OK;
sdm_response_t *resp_desc = NULL;
sdm_command_t *cmd_desc = NULL;
/*
* In the V1, the client ID is always MBOX_ATF_CLIENT_ID and in this
* routine we will collect the response which only belongs to this
* client ID. So safe to ignore this input.
*/
(void)ignore_client_id;
/* Clear the SDM doorbell interrupt */
if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) == 1U)
mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
/* Fill the command descriptor index and get the same */
status = mailbox_fill_cmd_desc(client_id, async_v1_job_id, resp);
if (status != MBOX_RET_OK) {
return status;
}
cmd_desc = mailbox_get_cmd_desc(client_id, async_v1_job_id);
/* Get the response from SDM, just go through one cycle */
status = mailbox_response_handler_fsm();
if (status != MBOX_RET_OK) {
mailbox_free_cmd_desc(cmd_desc);
*resp_len = 0U;
return status;
}
/* Check the local response queue with the given client ID */
resp_desc = mailbox_get_resp_desc_cid(client_id, &di);
if (resp_desc == NULL) {
mailbox_free_cmd_desc(cmd_desc);
*resp_len = 0U;
return MBOX_NO_RESPONSE;
}
/* Update the received mailbox response length, job ID and header */
*job_id = resp_desc->job_id;
*resp_len = resp_desc->rcvd_resp_len;
if (header != NULL) {
*header = resp_desc->header;
}
/* Check the mailbox response error code */
if (MBOX_RESP_ERR(resp_desc->header) > 0U) {
INFO("MBOX: Error in async response: %x\n", resp_desc->header);
status = -MBOX_RESP_ERR(resp_desc->header);
}
/* Free up the response and command descriptors */
mailbox_free_resp_desc(di);
mailbox_free_cmd_desc(cmd_desc);
return status;
}
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 status = 0;
sdm_command_t *cmd_desc = NULL;
VERBOSE("MBOX: cid: %d, jid: %d, cmd: %d, cmd_flag: %d\n",
client_id, job_id, cmd, cmd_flag);
if (IS_CMD_SET(cmd_flag, URGENT)) {
mmio_write_32(MBOX_OFFSET + MBOX_URG, cmd);
mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U);
} else {
/* Get a free command descriptor */
cmd_desc = mailbox_get_free_cmd_desc();
if (cmd_desc == NULL) {
return MBOX_BUFFER_FULL;
}
/* Record all the given values for the command. */
cmd_desc->client_id = client_id;
cmd_desc->job_id = job_id;
cmd_desc->cb = cb;
cmd_desc->cb_args = cb_args;
cmd_desc->cb_args_len = cb_args_len;
/* Push the command to mailbox FIFO */
status = fill_mailbox_circular_buffer(
MBOX_FRAME_CMD_HEADER(client_id, job_id,
args_len, IS_CMD_SET(cmd_flag, INDIRECT), cmd),
args,
args_len);
if (status != MBOX_RET_OK) {
INFO("MBOX: Failed to push the command to mailbox FIFO\n");
/* Free the command descriptor. */
mailbox_free_cmd_desc(cmd_desc);
}
}
INFO("MBOX: %s: status: %d\n", __func__, status);
return status;
}
static int mailbox_poll_response_v3(uint8_t client_id, uint8_t job_id,
uint32_t *resp, unsigned int *resp_len,
uint32_t urgent)
{
unsigned int timeout = 40U;
unsigned int sdm_loop = 255U;
bool is_cmd_desc_fill = false;
uint8_t di = 0U;
sdm_response_t *resp_desc = NULL;
sdm_command_t *cmd_desc = NULL;
while (sdm_loop != 0U) {
do {
if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM)
== 1U) {
break;
}
mdelay(10U);
} while (--timeout != 0U);
if (timeout == 0U) {
INFO("%s: Timed out waiting for SDM intr\n", __func__);
break;
}
mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
if ((urgent & 1U) != 0U) {
mdelay(5U);
if ((mmio_read_32(MBOX_OFFSET + MBOX_STATUS) &
MBOX_STATUS_UA_MASK) ^
(urgent & MBOX_STATUS_UA_MASK)) {
mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
return MBOX_RET_OK;
}
mmio_write_32(MBOX_OFFSET + MBOX_URG, 0U);
ERROR("MBOX: Mailbox did not get UA");
return MBOX_RET_ERROR;
}
/* Fill the command descriptor index and get the same. */
if (!is_cmd_desc_fill) {
if (mailbox_fill_cmd_desc(client_id, job_id, resp) !=
MBOX_RET_OK) {
return MBOX_BUFFER_FULL;
}
cmd_desc = mailbox_get_cmd_desc(client_id, job_id);
is_cmd_desc_fill = true;
}
/* Since it is sync call, will try to read till it time out */
(void)mailbox_response_handler_fsm();
/* Check the response queue with the given client ID and job ID */
resp_desc = mailbox_get_resp_desc(client_id, job_id, &di);
if (resp_desc != NULL) {
VERBOSE("%s: Resp received for cid %d, jid %d\n",
__func__, resp_desc->client_id, resp_desc->job_id);
uint16_t header = resp_desc->header;
/* Update the return response length */
if (resp_len != NULL) {
*resp_len = resp_desc->rcvd_resp_len;
}
/* Free the response and command descriptor */
mailbox_free_resp_desc(di);
mailbox_free_cmd_desc(cmd_desc);
if (MBOX_RESP_ERR(header) > 0U) {
INFO("%s: SDM err code: 0x%x\n", __func__,
MBOX_RESP_ERR(header));
return -MBOX_RESP_ERR(header);
}
VERBOSE("%s: MBOX_RET_OK\n", __func__);
return MBOX_RET_OK;
}
sdm_loop--;
}
INFO("%s: Timed out waiting for SDM\n", __func__);
return MBOX_TIMEOUT;
}
/* SDM response parser handler state machine. */
static void mailbox_response_parser(void)
{
int di = -1; /* Descriptor index */
uint32_t rin;
uint32_t rout;
switch (mbox_svc.next_resp_state) {
case SRS_WAIT_FOR_RESP:
{
mbox_svc.resp_state = SRS_WAIT_FOR_RESP;
rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
if (rin != rout) {
mbox_svc.next_resp_state = SRS_WAIT_FOR_HEADER;
}
break;
}
case SRS_WAIT_FOR_HEADER:
{
mbox_svc.resp_state = SRS_WAIT_FOR_HEADER;
uint32_t resp_hdr;
uint8_t trans_id = 0U;
rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
if (rin != rout) {
/* Read the header and dequeue from the queue. */
resp_hdr = mmio_read_32(MBOX_ENTRY_TO_ADDR(RESP, (rout)++));
rout %= MBOX_RESP_BUFFER_SIZE;
mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
/* Allocate a new response descriptor */
di = mailbox_get_free_resp_desc();
if (di != -1) {
mbox_svc.curr_di = di;
mbox_svc.resp_queue[di].header = resp_hdr;
mbox_svc.resp_queue[di].client_id = MBOX_RESP_CLIENT_ID(resp_hdr);
mbox_svc.resp_queue[di].job_id = MBOX_RESP_JOB_ID(resp_hdr);
mbox_svc.resp_queue[di].resp_len = MBOX_RESP_LEN(resp_hdr);
mbox_svc.resp_queue[di].flags |= (FLAG_SDM_RESPONSE_IS_USED |
FLAG_SDM_RESPONSE_IS_IN_PROGRESS);
mbox_svc.resp_queue[di].err_code = MBOX_RESP_ERR(resp_hdr);
trans_id = MBOX_RESP_TRANSACTION_ID(resp_hdr);
VERBOSE("MBOX: Resp Hdr: cid %d, jid %d, len %d, err_code 0x%x\n",
mbox_svc.resp_queue[di].client_id,
mbox_svc.resp_queue[di].job_id,
mbox_svc.resp_queue[di].resp_len,
mbox_svc.resp_queue[di].err_code);
/* Check if the response is an argument response */
if (mbox_svc.resp_queue[di].resp_len > 0) {
mbox_svc.next_resp_state = SRS_WAIT_FOR_ARGUMENTS;
} else {
VERBOSE("MBOX: Received complete response with no args\n");
/* Non argument response, done */
mbox_svc.resp_queue[mbox_svc.curr_di].flags |=
FLAG_SDM_RESPONSE_IS_VALID;
/* Go back to waiting for new response */
mbox_svc.next_resp_state = SRS_WAIT_FOR_RESP;
mbox_svc.curr_di = -1;
/* Mark the transaction ID as received */
spin_lock(&mbox_db_lock);
mbox_svc.received_bitmap[trans_id / MBOX_TID_BITMAP_SIZE] |=
(1ULL << (trans_id % MBOX_TID_BITMAP_SIZE));
spin_unlock(&mbox_db_lock);
}
} else {
mbox_svc.next_resp_state = SRS_SYNC_ERROR;
}
}
break;
}
case SRS_WAIT_FOR_ARGUMENTS:
{
mbox_svc.resp_state = SRS_WAIT_FOR_ARGUMENTS;
uint16_t mbox_resp_len = mbox_svc.resp_queue[mbox_svc.curr_di].resp_len;
uint32_t *read_buff = NULL;
uint16_t read_len = 0U;
uint16_t read_max_len = 0U;
uint32_t timeout = 0U;
/* Determine where to copy the buffer. */
sdm_command_t *cmd_desc = mailbox_get_cmd_desc(
mbox_svc.resp_queue[mbox_svc.curr_di].client_id,
mbox_svc.resp_queue[mbox_svc.curr_di].job_id);
if (cmd_desc != NULL && cmd_desc->cb_args != NULL) {
read_buff = cmd_desc->cb_args;
read_max_len = mbox_resp_len;
} else {
read_buff = (uint32_t *)mbox_svc.resp_queue[mbox_svc.curr_di].resp_data;
read_max_len = MBOX_SVC_MAX_RESP_DATA_SIZE;
}
rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
while ((read_len < mbox_resp_len) && (rin != rout) && (read_len < read_max_len)) {
timeout = 10000U;
/* Copy the response data to the buffer */
read_buff[read_len++] = mmio_read_32(MBOX_ENTRY_TO_ADDR(RESP, (rout)++));
VERBOSE("MBOX: 0x%x\n", read_buff[read_len - 1]);
/* Update the read out buffer index */
rout %= MBOX_RESP_BUFFER_SIZE;
mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
/*
* The response buffer is of 16 words size, this loop checks
* if the response buffer is empty and if empty trigger an
* interrupt to SDM and wait for the response buffer to fill
*/
do {
if (read_len == mbox_resp_len)
break;
rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
if (rout == rin) {
mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1U);
udelay(100);
} else {
break;
}
timeout--;
} while ((read_len < mbox_resp_len) && (timeout != 0U));
if (timeout == 0U) {
INFO("MBOX: Timeout waiting for response data\n");
mbox_svc.next_resp_state = SRS_SYNC_ERROR;
break;
}
}
/* Check if we have received all the arguments */
mbox_svc.resp_queue[mbox_svc.curr_di].rcvd_resp_len = read_len;
if (mbox_resp_len == read_len) {
uint8_t transaction_id =
((mbox_svc.resp_queue[mbox_svc.curr_di].client_id << 4) |
(mbox_svc.resp_queue[mbox_svc.curr_di].job_id));
VERBOSE("MBOX: Received all the response data len %d, transaction_id %d\n",
read_len, transaction_id);
spin_lock(&mbox_db_lock);
mbox_svc.received_bitmap[transaction_id / MBOX_TID_BITMAP_SIZE] |=
(1ULL << (transaction_id % MBOX_TID_BITMAP_SIZE));
spin_unlock(&mbox_db_lock);
mbox_svc.resp_queue[mbox_svc.curr_di].flags |= FLAG_SDM_RESPONSE_IS_VALID;
mbox_svc.next_resp_state = SRS_WAIT_FOR_RESP;
mbox_svc.curr_di = -1;
} else {
mbox_svc.next_resp_state = SRS_SYNC_ERROR;
VERBOSE("MBOX: Received partial response data len %d, max len %d\n",
read_len, read_max_len);
}
break;
}
case SRS_SYNC_ERROR:
{
mbox_svc.resp_state = SRS_SYNC_ERROR;
INFO("MBOX: Error in response handling\n");
break;
}
default:
break;
} /* switch */
}
static int mailbox_response_handler_fsm(void)
{
int status = MBOX_RET_OK;
spin_lock(&mbox_read_lock);
/* Mailbox peripheral response parser */
do {
/* Iterate till the state machine transition ends */
mailbox_response_parser();
/* Note down if there is any error in the response parsing */
if (mbox_svc.next_resp_state == SRS_SYNC_ERROR) {
status = MBOX_RET_ERROR;
}
} while (mbox_svc.resp_state != mbox_svc.next_resp_state);
spin_unlock(&mbox_read_lock);
return status;
}
int mailbox_response_poll_on_intr_v3(uint8_t *client_id, uint8_t *job_id,
uint64_t *bitmap)
{
uint32_t i = 0U;
int status = MBOX_RET_OK;
/* Clear the SDM doorbell interrupt immediately */
if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) == 1U) {
mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
}
/* Check mailbox FIFO for any pending responses available to read. */
status = mailbox_response_handler_fsm();
if (status != MBOX_RET_OK) {
return status;
}
/*
* Once we read the complete mailbox FIFO, let's mark up the bitmap for
* available responses with respect to each transcation IDs.
*/
status = MBOX_NO_RESPONSE;
spin_lock(&mbox_db_lock);
for (i = 0; i < MBOX_MAX_TIDS_BITMAP; i++) {
bitmap[i] = mbox_svc.interrupt_bitmap[i] ^ mbox_svc.received_bitmap[i];
if (bitmap[i] != 0 && status == MBOX_NO_RESPONSE) {
status = MBOX_RET_OK;
}
mbox_svc.interrupt_bitmap[i] = mbox_svc.received_bitmap[i];
}
spin_unlock(&mbox_db_lock);
return status;
}
int mailbox_response_poll_v3(uint8_t client_id, uint8_t job_id,
uint32_t *ret_args, uint32_t *ret_args_len)
{
sdm_command_t *cmd_desc = NULL;
sdm_response_t *resp_desc = NULL;
uint8_t di = 0U;
int status = MBOX_RET_OK;
/*
* Let's first check the local response queue with the given
* client ID and job ID
*/
resp_desc = mailbox_get_resp_desc(client_id, job_id, &di);
if (resp_desc == NULL) {
/* Not available in the local queue, let's read mailbox FIFO */
status = mailbox_response_handler_fsm();
if (status != MBOX_RET_OK) {
return status;
}
resp_desc = mailbox_get_resp_desc(client_id, job_id, &di);
}
cmd_desc = mailbox_get_cmd_desc(client_id, job_id);
if (cmd_desc != NULL && resp_desc != NULL) {
VERBOSE("MBOX: Resp found for cid %d, jid %d\n", client_id, job_id);
/* Command callback function */
*ret_args_len = cmd_desc->cb(resp_desc, cmd_desc, ret_args);
/* Free the command and response descriptors. */
mailbox_free_cmd_desc(cmd_desc);
mailbox_free_resp_desc(di);
return MBOX_RET_OK;
}
INFO("MBOX: No resp found for cid: %d, jid: %d\n", client_id, job_id);
return MBOX_NO_RESPONSE;
}
void mailbox_init_v3(void)
{
uint32_t count;
memset((void *)&mbox_svc, 0, sizeof(mbox_svc));
mbox_svc.next_resp_state = SRS_WAIT_FOR_RESP;
mbox_svc.resp_state = SRS_WAIT_FOR_RESP;
/* Free all entries from the response queue. */
for (count = 0; count < MBOX_SVC_RESP_QUEUE_SIZE; count++) {
mbox_svc.resp_queue[count].flags = 0;
}
/* Free all entries from the command queue. */
for (count = 0; count < MBOX_SVC_CMD_QUEUE_SIZE; count++) {
mbox_svc.cmd_queue[count].flags = 0;
}
mbox_svc.curr_di = -1;
}
#endif /* #if SIP_SVC_V3 */

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2020-2022, Intel Corporation. All rights reserved.
* Copyright (c) 2025, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -115,6 +116,16 @@ void bl31_platform_setup(void)
mmio_write_64(PLAT_CPU_RELEASE_ADDR,
(uint64_t)plat_secondary_cpus_bl31_entry);
#if SIP_SVC_V3
/*
* Re-initialize the mailbox to include V3 specific routines.
* In V3, this re-initialize is required because prior to BL31, U-Boot
* SPL has its own mailbox settings and this initialization will
* override to those settings as required by the V3 framework.
*/
mailbox_init();
#endif
mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
}

View file

@ -1,6 +1,7 @@
/*
* Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2019-2022, Intel Corporation. All rights reserved.
* Copyright (c) 2025, Altera Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -122,6 +123,16 @@ void bl31_platform_setup(void)
mmio_write_64(PLAT_CPU_RELEASE_ADDR,
(uint64_t)plat_secondary_cpus_bl31_entry);
#if SIP_SVC_V3
/*
* Re-initialize the mailbox to include V3 specific routines.
* In V3, this re-initialize is required because prior to BL31, U-Boot
* SPL has its own mailbox settings and this initialization will
* override to those settings as required by the V3 framework.
*/
mailbox_init();
#endif
mailbox_hps_stage_notify(HPS_EXECUTION_STATE_SSBL);
}