fix(intel): allow non-secure access to FPGA Crypto Services (FCS)
Allows non-secure software to access FPGA Crypto Services (FCS) through secure monitor calls (SMC). Signed-off-by: Abdul Halim, Muhammad Hadi Asyrafi <muhammad.hadi.asyrafi.abdul.halim@intel.com> Signed-off-by: Sieu Mun Tang <sieu.mun.tang@intel.com> Change-Id: I805b3f650abf5e118e2c55e469866d5d0ca68048
This commit is contained in:
parent
7facacec63
commit
4837a64093
|
@ -108,6 +108,7 @@
|
|||
#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 */
|
||||
|
@ -157,6 +158,10 @@
|
|||
#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
|
||||
|
@ -166,6 +171,19 @@
|
|||
#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);
|
||||
|
@ -180,6 +198,9 @@ int mailbox_send_cmd_async(uint32_t *job_id, uint32_t cmd, uint32_t *args,
|
|||
unsigned int len, unsigned int indirect);
|
||||
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);
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#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
|
||||
|
||||
|
@ -68,16 +69,21 @@
|
|||
#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
|
||||
|
||||
/* FPGA Crypto Services */
|
||||
#define INTEL_SIP_SMC_FCS_RANDOM_NUMBER 0xC200005A
|
||||
#define INTEL_SIP_SMC_FCS_CRYPTION 0x4200005B
|
||||
#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_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
|
||||
|
||||
/* ECC DBE */
|
||||
#define WARM_RESET_WFI_FLAG BIT(31)
|
||||
|
|
|
@ -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 @@ int mailbox_read_response(unsigned int *job_id, uint32_t *response,
|
|||
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 && 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)
|
||||
|
|
|
@ -552,6 +552,52 @@ uint32_t intel_hps_set_bridges(uint64_t enable, uint64_t mask)
|
|||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is responsible for handling all SiP calls from the NS world
|
||||
*/
|
||||
|
@ -724,6 +770,19 @@ uintptr_t sip_smc_handler(uint32_t smc_fid,
|
|||
|
||||
SMC_RET3(handle, status, x4, x5);
|
||||
|
||||
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_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);
|
||||
|
|
Loading…
Reference in New Issue