mirror of
https://github.com/apache/nuttx.git
synced 2026-10-01 19:36:28 +00:00
arch/arm/imxrt: Port the imx93 ELE driver for iMXRT118x
iMXRT118x uses the same security element as the imx93. Just add iMXRT specific register definitions and port over the driver code. Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
This commit is contained in:
parent
9b0d998082
commit
438eadd880
6 changed files with 1149 additions and 0 deletions
|
|
@ -155,4 +155,8 @@ if(CONFIG_IMXRT_TRDC)
|
|||
list(APPEND SRCS imxrt118x_trdc.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_IMXRT_ELE)
|
||||
list(APPEND SRCS imxrt118x_ele.c)
|
||||
endif()
|
||||
|
||||
target_sources(arch PRIVATE ${SRCS})
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@ config ARCH_CHIP_MIMXRT1189CVM8C_CM33
|
|||
select ARCH_CORTEXM33
|
||||
select ARMV8M_HAVE_STACKCHECK
|
||||
select IMXRT_TRDC
|
||||
select IMXRT_ELE
|
||||
---help---
|
||||
Target the Cortex-M33 core on the RT1189 SoC. Used to build a
|
||||
NuttX bootloader / minimal application that runs on the M33 out
|
||||
|
|
@ -424,6 +425,14 @@ config IMXRT_TRDC
|
|||
(arch/arm/src/imxrt/imxrt118x_trdc.c). Present on RT118x-class
|
||||
SoCs.
|
||||
|
||||
config IMXRT_ELE
|
||||
bool
|
||||
default n
|
||||
---help---
|
||||
Enable the NXP EdgeLock Enclave (ELE) messaging driver
|
||||
(arch/arm/src/imxrt/imxrt118x_ele.c). Present on RT118x-class
|
||||
SoCs.
|
||||
|
||||
menu "i.MX RT Peripheral Selection"
|
||||
|
||||
config IMXRT_EDMA
|
||||
|
|
|
|||
|
|
@ -150,3 +150,7 @@ endif
|
|||
ifeq ($(CONFIG_IMXRT_TRDC),y)
|
||||
CHIP_CSRCS += imxrt118x_trdc.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_IMXRT_ELE),y)
|
||||
CHIP_CSRCS += imxrt118x_ele.c
|
||||
endif
|
||||
|
|
|
|||
125
arch/arm/src/imxrt/hardware/rt118x/imxrt118x_ele.h
Normal file
125
arch/arm/src/imxrt/hardware/rt118x/imxrt118x_ele.h
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/imxrt/hardware/rt118x/imxrt118x_ele.h
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_IMXRT_HARDWARE_RT118X_IMXRT118X_ELE_H
|
||||
#define __ARCH_ARM_SRC_IMXRT_HARDWARE_RT118X_IMXRT118X_ELE_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "hardware/imxrt_memorymap.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define ELE_MAX_MSG 255U
|
||||
|
||||
#define ELE_CMD_TAG 0x17
|
||||
#define ELE_VERSION 0x6
|
||||
#define ELE_VERSION_FW 0x7
|
||||
#define ELE_RESP_TAG 0xe1
|
||||
#define ELE_OK 0xd6
|
||||
|
||||
/* ELE commands. */
|
||||
|
||||
#define ELE_LOAD_FW_REQ 0x02
|
||||
#define ELE_ENABLE_APC_REQ 0xd2
|
||||
#define ELE_RELEASE_RDC_REQ 0xc4
|
||||
#define ELE_GET_FW_VERSION_REQ 0x9d
|
||||
#define ELE_DERIVE_KEY_REQ 0xa9
|
||||
#define ELE_GET_EVENTS_REQ 0xa2
|
||||
#define ELE_GET_TRNG_STATE_REQ 0xa4
|
||||
#define ELE_GET_RNG_REQ 0xcd
|
||||
#define ELE_FWD_LIFECYCLE_UP_REQ 0x95
|
||||
#define ELE_OEM_CNTN_AUTH_REQ 0x87
|
||||
#define ELE_READ_FUSE_REQ 0x97
|
||||
#define ELE_RELEASE_CONTAINER_REQ 0x89
|
||||
#define ELE_START_RNG_REQ 0xa3
|
||||
#define ELE_VERIFY_IMAGE_REQ 0x88
|
||||
#define ELE_COMMIT_REQ 0xa8
|
||||
#define ELE_GET_INFO_REQ 0xda
|
||||
#define ELE_VOLTAGE_CHANGE_START_REQ 0x12
|
||||
#define ELE_VOLTAGE_CHANGE_FINISH_REQ 0x13
|
||||
|
||||
/* RT118x RDC identifiers used by ELE_RELEASE_RDC_REQ, from NXP
|
||||
* MCUXpresso SDK examples/_boards/evkmimxrt1180/board.c.
|
||||
*/
|
||||
|
||||
#define ELE_TRDC_AON_ID 0x74
|
||||
#define ELE_TRDC_WAKEUP_ID 0x78
|
||||
#define ELE_TRDC_MEGA_ID 0x82
|
||||
|
||||
#define ELE_CORE_CM33_ID 0x1
|
||||
#define ELE_CORE_CM7_ID 0x2
|
||||
|
||||
/* GET_INFO returned data. */
|
||||
|
||||
#define ELE_GET_INFO_BYTES 160
|
||||
#define ELE_GET_INFO_LC_WORD 2
|
||||
#define ELE_GET_INFO_LC_MASK 0xffff
|
||||
|
||||
/* System 3 Messaging Unit A (IMXRT1180RM Ch. 65).
|
||||
* The CM33 boots in Secure state and NXP's own SDK uses the Secure alias
|
||||
* (0x57540000) rather than the Non-secure alias (0x47540000) for all ELE
|
||||
* traffic — writes via the Non-secure alias may not reach the enclave
|
||||
* even though reads mirror the same peripheral.
|
||||
*/
|
||||
|
||||
#define ELE_MU_TCR (IMXRT_S3MUA_BASE + 0x120)
|
||||
#define ELE_MU_TSR (IMXRT_S3MUA_BASE + 0x124)
|
||||
#define ELE_MU_RCR (IMXRT_S3MUA_BASE + 0x128)
|
||||
#define ELE_MU_RSR (IMXRT_S3MUA_BASE + 0x12c)
|
||||
|
||||
#define ELE_RR_NUM 4
|
||||
#define ELE_TR_NUM 8
|
||||
#define ELE_MU_TR(i) (IMXRT_S3MUA_BASE + 0x200 + (i) * 4)
|
||||
#define ELE_MU_RR(i) (IMXRT_S3MUA_BASE + 0x280 + (i) * 4)
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
struct ele_header_t
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t data;
|
||||
struct
|
||||
{
|
||||
uint32_t version : 8;
|
||||
uint32_t size : 8;
|
||||
uint32_t command : 8;
|
||||
uint32_t tag : 8;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
struct ele_msg
|
||||
{
|
||||
struct ele_header_t header;
|
||||
uint32_t data[(ELE_MAX_MSG - 1)];
|
||||
};
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_IMXRT_HARDWARE_RT118X_IMXRT118X_ELE_H */
|
||||
640
arch/arm/src/imxrt/imxrt118x_ele.c
Normal file
640
arch/arm/src/imxrt/imxrt118x_ele.c
Normal file
|
|
@ -0,0 +1,640 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/imxrt/imxrt118x_ele.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/nuttx.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include "arm_internal.h"
|
||||
#include "hardware/rt118x/imxrt118x_memorymap.h"
|
||||
#include "imxrt118x_ele.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* The M7 core is Armv7-M and the M33 core is Armv8-M; pick whichever
|
||||
* D-Cache line size macro chip.h provided for the core we're building
|
||||
* for.
|
||||
*/
|
||||
|
||||
#if defined(ARMV8M_DCACHE_LINESIZE)
|
||||
# define DCACHE_LINESIZE ARMV8M_DCACHE_LINESIZE
|
||||
#else
|
||||
# define DCACHE_LINESIZE ARMV7M_DCACHE_LINESIZE
|
||||
#endif
|
||||
|
||||
#define upper_32_bits(n) ((uint32_t)(((n) >> 16) >> 16))
|
||||
#define lower_32_bits(n) ((uint32_t)(n))
|
||||
|
||||
#define ELE_RNG_TIMEOUT_US 5000
|
||||
#define ELE_RNG_SLEEP_US 100
|
||||
#define ELE_TRNG_STATUS_READY 0x3
|
||||
#define ELE_CSAL_STATUS_READY 0x2
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct ele_trng_state
|
||||
{
|
||||
uint8_t trng_state;
|
||||
uint8_t csal_state;
|
||||
uint16_t reserved;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct ele_msg g_msg;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt118x_ele_sendmsg
|
||||
*
|
||||
* Description:
|
||||
* Send a message to the EdgeLock Enclave over the System 3 Message Unit A.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void imxrt118x_ele_sendmsg(struct ele_msg *msg_ptr)
|
||||
{
|
||||
/* Check that ele is ready to receive */
|
||||
|
||||
while (!((1) & getreg32(ELE_MU_TSR)));
|
||||
|
||||
/* write header to slot 0 */
|
||||
|
||||
putreg32(msg_ptr->header.data, ELE_MU_TR(0));
|
||||
|
||||
/* write data */
|
||||
|
||||
for (int i = 1; i < msg_ptr->header.size; i++)
|
||||
{
|
||||
int tx_channel;
|
||||
|
||||
tx_channel = i % ELE_TR_NUM;
|
||||
while (!((1 << tx_channel) & getreg32(ELE_MU_TSR)));
|
||||
|
||||
/* Write data */
|
||||
|
||||
putreg32(msg_ptr->data[i - 1], ELE_MU_TR(tx_channel));
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt118x_ele_receivemsg
|
||||
*
|
||||
* Description:
|
||||
* Receive a response message from the EdgeLock Enclave.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void imxrt118x_ele_receivemsg(struct ele_msg *msg_ptr)
|
||||
{
|
||||
/* Check if data ready */
|
||||
|
||||
while (!((1) & getreg32(ELE_MU_RSR)));
|
||||
|
||||
/* Read Header from slot 0 */
|
||||
|
||||
msg_ptr->header.data = getreg32(ELE_MU_RR(0));
|
||||
|
||||
for (int i = 1; i < msg_ptr->header.size; i++)
|
||||
{
|
||||
/* Check if empty */
|
||||
|
||||
int rx_channel = (i) % ELE_RR_NUM;
|
||||
|
||||
while (!((1 << rx_channel) & getreg32(ELE_MU_RSR)));
|
||||
|
||||
/* Read data */
|
||||
|
||||
msg_ptr->data[i - 1] = getreg32(ELE_MU_RR(rx_channel));
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
void imxrt118x_ele_init(void)
|
||||
{
|
||||
putreg32(0, ELE_MU_TCR);
|
||||
putreg32(0, ELE_MU_RCR);
|
||||
|
||||
imxrt118x_ele_check_fw_version();
|
||||
}
|
||||
|
||||
int imxrt118x_ele_load_fw(uint32_t fw_addr)
|
||||
{
|
||||
g_msg.header.version = ELE_VERSION;
|
||||
g_msg.header.tag = ELE_CMD_TAG;
|
||||
g_msg.header.size = 4;
|
||||
g_msg.header.command = ELE_LOAD_FW_REQ;
|
||||
g_msg.data[0] = fw_addr;
|
||||
g_msg.data[1] = 0;
|
||||
g_msg.data[2] = fw_addr;
|
||||
|
||||
imxrt118x_ele_sendmsg(&g_msg);
|
||||
imxrt118x_ele_receivemsg(&g_msg);
|
||||
|
||||
if ((g_msg.data[0] & 0xff) == ELE_OK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
int imxrt118x_ele_release_rdc(uint32_t rdc_id)
|
||||
{
|
||||
g_msg.header.version = ELE_VERSION;
|
||||
g_msg.header.tag = ELE_CMD_TAG;
|
||||
g_msg.header.size = 2;
|
||||
g_msg.header.command = ELE_RELEASE_RDC_REQ;
|
||||
g_msg.data[0] = rdc_id;
|
||||
|
||||
imxrt118x_ele_sendmsg(&g_msg);
|
||||
imxrt118x_ele_receivemsg(&g_msg);
|
||||
|
||||
if ((g_msg.data[0] & 0xff) == ELE_OK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
uint32_t imxrt118x_ele_read_common_fuse(uint32_t fuse_id)
|
||||
{
|
||||
uint32_t value = 0;
|
||||
|
||||
g_msg.header.version = ELE_VERSION;
|
||||
g_msg.header.tag = ELE_CMD_TAG;
|
||||
g_msg.header.size = 2;
|
||||
g_msg.header.command = ELE_READ_FUSE_REQ;
|
||||
g_msg.data[0] = fuse_id;
|
||||
|
||||
imxrt118x_ele_sendmsg(&g_msg);
|
||||
imxrt118x_ele_receivemsg(&g_msg);
|
||||
|
||||
if ((g_msg.data[0] & 0xff) == ELE_OK)
|
||||
{
|
||||
value = g_msg.data[1];
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
int imxrt118x_ele_get_key(uint8_t *key, size_t key_size,
|
||||
uint8_t *ctx, size_t ctx_size)
|
||||
{
|
||||
if (!key)
|
||||
{
|
||||
_err("Invalid key parameter\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!ctx)
|
||||
{
|
||||
_err("Invalid context parameter\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((key_size != 16) && (key_size != 32))
|
||||
{
|
||||
_err("Invalid key size\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!IS_ALIGNED((uintptr_t)key, DCACHE_LINESIZE))
|
||||
{
|
||||
_err("Invalid key alignment\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!IS_ALIGNED((uintptr_t)ctx, DCACHE_LINESIZE))
|
||||
{
|
||||
_err("Invalid context alignment\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
g_msg.header.version = ELE_VERSION;
|
||||
g_msg.header.tag = ELE_CMD_TAG;
|
||||
g_msg.header.size = 7;
|
||||
g_msg.header.command = ELE_DERIVE_KEY_REQ;
|
||||
g_msg.data[0] = upper_32_bits((uintptr_t)key);
|
||||
g_msg.data[1] = lower_32_bits((uintptr_t)key);
|
||||
g_msg.data[2] = upper_32_bits((uintptr_t)ctx);
|
||||
g_msg.data[3] = lower_32_bits((uintptr_t)ctx);
|
||||
g_msg.data[4] = ((ctx_size << 16) | key_size);
|
||||
|
||||
uint32_t crc = g_msg.header.data;
|
||||
|
||||
for (uint32_t i = 0; i < g_msg.header.size - 2; i++)
|
||||
{
|
||||
crc ^= g_msg.data[i];
|
||||
}
|
||||
|
||||
g_msg.data[5] = crc;
|
||||
|
||||
up_flush_dcache((uintptr_t)ctx, (uintptr_t)(ctx + ctx_size));
|
||||
up_invalidate_dcache((uintptr_t)key, (uintptr_t)(key + key_size));
|
||||
|
||||
imxrt118x_ele_sendmsg(&g_msg);
|
||||
imxrt118x_ele_receivemsg(&g_msg);
|
||||
|
||||
up_invalidate_dcache((uintptr_t)key, (uintptr_t)(key + key_size));
|
||||
|
||||
if ((g_msg.data[0] & 0xff) == ELE_OK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
int imxrt118x_ele_get_events(uint32_t *buffer, size_t buffer_size)
|
||||
{
|
||||
size_t events_num;
|
||||
size_t i;
|
||||
|
||||
g_msg.header.version = ELE_VERSION;
|
||||
g_msg.header.tag = ELE_CMD_TAG;
|
||||
g_msg.header.size = 1;
|
||||
g_msg.header.command = ELE_GET_EVENTS_REQ;
|
||||
|
||||
imxrt118x_ele_sendmsg(&g_msg);
|
||||
imxrt118x_ele_receivemsg(&g_msg);
|
||||
|
||||
if ((g_msg.data[0] & 0xff) == ELE_OK)
|
||||
{
|
||||
events_num = g_msg.data[1] & 0xffff;
|
||||
if (buffer)
|
||||
{
|
||||
for (i = 0; (i < buffer_size) && (i < events_num); i++)
|
||||
{
|
||||
buffer[i] = g_msg.data[i + 2];
|
||||
}
|
||||
|
||||
return (int)i;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (int)events_num;
|
||||
}
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
int imxrt118x_ele_close_device(void)
|
||||
{
|
||||
g_msg.header.version = ELE_VERSION;
|
||||
g_msg.header.tag = ELE_CMD_TAG;
|
||||
g_msg.header.size = 2;
|
||||
g_msg.header.command = ELE_FWD_LIFECYCLE_UP_REQ;
|
||||
g_msg.data[0] = 0x08;
|
||||
|
||||
imxrt118x_ele_sendmsg(&g_msg);
|
||||
imxrt118x_ele_receivemsg(&g_msg);
|
||||
|
||||
if ((g_msg.data[0] & 0xff) == ELE_OK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
uint32_t imxrt118x_ele_get_lifecycle(void)
|
||||
{
|
||||
static uint8_t info[ELE_GET_INFO_BYTES]
|
||||
aligned_data(DCACHE_LINESIZE);
|
||||
|
||||
uint32_t addr = (uint32_t)(uintptr_t)info;
|
||||
|
||||
g_msg.header.version = ELE_VERSION;
|
||||
g_msg.header.tag = ELE_CMD_TAG;
|
||||
g_msg.header.size = 4;
|
||||
g_msg.header.command = ELE_GET_INFO_REQ;
|
||||
g_msg.data[0] = upper_32_bits(addr);
|
||||
g_msg.data[1] = lower_32_bits(addr);
|
||||
g_msg.data[2] = sizeof(info);
|
||||
|
||||
up_invalidate_dcache(addr, addr + sizeof(info));
|
||||
|
||||
imxrt118x_ele_sendmsg(&g_msg);
|
||||
imxrt118x_ele_receivemsg(&g_msg);
|
||||
|
||||
if ((g_msg.data[0] & 0xff) != ELE_OK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
up_invalidate_dcache(addr, addr + sizeof(info));
|
||||
|
||||
return ((uint32_t *)info)[ELE_GET_INFO_LC_WORD] & ELE_GET_INFO_LC_MASK;
|
||||
}
|
||||
|
||||
int imxrt118x_ele_auth_oem_ctnr(unsigned long ctnr_addr, uint32_t *response)
|
||||
{
|
||||
g_msg.header.version = ELE_VERSION;
|
||||
g_msg.header.tag = ELE_CMD_TAG;
|
||||
g_msg.header.size = 3;
|
||||
g_msg.header.command = ELE_OEM_CNTN_AUTH_REQ;
|
||||
g_msg.data[0] = upper_32_bits(ctnr_addr);
|
||||
g_msg.data[1] = lower_32_bits(ctnr_addr);
|
||||
|
||||
imxrt118x_ele_sendmsg(&g_msg);
|
||||
imxrt118x_ele_receivemsg(&g_msg);
|
||||
if (response)
|
||||
{
|
||||
*response = g_msg.data[0];
|
||||
}
|
||||
|
||||
if ((g_msg.data[0] & 0xff) == ELE_OK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
int imxrt118x_ele_release_container(uint32_t *response)
|
||||
{
|
||||
g_msg.header.version = ELE_VERSION;
|
||||
g_msg.header.tag = ELE_CMD_TAG;
|
||||
g_msg.header.size = 1;
|
||||
g_msg.header.command = ELE_RELEASE_CONTAINER_REQ;
|
||||
|
||||
imxrt118x_ele_sendmsg(&g_msg);
|
||||
imxrt118x_ele_receivemsg(&g_msg);
|
||||
|
||||
if (response)
|
||||
{
|
||||
*response = g_msg.data[0];
|
||||
}
|
||||
|
||||
if ((g_msg.data[0] & 0xff) == ELE_OK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
int imxrt118x_ele_verify_image(uint32_t img_id, uint32_t *response)
|
||||
{
|
||||
g_msg.header.version = ELE_VERSION;
|
||||
g_msg.header.tag = ELE_CMD_TAG;
|
||||
g_msg.header.size = 2;
|
||||
g_msg.header.command = ELE_VERIFY_IMAGE_REQ;
|
||||
g_msg.data[0] = 1 << img_id;
|
||||
|
||||
imxrt118x_ele_sendmsg(&g_msg);
|
||||
imxrt118x_ele_receivemsg(&g_msg);
|
||||
|
||||
if (response)
|
||||
{
|
||||
*response = g_msg.data[0];
|
||||
}
|
||||
|
||||
if ((g_msg.data[0] & 0xff) == ELE_OK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
int imxrt118x_ele_start_rng(void)
|
||||
{
|
||||
g_msg.header.version = ELE_VERSION;
|
||||
g_msg.header.tag = ELE_CMD_TAG;
|
||||
g_msg.header.size = 1;
|
||||
g_msg.header.command = ELE_START_RNG_REQ;
|
||||
|
||||
imxrt118x_ele_sendmsg(&g_msg);
|
||||
imxrt118x_ele_receivemsg(&g_msg);
|
||||
|
||||
if ((g_msg.data[0] & 0xff) == ELE_OK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
int imxrt118x_ele_get_trng_state(void)
|
||||
{
|
||||
g_msg.header.version = ELE_VERSION;
|
||||
g_msg.header.tag = ELE_CMD_TAG;
|
||||
g_msg.header.size = 1;
|
||||
g_msg.header.command = ELE_GET_TRNG_STATE_REQ;
|
||||
|
||||
imxrt118x_ele_sendmsg(&g_msg);
|
||||
imxrt118x_ele_receivemsg(&g_msg);
|
||||
|
||||
if ((g_msg.data[0] & 0xff) == ELE_OK)
|
||||
{
|
||||
struct ele_trng_state *ele_trng =
|
||||
(struct ele_trng_state *)(g_msg.data + 1);
|
||||
|
||||
if (ele_trng->trng_state != ELE_TRNG_STATUS_READY ||
|
||||
ele_trng->csal_state != ELE_CSAL_STATUS_READY)
|
||||
{
|
||||
/* Ensure imxrt118x_ele_start_rng() was called earlier or we
|
||||
* will end up here.
|
||||
*/
|
||||
|
||||
return -EBUSY;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
int imxrt118x_ele_get_random(uint32_t paddr, size_t len)
|
||||
{
|
||||
uint16_t counter = 0;
|
||||
uint16_t max_tries = ELE_RNG_TIMEOUT_US / ELE_RNG_SLEEP_US;
|
||||
|
||||
if (paddr == 0 || len == 0)
|
||||
{
|
||||
_err("Wrong input parameters!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
while ((imxrt118x_ele_get_trng_state() != 0))
|
||||
{
|
||||
if (counter > max_tries)
|
||||
{
|
||||
_err("Timed out after %hu iterations!\n", counter);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
usleep(ELE_RNG_SLEEP_US);
|
||||
counter++;
|
||||
}
|
||||
|
||||
/* Flush the cache before sending the request to ELE. */
|
||||
|
||||
up_flush_dcache((uintptr_t)paddr, (uintptr_t)(paddr + len));
|
||||
|
||||
g_msg.header.version = ELE_VERSION_FW;
|
||||
g_msg.header.tag = ELE_CMD_TAG;
|
||||
g_msg.header.size = 4;
|
||||
g_msg.header.command = ELE_GET_RNG_REQ;
|
||||
g_msg.data[0] = 0;
|
||||
g_msg.data[1] = paddr;
|
||||
g_msg.data[2] = len;
|
||||
|
||||
imxrt118x_ele_sendmsg(&g_msg);
|
||||
imxrt118x_ele_receivemsg(&g_msg);
|
||||
|
||||
if ((g_msg.data[0] & 0xff) == ELE_OK)
|
||||
{
|
||||
/* Invalidate the cache so we can read the result from RAM. */
|
||||
|
||||
up_invalidate_dcache((uintptr_t)paddr,
|
||||
(uintptr_t)(paddr + len));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
int imxrt118x_ele_commit(uint32_t info, uint32_t *response)
|
||||
{
|
||||
g_msg.header.version = ELE_VERSION;
|
||||
g_msg.header.tag = ELE_CMD_TAG;
|
||||
g_msg.header.size = 2;
|
||||
g_msg.header.command = ELE_COMMIT_REQ;
|
||||
g_msg.data[0] = info;
|
||||
|
||||
imxrt118x_ele_sendmsg(&g_msg);
|
||||
imxrt118x_ele_receivemsg(&g_msg);
|
||||
|
||||
if (response)
|
||||
{
|
||||
*response = g_msg.data[0];
|
||||
}
|
||||
|
||||
if ((g_msg.data[0] & 0xff) == ELE_OK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
int imxrt118x_ele_enable_apc(void)
|
||||
{
|
||||
g_msg.header.version = ELE_VERSION;
|
||||
g_msg.header.tag = ELE_CMD_TAG;
|
||||
g_msg.header.size = 1;
|
||||
g_msg.header.command = ELE_ENABLE_APC_REQ;
|
||||
|
||||
imxrt118x_ele_sendmsg(&g_msg);
|
||||
imxrt118x_ele_receivemsg(&g_msg);
|
||||
|
||||
if ((g_msg.data[0] & 0xff) == ELE_OK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
int imxrt118x_ele_voltage_change_start(void)
|
||||
{
|
||||
g_msg.header.version = ELE_VERSION;
|
||||
g_msg.header.tag = ELE_CMD_TAG;
|
||||
g_msg.header.size = 1;
|
||||
g_msg.header.command = ELE_VOLTAGE_CHANGE_START_REQ;
|
||||
|
||||
imxrt118x_ele_sendmsg(&g_msg);
|
||||
imxrt118x_ele_receivemsg(&g_msg);
|
||||
|
||||
if ((g_msg.data[0] & 0xff) == ELE_OK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
int imxrt118x_ele_voltage_change_finish(void)
|
||||
{
|
||||
g_msg.header.version = ELE_VERSION;
|
||||
g_msg.header.tag = ELE_CMD_TAG;
|
||||
g_msg.header.size = 1;
|
||||
g_msg.header.command = ELE_VOLTAGE_CHANGE_FINISH_REQ;
|
||||
|
||||
imxrt118x_ele_sendmsg(&g_msg);
|
||||
imxrt118x_ele_receivemsg(&g_msg);
|
||||
|
||||
if ((g_msg.data[0] & 0xff) == ELE_OK)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
int imxrt118x_ele_check_fw_version(void)
|
||||
{
|
||||
g_msg.header.version = ELE_VERSION;
|
||||
g_msg.header.tag = ELE_CMD_TAG;
|
||||
g_msg.header.size = 1;
|
||||
g_msg.header.command = ELE_GET_FW_VERSION_REQ;
|
||||
|
||||
imxrt118x_ele_sendmsg(&g_msg);
|
||||
imxrt118x_ele_receivemsg(&g_msg);
|
||||
|
||||
if ((g_msg.data[0] & 0xff) != ELE_OK)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
367
arch/arm/src/imxrt/imxrt118x_ele.h
Normal file
367
arch/arm/src/imxrt/imxrt118x_ele.h
Normal file
|
|
@ -0,0 +1,367 @@
|
|||
/****************************************************************************
|
||||
* arch/arm/src/imxrt/imxrt118x_ele.h
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_IMXRT_IMXRT118X_ELE_H
|
||||
#define __ARCH_ARM_SRC_IMXRT_IMXRT118X_ELE_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "hardware/rt118x/imxrt118x_ele.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt118x_ele_init
|
||||
*
|
||||
* Description:
|
||||
* Bring the EdgeLock Enclave up.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void imxrt118x_ele_init(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt118x_ele_load_fw
|
||||
*
|
||||
* Description:
|
||||
* Load the EdgeLock Enclave firmware.
|
||||
*
|
||||
* Input Parameters:
|
||||
* fw_addr - Address of the ELE firmware container.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success, a negated errno value otherwise.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt118x_ele_load_fw(uint32_t fw_addr);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt118x_ele_release_rdc
|
||||
*
|
||||
* Description:
|
||||
* Request ownership of one TRDC.
|
||||
*
|
||||
* Input Parameters:
|
||||
* rdc_id - Packed TRDC and core identifier.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success, a negated errno value otherwise.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt118x_ele_release_rdc(uint32_t rdc_id);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt118x_ele_read_common_fuse
|
||||
*
|
||||
* Description:
|
||||
* Read a common fuse value.
|
||||
*
|
||||
* Input Parameters:
|
||||
* fuse_id - Fuse ID
|
||||
*
|
||||
* Returned Value:
|
||||
* Fuse value. Returns zero if read failed.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t imxrt118x_ele_read_common_fuse(uint32_t fuse_id);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt118x_ele_get_key
|
||||
*
|
||||
* Description:
|
||||
* Return HW unique key value.
|
||||
*
|
||||
* Input Parameters:
|
||||
* key - Key buffer, must be cache line aligned
|
||||
* key_size - Key size in bytes, must be 16 or 32
|
||||
* ctx - Context buffer, must be cache line aligned
|
||||
* ctx_size - Context buffer size
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success, a negated errno value otherwise.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt118x_ele_get_key(uint8_t *key, size_t key_size,
|
||||
uint8_t *ctx, size_t ctx_size);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt118x_ele_get_events
|
||||
*
|
||||
* Description:
|
||||
* Return ELE events.
|
||||
*
|
||||
* Input Parameters:
|
||||
* buffer - Event buffer
|
||||
* buffer_size - Event buffer size
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) is returned if no events. A negated errno value is returned
|
||||
* on failure. Positive value is number of events read.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt118x_ele_get_events(uint32_t *buffer, size_t buffer_size);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt118x_ele_close_device
|
||||
*
|
||||
* Description:
|
||||
* Set device to OEM close state. This operation is irreversible.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success, a negated errno value otherwise.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt118x_ele_close_device(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt118x_ele_get_lifecycle
|
||||
*
|
||||
* Description:
|
||||
* Return the device's lifecycle value, queried from the ELE via
|
||||
* GET_INFO (RT118x has no i.MX9-style FSB lifecycle register).
|
||||
*
|
||||
* Returned Value:
|
||||
* Lifecycle value.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t imxrt118x_ele_get_lifecycle(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt118x_ele_auth_oem_ctnr
|
||||
*
|
||||
* Description:
|
||||
* Authenticate container header.
|
||||
*
|
||||
* Input Parameters:
|
||||
* ctnr_addr - Address of the container header.
|
||||
*
|
||||
* Output Parameters:
|
||||
* response - ELE response, can be used for debugging.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success, a negated errno value otherwise.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt118x_ele_auth_oem_ctnr(unsigned long ctnr_addr, uint32_t *response);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt118x_ele_release_container
|
||||
*
|
||||
* Description:
|
||||
* Release the container from the ELE, used after
|
||||
* imxrt118x_ele_auth_oem_ctnr().
|
||||
*
|
||||
* Output Parameters:
|
||||
* response - ELE response, can be used for debugging.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success, a negated errno value otherwise.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt118x_ele_release_container(uint32_t *response);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt118x_ele_verify_image
|
||||
*
|
||||
* Description:
|
||||
* Verify the specified image, for the current container.
|
||||
*
|
||||
* Input Parameters:
|
||||
* img_id - The id of the image in the context of the current container.
|
||||
*
|
||||
* Output Parameters:
|
||||
* response - ELE response, can be used for debugging.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success, a negated errno value otherwise.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt118x_ele_verify_image(uint32_t img_id, uint32_t *response);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt118x_ele_start_rng
|
||||
*
|
||||
* Description:
|
||||
* Sends command to initialize the ELE RNG context.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success, a negated errno value otherwise.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt118x_ele_start_rng(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt118x_ele_get_trng_state
|
||||
*
|
||||
* Description:
|
||||
* Query the state of the True Random Number Generator.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned if the Random Number Generator (RNG) is ready for
|
||||
* use. A negated errno value (-EBUSY) or another is returned on
|
||||
* failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt118x_ele_get_trng_state(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt118x_ele_get_random
|
||||
*
|
||||
* Description:
|
||||
* Request from the ELE the generation of a random number of specified
|
||||
* length.
|
||||
*
|
||||
* Input Parameters:
|
||||
* paddr - 32bit physical address to store the random number.
|
||||
* len - Length in bytes of the random number.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero is returned if ELE successfully generated the random number.
|
||||
* A negated errno value (-EBUSY) or another is returned on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt118x_ele_get_random(uint32_t paddr, size_t len);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt118x_ele_commit
|
||||
*
|
||||
* Description:
|
||||
* Sends commit command to the ELE.
|
||||
*
|
||||
* Input Parameters:
|
||||
* info - Information type to be committed
|
||||
*
|
||||
* Output Parameters:
|
||||
* response - ELE response, can be used for debugging.
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success, a negated errno value otherwise.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt118x_ele_commit(uint32_t info, uint32_t *response);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt118x_ele_enable_apc
|
||||
*
|
||||
* Description:
|
||||
* Enable Access Permission Control for the M7.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success, a negated errno value otherwise.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt118x_ele_enable_apc(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt118x_ele_voltage_change_start
|
||||
*
|
||||
* Description:
|
||||
* Begin an ELE-guarded VDD1P0 voltage change (VOLTAGE_CHANGE_START,
|
||||
* 0x12). When the digital glitch detector (GDET) is enabled, the DCDC
|
||||
* target must only be reprogrammed between this command and
|
||||
* imxrt118x_ele_voltage_change_finish(); otherwise the glitch detector
|
||||
* can trip on the transition and put the SoC into an unpredictable
|
||||
* (lockup/reset) state. While the change is in progress the ELE accepts
|
||||
* no other command and aborts if FINISH is not issued within 50 ms.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success, a negated errno value otherwise. ELE firmware that
|
||||
* does not implement the command simply rejects it, in which case the
|
||||
* caller may proceed with the (unguarded) voltage change.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt118x_ele_voltage_change_start(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt118x_ele_voltage_change_finish
|
||||
*
|
||||
* Description:
|
||||
* Complete an ELE-guarded VDD1P0 voltage change (VOLTAGE_CHANGE_FINISH,
|
||||
* 0x13), removing the GDET isolation started by
|
||||
* imxrt118x_ele_voltage_change_start(). Must be issued within 50 ms of
|
||||
* the START command.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success, a negated errno value otherwise.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt118x_ele_voltage_change_finish(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imxrt118x_ele_check_fw_version
|
||||
*
|
||||
* Description:
|
||||
* Query the EdgeLock Enclave firmware version (GET_FW_VERSION) and log
|
||||
* it, so it can be verified that the intended ELE firmware is active.
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* OK on success, a negated errno value otherwise.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int imxrt118x_ele_check_fw_version(void);
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_IMXRT_IMXRT118X_ELE_H */
|
||||
Loading…
Add table
Add a link
Reference in a new issue