openmv/lib/stm32/n6/src/stm32n6xx_hal_mce.c
iabdalkader daf2bb30da misc: Restructure repo.
Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
2025-04-13 08:28:34 +02:00

1049 lines
30 KiB
C

/**
******************************************************************************
* @file stm32n6xx_hal_mce.c
* @author MCD Application Team
* @brief MCE HAL module driver.
* This file provides firmware functions to manage the following
* features of the Memory Cipher Engine (MCE) peripheral:
* + Initialization and de-initialization functions
* + Region setting/enable functions
* + Peripheral State functions
*
******************************************************************************
* @attention
*
* Copyright (c) 2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
@verbatim
==============================================================================
##### How to use this driver #####
==============================================================================
[..]
The MCE HAL driver can be used as follows:
(#) ToBC (refer to MCE comments)
[..]
*** Callback registration ***
=============================================
[..]
The compilation flag USE_HAL_MCE_REGISTER_CALLBACKS, when set to 1,
allows the user to configure dynamically the driver callbacks.
Use Functions @ref HAL_MCE_RegisterCallback()
to register an interrupt callback.
[..]
ToBC (refer to MCE comments)
When the compilation flag USE_HAL_MCE_REGISTER_CALLBACKS is set to 0 or
not defined, the callback registration feature is not available and all callbacks
are set to the corresponding weak functions.
@endverbatim
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32n6xx_hal.h"
/** @addtogroup STM32N6xx_HAL_Driver
* @{
*/
/** @defgroup MCE MCE
* @brief MCE HAL module driver.
* @{
*/
#ifdef HAL_MCE_MODULE_ENABLED
#if defined(MCE1)
/* Private typedef -----------------------------------------------------------*/
/* Private defines -----------------------------------------------------------*/
#define MCE_TIMEOUT_VALUE 255U /* Internal timeout for keys valid flag */
#define MCE1_CONTEXT_NB 2U
/* Private macros ------------------------------------------------------------*/
#define IS_MCE_AES_INSTANCE(INSTANCE) ((INSTANCE) == MCE1)
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/** @addtogroup MCE_Exported_Functions
* @{
*/
/** @defgroup MCE_Exported_Functions_Group1 Initialization and de-initialization functions
* @brief Initialization and Configuration functions.
*
@verbatim
==============================================================================
##### Initialization and de-initialization functions #####
==============================================================================
@endverbatim
* @{
*/
/**
* @brief Initialize the MCE peripheral and create the associated handle.
* @param hmce pointer to an MCE_HandleTypeDef structure that contains
* the configuration information for MCE module
* @retval HAL status
*/
HAL_StatusTypeDef HAL_MCE_Init(MCE_HandleTypeDef *hmce)
{
/* Check the MCE handle allocation */
if (hmce == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
if (hmce->State == HAL_MCE_STATE_RESET)
{
/* Allocate lock resource and initialize it */
__HAL_UNLOCK(hmce);
#if (USE_HAL_MCE_REGISTER_CALLBACKS == 1)
/* Init the MCE Callback settings */
hmce->ErrorCallback = HAL_MCE_ErrorCallback; /* Legacy weak callback */
if (hmce->MspInitCallback == NULL)
{
hmce->MspInitCallback = HAL_MCE_MspInit; /* Legacy weak MspInit */
}
/* Init the low level hardware */
hmce->MspInitCallback(hmce);
#else
/* Init the low level hardware */
HAL_MCE_MspInit(hmce);
#endif /* USE_HAL_MCE_REGISTER_CALLBACKS */
}
/* Change the MCE state */
hmce->State = HAL_MCE_STATE_READY;
/* Return function status */
return HAL_OK;
}
/**
* @brief DeInitialize the MCE peripheral.
* @note Any lock set at peripheral, key or cipher context level requires a MCE peripheral reset
* @param hmce pointer to an MCE_HandleTypeDef structure that contains
* the configuration information for MCE module
* @retval HAL status
*/
HAL_StatusTypeDef HAL_MCE_DeInit(MCE_HandleTypeDef *hmce)
{
MCE_Region_TypeDef *p_region;
MCE_Context_TypeDef *p_context;
/* Check the MCE handle allocation */
if (hmce == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
/* Change the MCE state */
hmce->State = HAL_MCE_STATE_BUSY;
/* Disable interrupts */
CLEAR_BIT(hmce->Instance->IAIER, MCE_IAIER_IAEIE);
/* Disable all regions */
for (uint32_t i = MCE_REGION1; i <= MCE_REGION4; i++)
{
p_region = (MCE_Region_TypeDef *)((uint32_t)(hmce->Instance) + 0x40U + (0x10U * i));
CLEAR_BIT(p_region->REGCR, MCE_REGCR_BREN);
/** we don't have the registry ATTR in this product */
}
/* Disable all cipher contexts if any for the MCE instance */
if (hmce->Instance == MCE1)
{
for (uint32_t i = 0; i < MCE1_CONTEXT_NB; i++)
{
p_context = (MCE_Context_TypeDef *)((uint32_t)(hmce->Instance) + 0x240U + (0x30U * i));
CLEAR_BIT(p_context->CCCFGR, MCE_CCCFGR_CCEN);
}
}
/* Clear privileged-only configuration access */
/** we don't have the registry PRIVCFGR in this product */
/* Clear flags */
WRITE_REG(hmce->Instance->IACR, MCE_IACR_IAEF);
#if (USE_HAL_MCE_REGISTER_CALLBACKS == 1)
if (hmce->MspDeInitCallback == NULL)
{
hmce->MspDeInitCallback = HAL_MCE_MspDeInit; /* Legacy weak MspDeInit */
}
/* DeInit the low level hardware: CLOCK, NVIC */
hmce->MspDeInitCallback(hmce);
#else
/* DeInit the low level hardware: CLOCK, NVIC */
HAL_MCE_MspDeInit(hmce);
#endif /* USE_HAL_MCE_REGISTER_CALLBACKS */
/* Change the MCE state */
hmce->State = HAL_MCE_STATE_RESET;
/* Reset MCE error status */
hmce->ErrorCode = HAL_MCE_ERROR_NONE;
/* Release Lock */
__HAL_UNLOCK(hmce);
/* Return function status */
return HAL_OK;
}
/** ********* main sequence functions : set the configuration of regions, AES context and Noekeon config *********/
/**
* @brief Write instance master or fast master keys
* @param hmce pointer to an MCE_HandleTypeDef structure that contains
* the configuration information for MCE module
* @param pConfig pointer at an MCE_NoekeonConfig structure that contains
the configuration on the Noekeon encryption engine
* @note Writes are ignored if MKLOCK or GLOCK bit is set in MCE_CR register and HAL error
* is reported in that case
* @retval HAL status
*/
HAL_StatusTypeDef HAL_MCE_ConfigNoekeon(MCE_HandleTypeDef *hmce, const MCE_NoekeonConfigTypeDef *pConfig)
{
HAL_StatusTypeDef ret = HAL_OK;
uint32_t tickstart;
/* Check the parameters */
assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
/* If Key is null, or
if the global lock is set or
if the master keys lock is set,
return an error */
tickstart = HAL_GetTick();
if (((hmce->Instance->CR & (MCE_CR_GLOCK | MCE_CR_MKLOCK)) == 0U) && (pConfig->pKey != NULL))
{
/* Take Lock */
__HAL_LOCK(hmce);
MODIFY_REG(hmce->Instance->CR, MCE_CR_CIPHERSEL, MCE_NOEKEON);
/* master keys are used for encryption */
if (pConfig->KeyType == MCE_USE_MASTERKEYS)
{
/* If Master Key valid flag is set, need to write dummy value in MKEYRx to reset it */
if ((hmce->Instance->SR & MCE_SR_MKVALID) != 0U)
{
WRITE_REG(hmce->Instance->MKEYR0, 0U);
}
/* Set Key */
WRITE_REG(hmce->Instance->MKEYR0, pConfig->pKey[0]);
WRITE_REG(hmce->Instance->MKEYR1, pConfig->pKey[1]);
WRITE_REG(hmce->Instance->MKEYR2, pConfig->pKey[2]);
WRITE_REG(hmce->Instance->MKEYR3, pConfig->pKey[3]);
WRITE_REG(hmce->Instance->MKEYR4, pConfig->pKey[4]);
WRITE_REG(hmce->Instance->MKEYR5, pConfig->pKey[5]);
WRITE_REG(hmce->Instance->MKEYR6, pConfig->pKey[6]);
WRITE_REG(hmce->Instance->MKEYR7, pConfig->pKey[7]);
while (HAL_IS_BIT_CLR(hmce->Instance->SR, MCE_SR_MKVALID))
{
/* Check for the Timeout */
if ((HAL_GetTick() - tickstart) > MCE_TIMEOUT_VALUE)
{
hmce->ErrorCode |= HAL_MCE_MASTER_KEY_ERROR;
ret = HAL_ERROR;
break;
}
}
}
else if (pConfig->KeyType == MCE_USE_FASTMASTERKEYS)
{
/* If Fast Master Key valid flag is set, need to write dummy value in FMKEYRx to reset it */
if ((hmce->Instance->SR & MCE_SR_FMKVALID) != 0U)
{
WRITE_REG(hmce->Instance->FMKEYR0, 0U);
}
/* Set Key */
WRITE_REG(hmce->Instance->FMKEYR0, pConfig->pKey[0]);
WRITE_REG(hmce->Instance->FMKEYR1, pConfig->pKey[1]);
WRITE_REG(hmce->Instance->FMKEYR2, pConfig->pKey[2]);
WRITE_REG(hmce->Instance->FMKEYR3, pConfig->pKey[3]);
WRITE_REG(hmce->Instance->FMKEYR4, pConfig->pKey[4]);
WRITE_REG(hmce->Instance->FMKEYR5, pConfig->pKey[5]);
WRITE_REG(hmce->Instance->FMKEYR6, pConfig->pKey[6]);
WRITE_REG(hmce->Instance->FMKEYR7, pConfig->pKey[7]);
while (HAL_IS_BIT_CLR(hmce->Instance->SR, MCE_SR_FMKVALID))
{
/* Check for the Timeout */
if ((HAL_GetTick() - tickstart) > MCE_TIMEOUT_VALUE)
{
hmce->ErrorCode |= HAL_MCE_FASTMASTER_KEY_ERROR;
ret = HAL_ERROR;
break;
}
}
}
else
{
/* nothing to do, the keytype is not valid */
}
__HAL_UNLOCK(hmce);
}
return ret;
}
/**
* @brief Set context configuration.
* @param hmce pointer to an MCE_HandleTypeDef structure that contains
* the configuration information for MCE module
* @param AESConfig context configuration
* @param ContextIndex index of context that is configured
* @retval HAL status
*/
HAL_StatusTypeDef HAL_MCE_ConfigAESContext(MCE_HandleTypeDef *hmce, const MCE_AESConfigTypeDef *AESConfig,
uint32_t ContextIndex)
{
HAL_StatusTypeDef ret = HAL_ERROR;
MCE_Context_TypeDef *p_context;
uint32_t *p_key;
__IO uint32_t address;
/* Check the parameters */
assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
assert_param(IS_MCE_CONTEXT(hmce->Instance, ContextIndex));
/* If global lock is set or no configuration provided, context cannot be configured */
if (((hmce->Instance->CR & MCE_CR_GLOCK) != MCE_CR_GLOCK) && (AESConfig != NULL) && \
((ContextIndex == MCE_CONTEXT1) || (ContextIndex == MCE_CONTEXT2)))
{
address = (__IO uint32_t)((uint32_t)hmce->Instance + 0x240UL + \
(0x30UL * ((ContextIndex - MCE_CONTEXT1) >> MCE_REGCR_CTXID_Pos)));
p_context = (MCE_Context_TypeDef *)address;
MODIFY_REG(hmce->Instance->CR, MCE_CR_CIPHERSEL, AESConfig->KeySize);
/* Check cipher context is not locked */
if ((p_context->CCCFGR & MCE_CCCFGR_CCLOCK) != MCE_CCCFGR_CCLOCK)
{
if ((p_context->CCCFGR & MCE_CCCFGR_KEYLOCK) != MCE_CCCFGR_KEYLOCK)
{
/* Take Lock */
__HAL_LOCK(hmce);
/* Write nonce */
WRITE_REG(p_context->CCNR0, AESConfig->Nonce[0]);
WRITE_REG(p_context->CCNR1, AESConfig->Nonce[1]);
if (AESConfig->pKey != NULL)
{
p_key = AESConfig->pKey;
WRITE_REG(p_context->CCKEYR0, *p_key);
p_key++;
WRITE_REG(p_context->CCKEYR1, *p_key);
p_key++;
WRITE_REG(p_context->CCKEYR2, *p_key);
p_key++;
WRITE_REG(p_context->CCKEYR3, *p_key);
}
/* Compute theoretically expected CRC and compare it with that reported by the peripheral */
/* Write version */
MODIFY_REG(p_context->CCCFGR, MCE_CCCFGR_VERSION, ((uint32_t) AESConfig->Version) << MCE_CCCFGR_VERSION_Pos);
MODIFY_REG(p_context->CCCFGR, MCE_CCCFGR_MODE, (uint32_t) AESConfig->Cipher_Mode);
ret = HAL_OK;
/* Release Lock */
__HAL_UNLOCK(hmce);
}
}
}
return ret;
}
/**
* @brief Set region configuration.
* @param hmce pointer to an MCE_HandleTypeDef structure that contains
* the configuration information for MCE module
* @param RegionIndex index of region that is configured
* @param pConfig region configuration
* @note The region is enabled by default once the configuration is complete
* @note An enabled region is temporary disabled to apply the new configuration
* @retval HAL status
*/
HAL_StatusTypeDef HAL_MCE_ConfigRegion(MCE_HandleTypeDef *hmce, uint32_t RegionIndex,
const MCE_RegionConfigTypeDef *pConfig)
{
HAL_StatusTypeDef ret = HAL_ERROR;
MCE_Region_TypeDef *p_region;
__IO uint32_t address;
/* Check the parameters */
assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
assert_param(IS_MCE_REGIONINDEX(RegionIndex));
assert_param(IS_MCE_ALGORITHM(hmce->Instance, pConfig->Mode));
/** we have no AccessMode nor PrivilegedAccess fields in this product */
/* If global lock is set or no configuration provided, region cannot be configured */
if (((hmce->Instance->CR & MCE_CR_GLOCK) != MCE_CR_GLOCK) && (pConfig != NULL))
{
/* Take Lock */
__HAL_LOCK(hmce);
address = (__IO uint32_t)((uint32_t)hmce->Instance + 0x40U + (0x10U * RegionIndex));
p_region = (MCE_Region_TypeDef *)address;
/* If region is enabled, disable it during the configuration process */
if ((p_region->REGCR & MCE_REGCR_BREN) == MCE_REGCR_BREN)
{
CLEAR_BIT(p_region->REGCR, MCE_REGCR_BREN);
}
/* Set privileged access, ciphering algorithm and context ID */
MODIFY_REG(p_region->REGCR, MCE_REGCR_ENC, pConfig->Mode);
/* Set start and end addresses */
WRITE_REG(p_region->SADDR, pConfig->StartAddress);
WRITE_REG(p_region->EADDR, pConfig->EndAddress);
/* Set write attribute for the region */
/** we have no ATTR register in this product */
/* Enable the region by default */
SET_BIT(p_region->REGCR, MCE_REGCR_BREN);
ret = HAL_OK;
/* Release Lock */
__HAL_UNLOCK(hmce);
}
return ret;
}
/**
* @brief Set region AES Context.
* @param hmce pointer to an MCE_HandleTypeDef structure that contains
* the configuration information for MCE module
* @param ContextIndex index of context that is configured
* @param RegionIndex index of region that is configured
* @note The Region is enabled by default once the configuration is complete
* @note An enabled region is temporary disabled to apply the new configuration
* @retval HAL status
*/
HAL_StatusTypeDef HAL_MCE_SetRegionAESContext(MCE_HandleTypeDef *hmce, uint32_t ContextIndex, uint32_t RegionIndex)
{
HAL_StatusTypeDef ret = HAL_ERROR;
MCE_Region_TypeDef *p_region;
__IO uint32_t address;
assert_param(IS_MCE_CONTEXT(hmce->Instance, ContextIndex));
assert_param(IS_MCE_REGIONINDEX(RegionIndex));
/* If global lock is set, region cannot be configured */
if ((hmce->Instance->CR & MCE_CR_GLOCK) != MCE_CR_GLOCK)
{
/* Take Lock */
__HAL_LOCK(hmce);
address = (__IO uint32_t)((uint32_t)hmce->Instance + 0x40U + (0x10U * RegionIndex));
p_region = (MCE_Region_TypeDef *)address;
/* If region is enabled, disable it during the configuration process */
if ((p_region->REGCR & MCE_REGCR_BREN) == MCE_REGCR_BREN)
{
CLEAR_BIT(p_region->REGCR, MCE_REGCR_BREN);
}
/* Set context ID */
MODIFY_REG(p_region->REGCR, MCE_REGCR_CTXID, ContextIndex);
/* Enable the region by default */
SET_BIT(p_region->REGCR, MCE_REGCR_BREN);
ret = HAL_OK;
/* Release Lock */
__HAL_UNLOCK(hmce);
}
return ret;
}
/** ********* Enabling and disabling functions : enable/disable AES and Noekeon configurations and regions *********/
/**
* @brief Cipher context enable
* @param hmce pointer to an MCE_HandleTypeDef structure that contains
* the configuration information for MCE module
* @param ContextIndex index of context that is enabled
* @retval HAL status
*/
HAL_StatusTypeDef HAL_MCE_EnableAESContext(MCE_HandleTypeDef *hmce, uint32_t ContextIndex)
{
MCE_Context_TypeDef *p_context;
__IO uint32_t address;
/* Check the parameters */
assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
assert_param(IS_MCE_CONTEXT(hmce->Instance, ContextIndex));
if ((ContextIndex != MCE_CONTEXT1) && (ContextIndex != MCE_CONTEXT2))
{
return HAL_ERROR;
}
address = (__IO uint32_t)((uint32_t)hmce->Instance + 0x240UL + \
(0x30UL * ((ContextIndex - MCE_CONTEXT1) >> MCE_REGCR_CTXID_Pos)));
p_context = (MCE_Context_TypeDef *)address;
/* If cipher context is locked or if global lock is set,
and if cipher context is not enabled already, return an error */
if ((p_context->CCCFGR & MCE_CCCFGR_CCEN) != MCE_CCCFGR_CCEN)
{
if ((p_context->CCCFGR & MCE_CCCFGR_CCLOCK) == MCE_CCCFGR_CCLOCK)
{
return HAL_ERROR;
}
if ((hmce->Instance->CR & MCE_CR_GLOCK) == MCE_CR_GLOCK)
{
return HAL_ERROR;
}
}
__HAL_LOCK(hmce);
/* Enable context */
SET_BIT(p_context->CCCFGR, MCE_CCCFGR_CCEN);
__HAL_UNLOCK(hmce);
return HAL_OK;
}
/**
* @brief Cipher context disable
* @param hmce pointer to an MCE_HandleTypeDef structure that contains
* the configuration information for MCE module
* @param ContextIndex index of context that is disabled
* @retval HAL status
*/
HAL_StatusTypeDef HAL_MCE_DisableAESContext(MCE_HandleTypeDef *hmce, uint32_t ContextIndex)
{
MCE_Context_TypeDef *p_context;
__IO uint32_t address;
/* Check the parameters */
assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
assert_param(IS_MCE_CONTEXT(hmce->Instance, ContextIndex));
if ((ContextIndex != MCE_CONTEXT1) && (ContextIndex != MCE_CONTEXT2))
{
return HAL_ERROR;
}
address = (__IO uint32_t)((uint32_t)hmce->Instance + 0x240UL + \
(0x30UL * ((ContextIndex - MCE_CONTEXT1) >> MCE_REGCR_CTXID_Pos)));
p_context = (MCE_Context_TypeDef *)address;
/* If cipher context is locked or if global lock is set,
and if cipher context is not disabled already, return an error */
if ((p_context->CCCFGR & MCE_CCCFGR_CCEN) == MCE_CCCFGR_CCEN)
{
if ((p_context->CCCFGR & MCE_CCCFGR_CCLOCK) == MCE_CCCFGR_CCLOCK)
{
return HAL_ERROR;
}
if ((hmce->Instance->CR & MCE_CR_GLOCK) == MCE_CR_GLOCK)
{
return HAL_ERROR;
}
}
__HAL_LOCK(hmce);
/* Disable context */
CLEAR_BIT(p_context->CCCFGR, MCE_CCCFGR_CCEN);
__HAL_UNLOCK(hmce);
return HAL_OK;
}
/**
* @brief Enable region.
* @param hmce pointer to an MCE_HandleTypeDef structure that contains
* the configuration information for MCE module
* @param RegionIndex index of region that is enabled
* @retval HAL status
*/
HAL_StatusTypeDef HAL_MCE_EnableRegion(MCE_HandleTypeDef *hmce, uint32_t RegionIndex)
{
HAL_StatusTypeDef ret = HAL_ERROR;
MCE_Region_TypeDef *p_region;
__IO uint32_t address;
/* Check the parameters */
assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
assert_param(IS_MCE_REGIONINDEX(RegionIndex));
/* If global lock is set, region cannot be configured */
if ((hmce->Instance->CR & MCE_CR_GLOCK) != MCE_CR_GLOCK)
{
address = (__IO uint32_t)((uint32_t)hmce->Instance + 0x40U + (0x10U * RegionIndex));
p_region = (MCE_Region_TypeDef *)address;
/* Take Lock */
__HAL_LOCK(hmce);
/* Check region is not enabled, else error */
if ((p_region->REGCR & MCE_REGCR_BREN) != MCE_REGCR_BREN)
{
/* Enable the region */
SET_BIT(p_region->REGCR, MCE_REGCR_BREN);
ret = HAL_OK;
}
/* Release Lock */
__HAL_UNLOCK(hmce);
}
return ret;
}
/**
* @brief Disable region.
* @param hmce pointer to an MCE_HandleTypeDef structure that contains
* the configuration information for MCE module
* @param RegionIndex index of region that is disabled
* @retval HAL status
*/
HAL_StatusTypeDef HAL_MCE_DisableRegion(MCE_HandleTypeDef *hmce, uint32_t RegionIndex)
{
HAL_StatusTypeDef ret = HAL_ERROR;
MCE_Region_TypeDef *p_region;
__IO uint32_t address;
/* Check the parameters */
assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
assert_param(IS_MCE_REGIONINDEX(RegionIndex));
address = (__IO uint32_t)((uint32_t)hmce->Instance + 0x40U + (0x10U * RegionIndex));
p_region = (MCE_Region_TypeDef *)address;
/* If global lock is set, region cannot be configured */
if ((hmce->Instance->CR & MCE_CR_GLOCK) != MCE_CR_GLOCK)
{
/* Take Lock */
__HAL_LOCK(hmce);
/* Check region is enabled, else error */
if ((p_region->REGCR & MCE_REGCR_BREN) == MCE_REGCR_BREN)
{
/* Disable the region */
CLEAR_BIT(p_region->REGCR, MCE_REGCR_BREN);
ret = HAL_OK;
}
/* Release Lock */
__HAL_UNLOCK(hmce);
}
return ret;
}
/** ************* Lock functions : Lock AES and Noekeon configurations and keys *********/
/**
* @brief Lock MCE instance registers configuration
* @param hmce pointer to an MCE_HandleTypeDef structure that contains
* the configuration information for MCE module
* @note Once MCE_CR_GLOCK is set, all writes to MCE registers are ignored,
* with the exception of MCE_IACR and MCE_IAIER registers.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_MCE_LockGlobalConfig(MCE_HandleTypeDef *hmce)
{
/* Check the parameters */
assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
/* Take Lock */
__HAL_LOCK(hmce);
SET_BIT(hmce->Instance->CR, MCE_CR_GLOCK);
/* Release Lock */
__HAL_UNLOCK(hmce);
return HAL_OK;
}
/**
* @brief Lock cipher context
* @param hmce pointer to an MCE_HandleTypeDef structure that contains
* the configuration information for MCE module
* @param ContextIndex index of context that is locked
* @note Once MCE_CCCFGR_CCLOCK is set, writes to MCE_CCxCFGR and MCE_CCxNR registers
* are ignored until next MCE reset.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_MCE_LockAESContextConfig(MCE_HandleTypeDef *hmce, uint32_t ContextIndex)
{
HAL_StatusTypeDef ret = HAL_ERROR;
MCE_Context_TypeDef *p_context;
__IO uint32_t address;
/* Check the parameters */
assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
assert_param(IS_MCE_CONTEXT(hmce->Instance, ContextIndex));
/* If global lock is set or no configuration provided, context cannot be configured */
if (((hmce->Instance->CR & MCE_CR_GLOCK) != MCE_CR_GLOCK) && \
((ContextIndex == MCE_CONTEXT1) || (ContextIndex == MCE_CONTEXT2)))
{
address = (__IO uint32_t)((uint32_t)hmce->Instance + 0x240UL + \
(0x30UL * ((ContextIndex - MCE_CONTEXT1) >> MCE_REGCR_CTXID_Pos)));
p_context = (MCE_Context_TypeDef *)address;
/* Take Lock */
__HAL_LOCK(hmce);
SET_BIT(p_context->CCCFGR, MCE_CCCFGR_CCLOCK);
ret = HAL_OK;
/* Release Lock */
__HAL_UNLOCK(hmce);
}
return ret;
}
/**
* @brief Lock context cipher key
* @param hmce pointer to an MCE_HandleTypeDef structure that contains
* the configuration information for MCE module
* @param ContextIndex index of context the cipher key of which is locked
* @note Once MCE_CCCFGR_KEYLOCK is set, writes to MCE_CCxKEYR registers are ignored
* until next MCE reset. KEYCRC bitfield value does not change.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_MCE_LockAESContextKey(MCE_HandleTypeDef *hmce, uint32_t ContextIndex)
{
HAL_StatusTypeDef ret = HAL_ERROR;
MCE_Context_TypeDef *p_context;
__IO uint32_t address;
/* Check the parameters */
assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
assert_param(IS_MCE_CONTEXT(hmce->Instance, ContextIndex));
/* If global lock is set or no configuration provided, context cannot be configured */
if (((hmce->Instance->CR & MCE_CR_GLOCK) != MCE_CR_GLOCK) && \
((ContextIndex == MCE_CONTEXT1) || (ContextIndex == MCE_CONTEXT2)))
{
address = (__IO uint32_t)((uint32_t)hmce->Instance + 0x240UL + \
(0x30UL * ((ContextIndex - MCE_CONTEXT1) >> MCE_REGCR_CTXID_Pos)));
p_context = (MCE_Context_TypeDef *)address;
/* Take Lock */
__HAL_LOCK(hmce);
SET_BIT(p_context->CCCFGR, MCE_CCCFGR_KEYLOCK);
ret = HAL_OK;
/* Release Lock */
__HAL_UNLOCK(hmce);
}
return ret;
}
/**
* @brief Lock Noekeon master keys
* @param hmce pointer to an MCE_HandleTypeDef structure that contains
* the configuration information for MCE module
* @note Once MCE_CR_MKLOCK is set, writes to MCE_MKEYRx and MCE_FMKEYRx registers are ignored until next MCE reset.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_MCE_LockNoekeonMasterKeys(MCE_HandleTypeDef *hmce)
{
HAL_StatusTypeDef ret = HAL_ERROR;
/* Check the parameters */
assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
/* If global lock is set, master keys lock cannot be set */
if ((hmce->Instance->CR & MCE_CR_GLOCK) != MCE_CR_GLOCK)
{
/* Take Lock */
__HAL_LOCK(hmce);
SET_BIT(hmce->Instance->CR, MCE_CR_MKLOCK);
ret = HAL_OK;
/* Release Lock */
__HAL_UNLOCK(hmce);
}
return ret;
}
/**
* @brief Initialize the MCE MSP.
* @param hmce pointer to an MCE_HandleTypeDef structure that contains
* the configuration information for MCE module
* @retval None
*/
__weak void HAL_MCE_MspInit(MCE_HandleTypeDef *hmce)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hmce);
/* NOTE : This function should not be modified; when the callback is needed,
the HAL_MCE_MspInit can be implemented in the user file.
*/
}
/**
* @brief DeInitialize MCE MSP.
* @param hmce pointer to an MCE_HandleTypeDef structure that contains
* the configuration information for MCE module
* @retval None
*/
__weak void HAL_MCE_MspDeInit(MCE_HandleTypeDef *hmce)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hmce);
/* NOTE : This function should not be modified; when the callback is needed,
the HAL_MCE_MspDeInit can be implemented in the user file.
*/
}
/**
* @brief get the CRC key of the specified context.
* @param hmce pointer to an MCE_HandleTypeDef structure that contains
* the configuration information for MCE module
* @param pCRCKey pointer to the CRC key
* @param ContextIndex index of CONTEXT the CRC key
* @retval HAL status
*/
HAL_StatusTypeDef HAL_MCE_GetAESContextCRCKey(const MCE_HandleTypeDef *hmce, uint32_t *pCRCKey, uint32_t ContextIndex)
{
HAL_StatusTypeDef ret = HAL_OK;
const MCE_Context_TypeDef *p_context;
__IO uint32_t address;
/* Check the parameters */
assert_param(IS_MCE_AES_INSTANCE(hmce->Instance));
assert_param(IS_MCE_CONTEXT(hmce->Instance, ContextIndex));
if (*pCRCKey == 0x00U)
{
ret = HAL_ERROR;
}
address = (__IO uint32_t)((uint32_t)hmce->Instance + 0x240UL + \
(0x30UL * ((ContextIndex - MCE_CONTEXT1) >> MCE_REGCR_CTXID_Pos)));
p_context = (MCE_Context_TypeDef *)address;
*pCRCKey = READ_REG((p_context->CCCFGR)) & MCE_CCCFGR_KEYCRC;
*pCRCKey >>= MCE_CCCFGR_KEYCRC_Pos;
return ret;
}
/**
* @brief Compute Key CRC
* @param pKey pointer at set of keys
* @retval CRC value
*/
uint32_t HAL_MCE_KeyCRCComputation(const uint32_t *pKey)
{
uint8_t crc7_poly = 0x7;
const uint32_t key_strobe[4] = {0xAA55AA55U, 0x3U, 0x18U, 0xC0U};
uint8_t i;
uint8_t crc = 0;
uint32_t j;
uint32_t keyval;
uint32_t k;
const uint32_t *temp = pKey;
for (j = 0U; j < 4U; j++)
{
keyval = *temp;
temp++;
if (j == 0U)
{
keyval ^= key_strobe[0];
}
else
{
keyval ^= (key_strobe[j] << 24) | ((uint32_t)crc << 16) | (key_strobe[j] << 8) | crc;
}
crc = 0;
for (i = 0; i < (uint8_t)32; i++)
{
k = ((((uint32_t)crc >> 7) ^ ((keyval >> ((uint8_t)31 - i)) & ((uint8_t)0xF)))) & 1U;
crc <<= 1;
if (k != 0U)
{
crc ^= crc7_poly;
}
}
crc ^= (uint8_t)0x55;
}
return (uint32_t) crc;
}
/**
* @brief Handle MCE interrupt request.
* @param hmce pointer to an MCE_HandleTypeDef structure that contains
* the configuration information for MCE module
* @retval None
*/
void HAL_MCE_IRQHandler(MCE_HandleTypeDef *hmce)
{
uint32_t isr_reg;
isr_reg = READ_REG(hmce->Instance->IASR);
if ((isr_reg & MCE_IASR_IAEF) == MCE_IASR_IAEF)
{
/* Set configuration access error */
hmce->ErrorCode |= HAL_MCE_CONFIGURATION_ACCESS_ERROR;
/* Clear configuration access error flag */
WRITE_REG(hmce->Instance->IACR, MCE_IACR_IAEF);
}
#if (USE_HAL_MCE_REGISTER_CALLBACKS == 1)
hmce->ErrorCallback(hmce);
#else
HAL_MCE_ErrorCallback(hmce);
#endif /* USE_HAL_MCE_REGISTER_CALLBACKS */
}
/**
* @brief MCE error callback.
* @param hmce pointer to an MCE_HandleTypeDef structure that contains
* the configuration information for MCE module
* @retval None
*/
__weak void HAL_MCE_ErrorCallback(MCE_HandleTypeDef *hmce)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(hmce);
/* NOTE : This function should not be modified; when the callback is needed,
the HAL_MCE_ErrorCallback can be implemented in the user file.
*/
}
/**
* @brief Return the MCE state.
* @param hmce pointer to an MCE_HandleTypeDef structure that contains
* the configuration information for MCE module
* @retval HAL status
*/
HAL_MCE_StateTypeDef HAL_MCE_GetState(MCE_HandleTypeDef const *hmce)
{
/* Check the parameters */
assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
return hmce->State;
}
/**
* @brief Return the MCE error code.
* @param hmce pointer to an MCE_HandleTypeDef structure that contains
* the configuration information for MCE module
* @retval MCE error code (bitfield on 32 bits)
*/
uint32_t HAL_MCE_GetError(MCE_HandleTypeDef const *hmce)
{
/* Check the parameters */
assert_param(IS_MCE_ALL_INSTANCE(hmce->Instance));
return hmce->ErrorCode;
}
/**
* @}
*/
/**
* @}
*/
#endif /* MCE1 */
#endif /* HAL_MCE_MODULE_ENABLED */
/**
* @}
*/
/**
* @}
*/