Merge changes Ie9451e35,I1815deeb,If277b2b3,Ie2ceaf24,I7996d505, ... into integration
* changes:
fix(intel): add flash dcache after return response for INTEL_SIP_SMC_MBOX_SEND_CMD
fix(intel): extending to support large file size for SHA2/HMAC get digest and verifying
fix(intel): extending to support large file size for SHA-2 ECDSA data signing and signature verifying
fix(intel): extending to support large file size for AES encryption and decryption
feat(intel): support version 2 SiP SVC SMC function ID for mailbox commands
feat(intel): support version 2 SiP SVC SMC function ID for non-mailbox commands
fix(intel): update certificate mask for FPGA Attestation
feat(intel): update to support maximum response data size
feat(intel): support ECDSA HASH Verification
feat(intel): support ECDSA HASH Signing
feat(intel): support ECDH request
feat(intel): support ECDSA SHA-2 Data Signature Verification
feat(intel): support ECDSA SHA-2 Data Signing
feat(intel): support ECDSA Get Public Key
feat(intel): support session based SDOS encrypt and decrypt
feat(intel): support AES Crypt Service
feat(intel): support HMAC SHA-2 MAC verify request
feat(intel): support SHA-2 hash digest generation on a blob
feat(intel): support extended random number generation
feat(intel): support crypto service key operation
feat(intel): support crypto service session
feat(intel): extend attestation service to Agilex family
fix(intel): flush dcache before sending certificate to mailbox
fix(intel): introduce a generic response error code
fix(intel): allow non-secure access to FPGA Crypto Services (FCS)
feat(intel): single certificate feature enablement
feat(intel): initial commit for attestation service
fix(intel): update encryption and decryption command logic
diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c
index 7b3b0e2..211a7b7 100644
--- a/plat/intel/soc/agilex/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex/bl2_plat_setup.c
@@ -84,7 +84,7 @@
if (!intel_mailbox_is_fpga_not_ready()) {
socfpga_bridges_enable(SOC2FPGA_MASK | LWHPS2FPGA_MASK |
- FPGA2SOC_MASK);
+ FPGA2SOC_MASK);
}
}
diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk
index 0e5f911..6fe0be1 100644
--- a/plat/intel/soc/agilex/platform.mk
+++ b/plat/intel/soc/agilex/platform.mk
@@ -65,6 +65,7 @@
plat/intel/soc/agilex/soc/agilex_clock_manager.c \
plat/intel/soc/common/socfpga_psci.c \
plat/intel/soc/common/socfpga_sip_svc.c \
+ plat/intel/soc/common/socfpga_sip_svc_v2.c \
plat/intel/soc/common/socfpga_topology.c \
plat/intel/soc/common/sip/socfpga_sip_ecc.c \
plat/intel/soc/common/sip/socfpga_sip_fcs.c \
diff --git a/plat/intel/soc/common/include/socfpga_fcs.h b/plat/intel/soc/common/include/socfpga_fcs.h
index d3b7141..893551d 100644
--- a/plat/intel/soc/common/include/socfpga_fcs.h
+++ b/plat/intel/soc/common/include/socfpga_fcs.h
@@ -9,38 +9,300 @@
/* FCS Definitions */
-#define FCS_RANDOM_WORD_SIZE 8U
-#define FCS_PROV_DATA_WORD_SIZE 44U
-#define FCS_SHA384_WORD_SIZE 12U
+#define FCS_RANDOM_WORD_SIZE 8U
+#define FCS_PROV_DATA_WORD_SIZE 44U
+#define FCS_SHA384_WORD_SIZE 12U
-#define FCS_RANDOM_BYTE_SIZE (FCS_RANDOM_WORD_SIZE * 4U)
-#define FCS_PROV_DATA_BYTE_SIZE (FCS_PROV_DATA_WORD_SIZE * 4U)
-#define FCS_SHA384_BYTE_SIZE (FCS_SHA384_WORD_SIZE * 4U)
+#define FCS_RANDOM_BYTE_SIZE (FCS_RANDOM_WORD_SIZE * 4U)
+#define FCS_RANDOM_EXT_MAX_WORD_SIZE 1020U
+#define FCS_PROV_DATA_BYTE_SIZE (FCS_PROV_DATA_WORD_SIZE * 4U)
+#define FCS_SHA384_BYTE_SIZE (FCS_SHA384_WORD_SIZE * 4U)
-#define FCS_CRYPTION_DATA_0 0x10100
+#define FCS_RANDOM_EXT_OFFSET 3
+#define FCS_MODE_DECRYPT 0x0
+#define FCS_MODE_ENCRYPT 0x1
+#define FCS_ENCRYPTION_DATA_0 0x10100
+#define FCS_DECRYPTION_DATA_0 0x10102
+#define FCS_OWNER_ID_OFFSET 0xC
+#define FCS_CRYPTION_CRYPTO_HEADER 0x07000000
+#define FCS_CRYPTION_RESP_WORD_SIZE 4U
+#define FCS_CRYPTION_RESP_SIZE_OFFSET 3U
+
+#define PSGSIGMA_TEARDOWN_MAGIC 0xB852E2A4
+#define PSGSIGMA_SESSION_ID_ONE 0x1
+#define PSGSIGMA_UNKNOWN_SESSION 0xFFFFFFFF
+
+#define RESERVED_AS_ZERO 0x0
+/* FCS Single cert */
+
+#define FCS_BIG_CNTR_SEL 0x1
+
+#define FCS_SVN_CNTR_0_SEL 0x2
+#define FCS_SVN_CNTR_1_SEL 0x3
+#define FCS_SVN_CNTR_2_SEL 0x4
+#define FCS_SVN_CNTR_3_SEL 0x5
+
+#define FCS_BIG_CNTR_VAL_MAX 495U
+#define FCS_SVN_CNTR_VAL_MAX 64U
+
+/* FCS Attestation Cert Request Parameter */
+
+#define FCS_ATTEST_FIRMWARE_CERT 0x01
+#define FCS_ATTEST_DEV_ID_SELF_SIGN_CERT 0x02
+#define FCS_ATTEST_DEV_ID_ENROLL_CERT 0x04
+#define FCS_ATTEST_ENROLL_SELF_SIGN_CERT 0x08
+#define FCS_ATTEST_ALIAS_CERT 0x10
+#define FCS_ATTEST_CERT_MAX_REQ_PARAM 0xFF
+
+/* FCS Crypto Service */
+
+#define FCS_CS_KEY_OBJ_MAX_WORD_SIZE 88U
+#define FCS_CS_KEY_INFO_MAX_WORD_SIZE 36U
+#define FCS_CS_KEY_RESP_STATUS_MASK 0xFF
+#define FCS_CS_KEY_RESP_STATUS_OFFSET 16U
+
+#define FCS_CS_FIELD_SIZE_MASK 0xFFFF
+#define FCS_CS_FIELD_FLAG_OFFSET 24
+#define FCS_CS_FIELD_FLAG_INIT BIT(0)
+#define FCS_CS_FIELD_FLAG_UPDATE BIT(1)
+#define FCS_CS_FIELD_FLAG_FINALIZE BIT(2)
+
+#define FCS_AES_MAX_DATA_SIZE 0x10000000 /* 256 MB */
+#define FCS_AES_MIN_DATA_SIZE 0x20 /* 32 Byte */
+#define FCS_AES_CMD_MAX_WORD_SIZE 15U
+
+#define FCS_GET_DIGEST_CMD_MAX_WORD_SIZE 7U
+#define FCS_GET_DIGEST_RESP_MAX_WORD_SIZE 19U
+#define FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE 23U
+#define FCS_MAC_VERIFY_RESP_MAX_WORD_SIZE 4U
+#define FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET 8U
+
+#define FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE 5U
+#define FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE 7U
+#define FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE 43U
+#define FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE 17U
+#define FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE 52U
+#define FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE 29U
/* FCS Payload Structure */
+typedef struct fcs_rng_payload_t {
+ uint32_t session_id;
+ uint32_t context_id;
+ uint32_t crypto_header;
+ uint32_t size;
+} fcs_rng_payload;
+
+typedef struct fcs_encrypt_payload_t {
+ uint32_t first_word;
+ uint32_t src_addr;
+ uint32_t src_size;
+ uint32_t dst_addr;
+ uint32_t dst_size;
+} fcs_encrypt_payload;
-typedef struct fcs_crypt_payload_t {
+typedef struct fcs_decrypt_payload_t {
uint32_t first_word;
+ uint32_t owner_id[2];
+ uint32_t src_addr;
+ uint32_t src_size;
+ uint32_t dst_addr;
+ uint32_t dst_size;
+} fcs_decrypt_payload;
+
+typedef struct fcs_encrypt_ext_payload_t {
+ uint32_t session_id;
+ uint32_t context_id;
+ uint32_t crypto_header;
+ uint32_t src_addr;
+ uint32_t src_size;
+ uint32_t dst_addr;
+ uint32_t dst_size;
+} fcs_encrypt_ext_payload;
+
+typedef struct fcs_decrypt_ext_payload_t {
+ uint32_t session_id;
+ uint32_t context_id;
+ uint32_t crypto_header;
+ uint32_t owner_id[2];
uint32_t src_addr;
uint32_t src_size;
uint32_t dst_addr;
uint32_t dst_size;
-} fcs_crypt_payload;
+} fcs_decrypt_ext_payload;
+
+typedef struct psgsigma_teardown_msg_t {
+ uint32_t reserved_word;
+ uint32_t magic_word;
+ uint32_t session_id;
+} psgsigma_teardown_msg;
+
+typedef struct fcs_cntr_set_preauth_payload_t {
+ uint32_t first_word;
+ uint32_t counter_value;
+} fcs_cntr_set_preauth_payload;
+
+typedef struct fcs_cs_key_payload_t {
+ uint32_t session_id;
+ uint32_t reserved0;
+ uint32_t reserved1;
+ uint32_t key_id;
+} fcs_cs_key_payload;
+
+typedef struct fcs_crypto_service_data_t {
+ uint32_t session_id;
+ uint32_t context_id;
+ uint32_t key_id;
+ uint32_t crypto_param_size;
+ uint64_t crypto_param;
+ uint8_t is_updated;
+} fcs_crypto_service_data;
+
+typedef struct fcs_crypto_service_aes_data_t {
+ uint32_t session_id;
+ uint32_t context_id;
+ uint32_t param_size;
+ uint32_t key_id;
+ uint32_t crypto_param[7];
+ uint8_t is_updated;
+} fcs_crypto_service_aes_data;
/* Functions Definitions */
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 *send_id);
uint32_t intel_fcs_get_provision_data(uint32_t *send_id);
-uint32_t intel_fcs_cryption(uint32_t mode, uint32_t src_addr,
- uint32_t src_size, uint32_t dst_addr,
- uint32_t dst_size, uint32_t *send_id);
+uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type,
+ int32_t counter_value,
+ uint32_t test_bit,
+ uint32_t *mbox_error);
+uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size,
+ uint32_t dst_addr, uint32_t dst_size,
+ uint32_t *send_id);
+
+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,
+ 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 src_addr, uint32_t src_size,
+ uint32_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error);
+
+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);
+int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error);
+int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error);
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,
+ uint32_t *dst_size, uint32_t *mbox_error);
+
+int intel_fcs_open_crypto_service_session(uint32_t *session_id,
+ uint32_t *mbox_error);
+int intel_fcs_close_crypto_service_session(uint32_t session_id,
+ uint32_t *mbox_error);
+
+int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
+ uint32_t *mbox_error);
+int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error);
+int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
+ uint32_t *mbox_error);
+int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error);
+
+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,
+ 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_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,
+ 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_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,
+ uint32_t src_addr, uint32_t src_size,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error);
+
+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,
+ uint32_t src_addr, uint32_t src_size,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error);
+
+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_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_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,
+ 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,
+ uint32_t src_addr, uint32_t src_size,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error);
+
+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);
+
#endif /* SOCFPGA_FCS_H */
diff --git a/plat/intel/soc/common/include/socfpga_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h
index b260a62..1f4b2a4 100644
--- a/plat/intel/soc/common/include/socfpga_mailbox.h
+++ b/plat/intel/soc/common/include/socfpga_mailbox.h
@@ -10,95 +10,124 @@
#include <lib/utils_def.h>
-#define MBOX_OFFSET 0xffa30000
+#define MBOX_OFFSET 0xffa30000
-#define MBOX_ATF_CLIENT_ID 0x1U
-#define MBOX_MAX_JOB_ID 0xFU
-#define MBOX_MAX_IND_JOB_ID (MBOX_MAX_JOB_ID - 1U)
-#define MBOX_JOB_ID MBOX_MAX_JOB_ID
-
+#define MBOX_ATF_CLIENT_ID 0x1U
+#define MBOX_MAX_JOB_ID 0xFU
+#define MBOX_MAX_IND_JOB_ID (MBOX_MAX_JOB_ID - 1U)
+#define MBOX_JOB_ID MBOX_MAX_JOB_ID
+#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
+#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
/* Mailbox SDM doorbell */
-#define MBOX_DOORBELL_TO_SDM 0x400
-#define MBOX_DOORBELL_FROM_SDM 0x480
+#define MBOX_DOORBELL_TO_SDM 0x400
+#define MBOX_DOORBELL_FROM_SDM 0x480
/* Mailbox commands */
-#define MBOX_CMD_NOOP 0x00
-#define MBOX_CMD_SYNC 0x01
-#define MBOX_CMD_RESTART 0x02
-#define MBOX_CMD_CANCEL 0x03
-#define MBOX_CMD_VAB_SRC_CERT 0x0B
-#define MBOX_CMD_GET_IDCODE 0x10
-#define MBOX_CMD_GET_USERCODE 0x13
-#define MBOX_CMD_REBOOT_HPS 0x47
+#define MBOX_CMD_NOOP 0x00
+#define MBOX_CMD_SYNC 0x01
+#define MBOX_CMD_RESTART 0x02
+#define MBOX_CMD_CANCEL 0x03
+#define MBOX_CMD_VAB_SRC_CERT 0x0B
+#define MBOX_CMD_GET_IDCODE 0x10
+#define MBOX_CMD_GET_USERCODE 0x13
+#define MBOX_CMD_GET_CHIPID 0x12
+#define MBOX_CMD_REBOOT_HPS 0x47
/* Reconfiguration Commands */
-#define MBOX_CONFIG_STATUS 0x04
-#define MBOX_RECONFIG 0x06
-#define MBOX_RECONFIG_DATA 0x08
-#define MBOX_RECONFIG_STATUS 0x09
+#define MBOX_CONFIG_STATUS 0x04
+#define MBOX_RECONFIG 0x06
+#define MBOX_RECONFIG_DATA 0x08
+#define MBOX_RECONFIG_STATUS 0x09
/* HWMON Commands */
-#define MBOX_HWMON_READVOLT 0x18
-#define MBOX_HWMON_READTEMP 0x19
+#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_DIRECT 0x3B
+#define MBOX_CMD_QSPI_OPEN 0x32
+#define MBOX_CMD_QSPI_CLOSE 0x33
+#define MBOX_CMD_QSPI_SET_CS 0x34
+#define MBOX_CMD_QSPI_DIRECT 0x3B
/* RSU Commands */
-#define MBOX_GET_SUBPARTITION_TABLE 0x5A
-#define MBOX_RSU_STATUS 0x5B
-#define MBOX_RSU_UPDATE 0x5C
-#define MBOX_HPS_STAGE_NOTIFY 0x5D
+#define MBOX_GET_SUBPARTITION_TABLE 0x5A
+#define MBOX_RSU_STATUS 0x5B
+#define MBOX_RSU_UPDATE 0x5C
+#define MBOX_HPS_STAGE_NOTIFY 0x5D
/* FCS Command */
-#define MBOX_FCS_GET_PROVISION 0x7B
-#define MBOX_FCS_ENCRYPT_REQ 0x7E
-#define MBOX_FCS_DECRYPT_REQ 0x7F
-#define MBOX_FCS_RANDOM_GEN 0x80
+#define MBOX_FCS_GET_PROVISION 0x7B
+#define MBOX_FCS_CNTR_SET_PREAUTH 0x7C
+#define MBOX_FCS_ENCRYPT_REQ 0x7E
+#define MBOX_FCS_DECRYPT_REQ 0x7F
+#define MBOX_FCS_RANDOM_GEN 0x80
+#define MBOX_FCS_AES_CRYPT_REQ 0x81
+#define MBOX_FCS_GET_DIGEST_REQ 0x82
+#define MBOX_FCS_MAC_VERIFY_REQ 0x83
+#define MBOX_FCS_ECDSA_HASH_SIGN_REQ 0x84
+#define MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ 0x85
+#define MBOX_FCS_ECDSA_HASH_SIG_VERIFY 0x86
+#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_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
+
+/* PSG SIGMA Commands */
+#define MBOX_PSG_SIGMA_TEARDOWN 0xD5
+
+/* Attestation Commands */
+#define MBOX_CREATE_CERT_ON_RELOAD 0x180
+#define MBOX_GET_ATTESTATION_CERT 0x181
+#define MBOX_ATTESTATION_SUBKEY 0x182
+#define MBOX_GET_MEASUREMENT 0x183
+
/* Miscellaneous commands */
#define MBOX_GET_ROM_PATCH_SHA384 0x1B0
/* Mailbox Definitions */
-#define CMD_DIRECT 0
-#define CMD_INDIRECT 1
-#define CMD_CASUAL 0
-#define CMD_URGENT 1
+#define CMD_DIRECT 0
+#define CMD_INDIRECT 1
+#define CMD_CASUAL 0
+#define CMD_URGENT 1
-#define MBOX_WORD_BYTE 4U
-#define MBOX_RESP_BUFFER_SIZE 16
-#define MBOX_CMD_BUFFER_SIZE 32
+#define MBOX_WORD_BYTE 4U
+#define MBOX_RESP_BUFFER_SIZE 16
+#define MBOX_CMD_BUFFER_SIZE 32
+#define MBOX_INC_HEADER_MAX_WORD_SIZE 1024U
/* Execution states for HPS_STAGE_NOTIFY */
-#define HPS_EXECUTION_STATE_FSBL 0
-#define HPS_EXECUTION_STATE_SSBL 1
-#define HPS_EXECUTION_STATE_OS 2
+#define HPS_EXECUTION_STATE_FSBL 0
+#define HPS_EXECUTION_STATE_SSBL 1
+#define HPS_EXECUTION_STATE_OS 2
/* Status Response */
-#define MBOX_RET_OK 0
-#define MBOX_RET_ERROR -1
-#define MBOX_NO_RESPONSE -2
-#define MBOX_WRONG_ID -3
-#define MBOX_BUFFER_FULL -4
-#define MBOX_TIMEOUT -2047
+#define MBOX_RET_OK 0
+#define MBOX_RET_ERROR -1
+#define MBOX_NO_RESPONSE -2
+#define MBOX_WRONG_ID -3
+#define MBOX_BUFFER_FULL -4
+#define MBOX_BUSY -5
+#define MBOX_TIMEOUT -2047
/* Reconfig Status Response */
#define RECONFIG_STATUS_STATE 0
@@ -123,39 +152,56 @@
/* Mailbox Macros */
-#define MBOX_ENTRY_TO_ADDR(_buf, ptr) (MBOX_OFFSET + (MBOX_##_buf##_BUFFER) \
- + MBOX_WORD_BYTE * (ptr))
+#define MBOX_ENTRY_TO_ADDR(_buf, ptr) (MBOX_OFFSET + (MBOX_##_buf##_BUFFER) \
+ + 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 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)))
/* Mailbox response and status */
-#define MBOX_RESP_ERR(BUFFER) ((BUFFER) & 0x00000fff)
-#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_STATUS_UA_MASK (1<<8)
+#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_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_CMD_LEN_CMD(CMD_LEN) ((CMD_LEN) << 12)
-#define MBOX_INDIRECT(val) ((val) << 11)
-#define MBOX_CMD_MASK(header) ((header) & 0x7ff)
+#define MBOX_CLIENT_ID_CMD(CLIENT_ID) ((CLIENT_ID) << 28)
+#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)
+
+/* Mailbox payload */
+#define MBOX_DATA_MAX_LEN 0x3ff
+#define MBOX_PAYLOAD_FLAG_BUSY BIT(0)
/* RSU Macros */
-#define RSU_VERSION_ACMF BIT(8)
-#define RSU_VERSION_ACMF_MASK 0xff00
+#define RSU_VERSION_ACMF BIT(8)
+#define RSU_VERSION_ACMF_MASK 0xff00
/* Config Status Macros */
#define CONFIG_STATUS_WORD_SIZE 16U
#define CONFIG_STATUS_FW_VER_OFFSET 1
#define CONFIG_STATUS_FW_VER_MASK 0x00FFFFFF
+/* Data structure */
+
+typedef struct mailbox_payload {
+ uint32_t header;
+ uint32_t data[MBOX_DATA_MAX_LEN];
+} mailbox_payload_t;
+
+typedef struct mailbox_container {
+ uint32_t flag;
+ uint32_t index;
+ mailbox_payload_t *payload;
+} mailbox_container_t;
+
/* Mailbox Function Definitions */
void mailbox_set_int(uint32_t interrupt_input);
@@ -168,8 +214,13 @@
unsigned int *resp_len);
int mailbox_send_cmd_async(uint32_t *job_id, uint32_t cmd, uint32_t *args,
unsigned int len, unsigned int indirect);
+int mailbox_send_cmd_async_ext(uint32_t header_cmd, uint32_t *args,
+ unsigned int len);
int mailbox_read_response(uint32_t *job_id, uint32_t *response,
unsigned int *resp_len);
+int mailbox_read_response_async(uint32_t *job_id, uint32_t *header,
+ uint32_t *response, unsigned int *resp_len,
+ uint8_t ignore_client_id);
int iterate_resp(uint32_t mbox_resp_len, uint32_t *resp_buf,
unsigned int *resp_len);
diff --git a/plat/intel/soc/common/include/socfpga_reset_manager.h b/plat/intel/soc/common/include/socfpga_reset_manager.h
index 35ee672..cce16ab 100644
--- a/plat/intel/soc/common/include/socfpga_reset_manager.h
+++ b/plat/intel/soc/common/include/socfpga_reset_manager.h
@@ -9,15 +9,15 @@
#include "socfpga_plat_def.h"
-#define SOCFPGA_BRIDGE_ENABLE BIT(0)
-#define SOCFPGA_BRIDGE_HAS_MASK BIT(1)
+#define SOCFPGA_BRIDGE_ENABLE BIT(0)
+#define SOCFPGA_BRIDGE_HAS_MASK BIT(1)
-#define SOC2FPGA_MASK (1<<0)
-#define LWHPS2FPGA_MASK (1<<1)
-#define FPGA2SOC_MASK (1<<2)
-#define F2SDRAM0_MASK (1<<3)
-#define F2SDRAM1_MASK (1<<4)
-#define F2SDRAM2_MASK (1<<5)
+#define SOC2FPGA_MASK (1<<0)
+#define LWHPS2FPGA_MASK (1<<1)
+#define FPGA2SOC_MASK (1<<2)
+#define F2SDRAM0_MASK (1<<3)
+#define F2SDRAM1_MASK (1<<4)
+#define F2SDRAM2_MASK (1<<5)
/* Register Mapping */
@@ -111,7 +111,7 @@
/* Macros */
#define SOCFPGA_RSTMGR(_reg) (SOCFPGA_RSTMGR_REG_BASE \
- + (SOCFPGA_RSTMGR_##_reg))
+ + (SOCFPGA_RSTMGR_##_reg))
#define RSTMGR_FIELD(_reg, _field) (RSTMGR_##_reg##MODRST_##_field)
/* Function Declarations */
diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h
index ca6f1f8..f9a6ffd 100644
--- a/plat/intel/soc/common/include/socfpga_sip_svc.h
+++ b/plat/intel/soc/common/include/socfpga_sip_svc.h
@@ -9,29 +9,43 @@
/* SiP status response */
-#define INTEL_SIP_SMC_STATUS_OK 0
-#define INTEL_SIP_SMC_STATUS_BUSY 0x1
-#define INTEL_SIP_SMC_STATUS_REJECTED 0x2
-#define INTEL_SIP_SMC_STATUS_ERROR 0x4
-#define INTEL_SIP_SMC_RSU_ERROR 0x7
+#define INTEL_SIP_SMC_STATUS_OK 0
+#define INTEL_SIP_SMC_STATUS_BUSY 0x1
+#define INTEL_SIP_SMC_STATUS_REJECTED 0x2
+#define INTEL_SIP_SMC_STATUS_NO_RESPONSE 0x3
+#define INTEL_SIP_SMC_STATUS_ERROR 0x4
+#define INTEL_SIP_SMC_RSU_ERROR 0x7
/* SiP mailbox error code */
-#define GENERIC_RESPONSE_ERROR 0x3FF
+#define GENERIC_RESPONSE_ERROR 0x3FF
-/* SMC SiP service function identifier */
+/* SiP V2 command code range */
+#define INTEL_SIP_SMC_CMD_MASK 0xFFFF
+#define INTEL_SIP_SMC_CMD_V2_RANGE_BEGIN 0x400
+#define INTEL_SIP_SMC_CMD_V2_RANGE_END 0x4FF
+
+/* SiP V2 protocol header */
+#define INTEL_SIP_SMC_HEADER_JOB_ID_MASK 0xF
+#define INTEL_SIP_SMC_HEADER_JOB_ID_OFFSET 0U
+#define INTEL_SIP_SMC_HEADER_CID_MASK 0xF
+#define INTEL_SIP_SMC_HEADER_CID_OFFSET 4U
+#define INTEL_SIP_SMC_HEADER_VERSION_MASK 0xF
+#define INTEL_SIP_SMC_HEADER_VERSION_OFFSET 60U
+
+/* SMC SiP service function identifier for version 1 */
/* FPGA Reconfig */
-#define INTEL_SIP_SMC_FPGA_CONFIG_START 0xC2000001
-#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE 0x42000002
-#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE 0xC2000003
-#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE 0xC2000004
-#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM 0xC2000005
+#define INTEL_SIP_SMC_FPGA_CONFIG_START 0xC2000001
+#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE 0x42000002
+#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE 0xC2000003
+#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE 0xC2000004
+#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM 0xC2000005
/* FPGA Bitstream Flag */
-#define FLAG_PARTIAL_CONFIG BIT(0)
-#define FLAG_AUTHENTICATION BIT(1)
-#define CONFIG_TEST_FLAG(_flag, _type) (((flag) & FLAG_##_type) \
- == FLAG_##_type)
+#define FLAG_PARTIAL_CONFIG BIT(0)
+#define FLAG_AUTHENTICATION BIT(1)
+#define CONFIG_TEST_FLAG(_flag, _type) (((flag) & FLAG_##_type) \
+ == FLAG_##_type)
/* Secure Register Access */
#define INTEL_SIP_SMC_REG_READ 0xC2000007
@@ -39,57 +53,121 @@
#define INTEL_SIP_SMC_REG_UPDATE 0xC2000009
/* Remote System Update */
-#define INTEL_SIP_SMC_RSU_STATUS 0xC200000B
-#define INTEL_SIP_SMC_RSU_UPDATE 0xC200000C
-#define INTEL_SIP_SMC_RSU_NOTIFY 0xC200000E
-#define INTEL_SIP_SMC_RSU_RETRY_COUNTER 0xC200000F
-#define INTEL_SIP_SMC_RSU_DCMF_VERSION 0xC2000010
-#define INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION 0xC2000011
-#define INTEL_SIP_SMC_RSU_MAX_RETRY 0xC2000012
-#define INTEL_SIP_SMC_RSU_COPY_MAX_RETRY 0xC2000013
-#define INTEL_SIP_SMC_RSU_DCMF_STATUS 0xC2000014
-#define INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS 0xC2000015
+#define INTEL_SIP_SMC_RSU_STATUS 0xC200000B
+#define INTEL_SIP_SMC_RSU_UPDATE 0xC200000C
+#define INTEL_SIP_SMC_RSU_NOTIFY 0xC200000E
+#define INTEL_SIP_SMC_RSU_RETRY_COUNTER 0xC200000F
+#define INTEL_SIP_SMC_RSU_DCMF_VERSION 0xC2000010
+#define INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION 0xC2000011
+#define INTEL_SIP_SMC_RSU_MAX_RETRY 0xC2000012
+#define INTEL_SIP_SMC_RSU_COPY_MAX_RETRY 0xC2000013
+#define INTEL_SIP_SMC_RSU_DCMF_STATUS 0xC2000014
+#define INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS 0xC2000015
/* Hardware monitor */
-#define INTEL_SIP_SMC_HWMON_READTEMP 0xC2000020
-#define INTEL_SIP_SMC_HWMON_READVOLT 0xC2000021
-#define TEMP_CHANNEL_MAX (1 << 15)
-#define VOLT_CHANNEL_MAX (1 << 15)
+#define INTEL_SIP_SMC_HWMON_READTEMP 0xC2000020
+#define INTEL_SIP_SMC_HWMON_READVOLT 0xC2000021
+#define TEMP_CHANNEL_MAX (1 << 15)
+#define VOLT_CHANNEL_MAX (1 << 15)
/* ECC */
-#define INTEL_SIP_SMC_ECC_DBE 0xC200000D
+#define INTEL_SIP_SMC_ECC_DBE 0xC200000D
/* Generic Command */
-#define INTEL_SIP_SMC_HPS_SET_BRIDGES 0xC2000032
-#define INTEL_SIP_SMC_GET_ROM_PATCH_SHA384 0xC2000040
+#define INTEL_SIP_SMC_SERVICE_COMPLETED 0xC200001E
+#define INTEL_SIP_SMC_FIRMWARE_VERSION 0xC200001F
+#define INTEL_SIP_SMC_HPS_SET_BRIDGES 0xC2000032
+#define INTEL_SIP_SMC_GET_ROM_PATCH_SHA384 0xC2000040
-/* Send Mailbox Command */
-#define INTEL_SIP_SMC_MBOX_SEND_CMD 0xC200001E
-#define INTEL_SIP_SMC_FIRMWARE_VERSION 0xC200001F
-#define INTEL_SIP_SMC_HPS_SET_BRIDGES 0xC2000032
+#define SERVICE_COMPLETED_MODE_ASYNC 0x00004F4E
/* Mailbox Command */
-#define INTEL_SIP_SMC_GET_USERCODE 0xC200003D
+#define INTEL_SIP_SMC_MBOX_SEND_CMD 0xC200003C
+#define INTEL_SIP_SMC_GET_USERCODE 0xC200003D
-/* SiP Definitions */
+/* FPGA Crypto Services */
+#define INTEL_SIP_SMC_FCS_RANDOM_NUMBER 0xC200005A
+#define INTEL_SIP_SMC_FCS_RANDOM_NUMBER_EXT 0x4200008F
+#define INTEL_SIP_SMC_FCS_CRYPTION 0x4200005B
+#define INTEL_SIP_SMC_FCS_CRYPTION_EXT 0xC2000090
+#define INTEL_SIP_SMC_FCS_SERVICE_REQUEST 0x4200005C
+#define INTEL_SIP_SMC_FCS_SEND_CERTIFICATE 0x4200005D
+#define INTEL_SIP_SMC_FCS_GET_PROVISION_DATA 0x4200005E
+#define INTEL_SIP_SMC_FCS_CNTR_SET_PREAUTH 0xC200005F
+#define INTEL_SIP_SMC_FCS_PSGSIGMA_TEARDOWN 0xC2000064
+#define INTEL_SIP_SMC_FCS_CHIP_ID 0xC2000065
+#define INTEL_SIP_SMC_FCS_ATTESTATION_SUBKEY 0xC2000066
+#define INTEL_SIP_SMC_FCS_ATTESTATION_MEASUREMENTS 0xC2000067
+#define INTEL_SIP_SMC_FCS_GET_ATTESTATION_CERT 0xC2000068
+#define INTEL_SIP_SMC_FCS_CREATE_CERT_ON_RELOAD 0xC2000069
+#define INTEL_SIP_SMC_FCS_OPEN_CS_SESSION 0xC200006E
+#define INTEL_SIP_SMC_FCS_CLOSE_CS_SESSION 0xC200006F
+#define INTEL_SIP_SMC_FCS_IMPORT_CS_KEY 0x42000070
+#define INTEL_SIP_SMC_FCS_EXPORT_CS_KEY 0xC2000071
+#define INTEL_SIP_SMC_FCS_REMOVE_CS_KEY 0xC2000072
+#define INTEL_SIP_SMC_FCS_GET_CS_KEY_INFO 0xC2000073
+#define INTEL_SIP_SMC_FCS_AES_CRYPT_INIT 0xC2000074
+#define INTEL_SIP_SMC_FCS_AES_CRYPT_UPDATE 0x42000075
+#define INTEL_SIP_SMC_FCS_AES_CRYPT_FINALIZE 0x42000076
+#define INTEL_SIP_SMC_FCS_GET_DIGEST_INIT 0xC2000077
+#define INTEL_SIP_SMC_FCS_GET_DIGEST_UPDATE 0xC2000078
+#define INTEL_SIP_SMC_FCS_GET_DIGEST_FINALIZE 0xC2000079
+#define INTEL_SIP_SMC_FCS_MAC_VERIFY_INIT 0xC200007A
+#define INTEL_SIP_SMC_FCS_MAC_VERIFY_UPDATE 0xC200007B
+#define INTEL_SIP_SMC_FCS_MAC_VERIFY_FINALIZE 0xC200007C
+#define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIGN_INIT 0xC200007D
+#define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIGN_FINALIZE 0xC200007F
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_INIT 0xC2000080
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_UPDATE 0xC2000081
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE 0xC2000082
+#define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIG_VERIFY_INIT 0xC2000083
+#define INTEL_SIP_SMC_FCS_ECDSA_HASH_SIG_VERIFY_FINALIZE 0xC2000085
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_INIT 0xC2000086
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_UPDATE 0xC2000087
+#define INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_FINALIZE 0xC2000088
+#define INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_INIT 0xC2000089
+#define INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_FINALIZE 0xC200008B
+#define INTEL_SIP_SMC_FCS_ECDH_REQUEST_INIT 0xC200008C
+#define INTEL_SIP_SMC_FCS_ECDH_REQUEST_FINALIZE 0xC200008E
+
+#define INTEL_SIP_SMC_FCS_SHA_MODE_MASK 0xF
+#define INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK 0xF
+#define INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET 4U
+#define INTEL_SIP_SMC_FCS_ECC_ALGO_MASK 0xF
/* ECC DBE */
-#define WARM_RESET_WFI_FLAG BIT(31)
-#define SYSMGR_ECC_DBE_COLD_RST_MASK (SYSMGR_ECC_OCRAM_MASK |\
- SYSMGR_ECC_DDR0_MASK |\
- SYSMGR_ECC_DDR1_MASK)
+#define WARM_RESET_WFI_FLAG BIT(31)
+#define SYSMGR_ECC_DBE_COLD_RST_MASK (SYSMGR_ECC_OCRAM_MASK |\
+ SYSMGR_ECC_DDR0_MASK |\
+ SYSMGR_ECC_DDR1_MASK)
/* Non-mailbox SMC Call */
-#define INTEL_SIP_SMC_SVC_VERSION 0xC2000200
+#define INTEL_SIP_SMC_SVC_VERSION 0xC2000200
+
+/**
+ * SMC SiP service function identifier for version 2
+ * Command code from 0x400 ~ 0x4FF
+ */
+
+/* V2: Non-mailbox function identifier */
+#define INTEL_SIP_SMC_V2_GET_SVC_VERSION 0xC2000400
+#define INTEL_SIP_SMC_V2_REG_READ 0xC2000401
+#define INTEL_SIP_SMC_V2_REG_WRITE 0xC2000402
+#define INTEL_SIP_SMC_V2_REG_UPDATE 0xC2000403
+#define INTEL_SIP_SMC_V2_HPS_SET_BRIDGES 0xC2000404
+
+/* V2: Mailbox function identifier */
+#define INTEL_SIP_SMC_V2_MAILBOX_SEND_COMMAND 0xC2000420
+#define INTEL_SIP_SMC_V2_MAILBOX_POLL_RESPONSE 0xC2000421
/* SMC function IDs for SiP Service queries */
-#define SIP_SVC_CALL_COUNT 0x8200ff00
-#define SIP_SVC_UID 0x8200ff01
-#define SIP_SVC_VERSION 0x8200ff03
+#define SIP_SVC_CALL_COUNT 0x8200ff00
+#define SIP_SVC_UID 0x8200ff01
+#define SIP_SVC_VERSION 0x8200ff03
/* SiP Service Calls version numbers */
-#define SIP_SVC_VERSION_MAJOR 1
-#define SIP_SVC_VERSION_MINOR 0
+#define SIP_SVC_VERSION_MAJOR 1
+#define SIP_SVC_VERSION_MINOR 0
/* Structure Definitions */
@@ -103,14 +181,31 @@
};
/* Function Definitions */
-
+bool is_size_4_bytes_aligned(uint32_t size);
bool is_address_in_ddr_range(uint64_t addr, uint64_t size);
/* ECC DBE */
bool cold_reset_for_ecc_dbe(void);
uint32_t intel_ecc_dbe_notification(uint64_t dbe_value);
+/* Secure register access */
+uint32_t intel_secure_reg_read(uint64_t reg_addr, uint32_t *retval);
+uint32_t intel_secure_reg_write(uint64_t reg_addr, uint32_t val,
+ uint32_t *retval);
+uint32_t intel_secure_reg_update(uint64_t reg_addr, uint32_t mask,
+ uint32_t val, uint32_t *retval);
+
/* Miscellaneous HPS services */
uint32_t intel_hps_set_bridges(uint64_t enable, uint64_t mask);
+/* SiP Service handler for version 2 */
+uintptr_t sip_smc_handler_v2(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
+ void *cookie,
+ void *handle,
+ u_register_t flags);
+
#endif /* SOCFPGA_SIP_SVC_H */
diff --git a/plat/intel/soc/common/sip/socfpga_sip_fcs.c b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
index 85551a4..c4e30a2 100644
--- a/plat/intel/soc/common/sip/socfpga_sip_fcs.c
+++ b/plat/intel/soc/common/sip/socfpga_sip_fcs.c
@@ -11,13 +11,71 @@
#include "socfpga_mailbox.h"
#include "socfpga_sip_svc.h"
-static bool is_size_4_bytes_aligned(uint32_t size)
+/* FCS static variables */
+static fcs_crypto_service_aes_data fcs_aes_init_payload;
+static fcs_crypto_service_data fcs_sha_get_digest_param;
+static fcs_crypto_service_data fcs_sha_mac_verify_param;
+static fcs_crypto_service_data fcs_ecdsa_hash_sign_param;
+static fcs_crypto_service_data fcs_ecdsa_hash_sig_verify_param;
+static fcs_crypto_service_data fcs_sha2_data_sign_param;
+static fcs_crypto_service_data fcs_sha2_data_sig_verify_param;
+static fcs_crypto_service_data fcs_ecdsa_get_pubkey_param;
+static fcs_crypto_service_data fcs_ecdh_request_param;
+
+bool is_size_4_bytes_aligned(uint32_t size)
{
if ((size % MBOX_WORD_BYTE) != 0U) {
return false;
} else {
return true;
}
+}
+
+static bool is_8_bytes_aligned(uint32_t data)
+{
+ if ((data % (MBOX_WORD_BYTE * 2U)) != 0U) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+static bool is_32_bytes_aligned(uint32_t data)
+{
+ if ((data % (8U * MBOX_WORD_BYTE)) != 0U) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+static int intel_fcs_crypto_service_init(uint32_t session_id,
+ uint32_t context_id, uint32_t key_id,
+ uint32_t param_size, uint64_t param_data,
+ fcs_crypto_service_data *data_addr,
+ uint32_t *mbox_error)
+{
+ if (mbox_error == NULL) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (param_size != 4) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ memset(data_addr, 0, sizeof(fcs_crypto_service_data));
+
+ data_addr->session_id = session_id;
+ data_addr->context_id = context_id;
+ data_addr->key_id = key_id;
+ data_addr->crypto_param_size = param_size;
+ data_addr->crypto_param = param_data;
+
+ data_addr->is_updated = 0;
+
+ *mbox_error = 0;
+
+ return INTEL_SIP_SMC_STATUS_OK;
}
uint32_t intel_fcs_random_number_gen(uint64_t addr, uint64_t *ret_size,
@@ -57,6 +115,45 @@
return INTEL_SIP_SMC_STATUS_OK;
}
+int intel_fcs_random_number_gen_ext(uint32_t session_id, uint32_t context_id,
+ uint32_t size, uint32_t *send_id)
+{
+ int status;
+ uint32_t payload_size;
+ uint32_t crypto_header;
+
+ if (size > (FCS_RANDOM_EXT_MAX_WORD_SIZE *
+ MBOX_WORD_BYTE) || size == 0U) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_size_4_bytes_aligned(size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ crypto_header = (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_FINALIZE) <<
+ FCS_CS_FIELD_FLAG_OFFSET;
+
+ fcs_rng_payload payload = {
+ session_id,
+ context_id,
+ crypto_header,
+ size
+ };
+
+ payload_size = sizeof(payload) / MBOX_WORD_BYTE;
+
+ status = mailbox_send_cmd_async(send_id, MBOX_FCS_RANDOM_GEN,
+ (uint32_t *) &payload, payload_size,
+ CMD_INDIRECT);
+
+ if (status < 0) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
uint32_t intel_fcs_send_cert(uint64_t addr, uint64_t size,
uint32_t *send_id)
{
@@ -74,6 +171,8 @@
(uint32_t *)addr, size / MBOX_WORD_BYTE,
CMD_DIRECT);
+ flush_dcache_range(addr, size);
+
if (status < 0) {
return INTEL_SIP_SMC_STATUS_ERROR;
}
@@ -89,43 +188,123 @@
NULL, 0U, CMD_DIRECT);
if (status < 0) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+uint32_t intel_fcs_cntr_set_preauth(uint8_t counter_type, int32_t counter_value,
+ uint32_t test_bit, uint32_t *mbox_error)
+{
+ int status;
+ uint32_t first_word;
+ uint32_t payload_size;
+
+ if ((test_bit != MBOX_TEST_BIT) &&
+ (test_bit != 0)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if ((counter_type < FCS_BIG_CNTR_SEL) ||
+ (counter_type > FCS_SVN_CNTR_3_SEL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if ((counter_type == FCS_BIG_CNTR_SEL) &&
+ (counter_value > FCS_BIG_CNTR_VAL_MAX)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if ((counter_type >= FCS_SVN_CNTR_0_SEL) &&
+ (counter_type <= FCS_SVN_CNTR_3_SEL) &&
+ (counter_value > FCS_SVN_CNTR_VAL_MAX)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ first_word = test_bit | counter_type;
+ fcs_cntr_set_preauth_payload payload = {
+ first_word,
+ counter_value
+ };
+
+ payload_size = sizeof(payload) / MBOX_WORD_BYTE;
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CNTR_SET_PREAUTH,
+ (uint32_t *) &payload, payload_size,
+ CMD_CASUAL, NULL, NULL);
+
+ if (status < 0) {
+ *mbox_error = -status;
return INTEL_SIP_SMC_STATUS_ERROR;
}
return INTEL_SIP_SMC_STATUS_OK;
}
-uint32_t intel_fcs_cryption(uint32_t mode, uint32_t src_addr,
- uint32_t src_size, uint32_t dst_addr,
- uint32_t dst_size, uint32_t *send_id)
+uint32_t intel_fcs_encryption(uint32_t src_addr, uint32_t src_size,
+ uint32_t dst_addr, uint32_t dst_size, uint32_t *send_id)
{
int status;
- uint32_t cmd;
+ uint32_t load_size;
- fcs_crypt_payload payload = {
- FCS_CRYPTION_DATA_0,
+ fcs_encrypt_payload payload = {
+ FCS_ENCRYPTION_DATA_0,
src_addr,
src_size,
dst_addr,
dst_size };
+ load_size = sizeof(payload) / MBOX_WORD_BYTE;
if (!is_address_in_ddr_range(src_addr, src_size) ||
!is_address_in_ddr_range(dst_addr, dst_size)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
- if (!is_size_4_bytes_aligned(sizeof(fcs_crypt_payload))) {
+ if (!is_size_4_bytes_aligned(src_size)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
}
- if (mode != 0U) {
- cmd = MBOX_FCS_ENCRYPT_REQ;
- } else {
- cmd = MBOX_FCS_DECRYPT_REQ;
+ status = mailbox_send_cmd_async(send_id, MBOX_FCS_ENCRYPT_REQ,
+ (uint32_t *) &payload, load_size,
+ CMD_INDIRECT);
+ inv_dcache_range(dst_addr, dst_size);
+
+ if (status < 0) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+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 status;
+ uint32_t load_size;
+ uintptr_t id_offset;
+
+ id_offset = src_addr + FCS_OWNER_ID_OFFSET;
+ fcs_decrypt_payload payload = {
+ FCS_DECRYPTION_DATA_0,
+ {mmio_read_32(id_offset),
+ mmio_read_32(id_offset + MBOX_WORD_BYTE)},
+ src_addr,
+ src_size,
+ dst_addr,
+ dst_size };
+ load_size = sizeof(payload) / MBOX_WORD_BYTE;
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_size_4_bytes_aligned(src_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
}
- status = mailbox_send_cmd_async(send_id, cmd, (uint32_t *) &payload,
- sizeof(fcs_crypt_payload) / MBOX_WORD_BYTE,
+ status = mailbox_send_cmd_async(send_id, MBOX_FCS_DECRYPT_REQ,
+ (uint32_t *) &payload, load_size,
CMD_INDIRECT);
inv_dcache_range(dst_addr, dst_size);
@@ -165,3 +344,1396 @@
return INTEL_SIP_SMC_STATUS_OK;
}
+
+int intel_fcs_encryption_ext(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 status;
+ uint32_t payload_size;
+ uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
+ uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
+
+ if ((dst_size == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_size_4_bytes_aligned(src_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ fcs_encrypt_ext_payload payload = {
+ session_id,
+ context_id,
+ FCS_CRYPTION_CRYPTO_HEADER,
+ src_addr,
+ src_size,
+ dst_addr,
+ *dst_size
+ };
+
+ payload_size = sizeof(payload) / MBOX_WORD_BYTE;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ENCRYPT_REQ,
+ (uint32_t *) &payload, payload_size,
+ CMD_CASUAL, resp_data, &resp_len);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
+ *mbox_error = MBOX_RET_ERROR;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
+ inv_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_decryption_ext(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 status;
+ uintptr_t id_offset;
+ uint32_t payload_size;
+ uint32_t resp_len = FCS_CRYPTION_RESP_WORD_SIZE;
+ uint32_t resp_data[FCS_CRYPTION_RESP_WORD_SIZE] = {0U};
+
+ if ((dst_size == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_size_4_bytes_aligned(src_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ id_offset = src_addr + FCS_OWNER_ID_OFFSET;
+ fcs_decrypt_ext_payload payload = {
+ session_id,
+ context_id,
+ FCS_CRYPTION_CRYPTO_HEADER,
+ {mmio_read_32(id_offset),
+ mmio_read_32(id_offset + MBOX_WORD_BYTE)},
+ src_addr,
+ src_size,
+ dst_addr,
+ *dst_size
+ };
+
+ payload_size = sizeof(payload) / MBOX_WORD_BYTE;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_DECRYPT_REQ,
+ (uint32_t *) &payload, payload_size,
+ CMD_CASUAL, resp_data, &resp_len);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ if (resp_len != FCS_CRYPTION_RESP_WORD_SIZE) {
+ *mbox_error = MBOX_RET_ERROR;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = resp_data[FCS_CRYPTION_RESP_SIZE_OFFSET];
+ inv_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_sigma_teardown(uint32_t session_id, uint32_t *mbox_error)
+{
+ int status;
+
+ if ((session_id != PSGSIGMA_SESSION_ID_ONE) &&
+ (session_id != PSGSIGMA_UNKNOWN_SESSION)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ psgsigma_teardown_msg message = {
+ RESERVED_AS_ZERO,
+ PSGSIGMA_TEARDOWN_MAGIC,
+ session_id
+ };
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_PSG_SIGMA_TEARDOWN,
+ (uint32_t *) &message, sizeof(message) / MBOX_WORD_BYTE,
+ CMD_CASUAL, NULL, NULL);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_chip_id(uint32_t *id_low, uint32_t *id_high, uint32_t *mbox_error)
+{
+ int status;
+ uint32_t load_size;
+ uint32_t chip_id[2];
+
+ load_size = sizeof(chip_id) / MBOX_WORD_BYTE;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_GET_CHIPID, NULL,
+ 0U, CMD_CASUAL, (uint32_t *) chip_id, &load_size);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *id_low = chip_id[0];
+ *id_high = chip_id[1];
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_attestation_subkey(uint64_t src_addr, uint32_t src_size,
+ uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
+{
+ int status;
+ uint32_t send_size = src_size / MBOX_WORD_BYTE;
+ uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
+
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_ATTESTATION_SUBKEY,
+ (uint32_t *) src_addr, send_size, CMD_CASUAL,
+ (uint32_t *) dst_addr, &ret_size);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = ret_size * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_get_measurement(uint64_t src_addr, uint32_t src_size,
+ uint64_t dst_addr, uint32_t *dst_size, uint32_t *mbox_error)
+{
+ int status;
+ uint32_t send_size = src_size / MBOX_WORD_BYTE;
+ uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_MEASUREMENT,
+ (uint32_t *) src_addr, send_size, CMD_CASUAL,
+ (uint32_t *) dst_addr, &ret_size);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = ret_size * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_get_attestation_cert(uint32_t cert_request, uint64_t dst_addr,
+ uint32_t *dst_size, uint32_t *mbox_error)
+{
+ int status;
+ uint32_t ret_size = *dst_size / MBOX_WORD_BYTE;
+
+ if (mbox_error == NULL) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (cert_request < FCS_ATTEST_FIRMWARE_CERT ||
+ cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_GET_ATTESTATION_CERT,
+ (uint32_t *) &cert_request, 1U, CMD_CASUAL,
+ (uint32_t *) dst_addr, &ret_size);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = ret_size * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_create_cert_on_reload(uint32_t cert_request,
+ uint32_t *mbox_error)
+{
+ int status;
+
+ if (mbox_error == NULL) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (cert_request < FCS_ATTEST_FIRMWARE_CERT ||
+ cert_request > FCS_ATTEST_CERT_MAX_REQ_PARAM) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_CREATE_CERT_ON_RELOAD,
+ (uint32_t *) &cert_request, 1U, CMD_CASUAL,
+ NULL, NULL);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_open_crypto_service_session(uint32_t *session_id,
+ uint32_t *mbox_error)
+{
+ int status;
+ uint32_t resp_len = 1U;
+
+ if ((session_id == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_OPEN_CS_SESSION,
+ NULL, 0U, CMD_CASUAL, session_id, &resp_len);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_close_crypto_service_session(uint32_t session_id,
+ uint32_t *mbox_error)
+{
+ int status;
+
+ if (mbox_error == NULL) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_CLOSE_CS_SESSION,
+ &session_id, 1U, CMD_CASUAL, NULL, NULL);
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_import_crypto_service_key(uint64_t src_addr, uint32_t src_size,
+ uint32_t *send_id)
+{
+ int status;
+
+ if (src_size > (FCS_CS_KEY_OBJ_MAX_WORD_SIZE *
+ MBOX_WORD_BYTE)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(src_addr, src_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ status = mailbox_send_cmd_async(send_id, MBOX_FCS_IMPORT_CS_KEY,
+ (uint32_t *)src_addr, src_size / MBOX_WORD_BYTE,
+ CMD_INDIRECT);
+
+ if (status < 0) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_export_crypto_service_key(uint32_t session_id, uint32_t key_id,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error)
+{
+ int status;
+ uint32_t i;
+ uint32_t payload_size;
+ uint32_t resp_len = FCS_CS_KEY_OBJ_MAX_WORD_SIZE;
+ uint32_t resp_data[FCS_CS_KEY_OBJ_MAX_WORD_SIZE] = {0U};
+ uint32_t op_status = 0U;
+
+ if ((dst_size == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ fcs_cs_key_payload payload = {
+ session_id,
+ RESERVED_AS_ZERO,
+ RESERVED_AS_ZERO,
+ key_id
+ };
+
+ payload_size = sizeof(payload) / MBOX_WORD_BYTE;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_EXPORT_CS_KEY,
+ (uint32_t *) &payload, payload_size,
+ CMD_CASUAL, resp_data, &resp_len);
+
+ if (resp_len > 0) {
+ op_status = resp_data[0] & FCS_CS_KEY_RESP_STATUS_MASK;
+ }
+
+ if (status < 0) {
+ *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ if (resp_len > 1) {
+
+ /* Export key object is start at second response data */
+ *dst_size = (resp_len - 1) * MBOX_WORD_BYTE;
+
+ for (i = 1U; i < resp_len; i++) {
+ mmio_write_32(dst_addr, resp_data[i]);
+ dst_addr += MBOX_WORD_BYTE;
+ }
+
+ flush_dcache_range(dst_addr - *dst_size, *dst_size);
+
+ } else {
+
+ /* Unexpected response, missing key object in response */
+ *mbox_error = MBOX_RET_ERROR;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_remove_crypto_service_key(uint32_t session_id, uint32_t key_id,
+ uint32_t *mbox_error)
+{
+ int status;
+ uint32_t payload_size;
+ uint32_t resp_len = 1U;
+ uint32_t resp_data = 0U;
+ uint32_t op_status = 0U;
+
+ if (mbox_error == NULL) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ fcs_cs_key_payload payload = {
+ session_id,
+ RESERVED_AS_ZERO,
+ RESERVED_AS_ZERO,
+ key_id
+ };
+
+ payload_size = sizeof(payload) / MBOX_WORD_BYTE;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_REMOVE_CS_KEY,
+ (uint32_t *) &payload, payload_size,
+ CMD_CASUAL, &resp_data, &resp_len);
+
+ if (resp_len > 0) {
+ op_status = resp_data & FCS_CS_KEY_RESP_STATUS_MASK;
+ }
+
+ if (status < 0) {
+ *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+int intel_fcs_get_crypto_service_key_info(uint32_t session_id, uint32_t key_id,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error)
+{
+ int status;
+ uint32_t payload_size;
+ uint32_t resp_len = FCS_CS_KEY_INFO_MAX_WORD_SIZE;
+ uint32_t op_status = 0U;
+
+ if ((dst_size == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ fcs_cs_key_payload payload = {
+ session_id,
+ RESERVED_AS_ZERO,
+ RESERVED_AS_ZERO,
+ key_id
+ };
+
+ payload_size = sizeof(payload) / MBOX_WORD_BYTE;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_CS_KEY_INFO,
+ (uint32_t *) &payload, payload_size,
+ CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
+
+ if (resp_len > 0) {
+ op_status = mmio_read_32(dst_addr) &
+ FCS_CS_KEY_RESP_STATUS_MASK;
+ }
+
+ if (status < 0) {
+ *mbox_error = (-status) | (op_status << FCS_CS_KEY_RESP_STATUS_OFFSET);
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = resp_len * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+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)
+{
+ return intel_fcs_crypto_service_init(session_id, context_id,
+ key_id, param_size, param_data,
+ (void *) &fcs_sha_get_digest_param,
+ mbox_error);
+}
+
+int intel_fcs_get_digest_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 status;
+ uint32_t i;
+ uint32_t flag;
+ uint32_t crypto_header;
+ uint32_t resp_len;
+ uint32_t payload[FCS_GET_DIGEST_CMD_MAX_WORD_SIZE] = {0U};
+
+ if (dst_size == NULL || mbox_error == NULL) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (fcs_sha_get_digest_param.session_id != session_id ||
+ fcs_sha_get_digest_param.context_id != context_id) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ /* Source data must be 8 bytes aligned */
+ if (!is_8_bytes_aligned(src_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ resp_len = *dst_size / MBOX_WORD_BYTE;
+
+ /* Prepare crypto header */
+ flag = 0;
+
+ if (fcs_sha_get_digest_param.is_updated) {
+ fcs_sha_get_digest_param.crypto_param_size = 0;
+ } else {
+ flag |= FCS_CS_FIELD_FLAG_INIT;
+ }
+
+ if (is_finalised != 0U) {
+ flag |= FCS_CS_FIELD_FLAG_FINALIZE;
+ } else {
+ flag |= FCS_CS_FIELD_FLAG_UPDATE;
+ fcs_sha_get_digest_param.is_updated = 1;
+ }
+
+ crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
+ (fcs_sha_get_digest_param.crypto_param_size &
+ FCS_CS_FIELD_SIZE_MASK));
+
+ /* Prepare command payload */
+ i = 0;
+ payload[i] = fcs_sha_get_digest_param.session_id;
+ i++;
+ payload[i] = fcs_sha_get_digest_param.context_id;
+ i++;
+ payload[i] = crypto_header;
+ i++;
+
+ if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
+ FCS_CS_FIELD_FLAG_INIT) {
+ payload[i] = fcs_sha_get_digest_param.key_id;
+ i++;
+ /* Crypto parameters */
+ payload[i] = fcs_sha_get_digest_param.crypto_param
+ & INTEL_SIP_SMC_FCS_SHA_MODE_MASK;
+ payload[i] |= ((fcs_sha_get_digest_param.crypto_param
+ >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
+ & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
+ << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
+ i++;
+ }
+ /* Data source address and size */
+ payload[i] = src_addr;
+ i++;
+ payload[i] = src_size;
+ i++;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_GET_DIGEST_REQ,
+ payload, i, CMD_CASUAL,
+ (uint32_t *) dst_addr, &resp_len);
+
+ if (is_finalised != 0U) {
+ memset((void *)&fcs_sha_get_digest_param, 0,
+ sizeof(fcs_crypto_service_data));
+ }
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = resp_len * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+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)
+{
+ return intel_fcs_crypto_service_init(session_id, context_id,
+ key_id, param_size, param_data,
+ (void *) &fcs_sha_mac_verify_param,
+ mbox_error);
+}
+
+int intel_fcs_mac_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 status;
+ uint32_t i;
+ uint32_t flag;
+ uint32_t crypto_header;
+ uint32_t resp_len;
+ uint32_t payload[FCS_MAC_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
+ uintptr_t mac_offset;
+
+ if (dst_size == NULL || mbox_error == NULL) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (fcs_sha_mac_verify_param.session_id != session_id ||
+ fcs_sha_mac_verify_param.context_id != context_id) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (data_size >= src_size) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_size_4_bytes_aligned(src_size) ||
+ !is_8_bytes_aligned(data_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ resp_len = *dst_size / MBOX_WORD_BYTE;
+
+ /* Prepare crypto header */
+ flag = 0;
+
+ if (fcs_sha_mac_verify_param.is_updated) {
+ fcs_sha_mac_verify_param.crypto_param_size = 0;
+ } else {
+ flag |= FCS_CS_FIELD_FLAG_INIT;
+ }
+
+ if (is_finalised) {
+ flag |= FCS_CS_FIELD_FLAG_FINALIZE;
+ } else {
+ flag |= FCS_CS_FIELD_FLAG_UPDATE;
+ fcs_sha_mac_verify_param.is_updated = 1;
+ }
+
+ crypto_header = ((flag << FCS_CS_FIELD_FLAG_OFFSET) |
+ (fcs_sha_mac_verify_param.crypto_param_size &
+ FCS_CS_FIELD_SIZE_MASK));
+
+ /* Prepare command payload */
+ i = 0;
+ payload[i] = fcs_sha_mac_verify_param.session_id;
+ i++;
+ payload[i] = fcs_sha_mac_verify_param.context_id;
+ i++;
+ payload[i] = crypto_header;
+ i++;
+
+ if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
+ FCS_CS_FIELD_FLAG_INIT) {
+ payload[i] = fcs_sha_mac_verify_param.key_id;
+ i++;
+ /* Crypto parameters */
+ payload[i] = ((fcs_sha_mac_verify_param.crypto_param
+ >> INTEL_SIP_SMC_FCS_DIGEST_SIZE_OFFSET)
+ & INTEL_SIP_SMC_FCS_DIGEST_SIZE_MASK)
+ << FCS_SHA_HMAC_CRYPTO_PARAM_SIZE_OFFSET;
+ i++;
+ }
+ /* Data source address and size */
+ payload[i] = src_addr;
+ i++;
+ payload[i] = data_size;
+ i++;
+
+ if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
+ FCS_CS_FIELD_FLAG_FINALIZE) {
+ /* Copy mac data to command */
+ mac_offset = src_addr + data_size;
+ memcpy((uint8_t *) &payload[i], (uint8_t *) mac_offset,
+ src_size - data_size);
+
+ i += (src_size - data_size) / MBOX_WORD_BYTE;
+ }
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_MAC_VERIFY_REQ,
+ payload, i, CMD_CASUAL,
+ (uint32_t *) dst_addr, &resp_len);
+
+ if (is_finalised) {
+ memset((void *)&fcs_sha_mac_verify_param, 0,
+ sizeof(fcs_crypto_service_data));
+ }
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = resp_len * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+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)
+{
+ return intel_fcs_crypto_service_init(session_id, context_id,
+ key_id, param_size, param_data,
+ (void *) &fcs_ecdsa_hash_sign_param,
+ mbox_error);
+}
+
+int intel_fcs_ecdsa_hash_sign_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 *mbox_error)
+{
+ int status;
+ uint32_t i;
+ uint32_t payload[FCS_ECDSA_HASH_SIGN_CMD_MAX_WORD_SIZE] = {0U};
+ uint32_t resp_len;
+ uintptr_t hash_data_addr;
+
+ if ((dst_size == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (fcs_ecdsa_hash_sign_param.session_id != session_id ||
+ fcs_ecdsa_hash_sign_param.context_id != context_id) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ resp_len = *dst_size / MBOX_WORD_BYTE;
+
+ /* Prepare command payload */
+ /* Crypto header */
+ i = 0;
+ payload[i] = fcs_ecdsa_hash_sign_param.session_id;
+ i++;
+ payload[i] = fcs_ecdsa_hash_sign_param.context_id;
+
+ i++;
+ payload[i] = fcs_ecdsa_hash_sign_param.crypto_param_size
+ & FCS_CS_FIELD_SIZE_MASK;
+ payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
+ | FCS_CS_FIELD_FLAG_FINALIZE)
+ << FCS_CS_FIELD_FLAG_OFFSET;
+ i++;
+ payload[i] = fcs_ecdsa_hash_sign_param.key_id;
+
+ /* Crypto parameters */
+ i++;
+ payload[i] = fcs_ecdsa_hash_sign_param.crypto_param
+ & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
+
+ /* Hash Data */
+ i++;
+ hash_data_addr = src_addr;
+ memcpy((uint8_t *) &payload[i], (uint8_t *) hash_data_addr,
+ src_size);
+
+ i += src_size / MBOX_WORD_BYTE;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIGN_REQ,
+ payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
+ &resp_len);
+
+ memset((void *) &fcs_ecdsa_hash_sign_param,
+ 0, sizeof(fcs_crypto_service_data));
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = resp_len * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+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)
+{
+ return intel_fcs_crypto_service_init(session_id, context_id,
+ key_id, param_size, param_data,
+ (void *) &fcs_ecdsa_hash_sig_verify_param,
+ mbox_error);
+}
+
+int intel_fcs_ecdsa_hash_sig_verify_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 *mbox_error)
+{
+ int status;
+ uint32_t i = 0;
+ uint32_t payload[FCS_ECDSA_HASH_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
+ uint32_t resp_len;
+ uintptr_t hash_sig_pubkey_addr;
+
+ if ((dst_size == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (fcs_ecdsa_hash_sig_verify_param.session_id != session_id ||
+ fcs_ecdsa_hash_sig_verify_param.context_id != context_id) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ resp_len = *dst_size / MBOX_WORD_BYTE;
+
+ /* Prepare command payload */
+ /* Crypto header */
+ i = 0;
+ payload[i] = fcs_ecdsa_hash_sig_verify_param.session_id;
+
+ i++;
+ payload[i] = fcs_ecdsa_hash_sig_verify_param.context_id;
+
+ i++;
+ payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param_size
+ & FCS_CS_FIELD_SIZE_MASK;
+ payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
+ | FCS_CS_FIELD_FLAG_FINALIZE)
+ << FCS_CS_FIELD_FLAG_OFFSET;
+
+ i++;
+ payload[i] = fcs_ecdsa_hash_sig_verify_param.key_id;
+
+ /* Crypto parameters */
+ i++;
+ payload[i] = fcs_ecdsa_hash_sig_verify_param.crypto_param
+ & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
+
+ /* Hash Data Word, Signature Data Word and Public Key Data word */
+ i++;
+ hash_sig_pubkey_addr = src_addr;
+ memcpy((uint8_t *) &payload[i],
+ (uint8_t *) hash_sig_pubkey_addr, src_size);
+
+ i += (src_size / MBOX_WORD_BYTE);
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_HASH_SIG_VERIFY,
+ payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
+ &resp_len);
+
+ memset((void *)&fcs_ecdsa_hash_sig_verify_param,
+ 0, sizeof(fcs_crypto_service_data));
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = resp_len * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+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)
+{
+ return intel_fcs_crypto_service_init(session_id, context_id,
+ key_id, param_size, param_data,
+ (void *) &fcs_sha2_data_sign_param,
+ 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 status;
+ int i;
+ uint32_t flag;
+ uint32_t crypto_header;
+ uint32_t payload[FCS_ECDSA_SHA2_DATA_SIGN_CMD_MAX_WORD_SIZE] = {0U};
+ uint32_t resp_len;
+
+ if ((dst_size == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (fcs_sha2_data_sign_param.session_id != session_id ||
+ fcs_sha2_data_sign_param.context_id != context_id) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ /* Source data must be 8 bytes aligned */
+ if (!is_8_bytes_aligned(src_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ resp_len = *dst_size / MBOX_WORD_BYTE;
+
+ /* Prepare crypto header */
+ flag = 0;
+ if (fcs_sha2_data_sign_param.is_updated) {
+ fcs_sha2_data_sign_param.crypto_param_size = 0;
+ } else {
+ flag |= FCS_CS_FIELD_FLAG_INIT;
+ }
+
+ if (is_finalised != 0U) {
+ flag |= FCS_CS_FIELD_FLAG_FINALIZE;
+ } else {
+ flag |= FCS_CS_FIELD_FLAG_UPDATE;
+ fcs_sha2_data_sign_param.is_updated = 1;
+ }
+ crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
+ fcs_sha2_data_sign_param.crypto_param_size;
+
+ /* Prepare command payload */
+ i = 0;
+ payload[i] = fcs_sha2_data_sign_param.session_id;
+ i++;
+ payload[i] = fcs_sha2_data_sign_param.context_id;
+ i++;
+ payload[i] = crypto_header;
+ i++;
+
+ if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
+ FCS_CS_FIELD_FLAG_INIT) {
+ payload[i] = fcs_sha2_data_sign_param.key_id;
+ /* Crypto parameters */
+ i++;
+ payload[i] = fcs_sha2_data_sign_param.crypto_param
+ & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
+ i++;
+ }
+
+ /* Data source address and size */
+ payload[i] = src_addr;
+ i++;
+ payload[i] = src_size;
+ i++;
+ status = mailbox_send_cmd(MBOX_JOB_ID,
+ MBOX_FCS_ECDSA_SHA2_DATA_SIGN_REQ, payload,
+ i, CMD_CASUAL, (uint32_t *) dst_addr,
+ &resp_len);
+
+ if (is_finalised != 0U) {
+ memset((void *)&fcs_sha2_data_sign_param, 0,
+ sizeof(fcs_crypto_service_data));
+ }
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = resp_len * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+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)
+{
+ return intel_fcs_crypto_service_init(session_id, context_id,
+ key_id, param_size, param_data,
+ (void *) &fcs_sha2_data_sig_verify_param,
+ 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 status;
+ uint32_t i;
+ uint32_t flag;
+ uint32_t crypto_header;
+ uint32_t payload[FCS_ECDSA_SHA2_DATA_SIG_VERIFY_CMD_MAX_WORD_SIZE] = {0U};
+ uint32_t resp_len;
+ uintptr_t sig_pubkey_offset;
+
+ if ((dst_size == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (fcs_sha2_data_sig_verify_param.session_id != session_id ||
+ fcs_sha2_data_sig_verify_param.context_id != context_id) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_size_4_bytes_aligned(src_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_8_bytes_aligned(data_size) ||
+ !is_8_bytes_aligned(src_addr)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ resp_len = *dst_size / MBOX_WORD_BYTE;
+
+ /* Prepare crypto header */
+ flag = 0;
+ if (fcs_sha2_data_sig_verify_param.is_updated)
+ fcs_sha2_data_sig_verify_param.crypto_param_size = 0;
+ else
+ flag |= FCS_CS_FIELD_FLAG_INIT;
+
+ if (is_finalised != 0U)
+ flag |= FCS_CS_FIELD_FLAG_FINALIZE;
+ else {
+ flag |= FCS_CS_FIELD_FLAG_UPDATE;
+ fcs_sha2_data_sig_verify_param.is_updated = 1;
+ }
+ crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
+ fcs_sha2_data_sig_verify_param.crypto_param_size;
+
+ /* Prepare command payload */
+ i = 0;
+ payload[i] = fcs_sha2_data_sig_verify_param.session_id;
+ i++;
+ payload[i] = fcs_sha2_data_sig_verify_param.context_id;
+ i++;
+ payload[i] = crypto_header;
+ i++;
+
+ if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
+ FCS_CS_FIELD_FLAG_INIT) {
+ payload[i] = fcs_sha2_data_sig_verify_param.key_id;
+ i++;
+ /* Crypto parameters */
+ payload[i] = fcs_sha2_data_sig_verify_param.crypto_param
+ & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
+ i++;
+ }
+
+ /* Data source address and size */
+ payload[i] = src_addr;
+ i++;
+ payload[i] = data_size;
+ i++;
+
+ if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
+ FCS_CS_FIELD_FLAG_FINALIZE) {
+ /* Signature + Public Key Data */
+ sig_pubkey_offset = src_addr + data_size;
+ memcpy((uint8_t *) &payload[i], (uint8_t *) sig_pubkey_offset,
+ src_size - data_size);
+
+ i += (src_size - data_size) / MBOX_WORD_BYTE;
+ }
+
+ status = mailbox_send_cmd(MBOX_JOB_ID,
+ MBOX_FCS_ECDSA_SHA2_DATA_SIGN_VERIFY, payload, i,
+ CMD_CASUAL, (uint32_t *) dst_addr, &resp_len);
+
+ if (is_finalised != 0U) {
+ memset((void *) &fcs_sha2_data_sig_verify_param, 0,
+ sizeof(fcs_crypto_service_data));
+ }
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = resp_len * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+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)
+{
+ return intel_fcs_crypto_service_init(session_id, context_id,
+ key_id, param_size, param_data,
+ (void *) &fcs_ecdsa_get_pubkey_param,
+ mbox_error);
+}
+
+int intel_fcs_ecdsa_get_pubkey_finalize(uint32_t session_id, uint32_t context_id,
+ uint64_t dst_addr, uint32_t *dst_size,
+ uint32_t *mbox_error)
+{
+ int status;
+ int i;
+ uint32_t crypto_header;
+ uint32_t ret_size;
+ uint32_t payload[FCS_ECDSA_GET_PUBKEY_MAX_WORD_SIZE] = {0U};
+
+ if ((dst_size == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (fcs_ecdsa_get_pubkey_param.session_id != session_id ||
+ fcs_ecdsa_get_pubkey_param.context_id != context_id) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ ret_size = *dst_size / MBOX_WORD_BYTE;
+
+ crypto_header = ((FCS_CS_FIELD_FLAG_INIT |
+ FCS_CS_FIELD_FLAG_UPDATE |
+ FCS_CS_FIELD_FLAG_FINALIZE) <<
+ FCS_CS_FIELD_FLAG_OFFSET) |
+ fcs_ecdsa_get_pubkey_param.crypto_param_size;
+ i = 0;
+ /* Prepare command payload */
+ payload[i] = session_id;
+ i++;
+ payload[i] = context_id;
+ i++;
+ payload[i] = crypto_header;
+ i++;
+ payload[i] = fcs_ecdsa_get_pubkey_param.key_id;
+ i++;
+ payload[i] = (uint32_t) fcs_ecdsa_get_pubkey_param.crypto_param &
+ INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
+ i++;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDSA_GET_PUBKEY,
+ payload, i, CMD_CASUAL,
+ (uint32_t *) dst_addr, &ret_size);
+
+ memset((void *) &fcs_ecdsa_get_pubkey_param, 0,
+ sizeof(fcs_crypto_service_data));
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = ret_size * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+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)
+{
+ return intel_fcs_crypto_service_init(session_id, context_id,
+ key_id, param_size, param_data,
+ (void *) &fcs_ecdh_request_param,
+ mbox_error);
+}
+
+int intel_fcs_ecdh_request_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 *mbox_error)
+{
+ int status;
+ uint32_t i;
+ uint32_t payload[FCS_ECDH_REQUEST_CMD_MAX_WORD_SIZE] = {0U};
+ uint32_t resp_len;
+ uintptr_t pubkey;
+
+ if ((dst_size == NULL) || (mbox_error == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (fcs_ecdh_request_param.session_id != session_id ||
+ fcs_ecdh_request_param.context_id != context_id) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(src_addr, src_size) ||
+ !is_address_in_ddr_range(dst_addr, *dst_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ resp_len = *dst_size / MBOX_WORD_BYTE;
+
+ /* Prepare command payload */
+ i = 0;
+ /* Crypto header */
+ payload[i] = fcs_ecdh_request_param.session_id;
+ i++;
+ payload[i] = fcs_ecdh_request_param.context_id;
+ i++;
+ payload[i] = fcs_ecdh_request_param.crypto_param_size
+ & FCS_CS_FIELD_SIZE_MASK;
+ payload[i] |= (FCS_CS_FIELD_FLAG_INIT | FCS_CS_FIELD_FLAG_UPDATE
+ | FCS_CS_FIELD_FLAG_FINALIZE)
+ << FCS_CS_FIELD_FLAG_OFFSET;
+ i++;
+ payload[i] = fcs_ecdh_request_param.key_id;
+ i++;
+ /* Crypto parameters */
+ payload[i] = fcs_ecdh_request_param.crypto_param
+ & INTEL_SIP_SMC_FCS_ECC_ALGO_MASK;
+ i++;
+ /* Public key data */
+ pubkey = src_addr;
+ memcpy((uint8_t *) &payload[i], (uint8_t *) pubkey, src_size);
+ i += src_size / MBOX_WORD_BYTE;
+
+ status = mailbox_send_cmd(MBOX_JOB_ID, MBOX_FCS_ECDH_REQUEST,
+ payload, i, CMD_CASUAL, (uint32_t *) dst_addr,
+ &resp_len);
+
+ memset((void *)&fcs_ecdh_request_param, 0,
+ sizeof(fcs_crypto_service_data));
+
+ if (status < 0) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ *dst_size = resp_len * MBOX_WORD_BYTE;
+ flush_dcache_range(dst_addr, *dst_size);
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+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)
+{
+ if (mbox_error == NULL) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ memset((void *)&fcs_aes_init_payload, 0U, sizeof(fcs_aes_init_payload));
+
+ fcs_aes_init_payload.session_id = session_id;
+ fcs_aes_init_payload.context_id = context_id;
+ fcs_aes_init_payload.param_size = param_size;
+ fcs_aes_init_payload.key_id = key_id;
+
+ memcpy((uint8_t *) fcs_aes_init_payload.crypto_param,
+ (uint8_t *) param_addr, param_size);
+
+ fcs_aes_init_payload.is_updated = 0;
+
+ *mbox_error = 0;
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
+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 status;
+ int i;
+ uint32_t flag;
+ uint32_t crypto_header;
+ uint32_t fcs_aes_crypt_payload[FCS_AES_CMD_MAX_WORD_SIZE];
+
+ if (fcs_aes_init_payload.session_id != session_id ||
+ fcs_aes_init_payload.context_id != context_id) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if ((!is_8_bytes_aligned(src_addr)) ||
+ (!is_32_bytes_aligned(src_size)) ||
+ (!is_address_in_ddr_range(src_addr, src_size))) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if ((!is_8_bytes_aligned(dst_addr)) ||
+ (!is_32_bytes_aligned(dst_size))) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if ((dst_size > FCS_AES_MAX_DATA_SIZE ||
+ dst_size < FCS_AES_MIN_DATA_SIZE) ||
+ (src_size > FCS_AES_MAX_DATA_SIZE ||
+ src_size < FCS_AES_MIN_DATA_SIZE)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ /* Prepare crypto header*/
+ flag = 0;
+ if (fcs_aes_init_payload.is_updated) {
+ fcs_aes_init_payload.param_size = 0;
+ } else {
+ flag |= FCS_CS_FIELD_FLAG_INIT;
+ }
+
+ if (is_finalised != 0U) {
+ flag |= FCS_CS_FIELD_FLAG_FINALIZE;
+ } else {
+ flag |= FCS_CS_FIELD_FLAG_UPDATE;
+ fcs_aes_init_payload.is_updated = 1;
+ }
+ crypto_header = (flag << FCS_CS_FIELD_FLAG_OFFSET) |
+ fcs_aes_init_payload.param_size;
+
+ i = 0U;
+ fcs_aes_crypt_payload[i] = session_id;
+ i++;
+ fcs_aes_crypt_payload[i] = context_id;
+ i++;
+ fcs_aes_crypt_payload[i] = crypto_header;
+ i++;
+
+ if ((crypto_header >> FCS_CS_FIELD_FLAG_OFFSET) &
+ FCS_CS_FIELD_FLAG_INIT) {
+ fcs_aes_crypt_payload[i] = fcs_aes_init_payload.key_id;
+ i++;
+
+ memcpy((uint8_t *) &fcs_aes_crypt_payload[i],
+ (uint8_t *) fcs_aes_init_payload.crypto_param,
+ fcs_aes_init_payload.param_size);
+
+ i += fcs_aes_init_payload.param_size / MBOX_WORD_BYTE;
+ }
+
+ fcs_aes_crypt_payload[i] = (uint32_t) src_addr;
+ i++;
+ fcs_aes_crypt_payload[i] = src_size;
+ i++;
+ fcs_aes_crypt_payload[i] = (uint32_t) dst_addr;
+ i++;
+ fcs_aes_crypt_payload[i] = dst_size;
+ i++;
+
+ status = mailbox_send_cmd_async(send_id, MBOX_FCS_AES_CRYPT_REQ,
+ fcs_aes_crypt_payload, i,
+ CMD_INDIRECT);
+
+ if (is_finalised != 0U) {
+ memset((void *)&fcs_aes_init_payload, 0,
+ sizeof(fcs_aes_init_payload));
+ }
+
+ if (status < 0U) {
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
diff --git a/plat/intel/soc/common/soc/socfpga_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c
index 8ecd6db..778d4af 100644
--- a/plat/intel/soc/common/soc/socfpga_mailbox.c
+++ b/plat/intel/soc/common/soc/socfpga_mailbox.c
@@ -11,6 +11,8 @@
#include "socfpga_mailbox.h"
#include "socfpga_sip_svc.h"
+static mailbox_payload_t mailbox_resp_payload;
+static mailbox_container_t mailbox_resp_ctr = {0, 0, &mailbox_resp_payload};
static bool is_mailbox_cmdbuf_full(uint32_t cin)
{
@@ -171,6 +173,95 @@
return MBOX_NO_RESPONSE;
}
+int mailbox_read_response_async(unsigned int *job_id, uint32_t *header,
+ uint32_t *response, unsigned int *resp_len,
+ uint8_t ignore_client_id)
+{
+ uint32_t rin;
+ uint32_t rout;
+ uint32_t resp_data;
+ uint32_t ret_resp_len = 0;
+ uint8_t is_done = 0;
+
+ if ((mailbox_resp_ctr.flag & MBOX_PAYLOAD_FLAG_BUSY) != 0) {
+ ret_resp_len = MBOX_RESP_LEN(
+ mailbox_resp_ctr.payload->header) -
+ mailbox_resp_ctr.index;
+ }
+
+ if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) == 1U) {
+ mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0U);
+ }
+
+ rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
+ rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT);
+
+ while (rout != rin && !is_done) {
+
+ resp_data = mmio_read_32(MBOX_ENTRY_TO_ADDR(RESP, (rout)++));
+
+ rout %= MBOX_RESP_BUFFER_SIZE;
+ mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout);
+ rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN);
+
+ if ((mailbox_resp_ctr.flag & MBOX_PAYLOAD_FLAG_BUSY) != 0) {
+ mailbox_resp_ctr.payload->data[mailbox_resp_ctr.index] = resp_data;
+ mailbox_resp_ctr.index++;
+ ret_resp_len--;
+ } else {
+ if (!ignore_client_id) {
+ if (MBOX_RESP_CLIENT_ID(resp_data) != MBOX_ATF_CLIENT_ID) {
+ *resp_len = 0;
+ 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;
+ mailbox_resp_ctr.flag |= MBOX_PAYLOAD_FLAG_BUSY;
+ }
+
+ if (ret_resp_len == 0) {
+ is_done = 1;
+ }
+ }
+
+ if (is_done != 0) {
+
+ /* copy header data to input address if applicable */
+ if (header != 0) {
+ *header = mailbox_resp_ctr.payload->header;
+ }
+
+ /* copy response data to input buffer if applicable */
+ ret_resp_len = MBOX_RESP_LEN(mailbox_resp_ctr.payload->header);
+ if ((ret_resp_len > 0) && (response == NULL) && resp_len) {
+ if (*resp_len > ret_resp_len) {
+ *resp_len = ret_resp_len;
+ }
+
+ memcpy((uint8_t *) response,
+ (uint8_t *) mailbox_resp_ctr.payload->data,
+ *resp_len * MBOX_WORD_BYTE);
+ }
+
+ /* reset async response param */
+ mailbox_resp_ctr.index = 0;
+ mailbox_resp_ctr.flag = 0;
+
+ if (MBOX_RESP_ERR(mailbox_resp_ctr.payload->header) > 0U) {
+ INFO("Error in async response: %x\n",
+ mailbox_resp_ctr.payload->header);
+ return -MBOX_RESP_ERR(mailbox_resp_ctr.payload->header);
+ }
+
+ return MBOX_RET_OK;
+ }
+
+ *resp_len = 0;
+ return (mailbox_resp_ctr.flag & MBOX_PAYLOAD_FLAG_BUSY) ? MBOX_BUSY : MBOX_NO_RESPONSE;
+}
int mailbox_poll_response(uint32_t job_id, uint32_t urgent, uint32_t *response,
unsigned int *resp_len)
@@ -294,6 +385,12 @@
return MBOX_RET_OK;
}
+int mailbox_send_cmd_async_ext(uint32_t header_cmd, uint32_t *args,
+ unsigned int len)
+{
+ return fill_mailbox_circular_buffer(header_cmd, args, len);
+}
+
int mailbox_send_cmd_async(uint32_t *job_id, uint32_t cmd, uint32_t *args,
unsigned int len, unsigned int indirect)
{
diff --git a/plat/intel/soc/common/soc/socfpga_reset_manager.c b/plat/intel/soc/common/soc/socfpga_reset_manager.c
index c2d5535..bb4efab 100644
--- a/plat/intel/soc/common/soc/socfpga_reset_manager.c
+++ b/plat/intel/soc/common/soc/socfpga_reset_manager.c
@@ -4,9 +4,9 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <errno.h>
#include <common/debug.h>
#include <drivers/delay_timer.h>
-#include <errno.h>
#include <lib/mmio.h>
#include "socfpga_f2sdram_manager.h"
diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c
index 79444cf..f7dd392 100644
--- a/plat/intel/soc/common/socfpga_sip_svc.c
+++ b/plat/intel/soc/common/socfpga_sip_svc.c
@@ -63,8 +63,9 @@
args[2] = buffer->size - buffer->size_written;
current_buffer++;
current_buffer %= FPGA_CONFIG_BUFFER_SIZE;
- } else
+ } else {
args[2] = bytes_per_block;
+ }
buffer->size_written += args[2];
mailbox_send_cmd_async(&send_id, MBOX_RECONFIG_DATA, args,
@@ -79,10 +80,12 @@
static int intel_fpga_sdm_write_all(void)
{
- for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++)
+ for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
if (intel_fpga_sdm_write_buffer(
- &fpga_config_buffers[current_buffer]))
+ &fpga_config_buffers[current_buffer])) {
break;
+ }
+ }
return 0;
}
@@ -174,10 +177,11 @@
intel_fpga_sdm_write_all();
- if (*count > 0)
+ if (*count > 0) {
status = INTEL_SIP_SMC_STATUS_OK;
- else if (*count == 0)
+ } else if (*count == 0) {
status = INTEL_SIP_SMC_STATUS_BUSY;
+ }
for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
if (fpga_config_buffers[i].write_requested != 0) {
@@ -186,8 +190,9 @@
}
}
- if (all_completed == 1)
+ if (all_completed == 1) {
return INTEL_SIP_SMC_STATUS_OK;
+ }
return status;
}
@@ -249,9 +254,11 @@
static bool is_fpga_config_buffer_full(void)
{
- for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++)
- if (!fpga_config_buffers[i].write_requested)
+ for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) {
+ if (!fpga_config_buffers[i].write_requested) {
return false;
+ }
+ }
return true;
}
@@ -260,12 +267,15 @@
if (!addr && !size) {
return true;
}
- if (size > (UINT64_MAX - addr))
+ if (size > (UINT64_MAX - addr)) {
return false;
- if (addr < BL31_LIMIT)
+ }
+ if (addr < BL31_LIMIT) {
return false;
- if (addr + size > DRAM_BASE + DRAM_SIZE)
+ }
+ if (addr + size > DRAM_BASE + DRAM_SIZE) {
return false;
+ }
return true;
}
@@ -349,8 +359,9 @@
/* Secure register access */
uint32_t intel_secure_reg_read(uint64_t reg_addr, uint32_t *retval)
{
- if (is_out_of_sec_range(reg_addr))
+ if (is_out_of_sec_range(reg_addr)) {
return INTEL_SIP_SMC_STATUS_ERROR;
+ }
*retval = mmio_read_32(reg_addr);
@@ -360,8 +371,9 @@
uint32_t intel_secure_reg_write(uint64_t reg_addr, uint32_t val,
uint32_t *retval)
{
- if (is_out_of_sec_range(reg_addr))
+ if (is_out_of_sec_range(reg_addr)) {
return INTEL_SIP_SMC_STATUS_ERROR;
+ }
mmio_write_32(reg_addr, val);
@@ -385,8 +397,9 @@
static uint32_t intel_rsu_status(uint64_t *respbuf, unsigned int respbuf_sz)
{
- if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0)
+ if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) {
return INTEL_SIP_SMC_RSU_ERROR;
+ }
return INTEL_SIP_SMC_STATUS_OK;
}
@@ -399,8 +412,9 @@
static uint32_t intel_rsu_notify(uint32_t execution_stage)
{
- if (mailbox_hps_stage_notify(execution_stage) < 0)
+ if (mailbox_hps_stage_notify(execution_stage) < 0) {
return INTEL_SIP_SMC_RSU_ERROR;
+ }
return INTEL_SIP_SMC_STATUS_OK;
}
@@ -408,8 +422,9 @@
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)
+ if (mailbox_rsu_status((uint32_t *)respbuf, respbuf_sz) < 0) {
return INTEL_SIP_SMC_RSU_ERROR;
+ }
*ret_stat = respbuf[8];
return INTEL_SIP_SMC_STATUS_OK;
@@ -487,19 +502,19 @@
}
static uint32_t intel_mbox_send_cmd(uint32_t cmd, uint32_t *args,
- unsigned int len,
- uint32_t urgent, uint32_t *response,
+ unsigned int len, uint32_t urgent, uint64_t response,
unsigned int resp_len, int *mbox_status,
unsigned int *len_in_resp)
{
*len_in_resp = 0;
- *mbox_status = 0;
+ *mbox_status = GENERIC_RESPONSE_ERROR;
- if (!is_address_in_ddr_range((uint64_t)args, sizeof(uint32_t) * len))
+ if (!is_address_in_ddr_range((uint64_t)args, sizeof(uint32_t) * len)) {
return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
int status = mailbox_send_cmd(MBOX_JOB_ID, cmd, args, len, urgent,
- response, &resp_len);
+ (uint32_t *) response, &resp_len);
if (status < 0) {
*mbox_status = -status;
@@ -508,6 +523,9 @@
*mbox_status = 0;
*len_in_resp = resp_len;
+
+ flush_dcache_range(response, resp_len * MBOX_WORD_BYTE);
+
return INTEL_SIP_SMC_STATUS_OK;
}
@@ -526,19 +544,65 @@
return INTEL_SIP_SMC_STATUS_OK;
}
+uint32_t intel_smc_service_completed(uint64_t addr, uint32_t size,
+ uint32_t mode, uint32_t *job_id,
+ uint32_t *ret_size, uint32_t *mbox_error)
+{
+ int status = 0;
+ uint32_t resp_len = size / MBOX_WORD_BYTE;
+
+ if (resp_len > MBOX_DATA_MAX_LEN) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_address_in_ddr_range(addr, size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (mode == SERVICE_COMPLETED_MODE_ASYNC) {
+ status = mailbox_read_response_async(job_id,
+ NULL, (uint32_t *) addr, &resp_len, 0);
+ } else {
+ status = mailbox_read_response(job_id,
+ (uint32_t *) addr, &resp_len);
+
+ if (status == MBOX_NO_RESPONSE) {
+ status = MBOX_BUSY;
+ }
+ }
+
+ if (status == MBOX_NO_RESPONSE) {
+ return INTEL_SIP_SMC_STATUS_NO_RESPONSE;
+ }
+
+ if (status == MBOX_BUSY) {
+ return INTEL_SIP_SMC_STATUS_BUSY;
+ }
+
+ *ret_size = resp_len * MBOX_WORD_BYTE;
+ flush_dcache_range(addr, *ret_size);
+
+ if (status != MBOX_RET_OK) {
+ *mbox_error = -status;
+ return INTEL_SIP_SMC_STATUS_ERROR;
+ }
+
+ return INTEL_SIP_SMC_STATUS_OK;
+}
+
/* Miscellaneous HPS services */
uint32_t intel_hps_set_bridges(uint64_t enable, uint64_t mask)
{
int status = 0;
- if (enable & SOCFPGA_BRIDGE_ENABLE) {
- if ((enable & SOCFPGA_BRIDGE_HAS_MASK) != 0) {
+ if ((enable & SOCFPGA_BRIDGE_ENABLE) != 0U) {
+ if ((enable & SOCFPGA_BRIDGE_HAS_MASK) != 0U) {
status = socfpga_bridges_enable((uint32_t)mask);
} else {
status = socfpga_bridges_enable(~0);
}
} else {
- if ((enable & SOCFPGA_BRIDGE_HAS_MASK) != 0) {
+ if ((enable & SOCFPGA_BRIDGE_HAS_MASK) != 0U) {
status = socfpga_bridges_disable((uint32_t)mask);
} else {
status = socfpga_bridges_disable(~0);
@@ -556,7 +620,7 @@
* This function is responsible for handling all SiP calls from the NS world
*/
-uintptr_t sip_smc_handler(uint32_t smc_fid,
+uintptr_t sip_smc_handler_v1(uint32_t smc_fid,
u_register_t x1,
u_register_t x2,
u_register_t x3,
@@ -565,14 +629,14 @@
void *handle,
u_register_t flags)
{
- uint32_t retval = 0;
+ uint32_t retval = 0, completed_addr[3];
+ uint32_t retval2 = 0;
uint32_t mbox_error = 0;
- uint32_t completed_addr[3];
uint64_t retval64, rsu_respbuf[9];
int status = INTEL_SIP_SMC_STATUS_OK;
int mbox_status;
unsigned int len_in_resp;
- u_register_t x5, x6;
+ u_register_t x5, x6, x7;
switch (smc_fid) {
case SIP_SVC_UID:
@@ -695,6 +759,11 @@
status = intel_ecc_dbe_notification(x1);
SMC_RET1(handle, status);
+ case INTEL_SIP_SMC_SERVICE_COMPLETED:
+ status = intel_smc_service_completed(x1, x2, x3, &rcv_id,
+ &len_in_resp, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x1, len_in_resp);
+
case INTEL_SIP_SMC_FIRMWARE_VERSION:
status = intel_smc_fw_version(&retval);
SMC_RET2(handle, status, retval);
@@ -702,19 +771,295 @@
case INTEL_SIP_SMC_MBOX_SEND_CMD:
x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
- status = intel_mbox_send_cmd(x1, (uint32_t *)x2, x3, x4,
- (uint32_t *)x5, x6, &mbox_status,
- &len_in_resp);
+ status = intel_mbox_send_cmd(x1, (uint32_t *)x2, x3, x4, x5, x6,
+ &mbox_status, &len_in_resp);
SMC_RET3(handle, status, mbox_status, len_in_resp);
case INTEL_SIP_SMC_GET_USERCODE:
status = intel_smc_get_usercode(&retval);
SMC_RET2(handle, status, retval);
+ case INTEL_SIP_SMC_FCS_CRYPTION:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+
+ if (x1 == FCS_MODE_DECRYPT) {
+ status = intel_fcs_decryption(x2, x3, x4, x5, &send_id);
+ } else if (x1 == FCS_MODE_ENCRYPT) {
+ status = intel_fcs_encryption(x2, x3, x4, x5, &send_id);
+ } else {
+ status = INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ SMC_RET3(handle, status, x4, x5);
+
+ case INTEL_SIP_SMC_FCS_CRYPTION_EXT:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
+
+ if (x3 == FCS_MODE_DECRYPT) {
+ status = intel_fcs_decryption_ext(x1, x2, x4, x5, x6,
+ (uint32_t *) &x7, &mbox_error);
+ } else if (x3 == FCS_MODE_ENCRYPT) {
+ status = intel_fcs_encryption_ext(x1, x2, x4, x5, x6,
+ (uint32_t *) &x7, &mbox_error);
+ } else {
+ status = INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ SMC_RET4(handle, status, mbox_error, x6, x7);
+
+ case INTEL_SIP_SMC_FCS_RANDOM_NUMBER:
+ status = intel_fcs_random_number_gen(x1, &retval64,
+ &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x1, retval64);
+
+ case INTEL_SIP_SMC_FCS_RANDOM_NUMBER_EXT:
+ status = intel_fcs_random_number_gen_ext(x1, x2, x3,
+ &send_id);
+ SMC_RET1(handle, status);
+
+ case INTEL_SIP_SMC_FCS_SEND_CERTIFICATE:
+ status = intel_fcs_send_cert(x1, x2, &send_id);
+ SMC_RET1(handle, status);
+
+ case INTEL_SIP_SMC_FCS_GET_PROVISION_DATA:
+ status = intel_fcs_get_provision_data(&send_id);
+ SMC_RET1(handle, status);
+
+ case INTEL_SIP_SMC_FCS_CNTR_SET_PREAUTH:
+ status = intel_fcs_cntr_set_preauth(x1, x2, x3,
+ &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
case INTEL_SIP_SMC_HPS_SET_BRIDGES:
status = intel_hps_set_bridges(x1, x2);
SMC_RET1(handle, status);
+ case INTEL_SIP_SMC_HWMON_READTEMP:
+ status = intel_hwmon_readtemp(x1, &retval);
+ SMC_RET2(handle, status, retval);
+
+ case INTEL_SIP_SMC_HWMON_READVOLT:
+ status = intel_hwmon_readvolt(x1, &retval);
+ SMC_RET2(handle, status, retval);
+
+ case INTEL_SIP_SMC_FCS_PSGSIGMA_TEARDOWN:
+ status = intel_fcs_sigma_teardown(x1, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_CHIP_ID:
+ status = intel_fcs_chip_id(&retval, &retval2, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, retval, retval2);
+
+ case INTEL_SIP_SMC_FCS_ATTESTATION_SUBKEY:
+ status = intel_fcs_attestation_subkey(x1, x2, x3,
+ (uint32_t *) &x4, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x3, x4);
+
+ case INTEL_SIP_SMC_FCS_ATTESTATION_MEASUREMENTS:
+ status = intel_fcs_get_measurement(x1, x2, x3,
+ (uint32_t *) &x4, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x3, x4);
+
+ case INTEL_SIP_SMC_FCS_GET_ATTESTATION_CERT:
+ status = intel_fcs_get_attestation_cert(x1, x2,
+ (uint32_t *) &x3, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x2, x3);
+
+ case INTEL_SIP_SMC_FCS_CREATE_CERT_ON_RELOAD:
+ status = intel_fcs_create_cert_on_reload(x1, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_OPEN_CS_SESSION:
+ status = intel_fcs_open_crypto_service_session(&retval, &mbox_error);
+ SMC_RET3(handle, status, mbox_error, retval);
+
+ case INTEL_SIP_SMC_FCS_CLOSE_CS_SESSION:
+ status = intel_fcs_close_crypto_service_session(x1, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_IMPORT_CS_KEY:
+ status = intel_fcs_import_crypto_service_key(x1, x2, &send_id);
+ SMC_RET1(handle, status);
+
+ case INTEL_SIP_SMC_FCS_EXPORT_CS_KEY:
+ status = intel_fcs_export_crypto_service_key(x1, x2, x3,
+ (uint32_t *) &x4, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x3, x4);
+
+ case INTEL_SIP_SMC_FCS_REMOVE_CS_KEY:
+ status = intel_fcs_remove_crypto_service_key(x1, x2,
+ &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_GET_CS_KEY_INFO:
+ status = intel_fcs_get_crypto_service_key_info(x1, x2, x3,
+ (uint32_t *) &x4, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x3, x4);
+
+ case INTEL_SIP_SMC_FCS_GET_DIGEST_INIT:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ status = intel_fcs_get_digest_init(x1, x2, x3,
+ x4, x5, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_GET_DIGEST_UPDATE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ status = intel_fcs_get_digest_update_finalize(x1, x2, x3,
+ x4, x5, (uint32_t *) &x6, false,
+ &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_GET_DIGEST_FINALIZE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ status = intel_fcs_get_digest_update_finalize(x1, x2, x3,
+ x4, x5, (uint32_t *) &x6, true,
+ &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_MAC_VERIFY_INIT:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ status = intel_fcs_mac_verify_init(x1, x2, x3,
+ x4, x5, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_MAC_VERIFY_UPDATE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
+ status = intel_fcs_mac_verify_update_finalize(x1, x2, x3,
+ x4, x5, (uint32_t *) &x6, x7,
+ false, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_MAC_VERIFY_FINALIZE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
+ status = intel_fcs_mac_verify_update_finalize(x1, x2, x3,
+ x4, x5, (uint32_t *) &x6, x7,
+ true, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_INIT:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ status = intel_fcs_ecdsa_sha2_data_sign_init(x1, x2, x3,
+ x4, x5, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_UPDATE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ status = intel_fcs_ecdsa_sha2_data_sign_update_finalize(x1, x2,
+ x3, x4, x5, (uint32_t *) &x6, false,
+ &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIGN_FINALIZE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ status = intel_fcs_ecdsa_sha2_data_sign_update_finalize(x1, x2,
+ x3, x4, x5, (uint32_t *) &x6, true,
+ &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_HASH_SIGN_INIT:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ status = intel_fcs_ecdsa_hash_sign_init(x1, x2, x3,
+ x4, x5, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_HASH_SIGN_FINALIZE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ status = intel_fcs_ecdsa_hash_sign_finalize(x1, x2, x3,
+ x4, x5, (uint32_t *) &x6, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_HASH_SIG_VERIFY_INIT:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ status = intel_fcs_ecdsa_hash_sig_verify_init(x1, x2, x3,
+ x4, x5, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_HASH_SIG_VERIFY_FINALIZE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ status = intel_fcs_ecdsa_hash_sig_verify_finalize(x1, x2, x3,
+ x4, x5, (uint32_t *) &x6, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_INIT:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ status = intel_fcs_ecdsa_sha2_data_sig_verify_init(x1, x2, x3,
+ x4, x5, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_UPDATE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
+ status = intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(
+ x1, x2, x3, x4, x5, (uint32_t *) &x6,
+ x7, false, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_SHA2_DATA_SIG_VERIFY_FINALIZE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ x7 = SMC_GET_GP(handle, CTX_GPREG_X7);
+ status = intel_fcs_ecdsa_sha2_data_sig_verify_update_finalize(
+ x1, x2, x3, x4, x5, (uint32_t *) &x6,
+ x7, true, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_INIT:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ status = intel_fcs_ecdsa_get_pubkey_init(x1, x2, x3,
+ x4, x5, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_ECDSA_GET_PUBKEY_FINALIZE:
+ status = intel_fcs_ecdsa_get_pubkey_finalize(x1, x2, x3,
+ (uint32_t *) &x4, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x3, x4);
+
+ case INTEL_SIP_SMC_FCS_ECDH_REQUEST_INIT:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ status = intel_fcs_ecdh_request_init(x1, x2, x3,
+ x4, x5, &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_ECDH_REQUEST_FINALIZE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ status = intel_fcs_ecdh_request_finalize(x1, x2, x3,
+ x4, x5, (uint32_t *) &x6, &mbox_error);
+ SMC_RET4(handle, status, mbox_error, x5, x6);
+
+ case INTEL_SIP_SMC_FCS_AES_CRYPT_INIT:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ status = intel_fcs_aes_crypt_init(x1, x2, x3, x4, x5,
+ &mbox_error);
+ SMC_RET2(handle, status, mbox_error);
+
+ case INTEL_SIP_SMC_FCS_AES_CRYPT_UPDATE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ status = intel_fcs_aes_crypt_update_finalize(x1, x2, x3, x4,
+ x5, x6, false, &send_id);
+ SMC_RET1(handle, status);
+
+ case INTEL_SIP_SMC_FCS_AES_CRYPT_FINALIZE:
+ x5 = SMC_GET_GP(handle, CTX_GPREG_X5);
+ x6 = SMC_GET_GP(handle, CTX_GPREG_X6);
+ status = intel_fcs_aes_crypt_update_finalize(x1, x2, x3, x4,
+ x5, x6, true, &send_id);
+ SMC_RET1(handle, status);
+
case INTEL_SIP_SMC_GET_ROM_PATCH_SHA384:
status = intel_fcs_get_rom_patch_sha384(x1, &retval64,
&mbox_error);
@@ -725,20 +1070,33 @@
SIP_SVC_VERSION_MAJOR,
SIP_SVC_VERSION_MINOR);
- case INTEL_SIP_SMC_HWMON_READTEMP:
- status = intel_hwmon_readtemp(x1, &retval);
- SMC_RET2(handle, status, retval);
-
- case INTEL_SIP_SMC_HWMON_READVOLT:
- status = intel_hwmon_readvolt(x1, &retval);
- SMC_RET2(handle, status, retval);
-
default:
return socfpga_sip_handler(smc_fid, x1, x2, x3, x4,
cookie, handle, flags);
}
}
+uintptr_t sip_smc_handler(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
+ void *cookie,
+ void *handle,
+ u_register_t flags)
+{
+ uint32_t cmd = smc_fid & INTEL_SIP_SMC_CMD_MASK;
+
+ if (cmd >= INTEL_SIP_SMC_CMD_V2_RANGE_BEGIN &&
+ cmd <= INTEL_SIP_SMC_CMD_V2_RANGE_END) {
+ return sip_smc_handler_v2(smc_fid, x1, x2, x3, x4,
+ cookie, handle, flags);
+ } else {
+ return sip_smc_handler_v1(smc_fid, x1, x2, x3, x4,
+ cookie, handle, flags);
+ }
+}
+
DECLARE_RT_SVC(
socfpga_sip_svc,
OEN_SIP_START,
diff --git a/plat/intel/soc/common/socfpga_sip_svc_v2.c b/plat/intel/soc/common/socfpga_sip_svc_v2.c
new file mode 100644
index 0000000..791c714
--- /dev/null
+++ b/plat/intel/soc/common/socfpga_sip_svc_v2.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2022, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <common/debug.h>
+#include <common/runtime_svc.h>
+#include <lib/mmio.h>
+
+#include "socfpga_mailbox.h"
+#include "socfpga_sip_svc.h"
+
+static uint32_t intel_v2_mbox_send_cmd(uint32_t req_header,
+ uint32_t *data, uint32_t data_size)
+{
+ uint32_t value;
+ uint32_t len;
+
+ if ((data == NULL) || (data_size == 0)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (data_size > (MBOX_INC_HEADER_MAX_WORD_SIZE * MBOX_WORD_BYTE)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_size_4_bytes_aligned(data_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ /* Make sure client id align in SMC SiP V2 header and mailbox header */
+ value = (req_header >> INTEL_SIP_SMC_HEADER_CID_OFFSET) &
+ INTEL_SIP_SMC_HEADER_CID_MASK;
+
+ if (value != MBOX_RESP_CLIENT_ID(data[0])) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ /* Make sure job id align in SMC SiP V2 header and mailbox header */
+ value = (req_header >> INTEL_SIP_SMC_HEADER_JOB_ID_OFFSET) &
+ INTEL_SIP_SMC_HEADER_JOB_ID_MASK;
+
+ if (value != MBOX_RESP_JOB_ID(data[0])) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ /*
+ * Make sure data length align in SMC SiP V2 header and
+ * mailbox header
+ */
+ len = (data_size / MBOX_WORD_BYTE) - 1;
+
+ if (len != MBOX_RESP_LEN(data[0])) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ return mailbox_send_cmd_async_ext(data[0], &data[1], len);
+}
+
+static uint32_t intel_v2_mbox_poll_resp(uint64_t req_header,
+ uint32_t *data, uint32_t *data_size,
+ uint64_t *resp_header)
+{
+ int status = 0;
+ uint32_t resp_len;
+ uint32_t job_id = 0;
+ uint32_t client_id = 0;
+ uint32_t version;
+
+ if ((data == NULL) || (data_size == NULL) || (resp_header == NULL)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ if (!is_size_4_bytes_aligned(*data_size)) {
+ return INTEL_SIP_SMC_STATUS_REJECTED;
+ }
+
+ resp_len = (*data_size / MBOX_WORD_BYTE) - 1;
+ status = mailbox_read_response_async(&job_id, &data[0], &data[1],
+ &resp_len, 1);
+
+ if (status == MBOX_BUSY) {
+ status = INTEL_SIP_SMC_STATUS_BUSY;
+ } else if (status == MBOX_NO_RESPONSE) {
+ status = INTEL_SIP_SMC_STATUS_NO_RESPONSE;
+ } else {
+ *data_size = 0;
+
+ if (resp_len > 0) {
+ /*
+ * Fill in the final response length,
+ * the length include both mailbox header and payload
+ */
+ *data_size = (resp_len + 1) * MBOX_WORD_BYTE;
+
+ /* Extract the client id from mailbox header */
+ client_id = MBOX_RESP_CLIENT_ID(data[0]);
+ }
+
+ /*
+ * Extract SMC SiP V2 protocol version from
+ * SMC request header
+ */
+ version = (req_header >> INTEL_SIP_SMC_HEADER_VERSION_OFFSET) &
+ INTEL_SIP_SMC_HEADER_VERSION_MASK;
+
+ /* Fill in SMC SiP V2 protocol response header */
+ *resp_header = 0;
+ *resp_header |= (((uint64_t)job_id) &
+ INTEL_SIP_SMC_HEADER_JOB_ID_MASK) <<
+ INTEL_SIP_SMC_HEADER_JOB_ID_OFFSET;
+ *resp_header |= (((uint64_t)client_id) &
+ INTEL_SIP_SMC_HEADER_CID_MASK) <<
+ INTEL_SIP_SMC_HEADER_CID_OFFSET;
+ *resp_header |= (((uint64_t)version) &
+ INTEL_SIP_SMC_HEADER_VERSION_MASK) <<
+ INTEL_SIP_SMC_HEADER_VERSION_OFFSET;
+ }
+
+ return status;
+}
+
+uintptr_t sip_smc_handler_v2(uint32_t smc_fid,
+ u_register_t x1,
+ u_register_t x2,
+ u_register_t x3,
+ u_register_t x4,
+ void *cookie,
+ void *handle,
+ u_register_t flags)
+{
+ uint32_t retval = 0;
+ uint64_t retval64 = 0;
+ int status = INTEL_SIP_SMC_STATUS_OK;
+
+ switch (smc_fid) {
+ case INTEL_SIP_SMC_V2_GET_SVC_VERSION:
+ SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, x1,
+ SIP_SVC_VERSION_MAJOR,
+ SIP_SVC_VERSION_MINOR);
+
+ case INTEL_SIP_SMC_V2_REG_READ:
+ status = intel_secure_reg_read(x2, &retval);
+ SMC_RET4(handle, status, x1, retval, x2);
+
+ case INTEL_SIP_SMC_V2_REG_WRITE:
+ status = intel_secure_reg_write(x2, (uint32_t)x3, &retval);
+ SMC_RET4(handle, status, x1, retval, x2);
+
+ case INTEL_SIP_SMC_V2_REG_UPDATE:
+ status = intel_secure_reg_update(x2, (uint32_t)x3,
+ (uint32_t)x4, &retval);
+ SMC_RET4(handle, status, x1, retval, x2);
+
+ case INTEL_SIP_SMC_V2_HPS_SET_BRIDGES:
+ status = intel_hps_set_bridges(x2, x3);
+ SMC_RET2(handle, status, x1);
+
+ case INTEL_SIP_SMC_V2_MAILBOX_SEND_COMMAND:
+ status = intel_v2_mbox_send_cmd(x1, (uint32_t *)x2, x3);
+ SMC_RET2(handle, status, x1);
+
+ case INTEL_SIP_SMC_V2_MAILBOX_POLL_RESPONSE:
+ status = intel_v2_mbox_poll_resp(x1, (uint32_t *)x2,
+ (uint32_t *) &x3, &retval64);
+ SMC_RET4(handle, status, retval64, x2, x3);
+
+ default:
+ ERROR("%s: unhandled SMC V2 (0x%x)\n", __func__, smc_fid);
+ SMC_RET1(handle, SMC_UNK);
+ }
+}
diff --git a/plat/intel/soc/n5x/platform.mk b/plat/intel/soc/n5x/platform.mk
index b72bcc4..953bf0c 100644
--- a/plat/intel/soc/n5x/platform.mk
+++ b/plat/intel/soc/n5x/platform.mk
@@ -38,6 +38,7 @@
plat/intel/soc/n5x/bl31_plat_setup.c \
plat/intel/soc/common/socfpga_psci.c \
plat/intel/soc/common/socfpga_sip_svc.c \
+ plat/intel/soc/common/socfpga_sip_svc_v2.c \
plat/intel/soc/common/socfpga_topology.c \
plat/intel/soc/common/sip/socfpga_sip_ecc.c \
plat/intel/soc/common/sip/socfpga_sip_fcs.c \
diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c
index 92d827a..73e3216 100644
--- a/plat/intel/soc/stratix10/bl2_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl2_plat_setup.c
@@ -82,8 +82,8 @@
if (!intel_mailbox_is_fpga_not_ready()) {
socfpga_bridges_enable(SOC2FPGA_MASK | LWHPS2FPGA_MASK |
- FPGA2SOC_MASK | F2SDRAM0_MASK | F2SDRAM1_MASK |
- F2SDRAM2_MASK);
+ FPGA2SOC_MASK | F2SDRAM0_MASK | F2SDRAM1_MASK |
+ F2SDRAM2_MASK);
}
}
diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk
index 273b975..8b39b6f 100644
--- a/plat/intel/soc/stratix10/platform.mk
+++ b/plat/intel/soc/stratix10/platform.mk
@@ -64,6 +64,7 @@
plat/intel/soc/stratix10/bl31_plat_setup.c \
plat/intel/soc/common/socfpga_psci.c \
plat/intel/soc/common/socfpga_sip_svc.c \
+ plat/intel/soc/common/socfpga_sip_svc_v2.c \
plat/intel/soc/common/socfpga_topology.c \
plat/intel/soc/common/sip/socfpga_sip_ecc.c \
plat/intel/soc/common/sip/socfpga_sip_fcs.c \