/*********************************************************************************************************************** * FILE DESCRIPTION * ------------------------------------------------------------------------------------------------------------------*/ /** \file * \brief Main module of BM * * -------------------------------------------------------------------------------------------------------------------- * 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 * -------------------------------------------------------------------------------------------------------------------- * 04.00.00 2019-10-10 vistmo FBL-390 Adapt main function interface for vBaseEnv * 04.00.01 2019-11-05 visrie ESCAN00104616 No changes * ESCAN00104790 No changes * 05.00.00 2019-12-04 visrie FBL-456 Added support for new FblLibSecBoot interface * ESCAN00104644 Initialize DET module * ESCAN00105176 Added support for VTT use case * 05.01.00 2020-01-13 visrie ESCAN00104481 No changes * FBL-953 No changes * 05.02.00 2020-02-28 vistbe FBL-949 No changes * 06.00.00 2020-04-08 visrie FBL-1016 Support of EcuM functions * 06.00.01 2020-04-08 visrie ESCAN00106837 Compiler error: wrong argument type at FblSb_VerifySegments * 06.00.02 2020-10-28 visrcn ESCAN00107189 Compiler error: Wrong definition for FblMain function * 06.01.00 2021-08-11 visrie FBL-3394 Move default implementation of CheckReprogFlag into FblBm_Ap * Added/adapted MemMap sections * 06.02.00 2022-02-04 visrie FBL-4602 Added support of new SecBoot API (VerifyHeaderRom) * 06.02.01 2022-04-06 fmenke ESCAN00111029 [MCMP only] Compiler error: Label FblDiagInitPowerOn is not defined * 06.03.00 2022-04-08 visrie FBL-4126 No changes * 06.04.00 2022-04-11 lhopfhauer FBL-4822 Add support for new MagicFlag value and Swap API * 06.04.01 2022-04-28 fmenke ESCAN00111741 SecureBoot for Bootloader not checked during reprogramming * request started by application * 06.05.00 2022-05-06 lhopfhauer FBL-5148 Encapsulate call of FblInterruptDisable * 06.06.00 2022-07-13 fmenke FBL-5391 Add callout for missing optional dependency * 06.06.01 2022-08-04 jschmitding ESCAN00112070 FblSb_VerifySegments is needlessly called twice. * 06.07.00 2022-11-07 lhopfhauer FBL-4932 Adjust FBL LBT Check * 06.08.00 2022-11-30 visrie FBL-6065 No changes * 06.08.01 2024-03-04 visrie ESCAN00116460 Assertion missing in FblMemGet/SetInteger * 06.09.00 2024-05-16 lhopfhauer FBL-8602 Add support for OEM updater solution * 06.10.00 2024-11-15 erizk FBL-9652 Optimize startup times for secure boot * 06.11.00 2025-05-23 dganesh FBL-9715 Extend presence pattern to connect validity information * 06.12.00 2025-09-23 pharring FBL-10124 Add support for FblLib_Logger **********************************************************************************************************************/ #define BM_MAIN_SOURCE /*********************************************************************************************************************** * INCLUDES **********************************************************************************************************************/ #include "fbl_inc.h" #include "fbl_main_types.h" #include "bm_main.h" #include "fbl_fsm.h" #if defined( FBLBM_ENABLE_SECURE_BOOT ) # include "fbl_secboot.h" #endif #include "EcuM.h" /*********************************************************************************************************************** * VERSION **********************************************************************************************************************/ #if ( FBLBM_MAIN_VERSION != 0x0612u ) || \ ( FBLBM_MAIN_RELEASE_VERSION != 0x00u ) # error "Error in bm_main.c: Source and Header file are inconsistent!" #endif #if ( FBLBM_MAIN_VERSION != _FBLBM_MAIN_VERSION ) || \ ( FBLBM_MAIN_RELEASE_VERSION != _FBLBM_MAIN_RELEASE_VERSION ) # error "Error in bm_main.c: Source and v_ver.h are inconsistent!" #endif /* Interface version compatibility check: General callouts */ #if defined( FBLBM_AP_API_VERSION_MAJOR ) && \ defined( FBLBM_AP_API_VERSION_MINOR ) #else # error "Error in bm_main.c: Interface version requirements not defined!" #endif #if ( FBLBM_AP_API_VERSION_MAJOR != FBLBM_API_VERSION_MAJOR ) || \ ( FBLBM_AP_API_VERSION_MINOR > FBLBM_API_VERSION_MINOR ) # error "Error in bm_main.c: Interface version compatibility check failed!" #endif /* Interface version compatibility check: platform-specific callouts */ #if defined( FBLBM_AP_HW_API_VERSION_MAJOR ) # if defined( FBLBM_AP_HW_API_VERSION_MINOR ) # else # error "Error in bm_main.c: Interface version requirements not defined!" # endif # if ( FBLBM_AP_HW_API_VERSION_MAJOR != FBLBM_API_VERSION_MAJOR ) || \ ( FBLBM_AP_HW_API_VERSION_MINOR > FBLBM_API_VERSION_MINOR ) # error "Error in bm_main.c: Interface version compatibility check failed!" # endif #endif /* Interface version compatibility check: OEM-specific callouts */ #if defined( FBLBM_AP_OEM_API_VERSION_MAJOR ) # if defined( FBLBM_AP_OEM_API_VERSION_MINOR ) # else # error "Error in bm_main.c: Interface version requirements not defined!" # endif # if ( FBLBM_AP_OEM_API_VERSION_MAJOR != FBLBM_API_VERSION_MAJOR ) || \ ( FBLBM_AP_OEM_API_VERSION_MINOR > FBLBM_API_VERSION_MINOR ) # error "Error in bm_main.c: Interface version compatibility check failed!" # endif #endif /*********************************************************************************************************************** * DEFINES **********************************************************************************************************************/ #if defined( _MICROSOFT_C_VTT_ ) # define FBLBM_MAIN_ENABLE_VTT_USECASE #endif /* _MICROSOFT_C_VTT_ */ /** Helper macro for filling state structures (enhance readability) */ #define FBLBM_SIZE_AND_ARRAY(array) FBLBM_ARRAY_SIZE(array), (array) /* PRQA S 3453 */ /* MD_MSR_FctLikeMacro */ #if defined( FBLBM_ENABLE_SECURE_BOOT ) # if (!defined( FBLBM_DISABLE_USE_VERIFY_HEADER_ROM ) && \ ( ( FBLSB_API_REFERENCE_VERSION_MAJOR > 0x02u ) || \ (( FBLSB_API_REFERENCE_VERSION_MAJOR == 0x02u ) && ( FBLSB_API_REFERENCE_VERSION_MINOR >= 0x02u )))) # define FBLBM_ENABLE_USE_VERIFY_HEADER_ROM # endif #endif /* FBLBM_ENABLE_SECURE_BOOT */ #if defined( FBLBM_ENABLE_HEADER_VERIFICATION ) || defined( FBLBM_ENABLE_FBLLBT_VERIFICATION ) # define FBLBM_DISABLE_EARLY_FBL_SEGMENTS_CHECK #else # define FBLBM_ENABLE_EARLY_FBL_SEGMENTS_CHECK #endif /*********************************************************************************************************************** * TYPEDEFS, ENUMS **********************************************************************************************************************/ /** Bootmanager States */ /* PRQA S 3205 TAG_FblBmMain_3205_1 */ /* MD_FblBmMain_3205_UnusedIdentifiers */ typedef enum { FBLBM_STATE_POWER_ON, /* 0 */ FBLBM_STATE_INIT, /* 1 */ FBLBM_STATE_CHECK_FBL_VALIDITY, /* 2 */ FBLBM_STATE_FAILSAFE_UPDATER_ENABLED, /* 3 */ FBLBM_STATE_FAILSAFE_UPDATER_SEARCH_INIT, /* 4 */ FBLBM_STATE_FAILSAFE_UPDATER_CHECK, /* 5 */ FBLBM_STATE_FAILSAFE_UPDATER_SEARCH_NEXT, /* 6 */ FBLBM_STATE_FAILSAFE_UPDATER_USER_CHECK, /* 7 */ FBLBM_STATE_CALL_FAILSAFE_UPDATER, /* 8 */ FBLBM_STATE_CHECK_PP_KEY_AVAILABILITY, /* 9 */ FBLBM_STATE_CALL_FBL_PP_INIT_KEY, /* 10 */ FBLBM_STATE_CHECK_SIGNED_PP_VALIDITY, /* 11 */ FBLBM_STATE_SECURE_BOOT_ENABLED, /* 12 */ FBLBM_STATE_CHECK_KEY_AVAILABILITY, /* 13 */ FBLBM_STATE_CALL_FBL_INIT_KEY, /* 14 */ FBLBM_STATE_INIT_FBL_MAC_ENABLED, /* 15 */ FBLBM_STATE_CHECK_FBL_MAC_ERASED, /* 16 */ FBLBM_STATE_CALL_FBL_INIT_CMAC, /* 17 */ FBLBM_STATE_STAY_IN_BOOT_ENABLED, /* 18 */ FBLBM_STATE_CHECK_APPL_START_FLAG, /* 19 */ FBLBM_STATE_CHECK_FBL_LBT, /* 20 */ FBLBM_STATE_CHECK_REPROG_FLAG, /* 21 */ FBLBM_STATE_REPROG_LBT_ENABLED, /* 22 */ FBLBM_STATE_CHECK_REPROG_LBT, /* 23 */ FBLBM_STATE_TARGET_LIST_INIT, /* 24 */ FBLBM_STATE_TARGET_CHECK, /* 25 */ FBLBM_STATE_TARGET_LIST_NEXT, /* 26 */ FBLBM_STATE_CALL_TARGET, /* 27 */ FBLBM_STATE_CHECK_LATE_FBL_SEGMENTS, /* 28 */ FBLBM_STATE_CHECK_FBL_VERIFICATION_STAY_IN_BOOT, /* 29 */ FBLBM_STATE_CALL_FBL, /* 30 */ FBLBM_STATE_CALL_FBL_STAY_IN_BOOT, /* 31 */ FBLBM_STATE_CHECK_EARLY_FBL_SEGMENTS, /* 32 */ FBLBM_STATE_FAIL /* 33 */ } tFblBmState; /** Events for BM FSM: Only one Event "continue" */ typedef enum { FBLBM_EVENT_CONTINUE = kFblFsmDefaultEvent_Count /* 4 */ } tFblBmEvent; /* PRQA L:TAG_FblBmMain_3205_1 */ /*********************************************************************************************************************** * LOCAL FUNCTION PROTOTYPES **********************************************************************************************************************/ #define FBLBM_START_SEC_CODE #include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ static void FblBmDeinit(void); /* Event Handlers */ static tFblFsmGuard FblBmState_PowerOn_Entry (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); static tFblFsmGuard FblBmState_Init_Entry (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); #if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) || defined( FBLBM_ENABLE_UPDATER_FAILSAFE_USER ) static tFblFsmGuard FblBmState_CallFailsafeUpdater_Entry (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); #endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ #if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY) static tFblFsmGuard FblBmState_CallFblInitKey_Entry (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); #endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY */ #if ( FBLBM_BOOTTARGETLIST_SIZE > 0u ) static tFblFsmGuard FblBmState_CallTarget_Entry (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); #endif /* FBLBM_BOOTTARGETLIST_SIZE > 0u */ static tFblFsmGuard FblBmState_CallFbl_Entry (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); #if defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT ) static tFblFsmGuard FblBmState_CallFblStayInBoot_Entry (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); #endif /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ #if defined( FBLBM_ENABLE_SECURE_BOOT ) static tFblFsmGuard FblBmState_CheckEarlyFblSegments (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); #endif /* FBLBM_ENABLE_SECURE_BOOT */ #if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) static tFblFsmGuard FblBmState_CallFblInitCmac_Entry (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); #endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ static tFblFsmGuard FblBmState_Fail_Entry (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); /* Guards */ static tFblFsmGuard FblBmState_CheckFblValidity (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); #if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) static tFblFsmGuard FblBmState_FailsafeUpdaterSearchInit (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); static tFblFsmGuard FblBmState_FailsafeUpdaterCheck (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); static tFblFsmGuard FblBmState_FailsafeUpdaterSearchNext (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); #elif defined( FBLBM_ENABLE_UPDATER_FAILSAFE_USER ) static tFblFsmGuard FblBmState_FailsafeUpdaterUserCheck (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); #endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ #if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) static tFblFsmGuard FblBmState_CheckSignedPresPattKeyAvailability (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); static tFblFsmGuard FblBmState_CallFblInitKeySignedPresPatt (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); static tFblFsmGuard FblBmState_CheckSignedPresPattValidity (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); #endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ static tFblFsmGuard FblBmState_CheckKeyAvailability (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); #if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) static tFblFsmGuard FblBmState_CheckFblMacErased (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); #endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ #if defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT ) static tFblFsmGuard FblBmState_CheckApplStartFlag (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); #endif /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ static tFblFsmGuard FblBmState_CheckReprogFlag (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); static tFblFsmGuard FblBmState_CheckFblLbt (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); #if defined( FBL_LBT_ENABLE_REPROGRAMMABLE_LBT ) static tFblFsmGuard FblBmState_CheckReprogLbt (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); #endif /* FBL_LBT_ENABLE_REPROGRAMMABLE_LBT */ #if ( FBLBM_BOOTTARGETLIST_SIZE > 0u ) static tFblFsmGuard FblBmState_TargetListInit (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); static tFblFsmGuard FblBmState_TargetCheck (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); static tFblFsmGuard FblBmState_TargetListNext (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); #endif /* FBLBM_BOOTTARGETLIST_SIZE > 0u */ static tFblFsmGuard FblBmState_CheckLateFblSegments (tFblFsmContextPtr const pFsmContext, tFblFsmEvent event); #define FBLBM_STOP_SEC_CODE #include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ /*********************************************************************************************************************** * GLOBAL DATA **********************************************************************************************************************/ #define FBLBM_HEADER_START_SEC_CONST #include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ /** BM header data for access from application software */ V_MEMROM0 V_MEMROM1 tFblBmHeader V_MEMROM2 FblBmHeader = /* PRQA S 1514 */ /* MD_FblBmMain_1514_BmHeader */ { FBLBM_HEADER_MAGIC_VALUE, FBLBM_HEADER_MAJOR_VERSION, FBLBM_HEADER_MINOR_VERSION, FBL_HEADER_ADDRESS, #if defined( FBLBM_MAIN_ENABLE_FBL_START ) (tFblStrtFct)&FblStart, #else (tFblStrtFct)V_NULL, #endif #if defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT ) (tApplStrtFct)&ApplStart, #else (tApplStrtFct)V_NULL, #endif 0u, /* Checksum is not yet used */ FBLBM_HEADER_END_MAGIC_VALUE }; #define FBLBM_HEADER_STOP_SEC_CONST #include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ /*********************************************************************************************************************** * LOCAL DATA **********************************************************************************************************************/ #define FBLBM_START_SEC_VAR #include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ /** Block Info for the FBL block */ V_MEMRAM0 static V_MEMRAM1 tFblBmBlockInfo V_MEMRAM2 fblBmBlockInfo; #if defined( FBLBM_ENABLE_STANDALONE_MODE ) /** Local copy of FBL header structure */ V_MEMRAM0 static V_MEMRAM1 tFblHeader V_MEMRAM2 fblBmFblHeader; /* PRQA S 3218 */ /* MD_FBL_3218_FileScopeStatic */ #endif /* FBLBM_ENABLE_STANDALONE_MODE */ /** Context Structure of the Finite State Machine (FSM) */ V_MEMRAM0 static V_MEMRAM1 tFblFsmContext V_MEMRAM2 g_BmFsmContext; /* PRQA S 3218 */ /* MD_FBL_3218_FileScopeStatic */ #if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) || defined( FBLBM_ENABLE_UPDATER_FAILSAFE_USER ) /** Entry Point for Failsafe Updater */ V_MEMRAM0 static V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 g_BmFailsafeUpdaterBmHeader; #endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ #if ( FBLBM_BOOTTARGETLIST_SIZE > 0u ) /** Counter for search for valid target */ V_MEMRAM0 static V_MEMRAM1 vuintx V_MEMRAM2 g_BmTargetListIndex; /** Entry Point for target */ V_MEMRAM0 static V_MEMRAM1 tFblBmHdrHeader V_MEMRAM2 g_BmTargetBmHeader; #endif /* FBLBM_BOOTTARGETLIST_SIZE > 0u */ /** Error Code */ V_MEMRAM0 static V_MEMRAM1 tFblBmError V_MEMRAM2 g_BmError; #define FBLBM_STOP_SEC_VAR #include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ /***** State machine *****/ #define FBLBM_START_SEC_CONST #include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ /** State PowerOn (0) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_PowerOn[] = { /* Initialize Memory and go directly to next step: Init */ FBL_FSM_TRIGGER_ENTRY(FblBmState_PowerOn_Entry), FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_INIT) }; /** State Init (1) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_Init[] = { /* Call Init Routines * GOTO next step on continue-event */ FBL_FSM_TRIGGER_ENTRY(FblBmState_Init_Entry), FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_CHECK_FBL_VALIDITY) }; /** State CheckFblValidity (2) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckFblValidity[] = { /* Configuration switch: * IF Extended PP is enabled goto state CheckKeyPPAvailability * ELSEIF FBL is valid goto state CheckSecureBootEnabled * ELSE GOTO UpdaterEnabled */ #if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckFblValidity, FBLBM_STATE_CHECK_PP_KEY_AVAILABILITY), #else FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckFblValidity, FBLBM_STATE_SECURE_BOOT_ENABLED), #endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAILSAFE_UPDATER_ENABLED) }; /** State FailsafeUpdaterEnabled (3) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_FailsafeUpdaterEnabled[] = { /* Configuration switch: If Updater support is enabled search for updater. * This state is reached when no valid FBL is available. This can only happen * if a FBL-update process is interrupted. */ #if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_FAILSAFE_UPDATER_SEARCH_INIT) #elif defined( FBLBM_ENABLE_UPDATER_FAILSAFE_USER ) FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_FAILSAFE_UPDATER_USER_CHECK) #else /* FBLBM_ENABLE_UPDATER_FAILSAFE */ FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_FAIL) #endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ }; /** State FailsafeUpdaterSearchInit (4) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_FailsafeUpdaterSearchInit[] = { #if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_FailsafeUpdaterSearchInit, FBLBM_STATE_FAILSAFE_UPDATER_CHECK), /* */ #endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) }; /** State FailsafeUpdaterCheck (5) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_FailsafeUpdaterCheck[] = { /* If a update is aborted e.g. due to power loss, the FBL may be already erased. * In this case: Search for a valid Updater and call it */ #if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_FailsafeUpdaterCheck, FBLBM_STATE_CALL_FAILSAFE_UPDATER), FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAILSAFE_UPDATER_SEARCH_NEXT), #else /* FBLBM_ENABLE_UPDATER_FAILSAFE */ FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) #endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ }; /** State FailsafeUpdaterSearchNext (6) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_FailsafeUpdaterSearchNext[] = { #if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_FailsafeUpdaterSearchNext, FBLBM_STATE_FAILSAFE_UPDATER_CHECK), #endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) }; /** State FailsafeUpdaterUserCheck (7) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_FailsafeUpdaterUserCheck[] = { #if defined( FBLBM_ENABLE_UPDATER_FAILSAFE_USER ) FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_FailsafeUpdaterUserCheck, FBLBM_STATE_CALL_FAILSAFE_UPDATER), #endif FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) }; /** State CallFailsafeUpdater (8) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CallFailsafeUpdater[] = { /* Start the Updater */ #if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) || defined( FBLBM_ENABLE_UPDATER_FAILSAFE_USER ) FBL_FSM_TRIGGER_ENTRY(FblBmState_CallFailsafeUpdater_Entry), #endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) }; /** State CheckSignedPresPattKeyAvailability (9) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckSignedPresPattKeyAvailability[] = { /* Check if a Key is already available. If not, FBL shall be called to initialize the key. */ #if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckSignedPresPattKeyAvailability, FBLBM_STATE_CHECK_SIGNED_PP_VALIDITY), FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_CALL_FBL_PP_INIT_KEY) #else /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_FAIL) #endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ }; /** State CallFblInitKeySignedPresPatt (10) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CallFblInitKeySignedPresPatt[] = { /* Call FBL to initialize key */ #if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) FBL_FSM_TRIGGER_ENTRY(FblBmState_CallFblInitKeySignedPresPatt), #endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) }; /** State CheckSignedPresPattValidity with MAC (11) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckSignedPresPattValidity[] = { #if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckSignedPresPattValidity, FBLBM_STATE_SECURE_BOOT_ENABLED), FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAILSAFE_UPDATER_ENABLED) #else /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_FAIL) #endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ }; /** State SecureBootEnabled (12) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_SecureBootEnabled[] = { /* Configuration switch: * IF Secure Boot is enabled GOTO CheckKeyAvailability * ELSE skip this step */ #if defined( FBLBM_ENABLE_SECURE_BOOT ) FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_CHECK_KEY_AVAILABILITY) #else FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_CHECK_EARLY_FBL_SEGMENTS) #endif }; /** State CheckKeyAvailability (13) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckKeyAvailability[] = { /* Check if a Key is already available. If not, FBL shall be called to initialize the key. */ FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckKeyAvailability, FBLBM_STATE_INIT_FBL_MAC_ENABLED), FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_CALL_FBL_INIT_KEY) }; /** State CallFblInitKey (14) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CallFblInitKey[] = { /* Call FBL to initialize key */ #if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY) FBL_FSM_TRIGGER_ENTRY(FblBmState_CallFblInitKey_Entry), #endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY */ FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) }; /** State InitFblCmacEnabled (15) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_InitFblMacEnabled[] = { /* Configuration switch: * IF Secure Boot is enabled GOTO CheckFblMacErased * ELSE skip this step */ #if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_CHECK_FBL_MAC_ERASED) #else /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_CHECK_EARLY_FBL_SEGMENTS) #endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ }; /** State CheckFblMacErased (16) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckFblMacErased[] = { /* Check if a CMAC is available. If not, the FBL is probably written with a debugger and the CMAC area is in erased state. FBL shall be called to initialize the CMAC. */ #if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckFblMacErased, FBLBM_STATE_CALL_FBL_INIT_CMAC), FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_CHECK_EARLY_FBL_SEGMENTS) #else /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_FAIL) #endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ }; /** State CallFblInitCmac (17) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CallFblInitCmac[] = { /* Call FBL and set Magicflag to make it init its CMAC. Shall be used only for debugging. */ #if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) FBL_FSM_TRIGGER_ENTRY(FblBmState_CallFblInitCmac_Entry), #endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) }; /** State StayInBootEnabled (18) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_StayInBootEnabled[] = { /* Configuration Switch: If Stay in Boot is enabled, ApplStartMagicFlag must be evaluated to decide * if the application shall be started. Otherwise this can be skipped. */ #if defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT) FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_CHECK_APPL_START_FLAG) #else /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_CHECK_FBL_LBT) #endif /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ }; /** State CheckApplStartFlag (19) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckApplStartFlag[] = { /* Evaluate ApplStartMagicFlag to decide if the application shall be started. */ #if defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT ) FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckApplStartFlag, FBLBM_STATE_CHECK_FBL_LBT), FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_CHECK_FBL_VERIFICATION_STAY_IN_BOOT) #else /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_FAIL) #endif /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ }; /** State CheckFblLbt (20) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckFblLbt[] = { /* Check validity and verification of FBL-LBT * If it can't be verified/validated, something went wrong: The FBL (which contains the FBL-LBT) is valid but * the LBT is not verified/valid => Fail */ FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckFblLbt, FBLBM_STATE_REPROG_LBT_ENABLED), FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) }; /** State CheckReprogFlag (21) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckReprogFlag[] = { /* Check if Reprogramming Flag is set. If so, check if FBL is valid. */ FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckReprogFlag, FBLBM_STATE_CHECK_LATE_FBL_SEGMENTS), FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_STAY_IN_BOOT_ENABLED) }; /** State ReprogLbtEnable (22) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_ReprogLbtEnabled[] = { /* Configuration Switch: If a reprogrammable LBT is used... */ #if defined( FBL_LBT_ENABLE_REPROGRAMMABLE_LBT ) FBL_FSM_TRIGGER_UNCONDITIONAL( FBLBM_STATE_CHECK_REPROG_LBT), #else /* FBL_LBT_ENABLE_REPROGRAMMABLE_LBT */ FBL_FSM_TRIGGER_UNCONDITIONAL( FBLBM_STATE_TARGET_LIST_INIT) #endif /* FBL_LBT_ENABLE_REPROGRAMMABLE_LBT */ }; /** State CheckReprogLbt (23) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckReprogLbt[] = { /* Check validity/verification of the reprogrammable LBT. If it is not usable, the application can not be found. * Therefore the FBL is called as a fallback. */ #if defined( FBL_LBT_ENABLE_REPROGRAMMABLE_LBT ) FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckReprogLbt, FBLBM_STATE_TARGET_LIST_INIT), FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_CHECK_LATE_FBL_SEGMENTS) #else /* FBL_LBT_ENABLE_REPROGRAMMABLE_LBT */ FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_FAIL) #endif /* FBL_LBT_ENABLE_REPROGRAMMABLE_LBT */ }; /** State TargetListInit (24) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_TargetListInit[] = { /* Prepare searching the target list */ #if ( FBLBM_BOOTTARGETLIST_SIZE > 0u ) FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_TargetListInit, FBLBM_STATE_TARGET_CHECK), FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) #else /* FBLBM_BOOTTARGETLIST_SIZE == 0u */ FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_CHECK_LATE_FBL_SEGMENTS) #endif /* FBLBM_BOOTTARGETLIST_SIZE == 0u */ }; /** State TargetCheck (25) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_TargetCheck[] = { /* Check one entry of the target list. If all conditions match, call the target. * Otherwise go to "Next" */ #if ( FBLBM_BOOTTARGETLIST_SIZE > 0u ) FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_TargetCheck, FBLBM_STATE_CALL_TARGET), FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_TARGET_LIST_NEXT) #else /* FBLBM_BOOTTARGETLIST_SIZE == 0u */ FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_FAIL) #endif /* FBLBM_BOOTTARGETLIST_SIZE == 0u */ }; /** State TargetListNext (26) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_TargetListNext[] = { /* Get next element form target list */ #if ( FBLBM_BOOTTARGETLIST_SIZE > 0u ) FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_TargetListNext, FBLBM_STATE_TARGET_CHECK), FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_CHECK_LATE_FBL_SEGMENTS) #else /* FBLBM_BOOTTARGETLIST_SIZE == 0u */ FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_FAIL) #endif /* FBLBM_BOOTTARGETLIST_SIZE == 0u */ }; /** State CallTarget (27) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CallTarget[] = { /* Start the application/updater */ #if ( FBLBM_BOOTTARGETLIST_SIZE > 0u ) FBL_FSM_TRIGGER_ENTRY(FblBmState_CallTarget_Entry), #endif /* FBLBM_BOOTTARGETLIST_SIZE > 0u */ FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) }; /** State CheckLateFblSegments (28) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckLateFblSegments[] = { /* If verification (CMAC) of FBL is successful, call it. Otherwise go to Fail state */ FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckLateFblSegments, FBLBM_STATE_CALL_FBL), FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) }; /** State CheckFblVerificationStayInBoot (29) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckFblVerificationStayInBoot[] = { /* If verification (CMAC) of FBL is successful, call it. Otherwise go to Fail state */ FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckLateFblSegments, FBLBM_STATE_CALL_FBL_STAY_IN_BOOT), FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) }; /** State CallFbl (30) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CallFbl[] = { /* Start FBL */ FBL_FSM_TRIGGER_ENTRY(FblBmState_CallFbl_Entry), FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) }; /** State CallFblStayInBoot (31) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CallFblStayInBoot[] = { /* Start FBL (StayInBoot)*/ #if defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT) FBL_FSM_TRIGGER_ENTRY(FblBmState_CallFblStayInBoot_Entry), #endif /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) }; /** State CheckEarlyFblSegments (32) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_CheckEarlyFblSegments[] = { /* Check if FBL-Segments are valid. */ #if defined( FBLBM_ENABLE_SECURE_BOOT ) FBL_FSM_TRIGGER_TRANSITION_ACTION(FBLBM_EVENT_CONTINUE, FblBmState_CheckEarlyFblSegments, FBLBM_STATE_CHECK_REPROG_FLAG), FBL_FSM_TRIGGER_TRANSITION(FBLBM_EVENT_CONTINUE, FBLBM_STATE_FAIL) #else /* FBLBM_ENABLE_SECURE_BOOT */ FBL_FSM_TRIGGER_UNCONDITIONAL(FBLBM_STATE_CHECK_REPROG_FLAG) #endif /* FBLBM_ENABLE_SECURE_BOOT */ }; /** State Fail (33) */ V_MEMROM0 static V_MEMROM1 tFblFsmEventEntry V_MEMROM2 g_BmState_Fail[] = { /* Fail State */ FBL_FSM_TRIGGER_ENTRY(FblBmState_Fail_Entry) }; /** List of all States */ V_MEMROM0 static V_MEMROM1 tFblFsmStateDefinition V_MEMROM2 bmFsmStates[] = /* PRQA S 3218 */ /* MD_FBL_3218_FileScopeStatic */ { { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_PowerOn) }, /* 0 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_Init) }, /* 1 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckFblValidity) }, /* 2 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_FailsafeUpdaterEnabled) }, /* 3 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_FailsafeUpdaterSearchInit) }, /* 4 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_FailsafeUpdaterCheck) }, /* 5 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_FailsafeUpdaterSearchNext) }, /* 6 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_FailsafeUpdaterUserCheck ) }, /* 7 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CallFailsafeUpdater) }, /* 8 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckSignedPresPattKeyAvailability) }, /* 9 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CallFblInitKeySignedPresPatt) }, /* 10 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckSignedPresPattValidity) }, /* 11 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_SecureBootEnabled) }, /* 12 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckKeyAvailability) }, /* 13 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CallFblInitKey) }, /* 14 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_InitFblMacEnabled) }, /* 15 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckFblMacErased) }, /* 16 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CallFblInitCmac) }, /* 17 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_StayInBootEnabled) }, /* 18 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckApplStartFlag) }, /* 19 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckFblLbt) }, /* 20 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckReprogFlag) }, /* 21 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_ReprogLbtEnabled) }, /* 22 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckReprogLbt) }, /* 23 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_TargetListInit) }, /* 24 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_TargetCheck) }, /* 25 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_TargetListNext) }, /* 26 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CallTarget) }, /* 27 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckLateFblSegments) }, /* 28 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckFblVerificationStayInBoot) }, /* 29 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CallFbl) }, /* 30 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CallFblStayInBoot) }, /* 31 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_CheckEarlyFblSegments) }, /* 32 */ { FBL_FSM_DEFAULT_STATE, FBLBM_SIZE_AND_ARRAY(g_BmState_Fail) } /* 33 */ }; #define FBLBM_STOP_SEC_CONST #include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ /*********************************************************************************************************************** * LOCAL FUNCTIONS **********************************************************************************************************************/ #define FBLBM_START_SEC_CODE #include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ /********************************************************************************************************************** * FblBmState_PowerOn_Entry *********************************************************************************************************************/ /*! \brief Called directly on PowerOn * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_PowerOn_Entry(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif g_BmError = FBLBM_ERROR_NO_ERROR; FBLBM_CALLOUT_POWER_ON_PRE_HW(); FBLBM_CALLOUT_POWER_ON_PRE_OEM(); FBLBM_CALLOUT_POWER_ON_PRE(); #if !defined( FBLBM_MAIN_ENABLE_INTERRUPT_DISABLE_AT_POWER_ON ) /* Disable global interrupt handling */ FblInterruptDisable(); /* PRQA S 1006 */ /* MD_FblBmMain_1006 */ #endif /* FBLBM_MAIN_ENABLE_INTERRUPT_DISABLE_AT_POWER_ON */ #if defined( FBLBM_MAIN_ENABLE_VTT_USECASE ) #else /* Check if bootmanager header address is correctly configured in generation tool */ /* PRQA S 0306 1 */ /* MD_FblBmMain_0306_FblBmHeader */ assertFblGen(FblBmHeaderLocal == FblBmHeaderTable, kFblSysAssertParameterOutOfRange); #endif /* FBL_MAIN_ENABLE_VTT_USECASE */ /* Power on initialization of core modules */ ClrWDInit(); MemDriver_InitPowerOn(); #if !defined( FBLBM_ENABLE_STANDALONE_MODE ) /* Initialize states of diagnostic layer */ FblDiagInitPowerOn(); #endif /* Initialize intermediate access layer for LBT */ FblLbtInitPowerOn(); #if defined( FBLBM_MAIN_ENABLE_HARDWARE_SWAP ) /* Initialize hardware swap module */ FblSwapInitPowerOn(); #endif /* Initialization callout */ FBLBM_CALLOUT_POWER_ON_POST_HW(); FBLBM_CALLOUT_POWER_ON_POST_OEM(); FBLBM_CALLOUT_POWER_ON_POST(); return kFblFsmGuard_True; } /********************************************************************************************************************** * FblBmState_Init_Entry *********************************************************************************************************************/ /*! \brief Called as a 2nd step after PowerOn * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_Init_Entry(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif /* Early initialization callout */ FBLBM_CALLOUT_INIT_PRE_HW(); FBLBM_CALLOUT_INIT_PRE_OEM(); FBLBM_CALLOUT_INIT_PRE(); /* Initialize and activate watchdog */ FblInitWatchdog(); /* Initialize Timer */ FblTimerInit(); #if defined( FBLBM_ENABLE_STANDALONE_MODE ) EcuM_StartupTwo(); #else /* EcuM_StartupTwo is called by Bootloader * Modules which should be already available in the Bootmanager should be placed in INIT_ZERO or INIT_ONE phase */ #endif #if defined( FBLBM_ENABLE_SECURE_BOOT ) /* Initializes SecureBoot */ FblSb_Init(); #endif /* FBLBM_ENABLE_SECURE_BOOT */ #if defined( FBLBM_MAIN_ENABLE_HARDWARE_SWAP ) /* Execute the flash partition swap */ (void)FblSwapActivate(); #endif /* FBLBM_MAIN_ENABLE_HARDWARE_SWAP */ /* Late initialization callout */ FBLBM_CALLOUT_INIT_POST_HW(); FBLBM_CALLOUT_INIT_POST_OEM(); FBLBM_CALLOUT_INIT_POST(); return kFblFsmGuard_True; } #if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) || defined( FBLBM_ENABLE_UPDATER_FAILSAFE_USER ) /********************************************************************************************************************** * FblBmState_CallFailsafeUpdater_Entry *********************************************************************************************************************/ /*! \brief Call a failsafe updater * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_CallFailsafeUpdater_Entry(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif /* Disable Timer etc. */ FblBmDeinit(); /* PRQA S 2987 */ /* MD_FBL_2987_RedundantCode */ /* Call Failsafe Updater */ FBLBM_CALLOUT_CALL_FAILSAFE_UPDATER(&g_BmFailsafeUpdaterBmHeader); /* This code is never reached */ return kFblFsmGuard_True; } #endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ #if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY ) /********************************************************************************************************************** * FblBmState_CallFblInitKey_Entry *********************************************************************************************************************/ /*! \brief Call the FBL and set a magic flag to direct him to init the missing key * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) * \config FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_CallFblInitKey_Entry(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif /* Disable Timer etc. */ FblBmDeinit(); /* PRQA S 2987 */ /* MD_FBL_2987_RedundantCode */ FblBmSetInitKeysMagicFlag(); /* Call Fbl */ FBLBM_CALLOUT_CALL_FBL_INIT_KEYS(&fblBmBlockInfo.bmHeader); /* This code is never reached */ return kFblFsmGuard_True; } #endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY */ #if ( FBLBM_BOOTTARGETLIST_SIZE > 0u ) /********************************************************************************************************************** * FblBmState_CallTarget_Entry *********************************************************************************************************************/ /*! \brief Call a target (Application, Updater) * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_CallTarget_Entry(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { # if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; # endif /* Disable Timer etc. */ FblBmDeinit(); /* PRQA S 2987 */ /* MD_FBL_2987_RedundantCode */ /* Call Appl */ FBLBM_CALLOUT_CALL_TARGET(&g_BmTargetBmHeader); /* This code is never reached */ return kFblFsmGuard_True; } #endif/* FBLBM_BOOTTARGETLIST_SIZE > 0u */ #if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) /********************************************************************************************************************** * FblBmState_CallFblInitCmac_Entry *********************************************************************************************************************/ /*! \brief Call the FBL to initialize the FBL-CMAC(s) * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) * \config FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_CallFblInitCmac_Entry(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif /* Disable Timer etc. */ FblBmDeinit(); /* PRQA S 2987 */ /* MD_FBL_2987_RedundantCode */ FblBmSetInitCmacMagicFlag(); /* Call Fbl */ FBLBM_CALLOUT_CALL_FBL_INIT_CMAC(&fblBmBlockInfo.bmHeader); /* This code is never reached */ return kFblFsmGuard_True; } #endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ /********************************************************************************************************************** * FblBmState_CallFbl_Entry *********************************************************************************************************************/ /*! \brief Start the FBL * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_CallFbl_Entry(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif /* Disable Timer etc. */ FblBmDeinit(); /* PRQA S 2987 */ /* MD_FBL_2987_RedundantCode */ /* Call Fbl */ FBLBM_CALLOUT_CALL_FBL(&fblBmBlockInfo.bmHeader); /* This code is never reached */ return kFblFsmGuard_True; } # if defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT ) /********************************************************************************************************************** * FblBmState_CallFblStayInBoot_Entry *********************************************************************************************************************/ /*! \brief Start the FBL and set the magic flag that to check for a stay in boot message * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_CallFblStayInBoot_Entry(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif /* Disable Timer etc. */ FblBmDeinit(); /* PRQA S 2987 */ /* MD_FBL_2987_RedundantCode */ FblBmSetStayInBootMagicFlag(); /* Call Fbl */ FBLBM_CALLOUT_CALL_FBL(&fblBmBlockInfo.bmHeader); /* This code is never reached */ return kFblFsmGuard_True; } #endif /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ #if defined( FBLBM_ENABLE_SECURE_BOOT ) /********************************************************************************************************************** * FblBmState_CheckEarlyFblSegments *********************************************************************************************************************/ /*! \brief Start Early check of FBL segments. * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_CheckEarlyFblSegments(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { tFblFsmGuard result = kFblFsmGuard_True; # if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; # endif # if defined( FBLBM_ENABLE_EARLY_FBL_SEGMENTS_CHECK ) if (kFblOk != FblSb_VerifySegments(&fblBmBlockInfo.bmHeader)) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_FBL_VERIFICATION_FAILED; } # endif /* FBLBM_ENABLE_EARLY_FBL_SEGMENTS_CHECK */ return result; } #endif /* FBLBM_ENABLE_SECURE_BOOT */ /********************************************************************************************************************** * FblBmState_Fail_Entry *********************************************************************************************************************/ /*! \brief An error has happened. * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_Fail_Entry(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif FBLBM_CALLOUT_FATAL_ERROR(g_BmError); return kFblFsmGuard_False; } /********************************************************************************************************************** * FblBmCheckFblValidity *********************************************************************************************************************/ /*! \brief Checks the Header and the validity (e.g.: Presence Pattern) of the FBL * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_CheckFblValidity(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { tFblFsmGuard result; #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif result = kFblFsmGuard_True; #if defined( FBLBM_ENABLE_STANDALONE_MODE ) /* Read FBL header from configured memory location */ if (FblReadProm(FblBmHeader.fblHeaderAddress, (vuint8*) &fblBmFblHeader, sizeof(tFblHeader)) != sizeof(tFblHeader)) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_HEADER_READ_FAILED; } /* Check magic flag of the FBL header */ if (kFblFsmGuard_True == result) { if (fblBmFblHeader.magicFlag != FBL_MAIN_HEADER_MAGIC_FLAG) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_HEADER_MAGIC_FAILED; } } if (kFblFsmGuard_True == result) { /* Fill out the block descriptor for the FBL */ fblBmBlockInfo.logicalBlock.blockStartAddress = fblBmFblHeader.fblStartAddress; fblBmBlockInfo.logicalBlock.blockLength = fblBmFblHeader.fblLength; fblBmBlockInfo.logicalBlock.bmHeaderAddress = (tFblAddress) fblBmFblHeader.bmHeader; /* PRQA S 0306 */ /* MD_FblBmMain_0306 */ fblBmBlockInfo.logicalBlock.mandatoryType = TRUE; fblBmBlockInfo.logicalBlock.blockNr = 0x00u; # if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) /* Check if Presence Pattern is valid */ if (kFblOk != FBLBM_CALLOUT_IS_VALIDPATTERN(FBLBMHDR_TARGET_FBL, &fblBmBlockInfo.logicalBlock)) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_VALIDITY_FAILED; } # else /* Check if FBL is valid (e.g.: evaluate Presence Pattern) */ if (kFblOk != FBLBM_CALLOUT_IS_VALIDBLOCK(FBLBMHDR_TARGET_FBL, &fblBmBlockInfo.logicalBlock)) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_VALIDITY_FAILED; } # endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ } #else /* Fill out the block descriptor for the FBL */ fblBmBlockInfo.logicalBlock.blockStartAddress = FblHeader.fblStartAddress; fblBmBlockInfo.logicalBlock.blockLength = FblHeader.fblLength; fblBmBlockInfo.logicalBlock.bmHeaderAddress = (tFblAddress) FblHeader.bmHeader; /* PRQA S 0306 */ /* MD_FblBmMain_0306 */ fblBmBlockInfo.logicalBlock.mandatoryType = TRUE; fblBmBlockInfo.logicalBlock.blockNr = 0x00u; #endif /* FBLBM_ENABLE_STANDALONE_MODE */ if (kFblFsmGuard_True == result) /* PRQA S 2991, 2995 */ /* MD_FblBmMain_2991_2995 */ { if (FBLBMHDR_CHKHDR_OK != FblBmHdrGetBmHeader(FBLBMHDR_TARGET_FBL, fblBmBlockInfo.logicalBlock.bmHeaderAddress, &fblBmBlockInfo.bmHeader)) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_FBL_BMHEADER_INCORRECT; } } return result; } #if defined( FBLBM_ENABLE_UPDATER_FAILSAFE ) /********************************************************************************************************************** * FblBmState_FailsafeUpdaterSearchInit *********************************************************************************************************************/ /*! \brief Prepare the search for an failsafe Updater. * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) * \config FBLBM_ENABLE_UPDATER_FAILSAFE *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_FailsafeUpdaterSearchInit(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { tFblFsmGuard result; #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif /* Get BmHeader address from callout. In case FBLBM_ENABLE_UPDATER_FAILSAFE is enabled, callout * FBLBM_CALLOUT_SEARCH_FAILSAFE_UPDATER_NEXT is requested to return the next possible location */ if (kFblOk == FBLBM_CALLOUT_SEARCH_FAILSAFE_UPDATER_INIT()) { result = kFblFsmGuard_True; } else { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_UPDATER_SEARCH_INIT_FAILED; } return result; } /********************************************************************************************************************** * FblBmState_CheckFailsafeUpdater *********************************************************************************************************************/ /*! \brief Check if failsafe updater is valid and can be verified. * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) * \config FBLBM_ENABLE_UPDATER_FAILSAFE *********************************************************************************************************************/ /* PRQA S 3673, 6010, 6030 1 */ /* MD_FBL_3673_PointerToConstParameter, MD_MSR_STPTH, MD_MSR_STCYC */ static tFblFsmGuard FblBmState_FailsafeUpdaterCheck(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { tFblFsmGuard result; tFblBmBlockInfo blockInfo = { 0 }; vuint32 headerAddress; #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif result = kFblFsmGuard_True; if (kFblOk != FBLBM_CALLOUT_SEARCH_FAILSAFE_UPDATER_HEADER_ADDRESS(&headerAddress)) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_UPDATER_HEADER_ADDRESS; } /* Hint: The order of checks is different than checking an application because the FBL-LBT can not be used here */ if (kFblFsmGuard_True == result) { blockInfo.bmHeader.bmTargetHandle = FBLBMHDR_TARGET_FBLUPDATER; blockInfo.bmHeader.bmBlockStartAddress = 0u; blockInfo.bmHeader.bmBlockLength = 1u; blockInfo.bmHeader.bmEntryAddress = 0u; /* Read BM header from flash */ if (FblReadProm(headerAddress, (vuint8 *)&blockInfo.bmHeader, sizeof(tFblBmHdrHeader)) != sizeof(tFblBmHdrHeader)) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_UPDATER_HEADER_READ_ERROR; } } /* Check for correct target handle */ if (kFblFsmGuard_True == result) { if (blockInfo.bmHeader.bmTargetHandle != FBLBMHDR_TARGET_FBLUPDATER) /* PRQA S 2992,2996 */ /* MD_FblBmMain_2880_2992_2996_FlashRead */ { result = kFblFsmGuard_False; /* PRQA S 2880 */ /* MD_FblBmMain_2880_2992_2996_FlashRead */ g_BmError = FBLBM_ERROR_UPDATER_HEADER_TYPE; } } /* Check for consistency errors */ if (kFblFsmGuard_True == result) { if ( kFblOk != FblBmHdrCheckConsistency(&blockInfo.bmHeader)) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_UPDATER_HEADER_CONSISTENCY; } } /* Header seems to be OK, check if block is valid */ if (kFblFsmGuard_True == result) { /* Initialize the logical block structure */ blockInfo.logicalBlock.blockStartAddress = blockInfo.bmHeader.bmBlockStartAddress; blockInfo.logicalBlock.blockLength = blockInfo.bmHeader.bmBlockLength; if (kFblOk != FBLBM_CALLOUT_IS_VALIDBLOCK(blockInfo.bmHeader.bmTargetHandle, &blockInfo.logicalBlock)) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_UPDATER_BLOCK_VALIDITY; } } # if defined( FBLBM_ENABLE_SECURE_BOOT ) # if defined( FBLBM_ENABLE_HEADER_VERIFICATION ) if (kFblFsmGuard_True == result) { # if defined( FBLBM_ENABLE_USE_VERIFY_HEADER_ROM ) if (kFblOk != FblSb_VerifyHeaderRom(headerAddress, &blockInfo.bmHeader)) # else if (kFblOk != FblSb_VerifyHeader(&blockInfo.bmHeader)) # endif /* FBLBM_ENABLE_USE_VERIFY_HEADER_ROM */ { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_UPDATER_HEADER_CMAC_VERIFY; } } # endif /* FBLBM_ENABLE_HEADER_VERIFICATION */ if (kFblFsmGuard_True == result) { if (kFblOk != FblSb_VerifySegments(&blockInfo.bmHeader)) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_UPDATER_VERIFY; } } # endif /* FBLBM_ENABLE_SECURE_BOOT */ if (kFblFsmGuard_True == result) { g_BmFailsafeUpdaterBmHeader = blockInfo.bmHeader; } return result; } /********************************************************************************************************************** * FblBmState_FailsafeUpdaterSearchNext *********************************************************************************************************************/ /*! \brief Get next possible location for a Failsafe Updater BmHeader * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) * \config FBLBM_ENABLE_UPDATER_FAILSAFE *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_FailsafeUpdaterSearchNext(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { tFblFsmGuard result; #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif if (kFblOk == FBLBM_CALLOUT_SEARCH_FAILSAFE_UPDATER_NEXT()) { result = kFblFsmGuard_True; } else { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_UPDATER_SEARCH_NEXT_FINISHED; } return result; } #elif defined( FBLBM_ENABLE_UPDATER_FAILSAFE_USER ) /********************************************************************************************************************** * FblBmState_FailsafeUpdaterUserCheck *********************************************************************************************************************/ /*! \brief Prepare the search for an failsafe Updater. * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) * \config FBLBM_ENABLE_UPDATER_FAILSAFE_USER *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_FailsafeUpdaterUserCheck(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { tFblFsmGuard result = kFblFsmGuard_False; #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif if (FBLBM_CALLOUT_FAILSAFE_UPDATER_USER_CHECK(&g_BmFailsafeUpdaterBmHeader) == kFblOk) { result = kFblFsmGuard_True; } return result; } #endif /* FBLBM_ENABLE_UPDATER_FAILSAFE */ #if defined( FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN ) /********************************************************************************************************************** * FblBmState_CheckSignedPresPattKeyAvailability *********************************************************************************************************************/ /*! \brief Check if Key is available for MAC verification. If not, the FBL is called to initialize PP the key. * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_CheckSignedPresPattKeyAvailability(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { tFblFsmGuard result; #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif if (FBLBM_KEY_IS_NOT_AVAILABLE == FBLBM_CALLOUT_GET_PP_SIGN_KEYEMPTY()) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_KEY_NOT_AVAILABLE; } else { result = kFblFsmGuard_True; } return result; } /********************************************************************************************************************** * FblBmState_CallFblInitKeySignedPresPatt *********************************************************************************************************************/ /*! \brief Call the FBL and set a magic flag to direct him to init the missing signed presence pattern key * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_CallFblInitKeySignedPresPatt(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif /* Disable Timer etc. */ FblBmDeinit(); /* PRQA S 2987 */ /* MD_FBL_2987_RedundantCode */ FblBmSetSignedPPMagicFlag(); /* Call Fbl */ FBLBM_CALLOUT_CALL_FBL_INIT_SIGNED_PRESENCEPATTERN(&fblBmBlockInfo.bmHeader); /* This code is never reached */ return kFblFsmGuard_True; } /********************************************************************************************************************** * FblBmState_CheckSignedPresPattValidity *********************************************************************************************************************/ /*! \brief Checks the Header and the validity (e.g.: signed Presence Pattern) of the FBL * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_CheckSignedPresPattValidity(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { tFblFsmGuard result; #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif result = kFblFsmGuard_True; #if defined( FBLBM_ENABLE_STANDALONE_MODE ) /* Read FBL header from configured memory location */ if (FblReadProm(FblBmHeader.fblHeaderAddress, (vuint8*) &fblBmFblHeader, sizeof(tFblHeader)) != sizeof(tFblHeader)) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_HEADER_READ_FAILED; } /* Check magic flag of the FBL header */ if (kFblFsmGuard_True == result) { if (fblBmFblHeader.magicFlag != FBL_MAIN_HEADER_MAGIC_FLAG) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_HEADER_MAGIC_FAILED; } } if (kFblFsmGuard_True == result) { /* Fill out the block descriptor for the FBL */ fblBmBlockInfo.logicalBlock.blockStartAddress = fblBmFblHeader.fblStartAddress; fblBmBlockInfo.logicalBlock.blockLength = fblBmFblHeader.fblLength; fblBmBlockInfo.logicalBlock.bmHeaderAddress = (tFblAddress) fblBmFblHeader.bmHeader; /* PRQA S 0306 */ /* MD_FblBmMain_0306 */ fblBmBlockInfo.logicalBlock.mandatoryType = TRUE; fblBmBlockInfo.logicalBlock.blockNr = 0x00u; /* Check if FBL is valid (e.g.: evaluate Presence Pattern) */ if (kFblOk != FBLBM_CALLOUT_IS_VALIDBLOCK(FBLBMHDR_TARGET_FBL, &fblBmBlockInfo.logicalBlock)) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_VALIDITY_FAILED; } } #else /* Fill out the block descriptor for the FBL */ fblBmBlockInfo.logicalBlock.blockStartAddress = FblHeader.fblStartAddress; fblBmBlockInfo.logicalBlock.blockLength = FblHeader.fblLength; fblBmBlockInfo.logicalBlock.bmHeaderAddress = (tFblAddress) FblHeader.bmHeader; /* PRQA S 0306 */ /* MD_FblBmMain_0306 */ fblBmBlockInfo.logicalBlock.mandatoryType = TRUE; fblBmBlockInfo.logicalBlock.blockNr = 0x00u; #endif /* FBLBM_ENABLE_STANDALONE_MODE */ if (kFblFsmGuard_True == result) /* PRQA S 2991, 2995 */ /* MD_FblBmMain_2991_2995 */ { if (FBLBMHDR_CHKHDR_OK != FblBmHdrGetBmHeader(FBLBMHDR_TARGET_FBL, fblBmBlockInfo.logicalBlock.bmHeaderAddress, &fblBmBlockInfo.bmHeader)) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_FBL_BMHEADER_INCORRECT; } } return result; } #endif /* FBLNVPATTERN_ENABLE_SIGN_PRESENCE_PATTERN */ /********************************************************************************************************************** * FblBmState_CheckKeyAvailability *********************************************************************************************************************/ /*! \brief Check if Key is available for MAC verification. If not, the FBL is called to initialize the key. * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_CheckKeyAvailability(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { tFblFsmGuard result; #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif #if defined( FBLBM_ENABLE_SECURE_BOOT ) && \ defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_KEY ) if (FBLBM_KEY_IS_NOT_AVAILABLE == FBLBM_CALLOUT_GET_KEYEMPTY()) { /* Key is not available */ result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_KEY_NOT_AVAILABLE; } else { result = kFblFsmGuard_True; } #else /* No key needed or not configured to be checked, return OK to proceed */ result = kFblFsmGuard_True; #endif return result; } #if defined( FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC ) /********************************************************************************************************************** * FblBmState_CheckFblMacErased *********************************************************************************************************************/ /*! \brief Check if a CMAC (even an invalid one) is written for the FBL - if not call FBL to write a CMAC. * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) * \config FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_CheckFblMacErased(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { tFblFsmGuard result; #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif if (FBLBM_MAC_IS_AVAILABLE == FBLBM_CALLOUT_GET_FBL_CMACERASED(&fblBmBlockInfo)) { /* FBL-CMAC is already written */ result = kFblFsmGuard_False; } else { /* FBL-CMAC is not yet written */ result = kFblFsmGuard_True; } return result; } #endif /* FBLBM_ENABLE_SECBOOT_FBL_INIT_MAC */ #if defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT ) /********************************************************************************************************************** * FblBmState_CheckApplStartFlag *********************************************************************************************************************/ /*! \brief Check if the ApplStart flag is set * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) * \config FBLBM_MAIN_ENABLE_STAY_IN_BOOT *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_CheckApplStartFlag( tFblFsmContextPtr const pFsmContext, tFblFsmEvent event ) { tFblFsmGuard result; #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif if (FblBmChkApplStartMagicFlag()) { FblBmClrMagicFlag(); result = kFblFsmGuard_True; } else { result = kFblFsmGuard_False; } return result; } #endif /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ /********************************************************************************************************************** * FblBmState_CheckReprogFlag *********************************************************************************************************************/ /*! \brief Check if Reprogramming Flag is set * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) * \config FBL_DISABLE_STAY_IN_BOOT *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_CheckReprogFlag(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { tFblFsmGuard result; #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif /* Check if there is a reprogramming request (e.g. UDS, XCP, MCMP, OTA) */ if (FBLBM_CALLOUT_CHECKREPROGFLAG() == kFblOk) { /* Do not clear flag, as the Bootloader requires it as well */ result = kFblFsmGuard_True; } else { result = kFblFsmGuard_False; } return result; } /********************************************************************************************************************** * FblBmState_CheckFblLbt *********************************************************************************************************************/ /*! \brief Check the validity and verification of the FBL-LBT and / or FblBmHeader * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) *********************************************************************************************************************/ /* PRQA S 3673, 6010 1 */ /* MD_FBL_3673_PointerToConstParameter, MD_MSR_STPTH */ static tFblFsmGuard FblBmState_CheckFblLbt(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { #if defined( FBLBM_ENABLE_STANDALONE_MODE ) tFblFsmGuard result = kFblFsmGuard_True; # if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; # endif # if defined( FBLBM_ENABLE_SECURE_BOOT ) # if defined( FBLBM_ENABLE_HEADER_VERIFICATION ) # if defined( FBLBM_ENABLE_USE_VERIFY_HEADER_ROM ) if (kFblOk != FblSb_VerifyHeaderRom(fblBmBlockInfo.logicalBlock.bmHeaderAddress, &fblBmBlockInfo.bmHeader)) # else if (kFblOk != FblSb_VerifyHeader(&fblBmBlockInfo.bmHeader)) # endif /* FBLBM_ENABLE_USE_VERIFY_HEADER_ROM */ { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_FBL_BMHEADER_VERIFICATION_FAILED; } if (kFblFsmGuard_False != result) # endif /* FBLBM_ENABLE_HEADER_VERIFICATION */ { # if defined( FBLBM_ENABLE_FBLLBT_VERIFICATION ) if (kFblOk != FblSb_VerifyFblLbt(&fblBmFblHeader)) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_LBT_VERIFY; } else # endif /* FBLBM_ENABLE_FBLLBT_VERIFICATION */ # else /* FBLBM_ENABLE_SECURE_BOOT */ { # endif /* FBLBM_ENABLE_SECURE_BOOT */ { /* Validation of FBL-LBT successful: Use Fbl-LBT */ FblLbtActivateLbtBlockByAddress((tFblAddress)fblBmFblHeader.pLogicalBlockTable); /* PRQA S 0306 */ /* MD_FblBmMain_0306 */ /* Consistency check (BM-LBT <-> FBL-LBT) */ /* Check if block count exceeds built-in maximum value */ if (FblLbtGetBlockCount() > FBL_LBT_BLOCK_COUNT) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_LBT_TOO_LARGE; } else { result = kFblFsmGuard_True; } } } if (kFblFsmGuard_True != result) { /* Failure - switch back to internal LBT */ FblLbtInitPowerOn(); } return result; #else # if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; # endif return kFblFsmGuard_True; #endif /* FBLBM_ENABLE_STANDALONE_MODE */ } #if defined( FBL_LBT_ENABLE_REPROGRAMMABLE_LBT ) /********************************************************************************************************************** * FblBmState_CheckReprogLbt *********************************************************************************************************************/ /*! \brief Check if a Reprogrammable LBT is available. If so, use it. * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) * \config FBL_LBT_ENABLE_REPROGRAMMABLE_LBT *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_CheckReprogLbt( tFblFsmContextPtr const pFsmContext, tFblFsmEvent event ) { tFblFsmGuard result; tFblBmBlockInfo blockInfo; #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif result = kFblFsmGuard_True; /* Get Reprog-LBT from FBL-LBT */ if (kFblOk != FblLbtGetBlockDescriptorByNr(FBL_LBT_LBT_BLOCK_NUMBER, &blockInfo.logicalBlock)) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_REPROG_LBT_DESCR; } if (kFblFsmGuard_True == result) { if (kFblOk != FBLBM_CALLOUT_IS_VALIDBLOCK(FBLBMHDR_TARGET_REPROGLBT, &blockInfo.logicalBlock)) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_REPROG_LBT_INVALID; } } if (kFblFsmGuard_True == result) { if (FBLBMHDR_CHKHDR_OK != FblBmHdrGetBmHeader(FBLBMHDR_TARGET_REPROGLBT, blockInfo.logicalBlock.bmHeaderAddress, &blockInfo.bmHeader)) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_REPROG_LBT_BMHEADER_INCORRECT; } } # if defined( FBLBM_ENABLE_SECURE_BOOT ) # if defined( FBLBM_ENABLE_HEADER_VERIFICATION ) if (kFblFsmGuard_True == result) { # if defined( FBLBM_ENABLE_USE_VERIFY_HEADER_ROM ) if (kFblOk != FblSb_VerifyHeaderRom(blockInfo.logicalBlock.bmHeaderAddress, &blockInfo.bmHeader)) # else if (kFblOk != FblSb_VerifyHeader(&blockInfo.bmHeader)) # endif /* FBLBM_ENABLE_USE_VERIFY_HEADER_ROM */ { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_REPROG_LBT_VERIFY_HEADER; } } # endif/* FBLBM_ENABLE_HEADER_VERIFICATION */ if (kFblFsmGuard_True == result) { if (kFblOk != FblSb_VerifySegments(&blockInfo.bmHeader)) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_REPROG_LBT_VERIFY_SEGMENTS; } } # endif /* FBLBM_ENABLE_SECURE_BOOT */ if (kFblFsmGuard_True == result) { tFblLbtMagicFlag originalMagicFlag = FblLbtGetMagicFlag(); FblLbtActivateLbtBlockByAddress(blockInfo.logicalBlock.blockStartAddress); if (originalMagicFlag != FblLbtGetMagicFlag()) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_REPROG_LBT_MAGIC_FLAG; } else if (FblLbtGetBlockCount() > FBL_LBT_BLOCK_COUNT) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_REPROG_LBT_BLOCK_COUNT; } else { /* Nothing to do */ } if (kFblFsmGuard_True != result) { # if defined( FBLBM_ENABLE_STANDALONE_MODE ) /* Use LBT from FblHeader, if this point is reached it was already verified and checked for consistency */ FblLbtActivateLbtBlockByAddress((tFblAddress)fblBmFblHeader.pLogicalBlockTable); # else /* FBLBM_ENABLE_STANDALONE_MODE */ FblLbtInitPowerOn(); # endif /* FBLBM_ENABLE_STANDALONE_MODE */ } } return result; } #endif /* FBL_LBT_ENABLE_REPROGRAMMABLE_LBT */ #if ( FBLBM_BOOTTARGETLIST_SIZE > 0u ) /********************************************************************************************************************** * FblBmState_TargetListInit *********************************************************************************************************************/ /*! \brief Prepare target list search. Get target list via callout * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_TargetListInit(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { tFblFsmGuard result; #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif g_BmTargetListIndex = 0u; result = kFblFsmGuard_True; return result; } /********************************************************************************************************************** * FblBmState_TargetCheck *********************************************************************************************************************/ /*! \brief Check validity and verification of a target and all its dependencies * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) *********************************************************************************************************************/ /* PRQA S 3673, 6010, 6030, 6080 1 */ /* MD_FBL_3673_PointerToConstParameter, MD_MSR_STPTH, MD_MSR_STCYC, MD_MSR_STMIF */ static tFblFsmGuard FblBmState_TargetCheck(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { #if defined( FBLBM_ENABLE_SECURE_BOOT ) tFblResult fblSbResult; #endif /* FBLBM_ENABLE_SECURE_BOOT */ tFblFsmGuard result; tFblBmHdrTargetListEntry target; tFblBmHdrTargetHandle targetHandle; tFblBmBlockInfo blockInfoTarget = { 0 }; tFblBmBlockInfo blockInfoDep; vuintx index; tFblBmHdrCheckBmHeaderResult findHeaderResult; #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif target = FblBm_BootTargetList[g_BmTargetListIndex]; targetHandle = target.target; result = kFblFsmGuard_True; /* Check Application validity */ if (kFblOk != FBLBM_CALLOUT_CHECK_TARGET_VALIDITY(targetHandle)) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_TARGET_INVALID; } if (kFblFsmGuard_True == result) { if (FBLBMHDR_CHKHDR_OK != FblBmHdrFindValidHeader(targetHandle, &blockInfoTarget)) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_TARGET_NO_VALID_HEADER; } } #if defined( FBLBM_ENABLE_SECURE_BOOT ) if (kFblFsmGuard_True == result) { # if defined( FBLBM_ENABLE_HEADER_VERIFICATION ) # if defined( FBLBM_ENABLE_USE_VERIFY_HEADER_ROM ) fblSbResult = FblSb_VerifyHeaderRom(blockInfoTarget.logicalBlock.bmHeaderAddress, &blockInfoTarget.bmHeader); # else fblSbResult = FblSb_VerifyHeader(&blockInfoTarget.bmHeader); # endif /* FBLBM_ENABLE_USE_VERIFY_HEADER_ROM */ if (kFblOk == fblSbResult) # endif /* FBLBM_ENABLE_HEADER_VERIFICATION */ { fblSbResult = FblSb_VerifySegments(&blockInfoTarget.bmHeader); } if (kFblOk != fblSbResult) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_TARGET_VERIFICATION_FAILED; } } #endif /* FBLBM_ENABLE_SECURE_BOOT */ if (kFblFsmGuard_True == result) { /* Check all Mandatory dependencies */ for (index = 0u; index < target.dependenciesSize; index++) { targetHandle = target.dependencies[index].target; findHeaderResult = FblBmHdrFindValidHeader(targetHandle, &blockInfoDep); if (FBLBMHDR_CHKHDR_OK == findHeaderResult) { #if defined( FBLBM_ENABLE_SECURE_BOOT ) # if defined( FBLBM_ENABLE_HEADER_VERIFICATION ) # if defined( FBLBM_ENABLE_USE_VERIFY_HEADER_ROM ) fblSbResult = FblSb_VerifyHeaderRom(blockInfoDep.logicalBlock.bmHeaderAddress, &blockInfoDep.bmHeader); # else fblSbResult = FblSb_VerifyHeader(&blockInfoDep.bmHeader); # endif /* FBLBM_ENABLE_USE_VERIFY_HEADER_ROM */ if (kFblOk == fblSbResult) # endif/* FBLBM_ENABLE_HEADER_VERIFICATION */ { fblSbResult = FblSb_VerifySegments(&blockInfoDep.bmHeader); } if (kFblOk != fblSbResult) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_TARGET_DEP_VERIFY_FAILED; } #endif /* FBLBM_ENABLE_SECURE_BOOT */ } else { if (FBLBM_TARGET_TYPE_MANDATORY == target.dependencies[index].type) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_TARGET_DEP_MANDATORY_MISSING; } else { /* Ignore this block, it is optional */ FBLBM_CALLOUT_IS_OPTIONALBLOCK(targetHandle, &blockInfoDep.logicalBlock); } } if (kFblFsmGuard_False == result) { break; } } /* END FOR */ } /* Check if the target address is valid */ if (kFblFsmGuard_True == result) { if (blockInfoTarget.bmHeader.bmEntryAddress == FBLBMHDR_ENTRY_ADDRESS_INVALID) /* PRQA S 2962 */ /* MD_FBL_2962_UninitializedVariable */ { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_TARGET_INVALID_ADDRESS; assertFbl(0u, kFblSysAssertParameterOutOfRange); /* PRQA S 2741, 4558 */ /* MD_FBL_2741_4558_Assert */ } } if (kFblFsmGuard_True == result) { /* Store BmHeader of target */ g_BmTargetBmHeader = blockInfoTarget.bmHeader; } return result; } /********************************************************************************************************************** * FblBmState_TargetListNext *********************************************************************************************************************/ /*! \brief Get next target entry from target list. * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_TargetListNext(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { tFblFsmGuard result; #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif g_BmTargetListIndex++; if (FBLBM_BOOTTARGETLIST_SIZE > g_BmTargetListIndex) { result = kFblFsmGuard_True; } else { /* End of list reached */ result = kFblFsmGuard_False; } return result; } #endif /* FBLBM_BOOTTARGETLIST_SIZE > 0u */ /********************************************************************************************************************** * FblBmState_CheckLateFblSegments *********************************************************************************************************************/ /*! \brief Verify the whole FBL segments. * \param[in] pFsmContext Pointer to context of state machine * \param[in] event Event that caused handler execution * \return - kFblFsmGuard_True if transition to next configured state is allowed, * - kFblFsmGuard_False otherwise (transition prohibited, check further event handlers) *********************************************************************************************************************/ /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ static tFblFsmGuard FblBmState_CheckLateFblSegments(tFblFsmContextPtr const pFsmContext, tFblFsmEvent event) { tFblFsmGuard result; #if defined( V_ENABLE_USE_DUMMY_STATEMENT ) /* Parameters not used: avoid compiler warning */ (void)pFsmContext; (void)event; #endif #if defined( FBLBM_ENABLE_SECURE_BOOT ) # if defined( FBLBM_ENABLE_EARLY_FBL_SEGMENTS_CHECK ) /* Segments are already verified during the Check Early Fbl Segments state */ # else /* FBLBM_ENABLE_EARLY_FBL_SEGMENTS_CHECK */ if (kFblOk != FblSb_VerifySegments(&fblBmBlockInfo.bmHeader)) { result = kFblFsmGuard_False; g_BmError = FBLBM_ERROR_FBL_VERIFICATION_FAILED; } else # endif /* FBLBM_ENABLE_EARLY_FBL_SEGMENTS_CHECK */ #endif /* FBLBM_ENABLE_SECURE_BOOT */ { result = kFblFsmGuard_True; } return result; } /********************************************************************************************************************** * FblBmDeinit *********************************************************************************************************************/ /*! \brief Deinitialize e.g. stop the timer before calling a target. *********************************************************************************************************************/ static void FblBmDeinit(void) { FBLBM_CALLOUT_DEINIT_PRE_OEM(); FBLBM_CALLOUT_DEINIT_PRE_HW(); FBLBM_CALLOUT_DEINIT_PRE(); #if defined( FBL_WATCHDOG_ON ) /* Synchronize watchdog before application start */ ApplFblWDLong(); #endif /* FBL_WATCHDOG_ON */ /* Stop timer to avoid a timer interrupt after application start */ FblTimerStopp(); FBLBM_CALLOUT_DEINIT_POST_OEM(); FBLBM_CALLOUT_DEINIT_POST_HW(); FBLBM_CALLOUT_DEINIT_POST(); } /*********************************************************************************************************************** * GLOBAL FUNCTIONS **********************************************************************************************************************/ /*-- Bootmanager helper functions ----------------------------------------------------------------------------------------*/ #if defined( FBLBM_ENABLE_STANDALONE_MODE ) /*********************************************************************************************************************** * FblMemSetInteger **********************************************************************************************************************/ /*! \brief Convert given integer value to big-endian byte array * \param[in] count Number of relevant bytes * \param[in] input Input value * \param[out] buffer Pointer to output buffer **********************************************************************************************************************/ void FblMemSetInteger( vuintx count, vuint32 input, tFblMemRamData buffer) { vuint32 localInput = input; vuintx localCount = count; /* Integer to array conversion only supported for up to 32-bit values */ assertFblInternal(count <= sizeof(vuint32), kFblSysAssertParameterOutOfRange); /* Loop relevant bytes */ while (localCount > 0u) { localCount--; /* Store most significant byte first */ buffer[localCount] = (vuint8) (localInput & 0xFFu); /* Shift in next byte */ localInput >>= 8u; } } /*********************************************************************************************************************** * FblMemGetInteger **********************************************************************************************************************/ /*! \brief Convert given big-endian byte array to integer value * \param[in] count Number of relevant bytes * \param[in] buffer Pointer to input buffer * \return Integer value **********************************************************************************************************************/ vuint32 FblMemGetInteger( vuintx count, tFblMemConstRamData buffer) { vuint32 output = 0u; vuintx idx = 0u; vuintx localCount = count; /* Array to integer conversion only supported for up to 32-bit values */ assertFblInternal(count <= sizeof(vuint32), kFblSysAssertParameterOutOfRange); /* Loop relevant bytes */ while (localCount > 0u) { /* Most significant byte first */ output <<= 8u; /* Add current byte */ output |= (vuint32)buffer[idx]; idx++; localCount--; } return output; } #endif /* FBLBM_ENABLE_STANDALONE_MODE */ /*-- Main functions --------------------------------------------------------------------------------------------------*/ /*********************************************************************************************************************** * FblMain **********************************************************************************************************************/ /*! \brief Initializes the system and runs the bootmanager. **********************************************************************************************************************/ /* PRQA S 5209 1 */ /* MD_FblBmMain_5209_Main */ void V_API_NEAR FblMain(void) { /* Initialize state machine */ FblFsmInitPowerOn(); /* Start State Machine */ g_BmFsmContext.stateDefinitions = bmFsmStates; g_BmFsmContext.stateCount = FBLBM_ARRAY_SIZE(bmFsmStates); FblFsmInit(&g_BmFsmContext, (tFblFsmState) FBLBM_STATE_POWER_ON); while (g_BmFsmContext.state != (tFblFsmState) FBLBM_STATE_FAIL) { /* Request next step */ FblFsmTriggerEvent(&g_BmFsmContext, (tFblFsmEvent) FBLBM_EVENT_CONTINUE); FblFsmStateTask(&g_BmFsmContext); } FBLBM_CALLOUT_FATAL_ERROR(FBLBM_ERROR_END_OF_MAIN_REACHED); } #define FBLBM_STOP_SEC_CODE #include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ #if defined( FBLBM_MAIN_ENABLE_FBL_START ) # define FBLBM_FBLSTART_START_SEC_CODE # include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ /*********************************************************************************************************************** * FblStart **********************************************************************************************************************/ /*! \brief Transition from application into flash boot loader * \pre Valid application program running * \param[in] channel Specify the channel of the reprogramming request (e.g. UDS, XCP, MCMP, OTA) * \param[in] pFblStartParam Pointer to OEM specific parameter structure * \param[in] length Length of OEM specific parameter structure [Bytes] **********************************************************************************************************************/ # if defined( FBLBM_MAIN_ENABLE_FBLSTART_PARAM ) /* PRQA S 3673 2 */ /* MD_FBL_3673_PointerToConstParameter */ void FblStart( FBLBM_MAIN_FBLSTART_CHANNEL_HANDLE_TYPE_FIRST V_MEMRAM1 void V_MEMRAM2 V_MEMRAM3 * pFblStartParam, vuint8 length ) # else void FblStart( FBLBM_MAIN_FBLSTART_CHANNEL_HANDLE_TYPE_ONLY ) # endif /* FBL_MAIN_ENABLE_FBLSTART_PARAM */ { # if defined( FBLBM_MAIN_ENABLE_FBLSTART_PARAM ) vuintx i; # endif # if !defined( FBLBM_MAIN_ENABLE_INTERRUPT_DISABLE_AT_POWER_ON ) FblInterruptDisable(); /* PRQA S 1006 */ /* MD_FblBmMain_1006 */ # endif /* FBLBM_MAIN_ENABLE_INTERRUPT_DISABLE_AT_POWER_ON */ /* Restore bootmanager context - e.g. small data area base registers */ FblHwRestoreFblContext(); /* PRQA S 1006 */ /* MD_FblBmMain_1006 */ # if defined( FBLBM_MAIN_ENABLE_FBLSTART_PARAM ) /* Copy parameter to reset safe variable */ for (i = 0u; i < length; i++) { /* PRQA S 0316 1 */ /* MD_FblBmMain_0316 */ ((volatile vuint8*)&fblBmFblStartParameter)[i] = ((vuint8*)pFblStartParam)[i]; } # endif /* FBLBM_MAIN_ENABLE_FBLSTART_PARAM */ #if defined( FBLBM_MAIN_ENABLE_FBLSTART_CHANNEL ) fblBmFblStartChannel = FBLBM_MAIN_FBLSTART_CHANNEL_HANDLE; #endif /* FBLBM_MAIN_ENABLE_FBLSTART_CHANNEL */ /* Set FblStart magic flag Please pay attention: The FblStart magic flag does not use a shared memory area so that the buffer may overlap with the application stack. */ FblBmSetFblStartMagicFlag(); /* Generate reset */ FBLBM_CALLOUT_RESET(); } # define FBLBM_FBLSTART_STOP_SEC_CODE # include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ #endif /* FBLBM_MAIN_ENABLE_FBL_START */ #if defined( FBLBM_MAIN_ENABLE_STAY_IN_BOOT ) # define FBLBM_APPLSTART_START_SEC_CODE # include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ /*********************************************************************************************************************** * ApplStart **********************************************************************************************************************/ /*! \brief Transition from flash boot loader into application * \pre Valid FBL program running * \param[in] pApplStartParam Pointer to OEM specific parameter structure * \param[in] length Length of OEM specific parameter structure [Bytes] **********************************************************************************************************************/ # if defined( FBLBM_MAIN_ENABLE_APPLSTART_PARAM ) /* PRQA S 3673 1 */ /* MD_FBL_3673_PointerToConstParameter */ void ApplStart( V_MEMRAM1 void V_MEMRAM2 V_MEMRAM3 * pApplStartParam, vuint8 length ) # else void ApplStart( void ) # endif /* FBLBM_MAIN_ENABLE_APPLSTART_PARAM */ { # if defined( FBLBM_MAIN_ENABLE_APPLSTART_PARAM ) vuintx i; # endif # if !defined( FBLBM_MAIN_ENABLE_INTERRUPT_DISABLE_AT_POWER_ON ) FblInterruptDisable(); /* PRQA S 1006 */ /* MD_FblBmMain_1006 */ # endif /* FBLBM_MAIN_ENABLE_INTERRUPT_DISABLE_AT_POWER_ON */ /* Restore bootmanager context - e.g. small data area base registers */ FblHwRestoreFblContext(); /* PRQA S 1006 */ /* MD_FblBmMain_1006 */ # if defined( FBLBM_MAIN_ENABLE_APPLSTART_PARAM ) /* Copy parameter to reset safe variable */ for (i = 0u; i < length; i++) { /* PRQA S 0316 1 */ /* MD_FblBmMain_0316 */ ((volatile vuint8*)&fblBmApplStartParameter)[i] = ((vuint8*)pApplStartParam)[i]; } # endif /* FBLBM_MAIN_ENABLE_APPLSTART_PARAM */ /* Set ApplStart magic flag Please pay attention: The ApplStart magic flag does not use a shared memory area so that the buffer may overlap with the application stack. */ FblBmSetApplStartMagicFlag(); /* Generate reset */ FBLBM_CALLOUT_RESET(); } # define FBLBM_APPLSTART_STOP_SEC_CODE # include "MemMap.h" /* PRQA S 5087 */ /* MD_MSR_MemMap */ #endif /* FBLBM_MAIN_ENABLE_STAY_IN_BOOT */ /*********************************************************************************************************************** * CONFIGURATION CHECKS **********************************************************************************************************************/ #if ( defined( FBLBM_ENABLE_HEADER_VERIFICATION ) && !defined( FBLBM_ENABLE_FBLLBT_VERIFICATION ) ) # error "Configuration not supported" #endif /*********************************************************************************************************************** * MISRA DEVIATIONS **********************************************************************************************************************/ /* Justification for module-specific MISRA deviations: MD_FblBmMain_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. MD_FblBmMain_0306_FblBmHeader: Reason: A memory address is compared to a configured value. The configured value is interpreted as an integer. Risk: The comparison may fail due to different data types. Prevention: If this check fails, the configuration checks done by assertions have to verified manually. MD_FblBmMain_0316: Reason: API is defined with pointer to void parameter, so pointer has to be casted to or from void. Risk: Wrong data access or undefiend behavior for platforms where the byte alignment is not arbitrary. Prevention: Code inspection. MD_FblBmMain_1006: Reason: Interrupts are enabled/disabled using assembler code. Risk: The code is not portable for different compilers. Prevention: The assembler code provided by each FblHw module has to be tested. MD_FblBmMain_1514_BmHeader: Reason: MISRA: The object FblBmHeader is only referenced by function ..., in the translation unit where it is defined This object is exported globally to other modules. Risk: Name space pollution Prevention: No Prevention necessary MD_FBL_2962_UninitializedVariable: Reason: The variable is actually initialzed at runtime. The successive code will never be executed over not initialzed data. Risk: Some potential case not detected during development can lead to read a content which is not valid. Prevention: Write robust code which doesn't allow to read a non initialzed content. MD_FBL_2987_RedundantCode: Reason: QAC misinterprets the code which actually has side effects (i.e. hardware registers are written and read). Risk: No identifiable risk Prevention: No prevention required. MD_FblBmMain_2991_2995: Reason: The value of the if-controlling expression depends on the configuration. Risk: No risk. Prevention: No prevention necessary. MD_FblBmMain_2880_2992_2996_FlashRead: Reason: QAC does not interpret this correctly. The compared data is read from flash (and may therefore contain deviating values). Risk: No risk. Prevention: No prevention required. MD_FblBmMain_3205_UnusedIdentifiers Reason: Depending on the configuration some values of the enum definition are not referenced by the code. For clarity theses values are not omitted but kept as a place holder. Risk: No identifiable risk. Prevention: No prevention required. MD_FBL_3218_FileScopeStatic: Reason: Configuration constants/tables are kept at a central location for a better overview and maintenance. Risk: Unintended use of object in wrong scope. Prevention: Architectural pattern supports prevention of incorrect use of objects in wrong context. Code inspection focus on correct use of objects. MD_FBL_3673_PointerToConstParameter: Reason: Many standards like AUTOSAR, ISO, but also OEM specifications specify the function prototypes without const statement. We have to comply to this standards. Risk: Unintended read or write access into memory location. Prevention: Code inspection focus on correct access to expected memory location MD_FBL_2741_4558_Assert: Reason: The assertion macro has been designed to have an invariant condition and not using bool variable. Risk: No identifiable risk. Assertion macro are disable in production code. Prevention: No prevention required. MD_FblBmMain_5209_Main: Reason: The Vector standard API for main function follows ANSI C typical definition of main function returning int. Risk: No identifiable risk. Prevention: No prevention required. */ /*********************************************************************************************************************** * END OF FILE: BM_MAIN.C **********************************************************************************************************************/