1033 lines
47 KiB
C
1033 lines
47 KiB
C
|
|
/***********************************************************************************************************************
|
||
|
|
* FILE DESCRIPTION
|
||
|
|
* ------------------------------------------------------------------------------------------------------------------*/
|
||
|
|
/** \file
|
||
|
|
* \brief Application dependent routines
|
||
|
|
*
|
||
|
|
* \note Please note, that this file contains a collection of callback functions to be used with the
|
||
|
|
* Flash Bootloader. These functions may influence the behavior of the bootloader in principle.
|
||
|
|
* Therefore, great care must be taken to verify the correctness of the implementation.
|
||
|
|
* The contents of the originally delivered files are only examples resp. implementation proposals.
|
||
|
|
* With regard to the fact that these functions are meant for demonstration purposes only, Vector
|
||
|
|
* Informatik's liability shall be expressly excluded in cases of ordinary negligence, to the extent
|
||
|
|
* admissible by law or statute.
|
||
|
|
*
|
||
|
|
* --------------------------------------------------------------------------------------------------------------------
|
||
|
|
* COPYRIGHT
|
||
|
|
* --------------------------------------------------------------------------------------------------------------------
|
||
|
|
* \par Copyright
|
||
|
|
* \verbatim
|
||
|
|
* Copyright (c) 2025 by Vector Informatik GmbH. All rights reserved.
|
||
|
|
*
|
||
|
|
* This software is copyright protected and proprietary to Vector Informatik GmbH.
|
||
|
|
* Vector Informatik GmbH grants to you only those rights as set out in the license conditions.
|
||
|
|
* All other rights remain with Vector Informatik GmbH.
|
||
|
|
* \endverbatim
|
||
|
|
*/
|
||
|
|
/**********************************************************************************************************************/
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* REVISION HISTORY
|
||
|
|
* --------------------------------------------------------------------------------------------------------------------
|
||
|
|
* Version Date Author Change Id Description
|
||
|
|
* --------------------------------------------------------------------------------------------------------------------
|
||
|
|
* 01.00.00 2019-01-28 visrie - Initial version
|
||
|
|
* 01.01.00 2019-02-18 vismvi ESCAN00102171 Variable declared but never referenced
|
||
|
|
* visrie ESCAN00102310 Added callout to check reprogramming flag
|
||
|
|
* 01.01.01 2019-03-07 visrie ESCAN00102386 Fixed compiler error in ApplFbl_DetEntryHandler
|
||
|
|
* ESCAN00102399 Check NvPattern only for non-RAM blocks
|
||
|
|
* 02.00.00 2019-05-02 visrie ESCAN00102518 Added support to read block/application validity from NV-Memory
|
||
|
|
* ESCAN00102761 Added support for 3rd Party Tricore HSM
|
||
|
|
* ESCAN00103026 Provide BmHeader instead of StartAddress to ApplFblBmStartSoftware
|
||
|
|
* 03.00.00 2019-07-17 visrie ESCAN00103750 Removed target order list configuration
|
||
|
|
* 03.01.00 2019-08-14 visrie FBL-487 Exclude callouts if overwritten by OEM/HW layer
|
||
|
|
* 03.01.01 2019-09-04 visrcn ESCAN00103607 Memory qualifier mismatch
|
||
|
|
* 04.00.00 2019-12-04 visrie FBL-456 Updated to new LibSecBoot interface
|
||
|
|
* ESCAN00105135 Added support for new BRS API
|
||
|
|
* 04.01.00 2020-01-16 visrie FBL-524 Added support for vHsm SecBoot library
|
||
|
|
* 05.00.00 2020-04-09 visrie FBL-1016 Support new vBaseEnv, added support for VTT
|
||
|
|
* 05.01.00 2020-04-29 vistmo FBL-1584 Added OTA startup support
|
||
|
|
* 05.02.00 2020-08-13 vistmo FBL-1489 Added support for OTA swap activation
|
||
|
|
* 05.02.01 2021-03-17 vishor ESCAN00108386 ApplFblBmIsValidBlock implementation does not consider
|
||
|
|
* all possible use cases
|
||
|
|
* FBL-3018 No changes
|
||
|
|
* 05.03.00 2021-08-11 visrie FBL-3394 Move default implementation of CheckReprogFlag into FblBm_Ap
|
||
|
|
* 05.04.00 2021-09-17 visjdn FBL-3865 Add default SecBoot implementation for GHS/Escrypt
|
||
|
|
* 05.04.01 2022-04-06 vismix FBL-4773 Support THUMB mode
|
||
|
|
* 05.05.00 2022-04-07 vishor FBL-4822 Add support for new MagicFlag value and Swap API
|
||
|
|
* 05.05.01 2022-06-23 vismix ESCAN00111879 Boot manager does not wait for HSM update recovery
|
||
|
|
* 05.06.00 2022-07-13 vismix FBL-5391 Add callout for missing optional dependency
|
||
|
|
* 05.06.01 2022-11-29 vishor ESCAN00112986 Compiler error: Undefined symbols
|
||
|
|
* ApplFblPreMemDriver/ApplFblPostMemDriver
|
||
|
|
* 05.07.00 2023-06-29 vistbe FBL-7052 Add evaluation of ActivationPending
|
||
|
|
* 05.07.01 2023-12-18 visrie ESCAN00104829 Compiler error: Det.h missing in GENy based standalone BM
|
||
|
|
* ESCAN00111036 Compiler error: 'kFblApplicationValid' may be undeclared
|
||
|
|
* ESCAN00115752 No changes
|
||
|
|
* 05.08.00 2024-05-16 vishor FBL-8602 Add support for OEM updater solution
|
||
|
|
* 05.09.00 2025-05-23 dganesh FBL-9715 Extend presence pattern to connect validity information
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
|
||
|
|
#define BM_AP_SOURCE
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* INCLUDES
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
#include "bm_ap.h"
|
||
|
|
#include "bm_main.h"
|
||
|
|
#include "fbl_inc.h"
|
||
|
|
|
||
|
|
#include "fbl_main_types.h"
|
||
|
|
|
||
|
|
#if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN )
|
||
|
|
# include "Csm.h"
|
||
|
|
#endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */
|
||
|
|
# if defined( FBLBM_ENABLE_STANDALONE_MODE )
|
||
|
|
# include "Det.h"
|
||
|
|
# endif
|
||
|
|
#if defined( FBLBM_ENABLE_SECURE_BOOT )
|
||
|
|
# include "fbl_secboot.h"
|
||
|
|
# include "Csm.h"
|
||
|
|
# include "Crypto_30_vHsm.h"
|
||
|
|
#endif /* FBLBM_AP_ENABLE_3RD_PARTY_TRICORE_HSM_USED */
|
||
|
|
|
||
|
|
# include "BrsHw.h"
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* VERSION
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
|
||
|
|
#if ( FBLBM_AP_VERSION != 0x0509u ) || \
|
||
|
|
( FBLBM_AP_RELEASE_VERSION != 0x00u )
|
||
|
|
# error "Error in bm_ap.c: Source and Header file are inconsistent!"
|
||
|
|
#endif
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* DEFINES
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
|
||
|
|
#if defined( _MICROSOFT_C_VTT_ )
|
||
|
|
# define FBLBM_AP_ENABLE_VTT_USECASE
|
||
|
|
#endif /* _MICROSOFT_C_VTT_ */
|
||
|
|
|
||
|
|
/* If no explicit LB for the LBT exists use the bootloader LB */
|
||
|
|
#if !defined( FBL_MTAB_LBT_BLOCK_NUMBER )
|
||
|
|
# define FBL_MTAB_LBT_BLOCK_NUMBER FBL_MTAB_BOOTLOADER_BLOCK_NUMBER
|
||
|
|
#endif /* FBL_MTAB_LBT_BLOCK_NUMBER */
|
||
|
|
|
||
|
|
/* Helper macro to get number of array entries */
|
||
|
|
#if defined( FBLBMAP_ARRAY_SIZE )
|
||
|
|
#else
|
||
|
|
# define FBLBMAP_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) /* PRQA S 3453 */ /* MD_MSR_FctLikeMacro */
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if defined( FBLBM_AP_CALLOUT_CHECK_TARGET_VALIDITY ) && \
|
||
|
|
!defined( FBL_ENABLE_PRESENCE_PATTERN )
|
||
|
|
/** Compatibility define in case OEM layer uses different macro scheme */
|
||
|
|
# if !defined( kFblApplicationValid )
|
||
|
|
# if defined( kEepApplConsistent )
|
||
|
|
# define kFblApplicationValid kEepApplConsistent
|
||
|
|
# else
|
||
|
|
# error "kFblApplicationValid not defined or can't be mapped to an equivalent define/value."
|
||
|
|
/* TODO_CUSTOMER: Adjust the following define to map kFblApplicationValid to the correct value/define used by the OEM */
|
||
|
|
/* #define kFblApplicationValid <value/define> */
|
||
|
|
# endif
|
||
|
|
# endif /* !kFblApplicationValid */
|
||
|
|
#endif /* FBLBM_AP_CALLOUT_CHECK_TARGET_VALIDITY && !FBL_ENABLE_PRESENCE_PATTERN */
|
||
|
|
|
||
|
|
#if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN )
|
||
|
|
/** Key size of signed presence pattern */
|
||
|
|
# define FBLBM_SIGNED_PP_KEY_SIZE 0x10u
|
||
|
|
#endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* LOCAL DATA
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
|
||
|
|
#define FBLBMAP_START_SEC_VAR
|
||
|
|
#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */
|
||
|
|
|
||
|
|
#if defined( FBLBM_ENABLE_UPDATER_FAILSAFE )
|
||
|
|
V_MEMRAM0 static V_MEMRAM1 vuintx V_MEMRAM2 g_ApplFblBmSearchUpdaterHeaderIndex;
|
||
|
|
#endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */
|
||
|
|
|
||
|
|
#define FBLBMAP_STOP_SEC_VAR
|
||
|
|
#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* LOCAL FUNCTION PROTOTYPES
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
|
||
|
|
#if defined( FBLBM_ENABLE_SECURE_BOOT )
|
||
|
|
# define FBLBMAP_RAMCODE_START_SEC_CODE
|
||
|
|
# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */
|
||
|
|
static void ApplFblBmWaitForHsm(void);
|
||
|
|
# define FBLBMAP_RAMCODE_STOP_SEC_CODE
|
||
|
|
# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */
|
||
|
|
#endif /* FBLBM_ENABLE_SECURE_BOOT */
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* LOCAL FUNCTIONS
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
|
||
|
|
#if defined( FBLBM_ENABLE_SECURE_BOOT )
|
||
|
|
# define FBLBMAP_RAMCODE_START_SEC_CODE
|
||
|
|
# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblBmWaitForHsm
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Wait until vHSM is ready
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
static void ApplFblBmWaitForHsm(void)
|
||
|
|
{
|
||
|
|
Std_ReturnType retVal;
|
||
|
|
uint32 keyLength;
|
||
|
|
uint32 hsm2host;
|
||
|
|
uint32 host2hsm;
|
||
|
|
|
||
|
|
/* Wait until vHsm has been started */
|
||
|
|
do
|
||
|
|
{
|
||
|
|
keyLength = 4u;
|
||
|
|
retVal = Csm_KeyElementGet(0u, CRYPTO_KE_CUSTOM_VHSM_STATUS_HSM2HOST, (uint8 *)&hsm2host, &keyLength);
|
||
|
|
assertFblUser(retVal == E_OK, kFblSysAssertDet);
|
||
|
|
} while (hsm2host == 0u);
|
||
|
|
|
||
|
|
/* When a vHsmUpd is pending */
|
||
|
|
if ((hsm2host & (1uL << CRYPTO_30_VHSM_HSM2HOST_UPDATERRUNNING)) == (1uL << CRYPTO_30_VHSM_HSM2HOST_UPDATERRUNNING))
|
||
|
|
{
|
||
|
|
keyLength = 4u;
|
||
|
|
# error "Comment this line if vHsmUpdater is not used. If vHsmUpdater is used, please assign the value <vHsmUpd_Ext/vHsmUpd_ExtGeneral/vHsmUpd_ExtIpc/vHsmUpd_ExtIpcWaitMask> configured in the vHsm-updater to host2hsm below"
|
||
|
|
host2hsm = 0x80000000u;
|
||
|
|
/* Set configured Bit pattern to signalize the vHsmUpd that update can be started */
|
||
|
|
retVal = Csm_KeyElementSet(0u, CRYPTO_KE_CUSTOM_VHSM_STATUS_HOST2HSM, (uint8 *)&host2hsm, keyLength);
|
||
|
|
assertFblUser(retVal == E_OK, kFblSysAssertDet);
|
||
|
|
|
||
|
|
/* Wait until vHsmUpd has been finished */
|
||
|
|
do
|
||
|
|
{
|
||
|
|
FblLookForWatchdogVoid();
|
||
|
|
|
||
|
|
keyLength = 4u;
|
||
|
|
retVal = Csm_KeyElementGet(0u, CRYPTO_KE_CUSTOM_VHSM_STATUS_HSM2HOST, (uint8 *)&hsm2host, &keyLength);
|
||
|
|
assertFblUser(retVal == E_OK, kFblSysAssertDet);
|
||
|
|
} while ((hsm2host & ((1u << CRYPTO_30_VHSM_HSM2HOST_READY) | (1u << CRYPTO_30_VHSM_HSM2HOST_ACTIVE))) != ((1u << CRYPTO_30_VHSM_HSM2HOST_READY) | (1u << CRYPTO_30_VHSM_HSM2HOST_ACTIVE)));
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Wait until vHsm is ready */
|
||
|
|
Crypto_30_vHsm_WaitForHsmRam();
|
||
|
|
}
|
||
|
|
# define FBLBMAP_RAMCODE_STOP_SEC_CODE
|
||
|
|
# include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */
|
||
|
|
#endif /* FBLBM_ENABLE_SECURE_BOOT */
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* GLOBAL FUNCTIONS
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
|
||
|
|
#define FBLBMAP_START_SEC_CODE
|
||
|
|
#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblBmPowerOnPre
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Initialization callout
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
void ApplFblBmPowerOnPre( void )
|
||
|
|
{
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblBmPowerOnPost
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Initialization callout
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
void ApplFblBmPowerOnPost( void )
|
||
|
|
{
|
||
|
|
#if defined( FBL_ENABLE_OTA )
|
||
|
|
vOtaM_InitMemory();
|
||
|
|
#endif /* FBL_ENABLE_OTA */
|
||
|
|
}
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblBmInitPre
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Initialization callout
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
void ApplFblBmInitPre( void )
|
||
|
|
{
|
||
|
|
# if defined( BRS_FBL_LEGACY )
|
||
|
|
# if defined( BRSHW_PREINIT_AVAILABLE )
|
||
|
|
/* HW specific pre-initialization. */
|
||
|
|
BrsHwPreInitPowerOn();
|
||
|
|
# endif /* BRSHW_PREINIT_AVAILABLE */
|
||
|
|
|
||
|
|
# if defined( BRS_ENABLE_WATCHDOG )
|
||
|
|
/* Disable Watchdog */
|
||
|
|
BrsHwWatchdogInitPowerOn();
|
||
|
|
# endif /* BRS_ENABLE_WATCHDOG */
|
||
|
|
|
||
|
|
# if defined( BRS_ENABLE_PLLCLOCKS )
|
||
|
|
/* Initialize the PLLs. */
|
||
|
|
BrsHwPllInitPowerOn();
|
||
|
|
# endif /* BRS_ENABLE_PLLCLOCKS */
|
||
|
|
|
||
|
|
# if defined( BRSHW_DISABLE_ECC_AVAILABLE )
|
||
|
|
/* Disable Flash ECC error reporting. */
|
||
|
|
BrsHwDisableEccErrorReporting();
|
||
|
|
# endif /* BRSHW_DISABLE_ECC_AVAILABLE */
|
||
|
|
|
||
|
|
# if defined( FBL_ENABLE_PRE_TIMERINIT )
|
||
|
|
/* Timer is stopped by mode switch and has to be re-initialized. */
|
||
|
|
FblTimerInit();
|
||
|
|
# endif /* FBL_ENABLE_PRE_TIMERINIT */
|
||
|
|
# endif /* BRS_FBL_LEGACY */
|
||
|
|
}
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblBmInitPost
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Initialization callout
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
void ApplFblBmInitPost( void )
|
||
|
|
{
|
||
|
|
#if defined( FBLBM_ENABLE_SECURE_BOOT )
|
||
|
|
volatile vuint8 executeTestcode = kFblOk;
|
||
|
|
|
||
|
|
/* Wait until vHSM is ready */
|
||
|
|
ApplFblBmWaitForHsm();
|
||
|
|
|
||
|
|
if (executeTestcode == kFblOk) /* Testcode to initialize RAM key, to simulate written key */
|
||
|
|
{
|
||
|
|
Std_ReturnType retVal;
|
||
|
|
uint8 version[3u] = {0u};
|
||
|
|
uint32 versionLength = sizeof( version );
|
||
|
|
Crypto_VerifyResultType result = CRYPTO_E_VER_NOT_OK;
|
||
|
|
const uint8 key[16u] = {0u};
|
||
|
|
uint8 mac[16u] = {0u};
|
||
|
|
const uint8 data[16u] = {0u};
|
||
|
|
uint32 length = sizeof( mac );
|
||
|
|
|
||
|
|
/* Get the Version of the vHsm Firmware */
|
||
|
|
retVal = Crypto_30_vHsm_KeyElementGet( CryptoConf_CryptoKey_vHsm_Info, CRYPTO_KE_CUSTOM_VHSM_VERSION, version, &versionLength );
|
||
|
|
|
||
|
|
/* Fill the key used for the CMAC and set it to valid */
|
||
|
|
retVal |= Csm_KeyElementSet( CsmConf_CsmKey_CsmKey_SymmetricKey, CRYPTO_KE_MAC_KEY, key, sizeof( key ) );
|
||
|
|
retVal |= Csm_KeySetValid( CsmConf_CsmKey_CsmKey_SymmetricKey );
|
||
|
|
|
||
|
|
/* Generate the CMAC with the software implementation on the vHsm */
|
||
|
|
retVal |= Csm_MacGenerate( CsmConf_CsmJob_CsmJob_MacGen_Key1, CRYPTO_OPERATIONMODE_SINGLECALL, data, sizeof( data ), mac, &length );
|
||
|
|
retVal |= Csm_MacVerify( CsmConf_CsmJob_CsmJob_MacVer_Key1, CRYPTO_OPERATIONMODE_SINGLECALL, data, sizeof( data ), mac, sizeof( mac ) * 8u, &result );
|
||
|
|
|
||
|
|
if (retVal != E_OK)
|
||
|
|
{
|
||
|
|
while (1u)
|
||
|
|
{
|
||
|
|
;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
#endif /* FBLBM_ENABLE_SECURE_BOOT */
|
||
|
|
#if defined( FBL_ENABLE_OTA )
|
||
|
|
if (vOtaM_Init() != E_OK)
|
||
|
|
{
|
||
|
|
/* PRQA S 2741, 4558 1 */ /* MD_FblBmAp_2741_4558 */
|
||
|
|
assertFblUser(0u, kFblSysAssertInitializationFailed);
|
||
|
|
}
|
||
|
|
#endif /* FBL_ENABLE_OTA */
|
||
|
|
}
|
||
|
|
|
||
|
|
#if defined( FBLBM_AP_CALLOUT_RESET )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblBmReset
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Issue Reset
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
void ApplFblBmReset(void)
|
||
|
|
{
|
||
|
|
/* Reset ECU */
|
||
|
|
BrsHwSoftwareResetECU();
|
||
|
|
}
|
||
|
|
#endif /* FBLBM_AP_CALLOUT_RESET */
|
||
|
|
|
||
|
|
#if defined( FBLBM_AP_CALLOUT_CHECK_TARGET_VALIDITY )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblBmCheckTargetValidity
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Checks the validity of the target (Usually: Is the Application Validity Presence Pattern set)
|
||
|
|
* \param[in] targetHandle Target handle (e.g. Bootloader, Application, Updater)
|
||
|
|
* \return Result of operation
|
||
|
|
* kFblOk when operation succeeded
|
||
|
|
* kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/* PRQA S 6080 1 */ /* MD_MSR_STMIF */
|
||
|
|
tFblResult ApplFblBmCheckTargetValidity(tFblBmHdrTargetHandle targetHandle)
|
||
|
|
{
|
||
|
|
tFblResult result;
|
||
|
|
# if defined( FBL_ENABLE_PRESENCE_PATTERN )
|
||
|
|
vuint8 blockNo;
|
||
|
|
tBlockDescriptor blockDescriptor;
|
||
|
|
vuint8 device;
|
||
|
|
# else
|
||
|
|
vuint8 applValidity;
|
||
|
|
# endif
|
||
|
|
|
||
|
|
/* Check overall application validity for Application target */
|
||
|
|
if (targetHandle == FBLBMHDR_TARGET_APPL)
|
||
|
|
{
|
||
|
|
result = kFblFailed;
|
||
|
|
|
||
|
|
# if defined( FBL_ENABLE_PRESENCE_PATTERN )
|
||
|
|
/* Check if any PP for appl validity is set */
|
||
|
|
blockNo = 0u;
|
||
|
|
|
||
|
|
while ((blockNo < FblLbtGetBlockCount()) && (result != kFblOk))
|
||
|
|
{
|
||
|
|
if (kFblOk == FblLbtGetBlockDescriptorByNr(blockNo, &blockDescriptor))
|
||
|
|
{
|
||
|
|
if (kFblOk == FblMemGetDeviceByRange(blockDescriptor.blockStartAddress, blockDescriptor.blockLength, &device))
|
||
|
|
{
|
||
|
|
# if defined( kMioDeviceRam )
|
||
|
|
/* Do not check the presence pattern for RAM */
|
||
|
|
if (device != kMioDeviceRam)
|
||
|
|
# endif
|
||
|
|
{
|
||
|
|
result = FblNvPatternGet(&blockDescriptor, kFblNvPatternId_ApplValidity);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Prepare index for next loop */
|
||
|
|
blockNo++;
|
||
|
|
}
|
||
|
|
# else
|
||
|
|
/* Read validity from NV-memory */
|
||
|
|
if (ApplFblNvReadApplValidity(&applValidity) == kFblOk)
|
||
|
|
{
|
||
|
|
if (applValidity == kFblApplicationValid)
|
||
|
|
{
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
# endif
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
/* For all other targets, no overall validity is necessary */
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
#endif /* FBLBM_AP_CALLOUT_CHECK_TARGET_VALIDITY */
|
||
|
|
|
||
|
|
|
||
|
|
#if defined( FBLBM_AP_CALLOUT_IS_VALIDBLOCK )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblBmIsValidBlock
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Checks the preconditions of a specific target
|
||
|
|
* \param[in] targetHandle Target handle (e.g. Bootloader, Application)
|
||
|
|
* \param[in] pLogicalBlock Pointer to current logical block
|
||
|
|
* \return Result of operation
|
||
|
|
* kFblOk when operation succeeded
|
||
|
|
* kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult ApplFblBmIsValidBlock(tFblBmHdrTargetHandle targetHandle,
|
||
|
|
const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * pLogicalBlock)
|
||
|
|
{
|
||
|
|
tFblResult result;
|
||
|
|
# if defined( FBL_ENABLE_PRESENCE_PATTERN ) || defined( FBLBM_ENABLE_STANDALONE_MODE )
|
||
|
|
vuint8 device;
|
||
|
|
# endif /* FBL_ENABLE_PRESENCE_PATTERN || FBLBM_ENABLE_STANDALONE_MODE */
|
||
|
|
# if !defined( FBL_ENABLE_PRESENCE_PATTERN )
|
||
|
|
vuint8 validityFlags[kEepSizeValidityFlags];
|
||
|
|
vuint8 validityMask;
|
||
|
|
vuint8 byteIdx;
|
||
|
|
# endif /* !FBL_ENABLE_PRESENCE_PATTERN */
|
||
|
|
|
||
|
|
# if (!defined( FBLBM_ENABLE_STANDALONE_MODE ) || defined( FBL_ENABLE_PRESENCE_PATTERN ))
|
||
|
|
# if defined( V_ENABLE_USE_DUMMY_STATEMENT )
|
||
|
|
(void)targetHandle;
|
||
|
|
# endif /* V_ENABLE_USE_DUMMY_STATEMENT */
|
||
|
|
# endif /* ( !FBLBM_ENABLE_STANDALONE_MODE || FBL_ENABLE_PRESENCE_PATTERN ) */
|
||
|
|
|
||
|
|
result = kFblFailed;
|
||
|
|
|
||
|
|
# if defined( FBLBM_ENABLE_STANDALONE_MODE ) && !defined( FBL_ENABLE_PRESENCE_PATTERN)
|
||
|
|
# error "If presence pattern is disabled special handling must be configured for the FBL because \
|
||
|
|
validity flags are not available for the FBL."
|
||
|
|
/* Perform presence pattern check only for FBL, use NV validity flags for other blocks */
|
||
|
|
if (targetHandle == FBLBMHDR_TARGET_FBL)
|
||
|
|
# endif /* FBLBM_ENABLE_STANDALONE_MODE && !FBL_ENABLE_PRESENCE_PATTERN */
|
||
|
|
# if defined( FBL_ENABLE_PRESENCE_PATTERN ) || defined( FBLBM_ENABLE_STANDALONE_MODE )
|
||
|
|
{
|
||
|
|
/* Check the presence pattern value */
|
||
|
|
if (kFblOk == FblMemGetDeviceByRange(pLogicalBlock->blockStartAddress, pLogicalBlock->blockLength, &device))
|
||
|
|
{
|
||
|
|
# if defined( kMioDeviceRam )
|
||
|
|
/* Do not check the presence pattern for RAM */
|
||
|
|
if (device != kMioDeviceRam)
|
||
|
|
# endif /* kMioDeviceRam */
|
||
|
|
{
|
||
|
|
result = FblNvPatternGetByBlockDescriptor(pLogicalBlock, kFblNvPatternId_BlockValidity );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
# endif /* FBL_ENABLE_PRESENCE_PATTERN || FBLBM_ENABLE_STANDALONE_MODE */
|
||
|
|
# if !defined( FBL_ENABLE_PRESENCE_PATTERN )
|
||
|
|
# if defined( FBLBM_ENABLE_STANDALONE_MODE )
|
||
|
|
/* Check NV validity flags if block other than FBL is checked */
|
||
|
|
else
|
||
|
|
# endif /* FBLBM_ENABLE_STANDALONE_MODE */
|
||
|
|
{
|
||
|
|
/* Calculate index and mask for validity bit of logical block */
|
||
|
|
byteIdx = (pLogicalBlock->blockNr >> 0x03u);
|
||
|
|
validityMask = (vuint8)(0x01u << (pLogicalBlock->blockNr & 0x07u));
|
||
|
|
|
||
|
|
/* Read validity information from non-volatile memory */
|
||
|
|
if (ApplFblNvReadValidityFlags(validityFlags) == kFblOk)
|
||
|
|
{
|
||
|
|
if ((validityFlags[byteIdx] & validityMask) == 0u)
|
||
|
|
{
|
||
|
|
/* Block is valid */
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
# endif /* !FBL_ENABLE_PRESENCE_PATTERN */
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
#endif /* FBLBM_AP_CALLOUT_IS_VALIDBLOCK */
|
||
|
|
|
||
|
|
#if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN )
|
||
|
|
# if defined( FBLBM_AP_CALLOUT_IS_VALIDPATTERN )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblBmCheckPresencePattern
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Explicitly checks the presence pattern(excluding the CMAC) validity of the target
|
||
|
|
* \param[in] targetHandle Target handle (e.g. Bootloader, Application)
|
||
|
|
* \param[in] pLogicalBlock Pointer to current logical block
|
||
|
|
* \return Result of operation
|
||
|
|
* kFblOk when operation succeeded
|
||
|
|
* kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult ApplFblBmCheckPresencePattern(tFblBmHdrTargetHandle targetHandle,
|
||
|
|
const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * pLogicalBlock)
|
||
|
|
{
|
||
|
|
tFblResult result;
|
||
|
|
|
||
|
|
vuint8 device;
|
||
|
|
IO_PositionType patternAddress;
|
||
|
|
IO_SizeType patternLength;
|
||
|
|
tFblNvPatternState patternState;
|
||
|
|
|
||
|
|
# if defined( V_ENABLE_USE_DUMMY_STATEMENT )
|
||
|
|
(void)targetHandle;
|
||
|
|
# endif /* V_ENABLE_USE_DUMMY_STATEMENT */
|
||
|
|
|
||
|
|
result = kFblFailed;
|
||
|
|
|
||
|
|
/* Check the presence pattern value of Target */
|
||
|
|
if (kFblOk == FblMemGetDeviceByRange(pLogicalBlock->blockStartAddress, pLogicalBlock->blockLength, &device))
|
||
|
|
{
|
||
|
|
# if defined( kMioDeviceRam )
|
||
|
|
/* Do not check the presence pattern for RAM */
|
||
|
|
if (device != kMioDeviceRam)
|
||
|
|
# endif /* kMioDeviceRam */
|
||
|
|
{
|
||
|
|
/* Check state of Target pattern */
|
||
|
|
patternState = FblNvPatternGetPatternState(pLogicalBlock, kFblNvPatternId_BlockValidity, &patternAddress, &patternLength);
|
||
|
|
if ((patternState.markerState == FBL_NVPATTERN_STATE_EXPECTEDVALUE) && (patternState.maskState == FBL_NVPATTERN_STATE_ERASED))
|
||
|
|
{
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
# endif /* FBLBM_AP_CALLOUT_IS_VALIDPATTERN */
|
||
|
|
|
||
|
|
# if defined( FBLBM_AP_CALLOUT_GET_PP_SIGN_KEYEMPTY )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblBmGetPresPattSignInitStatus
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Checks if now keys has been programmed so far Presence pattern
|
||
|
|
* \return FBLBM_KEY_IS_AVAILABLE if the keys are already programmed
|
||
|
|
FBLBM_KEY_IS_NOT_AVAILABLE else
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblBmKeyEmptyResult ApplFblBmGetPresPattSignInitStatus( void )
|
||
|
|
{
|
||
|
|
/* TODO_CUSTOMER: implement check if key is available here. This can be done by querying the HSM/SHE (depending
|
||
|
|
* on the used hardware) or e.g. by checking a pattern in the flash which indicates that the FBL has written the key
|
||
|
|
* into the Crypto.
|
||
|
|
*/
|
||
|
|
tFblBmKeyEmptyResult result;
|
||
|
|
vuint8 key[FBLBM_SIGNED_PP_KEY_SIZE];
|
||
|
|
vuint32 keyLength;
|
||
|
|
|
||
|
|
if (Csm_KeyElementGet(FblNvPattern_GetCsmKeyIdMac, CRYPTO_KE_CIPHER_KEY, key, (uint32*)&keyLength) != CRYPTO_E_KEY_NOT_AVAILABLE)
|
||
|
|
{
|
||
|
|
result = FBLBM_KEY_IS_AVAILABLE;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
result = FBLBM_KEY_IS_NOT_AVAILABLE;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
# endif /* FBLBM_AP_CALLOUT_GET_PP_SIGN_KEYEMPTY */
|
||
|
|
#endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */
|
||
|
|
|
||
|
|
#if defined( FBLBM_CALLOUT_IS_OPTIONALBLOCK )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblBmIsOptionalBlock
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Callout when logical block is optional and not present
|
||
|
|
* \param[in] targetHandle Target handle (e.g. Bootloader, Application)
|
||
|
|
* \param[in] pLogicalBlock Pointer to current logical block
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
void ApplFblBmIsOptionalBlock(tFblBmHdrTargetHandle targetHandle,
|
||
|
|
const V_MEMRAM1 tBlockDescriptor V_MEMRAM2 V_MEMRAM3 * pLogicalBlock)
|
||
|
|
{
|
||
|
|
# if defined( V_ENABLE_USE_DUMMY_STATEMENT )
|
||
|
|
(void)targetHandle;
|
||
|
|
(void)pLogicalBlock;
|
||
|
|
# endif /* V_ENABLE_USE_DUMMY_STATEMENT */
|
||
|
|
}
|
||
|
|
#endif /* FBLBM_CALLOUT_IS_OPTIONALBLOCK */
|
||
|
|
|
||
|
|
#if defined( FBLBM_AP_CALLOUT_START_SOFTWARE )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblBmStartSoftware
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief This function is called to start a software (e.g. Bootloader)
|
||
|
|
* \details Please note: The function will never return because control is handed over to the running software.
|
||
|
|
* \param[in] bmHeader Pointer to the targets BM Header structure, which shall be started
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
void ApplFblBmStartSoftware(const V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHeader)
|
||
|
|
{
|
||
|
|
# if defined( BRS_INSTRUCTION_SET_THUMB )
|
||
|
|
JSR(bmHeader->bmEntryAddress | 1u); /* PRQA S 0305 */ /* MD_FblBmAp_0305 */
|
||
|
|
# else
|
||
|
|
JSR(bmHeader->bmEntryAddress); /* PRQA S 0305 */ /* MD_FblBmAp_0305 */
|
||
|
|
# endif
|
||
|
|
|
||
|
|
# if defined( FBL_ENABLE_SYSTEM_CHECK )
|
||
|
|
/* Code should never be reached */
|
||
|
|
while (1u)
|
||
|
|
{
|
||
|
|
;
|
||
|
|
}
|
||
|
|
# endif /* FBL_ENABLE_SYSTEM_CHECK */
|
||
|
|
}
|
||
|
|
#endif /* FBLBM_AP_CALLOUT_START_SOFTWARE* */
|
||
|
|
|
||
|
|
#if defined( FBLBM_AP_CALLOUT_FAILSAFE_UPDATER_USER_CHECK ) && defined( FBLBM_ENABLE_UPDATER_FAILSAFE_USER )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblBmFailsafeUpdaterUserCheck
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief This function can be used to implement a user-defined updater and provide its entry address
|
||
|
|
* \details This function will be called if the user-defined updater feature is enabled and will control the rest
|
||
|
|
* of the bootmanager program flow
|
||
|
|
* \param[out] bmHeader Pointer to the BM Header structure whose jump address must be updated in case updater is found
|
||
|
|
* \return kFblOk: User-defined updater is available, jump to address given by bmHeader->bmEntryAddress
|
||
|
|
* kFblFailed: User-defined updater is not available, proceed to next state (failed state)
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/* PRQA S 3673 1 */ /* MD_MSR_Rule8.13 */
|
||
|
|
tFblResult ApplFblBmFailsafeUpdaterUserCheck(V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 V_MEMRAM3 * bmHeader)
|
||
|
|
{
|
||
|
|
# if defined( V_ENABLE_USE_DUMMY_STATEMENT )
|
||
|
|
(void)bmHeader;
|
||
|
|
# endif /* V_ENABLE_USE_DUMMY_STATEMENT */
|
||
|
|
/* TODO_CUSTOMER: Implement user updater check here. If the user updater is valid, set bmHeader->bmEntryAddress
|
||
|
|
* to the jump address of the updater entry function and set return value to kFblOk */
|
||
|
|
|
||
|
|
return kFblFailed;
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if defined( FBLBM_ENABLE_SECURE_BOOT )
|
||
|
|
# if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY )
|
||
|
|
# if defined( FBLBM_AP_CALLOUT_GET_KEYEMPTY )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblBmGetKeyEmpty
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Checks if now keys has been programmed so far
|
||
|
|
* \return FBLBM_KEY_IS_AVAILABLE if the keys are already programmed
|
||
|
|
FBLBM_KEY_IS_NOT_AVAILABLE else
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblBmKeyEmptyResult ApplFblBmGetKeyEmpty( void )
|
||
|
|
{
|
||
|
|
/* TODO_CUSTOMER: implement check if key is available here. This can be done by querying the HSM/SHE (depending
|
||
|
|
* on the used hardware) or e.g. by checking a pattern in the flash which indicates that the FBL has written the key
|
||
|
|
* into the Crypto.
|
||
|
|
*/
|
||
|
|
tFblBmKeyEmptyResult result;
|
||
|
|
|
||
|
|
# error "No default implementation for this variant available."
|
||
|
|
/* Per default assume that the key is available */
|
||
|
|
result = FBLBM_KEY_IS_AVAILABLE;
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
# endif /* FBLBM_AP_CALLOUT_GET_KEYEMPTY */
|
||
|
|
# endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY */
|
||
|
|
|
||
|
|
# if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC )
|
||
|
|
# if defined( FBLBM_AP_CALLOUT_GET_FBL_CMACERASED )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblBmGetFblCmacErased
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Checks if MACs for the FBL has been programmed so far
|
||
|
|
* \return FBLBM_MAC_IS_AVAILABLE If the MACs of the FBL are already written
|
||
|
|
* FBLBM_MAC_IS_NOT_AVAILABLE Else. E.g. because the FBL is just flashed by a debugger
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblBmMacEmptyResult ApplFblBmGetFblCmacErased( const tFblBmBlockInfo * fblBlockInfo )
|
||
|
|
{
|
||
|
|
/* TODO_CUSTOMER: implement check if CMAC is available here. This can be done by checking the CMAC content or e.g.
|
||
|
|
* by checking a pattern in the flash which indicates that the FBL CMAC was already written
|
||
|
|
*/
|
||
|
|
|
||
|
|
tFblBmMacEmptyResult result;
|
||
|
|
|
||
|
|
|
||
|
|
# if defined( V_ENABLE_USE_DUMMY_STATEMENT )
|
||
|
|
(void)fblBlockInfo;
|
||
|
|
# endif /* V_ENABLE_USE_DUMMY_STATEMENT */
|
||
|
|
|
||
|
|
if (ApplFblSbIsInitialStartup() == kFblOk)
|
||
|
|
{
|
||
|
|
/* This is the first startup, the SecureBootSegments needs to be updated */
|
||
|
|
result = FBLBM_MAC_IS_NOT_AVAILABLE;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
result = FBLBM_MAC_IS_AVAILABLE;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
# endif /* FBLBM_AP_CALLOUT_GET_FBL_CMACERASED */
|
||
|
|
# endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */
|
||
|
|
#endif /* FBLBM_ENABLE_SECURE_BOOT */
|
||
|
|
|
||
|
|
#if defined( FBLBM_AP_CALLOUT_CHECKREPROGFLAG )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblBmCheckReprogFlag
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Checks if a reprogramming request flag is set.
|
||
|
|
* \return Result of operation
|
||
|
|
* kFblOk when reprogramming request flag is set
|
||
|
|
* kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult ApplFblBmCheckReprogFlag( void )
|
||
|
|
{
|
||
|
|
tFblResult result = kFblFailed;
|
||
|
|
# if !defined( FBL_ENABLE_FBL_START )
|
||
|
|
vuint8 progReqFlag = 0u;
|
||
|
|
# endif
|
||
|
|
|
||
|
|
# if defined( FBL_ENABLE_FBL_START )
|
||
|
|
if (FblBmChkFblStartMagicFlag())
|
||
|
|
{
|
||
|
|
/* FblStart magic flag is set, do not clear flag as the Bootloader requires it as well */
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
# else
|
||
|
|
/* Check the reprogramming request flag */
|
||
|
|
if (ApplFblNvReadProgReqFlag(&progReqFlag) == kFblOk)
|
||
|
|
{
|
||
|
|
if (progReqFlag == kEepFblReprogram)
|
||
|
|
{
|
||
|
|
/* UDS-Reprogramming flag is set, do not clear flag as the Bootloader requires it as well */
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
# if defined( FBL_ENABLE_XCP )
|
||
|
|
else if (progReqFlag == kEepFblXcpProgram)
|
||
|
|
{
|
||
|
|
/* XCP-Reprogramming flag is set, do not clear flag as the Bootloader requires it as well */
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
# endif
|
||
|
|
# if defined( FBL_ENABLE_OTA )
|
||
|
|
else if (progReqFlag == kEepFblOtaReprogram)
|
||
|
|
{
|
||
|
|
/* OTA-Reprogramming flag is set, do not clear flag as the Bootloader requires it as well */
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
# endif
|
||
|
|
else
|
||
|
|
{
|
||
|
|
/* Nothing to do */
|
||
|
|
}
|
||
|
|
}
|
||
|
|
# endif /* FBL_ENABLE_FBL_START */
|
||
|
|
|
||
|
|
# if defined( FBLBM_MAIN_ENABLE_MAGICFLAG ) && \
|
||
|
|
defined( FBLBM_ENABLE_SECURE_BOOT ) && \
|
||
|
|
defined( FBLBM_MAIN_ENABLE_HARDWARE_SWAP )
|
||
|
|
if (FblBmChkSBUpdateMagicFlag())
|
||
|
|
{
|
||
|
|
/* Start FBL in case of secure boot update */
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
# endif
|
||
|
|
|
||
|
|
# if defined( FBL_ENABLE_OTA )
|
||
|
|
if (vOtaM_GetState() == vOtaM_State_OtaRequest)
|
||
|
|
{
|
||
|
|
/* OTA request is pending -> bootloader should be started */
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
# endif /* FBL_ENABLE_OTA */
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
#endif /* FBLBM_AP_CALLOUT_CHECKREPROGFLAG */
|
||
|
|
|
||
|
|
#if defined( FBLBM_ENABLE_UPDATER_FAILSAFE )
|
||
|
|
# if defined( FBLBM_AP_CALLOUT_SEARCH_FAILSAFE_UPDATER_INIT )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblBmSearchUpdaterHeaderInit
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Prepare search for updater BmHeader location
|
||
|
|
* \return Result of operation
|
||
|
|
* kFblOk when operation succeeded
|
||
|
|
* kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult ApplFblBmSearchUpdaterHeaderInit(void)
|
||
|
|
{
|
||
|
|
g_ApplFblBmSearchUpdaterHeaderIndex = 0u;
|
||
|
|
return kFblOk;
|
||
|
|
}
|
||
|
|
# endif /* FBLBM_AP_CALLOUT_SEARCH_FAILSAFE_UPDATER_INIT */
|
||
|
|
|
||
|
|
# if defined( FBLBM_AP_CALLOUT_SEARCH_FAILSAFE_UPDATER_HEADER_ADDRESS )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblBmSearchUpdaterHeaderAddress
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Get address of possible location of a BmHeader for the Failsafe Updater
|
||
|
|
* \param[out] headerAddress Address where the BmHeader could possible be located
|
||
|
|
* \return Result of operation
|
||
|
|
* kFblOk when operation succeeded
|
||
|
|
* kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult ApplFblBmSearchUpdaterHeaderAddress(vuint32 * headerAddress)
|
||
|
|
{
|
||
|
|
vuint32 offset = 0u;
|
||
|
|
(* headerAddress) = FlashBlock[g_ApplFblBmSearchUpdaterHeaderIndex].begin + offset;
|
||
|
|
return kFblOk;
|
||
|
|
}
|
||
|
|
# endif /* FBLBM_AP_CALLOUT_SEARCH_FAILSAFE_UPDATER_HEADER_ADDRESS */
|
||
|
|
|
||
|
|
# if defined( FBLBM_AP_CALLOUT_SEARCH_FAILSAFE_UPDATER_NEXT )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblBmSearchUpdaterHeaderNext
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Get (next) possible location of a BmHeader for the Failsafe Updater
|
||
|
|
* \return Result of operation
|
||
|
|
* kFblOk when operation succeeded
|
||
|
|
* kFblFailed otherwise
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
tFblResult ApplFblBmSearchUpdaterHeaderNext(void)
|
||
|
|
{
|
||
|
|
tFblResult result;
|
||
|
|
|
||
|
|
g_ApplFblBmSearchUpdaterHeaderIndex++;
|
||
|
|
|
||
|
|
if (g_ApplFblBmSearchUpdaterHeaderIndex < kNrOfFlashBlock)
|
||
|
|
{
|
||
|
|
result = kFblOk;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
result = kFblFailed;
|
||
|
|
}
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
# endif /* FBLBM_AP_CALLOUT_SEARCH_FAILSAFE_UPDATER_NEXT */
|
||
|
|
#endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */
|
||
|
|
|
||
|
|
#if defined( FBLBM_AP_CALLOUT_FATAL_ERROR )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblBmFatalError
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief This function is called in case no valid starting software was found
|
||
|
|
* \details Provide here some final tasks which shall be executed
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
void ApplFblBmFatalError(tFblBmError error)
|
||
|
|
{
|
||
|
|
# if defined( V_ENABLE_USE_DUMMY_STATEMENT )
|
||
|
|
(void)error;
|
||
|
|
# endif /* V_ENABLE_USE_DUMMY_STATEMENT */
|
||
|
|
|
||
|
|
# if defined( FBL_ENABLE_SYSTEM_CHECK )
|
||
|
|
/* Code should never be reached */
|
||
|
|
while (1u)
|
||
|
|
{
|
||
|
|
;
|
||
|
|
}
|
||
|
|
# endif /* FBL_ENABLE_SYSTEM_CHECK */
|
||
|
|
}
|
||
|
|
#endif /* FBLBM_AP_CALLOUT_FATAL_ERROR */
|
||
|
|
|
||
|
|
/*-- Other callout functions -----------------------------------------------------------------------------------------*/
|
||
|
|
|
||
|
|
#if defined( FBLBM_ENABLE_STANDALONE_MODE )
|
||
|
|
# if defined( FBL_ENABLE_ASSERTION )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblFatalError
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Will be called in case of an urecoverable error
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
void ApplFblFatalError( FBL_DECL_ASSERT_EXTENDED_INFO(vuint8 errorCode) )
|
||
|
|
{
|
||
|
|
/* Change this variable in debugger in order to return to caller */
|
||
|
|
volatile vuint8 stayInWhile = 1u;
|
||
|
|
|
||
|
|
# if defined( V_ENABLE_USE_DUMMY_STATEMENT )
|
||
|
|
(void)errorCode;
|
||
|
|
# endif /* V_ENABLE_USE_DUMMY_STATEMENT */
|
||
|
|
|
||
|
|
while (0u != stayInWhile)
|
||
|
|
{
|
||
|
|
FblLookForWatchdogVoid();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
# endif /* FBL_ENABLE_ASSERTION */
|
||
|
|
|
||
|
|
# if (DET_ENABLED == STD_ON)
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFbl_DetEntryHandler
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Called by DET module to check if a DET error is intended bootloader behavior or not.
|
||
|
|
* \param[in] ModuleId Code number of the encountered assertion
|
||
|
|
* \param[in] InstanceId Name of the affected module (Only if extended info is enabled)
|
||
|
|
* \param[in] ApiId Line number where the assertion occurred (Only if extended info is enabled)
|
||
|
|
* \param[in] ErrorId Line number where the assertion occurred (Only if extended info is enabled)
|
||
|
|
* \return Report if error should be handed over to DET or not
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
# if ((DET_AR_RELEASE_MAJOR_VERSION >= 4u) && (DET_AR_RELEASE_MINOR_VERSION >= 3u))
|
||
|
|
FUNC(Std_ReturnType, DET_CODE) ApplFbl_DetEntryHandler( uint16 ModuleId, uint8 InstanceId, uint8 ApiId, uint8 ErrorId )
|
||
|
|
# else
|
||
|
|
FUNC(boolean, DET_APPL_CODE) ApplFbl_DetEntryHandler( uint16 ModuleId, uint8 InstanceId, uint8 ApiId, uint8 ErrorId )
|
||
|
|
# endif /* DET_AR_RELEASE_ */
|
||
|
|
{
|
||
|
|
# if ((DET_AR_RELEASE_MAJOR_VERSION >= 4u) && (DET_AR_RELEASE_MINOR_VERSION >= 3u))
|
||
|
|
Std_ReturnType result = E_OK;
|
||
|
|
/* Use result value of E_NOT_OK to ignore the DET */
|
||
|
|
# else
|
||
|
|
boolean result = FALSE;
|
||
|
|
/* Use result value of TRUE to ignore the DET */
|
||
|
|
# endif /* DET_AR_RELEASE_ */
|
||
|
|
|
||
|
|
# if defined( V_ENABLE_USE_DUMMY_STATEMENT )
|
||
|
|
(void)ModuleId;
|
||
|
|
(void)InstanceId;
|
||
|
|
(void)ApiId;
|
||
|
|
(void)ErrorId;
|
||
|
|
# endif /* V_ENABLE_USE_DUMMY_STATEMENT */
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
# endif /* DET_ENABLED == STD_ON */
|
||
|
|
|
||
|
|
# if defined( FBL_MIO_ENABLE_HOOKS )
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblPreMemDriver
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Function is called before the memory driver is executed.
|
||
|
|
* \param[in] device Memory device, which is going to be used.
|
||
|
|
* \param[in] function Function of the memory device, which is going to be called.
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
void ApplFblPreMemDriver( vuint8 device, vuint8 function )
|
||
|
|
{
|
||
|
|
uint8 opMode;
|
||
|
|
Std_ReturnType retVal;
|
||
|
|
|
||
|
|
# if defined( V_ENABLE_USE_DUMMY_STATEMENT )
|
||
|
|
/* Parameters not used: avoid compiler warning */
|
||
|
|
(void)device;
|
||
|
|
(void)function;
|
||
|
|
# endif
|
||
|
|
/* TODO_CUSTOMER: Adapt this example implementation to project-specific needs/requirements */
|
||
|
|
/* Suspend vHSM operations in data flash */
|
||
|
|
opMode = CRYPTO_30_VHSM_DATAFLASH_START;
|
||
|
|
retVal = Csm_KeyElementSet(CsmConf_CsmKey_CsmKey_vHsm_Hardware, CRYPTO_KE_CUSTOM_VHSM_FLASH_OPERATION, &opMode, 1u);
|
||
|
|
/* Suspend vHSM operations in code flash -> send it to RAM loop */
|
||
|
|
opMode = CRYPTO_30_VHSM_CODEFLASH_START;
|
||
|
|
retVal |= Csm_KeyElementSet(CsmConf_CsmKey_CsmKey_vHsm_Hardware, CRYPTO_KE_CUSTOM_VHSM_FLASH_OPERATION, &opMode, 1u);
|
||
|
|
|
||
|
|
/* Simulate DET functionality in case of any error */
|
||
|
|
assertFblUser(retVal == E_OK, kFblSysAssertDet);
|
||
|
|
}
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* ApplFblPostMemDriver
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
/*! \brief Function is called after the memory driver has finished the operation.
|
||
|
|
* \param[in] device Memory device, which is going to be used.
|
||
|
|
* \param[in] function Function of the memory device, which is going to be called.
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
void ApplFblPostMemDriver( vuint8 device, vuint8 function )
|
||
|
|
{
|
||
|
|
uint8 opMode;
|
||
|
|
Std_ReturnType retVal;
|
||
|
|
# if defined( V_ENABLE_USE_DUMMY_STATEMENT )
|
||
|
|
/* Parameters not used: avoid compiler warning */
|
||
|
|
(void)device;
|
||
|
|
(void)function;
|
||
|
|
# endif
|
||
|
|
/* TODO_CUSTOMER: Adapt this example implementation to project-specific needs/requirements */
|
||
|
|
/* Get vHSM back from RAM loop */
|
||
|
|
opMode = CRYPTO_30_VHSM_CODEFLASH_STOP;
|
||
|
|
retVal = Csm_KeyElementSet(CsmConf_CsmKey_CsmKey_vHsm_Hardware, CRYPTO_KE_CUSTOM_VHSM_FLASH_OPERATION, &opMode, 1u);
|
||
|
|
/* Give vHSM access to data flash operations */
|
||
|
|
opMode = CRYPTO_30_VHSM_DATAFLASH_STOP;
|
||
|
|
retVal |= Csm_KeyElementSet(CsmConf_CsmKey_CsmKey_vHsm_Hardware, CRYPTO_KE_CUSTOM_VHSM_FLASH_OPERATION, &opMode, 1u);
|
||
|
|
|
||
|
|
/* Simulate DET functionality in case of any error */
|
||
|
|
assertFblUser(retVal == E_OK, kFblSysAssertDet);
|
||
|
|
}
|
||
|
|
# endif /* FBL_MIO_ENABLE_HOOKS */
|
||
|
|
#endif /* FBLBM_ENABLE_STANDALONE_MODE */
|
||
|
|
|
||
|
|
#define FBLBMAP_STOP_SEC_CODE
|
||
|
|
#include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* MISRA DEVIATIONS
|
||
|
|
**********************************************************************************************************************/
|
||
|
|
|
||
|
|
/* Justification for module-specific MISRA deviations:
|
||
|
|
|
||
|
|
MD_FblBmAp_0305:
|
||
|
|
Reason: Boot manager needs to jump to a memory location to start a target/software.
|
||
|
|
Risk: Unintended jump to wrong memory location.
|
||
|
|
Prevention: No prevention possible, address is defined by the corresponding target.
|
||
|
|
|
||
|
|
MD_FblBmAp_0306:
|
||
|
|
Reason: Address conversion between integer values and pointers is required to allow for hardware independent
|
||
|
|
configuration and address range checks.
|
||
|
|
Risk: The size of integer required to hold the result of a pointer cast is implementation-defined.
|
||
|
|
Prevention: The size of the respective integer data type which holds the address value is adapted on a hardware
|
||
|
|
specific basis. The correctness of the respective implementation is verified by runtime tests.
|
||
|
|
|
||
|
|
MD_FblBmAp_2741_4558:
|
||
|
|
Reason: Assertion macros have to be disabled in production code and are used only for development.
|
||
|
|
Risk: Assertion code may be enabled in production code unintentionally. If a assertion condition is unexpectedly
|
||
|
|
false, the code is active. A problem may occur if the Macro is additionally changed from single statement
|
||
|
|
to multiple statement.
|
||
|
|
Prevention: Macro is not allowed to be changed without review. Development code is automatically disabled via
|
||
|
|
configuration of project state "Production".
|
||
|
|
|
||
|
|
*/
|
||
|
|
|
||
|
|
/***********************************************************************************************************************
|
||
|
|
* END OF FILE: BM_AP.C
|
||
|
|
**********************************************************************************************************************/
|