drivers: crypto: MEC172x crypto driver supporting hash
Implement zephyr crypto driver hash API's using calls to MEC172x ROM hash API's. Hardware supports zephyr driver hash modes: SHA-224, 256, 384, and 512. Driver supports synchronous (blocking) mode at this time. Signed-off-by: Manimaran A <manimaran.a@microchip.com>
This commit is contained in:
parent
f8d9cd67c8
commit
3cc7d37b70
|
@ -8,4 +8,5 @@ zephyr_library_sources_ifdef(CONFIG_CRYPTO_STM32 crypto_stm32.c)
|
|||
zephyr_library_sources_ifdef(CONFIG_CRYPTO_NRF_ECB crypto_nrf_ecb.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CRYPTO_INTEL_SHA crypto_intel_sha.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CRYPTO_NPCX_SHA crypto_npcx_sha.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CRYPTO_MCHP_XEC_SYMCR crypto_mchp_xec_symcr.c)
|
||||
zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS)
|
||||
|
|
|
@ -77,5 +77,6 @@ source "drivers/crypto/Kconfig.stm32"
|
|||
source "drivers/crypto/Kconfig.nrf_ecb"
|
||||
source "drivers/crypto/Kconfig.intel"
|
||||
source "drivers/crypto/Kconfig.npcx"
|
||||
source "drivers/crypto/Kconfig.xec"
|
||||
|
||||
endif # CRYPTO
|
||||
|
|
12
drivers/crypto/Kconfig.xec
Normal file
12
drivers/crypto/Kconfig.xec
Normal file
|
@ -0,0 +1,12 @@
|
|||
# Copyright (c) 2022 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
|
||||
config CRYPTO_MCHP_XEC_SYMCR
|
||||
bool "Microchip XEC symmetric crypto (AES/Hash) driver"
|
||||
default y
|
||||
depends on DT_HAS_MICROCHIP_XEC_SYMCR_ENABLED
|
||||
help
|
||||
Enable Microchip XEC symmetic crypto (AES/Hash) driver.
|
||||
Symmetric crypto provides a single hardware interface
|
||||
to AES and hash engines.
|
548
drivers/crypto/crypto_mchp_xec_symcr.c
Normal file
548
drivers/crypto/crypto_mchp_xec_symcr.c
Normal file
|
@ -0,0 +1,548 @@
|
|||
/*
|
||||
* Copyright (c) 2023 Microchip Technology Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT microchip_xec_symcr
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/crypto/crypto.h>
|
||||
#include <zephyr/drivers/clock_control.h>
|
||||
#include <zephyr/drivers/clock_control/mchp_xec_clock_control.h>
|
||||
#include "zephyr/sys/util.h"
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(xec_symcr, CONFIG_CRYPTO_LOG_LEVEL);
|
||||
|
||||
#include <soc.h>
|
||||
|
||||
/* ROM API for Hash without using external files */
|
||||
|
||||
enum mchp_rom_hash_alg_id {
|
||||
MCHP_ROM_HASH_ALG_NONE = 0,
|
||||
MCHP_ROM_HASH_ALG_SHA1,
|
||||
MCHP_ROM_HASH_ALG_SHA224,
|
||||
MCHP_ROM_HASH_ALG_SHA256,
|
||||
MCHP_ROM_HASH_ALG_SHA384,
|
||||
MCHP_ROM_HASH_ALG_SHA512,
|
||||
MCHP_ROM_HASH_ALG_SM3,
|
||||
MCHP_ROM_HASH_ALG_MAX
|
||||
};
|
||||
|
||||
#define MCHP_XEC_STRUCT_HASH_STATE_STRUCT_SIZE 8
|
||||
#define MCHP_XEC_STRUCT_HASH_STRUCT_SIZE 240
|
||||
|
||||
struct mchphashstate {
|
||||
uint32_t v[MCHP_XEC_STRUCT_HASH_STATE_STRUCT_SIZE / 4];
|
||||
};
|
||||
|
||||
struct mchphash {
|
||||
uint32_t v[MCHP_XEC_STRUCT_HASH_STRUCT_SIZE / 4];
|
||||
};
|
||||
|
||||
#define MCHP_XEC_ROM_API_BASE DT_REG_ADDR(DT_NODELABEL(rom_api))
|
||||
#define MCHP_XEC_ROM_API_ADDR(n) \
|
||||
(((uint32_t)(MCHP_XEC_ROM_API_BASE) + ((uint32_t)(n) * 4u)) | BIT(0))
|
||||
|
||||
#define MCHP_XEC_ROM_HASH_CREATE_SHA224_ID 95
|
||||
#define mchp_xec_rom_hash_create_sha224 \
|
||||
((int (*)(struct mchphash *)) MCHP_XEC_ROM_API_ADDR(MCHP_XEC_ROM_HASH_CREATE_SHA224_ID))
|
||||
|
||||
#define MCHP_XEC_ROM_HASH_CREATE_SHA256_ID 96
|
||||
#define mchp_xec_rom_hash_create_sha256 \
|
||||
((int (*)(struct mchphash *)) MCHP_XEC_ROM_API_ADDR(MCHP_XEC_ROM_HASH_CREATE_SHA256_ID))
|
||||
|
||||
#define MCHP_XEC_ROM_HASH_CREATE_SHA384_ID 97
|
||||
#define mchp_xec_rom_hash_create_sha384 \
|
||||
((int (*)(struct mchphash *)) MCHP_XEC_ROM_API_ADDR(MCHP_XEC_ROM_HASH_CREATE_SHA384_ID))
|
||||
|
||||
#define MCHP_XEC_ROM_HASH_CREATE_SHA512_ID 98
|
||||
#define mchp_xec_rom_hash_create_sha512 \
|
||||
((int (*)(struct mchphash *)) MCHP_XEC_ROM_API_ADDR(MCHP_XEC_ROM_HASH_CREATE_SHA512_ID))
|
||||
|
||||
|
||||
#define MCHP_XEC_ROM_HASH_INIT_STATE_ID 100
|
||||
#define mec172x_rom_hash_init_state \
|
||||
((void (*)(struct mchphash *, struct mchphashstate *, char *)) \
|
||||
MCHP_XEC_ROM_API_ADDR(MCHP_XEC_ROM_HASH_INIT_STATE_ID))
|
||||
|
||||
#define MCHP_XEC_ROM_HASH_RESUME_STATE_ID 101
|
||||
#define mchp_xec_rom_hash_resume_state \
|
||||
((void (*)(struct mchphash *, struct mchphashstate *)) \
|
||||
MCHP_XEC_ROM_API_ADDR(MCHP_XEC_ROM_HASH_RESUME_STATE_ID))
|
||||
|
||||
#define MCHP_XEC_ROM_HASH_SAVE_STATE_ID 102
|
||||
#define mchp_xec_rom_hash_save_state \
|
||||
((int (*)(struct mchphash *)) MCHP_XEC_ROM_API_ADDR(MCHP_XEC_ROM_HASH_SAVE_STATE_ID))
|
||||
|
||||
#define MCHP_XEC_ROM_HASH_FEED_ID 103
|
||||
#define mchp_xec_rom_hash_feed \
|
||||
((int (*)(struct mchphash *, const uint8_t *, size_t)) \
|
||||
MCHP_XEC_ROM_API_ADDR(MCHP_XEC_ROM_HASH_FEED_ID))
|
||||
|
||||
#define MCHP_XEC_ROM_HASH_DIGEST_ID 104
|
||||
#define mchp_xec_rom_hash_digest \
|
||||
((int (*)(struct mchphash *, char *)) MCHP_XEC_ROM_API_ADDR(MCHP_XEC_ROM_HASH_DIGEST_ID))
|
||||
|
||||
#define MCHP_XEC_ROM_HASH_WAIT_ID 105
|
||||
#define mec172x_rom_hash_wait \
|
||||
((int (*)(struct mchphash *)) MCHP_XEC_ROM_API_ADDR(MCHP_XEC_ROM_HASH_WAIT_ID))
|
||||
|
||||
#define MCHP_XEC_ROM_AH_DMA_INIT_ID 144
|
||||
#define mchp_xec_rom_ah_dma_init \
|
||||
((int (*)(uint8_t)) MCHP_XEC_ROM_API_ADDR(MCHP_XEC_ROM_AH_DMA_INIT_ID))
|
||||
|
||||
#define MCHP_ROM_AH_DMA_INIT_NO_RESET 0
|
||||
#define MCHP_ROM_AH_DMA_INIT_WITH_RESET 1
|
||||
|
||||
#define MCHP_XEC_SYMCR_CAPS_SUPPORT \
|
||||
(CAP_RAW_KEY | CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS | CAP_NO_IV_PREFIX)
|
||||
#define MCHP_XEC_SYMCR_MAX_SESSION 1
|
||||
#define MCHP_XEC_STATE_BUF_SIZE 256
|
||||
#define MCHP_XEC_BLOCK_BUF_SIZE 128
|
||||
|
||||
struct xec_symcr_hash_session {
|
||||
struct mchphash mhctx;
|
||||
struct mchphashstate mhstate;
|
||||
enum hash_algo algo;
|
||||
enum mchp_rom_hash_alg_id rom_algo;
|
||||
bool open;
|
||||
size_t blksz;
|
||||
size_t blklen;
|
||||
uint8_t blockbuf[MCHP_XEC_BLOCK_BUF_SIZE] __aligned(4);
|
||||
uint8_t statebuf[MCHP_XEC_STATE_BUF_SIZE] __aligned(4);
|
||||
};
|
||||
|
||||
struct xec_symcr_config {
|
||||
uint32_t regbase;
|
||||
const struct device *clk_dev;
|
||||
struct mchp_xec_pcr_clk_ctrl clk_ctrl;
|
||||
uint8_t irq_num;
|
||||
uint8_t girq;
|
||||
uint8_t girq_pos;
|
||||
uint8_t rsvd1;
|
||||
};
|
||||
|
||||
struct xec_symcr_data {
|
||||
struct xec_symcr_hash_session hash_sessions[MCHP_XEC_SYMCR_MAX_SESSION];
|
||||
};
|
||||
|
||||
static int mchp_xec_get_unused_session_index(struct xec_symcr_data *data)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MCHP_XEC_SYMCR_MAX_SESSION; i++) {
|
||||
if (!data->hash_sessions[i].open) {
|
||||
data->hash_sessions[i].open = true;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
struct hash_alg_to_rom {
|
||||
enum hash_algo algo;
|
||||
enum mchp_rom_hash_alg_id rom_algo;
|
||||
};
|
||||
|
||||
const struct hash_alg_to_rom hash_alg_tbl[] = {
|
||||
{ CRYPTO_HASH_ALGO_SHA224, MCHP_ROM_HASH_ALG_SHA224 },
|
||||
{ CRYPTO_HASH_ALGO_SHA256, MCHP_ROM_HASH_ALG_SHA256 },
|
||||
{ CRYPTO_HASH_ALGO_SHA384, MCHP_ROM_HASH_ALG_SHA384 },
|
||||
{ CRYPTO_HASH_ALGO_SHA512, MCHP_ROM_HASH_ALG_SHA512 },
|
||||
};
|
||||
|
||||
static enum mchp_rom_hash_alg_id lookup_hash_alg(enum hash_algo algo)
|
||||
{
|
||||
for (size_t n = 0; n < ARRAY_SIZE(hash_alg_tbl); n++) {
|
||||
if (hash_alg_tbl[n].algo == algo) {
|
||||
return hash_alg_tbl[n].rom_algo;
|
||||
}
|
||||
}
|
||||
|
||||
return MCHP_ROM_HASH_ALG_NONE;
|
||||
}
|
||||
|
||||
/* SHA-1, 224, and 256 use block size of 64 bytes
|
||||
* SHA-384 and 512 use 128 bytes.
|
||||
*/
|
||||
static size_t hash_block_size(enum hash_algo algo)
|
||||
{
|
||||
switch (algo) {
|
||||
case CRYPTO_HASH_ALGO_SHA384:
|
||||
case CRYPTO_HASH_ALGO_SHA512:
|
||||
return 128u;
|
||||
default:
|
||||
return 64u;
|
||||
}
|
||||
}
|
||||
|
||||
static int init_rom_hash_context(enum mchp_rom_hash_alg_id rom_algo, struct mchphash *c)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!c) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (rom_algo) {
|
||||
case MCHP_ROM_HASH_ALG_SHA224:
|
||||
ret = mchp_xec_rom_hash_create_sha224(c);
|
||||
break;
|
||||
case MCHP_ROM_HASH_ALG_SHA256:
|
||||
ret = mchp_xec_rom_hash_create_sha256(c);
|
||||
break;
|
||||
case MCHP_ROM_HASH_ALG_SHA384:
|
||||
ret = mchp_xec_rom_hash_create_sha384(c);
|
||||
break;
|
||||
case MCHP_ROM_HASH_ALG_SHA512:
|
||||
ret = mchp_xec_rom_hash_create_sha512(c);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ret) { /* use zephyr return value */
|
||||
ret = -EIO;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* use zephyr return values */
|
||||
int mchp_xec_rom_hash_init_state_wrapper(struct mchphash *c, struct mchphashstate *h,
|
||||
uint8_t *dmamem)
|
||||
{
|
||||
if (!c || !h || !dmamem) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mec172x_rom_hash_init_state(c, h, (char *)dmamem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mchp_xec_rom_hash_resume_state_wrapper(struct mchphash *c, struct mchphashstate *h)
|
||||
{
|
||||
if (!c || !h) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mchp_xec_rom_hash_resume_state(c, h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mchp_xec_rom_hash_save_state_wrapper(struct mchphash *c)
|
||||
{
|
||||
if (!c) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (mchp_xec_rom_hash_save_state(c) != 0) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mchp_xec_rom_hash_feed_wrapper(struct mchphash *c, const uint8_t *msg, size_t sz)
|
||||
{
|
||||
if ((!c) || (!msg && sz)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (mchp_xec_rom_hash_feed(c, (const char *)msg, sz) != 0) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mchp_xec_rom_hash_digest_wrapper(struct mchphash *c, uint8_t *digest)
|
||||
{
|
||||
if (!c || !digest) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (mchp_xec_rom_hash_digest(c, (char *)digest)) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Wait for hardware to finish.
|
||||
* returns 0 if hardware finished with no errors
|
||||
* returns -EIO if hardware stopped due to error
|
||||
* returns -EINVAL if parameter is bad, hardware may still be running!
|
||||
*/
|
||||
int mchp_xec_rom_hash_wait_wrapper(struct mchphash *c)
|
||||
{
|
||||
if (!c) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (mec172x_rom_hash_wait(c) != 0) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Called by application for update(finish==false)
|
||||
* and compute final hash digest(finish==true)
|
||||
*/
|
||||
static int xec_symcr_do_hash(struct hash_ctx *ctx, struct hash_pkt *pkt, bool finish)
|
||||
{
|
||||
struct xec_symcr_hash_session *hs = NULL;
|
||||
struct mchphash *c = NULL;
|
||||
struct mchphashstate *cstate = NULL;
|
||||
size_t fill_len = 0, rem_len = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (!ctx || !pkt) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
hs = (struct xec_symcr_hash_session *)ctx->drv_sessn_state;
|
||||
c = &hs->mhctx;
|
||||
cstate = &hs->mhstate;
|
||||
|
||||
if (!hs->open) {
|
||||
LOG_ERR("Session not open");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (!finish && !pkt->in_len) {
|
||||
return 0; /* nothing to do */
|
||||
}
|
||||
|
||||
/* Not final digest computation and not enough data to run engine */
|
||||
if (!finish && ((hs->blklen + pkt->in_len) < hs->blksz)) {
|
||||
memcpy(&hs->blockbuf[hs->blklen], pkt->in_buf, pkt->in_len);
|
||||
hs->blklen += pkt->in_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = init_rom_hash_context(hs->rom_algo, c);
|
||||
if (ret) {
|
||||
LOG_ERR("ROM context init error %d", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = mchp_xec_rom_hash_resume_state_wrapper(c, cstate);
|
||||
if (ret) {
|
||||
LOG_ERR("Resume state error %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
fill_len = pkt->in_len;
|
||||
rem_len = 0;
|
||||
if (!finish) {
|
||||
rem_len = pkt->in_len & (hs->blksz - 1u);
|
||||
fill_len = pkt->in_len & ~(hs->blksz - 1u);
|
||||
if (hs->blklen) {
|
||||
fill_len = ((hs->blklen + pkt->in_len) & ~(hs->blksz - 1u)) - hs->blklen;
|
||||
rem_len = pkt->in_len - fill_len;
|
||||
}
|
||||
}
|
||||
|
||||
if (hs->blklen) {
|
||||
ret = mchp_xec_rom_hash_feed_wrapper(c, (const uint8_t *)hs->blockbuf, hs->blklen);
|
||||
if (ret) {
|
||||
LOG_ERR("ROM hash feed error %d", ret);
|
||||
return ret;
|
||||
}
|
||||
hs->blklen = 0; /* consumed */
|
||||
}
|
||||
|
||||
ret = mchp_xec_rom_hash_feed_wrapper(c, (const uint8_t *)pkt->in_buf, fill_len);
|
||||
if (ret) {
|
||||
LOG_ERR("ROM hash feed error %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (finish) {
|
||||
ret = mchp_xec_rom_hash_digest_wrapper(c, pkt->out_buf);
|
||||
if (ret) {
|
||||
LOG_ERR("ROM Hash final error %d", ret);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
ret = mchp_xec_rom_hash_save_state(c);
|
||||
if (ret) {
|
||||
LOG_ERR("ROM hash save state error %d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
ret = mchp_xec_rom_hash_wait_wrapper(c);
|
||||
if (ret) {
|
||||
LOG_ERR("ROM hash wait error %d", ret);
|
||||
return ret;
|
||||
}
|
||||
if (finish) {
|
||||
hs->blklen = 0;
|
||||
} else {
|
||||
memcpy(hs->blockbuf, &pkt->in_buf[fill_len], rem_len);
|
||||
hs->blklen = rem_len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xec_symcr_hash_session_begin(const struct device *dev, struct hash_ctx *ctx,
|
||||
enum hash_algo algo)
|
||||
{
|
||||
struct xec_symcr_data *data = dev->data;
|
||||
struct xec_symcr_hash_session *hs = NULL;
|
||||
struct mchphash *c = NULL;
|
||||
struct mchphashstate *cstate = NULL;
|
||||
enum mchp_rom_hash_alg_id rom_algo = MCHP_ROM_HASH_ALG_NONE;
|
||||
int session_idx = 0;
|
||||
int ret = 0;
|
||||
|
||||
if (ctx->flags & ~(MCHP_XEC_SYMCR_CAPS_SUPPORT)) {
|
||||
LOG_ERR("Unsupported flag");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rom_algo = lookup_hash_alg(algo);
|
||||
if (rom_algo == MCHP_ROM_HASH_ALG_NONE) {
|
||||
LOG_ERR("Unsupported algo %d", algo);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
session_idx = mchp_xec_get_unused_session_index(data);
|
||||
if (session_idx < 0) {
|
||||
LOG_ERR("No session available");
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
hs = &data->hash_sessions[session_idx];
|
||||
|
||||
hs->algo = algo;
|
||||
hs->rom_algo = rom_algo;
|
||||
hs->open = false;
|
||||
hs->blklen = 0;
|
||||
hs->blksz = hash_block_size(algo);
|
||||
|
||||
ctx->drv_sessn_state = hs;
|
||||
ctx->started = false;
|
||||
ctx->hash_hndlr = xec_symcr_do_hash;
|
||||
|
||||
/* reset HW at beginning of session */
|
||||
ret = mchp_xec_rom_ah_dma_init(MCHP_ROM_AH_DMA_INIT_WITH_RESET);
|
||||
if (ret) {
|
||||
LOG_ERR("ROM HW init error %d", ret);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
c = &hs->mhctx;
|
||||
cstate = &hs->mhstate;
|
||||
|
||||
ret = init_rom_hash_context(hs->rom_algo, c);
|
||||
if (ret) {
|
||||
LOG_ERR("ROM HW context init error %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mchp_xec_rom_hash_init_state_wrapper(c, cstate, hs->statebuf);
|
||||
if (ret) {
|
||||
LOG_ERR("ROM HW init state error %d", ret);
|
||||
}
|
||||
|
||||
hs->open = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* struct hash_ctx {
|
||||
* const struct device *device; this device driver's instance structure
|
||||
* void *drv_sessn_state; pointer to driver instance struct session state. Defined by driver
|
||||
* hash_op hash_hndlr; pointer to this driver function. App calls via pointer to do operations
|
||||
* bool started; true if multipart hash has been started
|
||||
* uint16_t flags; app populates this before calling hash_begin_session
|
||||
* }
|
||||
*/
|
||||
static int xec_symcr_hash_session_free(const struct device *dev, struct hash_ctx *ctx)
|
||||
{
|
||||
struct xec_symcr_hash_session *hs = NULL;
|
||||
int ret = 0;
|
||||
|
||||
ret = mchp_xec_rom_ah_dma_init(MCHP_ROM_AH_DMA_INIT_WITH_RESET);
|
||||
if (ret) {
|
||||
ret = -EIO;
|
||||
LOG_ERR("ROM HW reset error %d", ret);
|
||||
}
|
||||
|
||||
hs = (struct xec_symcr_hash_session *)ctx->drv_sessn_state;
|
||||
|
||||
memset(hs, 0, sizeof(struct xec_symcr_hash_session));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int xec_symcr_query_hw_caps(const struct device *dev)
|
||||
{
|
||||
return MCHP_XEC_SYMCR_CAPS_SUPPORT;
|
||||
}
|
||||
|
||||
static int xec_symcr_init(const struct device *dev)
|
||||
{
|
||||
const struct xec_symcr_config *cfg = dev->config;
|
||||
int ret;
|
||||
|
||||
if (!device_is_ready(cfg->clk_dev)) {
|
||||
LOG_ERR("clock device not ready");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = clock_control_on(cfg->clk_dev, (clock_control_subsys_t *)&cfg->clk_ctrl);
|
||||
if (ret < 0) {
|
||||
LOG_ERR("clock on error %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mchp_xec_rom_ah_dma_init(MCHP_ROM_AH_DMA_INIT_WITH_RESET);
|
||||
if (ret) {
|
||||
ret = -EIO;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct crypto_driver_api xec_symcr_api = {
|
||||
.query_hw_caps = xec_symcr_query_hw_caps,
|
||||
.hash_begin_session = xec_symcr_hash_session_begin,
|
||||
.hash_free_session = xec_symcr_hash_session_free,
|
||||
};
|
||||
|
||||
#define XEC_SYMCR_PCR_INFO(i) \
|
||||
MCHP_XEC_PCR_SCR_ENCODE(DT_INST_CLOCKS_CELL(i, regidx), \
|
||||
DT_INST_CLOCKS_CELL(i, bitpos), \
|
||||
DT_INST_CLOCKS_CELL(i, domain))
|
||||
|
||||
#define XEC_SYMCR_INIT(inst) \
|
||||
\
|
||||
static struct xec_symcr_data xec_symcr_data_##inst; \
|
||||
\
|
||||
static const struct xec_symcr_config xec_symcr_cfg_##inst = { \
|
||||
.regbase = DT_INST_REG_ADDR(inst), \
|
||||
.clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(inst)), \
|
||||
.clk_ctrl = { \
|
||||
.pcr_info = XEC_SYMCR_PCR_INFO(inst), \
|
||||
}, \
|
||||
.irq_num = DT_INST_IRQN(inst), \
|
||||
.girq = DT_INST_PROP_BY_IDX(inst, girqs, 0), \
|
||||
.girq_pos = DT_INST_PROP_BY_IDX(inst, girqs, 1), \
|
||||
}; \
|
||||
\
|
||||
DEVICE_DT_INST_DEFINE(inst, &xec_symcr_init, NULL, \
|
||||
&xec_symcr_data_##inst, &xec_symcr_cfg_##inst, \
|
||||
POST_KERNEL, CONFIG_CRYPTO_INIT_PRIORITY, \
|
||||
&xec_symcr_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(XEC_SYMCR_INIT)
|
|
@ -471,10 +471,10 @@
|
|||
dmac: dmac@40002400 {
|
||||
compatible = "microchip,xec-dmac";
|
||||
reg = <0x40002400 0xc00>;
|
||||
interrupts = <24 0>, <25 0>, <26 0>, <27 0>,
|
||||
<28 0>, <29 0>, <30 0>, <31 0>,
|
||||
<32 0>, <33 0>, <34 0>, <35 0>,
|
||||
<36 0>, <37 0>, <38 0>, <39 0>;
|
||||
interrupts = <24 1>, <25 1>, <26 1>, <27 1>,
|
||||
<28 1>, <29 1>, <30 1>, <31 1>,
|
||||
<32 1>, <33 1>, <34 1>, <35 1>,
|
||||
<36 1>, <37 1>, <38 1>, <39 1>;
|
||||
girqs = < MCHP_XEC_ECIA(14, 0, 6, 24)
|
||||
MCHP_XEC_ECIA(14, 1, 6, 25)
|
||||
MCHP_XEC_ECIA(14, 2, 6, 26)
|
||||
|
@ -1027,6 +1027,22 @@
|
|||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
symcr: symcr@40100000 {
|
||||
compatible = "microchip,xec-symcr";
|
||||
reg = <0x40100000 0x1000>;
|
||||
interrupts = <68 1>;
|
||||
clocks = <&pcr 3 26 MCHP_XEC_PCR_CLK_PERIPH>;
|
||||
girqs = <16 3>;
|
||||
status = "disabled";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
};
|
||||
|
||||
rom_api: rom_api@1f000 {
|
||||
reg = <0x1f000 0x1000>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
20
dts/bindings/crypto/microchip,xec-symcr.yaml
Normal file
20
dts/bindings/crypto/microchip,xec-symcr.yaml
Normal file
|
@ -0,0 +1,20 @@
|
|||
# Copyright (c) 2023 Microchip Technology Inc.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: Microchip XEC symmetric crypto (AES/Hash) accelerator.
|
||||
|
||||
compatible: "microchip,xec-symcr"
|
||||
|
||||
include: base.yaml
|
||||
|
||||
properties:
|
||||
reg:
|
||||
required: true
|
||||
|
||||
clocks:
|
||||
required: true
|
||||
|
||||
girqs:
|
||||
type: array
|
||||
required: true
|
||||
description: XEC ECIA GIRQ number and bit position.
|
Loading…
Reference in a new issue